Friday, February 8, 2013

Circuit Parameters - VI

There is a couple of major design flaw in the previous approach.

  1. The component names are automatically generated. It is always better to let the user name the components as they may correspond to PCB designs etc.
  2. Any change in the circuit topology, even an extension of a branch would be seen a new circuit with default values. Better to check if any of the components in the new circuit have parameters in the parameter file and start with those parameters.

So, a change in the code. The components will now be names followed by an underscore ("_") and then the name of the component. Example: Resistor_R1, voltagesource_v1. Case is not important in the component names though it is in the tags.

The unique identifier continues to be cell position. However, for a particular component type, the same tag can't be used. For example: resistor_r1 and resistor_r1 would be illegal. However, two different components could have the same tag. For example: Resistor_br and inductor_br are OK. If the user want to name the components according to function, this might be a good option.

Here is the code (click on "view raw" below the box to see the entire code):


#! /usr/bin/env python
import sys, math
import network_reader as nw_rd
def csv_tuple(csv_elem):
""" Convert a cell position from spreadsheet form
to [row, tuple] form. """
csv_elem.upper()
# Create a dictionary of alphabets
csv_col="A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"
csv_dict={}
csv_col_list=csv_col.split(" ")
# Make the alphabets correspond to integers
for c1 in range(1, 27):
csv_dict[csv_col_list[c1-1]]=c1
# The cell position starts with a number
flag="number"
c1=0
while flag=="number":
# When conversion to int fails
# it means the element is an alphabet
try:
int(csv_elem[c1])
except ValueError:
flag="alphabet"
else:
c1+=1
# Split them up into numbers and alphabets
pol_row=int(csv_elem[0:c1])
pol_col=csv_elem[c1:]
elem_tuple=[pol_row-1, 0]
# Convert the alphabets to number
# Similar to converting binary to decimal
for c1 in range(len(pol_col)-1, -1, -1):
if len(pol_col)-1-c1>0:
elem_tuple[1]+=26*(len(pol_col)-1-c1)*csv_dict[pol_col[c1]]
else:
elem_tuple[1]+=csv_dict[pol_col[c1]]-1
return elem_tuple
def reading_params(param_file):
""" Read a file. Ramove additional quotes and
carriage returns. Remove leading spaces. """
from_file=[]
for line in param_file:
from_file.append(line.split(","))
for c1 in range(len(from_file)):
for c2 in range(len(from_file[c1])-1, -1, -1):
# Remove additional quotes and carriage returns
if from_file[c1][c2]:
nw_rd.scrub_elements(from_file, c1, c2)
# Remove blank spaces and null elements
if from_file[c1][c2]==" " or from_file[c1][c2]=="":
del from_file[c1][c2]
return from_file
class Resistor:
def __init__(self, res_index, res_pos, res_tag):
self.res_number=res_index
self.res_pos=res_pos
self.res_tag=res_tag
self.resistor=100.0
def display(self):
print "Resistor is ",
print self.res_tag,
print "= %f" %self.resistor,
print " located at ",
print self.res_pos
def ask_values(self, x_list, ckt_mat):
res_params=["Resistor"]
res_params.append(self.res_tag)
res_params.append(self.res_pos)
res_params.append(self.resistor)
x_list.append(res_params)
def get_values(self, x_list, ckt_mat):
self.resistor=float(x_list[0])
class Inductor:
def __init__(self, ind_index, ind_pos, ind_tag):
self.ind_number=ind_index
self.ind_pos=ind_pos
self.ind_tag=ind_tag
self.inductor=0.001
def display(self):
print "Inductor is ",
print self.ind_tag,
print "=%f" %self.inductor,
print " located at ",
print self.ind_pos
def ask_values(self, x_list, ckt_mat):
ind_params=["Inductor"]
ind_params.append(self.ind_tag)
ind_params.append(self.ind_pos)
ind_params.append(self.inductor)
x_list.append(ind_params)
def get_values(self, x_list, ckt_mat):
self.inductor=float(x_list[0])
class Capacitor:
def __init__(self, cap_index, cap_pos, cap_tag):
self.cap_number=cap_index
self.cap_pos=cap_pos
self.cap_tag=cap_tag
self.capacitor=10.0e-6
def display(self):
print "Capacitor is ",
print self.cap_tag,
print "= %f" %self.capacitor,
print " located at ",
print self.cap_pos
def ask_values(self, x_list, ckt_mat):
cap_params=["Capacitor"]
cap_params.append(self.cap_tag)
cap_params.append(self.cap_pos)
cap_params.append(self.capacitor)
x_list.append(cap_params)
def get_values(self, x_list, ckt_mat):
self.capacitor=float(x_list[0])
class Voltage_Source:
def __init__(self, volt_index, volt_pos, volt_tag):
self.volt_number=volt_index
self.volt_pos=volt_pos
self.volt_tag=volt_tag
self.v_peak=120.0
self.v_freq=60.0
self.v_phase=0.0
def display(self):
print "Voltage Source is ",
print self.volt_tag,
print "of %f V(peak), %f Hz(frequency) and %f (degrees phase shift)" %(self.v_peak, self.v_freq, self.v_phase),
print " located at ",
print self.volt_pos,
print " with positive polarity towards %s %s" %(nw_rd.csv_element(self.v_polrty), self.v_polrty)
def ask_values(self, x_list, ckt_mat):
volt_params=["VoltageSource"]
volt_params.append(self.volt_tag)
volt_params.append(self.volt_pos)
volt_params.append("Peak (Volts) = %f" %self.v_peak)
volt_params.append("Frequency (Hertz) = %f" %self.v_freq)
volt_params.append("Phase (degrees) = %f" %self.v_phase)
# Looking for a default value of polarity
# in the neighbouring cells
self.volt_elem=csv_tuple(self.volt_pos)
if self.volt_elem[0]>0:
if ckt_mat[self.volt_elem[0]-1][self.volt_elem[1]]:
self.v_polrty=[self.volt_elem[0]-1, self.volt_elem[1]]
elif self.volt_elem[1]>0:
if ckt_mat[self.volt_elem[0]][self.volt_elem[1]-1]:
self.v_polrty=[self.volt_elem[0], self.volt_elem[1]-1]
elif self.volt_elem[0]<len(ckt_mat)-1:
if ckt_mat[self.volt_elem[0]+1][self.volt_elem[1]]:
self.v_polrty=[self.volt_elem[0]+1, self.volt_elem[1]]
elif self.volt_elem[1]<len(ckt_mat)-1:
if ckt_mat[self.volt_elem[0]][self.volt_elem[1]+1]:
self.v_polrty=[self.volt_elem[0], self.volt_elem[1]+1]
volt_params.append("Positive polarity towards (cell) = %s" %nw_rd.csv_element(self.v_polrty))
x_list.append(volt_params)
def get_values(self, x_list, ckt_mat):
self.v_peak=float(x_list[0].split("=")[1])
self.v_freq=float(x_list[1].split("=")[1])
self.v_phase=float(x_list[2].split("=")[1])
volt_polrty=x_list[3].split("=")[1]
# Convert the human readable form of cell
# to [row, column] form
while volt_polrty[0]==" ":
volt_polrty=volt_polrty[1:]
self.v_polrty=csv_tuple(volt_polrty)
if not ckt_mat[self.v_polrty[0]][self.v_polrty[1]]:
print "Polarity incorrect. Branch does not exist at %s" %nw_rd.csv_element(self.v_polrty)
component_list={"resistor":Resistor, "inductor":Inductor, "capacitor":Capacitor, "voltagesource":Voltage_Source}
test_ckt=open("testckt1.csv","r")
# Read the circuit into tst_mat
# Also performs a scrubbing of tst_mat
tst_mat=nw_rd.csv_reader(test_ckt)
components_found={}
for c1 in range(len(tst_mat)):
for c2 in range(len(tst_mat[0])):
elem=tst_mat[c1][c2]
if elem:
# wire is a zero resistance connection
if elem.lower()!="wire":
if len(elem.split("_"))==1:
print "Error! Component at %s does not have a unique name/tag." %nw_rd.csv_element([c1, c2])
else:
[elem_name, elem_tag]=elem.split("_")
elem_type=elem_name.lower()
if elem_type[0]==" ":
elem_type=elem_type[1:]
if elem_tag[0]==" ":
elem_tag=elem_tag[1:]
# Check if component exists
if elem_type in component_list.keys():
# If found for the first time
# Create that dictionary element with key
# as component type
if elem_type not in components_found:
components_found[elem_type]=[[nw_rd.csv_element([c1, c2]), elem_tag]]
else:
# If already found, append it to
# dictionary item with that key.
components_found[elem_type].append([nw_rd.csv_element([c1, c2]), elem_tag])
else:
print "Error! Component at %s doesn't exist." %nw_rd.csv_element([c1, c2])
# Check if a component of the same type has the same tag.
for items in components_found.keys():
for c1 in range(len(components_found[items])):
for c2 in range(len(components_found[items])):
if c1!=c2:
if components_found[items][c1][1]==components_found[items][c2][1]:
print "Duplicate labels found for components of type %s at %s and %s" %(items, components_found[items][c1][0], components_found[items][c2][0])
component_objects={}
for items in components_found.keys():
# Take every type of component found
# item -> resistor, inductor etc
for c1 in range(len(components_found[items])):
# Each component type will be occurring
# multiple times. Iterate through every find.
# The list corresponding to each component is
# the unique cell position in the spreadsheet
component_objects[components_found[items][c1][0]] = \
component_list[items](c1+1, components_found[items][c1][0], components_found[items][c1][1])
# Check if the nw_params.csv file exists.
try:
csv_check_values=open("nw_params.csv","r")
# If not, it has to be created and filled
# with default values.
except:
#param_flag="no"
pass
# Check if any of the components with the same
# tags are present in nw_params.csv. If so, take
# those parameters from nw_params.csv and replace
# the default parameters in the component objects.
else:
params_from_file=reading_params(csv_check_values)
for c1 in range(len(params_from_file)):
# Remove leading spaces if any
# The first column is the type of element
if params_from_file[c1][0][0]==" ":
params_from_file[c1][0]=params_from_file[c1][0][1:]
name_from_file=params_from_file[c1][0].lower()
for c2 in range(len(components_found[name_from_file])):
# Remove leading spaces if any
if params_from_file[c1][1][0]==" ":
params_from_file[c1][1]=params_from_file[c1][1][1:]
# Check if the component tag exists in
# components found so far
if params_from_file[c1][1]==components_found[name_from_file][c2][1]:
# If so take the parameters and move them into the object
# having of that type and having the new cell position
component_objects[components_found[name_from_file][c2][0]].get_values(params_from_file[c1][3:], tst_mat)
csv_check_values.close()
values_to_file=[]
for items in component_objects.keys():
# Each component object has a method
# ask_values that prints in the csv file
# default values for parameters.
component_objects[items].ask_values(values_to_file, tst_mat)
csv_ask_values=open("nw_params.csv","w")
for c1 in range(len(values_to_file)):
for c2 in range(len(values_to_file[c1])):
csv_ask_values.write("%s" %values_to_file[c1][c2])
csv_ask_values.write(", ")
csv_ask_values.write("\n")
csv_ask_values.close()
# Wait for the user to enter parameters before
# reading the nw_params.csv file.
cont_ans="n"
while cont_ans.lower()!="y":
cont_ans=raw_input("Enter parameters in file nw_params.csv. When ready press y and enter to continue -> ")
print
csv_get_values=open("nw_params.csv","r")
params_from_file=reading_params(csv_get_values)
csv_get_values.close()
for c1 in range(len(params_from_file)):
# Getting rid of the beginning spaces
# in the component keys
if params_from_file[c1][2][0]==" ":
params_from_file[c1][2]=params_from_file[c1][2][1:]
component_objects[params_from_file[c1][2]].get_values(params_from_file[c1][3:], tst_mat)
# Just checking the objects
for items in component_objects.keys():
component_objects[items].display()
view raw csv_element3.py hosted with ❤ by GitHub

No comments:

Post a Comment