OPAL (Object Oriented Parallel Accelerator Library) 2024.2
OPAL
OpalOutputPlane.cpp
Go to the documentation of this file.
1// Copyright (c) 2023, Chris Rogers
2// All rights reserved
3//
4// This file is part of OPAL.
5//
6// OPAL is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// You should have received a copy of the GNU General Public License
12// along with OPAL. If not, see <https://www.gnu.org/licenses/>.
13//
14
20
21const std::string docstring =
22 std::string("The \"OUTPUTPLANE\" element writes out position at which")+
23 std::string("trajectories cross a given plane.");
24
26 OpalElement(SIZE, "OUTPUTPLANE", docstring.c_str()) {
27
29 ("CENTRE", "3-vector position of the plane centre [m]");
31 ("NORMAL", "3-vector normal to the plane");
33 ("REFERENCE_ALIGNMENT_PARTICLE",
34 "Set to a particle number (usually 0, the reference particle). "
35 "The first time that the particle crosses the reference plane, then "
36 "the plane will be moved to centre on that particle and point in S of the particle.", -1);
38 ("TOLERANCE", "Tolerance on position of track intercept [m]", 1e-6);
40 ("WIDTH", "Full width of the output plane [m], defined in the lab coordinate system (*not* the output plane coordinate system).");
42 ("HEIGHT", "Full height of the output plane [m], defined in the lab coordinate system (*not* the output plane coordinate system)");
44 ("RADIUS", "Maximum distance from centre of plane for crossings [m].");
46 ("ALGORITHM",
47 "The algorithm used to step from the track point to the plane", {"INTERPOLATION", "RK4"}, "RK4");
49 ("XSTART", "Define a plane with horizontal extent [m] from XSTART to XEND and vertical extent from YSTART to YEND", 0.0);
51 ("YSTART", "Define a plane with horizontal extent [m] from XSTART to XEND and vertical extent from YSTART to YEND", 1.0);
53 ("XEND", "Define a plane with horizontal extent [m] from XSTART to XEND and vertical extent from YSTART to YEND", 0.0);
55 ("YEND", "Define a plane with horizontal extent [m] from XSTART to XEND and vertical extent from YSTART to YEND", 0.0);
56
58 "Set to PROBE to define the plane using XSTART, XEND, YSTART, YEND or CENTRE_NORMAL to define the plane using centre and normal", {"CENTRE_NORMAL", "PROBE"}, "PROBE");
60 "Set to 0 for minimal output up to 4 to output diagnostics on every track step. Output is sent to OPAL", 0);
62 setElement(new OutputPlane("OUTPUTPLANE"));
63}
64
65
67 OpalElement(name, parent) {
68 OutputPlane* plane = dynamic_cast<OutputPlane*>(parent->getElement());
69 setElement(new OutputPlane(*plane));
70}
71
72
75
76
78 return new OpalOutputPlane(name, this);
79}
80
83 std::string placementStyle = Attributes::getString(itsAttr[PLACEMENT_STYLE]);
84 OutputPlane *output = dynamic_cast<OutputPlane *>(getElement());
85 Vector_t centre;
86 Vector_t normal;
87 double tolerance = Attributes::getReal(itsAttr[TOLERANCE]);
88 output->setTolerance(tolerance);
89
90 if (placementStyle == "CENTRE_NORMAL") {
91 std::vector<double> centreVec = Attributes::getRealArray(itsAttr[CENTRE]);
92 if (centreVec.size() != 3) {
93 throw OpalException("OpalOutputPlane::update()",
94 "OutputPlane centre should be a 3-vector");
95 }
96 centre = Vector_t(centreVec[0], centreVec[1], centreVec[2]);
97 std::vector<double> normalVec = Attributes::getRealArray(itsAttr[NORMAL]);
98 if (normalVec.size() != 3) {
99 throw OpalException("OpalOutputPlane::update()",
100 "OutputPlane normal should be a 3-vector");
101 }
102 normal = Vector_t(normalVec[0], normalVec[1], normalVec[2]);
103 if (euclidean_norm(normal) < tolerance) {
104 throw OpalException("OpalOutputPlane::update()",
105 "OutputPlane normal was not defined or almost zero");
106 }
107 } else if (placementStyle == "PROBE") {
108 centre = Vector_t(
111 0.0
112 );
113 centre *= 0.5; // average
114 normal = Vector_t(
117 0.0
118 );
119 double width = std::sqrt(normal[0]*normal[0]+normal[1]*normal[1]);
120 if (width < tolerance) {
121 throw OpalException("OpalOutputPlane::update()",
122 "OutputPlane had very small width or size was not defined");
123 }
124 output->setHorizontalExtent(width/2.0);
125 } else {
126 throw OpalException("OpalOutputPlane::update()",
127 "Did not recognise OutputPlane placement style '"+placementStyle+"'");
128 }
129 output->setCentre(centre);
130 output->setNormal(normal);
131
132
133 if (itsAttr[WIDTH]) {
134 double width = Attributes::getReal(itsAttr[WIDTH]);
135 if (width < 0) {
136 throw OpalException("OpalOutputPlane::update()",
137 "OutputPlane had negative width");
138 }
139 output->setHorizontalExtent(width/2.0);
140 }
141 if (itsAttr[HEIGHT]) {
142 double height = Attributes::getReal(itsAttr[HEIGHT]);
143 if (height < 0) {
144 throw OpalException("OpalOutputPlane::update()",
145 "OutputPlane had negative height");
146 }
147 output->setVerticalExtent(height/2.0);
148 }
149 if (itsAttr[RADIUS]) {
150 double radius = Attributes::getReal(itsAttr[RADIUS]);
151 if (radius < 0) {
152 throw OpalException("OpalOutputPlane::update()",
153 "OutputPlane had negative radius");
154 }
155 output->setRadialExtent(radius);
156 }
157
160 int refAlign = std::floor(ref + 0.5);
161 if (refAlign >= 0) { // disabled if negative
162 output->setRecentre(refAlign);
163 }
164 } else {
165 output->setRecentre(-1);
166 }
167 std::string algorithm = Attributes::getString(itsAttr[ALGORITHM]);
168 if (algorithm == "RK4") {
170 } else if (algorithm == "INTERPOLATION") {
172 }
175 // Transmit "unknown" attributes.
177}
T euclidean_norm(const Vector< T > &)
Euclidean norm.
Definition Vector.h:243
const std::string docstring
const std::string name
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.
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.
ElementBase * getElement() const
Return the embedded CLASSIC element.
Definition Element.h:120
void setElement(ElementBase *)
Assign new CLASSIC element.
Definition Element.h:125
std::vector< Attribute > itsAttr
The object attributes.
Definition Object.h:216
void setOutputFN(std::string fn)
Set output filename.
void setAlgorithm(algorithm alg)
void setVerticalExtent(double z)
void setCentre(Vector_t centre)
void setNormal(Vector_t normal)
void setTolerance(double tolerance)
void setRadialExtent(double r)
void setVerboseLevel(int verbose)
void setHorizontalExtent(double width)
void setRecentre(int willRecentre)
virtual void updateUnknown(ElementBase *)
Transmit the ``unknown'' (not known to OPAL) attributes to CLASSIC.
virtual void update()
Update the embedded CLASSIC element.
OpalElement(int size, const char *name, const char *help)
Exemplar constructor.
void registerOwnership() const
OpalOutputPlane()
Exemplar constructor.
virtual ~OpalOutputPlane()
virtual void update()
Fill in all registered attributes.
virtual OpalOutputPlane * clone(const std::string &name)
Make clone.
The base class for all OPAL exceptions.
Vektor< double, 3 > Vector_t