31#include <boost/regex.hpp>
42 (
"TYPE",
"The element design type.",
56 (
"L",
"The element length in m");
59 (
"ELEMEDGE",
"The position of the element in path length (in m)");
62 (
"APERTURE",
"The element aperture");
65 (
"WAKEF",
"Defines the wake function");
68 (
"PARTICLEMATTERINTERACTION",
"Defines the particle mater interaction handler");
71 (
"ORIGIN",
"The location of the element");
74 (
"ORIENTATION",
"The Tait-Bryan angles for the orientation of the element");
77 (
"X",
"The x-coordinate of the location of the element", 0);
80 (
"Y",
"The y-coordinate of the location of the element", 0);
83 (
"Z",
"The z-coordinate of the location of the element", 0);
86 (
"THETA",
"The rotation about the y-axis of the element", 0);
89 (
"PHI",
"The rotation about the x-axis of the element", 0);
92 (
"PSI",
"The rotation about the z-axis of the element", 0);
95 (
"DX",
"Misalignment in x direction",0.0);
98 (
"DY",
"Misalignment in y direction",0.0);
101 (
"DZ",
"Misalignment in z direction",0.0);
104 (
"DTHETA",
"Misalignment in theta (Tait-Bryan angles)",0.0);
107 (
"DPHI",
"Misalignment in theta (Tait-Bryan angles)",0.0);
110 (
"DPSI",
"Misalignment in theta (Tait-Bryan angles)",0.0);
113 (
"OUTFN",
"Output filename");
116 (
"DELETEONTRANSVERSEEXIT",
"Flag controlling if particles should be deleted if they exit "
117 "the element transversally",
true);
120 for (
unsigned int i = 0; i <
end; ++ i) {
138 std::vector<double>({0.5, 0.5, 1.0}));
143 boost::regex square(
"square *\\((.*)\\)", boost::regex::icase);
144 boost::regex rectangle(
"rectangle *\\((.*)\\)", boost::regex::icase);
145 boost::regex circle(
"circle *\\((.*)\\)", boost::regex::icase);
146 boost::regex ellipse(
"ellipse *\\((.*)\\)", boost::regex::icase);
148 boost::regex twoArguments(
"([^,]*),([^,]*)");
149 boost::regex threeArguments(
"([^,]*),([^,]*),([^,]*)");
153 const double width2HalfWidth = 0.5;
155 if (boost::regex_search(aperture, match, square)) {
156 std::string arguments = match[1];
157 if (!boost::regex_search(arguments, match, twoArguments)) {
161 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
162 retvalue.second[1] = retvalue.second[0];
163 }
catch (
const std::exception &ex) {
165 "could not convert '" + arguments +
"' to double");
172 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
173 retvalue.second[1] = retvalue.second[0];
174 retvalue.second[2] = std::stod(match[2]);
175 }
catch (
const std::exception &ex) {
177 "could not convert '" + arguments +
"' to doubles");
184 if (boost::regex_search(aperture, match, rectangle)) {
185 std::string arguments = match[1];
187 if (!boost::regex_search(arguments, match, threeArguments)) {
193 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
194 sz = arguments.find_first_of(
",", sz) + 1;
195 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
197 }
catch (
const std::exception &ex) {
199 "could not convert '" + arguments +
"' to doubles");
206 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
207 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
208 retvalue.second[2] = std::stod(match[3]);
209 }
catch (
const std::exception &ex) {
211 "could not convert '" + arguments +
"' to doubles");
218 if (boost::regex_search(aperture, match, circle)) {
219 std::string arguments = match[1];
220 if (!boost::regex_search(arguments, match, twoArguments)) {
224 retvalue.second[0] = width2HalfWidth * std::stod(arguments);
225 retvalue.second[1] = retvalue.second[0];
226 }
catch (
const std::exception &ex) {
228 "could not convert '" + arguments +
"' to double");
235 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
236 retvalue.second[1] = retvalue.second[0];
237 retvalue.second[2] = std::stod(match[2]);
238 }
catch (
const std::exception &ex) {
240 "could not convert '" + arguments +
"' to doubles");
247 if (boost::regex_search(aperture, match, ellipse)) {
248 std::string arguments = match[1];
250 if (!boost::regex_search(arguments, match, threeArguments)) {
256 retvalue.second[0] = width2HalfWidth * std::stod(arguments, &sz);
257 sz = arguments.find_first_of(
",", sz) + 1;
258 retvalue.second[1] = width2HalfWidth * std::stod(arguments.substr(sz));
260 }
catch (
const std::exception &ex) {
262 "could not convert '" + arguments +
"' to doubles");
269 retvalue.second[0] = width2HalfWidth * std::stod(match[1]);
270 retvalue.second[1] = width2HalfWidth * std::stod(match[2]);
271 retvalue.second[2] = std::stod(match[3]);
272 }
catch (
const std::exception &ex) {
274 "could not convert '" + arguments +
"' to doubles");
281 if (!aperture.empty()) {
283 "Unknown aperture type '" + aperture +
"'.");
319 "unknown attribute \"" + name +
"\"");
332 "Delimiter \"=\" or \":=\" expected.");
336 attr->
parse(stat,
true);
338 attr->
parse(stat,
false);
351 if (parent != 0 && ! parent->
getOpalName().empty()) {
364 const std::string& sName,
365 const std::string& tName,
388 int div = 2 * (order + 1);
400 std::string normImage = sNorm.
getImage();
402 normImage =
"(" + normImage +
")*(" + length.
getImage() +
")";
412 std::string skewImage = sSkew.
getImage();
414 skewImage =
"(" + skewImage +
")*(" + length.
getImage() +
")";
427 double strength = std::sqrt(sn * sn + ss * ss);
429 std::ostringstream ts;
431 std::string image = ts.str();
433 image =
"(" + image +
")*(" + length.
getImage() +
")";
436 double tilt = - std::atan2(ss, sn) / double(div);
447 std::string normImage = sNorm.
getImage();
448 std::string skewImage = sSkew.
getImage();
450 "SQRT((" + normImage +
")^2+(" + skewImage +
")^2)";
453 image =
"(" + image +
")*(" + length.
getImage() +
")";
461 divisor[0] += div / 10;
462 divisor[1] += div % 10;
464 image =
"-ATAN2(" + skewImage +
',' + normImage +
")/" + divisor;
483 if (dir.size() == 3) {
484 Quaternion rotTheta(std::cos(0.5 * dir[0]), 0, std::sin(0.5 * dir[0]), 0);
485 Quaternion rotPhi(std::cos(0.5 * dir[1]), std::sin(0.5 * dir[1]), 0, 0);
486 Quaternion rotPsi(std::cos(0.5 * dir[2]), 0, 0, std::sin(0.5 * dir[2]));
487 rotation = rotTheta * (rotPhi * rotPsi);
491 "Parameter orientation is array of 3 values (theta, phi, psi);\n" +
492 std::to_string(dir.size()) +
" values provided");
496 if (ori.size() == 3) {
501 "Parameter origin is array of 3 values (x, y, z);\n" +
502 std::to_string(ori.size()) +
" values provided");
518 }
else if (!
itsAttr[
X].defaultUsed() ||
532 Quaternion rotTheta(std::cos(0.5 * theta), 0, std::sin(0.5 * theta), 0);
533 Quaternion rotPhi(std::cos(0.5 * phi), std::sin(0.5 * phi), 0, 0);
534 Quaternion rotPsi(std::cos(0.5 * psi), 0, 0, std::sin(0.5 * psi));
535 Quaternion rotation = rotTheta * (rotPhi * rotPsi);
550 Quaternion rotationY(std::cos(0.5 * dtheta), 0, std::sin(0.5 * dtheta), 0);
551 Quaternion rotationX(std::cos(0.5 * dphi), std::sin(0.5 * dphi), 0, 0);
552 Quaternion rotationZ(std::cos(0.5 * dpsi), 0, 0, std::sin(0.5 * dpsi));
553 Quaternion misalignmentRotation = rotationY * rotationX * rotationZ;
566 for (std::vector<Attribute>::size_type i =
itsSize;
575 const std::string& image,
int& len) {
576 len += name.length() + image.length() + 2;
579 len = name.length() + image.length() + 3;
583 os << name <<
'=' << image;
587(std::ostream &os,
const std::string &name,
double value,
int &len) {
588 std::ostringstream ss;
589 ss << value << std::ends;
599 for (
unsigned int i =
COMMON; i <
end; ++ i) {
ippl::Vector< T, Dim > Vector_t
PartBunch< T, Dim >::ConstIterator end(PartBunch< T, Dim > const &bunch)
std::string parseString(Statement &, const char msg[])
Parse string value.
void parseDelimiter(Statement &stat, char delim)
Test for one-character delimiter.
double parseRealConst(Statement &)
Parse real constant.
Attribute makeBool(const std::string &name, const std::string &help)
Make logical attribute.
double getReal(const Attribute &attr)
Return real value.
Attribute makePredefinedString(const std::string &name, const std::string &help, const std::initializer_list< std::string > &predefinedStrings)
Make predefined string attribute.
Attribute makeReal(const std::string &name, const std::string &help)
Make real attribute.
bool getBool(const Attribute &attr)
Return logical value.
Attribute makeRealArray(const std::string &name, const std::string &help)
Create real array attribute.
std::vector< double > getRealArray(const Attribute &attr)
Get array value.
std::string getString(const Attribute &attr)
Get string value.
Attribute makeString(const std::string &name, const std::string &help)
Make string attribute.
constexpr double pi
The value of.
void setElementPosition(double elemedge)
Access to ELEMEDGE attribute.
void setAperture(const ApertureType &type, const std::vector< double > &args)
void setMisalignment(const CoordinateSystemTrafo &cst)
virtual void setAttribute(const std::string &aKey, double val)
Set value of an attribute.
void setFlagDeleteOnTransverseExit(bool=true)
void setRotationAboutZ(double rotation)
Set rotation about z axis in bend frame.
void setCSTrafoGlobal2Local(const CoordinateSystemTrafo &ori)
A representation of an Object attribute.
AttributeBase & getBase() const
Return reference to polymorphic value.
const std::string & getName() const
Return the attribute name.
void setDefault()
Assign default value.
void parse(Statement &stat, bool eval)
Parse attribute.
void parseComponent(Statement &stat, bool eval, int index)
Parse array component.
std::string getImage() const
Return printable representation.
virtual bool isExpression() const
Test for expression.
static void addAttributeOwner(const std::string &owner, const OwnerType &type, const std::string &name)
ElementBase * getElement() const
Return the embedded CLASSIC element.
Element(int size, const char *name, const char *help)
Constructor for exemplars.
Object * getParent() const
Return parent pointer.
const std::string & getOpalName() const
Return object name.
Object(int size, const char *name, const char *help)
Constructor for exemplars.
virtual Attribute * findAttribute(const std::string &name)
Find an attribute by name.
std::vector< Attribute > itsAttr
The object attributes.
Quaternion conjugate() const
std::pair< ApertureType, std::vector< double > > getApert() const
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 double getLength() const
Return element length.
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).
virtual void parse(Statement &)
Parse the element.
const std::string getParticleMatterInteraction() const
@ PARTICLEMATTERINTERACTION
const std::string getWakeF() const
Return the element's type name.
virtual void updateUnknown(ElementBase *)
Transmit the ``unknown'' (not known to OPAL) attributes to CLASSIC.
const std::string getTypeName() const
Return the element's type name.
virtual void print(std::ostream &) const
Print the object.
virtual void update()
Update the embedded CLASSIC element.
OpalElement(int size, const char *name, const char *help)
Exemplar constructor.
void registerOwnership() const
Interface for statements.
bool delimiter(char c)
Test for delimiter.
The base class for all OPAL exceptions.