CMS 3D CMS Logo

DDLRotationAndReflection.cc
Go to the documentation of this file.
10 #include "Math/GenVector/Cartesian3D.h"
11 #include "Math/GenVector/DisplacementVector3D.h"
12 
13 #include <cmath>
14 #include <iostream>
15 #include <map>
16 #include <utility>
17 
18 class DDCompactView;
19 
20 using namespace geant_units::operators;
21 
23  : DDXMLElement( myreg )
24 {}
25 
26 void
28 {
29  DD3Vector x = makeX(nmspace);
30  DD3Vector y = makeY(nmspace);
31  DD3Vector z = makeZ(nmspace);
32 
34 
35  if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 0)
36  {
37  DDRotation ddrot = DDrot( getDDName( nmspace ), std::make_unique<DDRotationMatrix>( x, y, z ));
38  }
39  else if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 1)
40  {
41  std::string msg("\nDDLRotationAndReflection attempted to make a");
42  msg += " left-handed rotation with a Rotation element. If";
43  msg += " you meant to make a reflection, use ReflectionRotation";
44  msg += " elements, otherwise, please check your matrix. Other";
45  msg += " errors may follow. Rotation matrix not created.";
46  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could become a throwWarning or something.
47  }
48  else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 1)
49  {
51  DDRotation ddrot =
52  DDrotReflect(getDDName(nmspace)
53  , ev.eval(nmspace, atts.find("thetaX")->second)
54  , ev.eval(nmspace, atts.find("phiX")->second)
55  , ev.eval(nmspace, atts.find("thetaY")->second)
56  , ev.eval(nmspace, atts.find("phiY")->second)
57  , ev.eval(nmspace, atts.find("thetaZ")->second)
58  , ev.eval(nmspace, atts.find("phiZ")->second));
59  }
60  else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 0)
61  {
62  std::string msg("WARNING: Attempted to make a right-handed");
63  msg += " rotation using a ReflectionRotation element. ";
64  msg += " If you meant to make a Rotation, use Rotation";
65  msg += " elements, otherwise, please check your matrix.";
66  msg += " Other errors may follow. ReflectionRotation";
67  msg += " matrix not created.";
68  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could be a throwWarning or something.
69  }
70  else
71  {
72  std::string msg = "\nDDLRotationAndReflection::processElement tried to process wrong element.";
73  throwError(msg);
74  }
75  // after a rotation or reflection rotation has been processed, clear it
76  clear();
77 }
78 
79 
80 // returns 1 if it is a left-handed CLHEP rotation matrix, 0 if not, but is okay, -1 if
81 // it is not an orthonormal matrix.
82 //
83 // Upon encountering the end tag of a Rotation element, we've got to feed
84 // the appropriate rotation in to the DDCore. This is an attempt to do so.
85 //
86 // Basically, I cannibalized code from g3tog4 (see http link below) and then
87 // provided the information from our DDL to the same calls. Tim Cox showed me
88 // how to build the rotation matrix (mathematically) and the g3tog4 code basically
89 // did the rest.
90 //
91 
92 int
94 {
95  int ret = 0;
96 
97  // check for orthonormality and left-handedness
98 
99  double check = (x.Cross(y)).Dot(z);
100  double tol = 1.0e-3;
103 
104  if (1.0-std::abs(check)>tol) {
105  std::cout << "DDLRotationAndReflection Coordinate axes forming rotation matrix "
106  << getDDName(nmspace)
107  << " are not orthonormal.(tolerance=" << tol
108  << " check=" << std::abs(check) << ")"
109  << std::endl
110  << " thetaX=" << (atts.find("thetaX")->second)
111  << ' ' << convertRadToDeg( ev.eval(nmspace, atts.find("thetaX")->second) ) << std::endl
112  << " phiX=" << (atts.find("phiX")->second)
113  << ' ' << convertRadToDeg( ev.eval(nmspace, atts.find("phiX")->second) ) << std::endl
114  << " thetaY=" << (atts.find("thetaY")->second)
115  << ' ' << convertRadToDeg( ev.eval(nmspace, atts.find("thetaY")->second) ) << std::endl
116  << " phiY=" << (atts.find("phiY")->second)
117  << ' ' << convertRadToDeg( ev.eval(nmspace, atts.find("phiY")->second) ) << std::endl
118  << " thetaZ=" << (atts.find("thetaZ")->second)
119  << ' ' << convertRadToDeg( ev.eval(nmspace, atts.find("thetaZ")->second) ) << std::endl
120  << " phiZ=" << (atts.find("phiZ")->second)
121  << ' ' << convertRadToDeg( ev.eval(nmspace, atts.find("phiZ")->second) )
122  << std::endl
123  << " WAS NOT CREATED!" << std::endl;
124  ret = -1;
125  }
126  else if (1.0+check<=tol) {
127  ret = 1;
128  }
129  return ret;
130 }
131 
132 DD3Vector
134 {
135  DD3Vector x;
137  if (atts.find("thetaX") != atts.end())
138  {
140  double thetaX = ev.eval(nmspace, atts.find("thetaX")->second);
141  double phiX = ev.eval(nmspace, atts.find("phiX")->second);
142  // colx
143  x.SetX(sin(thetaX) * cos(phiX));
144  x.SetY(sin(thetaX) * sin(phiX));
145  x.SetZ(cos(thetaX));
146  }
147  return x;
148 }
149 
150 DD3Vector
152 {
153  DD3Vector y;
155  if (atts.find("thetaY") != atts.end())
156  {
158  double thetaY = ev.eval(nmspace, atts.find("thetaY")->second);
159  double phiY = ev.eval(nmspace, atts.find("phiY")->second);
160 
161  // coly
162  y.SetX(sin(thetaY) * cos(phiY));
163  y.SetY(sin(thetaY) * sin(phiY));
164  y.SetZ(cos(thetaY));
165  }
166  return y;
167 }
168 
169 DD3Vector
171 {
172  DD3Vector z;
174  if (atts.find("thetaZ") != atts.end())
175  {
177  double thetaZ = ev.eval(nmspace, atts.find("thetaZ")->second);
178  double phiZ = ev.eval(nmspace, atts.find("phiZ")->second);
179 
180  // colz
181  z.SetX(sin(thetaZ) * cos(phiZ));
182  z.SetY(sin(thetaZ) * sin(phiZ));
183  z.SetZ(cos(thetaZ));
184  }
185  return z;
186 }
DDLElementRegistry * myRegistry_
Definition: DDXMLElement.h:172
void processElement(const std::string &name, const std::string &nmspace, DDCompactView &cpv) override
Processing the element.
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
virtual const DDXMLAttribute & getAttributeSet(size_t aIndex=0) const
Get a "row" of attributes, i.e. one attribute set.
Definition: DDXMLElement.cc:72
void throwError(const std::string &keyMessage) const
format std::string for throw an error.
constexpr NumType convertRadToDeg(NumType radians)
Definition: GeantUnits.h:98
bool ev
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:80
DD3Vector makeZ(const std::string &nmspace)
std::map< std::string, std::string > DDXMLAttribute
Definition: DDXMLElement.h:45
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:68
DD3Vector makeX(const std::string &nmspace)
ClhepEvaluator & evaluator()
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
A DD Translation is currently implemented with Root Vector3D.
Definition: DDTranslation.h:6
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
DDRotation DDrotReflect(const DDName &name, double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
Defines a rotation-reflection in the Geant3 way.
Definition: DDRotation.cc:124
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
DDRotation DDrot(const DDName &name, std::unique_ptr< DDRotationMatrix > rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:80
int isLeftHanded(const DD3Vector &x, const DD3Vector &y, const DD3Vector &z, const std::string &nmspace)
returns 1 = left handed rotation matrix, 0 = right-handed, -1 = not orthonormal.
DDLRotationAndReflection(DDLElementRegistry *myreg)
This is a base class for processing XML elements in the DDD.
Definition: DDXMLElement.h:48
tuple msg
Definition: mps_check.py:279
double eval(const std::string &ns, const std::string &expr)
The main class for processing parsed elements.
virtual void clear(void)
clear this element&#39;s contents.
Definition: DDXMLElement.cc:54
def check(config)
Definition: trackerTree.py:14
virtual const DDName getDDName(const std::string &defaultNS, const std::string &attname=std::string("name"), size_t aIndex=0)
Definition: DDXMLElement.cc:79
DD3Vector makeY(const std::string &nmspace)