CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
DDLRotationAndReflection.cc
Go to the documentation of this file.
1 /***************************************************************************
2  DDLRotationAndReflection.cc - description
3  -------------------
4  begin : Tue Aug 6 2002
5  email : case@ucdhep.ucdavis.edu
6 ***************************************************************************/
7 
8 /***************************************************************************
9  * *
10  * DDDParser sub-component of DDD *
11  * *
12  ***************************************************************************/
13 
15 
19 
21 
22 //CLHEP dependency
23 #include "CLHEP/Units/GlobalSystemOfUnits.h"
24 
25 #include <cmath>
26 
28  : DDXMLElement( myreg )
29 {}
30 
32 {}
33 
34 void
36 {
37 
38  DCOUT_V('P', "DDLRotationAndReflection::processElement started " << name);
39 
40  DD3Vector x = makeX(nmspace);
41  DD3Vector y = makeY(nmspace);
42  DD3Vector z = makeZ(nmspace);
43 
45 
46 
47  if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 0)
48  {
49  DDRotationMatrix* ddr = new DDRotationMatrix(x, y, z);
50  DDRotation ddrot = DDrot(getDDName(nmspace), ddr);
51  DCOUT_V ('p', "Rotation created: " << ddrot << std::endl);
52  }
53  else if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 1)
54  {
55  std::string msg("\nDDLRotationAndReflection attempted to make a");
56  msg += " left-handed rotation with a Rotation element. If";
57  msg += " you meant to make a reflection, use ReflectionRotation";
58  msg += " elements, otherwise, please check your matrix. Other";
59  msg += " errors may follow. Rotation matrix not created.";
60  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could become a throwWarning or something.
61  }
62  else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 1)
63  {
65  DDRotation ddrot =
66  DDrotReflect(getDDName(nmspace)
67  , ev.eval(nmspace, atts.find("thetaX")->second)
68  , ev.eval(nmspace, atts.find("phiX")->second)
69  , ev.eval(nmspace, atts.find("thetaY")->second)
70  , ev.eval(nmspace, atts.find("phiY")->second)
71  , ev.eval(nmspace, atts.find("thetaZ")->second)
72  , ev.eval(nmspace, atts.find("phiZ")->second));
73  DCOUT_V ('p', "Rotation created: " << ddrot << std::endl);
74  }
75  else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 0)
76  {
77  std::string msg("WARNING: Attempted to make a right-handed");
78  msg += " rotation using a ReflectionRotation element. ";
79  msg += " If you meant to make a Rotation, use Rotation";
80  msg += " elements, otherwise, please check your matrix.";
81  msg += " Other errors may follow. ReflectionRotation";
82  msg += " matrix not created.";
83  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could be a throwWarning or something.
84  }
85  else
86  {
87  std::string msg = "\nDDLRotationAndReflection::processElement tried to process wrong element.";
88  throwError(msg);
89  }
90  // after a rotation or reflection rotation has been processed, clear it
91  clear();
92 
93  DCOUT_V('P', "DDLRotationAndReflection::processElement completed");
94 }
95 
96 
97 // returns 1 if it is a left-handed CLHEP rotation matrix, 0 if not, but is okay, -1 if
98 // it is not an orthonormal matrix.
99 //
100 // Upon encountering the end tag of a Rotation element, we've got to feed
101 // the appropriate rotation in to the DDCore. This is an attempt to do so.
102 //
103 // Basically, I cannibalized code from g3tog4 (see http link below) and then
104 // provided the information from our DDL to the same calls. Tim Cox showed me
105 // how to build the rotation matrix (mathematically) and the g3tog4 code basically
106 // did the rest.
107 //
108 
109 int
111 {
112  DCOUT_V('P', "DDLRotation::isLeftHanded started");
113 
114  int ret = 0;
115 
116  /**************** copied and cannibalized code:
117 
118  from g3tog4
119 
120  http://atlassw1.phy.bnl.gov/lxr/source/external/geant4.3.1/source/g3tog4/src/G4gsrotm.cc
121 
122  48 // Construct unit std::vectors
123  49
124  50 G4ThreeVector x(sin(th1r)*cos(phi1r), sin(th1r)*sin(phi1r), cos(th1r)->second;
125  51 G4ThreeVector y(sin(th2r)*cos(phi2r), sin(th2r)*sin(phi2r), cos(th2r));
126  52 G4ThreeVector z(sin(th3r)*cos(phi3r), sin(th3r)*sin(phi3r), cos(th3r));
127  53
128  54 // check for orthonormality and left-handedness
129  55
130  56 G4double check = (x.cross(y))*z;
131  57 G4double tol = 1.0e-3;
132  58
133  59 if (1-abs(check)>tol) {
134  60 G4cerr << "Coordinate axes forming rotation matrix "
135  61 << irot << " are not orthonormal.(" << 1-abs(check) << ")"
136  62 << G4std::endl;
137  63 G4cerr << " thetaX=" << theta1;
138  64 G4cerr << " phiX=" << phi1;
139  65 G4cerr << " thetaY=" << theta2;
140  66 G4cerr << " phiY=" << phi2;
141  67 G4cerr << " thetaZ=" << theta3;
142  68 G4cerr << " phiZ=" << phi3;
143  69 G4cerr << G4std::endl;
144  70 G4Exception("G4gsrotm error");
145  71 }
146  72 else if (1+check<=tol) {
147  73 G4cerr << "G4gsrotm warning: coordinate axes forming rotation "
148  74 << "matrix " << irot << " are left-handed" << G4std::endl;
149  75 }
150  76
151  77 G3toG4RotationMatrix* rotp = new G3toG4RotationMatrix;
152  78
153  79 rotp->SetRotationMatrixByRow(x, y, z);
154 
155  ****************/
156 
157 
158  // check for orthonormality and left-handedness
159 
160  double check = (x.Cross(y)).Dot(z);
161  double tol = 1.0e-3;
164 
165  if (1.0-std::abs(check)>tol) {
166  std::cout << "DDLRotationAndReflection Coordinate axes forming rotation matrix "
167  << getDDName(nmspace)
168  << " are not orthonormal.(tolerance=" << tol
169  << " check=" << std::abs(check) << ")"
170  << std::endl
171  << " thetaX=" << (atts.find("thetaX")->second)
172  << ' ' << ev.eval(nmspace, atts.find("thetaX")->second)/deg << std::endl
173  << " phiX=" << (atts.find("phiX")->second)
174  << ' ' << ev.eval(nmspace, atts.find("phiX")->second)/deg << std::endl
175  << " thetaY=" << (atts.find("thetaY")->second)
176  << ' ' << ev.eval(nmspace, atts.find("thetaY")->second)/deg << std::endl
177  << " phiY=" << (atts.find("phiY")->second)
178  << ' ' << ev.eval(nmspace, atts.find("phiY")->second)/deg << std::endl
179  << " thetaZ=" << (atts.find("thetaZ")->second)
180  << ' ' << ev.eval(nmspace, atts.find("thetaZ")->second)/deg << std::endl
181  << " phiZ=" << (atts.find("phiZ")->second)
182  << ' ' << ev.eval(nmspace, atts.find("phiZ")->second)/deg
183  << std::endl
184  << " WAS NOT CREATED!" << std::endl;
185  ret = -1;
186  }
187  else if (1.0+check<=tol) {
188  ret = 1;
189  }
190  DCOUT_V('P', "DDLRotation::isLeftHanded completed");
191  return ret;
192 }
193 
194 DD3Vector
196 {
197  DD3Vector x;
199  if (atts.find("thetaX") != atts.end())
200  {
202  double thetaX = ev.eval(nmspace, atts.find("thetaX")->second.c_str());
203  double phiX = ev.eval(nmspace, atts.find("phiX")->second.c_str());
204  // colx
205  x.SetX(sin(thetaX) * cos(phiX));
206  x.SetY(sin(thetaX) * sin(phiX));
207  x.SetZ(cos(thetaX));
208  }
209  return x;
210 }
211 
212 DD3Vector
214 {
215  DD3Vector y;
217  if (atts.find("thetaY") != atts.end())
218  {
220  double thetaY = ev.eval(nmspace, atts.find("thetaY")->second.c_str());
221  double phiY = ev.eval(nmspace, atts.find("phiY")->second.c_str());
222 
223  // coly
224  y.SetX(sin(thetaY) * cos(phiY));
225  y.SetY(sin(thetaY) * sin(phiY));
226  y.SetZ(cos(thetaY));
227  }
228  return y;
229 }
230 
232 {
233  DD3Vector z;
235  if (atts.find("thetaZ") != atts.end())
236  {
238  double thetaZ = ev.eval(nmspace, atts.find("thetaZ")->second.c_str());
239  double phiZ = ev.eval(nmspace, atts.find("phiZ")->second.c_str());
240 
241  // colz
242  z.SetX(sin(thetaZ) * cos(phiZ));
243  z.SetY(sin(thetaZ) * sin(phiZ));
244  z.SetZ(cos(thetaZ));
245  }
246  return z;
247 }
void processElement(const std::string &name, const std::string &nmspace, DDCompactView &cpv)
Processing the element.
DD3Vector makeZ(std::string nmspace)
DD3Vector makeX(std::string nmspace)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
virtual const DDXMLAttribute & getAttributeSet(size_t aIndex=0) const
Get a &quot;row&quot; of attributes, i.e. one attribute set.
Definition: DDXMLElement.cc:79
void throwError(const std::string &keyMessage) const
format std::string for throw an error.
#define abs(x)
Definition: mlp_lapack.h:159
type of data representation of DDCompactView
Definition: DDCompactView.h:77
float float float z
std::map< std::string, std::string > DDXMLAttribute
Definition: DDXMLElement.h:55
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:66
static value_type & instance()
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
A DD Translation is currently implemented with Root Vector3D.
Definition: DDTranslation.h:6
bool check(const DataFrame &df, bool capcheck, bool dvercheck)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
Interface of an Expression Evaluator.
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:136
DD3Vector makeY(std::string nmspace)
DDRotation DDrot(const DDName &name, DDRotationMatrix *rot)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:91
#define DCOUT_V(M_v_Y, M_v_S)
Definition: DDdebug.h:54
virtual double eval(const std::string &ns, const std::string &expr)=0
evaluate an expression expr inside the local namespace
DDLRotationAndReflection(DDLElementRegistry *myreg)
Constructor.
This is a base class for processing XML elements in the DDD.
Definition: DDXMLElement.h:58
~DDLRotationAndReflection(void)
Destructor.
The main class for processing parsed elements.
tuple cout
Definition: gather_cfg.py:121
virtual void clear(void)
clear this element&#39;s contents.
Definition: DDXMLElement.cc:61
Definition: DDAxes.h:10
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:86
int isLeftHanded(DD3Vector x, DD3Vector y, DD3Vector z, const std::string &nmspace)
returns 1 = left handed rotation matrix, 0 = right-handed, -1 = not orthonormal.