OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
Line.cpp
Go to the documentation of this file.
1 
2 // ------------------------------------------------------------------------
3 // $RCSfile: Line.cpp,v $
4 // ------------------------------------------------------------------------
5 // $Revision: 1.3.4.1 $
6 // ------------------------------------------------------------------------
7 // Copyright: see Copyright.readme
8 // ------------------------------------------------------------------------
9 //
10 // Class: Line
11 // The class for OPAL beam lines.
12 //
13 // ------------------------------------------------------------------------
14 //
15 // $Date: 2002/12/09 15:06:08 $
16 // $Author: jsberg $
17 //
18 // ------------------------------------------------------------------------
19 
20 #include "Lines/Line.h"
25 #include "Attributes/Attributes.h"
26 #include "Beamlines/Beamline.h"
28 #include "Expressions/SAutomatic.h"
29 #include "Expressions/SBinary.h"
30 #include "Expressions/SRefExpr.h"
31 #include "Expressions/TFunction2.h"
32 #include "Lines/LineTemplate.h"
33 #include "Lines/Replacer.h"
34 #include "Parser/Statement.h"
35 #include "Utilities/Options.h"
36 #include "Utilities/ParseError.h"
37 #include <algorithm>
38 #include <iostream>
39 
40 using namespace Expressions;
41 
42 // Class Line
43 // ------------------------------------------------------------------------
44 
45 // The attributes of class Line.
46 namespace {
47  enum {
48  TYPE, // The type attribute.
49  LENGTH, // The line length.
50  ORIGIN, // The location of the particle source
51  ORIENTATION, // The orientation of the particle source
52  X,
53  Y,
54  Z,
55  THETA,
56  PHI,
57  PSI,
58  SIZE
59  };
60 
61  // Auxiliary function for adding two element lengths.
62  double AttAdd(double a, double b)
63  { return a + b; }
64 }
65 
66 
68  BeamSequence(SIZE, "LINE",
69  "The \"LINE\" statement defines a beamline list.\n"
70  "\t<name> : line = (<list>)") {
72  ("TYPE", "Design type");
73 
75  ("L", "Total length of line in m");
76  itsAttr[LENGTH].setReadOnly(true);
77 
79  ("ORIGIN", "The location of the particle source");
80 
81  itsAttr[ORIENTATION] = Attributes::makeRealArray
82  ("ORIENTATION", "The Tait-Bryan angles for the orientation of the particle source");
83 
85  ("X", "The x-coordinate of the location of the particle source", 0);
86 
88  ("Y", "The y-coordinate of the location of the particle source", 0);
89 
91  ("Z", "The z-coordinate of the location of the particle source", 0);
92 
94  ("THETA", "The rotation about the y-axis of the particle source", 0);
95 
97  ("PHI", "The rotation about the x-axis of the particle source", 0);
98 
100  ("PSI", "The rotation about the z-axis of the particle source", 0);
101 
102  setElement((new FlaggedBeamline("LINE"))->makeAlignWrapper());
103 
105 }
106 
107 
108 Line::Line(const std::string &name, Line *parent):
109  // Do not copy list members; they will be filled at parse time.
110  BeamSequence(name, parent) {
111  setElement((new FlaggedBeamline(name))->makeAlignWrapper());
112 }
113 
114 
116 {}
117 
118 
119 Line *Line::clone(const std::string &name) {
120  return new Line(name, this);
121 }
122 
123 
124 Line *Line::copy(const std::string &name) {
125  Line *clone = new Line(name, this);
126  FlaggedBeamline *oldLine = fetchLine();
127  FlaggedBeamline *newLine = clone->fetchLine();
128  std::copy(oldLine->begin(), oldLine->end(), std::back_inserter(*newLine));
129  return &*clone;
130 }
131 
132 double Line::getLength() const {
133  return Attributes::getReal(itsAttr[LENGTH]);
134 }
135 
136 
138 (const std::string &name, TokenStream &is, Statement &statement) {
139  LineTemplate *macro = new LineTemplate(name, this);
140 
141  try {
142  macro->parseTemplate(is, statement);
143  return macro;
144  } catch(...) {
145  delete macro;
146  macro = 0;
147  throw;
148  }
149 }
150 
151 
152 void Line::parse(Statement &stat) {
153  static const TFunction2<double, double> plus = { "+", 4, AttAdd };
154 
155  // Check for delimiters.
156  parseDelimiter(stat, '=');
157  parseDelimiter(stat, '(');
158 
159  // Clear all reference counts.
161 
162  // Parse the line list.
163  parseList(stat);
164 
165  // Insert the begin and end markers.
166  FlaggedBeamline *line = fetchLine();
167  ElementBase *markS = Element::find("#S")->getElement();
168  FlaggedElmPtr first(markS, false);
169  line->push_front(first);
170 
171  ElementBase *markE = Element::find("#E")->getElement();
172  FlaggedElmPtr last(markE, false);
173  line->push_back(last);
174 
175  // Construct expression for length, and fill in occurrence counters.
176  PtrToScalar<double> expr;
177  for(FlaggedBeamline::iterator i = line->begin(); i != line->end(); ++i) {
178  // Accumulate length.
179  PtrToScalar<double> temp =
180  new SRefExpr<double>(i->getElement()->getName(), "L");
181  if(expr.isValid() && temp.isValid()) {
182  expr = SBinary<double, double>::make(plus, expr, temp);
183  } else {
184  expr = temp;
185  }
186 
187  // Do the required instantiations.
188  ElementBase *base = i->getElement();
189  i->setElement(base->copyStructure());
190  Element *elem = Element::find(base->getName());
191  i->setCounter(elem->increment());
192  }
193  if(expr.isValid()) itsAttr[LENGTH].set(new SAutomatic<double>(expr));
194 
195  while(stat.delimiter(',')) {
196  std::string name = Expressions::parseString(stat, "Attribute name expected.");
197  Attribute *attr = findAttribute(name);
198 
199  if (attr != 0) {
200  if(stat.delimiter('=')) {
201  attr->parse(stat, true);
202  } else if(stat.delimiter(":=")) {
203  attr->parse(stat, false);
204  } else {
205  attr->setDefault();
206  }
207  }
208  }
209 
210  if (itsAttr[ORIGIN] || itsAttr[ORIENTATION]) {
211  std::vector<double> origin = Attributes::getRealArray(itsAttr[ORIGIN]);
212  if (origin.size() == 3) {
213  line->setOrigin3D(Vector_t(origin[0],
214  origin[1],
215  origin[2]));
216  } else {
217  line->setOrigin3D(Vector_t(0.0));
218  if (itsAttr[ORIGIN]) {
219  throw OpalException("Line::parse","Parameter origin is array of 3 values (x, y, z);\n" +
220  std::to_string(origin.size()) + " values provided");
221  }
222  }
223 
224  std::vector<double> direction = Attributes::getRealArray(itsAttr[ORIENTATION]);
225  if (direction.size() == 3) {
226  const double &theta = direction[0];
227  const double &phi = direction[1];
228  const double &psi = direction[2];
229 
230  Quaternion rotTheta(cos(0.5 * theta), 0, -sin(0.5 * theta), 0);
231  Quaternion rotPhi(cos(0.5 * phi), -sin(0.5 * phi), 0, 0);
232  Quaternion rotPsi(cos(0.5 * psi), 0, 0, -sin(0.5 * psi));
233  line->setInitialDirection(rotPsi * rotPhi * rotTheta);
234  } else {
235  line->setInitialDirection(Quaternion(1, 0, 0, 0));
236  if (itsAttr[ORIENTATION]) {
237  throw OpalException("Line::parse","Parameter orientation is array of 3 values (theta, phi, psi);\n" +
238  std::to_string(direction.size()) + " values provided");
239  }
240  }
241 
242  line->setRelativeFlag(true);
243  } else {
244  const Vector_t origin(Attributes::getReal(itsAttr[X]),
247 
248  const double theta = Attributes::getReal(itsAttr[THETA]);
249  const double phi = Attributes::getReal(itsAttr[PHI]);
250  const double psi = Attributes::getReal(itsAttr[PSI]);
251 
252  Quaternion rotTheta(cos(0.5 * theta), 0, -sin(0.5 * theta), 0);
253  Quaternion rotPhi(cos(0.5 * phi), -sin(0.5 * phi), 0, 0);
254  Quaternion rotPsi(cos(0.5 * psi), 0, 0, -sin(0.5 * psi));
255 
256  line->setOrigin3D(origin);
257  line->setInitialDirection(rotPsi * rotPhi * rotTheta);
258 
259  line->setRelativeFlag(!itsAttr[X].defaultUsed() ||
260  !itsAttr[Y].defaultUsed() ||
261  !itsAttr[Z].defaultUsed() ||
262  !itsAttr[THETA].defaultUsed() ||
263  !itsAttr[PHI].defaultUsed() ||
264  !itsAttr[PSI].defaultUsed());
265  }
266 }
267 
268 
269 void Line::print(std::ostream &os) const {
270  os << getOpalName() << ":LINE=(";
271  const FlaggedBeamline *line = fetchLine();
272  bool seen = false;
273 
274  for(FlaggedBeamline::const_iterator i = line->begin();
275  i != line->end(); ++i) {
276  const std::string name = i->getElement()->getName();
277  if(name[0] != '#') {
278  if(seen) os << ',';
279  if(i->getReflectionFlag()) os << '-';
280  os << name;
281  seen = true;
282  }
283  }
284 
285  os << ')';
286  os << ';';
287  os << std::endl;
288 }
289 
290 
292  return dynamic_cast<FlaggedBeamline *>(getElement()->removeWrappers());
293 }
294 
295 
297  FlaggedBeamline *line = fetchLine();
298 
299  do {
300  // Reversed member ?
301  bool rev = stat.delimiter('-');
302 
303  // Repetition count.
304  int repeat = 1;
305  if(stat.integer(repeat)) parseDelimiter(stat, '*');
306 
307  // List member.
308  if(stat.delimiter('(')) {
309  // Anonymous sub-line is expanded immediately.
310  Line nestedLine;
311  nestedLine.parseList(stat);
312  FlaggedBeamline *subLine = nestedLine.fetchLine();
313 
314  while(repeat-- > 0) {
315  if(rev) {
316  for(FlaggedBeamline::reverse_iterator i = subLine->rbegin();
317  i != subLine->rend(); ++i) {
318  FlaggedElmPtr fep(*i);
319  fep.setReflectionFlag(false);
320  line->push_back(fep);
321  }
322  } else {
323  for(FlaggedBeamline::iterator i = subLine->begin();
324  i != subLine->end(); ++i) {
325  FlaggedElmPtr fep(*i);
326  line->push_back(fep);
327  }
328  }
329  }
330  } else {
331  // Identifier.
332  std::string name = parseString(stat, "Line member expected.");
334 
335  if(! obj.isValid()) {
336  throw ParseError("Line::parseList()",
337  "Element \"" + name + "\" is undefined.");
338  }
339 
340  if(stat.delimiter('(')) {
341  // Line or sequence macro.
342  // This instance will always be an anonymous object.
343  obj = obj->makeInstance(name, stat, 0);
344  }
345 
346  if(Element *elem = dynamic_cast<Element *>(&*obj)) {
347  while(repeat-- > 0) {
348  ElementBase *base = elem->getElement();
349  FlaggedElmPtr member(base, rev);
350  line->push_back(member);
351  }
352  } else {
353  throw ParseError("Line::parseList()",
354  "Object \"" + name + "\" cannot be a line member.");
355  }
356  }
357  } while(stat.delimiter(','));
358 
359  parseDelimiter(stat, ')');
360 }
361 
362 
363 void Line::replace(Object *oldObject, Object *newObject) {
364  Element *oldElement = dynamic_cast<Element *>(oldObject);
365  Element *newElement = dynamic_cast<Element *>(newObject);
366 
367  if(oldElement != 0 && newElement != 0) {
368  Replacer rep(*fetchLine(),
369  oldElement->getOpalName(),
370  newElement->getElement());
371  rep.execute();
372  }
373 }
An expression defined as a reference to a scalar.
Definition: SRefExpr.h:41
bool integer(int &value)
Return signed integer.
Definition: Statement.cpp:81
Definition: rbendmap.h:8
Interface for basic beam line object.
Definition: ElementBase.h:128
Parse exception.
Definition: ParseError.h:32
Abstract interface for a stream of input tokens.
Definition: TokenStream.h:33
void setDefault()
Assign default value.
Definition: Attribute.cpp:143
virtual void print(std::ostream &stream) const
Print the line.
Definition: Line.cpp:269
The base class for all OPAL exceptions.
Definition: OpalException.h:28
Definition: rbendmap.h:8
Tps< T > sin(const Tps< T > &x)
Sine.
Definition: TpsMath.h:111
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
virtual ElementBase * removeWrappers()
Return the design element.
void setRelativeFlag(bool flag)
Definition: TBeamline.h:465
virtual FlaggedBeamline * fetchLine() const
Return the embedded CLASSIC beam line.
Definition: Line.cpp:291
A scalar expression with two scalar operands.
Definition: SBinary.h:39
virtual const std::string & getName() const
Get element name.
Definition: ElementBase.cpp:95
A function of two U&#39;s returning a T.
Definition: TFunction2.h:31
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
Definition: Object.h:214
virtual Line * clone(const std::string &name)
Make clone.
Definition: Line.cpp:119
virtual Line * copy(const std::string &name)
Make complete copy.
Definition: Line.cpp:124
Clear Reference.
Definition: OpalData.h:150
void apply(const ObjectFunction &)
Apply a function to all objects.
Definition: OpalData.cpp:516
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
static OpalData * getInstance()
Definition: OpalData.cpp:209
const std::string & getOpalName() const
Return object name.
Definition: Object.cpp:284
Template class for beam lines.
Definition: TBeamline.h:40
virtual Object * makeTemplate(const std::string &name, TokenStream &is, Statement &stat)
Make a line template.
Definition: Line.cpp:138
The base class for all OPAL elements.
Definition: Element.h:46
A representation of an Object attribute.
Definition: Attribute.h:55
void setOrigin3D(const Vector_t &ori)
Definition: TBeamline.h:445
virtual double getLength() const
Return line length.
Definition: Line.cpp:132
Object attribute with an ``automatic&#39;&#39; scalar value.
Definition: SAutomatic.h:38
Interface for statements.
Definition: Statement.h:38
Reference-counted pointer.
Definition: Pointer.h:38
void setInitialDirection(const Quaternion &rot)
Definition: TBeamline.h:455
void registerOwnership(const AttributeHandler::OwnerType &itsClass) const
Definition: Object.cpp:194
bool isValid() const
Test for validity.
Definition: Pointer.h:170
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
Definition: Attributes.cpp:258
virtual Object * makeInstance(const std::string &name, Statement &, const Parser *)
Macro handler function.
Definition: Object.cpp:94
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition: Element.h:133
virtual ~Line()
Definition: Line.cpp:115
Vektor< double, 3 > Vector_t
Definition: Vektor.h:6
virtual ElementBase * copyStructure()
Make a structural copy.
bool isValid() const
Test for validity.
Definition: OwnPtr.h:144
virtual void execute()
Apply the algorithm to the top-level beamline.
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition: Element.h:128
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
void parseTemplate(TokenStream &is, Statement &stat)
Parse the line template.
An ``archetype&#39;&#39; for a OPAL beam line with arguments.
Definition: LineTemplate.h:36
Object * find(const std::string &name)
Find entry.
Definition: OpalData.cpp:618
The base class for all OPAL objects.
Definition: Object.h:48
Tps< T > cos(const Tps< T > &x)
Cosine.
Definition: TpsMath.h:129
int increment()
Increment and return the occurrence counter.
Definition: Object.cpp:320
const std::string name
virtual void parse(Statement &stat)
Parse the line object.
Definition: Line.cpp:152
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
Definition: Attributes.cpp:253
Line()
Exemplar constructor.
Definition: Line.cpp:67
void parseList(Statement &)
Definition: Line.cpp:296
virtual void replace(Object *oldObject, Object *newObject)
Replace references.
Definition: Line.cpp:363
std::string::iterator iterator
Definition: MSLang.h:16
double getReal(const Attribute &attr)
Return real value.
Definition: Attributes.cpp:217
The LINE definition.
Definition: Line.h:36
std::string parseString(Statement &, const char msg[])
Parse string value.
Replace all references to named element by a new version.
Definition: Replacer.h:32
bool delimiter(char c)
Test for delimiter.
Definition: Statement.cpp:103
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Definition: Attributes.cpp:296
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
Definition: Attributes.cpp:205
void parse(Statement &stat, bool eval)
Parse attribute.
Definition: Attribute.cpp:125
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
TBeamline< FlaggedElmPtr > FlaggedBeamline
A beam line with flagged elements.
A section of a beam line.
Definition: FlaggedElmPtr.h:36
void setReflectionFlag(bool flag) const
Set reflection flag.