## -*-octave-*- function [bonds,components,n_vector_bonds] = \ ibg2abg(name,bonds,infofile,errorfile) ## write useful quantity of data to log struct_levels_to_print = 6; ################################ ## create component structure ## ################################ ## loop over each bond in ibg.m file for [bond, bond_name] = bonds ## get the bond number i = str2num(split(bond_name, "bond")(2,:)); ## populate "head" and "tail" structures ## then copy the contents to an overall structure ## track (signed) vector bond number within each component head.index = +i; tail.index = -i; ## extract type of component at each end head_type = deblank(split(bond.head.component, ":")(1,:)); tail_type = deblank(split(bond.tail.component, ":")(1,:)); ## extract name of component at each end head_name = deblank(split(bond.head.component, ":")(2,:)); tail_name = deblank(split(bond.tail.component, ":")(2,:)); ## extract port label data head.label = bond.head.ports; tail.label = bond.tail.ports; ## determine whether internal port or subsystem ## and fix names of ports if (strcmp(head_type, "SS") & (index(head_name, "[") == 1)) head_comp_or_port = "port"; head_name = mtt_strip_name(head_name); else head_comp_or_port = "comp"; endif if (strcmp(tail_type, "SS") & (index(tail_name, "[") == 1)) tail_comp_or_port = "port"; tail_name = mtt_strip_name(tail_name); else tail_comp_or_port = "comp"; endif ## copy data to object structure (objects) eval(sprintf("objects.%s.%s.type = '%s';", head_comp_or_port, head_name, head_type)); eval(sprintf("objects.%s.%s.type = '%s';", tail_comp_or_port, tail_name, tail_type)); eval(sprintf("objects.%s.%s.bond%i = head;", head_comp_or_port, head_name, i)); eval(sprintf("objects.%s.%s.bond%i = tail;", tail_comp_or_port, tail_name, i)); endfor disp("--finished extracting data from ibg.m --") objects ## object structure: ## ## objects ## comp ## %s (name) ## type ## bond%i ## label ## port ## %s (name) ## type ## bond%i ## label ## ## "comp" contains components, subsystems and external SS ## "port" contains internal SS:[...] #################################################### ## count number of vector bonds on each component ## #################################################### if (isfield(objects, "comp")) for [comp, comp_name] = objects.comp n = size(struct_elements(comp))(1) - 1; eval(sprintf("objects.comp.%s.n_bonds = %i;", comp_name, n)); endfor endif if (isfield(objects, "port")) for [port, port_name] = objects.port n = size(struct_elements(port))(1) - 1; eval(sprintf("objects.port.%s.n_bonds = %i;", port_name, n)); endfor endif disp("-- finished counting number of bonds on components --") objects ## objects ## comp ## %s (name) ## type ## n_bonds ## bond%i ## label ## port ## %s (name) ## type ## n_bonds ## bond%i ## label ######################################################## ## ensure labels exist on all ports of each component ## ######################################################## if (isfield(objects, "comp")) for [comp, comp_name] = objects.comp if (strcmp(comp.type, "0") | strcmp(comp.type, "1")) ## convert type if (strcmp(comp.type, "0")) comp.type = "zero"; elseif (strcmp(comp.type, "1")) comp.type = "one"; endif ## component is a junction n_named_ports = 0; ## get labelled ports for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) if (! isfield (bond, "label")) bond.label = "[]" endif if (! strcmp(bond.label, "[]")) n_named_ports += 1; port_label = bond.label; endif endif eval(sprintf("comp.%s = bond;", bond_name)); endfor ## attach labels to unlabelled ports if (n_named_ports == 0) mtt_info(sprintf("Defaulting all ports on junction %s to 'in'", \ comp_name), infofile); for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) bond.label = "in"; endif eval(sprintf("comp.%s = bond;", bond_name)); endfor elseif (n_named_ports == 1) mtt_info(sprintf("Defaulting all ports on junction %s to %s", \ comp_name, port_label), infofile); for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) bond.label = port_label; endif eval(sprintf("comp.%s = bond;", bond_name)); endfor elseif (n_named_ports != comp.n_bonds) mtt_error(sprintf("Junction must have 0,1 or %i port labels", \ comp.n_bonds), errorfile); endif else ## component is not a junction for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) if (strcmp(bond.label, "[]")) if (bond.index > 0) bond.label = "in"; else bond.label = "out"; endif else bond.label = mtt_strip_name(bond.label); endif endif eval(sprintf("comp.%s = bond;", bond_name)); endfor endif eval(sprintf("objects.comp.%s = comp;", comp_name)); endfor endif #################### ## expand aliases ## #################### if (isfield(objects, "comp")) for [comp, comp_name] = objects.comp if ((! strcmp(comp.type, "zero")) & (! strcmp(comp.type, "one"))) alias = eval(sprintf("%s_alias", comp.type)); if (isstruct(alias)) for [bond, bond_name] = comp; if (isstruct(bond)) if (isfield(alias, bond.label)) old_name = bond.label; new_name = eval(sprintf("alias.%s", old_name)); bond.label = new_name; mtt_info(sprintf("Aliasing [%s] on %s (%s) to [%s]", old_name, comp_name, comp.type, new_name), infofile); endif endif eval(sprintf("comp.%s = bond;", bond_name)); endfor endif eval(sprintf("objects.comp.%s = comp;", comp_name)); endif endfor endif disp("-- finished expanding aliases --") objects ## objects ## comp ## %s (name) ## type ## n_bonds ## bond%i ## label ## port ## %s (name) ## type ## n_bonds ## bond%i ## label ########################################## ## create sub-bonds according to labels ## ########################################## if (isfield(objects, "comp")) for [comp, comp_name] = objects.comp for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) [sub_bonds, n_sub_bonds] = split_port(bond.label); for i = 1:n_sub_bonds eval(sprintf("bond.subbond%i.label = '%s';", i, deblank(sub_bonds(i,:)))) endfor endif eval(sprintf("comp.%s = bond;", bond_name)); endfor eval(sprintf("objects.comp.%s = comp;", comp_name)); endfor endif if (isfield(objects, "port")) for [port, port_name] = objects.port for [bond, bond_name] = port if (index(bond_name, "bond") == 1) [sub_bonds, n_sub_bonds] = split_port(bond.label); for i = 1:n_sub_bonds eval(sprintf("bond.subbond%i.label = '%s';", i, deblank(sub_bonds(i,:)))); endfor endif eval(sprintf("port.%s = bond;", bond_name)); endfor eval(sprintf("objects.port.%s = port;", port_name)); endfor endif disp("-- finished creating sub-bonds --") objects ## objects ## comp ## %s (name) ## type ## n_bonds ## bond%i ## label ## subbond%i ## port ## %s (name) ## type ## n_bonds ## bond%i ## label ## subbond%i ######################################### ## assign a unique number to each bond ## ######################################### unique_bond_number = 0; for [bond, bond_name] = bonds i = str2num(split(bond_name, "bond")(2,:)); ## extract type of component at each end head.type = deblank(split(bond.head.component, ":")(1,:)); tail.type = deblank(split(bond.tail.component, ":")(1,:)); ## extract name of component at each end head_name = deblank(split(bond.head.component, ":")(2,:)); tail_name = deblank(split(bond.tail.component, ":")(2,:)); ## determine whether internal port or subsystem ## and fix names of ports if (strcmp(head.type, "SS") & (index(head_name, "[") == 1)) head_comp_or_port = "port"; head_name = mtt_strip_name(head_name); else head_comp_or_port = "comp"; endif if (strcmp(tail.type, "SS") & (index(tail_name, "[") == 1)) tail_comp_or_port = "port"; tail_name = mtt_strip_name(tail_name); else tail_comp_or_port = "comp"; endif ## create strings to reference each component head_str = sprintf("objects.%s.%s.bond%i", head_comp_or_port, head_name, i) tail_str = sprintf("objects.%s.%s.bond%i", tail_comp_or_port, tail_name, i) head_bond = eval(head_str); tail_bond = eval(tail_str); ## check compatible sizes head.n_subs = size(struct_elements(head_bond))(1) - 2; tail.n_subs = size(struct_elements(tail_bond))(1) - 2; if (head.n_subs != tail.n_subs) mtt_error(sprintf("Vector ports '%s' (%s:%s) and '%s' (%s:%s) are not compatible", head_bond.label, head.type, head_name, tail_bond.label, tail.type, tail_name), errorfile); elseif (head.n_subs > 1) mtt_info(sprintf("Vector port '%s'(%s:%s) matches '%s' (%s:%s)", head_bond.label, head.type, head_name, tail_bond.label, tail.type, tail_type), infofile); endif ## write type at other end eval(sprintf("%s.other_end_type = '%s';", head_str, tail.type)); eval(sprintf("%s.other_end_type = '%s';", tail_str, head.type)); ## assign bond number for i = 1:head.n_subs ++unique_bond_number; eval(sprintf("%s.subbond%i.index = +%i;", head_str, i, unique_bond_number)); eval(sprintf("%s.subbond%i.index = -%i;", tail_str, i, unique_bond_number)); ## write causality for bond if (strcmp(bond.causality.effort, "head")) eval(sprintf("causality(%i,1) = +1;", unique_bond_number)); elseif (strcmp(bond.causality.effort, "tail")) eval(sprintf("causality(%i,1) = -1;", unique_bond_number)); else eval(sprintf("causality(%i,1) = 0;", unique_bond_number)); endif if (strcmp(bond.causality.flow, "head")) eval(sprintf("causality(%i,2) = -1;", unique_bond_number)); elseif (strcmp(bond.causality.flow, "tail")) eval(sprintf("causality(%i,2) = +1;", unique_bond_number)); else eval(sprintf("causality(%i,2) = 0;", unique_bond_number)); endif endfor endfor disp("-- finished assigning unique numbers to bonds --") objects ## objects ## comp ## %s (name) ## type ## n_bonds ## bond%i ## label ## subbond%i ## index ## port ## %s (name) ## type ## n_bonds ## bond%i ## label ## subbond%i ## index ## causality matrix is called "bonds" bonds = causality disp("-- finished writing bonds matrix --") ################################# ## map component data to cmp.m ## ################################# ## count number of components if (isfield(objects, "comp")) n_comps = size(struct_elements(objects.comp), 1) else n_comps = 0; endif ## count number of internal ports if (isfield(objects, "port")) n_ports = size(struct_elements(objects.port), 1) else n_ports = 0; endif ## read data from _cmp.m for cmp = 1:(n_comps + n_ports) [this_type, this_name] = eval(sprintf("%s_cmp(%i)", name, cmp)); ## determine if internal port (and fix name) or subsystem if (strcmp(this_type, "SS") & (index(this_name, "[") == 1)) comp_or_port = "port"; this_name = mtt_strip_name(this_name) else comp_or_port = "comp"; endif eval(sprintf("objects.%s.%s.index = cmp;", comp_or_port, this_name)); endfor disp("-- finished getting component indices from cmp.m --") objects ## objects ## comp ## %s (name) ## type ## n_bonds ## bond%i ## label ## subbond%i ## index ## index ## port ## %s (name) ## type ## n_bonds ## bond%i ## label ## subbond%i ## index ## index ########################## ## write n_vector_bonds ## ########################## if (isfield(objects, "comp")) for [comp, comp_name] = objects.comp n_vector_bonds(comp.index,1) = comp.n_bonds; endfor endif disp("-- finished writing n_vector_bonds --") n_vector_bonds ########################################### ## Write connections matrix (components) ## ########################################### if (isfield(objects, "comp")) n_comps = size(struct_elements(objects.comp))(1); else n_comps = 0; endif components = zeros(n_comps+n_ports, max(n_vector_bonds)); if (isfield(objects, "comp")) for [comp, comp_name] = objects.comp ## get portlist for component if exist([comp.type, '_cause']) == 0 eval(sprintf("ABG = %s_abg;", comp.type)); if isfield(ABG, "portlist") port_list = ABG.portlist; else error(sprintf("Component %s has no ports", comp.type)); endif else ## must be a simple component: ## lib/comp/simple/comp_ports.m assigns port numbers port_list = comp_ports(comp.type, comp.n_bonds) endif ## but do what with it? counter = 0; n_ports = size(port_list,1) if (strcmp(comp.type, "zero")) | (strcmp(comp.type, "one")) for port = 1 : n_ports component_type = comp.type the_port_list = port_list the_port = port label = port_list(port,:) if (index (label, "[") == 1) label = mtt_strip_name(label) endif label = deblank(label) for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) for [sub_bond, sub_bond_name] = bond if (index(sub_bond_name, "subbond") == 1) sub_bond_label = sub_bond.label if (index (sub_bond_label, "[") == 1) sub_bond_label = mtt_strip_name(sub_bond_label) endif sub_bond_label = deblank(sub_bond_label) if (strcmp(sub_bond_label, label) | strcmp (sub_bond_label,"in")) components(comp.index, ++counter) = sub_bond.index endif endif endfor endif endfor endfor elseif (n_ports == 1) ## no ordering necessary for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) for [sub_bond, sub_bond_name] = bond if (index(sub_bond_name, "subbond") == 1) components(comp.index, ++counter) = sub_bond.index endif endfor endif endfor else ## multiple ports, need to order them for port = 1 : n_ports component_type = comp.type the_port_list = port_list the_port = port label = port_list(port,:) if (index (label, "[") == 1) label = mtt_strip_name(label) endif label = deblank(label) for [bond, bond_name] = comp if (index(bond_name, "bond") == 1) for [sub_bond, sub_bond_name] = bond if (index(sub_bond_name, "subbond") == 1) sub_bond_label = sub_bond.label if (index (sub_bond_label, "[") == 1) sub_bond_label = mtt_strip_name(sub_bond_label) endif sub_bond_label = deblank(sub_bond_label) ## unalias sub_bond label if exist([comp.type, '_alias']) eval(sprintf("alias = %s_alias", comp.type)) if isstruct(alias) while_counter = 0; while isfield(alias, sub_bond_label) old_sub_bond_label = sub_bond_label; sub_bond_label = eval(sprintf("alias.%s", sub_bond_label)) if strcmp(old_sub_bond_label, sub_bond_label) break; endif endwhile endif endif if (strcmp(sub_bond_label, label)) components(comp.index, ++counter) = sub_bond.index endif endif endfor endif endfor endfor endif endfor endif disp("-- finished getting port_list --") port_list if (isfield(objects, "port")) for [port, port_name] = objects.port counter = 0; for [bond, bond_name] = port if (index(bond_name, "bond") == 1) for [sub_bond, sub_bond_name] = bond if (index(sub_bond_name, "subbond") == 1) components(port.index, ++counter) = sub_bond.index; endif endfor endif endfor endfor endif disp("-- finished writing components matrix --") components endfunction