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