41 #include <boost/regex.hpp>
50 Element(size, name, help), itsSize(size) {
52 (
"TYPE",
"The element design type (the project name)");
54 (
"L",
"The element length in m");
56 (
"ELEMEDGE",
"The position of the element in path length (in m)");
58 (
"APERTURE",
"The element aperture");
60 (
"WAKEF",
"Defines the wake function");
62 (
"PARTICLEMATTERINTERACTION",
"Defines the particle mater interaction handler");
64 (
"ORIGIN",
"The location of the element");
67 (
"ORIENTATION",
"The Tait-Bryan angles for the orientation of the element");
70 (
"X",
"The x-coordinate of the location of the element", 0);
73 (
"Y",
"The y-coordinate of the location of the element", 0);
76 (
"Z",
"The z-coordinate of the location of the element", 0);
79 (
"THETA",
"The rotation about the y-axis of the element", 0);
82 (
"PHI",
"The rotation about the x-axis of the element", 0);
85 (
"PSI",
"The rotation about the z-axis of the element", 0);
88 (
"DX",
"Misalignment in x direction",0.0);
90 (
"DY",
"Misalignment in y direction",0.0);
92 (
"DZ",
"Misalignment in z direction",0.0);
94 (
"DTHETA",
"Misalignment in theta (Tait-Bryan angles)",0.0);
96 (
"DPHI",
"Misalignment in theta (Tait-Bryan angles)",0.0);
98 (
"DPSI",
"Misalignment in theta (Tait-Bryan angles)",0.0);
100 const unsigned int end =
COMMON;
101 for (
unsigned int i = 0; i < end; ++ i) {
105 static bool first =
true;
134 Element(name, parent), itsSize(parent->itsSize)
164 double dx, dy, dz, dphi, dtheta, dpsi;
189 for(; cur != end; ++cur) {
199 std::string::size_type i = 0;
203 while(isdigit(name[i])) ++i;
204 if(name[i] ==
'S') ++i;
206 if(name[i] ==
'L' && ++i == name.length()) {
209 throw OpalException(
"OpalElement::findRegisteredAttribute()",
210 "There is no element which has an attribute "
211 "called \"" + name +
"\".");
222 std::vector<double>({0.5, 0.5, 1.0}));
227 boost::regex square(
"square *\\((.*)\\)", boost::regex::icase);
228 boost::regex rectangle(
"rectangle *\\((.*)\\)", boost::regex::icase);
229 boost::regex circle(
"circle *\\((.*)\\)", boost::regex::icase);
230 boost::regex ellipse(
"ellipse *\\((.*)\\)", boost::regex::icase);
232 boost::regex twoArguments(
"([^,]*),([^,]*)");
233 boost::regex threeArguments(
"([^,]*),([^,]*),([^,]*)");
237 const double width2HalfWidth = 0.5;
239 if (boost::regex_search(aperture, match, square)) {
240 std::string arguments = match[1];
241 if (!boost::regex_search(arguments, match, twoArguments)) {
245 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
246 retvalue.second[1] = retvalue.second[0];
247 }
catch (
const std::exception &ex) {
249 "could not convert '" + arguments +
"' to double");
256 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
257 retvalue.second[1] = retvalue.second[0];
258 retvalue.second[2] = std::stod(match[2]);
259 }
catch (
const std::exception &ex) {
261 "could not convert '" + arguments +
"' to doubles");
268 if (boost::regex_search(aperture, match, rectangle)) {
269 std::string arguments = match[1];
271 if (!boost::regex_search(arguments, match, threeArguments)) {
277 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
278 sz = arguments.find_first_of(
",", sz) + 1;
279 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
281 }
catch (
const std::exception &ex) {
283 "could not convert '" + arguments +
"' to doubles");
290 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
291 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
292 retvalue.second[2] = std::stod(match[3]);
293 }
catch (
const std::exception &ex) {
295 "could not convert '" + arguments +
"' to doubles");
302 if (boost::regex_search(aperture, match, circle)) {
303 std::string arguments = match[1];
304 if (!boost::regex_search(arguments, match, twoArguments)) {
308 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
309 retvalue.second[1] = retvalue.second[0];
310 }
catch (
const std::exception &ex) {
312 "could not convert '" + arguments +
"' to double");
319 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
320 retvalue.second[1] = retvalue.second[0];
321 retvalue.second[2] = std::stod(match[2]);
322 }
catch (
const std::exception &ex) {
324 "could not convert '" + arguments +
"' to doubles");
331 if (boost::regex_search(aperture, match, ellipse)) {
332 std::string arguments = match[1];
334 if (!boost::regex_search(arguments, match, threeArguments)) {
340 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
341 sz = arguments.find_first_of(
",", sz) + 1;
342 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
344 }
catch (
const std::exception &ex) {
346 "could not convert '" + arguments +
"' to doubles");
353 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
354 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
355 retvalue.second[2] = std::stod(match[3]);
356 }
catch (
const std::exception &ex) {
358 "could not convert '" + arguments +
"' to doubles");
367 "Unknown aperture type '" + aperture +
"'.");
403 "unknown attribute \"" + name +
"\"");
416 "Delimiter \"=\" or \":=\" expected.");
420 attr->
parse(stat,
true);
422 attr->
parse(stat,
false);
435 if(parent != 0 && ! parent->
getOpalName().empty()) {
447 (
const std::string &
name,
double value) {
448 attributeRegistry[
name]->setReal(value);
453 (
const std::string &name,
const std::string &value) {
454 attributeRegistry[
name]->setString(value);
459 (std::ostream &os,
int order,
int &len,
460 const std::string &sName,
const std::string &tName,
481 int div = 2 * (order + 1);
493 std::string normImage = sNorm.
getImage();
495 normImage =
"(" + normImage +
")*(" + length.
getImage() +
")";
497 printAttribute(os, sName, normImage, len);
505 std::string skewImage = sSkew.
getImage();
507 skewImage =
"(" + skewImage +
")*(" + length.
getImage() +
")";
509 printAttribute(os, sName, skewImage, len);
511 printAttribute(os, tName, tilt, len);
520 double strength =
sqrt(sn * sn + ss * ss);
522 std::ostringstream ts;
524 std::string image = ts.str();
526 image =
"(" + image +
")*(" + length.
getImage() +
")";
528 printAttribute(os, sName, image, len);
529 double tilt = -
atan2(ss, sn) / double(div);
530 if(tilt) printAttribute(os, tName, tilt, len);
540 std::string normImage = sNorm.
getImage();
541 std::string skewImage = sSkew.
getImage();
543 "SQRT((" + normImage +
")^2+(" + skewImage +
")^2)";
544 printAttribute(os, sName, image, len);
546 image =
"(" + image +
")*(" + length.
getImage() +
")";
554 divisor[0] += div / 10;
555 divisor[1] += div % 10;
557 image =
"-ATAN2(" + skewImage +
',' + normImage +
")/" + divisor;
558 printAttribute(os, tName, image, len);
576 if (dir.size() == 3) {
580 rotation = rotTheta * (rotPhi * rotPsi);
583 throw OpalException(
"Line::parse",
"Parameter orientation is array of 3 values (theta, phi, psi);\n" +
584 std::to_string(dir.size()) +
" values provided");
588 if (ori.size() == 3) {
589 origin =
Vector_t(ori[0], ori[1], ori[2]);
592 throw OpalException(
"Line::parse",
"Parameter origin is array of 3 values (x, y, z);\n" +
593 std::to_string(ori.size()) +
" values provided");
609 }
else if (!
itsAttr[
X].defaultUsed() ||
626 Quaternion rotation = rotTheta * (rotPhi * rotPsi);
644 Quaternion misalignmentRotation = rotationY * rotationX * rotationZ;
655 for(std::vector<Attribute>::size_type i =
itsSize;
665 (std::ostream &os,
const std::string &name,
const std::string &image,
int &len) {
666 len += name.length() + image.length() + 2;
669 len = name.length() + image.length() + 3;
673 os << name <<
'=' << image;
677 (std::ostream &os,
const std::string &name,
double value,
int &len) {
678 std::ostringstream ss;
679 ss << value << std::ends;
680 printAttribute(os, name, ss.str(), len);
704 const unsigned int end =
itsSize;
706 for (
unsigned int i =
COMMON; i < end; ++ i) {
double Round(double value)
Round the double argument.
const std::string getTypeName() const
Return the element's type name.
Euclid3D & offset() const
Return the offset.
void getMisalignment(double &x, double &y, double &s) const
static AttCell * registerStringAttribute(const std::string &name)
Register a ``string'' element attribute.
double parseRealConst(Statement &)
Parse real constant.
Interface for basic beam line object.
Vector_t getTaitBryantAngles(Quaternion rotation, const std::string &elementName)
virtual void fillRegisteredAttributes(const ElementBase &, ValueFlag)
Fill in all registered attributes.
ValueFlag
Switch for value desired on ATTLIST command.
void setDefault()
Assign default value.
The base class for all OPAL exceptions.
Tps< T > sin(const Tps< T > &x)
Sine.
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
const_iterator end() const
Iterator marking the end of the list.
virtual ElementBase * removeWrappers()
Return the design element.
Define the position of a misaligned element.
void setRotationAboutZ(double rotation)
Set rotation about z axis in bend frame.
Object * getParent() const
Return parent pointer.
NameMap::const_iterator const_iterator
An iterator for a map of name versus value.
The abstract base class for attribute cells.
virtual double getLength() const
Return element length.
virtual void setAttribute(const std::string &aKey, double val)
Set value of an attribute.
static void setRegisteredAttribute(const std::string &, double)
Store a registered real attribute.
A pointer which owns the object pointed at.
std::vector< Attribute > itsAttr
The object attributes (see Attribute.hh).
std::pair< ElementBase::ApertureType, std::vector< double > > getApert() const
const_iterator begin() const
Iterator accessing first member.
static void addAttributeOwner(const std::string &owner, const OwnerType &type, const std::string &name)
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
virtual void parse(Statement &)
Parse the element.
const Object * getBaseObject() const
Return the object's base type object.
static std::map< std::string, OwnPtr< AttCell > > attributeRegistry
The registry for named attributes.
const std::string & getOpalName() const
Return object name.
void parseComponent(Statement &stat, bool eval, int index)
Parse array component.
The base class for all OPAL elements.
A representation of an Object attribute.
void setMisalignment(double x, double y, double s)
constexpr double pi
The value of .
std::string getImage() const
Return printable representation.
Quaternion getRotation() const
virtual double getElementLength() const
Get design length.
void getAll(double &x, double &y, double &z, double &vx, double &vy, double &vz) const
Unpack.
const std::string getWakeF() const
Return the element's type name.
Interface for statements.
Base class for all beam line elements.
const std::string getParticleMatterInteraction() const
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
static void printAttribute(std::ostream &os, const std::string &name, const std::string &image, int &len)
Print an attribute with a OPAL-8 name (as an expression).
PETE_TBTree< FnArcTan2, PETE_Scalar< Vektor< T1, Dim > >, typename T2::PETE_Expr_t > atan2(const Vektor< T1, Dim > &l, const PETE_Expr< T2 > &r)
void setCSTrafoGlobal2Local(const CoordinateSystemTrafo &ori)
Vektor< double, 3 > Vector_t
bool isValid() const
Test for validity.
void registerOwnership() const
Vector_t getOrigin() const
virtual void update()
Update the embedded CLASSIC element.
static void printMultipoleStrength(std::ostream &os, int order, int &len, const std::string &sName, const std::string &tName, const Attribute &length, const Attribute &vNorm, const Attribute &vSkew)
Print multipole components in OPAL-8 format.
virtual void updateUnknown(ElementBase *)
Transmit the ``unknown'' (not known to OPAL) attributes to CLASSIC.
Tps< T > sqrt(const Tps< T > &x)
Square root.
The class for attribute cells with a real value.
ElementBase * getElement() const
Return the embedded CLASSIC element.
The base class for all OPAL objects.
Tps< T > cos(const Tps< T > &x)
Cosine.
virtual bool isExpression() const
Test for expression.
void setAperture(const ApertureType &type, const std::vector< double > &args)
The class for attribute cells with a string value.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
void setElementPosition(double elemedge)
Access to ELEMEDGE attribute.
Quaternion conjugate() const
static AttCell * findRegisteredAttribute(const std::string &name)
Find a registered attribute.
double getReal(const Attribute &attr)
Return real value.
std::string parseString(Statement &, const char msg[])
Parse string value.
bool delimiter(char c)
Test for delimiter.
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
void parse(Statement &stat, bool eval)
Parse attribute.
static AttCell * registerRealAttribute(const std::string &name)
Register a ``real'' element attribute.
const std::string & getName() const
Return the attribute name.
AttributeBase & getBase() const
Return reference to polymorphic value.
Inform & endl(Inform &inf)
virtual void print(std::ostream &) const
Print the object.
std::string getString(const Attribute &attr)
Get string value.
CoordinateSystemTrafo getCSTrafoGlobal2Local() const