OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Sequence.cpp
Go to the documentation of this file.
1 // ------------------------------------------------------------------------
2 // $RCSfile: Sequence.cpp,v $
3 // ------------------------------------------------------------------------
4 // $Revision: 1.3.4.1 $
5 // ------------------------------------------------------------------------
6 // Copyright: see Copyright.readme
7 // ------------------------------------------------------------------------
8 //
9 // Class: Sequence
10 // The class of OPAL element sequences.
11 //
12 // ------------------------------------------------------------------------
13 //
14 // $Date: 2002/12/09 15:06:08 $
15 // $Author: jsberg $
16 //
17 // ------------------------------------------------------------------------
18 
19 #include "Lines/Sequence.h"
22 #include "Attributes/Attributes.h"
23 #include "BeamlineCore/DriftRep.h"
24 #include "Beamlines/Beamline.h"
25 #include "Elements/OpalDrift.h"
26 
27 #include "Lines/Replacer.h"
28 #include "Lines/SequenceParser.h"
29 #include "Lines/SequenceTemplate.h"
31 #include "Utilities/Options.h"
32 
33 #include <cmath>
34 #include <iostream>
35 #include <sstream>
36 #include <vector>
37 
38 // Class Sequence
39 // ------------------------------------------------------------------------
40 
41 // The attributes of class Sequence.
42 namespace {
43  enum {
44  TYPE, // The design type.
45  LENGTH, // The total sequence length.
46  REFER, // The reference position for members.
47  REFPOS, // The reference position for the sequence.
48  SIZE
49  };
50 }
51 
52 
54  BeamSequence(SIZE, "SEQUENCE",
55  "The \"SEQUENCE\" statement initiates parsing of an "
56  "element sequence.\n"
57  "\t<label>: SEQUENCE,L=<length>,REFER=<reference>\n"
58  "\t\t...\n"
59  "\t\t<object>: <class>,AT=<real>{,<attribute>=<value>}\n"
60  "\t\t<object>: <class>,DRIFT=<real>{,<attribute>=<value>}\n"
61  "\t\t...\n"
62  "\tEND;") {
64  ("TYPE", "The design type");
66  ("L", "Total length of sequence in m");
67 
69  ("REFER",
70  "Reference position for members:\n"
71  "\tENTRY | EXIT | CENTRE (default is CENTRE)", "CENTRE");
73  ("REFPOS",
74  "Element giving reference position for this sequence"
75  "\t(if given, this position is used instead of the centre, when the"
76  "\tsequence is nested in another sequence with \"REFER=CENTRE\")");
77 
78  setElement((new TLine("SEQUENCE"))->makeAlignWrapper());
79 
81 }
82 
83 
84 Sequence::Sequence(const std::string &name, Sequence *parent):
85  BeamSequence(name, parent)
86  // Do not copy parent's line, it will be filled in at parse time,
87  // In case of a clone within a sequence, it is filled by the method
88  // SequenceParser::parseMember().
89 {
90  setElement((new TLine(name))->makeAlignWrapper());
91 }
92 
93 
95 {}
96 
97 
98 Sequence *Sequence::clone(const std::string &name) {
99  return new Sequence(name, this);
100 }
101 
102 
103 Sequence *Sequence::copy(const std::string &name) {
104  TLine *oldLine = fetchLine();
105  TLine *newLine = new TLine(name);
106 
107  for(TLine::iterator i = oldLine->begin(); i != oldLine->end(); ++i) {
108  SequenceMember member(*i);
109 
110  if(i->itsType == SequenceMember::GENERATED) {
111  member.setElement(member.getElement()->clone());
112  } else {
113  member.setElement(member.getElement()->copyStructure());
114  }
115 
116  newLine->push_back(member);
117  }
118 
119  Sequence *newSeq = dynamic_cast<Sequence *>(clone(name));
120  newSeq->storeLine(*newLine);
121  return newSeq;
122 }
123 
125 Sequence::findNamedPosition(TLine &line, const std::string &name) const {
126  TLine::iterator first = line.begin();
127  TLine::iterator last = line.end();
128 
129  for(TLine::iterator iter = first; iter != last; ++iter) {
130  if(iter->itsType != SequenceMember::GENERATED) {
131  if(iter->getElement()->getName() == name) {
132  TLine::iterator test = iter;
133 
134  while(++test != line.end()) {
135  if(test->getElement()->getName() == name) {
136  throw OpalException("Sequence::findNamedPosition()", "Element \"" +
137  name + "\" is not unique in sequence.");
138  }
139  }
140 
141  return iter;
142  }
143  }
144  }
145 
146  throw OpalException("Sequence::findNamedPosition()",
147  "Element \"" + name + "\" not found in sequence.");
148 }
149 
150 
151 double Sequence::getLength() const {
152  return Attributes::getReal(itsAttr[LENGTH]);
153 }
154 
155 
156 double Sequence::getEntrance(ReferenceType ref) const {
157  if(itsRefPoint.empty()) {
158  return Element::getEntrance(ref);
159  } else {
160  TLine *line = fetchLine();
162  return (- iter->itsPosition);
163  }
164 }
165 
166 
167 double Sequence::getExit(ReferenceType ref) const {
168  if(itsRefPoint.empty()) {
169  return Element::getExit(ref);
170  } else {
171  TLine *line = fetchLine();
173  return (getLength() - iter->itsPosition);
174  }
175 }
176 
177 
179  std::string ref = Attributes::getString(itsAttr[REFER]);
180  ReferenceType code = IS_CENTRE;
181 
182  if(ref == "ENTRY") {
183  code = IS_ENTRY;
184  } else if(ref == "EXIT") {
185  code = IS_EXIT;
186  }
187 
188  return code;
189 }
190 
191 
193 (const std::string &name, TokenStream &is, Statement &statement) {
194  SequenceTemplate *macro = new SequenceTemplate(name, this);
195 
196  try {
197  macro->parseTemplate(is, statement);
198  return macro;
199  } catch(...) {
200  delete macro;
201  macro = 0;
202  throw;
203  }
204 }
205 
206 
207 void Sequence::parse(Statement &statement) {
208  // Look for "REFER" and "L" attributes.
209  Object::parse(statement);
210 
211  // Set up to parse members.
212  SequenceParser parser(this);
213  parser.run();
214  if(itsAttr[REFPOS]) itsRefPoint = Attributes::getString(itsAttr[REFPOS]);
215 }
216 
217 
218 
219 void Sequence::print(std::ostream &os) const {
220  TLine *line = fetchLine();
221  std::streamsize old_prec = os.precision(12);
222 
223  if(isShared()) os << "SHARED ";
224  os << getOpalName() << ":SEQUENCE";
225 
226  for(const Attribute& i : itsAttr) {
227  if(i) {
228  os << ',' << i.getName()
229  << (i.isExpression() ? ":=" : "=") << i;
230  }
231  }
232 
233  os << ";" << std::endl;
234 
235  for(TLine::const_iterator iter = line->begin();
236  iter != line->end(); ++iter) {
237  const SequenceMember &member = *iter;
238 
239  if(member.itsType != SequenceMember::GENERATED) {
240  const std::string &name = member.getElement()->getName();
241  if(name[0] != '#') {
242  // Name of current element.
243  os << " ";
244  if(member.getReflectionFlag()) os << '-';
245  os << name;
246 
247  // Position of current element.
248  os << ",AT=" << member.itsPosition;
249  os << ';' << std::endl;
250  }
251  }
252  }
253 
254  os << "ENDSEQUENCE;" << std::endl;
255 
256  os.precision(old_prec);
257 }
258 
259 
260 void Sequence::replace(Object *oldObject, Object *newObject) {
261  Element *oldElement = dynamic_cast<Element *>(oldObject);
262  Element *newElement = dynamic_cast<Element *>(newObject);
263 
264  if(oldElement != 0 && newElement != 0) {
265  Replacer rep(*fetchLine(),
266  oldElement->getOpalName(),
267  newElement->getElement());
268  rep.execute();
269  }
270 }
271 
272 
274  TLine *line = fetchLine();
275  if(! line->empty()) updateList(this, line);
276 }
277 
278 
280  return dynamic_cast<TLine *>(getElement()->removeWrappers());
281 }
282 
283 
284 void Sequence::storeLine(TLine &newLine) {
285  // Remove any old line and assign new one.
286  TLine *line = fetchLine();
287  line->erase(line->begin(), line->end());
288  line->swap(newLine);
289 
290  // Store the reference code.
291  itsCode = getReference();
292 
293  // Clear all occurrence counts.
295 
296  // Set occurrence counts.
297  for(TLine::iterator i = line->begin(); i != line->end(); ++i) {
298  if(i->itsType != SequenceMember::GENERATED) {
299  const std::string &name = i->getElement()->getName();
300  Element *elem = Element::find(name);
301  // ada 4.5 2000 to speed up matching, add a pointer to
302  // opal elements in order to avoid serching the opal elements
303  i->OpalElement = elem;
304  i->setCounter(elem->increment());
305  }
306  }
307 
308  // Fill in the drift spaces.
309  // update();
310 }
311 
312 
313 void Sequence::addEndMarkers(TLine &line) const {
314  SequenceMember member;
315  member.setElement(Element::find("#S")->getElement());
316  member.itsPosition = 0.0;
319  line.push_front(member);
320  member.setElement(Element::find("#E")->getElement());
321  member.itsPosition = getLength();
322  line.push_back(member);
323 }
324 
325 
327  // It is assumed that the elements preceding and following the drift exist.
328  TLine::iterator prev(drift);
329  --prev;
330  const std::string prev_name = prev->getElement()->getName();
331 
332  // ada 4.5 2000 to speed up matching, add a pointer to
333  // opal elements in order to avoid serching the opal elements
334  // Element *prev_elem = Element::find(prev_name);
335  Pointer<Element> prev_elem = prev->OpalElement;
336  double prev_exit = prev->itsPosition + prev_elem->getExit(itsCode);
337 
338  TLine::iterator next(drift);
339  ++next;
340  const std::string next_name = next->getElement()->getName();
341 
342  // ada 4.5 2000 to speed up matching, add a pointer to
343  // opal elements in order to avoid serching the opal elements
344  // Element *next_elem = Element::find(next_name);
345  Pointer<Element> next_elem = next->OpalElement;
346  double next_entry = next->itsPosition + next_elem->getEntrance(itsCode);
347 
348  double driftLength = next_entry - prev_exit;
349 
350  static double tolerance = 1.0e-8;
351  if(std::abs(driftLength) < tolerance) {
352  driftLength = 0.0;
353  } else if(driftLength < 0.0) {
354  driftLength = 0.0;
355  std::ostringstream os;
356  os << "Inconsistent positions in sequence \"" << getOpalName() + "\";\n"
357  << "previous element: \"" << prev_name + "\" at = "
358  << prev->itsPosition << ",\n"
359  << "following element: \"" << next_name + "\" at = "
360  << next->itsPosition << "." << std::ends;
361  throw OpalException("Sequence::findDriftLength()", os.str());
362  // ada 15-6-2000 move driftLength = 0.0; bevore throw
363  }
364 
365  return driftLength;
366 }
367 
368 
370  TLine::iterator i = line.begin();
371  while(true) {
372  ++i;
373  if(i == line.end()) break;
374  SequenceMember member;
375  DriftRep *drift = new DriftRep();
376  drift->setName("[DRIFT]");
377  member.setElement(drift);
379  line.insert(i, member);
380  }
381 }
382 
383 
385  TLine::iterator iter = line->begin();
386  TLine::iterator last = line->end();
387 
388  while(true) {
389  // Recursive call for nested beam non-shared sequence.
390  if(iter == last) break;
391  ElementBase *base = iter->getElement()->removeWrappers();
392  if(! base->isSharable()) {
393  TLine *sub_line = dynamic_cast<TLine *>(base);
394  if(sub_line != 0) {
395  const std::string &sub_name = sub_line->getName();
396  Sequence *sub_seq = dynamic_cast<Sequence *>(OpalData::getInstance()->find(sub_name));
397  updateList(sub_seq, sub_line);
398  }
399  }
400  ++iter;
401 
402  // Fill in drift length.
403  if(iter == last) break;
404  double driftLength = seq->findDriftLength(iter);
405  iter->setLength(driftLength);
406  ++iter;
407  }
408 }
virtual double getExit(ReferenceType) const
Return arc length from origin to exit (positive !).
Definition: Element.cpp:78
virtual bool isShared() const
Shared flag.
Definition: Object.cpp:247
PETE_TUTree< FnAbs, typename T::PETE_Expr_t > abs(const PETE_Expr< T > &l)
double findDriftLength(TLine::iterator drift) const
Definition: Sequence.cpp:326
virtual ~Sequence()
Definition: Sequence.cpp:94
virtual void print(std::ostream &) const
Print sequence.
Definition: Sequence.cpp:219
Interface for basic beam line object.
Definition: ElementBase.h:128
virtual TLine * fetchLine() const
Return the embedded CLASSIC beam line.
Definition: Sequence.cpp:279
void parseTemplate(TokenStream &, Statement &)
Parse the sequence template.
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
The base class for all OPAL exceptions.
Definition: OpalException.h:28
virtual void setName(const std::string &name)
Set element name.
virtual ElementBase * removeWrappers()
Return the design element.
Sequence()
Exemplar constructor.
Definition: Sequence.cpp:53
An ``archetype&#39;&#39; for a SEQUENCE with arguments.
virtual const std::string & getName() const
Get element name.
Definition: ElementBase.cpp:95
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
virtual void parse(Statement &)
Parse sequence.
Definition: Sequence.cpp:207
TLine::iterator findNamedPosition(TLine &, const std::string &) const
Definition: Sequence.cpp:125
Clear Reference.
Definition: OpalData.h:150
double itsPosition
The position attribute (&quot;AT&quot; or &quot;DRIFT&quot;).
void insertDrifts(TLine &line)
Definition: Sequence.cpp:369
virtual double getEntrance(ReferenceType) const
Return the arc length from origin to entrance.
Definition: Sequence.cpp:156
virtual void replace(Object *oldObject, Object *newObject)
Replace references to elements.
Definition: Sequence.cpp:260
void apply(const ObjectFunction &)
Apply a function to all objects.
Definition: OpalData.cpp:516
ReferenceType getReference() const
Return the reference type flag.
Definition: Sequence.cpp:178
static OpalData * getInstance()
Definition: OpalData.cpp:209
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:284
MemberType itsType
Type word.
Template class for beam lines.
Definition: TBeamline.h:40
The base class for all OPAL elements.
Definition: Element.h:46
A representation of an Object attribute.
Definition: Attribute.h:55
ReferenceType
Reference for element positioning.
Definition: Element.h:52
ReferenceType itsCode
Definition: Sequence.h:129
void addEndMarkers(TLine &line) const
Definition: Sequence.cpp:313
Interface for statements.
Definition: Statement.h:38
static void updateList(Sequence *, TLine *)
Definition: Sequence.cpp:384
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:194
void storeLine(TLine &line)
Store sequence line.
Definition: Sequence.cpp:284
The SEQUENCE definition.
Definition: Sequence.h:38
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:133
virtual ElementBase * copyStructure()
Make a structural copy.
The parser for SEQUENCE members.
virtual Sequence * clone(const std::string &name)
Make clone.
Definition: Sequence.cpp:98
virtual ElementBase * clone() const =0
Return clone.
int precision() const
Definition: Inform.h:115
virtual void execute()
Apply the algorithm to the top-level beamline.
virtual double getExit(ReferenceType) const
Return the arc length from origin to exit.
Definition: Sequence.cpp:167
TBeamline< SequenceMember > TLine
The type of a sequence line.
Definition: Sequence.h:47
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:128
virtual void run() const
Read current stream.
Definition: OpalParser.cpp:601
The base class for all OPAL beam lines and sequences.
Definition: BeamSequence.h:32
static Element * find(const std::string &name)
Find named Element.
Definition: Element.cpp:37
virtual Sequence * copy(const std::string &name)
Make copy of the sequence line.
Definition: Sequence.cpp:103
virtual double getLength() const
Return sequence length.
Definition: Sequence.cpp:151
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:618
The base class for all OPAL objects.
Definition: Object.h:48
int increment()
Increment and return the occurrence counter.
Definition: Object.cpp:320
PositionType itsFlag
Flag word.
const std::string name
bool getReflectionFlag() const
Get reflection flag.
bool isSharable() const
Test if the element can be shared.
Definition: ElementBase.h:559
std::string itsRefPoint
Definition: Sequence.h:132
std::string::iterator iterator
Definition: MSLang.h:16
virtual void parse(Statement &)
Parse the object.
Definition: Object.cpp:100
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:217
Replace all references to named element by a new version.
Definition: Replacer.h:32
virtual void update()
Update the embedded CLASSIC beam line.
Definition: Sequence.cpp:273
virtual Object * makeTemplate(const std::string &, TokenStream &, Statement &)
Make a sequence template.
Definition: Sequence.cpp:193
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:296
ElementBase * getElement() const
Get the element pointer.
Definition: ElmPtr.h:58
virtual double getEntrance(ReferenceType) const
Return arc length from origin to entrance (negative !).
Definition: Element.cpp:63
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:205
Representation for a drift space.
Definition: DriftRep.h:32
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
void setElement(ElementBase *)
Set the element pointer.
Definition: ElmPtr.h:63
A member of a SEQUENCE.
std::string getString(const Attribute &attr)
Get string value.
Definition: Attributes.cpp:307