BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
parser.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "parser.h"
20
21#include <algorithm>
22#include <cmath>
23#include <iostream>
24#include <list>
25#include <set>
26#include <string>
27#include <vector>
28
29// for getpwuid: http://linux.die.net/man/3/getpwuid
30#include <unistd.h>
31#include <sys/types.h>
32#include <pwd.h>
33
34#include "array.h"
35#include "sym_table.h"
36
37namespace {
38 // helper method
39 // replace algorithm of all substring instances
40 // from http://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string
41 void replaceAll(std::string& source, const std::string& from, const std::string& to)
42 {
43 std::string newString;
44 newString.reserve( source.length() ); // avoids a few memory allocations
45
46 std::string::size_type lastPos = 0;
47 std::string::size_type findPos;
48
49 while( std::string::npos != ( findPos = source.find( from, lastPos )))
50 {
51 newString.append( source, lastPos, findPos - lastPos );
52 newString += to;
53 lastPos = findPos + from.length();
54 }
55
56 // Care for the rest after last occurrence
57 newString += source.substr( lastPos );
58
59 source.swap( newString );
60 }
61}
62
63namespace GMAD {
64 // Explicitly make the templates we need here
65 template void Parser::Add<ScorerMesh, FastList<ScorerMesh> >(bool unique, const std::string& className);
66 template void Parser::Add<CavityModel, FastList<CavityModel> >(bool unique, const std::string& className);
67 template void Parser::Add<BLMPlacement, FastList<BLMPlacement> >(bool unique, const std::string& className);
68 template void Parser::Add<Modulator, FastList<Modulator> >(bool unique, const std::string& className);
69 template void Parser::Add<SamplerPlacement, FastList<SamplerPlacement> >(bool unique, const std::string& className);
70 template void Parser::Add<Atom, FastList<Atom> >(bool unique, const std::string& className);
71 template void Parser::Add<Field, FastList<Field> >(bool unique, const std::string& className);
72 template void Parser::Add<Query, FastList<Query> >(bool unique, const std::string& className);
73 template void Parser::Add<Region, FastList<Region> >(bool unique, const std::string& className);
74 template void Parser::Add<Scorer, FastList<Scorer> >(bool unique, const std::string& className);
75 template void Parser::Add<Tunnel, FastList<Tunnel> >(bool unique, const std::string& className);
76 template void Parser::Add<Crystal, FastList<Crystal> >(bool unique, const std::string& className);
77 template void Parser::Add<Aperture, FastList<Aperture> >(bool unique, const std::string& className);
78 template void Parser::Add<Material, FastList<Material> >(bool unique, const std::string& className);
79 template void Parser::Add<NewColour, FastList<NewColour> >(bool unique, const std::string& className);
80 template void Parser::Add<PhysicsBiasing, FastList<PhysicsBiasing> >(bool unique, const std::string& className);
81}
82
83using namespace GMAD;
84
85namespace GMAD {
86 extern std::string yyfilename;
87}
88
89extern int yyparse();
90extern FILE *yyin;
91
92Parser* Parser::instance = nullptr;
93
95{
96 if (!instance)
97 {
98 std::cerr << "Parser has not been initialized!" << std::endl;
99 exit(1);
100 }
101 return instance;
102}
103
104Parser* Parser::Instance(const std::string& name)
105{
106 if(instance)
107 {
108 std::cerr << "Warning parser was already initialized!" << std::endl;
109 delete instance;
110 }
111 instance = new Parser(name);
112 return instance;
113}
114
116{
117 beamline_list.erase();
118 // delete allocated lines
119 for (auto element : allocated_lines)
120 {delete element;}
121
122 instance = nullptr;
123}
124
125Parser::Parser(std::string name)
126{
127 instance = this;
128#ifdef BDSDEBUG
129 std::cout << "gmad_parser> opening file" << std::endl;
130#endif
131 // replace all ~ symbols with home directory to allow for that
132 // note $HOME is not necessarily equivalent to ~
133 // see http://linux.die.net/man/3/getpwuid
134 std::string tilde("~");
135 std::string home(getpwuid(getuid())->pw_dir);
136
137 replaceAll(name,tilde,home);
138
139 FILE *f = fopen(name.c_str(),"r");
140
141 if(f==nullptr)
142 {
143 std::cerr << "gmad_parser> Can't open input file " << name << std::endl;
144 exit(1);
145 }
146 // set global string for parser
147 yyfilename = std::string(name);
148
149 Initialise();
150
151 std::cout.precision(10); // set output precision to 10 decimals
152
153 ParseFile(f);
154}
155
156void Parser::ParseFile(FILE *f)
157{
158 yyin=f;
159
160#ifdef BDSDEBUG
161 std::cout << "gmad_parser> beginning to parse file" << std::endl;
162#endif
163
164 while(!feof(yyin))
165 {yyparse();}
166
168#ifdef BDSDEBUG
169 std::cout << "gmad_parser> finished to parsing file" << std::endl;
170#endif
171 // clear temporary stuff
172#ifdef BDSDEBUG
173 std::cout << "gmad_parser> clearing temporary lists" << std::endl;
174#endif
175 element_list.clear();
176 tmp_list.clear();
178 for(auto it : var_list)
179 {delete it;}
180
181#ifdef BDSDEBUG
182 std::cout << "gmad_parser> finished" << std::endl;
183#endif
184
185 fclose(f);
186}
187
189{
190 const int reserved = 1;
191 // embedded arithmetical functions
192 add_func("sqrt",std::sqrt);
193 add_func("cos",std::cos);
194 add_func("sin",std::sin);
195 add_func("exp",std::exp);
196 add_func("log",std::log);
197 add_func("tan",std::tan);
198 add_func("asin",std::asin);
199 add_func("acos",std::acos);
200 add_func("atan",std::atan);
201 add_func("abs",std::abs);
202
203 add_var("pi", 4.0*std::atan(1),reserved);
204 add_var("twopi", 8.0*std::atan(1),reserved);
205 add_var("halfpi", 2.0*std::atan(1),reserved);
206
207 add_var("PeV",1e6, reserved);
208 add_var("TeV",1e3, reserved);
209 add_var("GeV",1.0 ,reserved);
210 add_var("MeV",1e-3,reserved);
211 add_var("keV",1e-6,reserved);
212 add_var("KeV",1e-6,reserved); // for compatibility
213 add_var("eV" ,1e-9,reserved);
214
215 add_var("PJ", 1e12, reserved);
216 add_var("GJ", 1e9, reserved);
217 add_var("MJ", 1e6, reserved);
218 add_var("kJ", 1e3, reserved);
219 add_var("J", 1, reserved);
220 add_var("mJ", 1e-3, reserved);
221 add_var("uJ", 1e-6, reserved);
222 add_var("nJ", 1e-9, reserved);
223 add_var("pJ", 1e-12, reserved);
224
225 add_var("mV",1e-3,reserved);
226 add_var("V" ,1.0, reserved);
227 add_var("kV",1e+3,reserved);
228 add_var("MV",1e+6,reserved);
229 add_var("GV",1e+9,reserved);
230
231 add_var("Tesla",1.0,reserved);
232 add_var("T", 1.0,reserved);
233
234 add_var("km" ,1e3 ,reserved);
235 add_var("m" ,1.0 ,reserved);
236 add_var("cm" ,1e-2,reserved);
237 add_var("mm" ,1e-3,reserved);
238 add_var("um" ,1e-6,reserved);
239 add_var("mum",1e-6,reserved);
240 add_var("nm" ,1e-9,reserved);
241 add_var("ang",1e-10,reserved);
242 add_var("pm" ,1e-12,reserved);
243
244 add_var("s" ,1.0 ,reserved);
245 add_var("ms" ,1.e-3,reserved);
246 add_var("us" ,1.e-6,reserved);
247 add_var("ns" ,1.e-9,reserved);
248 add_var("ps" ,1.e-12,reserved);
249
250 add_var("Hz" ,1.0, reserved);
251 add_var("kHz",1e+3, reserved);
252 add_var("MHz",1e+6, reserved);
253 add_var("GHz",1e+9, reserved);
254 add_var("THz",1e+12,reserved);
255
256 add_var("rad" ,1.0, reserved);
257 add_var("mrad",1e-3,reserved);
258 add_var("urad",1e-6,reserved);
259 add_var("nrad",1e-9,reserved);
260
261 add_var("degrees",std::atan(1)/45,reserved);
262
263 add_var("clight",2.99792458e+8,reserved);
264
265 params.flush();
266}
267
269{
270 std::cout << "parsing complete..." << std::endl;
271 exit(0);
272}
273
274void Parser::write_table(std::string* name, ElementType type, bool isLine)
275{
276 Element e;
277 e.set(params,*name,type);
278 if (isLine)
279 {
280 e.lst = new std::list<Element>(tmp_list);
281 allocated_lines.push_back(e.lst);
282 // clean list
283 tmp_list.clear();
284 sequences.push_back(*name); // append to all sequence definitions
285 }
286
287 // insert element with uniqueness requirement
288 element_list.push_back(e,true);
289}
290
292{
293 for (const auto& name : sequences)
294 {
295 FastList<Element>* newLine = new FastList<Element>();
296 expand_line(*newLine, name);
297 expandedSequences[name] = newLine;
298 }
299}
300
301void Parser::expand_line(const std::string& name,
302 const std::string& start,
303 const std::string& end)
304{
305 expand_line(beamline_list, name, start, end);
306}
307
309 const std::string& name,
310 const std::string& start,
311 const std::string& end)
312{
313 const Element& line = find_element(name);
314 if(line.type != ElementType::_LINE && line.type != ElementType::_REV_LINE )
315 {
316 std::cerr << "Error with use command: \"" << name << "\" is not a line" << std::endl;
317 exit(1);
318 }
319
320 // delete the previous beamline
321 target.clear();
322
323 // expand the desired beamline
324 Element e;
325 e.type = line.type;
326 e.name = name;
327 e.l = 0;
328 e.lst = nullptr;
329
330 target.push_back(e);
331
332#ifdef BDSDEBUG
333 std::cout << "expanding line " << name << ", range = " << start << end << std::endl;
334#endif
335 if (!line.lst)
336 {return;} //list empty
337
338 // first expand the whole range
339 std::list<Element>::iterator sit = line.lst->begin();
340 std::list<Element>::iterator eit = line.lst->end();
341
342 // copy the list into the resulting list
343 switch(line.type)
344 {
345 case ElementType::_LINE:
346 {target.insert(target.end(),sit,eit); break;}
347 case ElementType::_REV_LINE:
348 {target.insert(target.end(),line.lst->rbegin(),line.lst->rend()); break;}
349 default:
350 {target.insert(target.end(),sit,eit); break;}
351 }
352 // bool to check if beamline is fully expanded
353 bool is_expanded = false;
354
355 // parse starting from the second element until the list is expanded
356 int iteration = 0;
357 while (!is_expanded)
358 {
359 is_expanded = true;
360 // start at second element
361 std::list<Element>::iterator it = ++target.begin();
362 for (; it!=target.end(); ++it)
363 {
364 Element& element = *it; // alias
365 const ElementType& type = element.type;
366#ifdef BDSDEBUG
367 std::cout << element.name << " , " << type << std::endl;
368#endif
369 // if list - expand further
370 if (type != ElementType::_LINE && type != ElementType::_REV_LINE)
371 {continue;}
372 is_expanded = false;
373 // lookup the line in main list
374 std::list<Element>::const_iterator tmpit = element_list.find(element.name);
375 std::list<Element>::const_iterator iterEnd = element_list.end();
376 if ( (tmpit != iterEnd) && ( (*tmpit).lst != nullptr) )
377 { // sublist found and not empty
378 const Element& list = *tmpit; // alias
379#ifdef BDSDEBUG
380 std::cout << "inserting sequence for " << element.name << " - " << list.name << " ...";
381#endif
382 if (type == ElementType::_LINE)
383 {target.insert(it,list.lst->begin(),list.lst->end());}
384 else if (type == ElementType::_REV_LINE)
385 {
386 //iterate over list and invert any sublines contained within. SPM
387 std::list<Element> tmpList;
388 tmpList.insert(tmpList.end(),list.lst->begin(),list.lst->end());
389 for (std::list<Element>::iterator itLineInverter = tmpList.begin();
390 itLineInverter != tmpList.end(); ++itLineInverter)
391 {
392 if ( (*itLineInverter).type == ElementType::_LINE)
393 {(*itLineInverter).type = ElementType::_REV_LINE;}
394 else if ((*itLineInverter).type == ElementType::_REV_LINE)
395 {(*itLineInverter).type = ElementType::_LINE;}
396 }
397 target.insert(it,tmpList.rbegin(),tmpList.rend());
398 }
399#ifdef BDSDEBUG
400 std::cout << "inserted" << std::endl;
401#endif
402 // delete the list pointer
403 target.erase(it--);
404 }
405 else if ( tmpit != iterEnd )
406 { // entry points to a scalar element type -
407 //transfer properties from the main list
408#ifdef BDSDEBUG
409 std::cout << "keeping element..." << element.name << std::endl;
410#endif
411 // copy properties
412 element = (*tmpit);
413
414#ifdef BDSDEBUG
415 std::cout << "done" << std::endl;
416#endif
417 }
418 else
419 { // element of undefined type
420 std::cerr << "Error : Expanding line \"" << name << "\" : element \"" << element.name
421 << "\" has not been defined! " << std::endl;
422 exit(1);
423 }
424 }
425 iteration++;
426 if ( iteration > MAX_EXPAND_ITERATIONS )
427 {
428 std::cerr << "Error : Line expansion of '" << name << "' seems to loop, " << std::endl
429 << "possible recursive line definition, quitting" << std::endl;
430 exit(1);
431 }
432 }// while
433
434 // leave only the desired range
435 //
436 // rule - from first occurrence of 'start' till first 'end' coming after 'start'
437
438 if ( !start.empty()) // determine the start element
439 {
440 std::list<Element>::const_iterator startIt = target.find(std::string(start));
441
442 if(startIt!=target.end())
443 {target.erase(target.begin(),startIt);}
444 }
445
446 if ( !end.empty()) // determine the end element
447 {
448 std::list<Element>::const_iterator endIt = target.find(std::string(end));
449
450 if(endIt!=target.end())
451 {target.erase(++endIt,target.end());}
452 }
453
454 // insert the tunnel if present
455
456 std::list<Element>::iterator itTunnel = element_list.find("tunnel");
457 if (itTunnel!=element_list.end())
458 {target.push_back(*itTunnel);}
459}
460
461const FastList<Element>& Parser::get_sequence(const std::string& name)
462{
463 // search for previously queried beamlines
464 const auto search = expandedSequences.find(name);
465 if (search != expandedSequences.end())
466 {return *(search->second);}
467 else
468 {std::cerr << "parser> no such sequence \"" << name << "\"" << std::endl; exit(1);}
469}
470
471void Parser::set_sampler(const std::string& name,
472 int count,
473 ElementType type,
474 const std::string& samplerType,
475 double samplerRadius,
476 int particleSetID)
477{
478 // if count equal to -2 add to all elements regardless of name
479 // typically used for output elements like samplers
480 // skip first element and add one at the end
481 if (count == -2)
482 {
483 for (auto it = beamline_list.begin(); it != beamline_list.end(); ++it)
484 {// skip LINEs
485 if((*it).type == ElementType::_LINE || (*it).type == ElementType::_REV_LINE)
486 {continue;}
487 // if type not equal to NONE and elements have to match type
488 if (type != ElementType::_NONE && type != (*it).type)
489 {continue;}
490
491 (*it).setSamplerInfo(samplerType,(*it).name,samplerRadius,particleSetID);
492 }
493 }
494 else if (count == -1) // if count equal to -1 add sampler to all element instances
495 {
496 auto itPair = beamline_list.equal_range(name);
497 if (itPair.first == itPair.second)
498 {
499 std::string msg = "parser> SetSampler> current beamline doesn't contain element \"" + name + "\"";
500 yyerror2(msg.c_str());
501 }
502 for (auto it = itPair.first; it != itPair.second; ++it)
503 {
504 // if sampler is attached to a marker, really attach it to the previous element with the name of marker
505 auto elementIt = (it->second);
506 std::string samplerName = elementIt->name;
507 if ((*elementIt).type == ElementType::_MARKER)
508 {
509 // need to find real element before
510 // but careful not to go beyond first element also!
511 while ((*elementIt).isSpecial())
512 {
513 elementIt--;
514 // have to break first before continue since in while loop
515 if (elementIt == beamline_list.begin())
516 {break;}
517 }
518
519 if (elementIt==beamline_list.begin())
520 {
521 std::cout << "parser> SetSampler> WARNING: no element before marker " << name << ", no sampler added" << std::endl;
522 continue;
523 }
524 }
525 (*elementIt).setSamplerInfo(samplerType,samplerName,samplerRadius,particleSetID);
526 }
527 }
528 else
529 {
530 auto it = beamline_list.find(name,count);
531 if (it==beamline_list.end())
532 {
533 std::string msg = "parser> SetSampler> current beamline doesn't contain element \"" + name + "\" with number " + std::to_string(count);
534 yyerror2(msg.c_str());
535 }
536 // if sampler is attached to a marker, really attach it to the previous element with the name of marker
537 std::string samplerName = (*it).name;
538 if ((*it).type == ElementType::_MARKER)
539 {
540 // need to find real element before
541 // but careful not to go beyond first element also!
542 while ((*it).isSpecial())
543 {
544 it--;
545 if (it == beamline_list.begin())
546 {
547 std::cout << "parser> SetSampler> WARNING: no element before marker " << name << ", no sampler added" << std::endl;
548 return;
549 }
550 }
551 }
552 (*it).setSamplerInfo(samplerType,samplerName,samplerRadius,particleSetID);
553 }
554}
555
556int Parser::add_sampler_partIDSet(std::list<int>* samplerPartIDListIn)
557{
558 if (!samplerPartIDListIn)
559 {return -1;}
560 std::set<int> partIDs = std::set<int>(std::begin(*samplerPartIDListIn), std::end(*samplerPartIDListIn));
561 auto alreadyExists = samplerFilters.count(partIDs);
562 if (alreadyExists > 0)
563 {return setToSamplerFilterID[partIDs];}
564 else
565 {
566 int particleSetID = (int) samplerFilterIDToSet.size();
567 samplerFilterIDToSet[particleSetID] = partIDs;
568 setToSamplerFilterID[partIDs] = particleSetID;
569 samplerFilters.insert(partIDs);
570 return particleSetID;
571 }
572}
573
574void Parser::add_sampler(const std::string& name, int count, ElementType type, std::string samplerType, std::list<int>* samplerPartIDListIn)
575{
576#ifdef BDSDEBUG
577 std::cout << "inserting sampler " << name;
578 if (count>=0)
579 {std::cout << "[" << count << "]";}
580 std::cout << std::endl;
581#endif
582 int particleSetID = add_sampler_partIDSet(samplerPartIDListIn);
583 set_sampler(name,count,type,samplerType,0,particleSetID);
584}
585
586Element& Parser::find_element(const std::string& element_name)
587{
588 std::list<Element>::iterator it = element_list.find(element_name);
589 std::list<Element>::const_iterator iterEnd = element_list.end();
590
591 if(it == iterEnd)
592 {
593 std::cerr << "parser.h> Error: element (type) \"" << element_name
594 << "\" has not been defined." << std::endl;
595 exit(1);
596 }
597 return (*it);
598}
599
600const Element& Parser::find_element(const std::string& element_name)const
601{
602 auto search = element_list.find(element_name);
603 if (search == element_list.end())
604 {
605 std::cerr << "parser.h> Error: unknown element \"" << element_name << "\"." << std::endl;
606 exit(1);
607 }
608 return (*search);
609}
610
611const Element* Parser::find_placement_element_safe(const std::string& element_name) const
612{
613 const Element* result = nullptr;
614 auto search = placement_elements.find(element_name);
615 if (search != placement_elements.end())
616 {
617 const GMAD::Element& ele = *search;
618 result = &ele;
619 }
620 return result;
621}
622
623const Element* Parser::find_element_safe(const std::string& element_name) const
624{
625 const Element* result = nullptr;
626 auto search = element_list.find(element_name);
627 if (search != element_list.end())
628 {
629 const GMAD::Element& ele = *search;
630 result = &ele;
631 }
632 return result;
633}
634
635double Parser::property_lookup(const std::string& element_name, const std::string& property_name)const
636{
637 const Element& element = find_element(element_name);
638 return element.property_lookup(property_name);
639}
640
641void Parser::add_element_temp(const std::string& name, int number, bool pushfront, ElementType linetype)
642{
643#ifdef BDSDEBUG
644 std::cout << "matched sequence element, " << name;
645 if (number > 1)
646 {std::cout << " * " << number;}
647 std::cout << std::endl;
648#endif
649 // add to temporary element sequence
650 Element e;
651 e.name = name;
652 e.type = linetype;
653 e.lst = nullptr;
654 if (pushfront)
655 {
656 for (int i = 0; i < number; i++)
657 {tmp_list.push_front(e);}
658 }
659 else
660 {
661 for (int i = 0; i < number; i++)
662 {tmp_list.push_back(e);}
663 }
664}
665
666int Parser::copy_element_to_params(const std::string& elementName)
667{
668 int type;
669#ifdef BDSDEBUG
670 std::cout << "newinstance : VARIABLE -- " << elementName << std::endl;
671#endif
672 const Element& element = find_element(elementName);
673
674 // inherit properties from the base type
675 type = static_cast<int>(element.type);
676 params.inherit_properties(element);
677
678 return type;
679}
680
681void Parser::add_func(std::string name, double (*func)(double))
682{
683 Symtab *sp=symtab_map.symcreate(name);
684 sp->Set(func);
685}
686
687void Parser::add_var(std::string name, double value, int is_reserved)
688{
689 Symtab* sp = symtab_map.symcreate(name);
690 sp->Set(value,is_reserved);
691}
692
693bool Parser::InvalidSymbolName(const std::string& s, std::string& errorReason)
694{
695 bool result = false;
696 if (options.NameExists(s))
697 {result = true; errorReason = "The variable name \"" + s + "\" is an option name and cannot be used as a variable name";}
698 return result;
699}
700
701Symtab * Parser::symcreate(const std::string& s)
702{
703 return symtab_map.symcreate(s);
704}
705
706Symtab * Parser::symlook(const std::string& s)
707{
708 return symtab_map.symlook(s);
709}
710void Parser::Store(double value)
711{
712 tmparray.push_front(value);
713}
714
715void Parser::Store(const std::string& name)
716{
717 tmpstring.push_front(name);
718}
719
721{
722 array->Copy(tmparray);
723 tmparray.clear();
724}
725
727{
728 array->Copy(tmpstring);
729 tmpstring.clear();
730}
731
733{
734 params.flush();
735 samplerFilters.clear();
736}
737
738void Parser::Overwrite(const std::string& objectName)
739{
740 // find object and set values
741
742 // possible object types are:
743 // element, atom, colour, crystal, field, material, physicsbiasing, placement,
744 // query, region, tunnel, cavitymodel, samplerplacement, aperture, scorer, scorermesh, blm
745 bool extended = false;
746 auto element_it = element_list.find(objectName);
747 if (element_it != element_list.end())
748 {
749 ExtendObject(*element_it);
750 extended = true;
751 }
752 else
753 {
754 auto it = xsecbias_list.find(objectName);
755 if (it != xsecbias_list.end() )
756 {
757 ExtendObject(*it);
758 extended = true;
759 }
760 }
761 // vectors
762 if (!extended) {
763 if ( (extended = FindAndExtend<Atom> (objectName)) ) {}
764 else if ( (extended = FindAndExtend<NewColour> (objectName)) ) {}
765 else if ( (extended = FindAndExtend<Crystal> (objectName)) ) {}
766 else if ( (extended = FindAndExtend<Field> (objectName)) ) {}
767 else if ( (extended = FindAndExtend<Material> (objectName)) ) {}
768 else if ( (extended = FindAndExtend<Placement> (objectName)) ) {}
769 else if ( (extended = FindAndExtend<Query> (objectName)) ) {}
770 else if ( (extended = FindAndExtend<Region> (objectName)) ) {}
771 else if ( (extended = FindAndExtend<Tunnel> (objectName)) ) {}
772 else if ( (extended = FindAndExtend<CavityModel>(objectName)) ) {}
773 else if ( (extended = FindAndExtend<SamplerPlacement>(objectName)) ) {}
774 else if ( (extended = FindAndExtend<Scorer> (objectName)) ) {}
775 else if ( (extended = FindAndExtend<ScorerMesh> (objectName)) ) {}
776 else if ( (extended = FindAndExtend<Aperture> (objectName)) ) {}
777 else if ( (extended = FindAndExtend<BLMPlacement> (objectName)) ) {}
778 else if ( (extended = FindAndExtend<Modulator> (objectName)) ) {}
779 }
780
781 if (!extended)
782 {
783 std::cerr << "parser.h> Error: object \"" << objectName
784 << "\" has not been defined and can't be extended." << std::endl;
785 exit(1);
786 }
787
788 // clear maps
789 extendedNumbers.clear();
790 extendedStrings.clear();
791 extendedVectors.clear();
792}
793
794template <class C>
795bool Parser::FindAndExtend(const std::string& objectName)
796{
797 GMAD::FastList<C>& fl = GetList<C>();
798 auto search = fl.find(objectName);
799 if (search != fl.end())
800 {
801 ExtendObject(*search);
802 return true;
803 }
804 return false;
805}
806
807template<class C>
808void Parser::ExtendObject(C& object)
809{
810 for (auto& option : extendedNumbers)
811 {object.set_value(option.first, option.second);}
812 for (auto& option : extendedStrings)
813 {object.set_value(option.first, option.second);}
814 for (auto& option : extendedVectors)
815 {object.set_value(option.first, option.second);}
816}
817
818void Parser::AddVariable(std::string* name)
819{
820 var_list.push_back(name);
821}
822
824{
825 beamline_list.print();
826}
827
829{
830 element_list.print();
831}
832
834{
835 options.print();
836}
837
838bool Parser::TryPrintingObject(const std::string& objectName) const
839{
840 // We just don't know the type of the object, only the name, so we must
841 // search each member vector. Try to optimise by returning once done.
842 // This is a cpu-heavy solution vs a memory-heavy one that would have to
843 // keep a duplicate copy of all objects for printing.
844
845 const std::string& on = objectName; // shortcut
846
847 // we use a lambda to compare against obj.name instead of obj itself
848 auto searchAtom = std::find_if(atom_list.begin(), atom_list.end(), [&on](const Atom& obj) {return obj.name == on;});
849 if (searchAtom != atom_list.end())
850 {searchAtom->print(); return true;}
851 auto searchNewColour = std::find_if(colour_list.begin(), colour_list.end(), [&on](const NewColour& obj) {return obj.name == on;});
852 if (searchNewColour != colour_list.end())
853 {searchNewColour->print(); return true;}
854 auto searchCrystal = std::find_if(crystal_list.begin(), crystal_list.end(), [&on](const Crystal& obj) {return obj.name == on;});
855 if (searchCrystal != crystal_list.end())
856 {searchCrystal->print(); return true;}
857 auto searchField = std::find_if(field_list.begin(), field_list.end(), [&on](const Field& obj) {return obj.name == on;});
858 if (searchField != field_list.end())
859 {searchField->print(); return true;}
860 auto searchMaterial = std::find_if(material_list.begin(), material_list.end(), [&on](const Material& obj) {return obj.name == on;});
861 if (searchMaterial != material_list.end())
862 {searchMaterial->print(); return true;}
863 auto searchQuery = std::find_if(query_list.begin(), query_list.end(), [&on](const Query& obj) {return obj.name == on;});
864 if (searchQuery != query_list.end())
865 {searchQuery->print(); return true;}
866 auto searchRegion = std::find_if(region_list.begin(), region_list.end(), [&on](const Region& obj) {return obj.name == on;});
867 if (searchRegion != region_list.end())
868 {searchRegion->print(); return true;}
869 auto searchTunnel = std::find_if(tunnel_list.begin(), tunnel_list.end(), [&on](const Tunnel& obj) {return obj.name == on;});
870 if (searchTunnel != tunnel_list.end())
871 {searchTunnel->print(); return true;}
872 auto searchXsecbias = std::find_if(xsecbias_list.begin(), xsecbias_list.end(), [&on](const PhysicsBiasing& obj) {return obj.name == on;});
873 if (searchXsecbias != xsecbias_list.end())
874 {searchXsecbias->print(); return true;}
875 auto searchPlacement = std::find_if(placement_list.begin(), placement_list.end(), [&on](const Placement& obj) {return obj.name == on;});
876 if (searchPlacement != placement_list.end())
877 {searchPlacement->print(); return true;}
878 auto searchCavityModel = std::find_if(cavitymodel_list.begin(), cavitymodel_list.end(), [&on](const CavityModel& obj) {return obj.name == on;});
879 if (searchCavityModel != cavitymodel_list.end())
880 {searchCavityModel->print(); return true;}
881 auto searchSamplerPlacement = std::find_if(samplerplacement_list.begin(), samplerplacement_list.end(), [&on](const SamplerPlacement& obj) {return obj.name == on;});
882 if (searchSamplerPlacement != samplerplacement_list.end())
883 {searchSamplerPlacement->print(); return true;}
884 auto searchScorer = std::find_if(scorer_list.begin(), scorer_list.end(), [&on](const Scorer& obj) {return obj.name == on;});
885 if (searchScorer != scorer_list.end())
886 {searchScorer->print(); return true;}
887 auto searchScorerMesh = std::find_if(scorermesh_list.begin(), scorermesh_list.end(), [&on](const ScorerMesh& obj) {return obj.name == on;});
888 if (searchScorerMesh != scorermesh_list.end())
889 {searchScorerMesh->print(); return true;}
890 auto searchAperture = std::find_if(aperture_list.begin(), aperture_list.end(), [&on](const Aperture& obj) {return obj.name == on;});
891 if (searchAperture != aperture_list.end())
892 {searchAperture->print(); return true;}
893 auto searchBLMPlacement = std::find_if(blm_list.begin(), blm_list.end(), [&on](const BLMPlacement& obj) {return obj.name == on;});
894 if (searchBLMPlacement != blm_list.end())
895 {searchBLMPlacement->print(); return true;}
896 auto searchModulator = std::find_if(modulator_list.begin(), modulator_list.end(), [&on](const Modulator& obj) {return obj.name == on;});
897 if (searchModulator != modulator_list.end())
898 {searchModulator->print(); return true;}
899
900 return false;
901}
902
904{
905 return beamline_list;
906}
907
908//template specialisation
909// put explicitly in namespace since g++ complains
910namespace GMAD {
911 template<>
912 Beam& Parser::GetGlobal(){return beam;}
913
914 template<>
916
917 template<>
919
920 template<>
922
923 template<>
924 FastList<Region>& Parser::GetList<Region>(){return region_list;}
925
926 template<>
928
929 template<>
930 FastList<NewColour>& Parser::GetList<NewColour>(){return colour_list;}
931
932 template<>
934
935 template<>
936 FastList<Crystal>& Parser::GetList<Crystal>(){return crystal_list;}
937
938 template<>
939 Field& Parser::GetGlobal(){return field;}
940
941 template<>
942 FastList<Field>& Parser::GetList<Field>(){return field_list;}
943
944 template<>
945 Query& Parser::GetGlobal(){return query;}
946
947 template<>
948 FastList<Query>& Parser::GetList<Query>(){return query_list;}
949
950 template<>
951 Atom& Parser::GetGlobal(){return atom;}
952
953 template<>
954 FastList<Atom>& Parser::GetList<Atom>(){return atom_list;}
955
956 template<>
958
959 template<>
960 FastList<Material>& Parser::GetList<Material>(){return material_list;}
961
962 template<>
964
965 template<>
966 FastList<Tunnel>& Parser::GetList<Tunnel>(){return tunnel_list;}
967
968 template<>
970
971 template<>
972 FastList<CavityModel>& Parser::GetList<CavityModel>(){return cavitymodel_list;}
973
974 template<>
976
977 template<>
978 FastList<Scorer>& Parser::GetList<Scorer>() {return scorer_list;}
979
980 template<>
982
983 template<>
984 FastList<ScorerMesh>& Parser::GetList<ScorerMesh>() {return scorermesh_list;}
985
986 template<>
988
989 template<>
990 FastList<Placement>& Parser::GetList<Placement>(){return placement_list;}
991
992 template<>
994
995 template<>
996 FastList<PhysicsBiasing>& Parser::GetList<PhysicsBiasing, FastList<PhysicsBiasing>>(){return xsecbias_list;}
997
998 template<>
1000
1001 template<>
1002 FastList<SamplerPlacement>& Parser::GetList<SamplerPlacement>() {return samplerplacement_list;}
1003
1004 template<>
1006
1007 template<>
1008 FastList<BLMPlacement>& Parser::GetList<BLMPlacement>() {return blm_list;}
1009
1010 template<>
1012
1013 template<>
1014 FastList<Modulator>& Parser::GetList<Modulator>() {return modulator_list;}
1015
1016 template<>
1018
1019 template<>
1020 FastList<Aperture>& Parser::GetList<Aperture>() {return aperture_list;}
1021
1022 template<>
1023 void Parser::ExtendValue(const std::string& property, double value)
1024 {extendedNumbers[property]=value;}
1025
1026 template<>
1027 void Parser::ExtendValue(const std::string& property, std::string value)
1028 {extendedStrings[property]=value;}
1029
1030 template<>
1031 void Parser::ExtendValue(const std::string& property, Array* value)
1032 {extendedVectors[property]=value;}
1033
1034 template <class C, class Container>
1036 {
1037 // copy from global
1038 C& global = GetGlobal<C>();
1039 C inst(global);
1040 // reset global
1041 global.clear();
1042#ifdef BDSDEBUG
1043 inst.print();
1044#endif
1045 GetList<C, Container>().push_back(inst);
1046 }
1047
1048 template <class C, class Container>
1049 void Parser::Add(bool unique, const std::string& className)
1050 {
1051 // copy from global
1052 C& global = GetGlobal<C>();
1053 C inst(global);
1054 // reset global
1055 global.clear();
1056#ifdef BDSDEBUG
1057 inst.print();
1058#endif
1059 GetList<C, Container>().push_back(inst, unique, className);
1060 }
1061
1068 template <>
1069 void Parser::Add<Placement, FastList<Placement>>(bool unique, const std::string& className)
1070 {
1071 // copy from global
1072 Placement& global = GetGlobal<Placement>();
1073 Placement inst(global);
1074 // reset global
1075 global.clear();
1076#ifdef BDSDEBUG
1077 inst.print();
1078#endif
1079 GetList<Placement, FastList<Placement>>().push_back(inst, unique, className);
1080 // if an element definition is used for a placement, keep a separate copy of it
1081 if (!inst.bdsimElement.empty())
1082 {
1083 const Element* elDef = find_element_safe(inst.bdsimElement);
1084 if (!elDef)
1085 {
1086 std::cerr << "The bdsimElement referred to in \"" << inst.name << "\" (\""
1087 << inst.bdsimElement << "\") cannot be found and should be defined"
1088 << " before this placement" << std::endl;
1089 exit(1);
1090 }
1091 placement_elements.push_back(Element(*elDef));
1092 }
1093 }
1094}
Aperture class.
Definition: aperture.h:38
Representation of arrays used in tokens.
Definition: array.h:40
void Copy(Container< std::string, std::allocator< std::string > > &cpy)
Copy STL string containers into symbols.
Definition: array.h:86
blm for parser.
Definition: blmplacement.h:39
Beam class.
Definition: beam.h:44
RF CavityModel class for parser.
Definition: cavitymodel.h:35
Crystal class for parser.
Definition: crystal.h:37
List with Efficient Lookup.
Definition: fastlist.h:42
FastListIterator begin()
Definition: fastlist.h:215
FastListIterator insert(FastListInputIterator position, const T &val)
template definitions need to be in header
Definition: fastlist.h:115
FastListIterator end()
Definition: fastlist.h:220
void clear()
empty lists
Definition: fastlist.h:169
void erase()
erase elements
Definition: fastlist.h:175
void push_back(const T &el, bool unique=false, const std::string &objectName="element")
Definition: fastlist.h:152
FastListConstIterator find(std::string name, unsigned int count=1) const
Definition: fastlist.h:245
Field class for parser.
Definition: field.h:37
Modulator class for parser.
Definition: modulator.h:37
Colour definition for parser.
Definition: newcolour.h:40
void print() const
print some properties
Definition: optionsBase.cc:379
Options class.
Definition: options.h:44
Parser class.
Definition: parser.h:80
void Overwrite(const std::string &objectName)
Overwrite object with current values.
Definition: parser.cc:738
FastList< Atom > atom_list
List of parser defined instances of that object.
Definition: parser.h:233
void Add()
Insert global object of parser class C in Container class.
Definition: parser.cc:1035
std::vector< std::list< Element > * > allocated_lines
Definition: parser.h:264
double property_lookup(const std::string &element_name, const std::string &property_name) const
access property of Element with element_name
Definition: parser.cc:635
FastList< BLMPlacement > blm_list
List of parser defined instances of that object.
Definition: parser.h:248
std::vector< std::string > sequences
Names of all defined sequences in the parser with 'line'.
Definition: parser.h:313
void FillString(Array *)
Definition: parser.cc:726
const int MAX_EXPAND_ITERATIONS
maximum number of nested lines
Definition: parser.h:257
void quit()
Exit method.
Definition: parser.cc:268
Scorer scorer
The one instance we fill before appending to a list.
Definition: parser.h:280
void ExtendValue(const std::string &property, T value)
Add value to be extended to object.
void ExtendObject(C &object)
Extend object with maps.
Definition: parser.cc:808
FastList< Crystal > crystal_list
List of parser defined instances of that object.
Definition: parser.h:235
FastList< Placement > placement_list
List of parser defined instances of that object.
Definition: parser.h:242
Material material
The one instance we fill before appending to a list.
Definition: parser.h:272
virtual ~Parser()
Destructor.
Definition: parser.cc:115
Atom atom
The one instance we fill before appending to a list.
Definition: parser.h:268
Symtab * symlook(const std::string &s)
look up parser symbol
Definition: parser.cc:706
static Parser * Instance()
Access method.
Definition: parser.cc:94
std::map< std::string, FastList< Element > * > expandedSequences
Cached copy of expanded sequences.
Definition: parser.h:316
FastList< Region > region_list
List of parser defined instances of that object.
Definition: parser.h:239
FastList< Modulator > modulator_list
List of parser defined instances of that object.
Definition: parser.h:249
FastList< NewColour > colour_list
List of parser defined instances of that object.
Definition: parser.h:234
Parameters params
The one instance we fill before appending to a list.
Definition: parser.h:267
int add_sampler_partIDSet(std::list< int > *samplerPartIDListIn)
Definition: parser.cc:556
FastList< Scorer > scorer_list
List of parser defined instances of that object.
Definition: parser.h:245
FastList< Tunnel > tunnel_list
List of parser defined instances of that object.
Definition: parser.h:240
FastList< Element > element_list
List of all encountered elements.
Definition: parser.h:302
void add_sampler(const std::string &name, int count, ElementType type, std::string samplerType, std::list< int > *samplerPartIDListIn=nullptr)
insert a sampler into beamline_list
Definition: parser.cc:574
C & GetGlobal()
Get global object of parser class C.
int copy_element_to_params(const std::string &elementName)
copy properties from Element into params, returns element type as integer, returs _NONE if not found
Definition: parser.cc:666
Crystal crystal
The one instance we fill before appending to a list.
Definition: parser.h:270
bool TryPrintingObject(const std::string &objectName) const
Definition: parser.cc:838
Options options
General options.
Definition: parser.h:229
Element & find_element(const std::string &element_name)
find element
Definition: parser.cc:586
FastList< Aperture > aperture_list
List of parser defined instances of that object.
Definition: parser.h:247
Modulator modulator
The one instance we fill before appending to a list.
Definition: parser.h:284
Tunnel tunnel
The one instance we fill before appending to a list.
Definition: parser.h:277
void expand_line(FastList< Element > &target, const std::string &name, const std::string &start="", const std::string &end="")
Definition: parser.cc:308
FastList< PhysicsBiasing > xsecbias_list
List of parser defined instances of that object.
Definition: parser.h:241
void write_table(std::string *name, ElementType type, bool isLine=false)
Method that transfers parameters to element properties.
Definition: parser.cc:274
FastList< ScorerMesh > scorermesh_list
List of parser defined instances of that object.
Definition: parser.h:246
const Element * find_placement_element_safe(const std::string &element_name) const
search placement_element
Definition: parser.cc:611
void PrintElements() const
Print methods.
Definition: parser.cc:828
FastList< Element > placement_elements
Definition: parser.h:307
std::vector< std::string * > var_list
Variable vector for memory storage.
Definition: parser.h:321
FastList< Element > beamline_list
Beamline.
Definition: parser.h:231
void add_element_temp(const std::string &name, int number, bool pushfront, ElementType linetype)
add element to temporary element sequence tmp_list
Definition: parser.cc:641
std::set< std::set< int > > samplerFilters
Definition: parser.h:325
FastList< SamplerPlacement > samplerplacement_list
List of parser defined instances of that object.
Definition: parser.h:244
Field field
The one instance we fill before appending to a list.
Definition: parser.h:271
std::list< Element > tmp_list
Temporary list.
Definition: parser.h:310
Query query
The one instance we fill before appending to a list.
Definition: parser.h:275
Aperture aperture
The one instance we fill before appending to a list.
Definition: parser.h:282
void AddVariable(std::string *name)
Add variable memory to variable list for memory management.
Definition: parser.cc:818
BLMPlacement blm
The one instance we fill before appending to a list.
Definition: parser.h:283
std::map< std::string, std::string > extendedStrings
Map for options of type string for extending objects.
Definition: parser.h:297
Region region
The one instance we fill before appending to a list.
Definition: parser.h:276
void ParseFile(FILE *f)
Parse the input file and construct beamline_list and options.
Definition: parser.cc:156
bool FindAndExtend(const std::string &objectName)
Find object by name in list.
Definition: parser.cc:795
SymbolMap symtab_map
Parser symbol map.
Definition: parser.h:319
void PrintBeamline() const
Print methods.
Definition: parser.cc:823
const FastList< Element > & get_sequence(const std::string &name)
Definition: parser.cc:461
std::map< std::string, Array * > extendedVectors
Map for options of type vector for extending objects.
Definition: parser.h:299
void set_sampler(const std::string &name, int count, ElementType type, const std::string &samplerType, double samplerRadius=0, int particleSetID=-1)
Set sampler.
Definition: parser.cc:471
Symtab * symcreate(const std::string &s)
create new parser symbol
Definition: parser.cc:701
NewColour colour
The one instance we fill before appending to a list.
Definition: parser.h:269
ScorerMesh scorermesh
The one instance we fill before appending to a list.
Definition: parser.h:281
const FastList< Element > & GetBeamline() const
Definition: parser.cc:903
void PrintOptions() const
Print methods.
Definition: parser.cc:833
void ClearParams()
Definition: parser.cc:732
void FillArray(Array *)
Definition: parser.cc:720
FastList< Field > field_list
List of parser defined instances of that object.
Definition: parser.h:236
FastList< CavityModel > cavitymodel_list
List of parser defined instances of that object.
Definition: parser.h:243
std::map< std::string, double > extendedNumbers
Map for options of type double for extending objects.
Definition: parser.h:295
Placement placement
The one instance we fill before appending to a list.
Definition: parser.h:274
std::list< double > tmparray
temporary list for reading of arrays in parser
Definition: parser.h:260
CavityModel cavitymodel
The one instance we fill before appending to a list.
Definition: parser.h:278
FastList< Query > query_list
List of parser defined instances of that object.
Definition: parser.h:238
Parser()=delete
No default constructor.
void Store(double value)
Add value to front of temporary list.
Definition: parser.cc:710
static Parser * instance
Instance.
Definition: parser.h:96
PhysicsBiasing xsecbias
The one instance we fill before appending to a list.
Definition: parser.h:273
Beam beam
Beam instance;.
Definition: parser.h:227
void add_func(std::string name, double(*func)(double))
Add function to parser.
Definition: parser.cc:681
void Initialise()
Initialisation of parser functions and constants.
Definition: parser.cc:188
FastList< Material > material_list
List of parser defined instances of that object.
Definition: parser.h:237
const Element * find_element_safe(const std::string &element_name) const
find element by pointer - nullptr if not found - searches element_list
Definition: parser.cc:623
void expand_sequences()
Expand all sequences define with 'line' into FastLists.
Definition: parser.cc:291
std::list< std::string > tmpstring
temporary list for reading of arrays in parser
Definition: parser.h:261
SamplerPlacement samplerplacement
The one instance we fill before appending to a list.
Definition: parser.h:279
Physics biasing class for parser.
Placement class for parser.
Definition: placement.h:41
std::string name
Name of this placement.
Definition: placement.h:43
void clear()
reset
Definition: placement.cc:33
void print() const
print some properties
Definition: placement.cc:91
std::string bdsimElement
Name of bdsim-built component to place instead of piece of geometry.
Definition: placement.h:45
Query structure class for parser.
Definition: query.h:37
Region class for parser.
Definition: region.h:36
Sampler placement class for parser.
ScorerMesh class for parser.
Definition: scorermesh.h:38
Scorer class for parser.
Definition: scorer.h:37
void clear()
Destructor that clears memory.
Definition: symbolmap.cc:48
Symtab * symlook(std::string s)
Look up parser symbol.
Definition: symbolmap.cc:42
Symtab * symcreate(std::string s)
Create new parser symbol.
Definition: symbolmap.cc:28
Common header for the lexer and the parser to share Symbol table for numeric variables,...
Definition: sym_table.h:33
void Set(Array *)
Set to Array value.
Definition: sym_table.cc:37
Tunnel class for parser.
Definition: tunnel.h:35
Parser namespace for GMAD language. Combination of Geant4 and MAD.
ElementType
types of elements
Definition: elementtype.h:28
Atom class.
Definition: atom.h:36
Element class.
Definition: element.h:43
double property_lookup(std::string property_name) const
Definition: element.cc:630
void set(const Parameters &params)
set method from Parameters structure
Definition: element.cc:658
std::list< Element > * lst
in case the element is a list itself (line)
Definition: element.h:247
double l
length in metres
Definition: element.h:49
ElementType type
element enum
Definition: element.h:44
Material class.
Definition: material.h:39
Parameters - Element class with booleans.
Definition: parameters.h:44
void inherit_properties(const Element &e)
Definition: parameters.cc:213
void flush()
Reset the parameters to defaults and setMap.
Definition: parameters.cc:205