00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "AMLLatticeExpander.hpp"
00026
00027 using namespace std;
00028 namespace BU = BasicUtilities;
00029
00030
00031
00032
00033 AMLLatticeExpander::AMLLatticeExpander() {
00034 scratch_root = NULL;
00035 }
00036
00037 AMLLatticeExpander::~AMLLatticeExpander() {
00038 if (scratch_root) scratch_root->deleteNode();
00039 }
00040
00041
00042
00043
00044 UAPNode* AMLLatticeExpander::AMLExpandLattice(UAPNode* UAPRoot) {
00045
00046
00047
00048 info_out.parsing_status = "Expanding AML Lattice.";
00049 info_out.ix_line = -1;
00050 info_out.everything_ok = true;
00051
00052 if (scratch_root) scratch_root->deleteNode();
00053 scratch_root = new UAPNode("scratch_root");
00054
00055
00056
00057 NodeVec aml_rep_list = UAPRoot->getChildrenByName("AML_representation");
00058 if (aml_rep_list.size() == 0) {
00059 info_out.error ("Cannot find node: \"AML_representation\"",
00060 "Which should be a subnode of the root node");
00061 return NULL;
00062 }
00063 if (aml_rep_list.size() > 1) {
00064 info_out.error ("More than one \"AML_representation\" node!");
00065 return NULL;
00066 }
00067
00068
00069
00070 NodeVec expand_list = UAPRoot->getChildrenByName("expanded_lattice");
00071 for (NodeVecIter it = expand_list.begin(); it != expand_list.end(); it++)
00072 (*it)->deleteNode();
00073 UAPNode* expand_root = UAPRoot->addChild("expanded_lattice");
00074
00075
00076
00077 UAPNode* aml_rep = scratch_root->addChildCopy(aml_rep_list.front());
00078 all_map.clear();
00079 make_named_lists(aml_rep);
00080
00081
00082
00083 InheritBookkeeper (aml_rep);
00084 apply_sets ("set", "value", aml_rep);
00085 apply_sets ("string_set", "string", aml_rep);
00086 UAPUtilities utilities(aml_rep);
00087 utilities.evaluate();
00088 convert_to_actual (aml_rep);
00089
00090
00091
00092 control_root = expand_root->addChild("control_list");
00093 global_root = expand_root->addChild("global");
00094
00095 NodeVec global_list = aml_rep->getSubNodesByName("global");
00096 if (global_list.size() > 1) info_out.error ("Multiple <global> nodes");
00097 if (global_list.size() == 1) transfer_info_to_new_node (global_list.front(), global_root);
00098
00099
00100
00101
00102 if (!expand_machines(aml_rep, expand_root)) return NULL;
00103 if (!connect_branch_and_merger(expand_root)) return NULL;
00104
00105
00106
00107
00108
00109 NodeVec supers = aml_rep->getSubNodesByName("superimpose");
00110 for (NodeVecIter is = supers.begin(); is != supers.end(); is++) {
00111 UAPNode* ele_or_sect = (*is)->getParent();
00112 if (ele_or_sect->getParent()->getName() == "sector") continue;
00113 superimpose_element (ele_or_sect, expand_root);
00114 }
00115
00116
00117
00118 if (!add_controls(aml_rep, expand_root)) return NULL;
00119 AU.controllerBookkeeper (expand_root);
00120
00121
00122
00123 apply_post_sets ("post_set", "value", aml_rep, expand_root);
00124 apply_post_sets ("post_string_set", "string", aml_rep, expand_root);
00125
00126 if (! info_out.everything_ok) return NULL;
00127 return expand_root;
00128
00129 }
00130
00131
00132
00133
00134 bool AMLLatticeExpander::InheritBookkeeper (UAPNode* root) {
00135
00136
00137
00138
00139 PrintInfoStruct info_out;
00140
00141
00142
00143 NodeVec inherit_list = Twig::getSubNodes(root, "(inherit)");
00144 NodeVec named_list = Twig::getSubNodes(root, "(name)");
00145
00146
00147
00148
00149
00150
00151 bool ok = true;
00152 UAPNode* root_ref = new UAPNode("root");
00153 NodeMap node_map;
00154
00155
00156
00157 for (NodeVecIter il = inherit_list.begin(); il != inherit_list.end(); il++) {
00158
00159 UAPNode* to_node = *il;
00160 string from_str = to_node->getAttributeString("inherit");
00161 string to_str = to_node->getAttributeString("name");
00162
00163
00164
00165
00166 to_node->getAttribute("inherit")->setName("inherited_from");
00167
00168
00169
00170 bool found_node = false;
00171
00172 if (BU::found(node_map, from_str)) {
00173
00174
00175
00176
00177
00178 if (BU::found(node_map, to_str)) {
00179 UAPNode* to_node_ref = node_map[to_str];
00180 UAPNode* parent = to_node_ref->getParent();
00181 to_node_ref->detachNode();
00182 UAPNode* from_node_ref = node_map[from_str];
00183 from_node_ref->getChildren().push_back(to_node_ref);
00184
00185
00186
00187
00188 } else if (BU::found(node_map, from_str)) {
00189 UAPNode* from_node_ref = node_map[from_str];
00190 UAPNode* to_node_ref = from_node_ref->addChild(to_str);
00191 to_node_ref->setConnect(to_node);
00192 if (to_str != "") node_map[to_str] = to_node_ref;
00193 }
00194
00195
00196
00197 } else {
00198
00199 UAPNode* from_node = NULL;
00200 for (NodeVecIter nl = named_list.begin(); nl != named_list.end(); nl++) {
00201 if ((*nl)->getAttributeString("name") != from_str) continue;
00202 from_node = *nl;
00203 break;
00204 }
00205
00206 if (!from_node) {
00207 ok = false;
00208 info_out.error ("CANNOT FIND BASE NODE FOR INHERITANCE.", to_node->toString());
00209
00210
00211
00212
00213 } else if (BU::found(node_map, to_str)) {
00214 UAPNode* from_node_ref = root_ref->addChild(from_str);
00215 from_node_ref->setConnect(from_node);
00216 node_map[from_str] = from_node_ref;
00217 UAPNode* to_node_ref = node_map[to_str];
00218 UAPNode* parent = to_node_ref->getParent();
00219 to_node_ref->detachNode();
00220 from_node_ref->getChildren().push_back(to_node_ref);
00221
00222
00223
00224 } else {
00225 UAPNode* from_node_ref = root_ref->addChild(from_str);
00226 from_node_ref->setConnect(from_node);
00227 node_map[from_str] = from_node_ref;
00228 UAPNode* to_node_ref = from_node_ref->addChild(to_str);
00229 to_node_ref->setConnect(to_node);
00230 if (to_str != "") node_map[to_str] = to_node_ref;
00231 }
00232
00233 }
00234
00235 }
00236
00237
00238
00239 NodeVec children = root_ref->getChildren();
00240 for (NodeVecIter ir = children.begin(); ir != children.end(); ir++)
00241 inherit_from (*ir);
00242
00243
00244
00245 root_ref->deleteNode();
00246 return ok;
00247 }
00248
00249
00250
00251
00252 void AMLLatticeExpander::inherit_from (UAPNode* parent_ref) {
00253
00254
00255
00256 UAPNode* from_node = parent_ref->getConnect();
00257
00258
00259
00260
00261 NodeVec children_ref = parent_ref->getChildren();
00262 for (NodeVecIter ir = children_ref.begin(); ir != children_ref.end(); ir++) {
00263 UAPNode* child_ref = *ir;
00264 UAPNode* to_node = child_ref->getConnect();
00265
00266 NodeVec pc = from_node->getChildren();
00267 for (NodeVecIter ic = pc.begin(); ic != pc.end(); ic++)
00268 inherit_pusher (*ic, to_node);
00269
00270
00271
00272 inherit_from (child_ref);
00273 }
00274
00275 }
00276
00277
00278
00279
00280 void AMLLatticeExpander::inherit_pusher (UAPNode* from_child, UAPNode* to_node) {
00281
00282
00283
00284 string from_str = from_child->getName();
00285 UAPNode* to_child = to_node->getChildByName(from_str);
00286
00287 if (to_child) {
00288 NodeVec pc = from_child->getChildren();
00289 for (NodeVecIter ic = pc.begin(); ic != pc.end(); ic++)
00290 inherit_pusher (*ic, to_child);
00291
00292 } else {
00293
00294 to_node->addChildCopy(from_child);
00295 }
00296
00297 }
00298
00299
00300
00301
00302 void AMLLatticeExpander::make_named_lists(UAPNode* root) {
00303
00304
00305
00306 NodeVec children = root->getChildren();
00307 for (NodeVecCIter in = children.begin(); in != children.end(); in++) {
00308 UAPNode* node = *in;
00309 make_named_lists (node);
00310 if (!node->getAttribute("name")) continue;
00311 string name = node->getAttributeString("name");
00312 if (all_map.find(name) != all_map.end() ) {
00313 info_out.error ("Duplicate named element: " + name);
00314 }
00315 all_map[name] = node;
00316 if (node->getName() == "element") element_map[name] = node;
00317 if (node->getName() == "controller") controller_map[name] = node;
00318
00319 if (node->getName() == "girder") girder_map[name] = node;
00320 }
00321
00322 }
00323
00324
00325
00326
00327 bool AMLLatticeExpander::expand_machines (UAPNode* aml_rep, UAPNode* expand_root) {
00328
00329 string name, ref;
00330 NodeVec ref_list, name_list, machine_list;
00331 StrList duplicates;
00332
00333
00334
00335
00336 sector_map.clear();
00337 duplicates.clear();
00338 NodeVec children = aml_rep->getChildren();
00339 for (NodeVecCIter im = children.begin(); im != children.end(); im++) {
00340 map_sub_nodes (*im, "sector", "name", sector_map, duplicates, false);
00341 }
00342 for (StrListCIter ia=duplicates.begin(); ia!=duplicates.end(); ia++) {
00343 info_out.error ("Duplicate sector name: " + *ia);
00344 }
00345
00346
00347
00348 NodeMap list_map;
00349 duplicates.clear();
00350 for (NodeVecCIter im=machine_list.begin(); im!=machine_list.end(); im++) {
00351 map_sub_nodes (*im, "list", "name", list_map, duplicates, false);
00352 }
00353 for (StrListCIter ia=duplicates.begin(); ia!=duplicates.end(); ia++) {
00354 info_out.error ("Two <list>s have the same \"name\": " + *ia);
00355 }
00356
00357
00358
00359 UAPNode* lists_root = scratch_root->addChild("lists_root");
00360
00361 for (NodeMapIter it = list_map.begin(); it != list_map.end(); it++) {
00362 UAPNode* this_root = lists_root->addChild(it->first);
00363 sector_call_list.clear();
00364 expand_this_sector_or_list (this_root, it->second, +1, false, true, "");
00365 }
00366
00367
00368
00369 map_list_children.clear();
00370 map_list_iter.clear();
00371
00372 NodeVec l_child = lists_root->getChildren();
00373 for (NodeVecCIter it = l_child.begin(); it != l_child.end(); it++) {
00374 string name = (*it)->getName();
00375 map_list_children[name] = (*it)->getChildren();
00376 map_list_iter[name] = map_list_children[name].begin();
00377 }
00378
00379
00380
00381 machine_list = aml_rep->getSubNodesByName("machine");
00382 for (NodeVecCIter it=machine_list.begin(); it!=machine_list.end(); it++) {
00383 bool has_name = (*it)->getAttribute("name");
00384 bool has_ref = (*it)->getAttribute("ref");
00385 if (has_name && has_ref) {
00386 info_out.error ("\"machine\" Node has both \"name\" and \"ref\" attributes!",
00387 (*it)->toString());
00388 }
00389 if (has_ref) ref_list.push_back(*it);
00390 if (has_name) name_list.push_back(*it);
00391 }
00392
00393
00394
00395 for (NodeVecCIter ir=ref_list.begin(); ir!=ref_list.end(); ir++) {
00396 UAPAttribute* attrib_ref = (*ir)->getAttribute("ref");
00397 ref = attrib_ref->getValue();
00398 bool match = false;
00399 for (NodeVecCIter im=name_list.begin(); im!=name_list.end(); im++) {
00400 name = (*im)->getAttributeString("name");
00401 if (ref == name) match = true;
00402 }
00403 if (!match) {
00404 info_out.error ("Reference machine with reference to: " + ref,
00405 "Not matched any machine with that name!", (*ir)->toString());
00406 }
00407 }
00408
00409
00410
00411
00412
00413 if (machine_list.size() == 0) {
00414 info_out.error("No machine found to expand");
00415 return false;
00416 }
00417
00418 UAPNode* machine_root = machine_list.back();
00419 if (machine_root ->getParent()->getName() == "machine")
00420 machine_root = machine_root->getParent();
00421 if (machine_root->getAttribute("ref")) {
00422 ref = machine_root->getAttributeString("ref");
00423 for (NodeVecCIter im=name_list.begin(); im!=name_list.end(); im++) {
00424 name = (*im)->getAttributeString("name");
00425 if (ref == name) {
00426 machine_root = *im;
00427 break;
00428 }
00429 }
00430 }
00431
00432
00433
00434 NodeVec m_list = machine_root->getChildrenByName("machine");
00435 if (m_list.size() > 0) {
00436 for (NodeVecIter im = m_list.begin(); im != m_list.end(); im++) {
00437 if ((*im)->getAttribute("ref")) {
00438 ref = (*im)->getAttributeString("ref");
00439 for (NodeVecCIter in = name_list.begin(); in != name_list.end(); in++) {
00440 name = (*in)->getAttributeString("name");
00441 if (name == ref) expand_this_machine(*in, aml_rep, expand_root);
00442 }
00443 } else {
00444 expand_this_machine (*im, aml_rep, expand_root);
00445 }
00446 }
00447 } else {
00448 expand_this_machine (machine_root, aml_rep, expand_root);
00449 }
00450
00451
00452
00453 return info_out.everything_ok;
00454
00455 }
00456
00457
00458
00459
00460 void AMLLatticeExpander::expand_this_machine (UAPNode* machine_in, UAPNode* aml_rep,
00461 UAPNode* expand_root) {
00462
00463 string value;
00464 NodeVec a_list;
00465 UAPNode* machine;
00466 string sector_name;
00467 StrList duplicates;
00468
00469
00470
00471 machine = expand_root->addChild("machine");
00472 if (UAPAttribute* attrib = machine_in->getAttribute("name"))
00473 machine->addAttribute("name", attrib->getValue());
00474 UAPNode* tracking_root = machine->addChild("tracking_lattice");
00475
00476
00477
00478
00479 master_root = machine->addChild("master_list");
00480
00481
00482
00483 UAPNode* child = tracking_root->addChild("element");
00484 child->addAttribute("name", "beginning");
00485 child->addChild("marker");
00486
00487
00488
00489 if (machine_in->getChildrenByName("sector").size() != 1) {
00490 info_out.error ("Machine does not have exactly one sector: " + machine_in->toString());
00491 return;
00492 }
00493
00494
00495
00496 UAPNode* sector_root = machine_in->getChildByName("sector");
00497 expand_this_sector_or_list (tracking_root, sector_root, 1, false, false, "");
00498
00499
00500
00501
00502 calc_s_positions (tracking_root);
00503
00504
00505
00506 transfer_node_info_to_machine ("beam", aml_rep, machine_in, machine);
00507 transfer_node_info_to_machine ("lattice", aml_rep, machine_in, machine);
00508
00509
00510
00511 sector_call_list.clear();
00512 for (MultiMap::iterator it = multi_map.begin(); it != multi_map.end(); it++)
00513 delete it->second;
00514 multi_map.clear();
00515
00516 }
00517
00518
00519
00520
00521 void AMLLatticeExpander::transfer_node_info_to_machine (string who,
00522 UAPNode* aml_rep, UAPNode* machine_in, UAPNode* machine) {
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 NodeVec who_list = aml_rep->getSubNodesByName(who);
00533
00534 UAPNode* global_who = NULL;
00535 for (NodeVecCIter ib = who_list.begin(); ib != who_list.end(); ib++) {
00536 UAPNode* this_who = *ib;
00537 UAPNode* parent = this_who;
00538 while (parent != aml_rep) {
00539 parent = parent->getParent();
00540 if (parent->getName() == "machine") break;
00541 if (global_who) {
00542 info_out.error ("Multiple global <" + who + "> nodes");
00543 }
00544 if (parent == aml_rep) global_who = this_who;
00545 }
00546 }
00547
00548
00549
00550 who_list = machine_in->getSubNodesByName(who);
00551 if (who_list.size() > 1) {
00552 info_out.error ("Multiple <" + who + "> nodes in machine", machine_in->toString());
00553 }
00554
00555
00556
00557 UAPNode* who_root = machine->addChild(who);
00558 if (global_who) transfer_info_to_new_node (global_who, who_root);
00559 if (who_list.size() > 0) transfer_info_to_new_node (who_list.front(), who_root);
00560 convert_to_actual (who_root);
00561
00562 }
00563
00564
00565
00566
00567 void AMLLatticeExpander::transfer_info_to_new_node (UAPNode* old_node, UAPNode* new_node) {
00568
00569
00570
00571 AttributeVec old_att = old_node->getAttributes();
00572 for (AttributeVecCIter ia = old_att.begin(); ia != old_att.end(); ia++)
00573 new_node->addAttribute(ia->getName(), ia->getValue());
00574
00575
00576
00577 NodeVec old_children = old_node->getChildren();
00578 for (NodeVecCIter in = old_children.begin(); in != old_children.end(); in++) {
00579 UAPNode* old_child = *in;
00580 string name = old_child->getName();
00581 UAPNode* new_child = new_node->getChildByName(name);
00582 if (new_child)
00583 transfer_info_to_new_node (old_child, new_child);
00584 else
00585 new_node->addChildCopy(old_child);
00586 }
00587
00588 }
00589
00590
00591
00592
00593 void AMLLatticeExpander::superimpose_sector_given_ref (UAPNode* super_sect_in,
00594 UAPNode* ref_ele, string ref_origin) {
00595
00596
00597 bool ok;
00598
00599
00600
00601 double ref_len = AU.getAMLAttributeNumericValue(ref_ele, "length@actual", ok);
00602 double s_ref = AU.getAMLAttributeNumericValue(ref_ele, "s@actual", ok);
00603
00604 UAPNode* superimpose_node = super_sect_in->getChildByName("superimpose");
00605 if (!superimpose_node) {
00606 info_out.error ("Cannot find <superimpose> of element.",
00607 super_sect_in->toStringTree());
00608 return;
00609 }
00610
00611 string ref_origin2 = superimpose_node->getAttributeString("ref_origin");
00612 if (ref_origin2 != "") ref_origin = ref_origin2;
00613
00614 if (ref_origin == "ENTRANCE")
00615 s_ref = s_ref - ref_len;
00616 else if (ref_origin == "" || ref_origin == "CENTER")
00617 s_ref = s_ref - ref_len/2;
00618 else if (ref_origin != "EXIT") {
00619 info_out.error ("Bad \"ref_origin\" attribute for superposition: " +
00620 superimpose_node->toString());
00621 return;
00622 }
00623
00624
00625
00626 UAPNode* machine_root = ref_ele->getParent()->getParent();
00627 superimpose_sector_given_s (super_sect_in, s_ref, machine_root);
00628 return;
00629
00630 }
00631
00632
00633
00634
00635 void AMLLatticeExpander::superimpose_sector_given_s (UAPNode* super_sect_in,
00636 double s_entrance, UAPNode* machine_root, string tag) {
00637
00638 bool ok;
00639
00640
00641
00642 UAPNode* super_sect = super_sect_in;
00643 string sector_name = super_sect_in->getAttributeString("ref");
00644 if (sector_name != "") {
00645 super_sect = sector_map[sector_name];
00646 if (!super_sect) {
00647 info_out.error ("No sector could be found named: " + sector_name,
00648 "Needed for: " + super_sect_in->toString());
00649 return;
00650 }
00651 }
00652
00653 double length = BU::string_to_double(super_sect->getAttributeString("length"), ok);
00654
00655
00656
00657 NodeMap sector_child_eles;
00658
00659 NodeVec sect_eles = super_sect->getChildren();
00660 for (NodeVecIter ie = sect_eles.begin(); ie != sect_eles.end(); ie++) {
00661
00662 UAPNode* ele = *ie;
00663
00664
00665
00666 UAPNode* superimpose = ele->getChildByName("superimpose");
00667 if (!superimpose) {
00668 info_out.error ("Element does not have <superimpose> child.", ele->toStringTree());
00669 return;
00670 }
00671
00672
00673
00674 UAPNode* ref_ele;
00675 string ref_name = superimpose->getAttributeString("ref_element");
00676 if (ref_name != "") {
00677 ref_ele = sector_child_eles[ref_name];
00678 if (!ref_ele) {
00679 info_out.error("Unknown reference element: " + superimpose->toString(),
00680 "In element of sector:",
00681 super_sect->toStringTree());
00682 return;
00683 }
00684 }
00685
00686
00687
00688 double s_ref = s_entrance;
00689 string ref_origin = superimpose->getAttributeString("ref_origin");
00690 if (ref_origin == "CENTER")
00691 s_ref = s_entrance + length / 2;
00692 else if (ref_origin == "EXIT")
00693 s_ref = s_entrance + length;
00694 else if (ref_origin != "ENTRANCE") {
00695 info_out.error ("Bad \"ref_origin\" value: " + ref_origin,
00696 ele->toStringTree());
00697 return;
00698 }
00699
00700
00701
00702 if (ele->getName() == "element") {
00703
00704
00705
00706 UAPNode* added_ele;
00707 if (ref_name == "")
00708 added_ele = superimpose_element_given_s (ele, s_ref, machine_root);
00709 else
00710 added_ele = superimpose_element_given_ref (ele, ref_ele);
00711
00712 if (!added_ele) return;
00713 string ele_name = ele->getAttributeString("ref");
00714 if (ele_name == "") ele_name = ele->getAttributeString("name");
00715 sector_child_eles[ele_name] = added_ele;
00716
00717
00718
00719 } else if (ele->getName() == "sector") {
00720 if (ref_name == "")
00721 superimpose_sector_given_s (ele, s_ref, machine_root, tag);
00722 else
00723 superimpose_sector_given_ref (ele, ref_ele);
00724
00725
00726
00727
00728 } else {
00729 info_out.error ("Unknown child: " + ele->toString(),
00730 "Of sector: " + super_sect_in->toString());
00731 return;
00732 }
00733
00734 }
00735
00736 }
00737
00738
00739
00740
00741 void AMLLatticeExpander::superimpose_element (UAPNode* super_ele, UAPNode* expand_root) {
00742
00743
00744
00745 if (super_ele->getName() != "element") {
00746 info_out.error ("Error in superimpose_element routine.",
00747 "Node argument is not an <element>: ",
00748 super_ele->toString());
00749 return;
00750 }
00751
00752 UAPNode* superimpose_node = super_ele->getChildByName("superimpose");
00753 if (!superimpose_node) {
00754 info_out.error ("Error in superimpose_element routine.",
00755 "Cannot find superimpose node in element:",
00756 superimpose_node->toStringTree());
00757 return;
00758 }
00759
00760
00761
00762 string ref_name = superimpose_node->getAttributeString("ref_element");
00763 if (ref_name == "") ref_name = "beginning";
00764
00765 NodeVec ref_eles = get_named_elements (ref_name, expand_root);
00766 if (ref_eles.empty()) {
00767 info_out.error ("No reference element found in lattice with name: " + ref_name,
00768 "For superpostion: " + superimpose_node->toString());
00769 return;
00770 }
00771
00772
00773
00774 for (NodeVecIter ie = ref_eles.begin(); ie != ref_eles.end(); ie++) {
00775 UAPNode* ref_ele = *ie;
00776
00777
00778
00779 if (ref_ele->getAttributeString("lord_rank") != "MULTIPASS_LORD") {
00780 superimpose_element_given_ref (super_ele, ref_ele);
00781 continue;
00782 }
00783
00784
00785
00786
00787 NodeVec slaves = ref_ele->getList(SLAVE);
00788 for (NodeVecIter is = slaves.begin(); is != slaves.end(); is++) {
00789 UAPNode* slave = *is;
00790 superimpose_element_given_ref (super_ele, ref_ele);
00791
00792 }
00793
00794 }
00795
00796 }
00797
00798
00799
00800
00801 UAPNode* AMLLatticeExpander::superimpose_element_given_ref (UAPNode* ele_in,
00802 UAPNode* ref_ele) {
00803
00804 bool ok;
00805
00806
00807
00808 double ref_len = AU.getAMLAttributeNumericValue(ref_ele, "length@actual", ok);
00809 double s_ref = AU.getAMLAttributeNumericValue(ref_ele, "s@actual", ok);
00810
00811 UAPNode* superimpose_node = ele_in->getChildByName("superimpose");
00812 if (!superimpose_node) {
00813 info_out.error ("Cannot find <superimpose> of element.",
00814 ele_in->toStringTree());
00815 return NULL;
00816 }
00817
00818 string ref_origin = superimpose_node->getAttributeString("ref_origin");
00819 if (ref_origin == "ENTRANCE")
00820 s_ref = s_ref - ref_len;
00821 else if (ref_origin == "" || ref_origin == "CENTER")
00822 s_ref = s_ref - ref_len/2;
00823 else if (ref_origin != "EXIT") {
00824 info_out.error ("Bad \"ref_origin\" attribute for superposition: " +
00825 superimpose_node->toString());
00826 return NULL;
00827 }
00828
00829
00830
00831 UAPNode* machine_root = ref_ele->getParent()->getParent();
00832 return superimpose_element_given_s (ele_in, s_ref, machine_root);
00833
00834 }
00835
00836
00837
00838
00839 UAPNode* AMLLatticeExpander::superimpose_element_given_s (UAPNode* ele_in,
00840 double s_ref, UAPNode* machine_root) {
00841
00842 bool ok;
00843
00844
00845
00846 UAPNode* super_ele = ele_in;
00847 string ele_name = ele_in->getAttributeString("ref");
00848 if (ele_name != "") {
00849 if (!BU::found(element_map, ele_name)) {
00850 info_out.error ("Element not found: " + ele_name,
00851 "Referred to in: " + ele_in->toString());
00852 return NULL;
00853 }
00854 super_ele = element_map[ele_name];
00855 }
00856
00857
00858
00859 UAPNode* tracking_root = machine_root->getChildByName("tracking_lattice");
00860
00861
00862
00863 master_root = machine_root->getChildByName("master_list");
00864 UAPNode* super_lord = master_root->addChildCopy(super_ele);
00865
00866 UAPNode* superimpose_node = ele_in->getChildByName("superimpose");
00867 if (!superimpose_node) {
00868 info_out.error ("Cannot find <superimpose> of element.",
00869 ele_in->toStringTree());
00870 return NULL;
00871 }
00872
00873 string ele_origin = superimpose_node->getAttributeString("ele_origin");
00874
00875
00876
00877
00878 double offset = 0;
00879 if (UAPAttribute* off = superimpose_node->getAttribute("offset"))
00880 offset = BU::string_to_double(off->getValue(), ok);
00881
00882 double super_len = AU.getAMLAttributeNumericValue(super_lord, "length@actual", ok);
00883 if (!ok) {
00884 info_out.error ("Bad attribute \"length\" value of element:", super_lord->toStringTree());
00885 return NULL;
00886 }
00887
00888 double s1 = s_ref + offset;
00889 if (ele_origin == "EXIT")
00890 s1 = s1 - super_len;
00891 else if (ele_origin == "" || ele_origin == "CENTER")
00892 s1 = s1 - super_len/2;
00893 else if (ele_origin != "ENTRANCE") {
00894 info_out.error ("Bad \"ele_origin\" attribute for superposition: " +
00895 superimpose_node->toString());
00896 return NULL;
00897 }
00898
00899 double s2 = s1 + super_len;
00900
00901 UAPNode* ele = *(tracking_root->getChildren().begin());
00902
00903 double s1_lat = AU.getAMLAttributeNumericValue (ele, "s@actual", ok);
00904 if (!ok) {
00905 info_out.error ("Bad \"s\" attribute of element:", ele->toStringTree());
00906 return NULL;
00907 }
00908
00909 ele = tracking_root->getChildren().back();
00910
00911 double s2_lat = AU.getAMLAttributeNumericValue (ele, "s@actual", ok);
00912 if (!ok) {
00913 info_out.error ("Bad \"s\" attribute of element:", ele->toStringTree());
00914 return NULL;
00915 }
00916
00917 double len_lat = s2_lat - s1_lat;
00918
00919 UAPNode* g_node = machine_root->getChildByName("lattice");
00920 if (g_node) g_node = g_node->getChildByName("geometry");
00921 string geometry = "";
00922 if (g_node) geometry = g_node->getAttributeString("type");
00923
00924 if (s1 < s1_lat) {
00925 if (geometry != "CIRCULAR") {
00926 info_out.error ("Superposition extends beyond beginning of lattice");
00927 return NULL;
00928 }
00929 s1 = s1 + len_lat;
00930 }
00931
00932 if (s2 > s2_lat) {
00933 if (geometry != "CIRCULAR") {
00934 info_out.error ("Superposition extends beyond end of lattice");
00935 return NULL;
00936 }
00937 s2 = s2 - len_lat;
00938 }
00939
00940
00941
00942
00943 NodeVecIter s1_iter, s2_iter;
00944 if (super_len == 0) {
00945 AU.splitElement (machine_root, s1, s1_iter);
00946 UAPNode* new_ele = tracking_root->addChildCopy (super_lord, *s1_iter);
00947 new_ele->getChildByName("superimpose")->deleteNode();
00948 super_lord->deleteNode();
00949 calc_s_positions (tracking_root);
00950 return new_ele;
00951 }
00952
00953
00954
00955
00956
00957 if (s2 > s1) {
00958 AU.splitElement (machine_root, s2, s2_iter);
00959 AU.splitElement (machine_root, s1, s1_iter);
00960 } else {
00961 AU.splitElement (machine_root, s1, s1_iter);
00962 AU.splitElement (machine_root, s2, s2_iter);
00963 }
00964
00965
00966
00967 super_lord->addAttribute("lord_rank", "SUPER_LORD");
00968 super_lord->addChild("s")->addAttribute("actual", BU::double_to_string(s2, ok));
00969 super_lord->getChildByName("superimpose")->deleteNode();
00970
00971 for (NodeVecIter in = s1_iter; in != s2_iter; in++) {
00972
00973
00974
00975
00976 if (in == tracking_root->getChildren().end())
00977 in = tracking_root->getChildren().begin();
00978
00979 if (in == tracking_root->getChildren().begin()) in++;
00980
00981 UAPNode* this_ele = *in;
00982
00983
00984
00985 if (AU.getAMLAttributeNumericValue(this_ele, "length@actual", ok) == 0) continue;
00986
00987
00988
00989 if (this_ele->getAttributeString("slave_rank") == "SUPER_SLAVE") {
00990 this_ele->add(MASTER, super_lord);
00991 super_lord->add(SLAVE, this_ele);
00992 continue;
00993 }
00994
00995
00996
00997
00998 UAPNode* super_this_ele = master_root->addChildCopy(this_ele);
00999 super_this_ele->addAttribute("lord_rank", "SUPER_LORD");
01000 super_this_ele->add(SLAVE, this_ele);
01001
01002 super_lord->add(SLAVE, this_ele);
01003
01004 this_ele->addAttribute("slave_rank", "SUPER_SLAVE");
01005 this_ele->add(MASTER, super_this_ele);
01006 this_ele->add(MASTER, super_lord);
01007
01008
01009 UAPNode* len_node = this_ele->getChildByName("length");
01010 len_node->removeAttribute("design");
01011 len_node->removeAttribute("err");
01012
01013 }
01014
01015 AU.form_super_slave_names(super_lord);
01016 calc_s_positions (tracking_root);
01017
01018 return super_lord;
01019
01020 }
01021
01022
01023
01024
01025 NodeVec AMLLatticeExpander::get_named_elements (const string& ref_name, UAPNode* root) {
01026
01027 NodeVec match_eles;
01028
01029 NodeVec eles = root->getSubNodesByName("element");
01030 for (NodeVecIter ie = eles.begin(); ie != eles.end(); ie++) {
01031 UAPNode* ref_ele = *ie;
01032 string name = ref_ele->getAttributeString("name");
01033 if (name == ref_name) match_eles.push_back(ref_ele);
01034 }
01035
01036 return match_eles;
01037
01038 }
01039
01040
01041
01042
01043
01044
01045
01046
01047 void AMLLatticeExpander::expand_this_sector_or_list (UAPNode* tracking_root,
01048 UAPNode* sector_in, int direction, bool multipass, bool expanding_a_list, string prefix) {
01049
01050
01051
01052 bool has_name = sector_in->getAttribute("name");
01053 bool has_ref = sector_in->getAttribute("ref");
01054 string sector_name = "";
01055 if (has_name) sector_name = sector_in->getAttributeString("name");
01056 if (has_ref) sector_name = sector_in->getAttributeString("ref");
01057
01058
01059
01060
01061 for (StrListCIter it = sector_call_list.begin(); it != sector_call_list.end(); it++) {
01062 if (sector_name == *it) {
01063 info_out.error ("Infinite loop expanding machine");
01064 throw;
01065 }
01066 }
01067 if (has_name || has_ref) sector_call_list.push_back(sector_name);
01068
01069
01070
01071
01072 UAPNode* sector_def;
01073 if (sector_in->getName() == "list") {
01074 sector_def = sector_in;
01075 } else if (has_name || has_ref) {
01076 sector_def = sector_map[sector_name];
01077 if (!sector_def) {
01078 info_out.error ("No sector could be found named: " + sector_name,
01079 "Needed for: " + sector_in->toString());
01080 return;
01081 }
01082
01083 } else {
01084 sector_def = sector_in;
01085 }
01086
01087 NodeVec children = sector_def->getChildren();
01088
01089
01090
01091 bool has_length = (sector_def->getAttribute("length") != NULL);
01092
01093
01094
01095 int repeat = 1;
01096
01097 if (UAPAttribute* attrib = sector_in->getAttribute("repeat")) {
01098 if (!attrib->getInt(repeat)) {
01099 info_out.error ("Sector repeat attribute is not an integer", sector_in->toString());
01100 }
01101 }
01102
01103
01104
01105
01106 StrMap arg_map;
01107 if (!get_arg_map (sector_in, sector_def, arg_map)) return;
01108
01109
01110
01111 bool reflect;
01112 if (UAPAttribute* attrib = sector_in->getAttribute("reflection")) {
01113 reflect = false;
01114 if (!attrib->getBool(reflect)) {
01115 info_out.error ("Sector reflection attribute is not a true or false",
01116 sector_in->toString());
01117 }
01118 if (has_length) {
01119 info_out.error ("A sector cannot have both \"reflection\" and \"length\" attributes.",
01120 sector_in->toString());
01121 return;
01122 }
01123 if (reflect) direction = -direction;
01124 }
01125
01126
01127
01128
01129 bool multi = false;
01130
01131 if (UAPAttribute* attrib = sector_def->getAttribute("multipass")) {
01132 if (expanding_a_list) {
01133 info_out.error ("Multipass attribute not allowed a list definition",
01134 "Bad <sector>: " + sector_def->toString());
01135 }
01136 if (!attrib->getBool(multi)) {
01137 info_out.error ("Sector multipass attribute is not a true or false",
01138 "Bad <sector>: " + sector_def->toString());
01139 }
01140 }
01141
01142 if (UAPAttribute* attrib = sector_in->getAttribute("multipass")) {
01143 if (expanding_a_list) {
01144 info_out.error ("Multipass attribute not allowed a list definition",
01145 "Bad <sector>: " + sector_in->toString());
01146 }
01147 if (!attrib->getBool(multi)) {
01148 info_out.error ("Sector multipass attribute is not a true or false",
01149 "Bad <sector>: " + sector_in->toString());
01150 }
01151 }
01152
01153
01154
01155
01156 if (multipass) {
01157 if (multi_map.find(sector_name) != multi_map.end()) {
01158 info_out.error ("Sector used to start a multipass region: " + sector_name,
01159 "Is also used as a subsector in a multipass region.");
01160 }
01161 }
01162
01163
01164
01165
01166 if (!multipass && multi) {
01167 if (multi_map.find(sector_name) == multi_map.end()) {
01168 this_multi = new multipass_struct;
01169 this_multi->n_pass = 1;
01170 multi_map[sector_name] = this_multi;
01171 } else {
01172 this_multi = multi_map[sector_name];
01173 this_multi->n_pass++;
01174 if (direction == 1) {
01175 this_multi->iter = (this_multi->masters).begin();
01176 } else {
01177 this_multi->iter = (this_multi->masters).end();
01178 }
01179 }
01180 this_multi->direction = direction;
01181 multipass = true;
01182 }
01183
01184
01185
01186 if (UAPAttribute* attrib = sector_in->getAttribute("prefix")) {
01187 prefix += "." + attrib->getValue();
01188 } else if (attrib = sector_in->getAttribute("prefix")) {
01189 prefix += "." + attrib->getValue();
01190 }
01191
01192
01193
01194
01195 UAPNode* girder = sector_in->getChildByName("girder");
01196 if (!girder) girder = sector_def->getChildByName("girder");
01197
01198 if (girder) {
01199 UAPNode* girder_control = control_root->addChildCopy(girder);
01200 girder_list.push_back(girder_control);
01201 }
01202
01203
01204
01205 bool ok;
01206 for (int ir = 0; ir < repeat; ir++) {
01207
01208 string prefix_out = prefix;
01209 string str = BU::int_to_string(ir, ok);
01210
01211 size_t ic = prefix_out.find("#COUNT");
01212 if (ic != string::npos) prefix_out.replace(ic, 6, str);
01213
01214
01215
01216 if (has_length) {
01217
01218 double s_sector = AU.getAMLAttributeNumericValue(
01219 tracking_root->getChildren().back(), "s@actual", ok);
01220
01221 UAPNode* drift = new UAPNode("element");
01222 string name = sector_name + "_sector";
01223 drift->addAttribute("name", name);
01224 drift->addChild("length")->addAttribute("actual",
01225 sector_def->getAttributeString("length"));
01226 element_map[name] = drift;
01227 add_this_element_or_sector (tracking_root, drift, arg_map, direction,
01228 multipass, expanding_a_list, prefix_out);
01229 element_map.erase(name);
01230 delete drift;
01231
01232 calc_s_positions (tracking_root);
01233 UAPNode* machine_root = tracking_root->getParent();
01234 superimpose_sector_given_s (sector_def, s_sector, machine_root, prefix_out);
01235
01236
01237
01238
01239
01240 } else if (direction == 1) {
01241 for (NodeVecCIter in = children.begin(); in != children.end(); in++) {
01242 add_this_element_or_sector (tracking_root, *in, arg_map, direction,
01243 multipass, expanding_a_list, prefix_out);
01244 }
01245
01246 } else {
01247 for (NodeVecRevIter in = children.rbegin(); in != children.rend(); in++) {
01248 add_this_element_or_sector (tracking_root, *in, arg_map, direction,
01249 multipass, expanding_a_list, prefix_out);
01250 }
01251 }
01252
01253 }
01254
01255
01256
01257 if (has_name || has_ref) sector_call_list.pop_back();
01258 if (girder) girder_list.pop_back();
01259
01260 }
01261
01262
01263
01264
01265 void AMLLatticeExpander::add_this_element_or_sector (UAPNode* tracking_root,
01266 UAPNode* node, StrMap& arg_map, int direction, bool multipass,
01267 bool expanding_a_list, string prefix) {
01268
01269 UAPAttribute* attrib;
01270 UAPNode* sector_node = node->getParent();
01271 string type_of_node = node->getName();
01272
01273
01274
01275
01276 if (type_of_node == "girder") {
01277 if (node->getChildIndexNumber() != 0) {
01278 info_out.error ("A girder node, if present, must be the first child of a sector.",
01279 sector_node->toStringTree());
01280 }
01281 return;
01282 }
01283
01284
01285
01286 string name;
01287 if (node->getAttribute("ref")) {
01288 UAPAttribute* attrib_ref = node->getAttribute("ref");
01289 name = attrib_ref->getValue();
01290 if (arg_map.find(name) != arg_map.end()) name = arg_map[name];
01291 } else {
01292 UAPAttribute* attrib_name = node->getAttribute("name");
01293 if (attrib_name) name = attrib_name->getValue();
01294 }
01295
01296
01297
01298 if (type_of_node == "sector") {
01299 expand_this_sector_or_list (tracking_root, node, direction, multipass,
01300 expanding_a_list, prefix);
01301 return;
01302 }
01303
01304
01305
01306 if (type_of_node == "element" && map_list_iter.find(name) != map_list_iter.end()) {
01307 if (expanding_a_list) {
01308 info_out.error ("A reference is not allowed inside a <list>",
01309 "Referenced in <list>: " + sector_node->toStringTree());
01310 return;
01311 }
01312 if (map_list_iter.find(name) == map_list_iter.end()) {
01313 info_out.error ("List not found: " + name,
01314 "Referenced in sector: " + sector_call_list.back());
01315 return;
01316 }
01317
01318 UAPNode* node = *map_list_iter[name];
01319 string list_name = name;
01320 name = node->getName();
01321 if (element_map.find(name) == element_map.end()) {
01322 info_out.error ("Element not found: " + name,
01323 "Referenced in list: " + sector_node->toStringTree());
01324 return;
01325 }
01326
01327 UAPNode* element = element_map[name];
01328 element = tracking_root->addChildCopy(element);
01329 if (multipass) add_multipass_element (element);
01330
01331
01332 NodeVecCIter temp = ++map_list_iter[list_name];
01333 if (temp == map_list_children[list_name].end())
01334 temp = map_list_children[list_name].begin();
01335 map_list_iter.erase(list_name);
01336 map_list_iter[list_name] = temp;
01337
01338 return;
01339 }
01340
01341
01342
01343 if (type_of_node == "element") {
01344
01345 if (expanding_a_list) {
01346 tracking_root->addChild(name);
01347 return;
01348 }
01349
01350 if (element_map.find(name) == element_map.end()) {
01351 info_out.error ("Element not found: " + name,
01352 "Referenced in sector: " + sector_call_list.back());
01353 return;
01354 }
01355
01356 UAPNode* element = element_map[name];
01357 element = tracking_root->addChildCopy(element);
01358 if (multipass) add_multipass_element (element);
01359
01360
01361
01362 for (NodeVecCIter ig = girder_list.begin(); ig != girder_list.end(); ig++) {
01363 element->add(MASTER, *ig);
01364 (*ig)->add(SLAVE, element);
01365 }
01366
01367
01368
01369 if (attrib = node->getAttribute("prefix")) prefix += "." + attrib->getValue();
01370 if (prefix != "") {
01371 prefix.erase(0,1);
01372 element->addAttribute("prefix", prefix);
01373 }
01374 return;
01375 }
01376
01377
01378
01379 if (type_of_node == "branch" || type_of_node == "merger") {
01380 if (!node->getAttribute("name")) {
01381 info_out.error ("In sector: " + sector_call_list.back(),
01382 "<merger> or <branch> subnode within <sector> node must ",
01383 "have \"name\" attribute: " + node->toString());
01384 return;
01385 }
01386 if (expanding_a_list) {
01387 info_out.error ("In list: " + sector_call_list.front(),
01388 "<merger> or <branch> subnode not allowed when expanding a <list>");
01389 return;
01390 }
01391 tracking_root->addChildCopy(node);
01392
01393 return;
01394 }
01395
01396
01397
01398 info_out.error ("In <sector> found child node: " + node->toString(),
01399 "that is not a <sector>, <element>, <branch>, nor <merger>.",
01400 sector_node->toStringTree());
01401 return;
01402
01403 }
01404
01405
01406
01407
01408 bool AMLLatticeExpander::connect_branch_and_merger(UAPNode* expand_root) {
01409
01410 NodeMap branch_map, merger_map, to_map, from_map;
01411 StrList duplicates;
01412
01413
01414
01415 map_sub_nodes (expand_root, "branch", "name", branch_map, duplicates);
01416 for (StrListCIter ia=duplicates.begin(); ia!=duplicates.end(); ia++) {
01417 info_out.error ("Duplicate branch name: " + *ia);
01418 }
01419
01420 map_sub_nodes (expand_root, "merger", "name", merger_map, duplicates);
01421 for (StrListCIter ia=duplicates.begin(); ia!=duplicates.end(); ia++) {
01422 info_out.error ("Duplicate merger name: " + *ia);
01423 }
01424
01425
01426
01427 for (NodeMapCIter ib = branch_map.begin(); ib != branch_map.end(); ib++) {
01428 UAPNode* branch = ib->second;
01429 string branch_name = ib->first;
01430 map_sub_nodes (branch, "to", "ref", to_map, duplicates);
01431 for (StrListCIter ia=duplicates.begin(); ia!=duplicates.end(); ia++) {
01432 info_out.error ("Duplicate <to> subnodes in branch: " + branch->toString(),
01433 "Duplicate <to> reference is: " + *ia);
01434 }
01435
01436
01437
01438 for (NodeMapCIter it = to_map.begin(); it != to_map.end(); it++) {
01439 UAPNode* to = (*it).second;
01440 UAPAttribute* attrib_ref = to->getAttribute("ref");
01441 if (!attrib_ref) {
01442 info_out.error ("Subnode of this <branch>: " + branch->toString(),
01443 "Does not have a \"ref\" attribute: " + to->toString());
01444 continue;
01445 }
01446 string merge_to = attrib_ref->getValue();
01447 if (merger_map.find(merge_to) == merger_map.end()) {
01448 info_out.error ("Subnode of this <branch>: " + branch->toString(),
01449 "Has reference to unknown <merger> node: " + to->toString());
01450 continue;
01451 }
01452
01453
01454
01455
01456 UAPNode* merger = merger_map[merge_to];
01457 map_sub_nodes (merger, "from", "ref", from_map, duplicates);
01458 for (StrListCIter ia=duplicates.begin(); ia!=duplicates.end(); ia++) {
01459 info_out.error ("Duplicate <from> subnodes in merger: " + merger->toString(),
01460 "Duplicate <from> reference is: " + *ia);
01461 }
01462 if (from_map.find(branch_name) == from_map.end()) {
01463 info_out.error ("No corresponding <from> subnode of <merger>: " + merger->toString(),
01464 "To match <to> subnode: " + to->toString(),
01465 "of <branch>: " + branch->toString());
01466 continue;
01467 }
01468 UAPNode* from = from_map[branch_name];
01469 to->setConnect(from);
01470 from->setConnect(to);
01471 }
01472 }
01473
01474
01475 for (NodeMapCIter im = merger_map.begin(); im != merger_map.end(); im++) {
01476 UAPNode* merger = (*im).second;
01477 string merger_name = (*im).first;
01478 map_sub_nodes (merger, "from", "ref", from_map, duplicates);
01479
01480
01481 for (NodeMapCIter it = from_map.begin(); it != from_map.end(); it++) {
01482 UAPNode* from = (*it).second;
01483 if (!from->getConnect()) {
01484 info_out.error ("Subnode <from>: " + from->toString(),
01485 "Of <merger> node: " + merger->toString(),
01486 "Does not have a corresponding <to> subnode of any <branch>.");
01487 continue;
01488 }
01489 }
01490 }
01491
01492 return info_out.everything_ok;
01493 }
01494
01495
01496
01497
01498 bool AMLLatticeExpander::add_controls(UAPNode* aml_rep, UAPNode* expand_root) {
01499
01500
01501
01502 NodeVec ele_list = expand_root->getSubNodesByName("element");
01503
01504
01505
01506 NodeVec controls = aml_rep->getSubNodesByName("controller");
01507 for (NodeVecCIter ic = controls.begin(); ic != controls.end(); ic++) {
01508 UAPNode* new_control = control_root->addChildCopy(*ic);
01509 ele_list.push_back(new_control);
01510 }
01511
01512
01513
01514 controls = control_root->getChildren();
01515 for (NodeVecCIter ic = controls.begin(); ic != controls.end(); ic++) {
01516
01517 UAPNode* controller = *ic;
01518 string dflt_attrib = controller->getAttributeString("attribute");
01519 NodeVec s_list = controller->getChildren();
01520
01521 for (NodeVecIter is = s_list.begin(); is != s_list.end(); is++) {
01522 UAPNode* slave_node = *is;
01523 if (slave_node->getName() != "slave") continue;
01524
01525 string target_str = slave_node->getAttributeString("target");
01526 Twig twig(target_str, true);
01527 string attrib_name = twig.toNodeString(true);
01528 if (attrib_name == "") attrib_name = dflt_attrib;
01529 string slave_name = twig.name;
01530
01531 if (slave_name == "") {
01532 info_out.error ("No \"element\" attribute for slave of controller: " +
01533 slave_node->toString());
01534 return false;
01535 }
01536
01537
01538 for (NodeVecCIter ie = ele_list.begin(); ie != ele_list.end(); ie++) {
01539 UAPNode* slave_ele = *ie;
01540 if (slave_ele->getAttributeString("name") != slave_name) continue;
01541 slave_node->add(SLAVE, slave_ele);
01542 slave_ele->add(CONTROLLER, slave_node);
01543 }
01544 }
01545 }
01546
01547 return true;
01548
01549 }
01550
01551
01552
01553
01554 bool AMLLatticeExpander::get_arg_map (UAPNode* main_sector, UAPNode* sub_sector,
01555 StrMap& arg_map) {
01556
01557
01558 if (bool(main_sector->getAttribute("args")) != bool(sub_sector->getAttribute("args"))) {
01559 info_out.error (
01560 "Sector without an argument list references a sector that has one or vice versa.",
01561 "This sector: " + main_sector->toString(),
01562 "References this sector: " + sub_sector->toString());
01563 return false;
01564 }
01565
01566
01567 if (!(main_sector->getAttribute("args"))) return true;
01568
01569
01570 StrList actual_args, dummy_args;
01571 if (!AU.getSectorArgList (main_sector, actual_args)) return false;
01572 if (!AU.getSectorArgList (sub_sector, dummy_args)) return false;
01573 if (actual_args.size() != dummy_args.size()) {
01574 info_out.error ("Number of actual arguments does not match number of dummy arguments",
01575 "This sector: " + main_sector->toString(),
01576 "Calls this sector: " + sub_sector->toString());
01577 return false;
01578 }
01579
01580
01581 StrListCIter id = dummy_args.begin();
01582 for (StrListCIter ia = actual_args.begin(); ia != actual_args.end(); ia++) {
01583 arg_map[*id] = *ia;
01584 id++;
01585 }
01586
01587 return true;
01588
01589 }
01590
01591
01592
01593
01594 void AMLLatticeExpander::map_sub_nodes(UAPNode* root, const string& node_name,
01595 const string& attrib_name, NodeMap& map, StrList& duplicates, bool clear) {
01596
01597 if (clear) {
01598 map.clear();
01599 duplicates.clear();
01600 }
01601
01602 NodeVec a_list = root->getSubNodesByName(node_name);
01603 for (NodeVecCIter ia=a_list.begin(); ia!=a_list.end(); ia++) {
01604 if (!(*ia)->getAttribute(attrib_name)) continue;
01605 string name = (*ia)->getAttributeString(attrib_name);
01606 if (map.find(name) != map.end()) duplicates.push_back(name);
01607 map[name] = *ia;
01608 }
01609
01610 return;
01611
01612 }
01613
01614
01615
01616
01617 void AMLLatticeExpander::add_multipass_element (UAPNode* slave) {
01618
01619 UAPNode* master;
01620
01621
01622 if (this_multi->n_pass == 1) {
01623 master = master_root->addChildCopy(slave);
01624 master->addAttribute("lord_rank", "MULTIPASS_LORD");
01625 if (this_multi->direction == 1) this_multi->masters.push_back(master);
01626 if (this_multi->direction == -1) this_multi->masters.insert(this_multi->masters.begin(), master);
01627 } else {
01628 if (this_multi->direction == 1) master = *(this_multi->iter)++;
01629 if (this_multi->direction == -1) master = *--(this_multi->iter);
01630 }
01631
01632
01633 UAPAttribute* name_attrib = slave->getAttribute("name");
01634 string name = name_attrib->getValue();
01635 bool ok;
01636 string str_i = BU::int_to_string (this_multi->n_pass, ok);
01637 name = name + "|" + str_i;
01638 name_attrib->setValue(name);
01639
01640
01641 slave->add(MASTER, master);
01642 slave->addAttribute("slave_rank", "MULTIPASS_SLAVE");
01643 master->add(SLAVE, slave);
01644
01645 return;
01646
01647 }
01648
01649
01650
01651
01652 void AMLLatticeExpander::convert_to_actual (UAPNode* root) {
01653
01654
01655
01656 bool ok;
01657
01658 NodeVec children = root->getChildren();
01659 for (NodeVecIter ic = children.begin(); ic != children.end(); ic++) {
01660
01661 UAPNode* child = *ic;
01662 convert_to_actual (child);
01663 UAPAttribute* design = child->getAttribute("design");
01664 UAPAttribute* err = child->getAttribute("err");
01665 if (!design && !err) continue;
01666
01667 double d = 0;
01668 if (design) {
01669 d = BU::string_to_double(design->getValue(), ok);
01670 if (!ok) {
01671 info_out.error ("Bad design number for node: " + child->toString());
01672 continue;
01673 }
01674 }
01675
01676 double e = 0;
01677 if (err) {
01678 e = BU::string_to_double(err->getValue(), ok);
01679 if (!ok) {
01680 info_out.error ("Bad err number for node: " + child->toString());
01681 continue;
01682 }
01683 }
01684
01685 child->addAttribute("actual", BU::double_to_string(d+e, ok));
01686
01687 }
01688
01689 }
01690
01691
01692
01693
01694 void AMLLatticeExpander::calc_s_positions (UAPNode* tracking_root) {
01695
01696 NodeVec eles = tracking_root->getChildren();
01697 bool ok;
01698
01699
01700
01701 UAPNode* ele0 = *eles.begin();
01702 double s = 0;
01703 if (UAPNode* s_child = ele0->getChildByName("s"))
01704 s = BU::string_to_double(s_child->getAttributeString("actual"), ok);
01705 else
01706 ele0->addChild("s")->addAttribute("actual", "0");
01707
01708
01709
01710 for (NodeVecIter ie = ++eles.begin(); ie != eles.end(); ie++) {
01711 UAPNode* ele = *ie;
01712 double l = 0;
01713 if (UAPNode* l_child = ele->getChildByName("length"))
01714 l = BU::string_to_double(l_child->getAttributeString("actual"), ok);
01715 s = s + l;
01716 string s_str;
01717 if (UAPNode* s_node = ele->getChildByName("s"))
01718 s_node->addAttribute("actual", BU::double_to_string (s, ok));
01719 else
01720 ele->addChild("s")->addAttribute("actual", BU::double_to_string (s, ok));
01721 }
01722
01723 }
01724
01725
01726
01727
01728 void AMLLatticeExpander::apply_sets (string set_str, string value_str, UAPNode* aml_rep) {
01729
01730
01731
01732 tree_transverser (aml_rep);
01733 while (true) {
01734 UAPNode* set_node = tree_transverser();
01735
01736 if (!set_node) return;
01737 if (set_node->getName() != set_str) continue;
01738
01739 string full_attrib = set_node->getAttributeString("attribute");
01740 Twig twig;
01741 if (!twig.fromString(full_attrib)) {
01742 info_out.error ("Bad attribute: " + full_attrib, "Of " + set_node->toString());
01743 continue;
01744 }
01745
01746
01747
01748 if (!BU::found(all_map, twig.name)) {
01749 info_out.error ("Node not found: " + twig.name, "For " + set_node->toString());
01750 continue;
01751 }
01752 UAPNode* named_node = all_map[twig.name];
01753
01754 if (twig.target_attribute == "") twig.target_attribute = "design";
01755
01756 UAPNode* attrib_node = twig.getLocalSubNode(named_node, true);
01757 if (!attrib_node) {
01758 info_out.error ("Invalid attribute name: " + full_attrib,
01759 "For " + set_node->toString());
01760 continue;
01761 }
01762
01763 string value = set_node->getAttributeString(value_str);
01764 if (value == "") {
01765 info_out.error ("Set: " + set_node->toString(),
01766 "Does not have a \"" + value_str + "\" attribute");
01767 return;
01768 }
01769 attrib_node->addAttribute(twig.target_attribute, value);
01770
01771 }
01772
01773 }
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784 void AMLLatticeExpander::apply_post_sets (string set_str, string value_str,
01785 UAPNode* aml_rep, UAPNode* target_root) {
01786
01787
01788
01789 map<string, NodeVec> named_node_map;
01790 NodeVec named_node_list;
01791
01792 tree_transverser(target_root);
01793 while(true) {
01794 UAPNode* node = tree_transverser();
01795 if (!node) break;
01796 string name = node->getAttributeString("name");
01797 if (name == "") continue;
01798 named_node_list.push_back(node);
01799 if (BU::found(named_node_map, name)) {
01800 NodeVec node_list = named_node_map[name];
01801 node_list.push_back(node);
01802 named_node_map.erase(name);
01803 named_node_map[name] = node_list;
01804 } else {
01805 NodeVec node_list;
01806 node_list.push_back(node);
01807 named_node_map[name] = node_list;
01808 }
01809 }
01810
01811
01812
01813 tree_transverser (aml_rep);
01814 while (true) {
01815 UAPNode* set_node = tree_transverser();
01816
01817 if (!set_node) return;
01818 if (set_node->getName() != set_str) continue;
01819
01820
01821
01822 string full_attrib = set_node->getAttributeString("attribute");
01823 Twig twig;
01824 if (!twig.fromString(full_attrib)) {
01825 info_out.error ("Bad attribute: " + full_attrib, "Of " + set_node->toString());
01826 continue;
01827 }
01828
01829 if (twig.target_attribute == "") twig.target_attribute = "design";
01830
01831
01832
01833 bool found = false;
01834 NodeVec node_list;
01835
01836
01837 if (twig.name.find("*") != string::npos || twig.name.find("?") != string::npos)
01838 node_list = named_node_list;
01839 else
01840 node_list = named_node_map[twig.name];
01841
01842 for (NodeVecIter in = node_list.begin(); in != node_list.end(); in++) {
01843 UAPNode* named_node = *in;
01844
01845 if (!twig.matchNameAndPrefix(named_node)) continue;
01846
01847 UAPNode* attrib_node = twig.getLocalSubNode(named_node, true);
01848 if (!attrib_node) {
01849 info_out.error ("Invalid attribute name: " + full_attrib,
01850 "For " + set_node->toString());
01851 continue;
01852 }
01853
01854 string value = set_node->getAttributeString(value_str);
01855 if (value == "") {
01856 info_out.error ("<" + set_str + "> does not have a \"" + value_str + "\" attribute",
01857 set_node->toString());
01858 return;
01859 }
01860 attrib_node->addAttribute(twig.target_attribute, value);
01861 found = true;
01862 }
01863
01864 if (!found) info_out.error ("No node found to set for " + set_node->toString());
01865
01866 }
01867
01868 }
01869
01870
01871
01872
01873 UAPNode* AMLLatticeExpander::tree_transverser (UAPNode* root) {
01874
01875
01876
01877 if (root) {
01878 iter_list.clear();
01879 parents.clear();
01880 parents.insert(parents.begin(), root);
01881 return root;
01882 }
01883
01884
01885
01886 UAPNode* current_node = parents.front();
01887 NodeVec& children = current_node->getChildren();
01888 if (children.size() > 0) {
01889 current_node = children.front();
01890 parents.insert(parents.begin(), current_node);
01891 iter_list.push_front(children.begin());
01892 return current_node;
01893 }
01894
01895
01896
01897
01898 while (true) {
01899 if (iter_list.size() == 0) return NULL;
01900 UAPNode* current_node = parents.front();
01901 NodeVec& children = current_node->getParent()->getChildren();
01902 NodeVecIter& iter = iter_list.front();
01903 iter++;
01904
01905 if (iter == children.end()) {
01906 parents.erase(parents.begin());
01907 iter_list.pop_front();
01908 continue;
01909
01910 } else {
01911 current_node = *iter;
01912 parents.front() = current_node;
01913 return current_node;
01914 }
01915 }
01916
01917 }