CMS 3D CMS Logo

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