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 
25  DD3Vector x = makeX(nmspace);
26  DD3Vector y = makeY(nmspace);
27  DD3Vector z = makeZ(nmspace);
28 
30 
31  if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 0) {
32  DDRotation ddrot = DDrot(getDDName(nmspace), std::make_unique<DDRotationMatrix>(x, y, z));
33  } else if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 1) {
34  std::string msg("\nDDLRotationAndReflection attempted to make a");
35  msg += " left-handed rotation with a Rotation element. If";
36  msg += " you meant to make a reflection, use ReflectionRotation";
37  msg += " elements, otherwise, please check your matrix. Other";
38  msg += " errors may follow. Rotation matrix not created.";
39  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection")
40  << msg << std::endl; // this could become a throwWarning or something.
41  } else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 1) {
43  DDRotation ddrot = DDrotReflect(getDDName(nmspace),
44  ev.eval(nmspace, atts.find("thetaX")->second),
45  ev.eval(nmspace, atts.find("phiX")->second),
46  ev.eval(nmspace, atts.find("thetaY")->second),
47  ev.eval(nmspace, atts.find("phiY")->second),
48  ev.eval(nmspace, atts.find("thetaZ")->second),
49  ev.eval(nmspace, atts.find("phiZ")->second));
50  } else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 0) {
51  std::string msg("WARNING: Attempted to make a right-handed");
52  msg += " rotation using a ReflectionRotation element. ";
53  msg += " If you meant to make a Rotation, use Rotation";
54  msg += " elements, otherwise, please check your matrix.";
55  msg += " Other errors may follow. ReflectionRotation";
56  msg += " matrix not created.";
57  edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection")
58  << msg << std::endl; // this could be a throwWarning or something.
59  } else {
60  std::string msg = "\nDDLRotationAndReflection::processElement tried to process wrong element.";
61  throwError(msg);
62  }
63  // after a rotation or reflection rotation has been processed, clear it
64  clear();
65 }
66 
67 // returns 1 if it is a left-handed CLHEP rotation matrix, 0 if not, but is okay, -1 if
68 // it is not an orthonormal matrix.
69 //
70 // Upon encountering the end tag of a Rotation element, we've got to feed
71 // the appropriate rotation in to the DDCore. This is an attempt to do so.
72 //
73 // Basically, I cannibalized code from g3tog4 (see http link below) and then
74 // provided the information from our DDL to the same calls. Tim Cox showed me
75 // how to build the rotation matrix (mathematically) and the g3tog4 code basically
76 // did the rest.
77 //
78 
80  const DD3Vector& y,
81  const DD3Vector& z,
82  const std::string& nmspace) {
83  int ret = 0;
84 
85  // check for orthonormality and left-handedness
86 
87  double check = (x.Cross(y)).Dot(z);
88  double tol = 1.0e-3;
91 
92  if (1.0 - std::abs(check) > tol) {
93  std::cout << "DDLRotationAndReflection Coordinate axes forming rotation matrix " << getDDName(nmspace)
94  << " are not orthonormal.(tolerance=" << tol << " check=" << std::abs(check) << ")" << std::endl
95  << " thetaX=" << (atts.find("thetaX")->second) << ' '
96  << convertRadToDeg(ev.eval(nmspace, atts.find("thetaX")->second)) << std::endl
97  << " phiX=" << (atts.find("phiX")->second) << ' '
98  << convertRadToDeg(ev.eval(nmspace, atts.find("phiX")->second)) << std::endl
99  << " thetaY=" << (atts.find("thetaY")->second) << ' '
100  << convertRadToDeg(ev.eval(nmspace, atts.find("thetaY")->second)) << std::endl
101  << " phiY=" << (atts.find("phiY")->second) << ' '
102  << convertRadToDeg(ev.eval(nmspace, atts.find("phiY")->second)) << std::endl
103  << " thetaZ=" << (atts.find("thetaZ")->second) << ' '
104  << convertRadToDeg(ev.eval(nmspace, atts.find("thetaZ")->second)) << std::endl
105  << " phiZ=" << (atts.find("phiZ")->second) << ' '
106  << convertRadToDeg(ev.eval(nmspace, atts.find("phiZ")->second)) << std::endl
107  << " WAS NOT CREATED!" << std::endl;
108  ret = -1;
109  } else if (1.0 + check <= tol) {
110  ret = 1;
111  }
112  return ret;
113 }
114 
116  DD3Vector x;
118  if (atts.find("thetaX") != atts.end()) {
120  double thetaX = ev.eval(nmspace, atts.find("thetaX")->second);
121  double phiX = ev.eval(nmspace, atts.find("phiX")->second);
122  // colx
123  x.SetX(sin(thetaX) * cos(phiX));
124  x.SetY(sin(thetaX) * sin(phiX));
125  x.SetZ(cos(thetaX));
126  }
127  return x;
128 }
129 
131  DD3Vector y;
133  if (atts.find("thetaY") != atts.end()) {
135  double thetaY = ev.eval(nmspace, atts.find("thetaY")->second);
136  double phiY = ev.eval(nmspace, atts.find("phiY")->second);
137 
138  // coly
139  y.SetX(sin(thetaY) * cos(phiY));
140  y.SetY(sin(thetaY) * sin(phiY));
141  y.SetZ(cos(thetaY));
142  }
143  return y;
144 }
145 
147  DD3Vector z;
149  if (atts.find("thetaZ") != atts.end()) {
151  double thetaZ = ev.eval(nmspace, atts.find("thetaZ")->second);
152  double phiZ = ev.eval(nmspace, atts.find("phiZ")->second);
153 
154  // colz
155  z.SetX(sin(thetaZ) * cos(phiZ));
156  z.SetY(sin(thetaZ) * sin(phiZ));
157  z.SetZ(cos(thetaZ));
158  }
159  return z;
160 }
DDLElementRegistry * myRegistry_
Definition: DDXMLElement.h:173
ret
prodAgent to be discontinued
constexpr NumType convertRadToDeg(NumType radians)
Definition: angle_units.h:21
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
Log< level::Error, false > LogError
Compact representation of the geometrical detector hierarchy.
Definition: DDCompactView.h:81
DD3Vector makeZ(const std::string &nmspace)
float float float z
std::map< std::string, std::string > DDXMLAttribute
Definition: DDXMLElement.h:45
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:57
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double > > DD3Vector
DD3Vector makeX(const std::string &nmspace)
ClhepEvaluator & evaluator()
virtual const DDXMLAttribute & getAttributeSet(size_t aIndex=0) const
Get a "row" of attributes, i.e. one attribute set.
Definition: DDXMLElement.cc:54
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:101
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:67
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:285
float x
The main class for processing parsed elements.
virtual void clear(void)
clear this element&#39;s contents.
Definition: DDXMLElement.cc:40
void throwError(const std::string &keyMessage) const
format std::string for throw an error.
virtual const DDName getDDName(const std::string &defaultNS, const std::string &attname=std::string("name"), size_t aIndex=0)
Definition: DDXMLElement.cc:56
DD3Vector makeY(const std::string &nmspace)