CMS 3D CMS Logo

DDLRotationAndReflection.cc
Go to the documentation of this file.
2 #include "CLHEP/Units/GlobalSystemOfUnits.h"
3 #include "CLHEP/Units/SystemOfUnits.h"
11 #include "Math/GenVector/Cartesian3D.h"
12 #include "Math/GenVector/DisplacementVector3D.h"
13 
14 #include <cmath>
15 #include <iostream>
16 #include <map>
17 #include <utility>
18 
19 class DDCompactView;
20 
22  : DDXMLElement( myreg )
23 {}
24 
25 void
27 {
28  DD3Vector x = makeX(nmspace);
29  DD3Vector y = makeY(nmspace);
30  DD3Vector z = makeZ(nmspace);
31 
33 
34 
35  if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 0)
36  {
37  DDRotationMatrix* ddr = new DDRotationMatrix(x, y, z);
38  DDRotation ddrot = DDrot(getDDName(nmspace), ddr);
39  }
40  else if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 1)
41  {
42  std::string msg("\nDDLRotationAndReflection attempted to make a");
43  msg += " left-handed rotation with a Rotation element. If";
44  msg += " you meant to make a reflection, use ReflectionRotation";
45  msg += " elements, otherwise, please check your matrix. Other";
46  msg += " errors may follow. Rotation matrix not created.";
47  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could become a throwWarning or something.
48  }
49  else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 1)
50  {
52  DDRotation ddrot =
53  DDrotReflect(getDDName(nmspace)
54  , ev.eval(nmspace, atts.find("thetaX")->second)
55  , ev.eval(nmspace, atts.find("phiX")->second)
56  , ev.eval(nmspace, atts.find("thetaY")->second)
57  , ev.eval(nmspace, atts.find("phiY")->second)
58  , ev.eval(nmspace, atts.find("thetaZ")->second)
59  , ev.eval(nmspace, atts.find("phiZ")->second));
60  }
61  else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 0)
62  {
63  std::string msg("WARNING: Attempted to make a right-handed");
64  msg += " rotation using a ReflectionRotation element. ";
65  msg += " If you meant to make a Rotation, use Rotation";
66  msg += " elements, otherwise, please check your matrix.";
67  msg += " Other errors may follow. ReflectionRotation";
68  msg += " matrix not created.";
69  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could be a throwWarning or something.
70  }
71  else
72  {
73  std::string msg = "\nDDLRotationAndReflection::processElement tried to process wrong element.";
74  throwError(msg);
75  }
76  // after a rotation or reflection rotation has been processed, clear it
77  clear();
78 }
79 
80 
81 // returns 1 if it is a left-handed CLHEP rotation matrix, 0 if not, but is okay, -1 if
82 // it is not an orthonormal matrix.
83 //
84 // Upon encountering the end tag of a Rotation element, we've got to feed
85 // the appropriate rotation in to the DDCore. This is an attempt to do so.
86 //
87 // Basically, I cannibalized code from g3tog4 (see http link below) and then
88 // provided the information from our DDL to the same calls. Tim Cox showed me
89 // how to build the rotation matrix (mathematically) and the g3tog4 code basically
90 // did the rest.
91 //
92 
93 int
95 {
96  int ret = 0;
97 
98  /**************** copied and cannibalized code:
99 
100  from g3tog4
101 
102  http://atlassw1.phy.bnl.gov/lxr/source/external/geant4.3.1/source/g3tog4/src/G4gsrotm.cc
103 
104  48 // Construct unit std::vectors
105  49
106  50 G4ThreeVector x(sin(th1r)*cos(phi1r), sin(th1r)*sin(phi1r), cos(th1r)->second;
107  51 G4ThreeVector y(sin(th2r)*cos(phi2r), sin(th2r)*sin(phi2r), cos(th2r));
108  52 G4ThreeVector z(sin(th3r)*cos(phi3r), sin(th3r)*sin(phi3r), cos(th3r));
109  53
110  54 // check for orthonormality and left-handedness
111  55
112  56 G4double check = (x.cross(y))*z;
113  57 G4double tol = 1.0e-3;
114  58
115  59 if (1-abs(check)>tol) {
116  60 G4cerr << "Coordinate axes forming rotation matrix "
117  61 << irot << " are not orthonormal.(" << 1-abs(check) << ")"
118  62 << G4std::endl;
119  63 G4cerr << " thetaX=" << theta1;
120  64 G4cerr << " phiX=" << phi1;
121  65 G4cerr << " thetaY=" << theta2;
122  66 G4cerr << " phiY=" << phi2;
123  67 G4cerr << " thetaZ=" << theta3;
124  68 G4cerr << " phiZ=" << phi3;
125  69 G4cerr << G4std::endl;
126  70 G4Exception("G4gsrotm error");
127  71 }
128  72 else if (1+check<=tol) {
129  73 G4cerr << "G4gsrotm warning: coordinate axes forming rotation "
130  74 << "matrix " << irot << " are left-handed" << G4std::endl;
131  75 }
132  76
133  77 G3toG4RotationMatrix* rotp = new G3toG4RotationMatrix;
134  78
135  79 rotp->SetRotationMatrixByRow(x, y, z);
136 
137  ****************/
138 
139 
140  // check for orthonormality and left-handedness
141 
142  double check = (x.Cross(y)).Dot(z);
143  double tol = 1.0e-3;
146 
147  if (1.0-std::abs(check)>tol) {
148  std::cout << "DDLRotationAndReflection Coordinate axes forming rotation matrix "
149  << getDDName(nmspace)
150  << " are not orthonormal.(tolerance=" << tol
151  << " check=" << std::abs(check) << ")"
152  << std::endl
153  << " thetaX=" << (atts.find("thetaX")->second)
154  << ' ' << ev.eval(nmspace, atts.find("thetaX")->second)/deg << std::endl
155  << " phiX=" << (atts.find("phiX")->second)
156  << ' ' << ev.eval(nmspace, atts.find("phiX")->second)/deg << std::endl
157  << " thetaY=" << (atts.find("thetaY")->second)
158  << ' ' << ev.eval(nmspace, atts.find("thetaY")->second)/deg << std::endl
159  << " phiY=" << (atts.find("phiY")->second)
160  << ' ' << ev.eval(nmspace, atts.find("phiY")->second)/deg << std::endl
161  << " thetaZ=" << (atts.find("thetaZ")->second)
162  << ' ' << ev.eval(nmspace, atts.find("thetaZ")->second)/deg << std::endl
163  << " phiZ=" << (atts.find("phiZ")->second)
164  << ' ' << ev.eval(nmspace, atts.find("phiZ")->second)/deg
165  << std::endl
166  << " WAS NOT CREATED!" << std::endl;
167  ret = -1;
168  }
169  else if (1.0+check<=tol) {
170  ret = 1;
171  }
172  return ret;
173 }
174 
175 DD3Vector
177 {
178  DD3Vector x;
180  if (atts.find("thetaX") != atts.end())
181  {
183  double thetaX = ev.eval(nmspace, atts.find("thetaX")->second);
184  double phiX = ev.eval(nmspace, atts.find("phiX")->second);
185  // colx
186  x.SetX(sin(thetaX) * cos(phiX));
187  x.SetY(sin(thetaX) * sin(phiX));
188  x.SetZ(cos(thetaX));
189  }
190  return x;
191 }
192 
193 DD3Vector
195 {
196  DD3Vector y;
198  if (atts.find("thetaY") != atts.end())
199  {
201  double thetaY = ev.eval(nmspace, atts.find("thetaY")->second);
202  double phiY = ev.eval(nmspace, atts.find("phiY")->second);
203 
204  // coly
205  y.SetX(sin(thetaY) * cos(phiY));
206  y.SetY(sin(thetaY) * sin(phiY));
207  y.SetZ(cos(thetaY));
208  }
209  return y;
210 }
211 
213 {
214  DD3Vector z;
216  if (atts.find("thetaZ") != atts.end())
217  {
219  double thetaZ = ev.eval(nmspace, atts.find("thetaZ")->second);
220  double phiZ = ev.eval(nmspace, atts.find("phiZ")->second);
221 
222  // colz
223  z.SetX(sin(thetaZ) * cos(phiZ));
224  z.SetY(sin(thetaZ) * sin(phiZ));
225  z.SetZ(cos(thetaZ));
226  }
227  return z;
228 }
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.
bool ev
type of data representation of DDCompactView
Definition: DDCompactView.h:90
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:67
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:137
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
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.
DDRotation DDrot(const DDName &name, DDRotationMatrix *rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:90
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:277
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
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
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)