CMS 3D CMS Logo

DDRotation.cc
Go to the documentation of this file.
1 #include <cstdio>
2 #include <atomic>
3 #include <cmath>
4 #include <sstream>
5 #include <string>
6 
15 #include "Math/GenVector/AxisAngle.h"
16 #include "Math/GenVector/Cartesian3D.h"
17 #include "Math/GenVector/DisplacementVector3D.h"
18 
19 using namespace geant_units::operators;
20 
21 std::ostream & operator<<(std::ostream & os, const DDRotation & r)
22 {
24  if (defined.first) {
25  os << *(defined.first) << " ";
26  if (defined.second) {
27  const DDRotationMatrix & rm = r.rotation();
28  DDAxisAngle ra(rm);
29  os << "t=" << convertRadToDeg( ra.Axis().Theta() ) << "deg "
30  << "p=" << convertRadToDeg( ra.Axis().Phi() ) << "deg "
31  << "a=" << convertRadToDeg( ra.Angle() ) << "deg";
32  }
33  else {
34  os << "* rotation not defined * ";
35  }
36  }
37  else {
38  os << "* rotation not declared * ";
39  }
40  return os;
41 }
42 
44  : DDBase< DDName, std::unique_ptr<DDRotationMatrix> >()
45 {
46  constexpr char const* baseName = "DdBlNa";
47  // In this particular case, we do not really care about multiple threads
48  // using the same counter, we simply need to have a unique id for the
49  // blank matrix being created, so just making this static an atomic should do
50  // the trick. In order to ensure repeatibility one should also include some
51  // some run specific Id, I guess. Not sure it really matters.
52  static std::atomic<int> countBlank;
53  char buf[64];
54  snprintf( buf, 64, "%s%i", baseName, countBlank++ );
55  create( DDName( buf, baseName ), std::make_unique<DDRotationMatrix>());
56 }
57 
59  : DDBase< DDName, std::unique_ptr<DDRotationMatrix>>()
60 {
61  create( name );
62 }
63 
64 DDRotation::DDRotation( const DDName & name, std::unique_ptr<DDRotationMatrix> rot )
65  : DDBase< DDName, std::unique_ptr<DDRotationMatrix>>()
66 {
67  create( name, std::move( rot ));
68 }
69 
70 DDRotation::DDRotation( std::unique_ptr<DDRotationMatrix> rot )
71  : DDBase< DDName, std::unique_ptr<DDRotationMatrix>>()
72 {
73  static std::atomic<int> countNN;
74  char buf[64];
75  snprintf(buf, 64, "DdNoNa%i", countNN++);
76  create( DDName( buf, "DdNoNa" ), std::move( rot ));
77 }
78 
80 DDrot( const DDName & ddname, std::unique_ptr<DDRotationMatrix> rot )
81 {
82  // memory of rot goes sto DDRotationImpl!!
83  return DDRotation(ddname, std::move( rot ));
84 }
85 
86 std::unique_ptr<DDRotation>
87 DDrotPtr( const DDName & ddname, std::unique_ptr<DDRotationMatrix> rot )
88 {
89  // memory of rot goes sto DDRotationImpl!!
90  return std::make_unique<DDRotation>( ddname, std::move( rot ));
91 }
92 
93 // makes sure that the DDRotationMatrix constructed is right-handed and orthogonal.
95  double thetaX, double phiX,
96  double thetaY, double phiY,
97  double thetaZ, double phiZ)
98 {
99  // define 3 unit std::vectors
100  DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
101  DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
102  DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
103 
104  double tol = 1.0e-3; // Geant4 compatible
105  double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
106  if (fabs(1.-check)>tol) {
107  edm::LogError("DDRotation") << ddname << " is not a RIGHT-handed orthonormal matrix!" << std::endl;
108  throw cms::Exception("DDException") << ddname.name() << " is not RIGHT-handed!";
109  }
110 
111  return DDRotation( ddname,
112  std::make_unique<DDRotationMatrix>(x.x(),y.x(),z.x(),
113  x.y(),y.y(),z.y(),
114  x.z(),y.z(),z.z()));
115 }
116 
118 DDrotReflect( const DDName & ddname, std::unique_ptr<DDRotationMatrix> rot )
119 {
120  return DDRotation( ddname, std::move( rot ));
121 }
122 
123 // makes sure that the DDRotationMatrix built is LEFT-handed coordinate system (i.e. reflected)
125  double thetaX, double phiX,
126  double thetaY, double phiY,
127  double thetaZ, double phiZ )
128 {
129  // define 3 unit std::vectors forming the new left-handed axes
130  DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
131  DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
132  DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
133 
134  double tol = 1.0e-3; // Geant4 compatible
135  double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
136  if (fabs(1.+check)>tol) {
137  edm::LogError("DDRotation") << ddname << " is not a LEFT-handed orthonormal matrix!" << std::endl;
138  throw cms::Exception("DDException") << ddname.name() << " is not LEFT-handed!";
139  }
140 
141  return DDRotation( ddname,
142  std::make_unique<DDRotationMatrix>(x.x(),y.x(),z.x(),
143  x.y(),y.y(),z.y(),
144  x.z(),y.z(),z.z()));
145 }
146 
147 // does NOT check LEFT or Right handed coordinate system takes either.
148 std::unique_ptr<DDRotationMatrix>
149 DDcreateRotationMatrix( double thetaX, double phiX,
150  double thetaY, double phiY,
151  double thetaZ, double phiZ )
152 {
153  // define 3 unit std::vectors forming the new left-handed axes
154  DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
155  DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
156  DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
157 
158  double tol = 1.0e-3; // Geant4 compatible
159  double check = (x.Cross(y)).Dot(z);// in case of a LEFT-handed orthogonal system this must be -1, RIGHT-handed: +1
160  if ((1.-fabs(check))>tol) {
161  std::ostringstream o;
162  o << "matrix is not an (left or right handed) orthonormal matrix! (in deg)" << std::endl
163  << " thetaX=" << convertRadToDeg( thetaX ) << " phiX=" << convertRadToDeg( phiX ) << std::endl
164  << " thetaY=" << convertRadToDeg( thetaY ) << " phiY=" << convertRadToDeg( phiY ) << std::endl
165  << " thetaZ=" << convertRadToDeg( thetaZ ) << " phiZ=" << convertRadToDeg( phiZ ) << std::endl;
166  edm::LogError("DDRotation") << o.str() << std::endl;
167 
168  throw cms::Exception("DDException") << o.str();
169  }
170 
171  return std::make_unique<DDRotationMatrix>(x.x(),y.x(),z.x(),
172  x.y(),y.y(),z.y(),
173  x.z(),y.z(),z.z());
174 }
175 
177 DDanonymousRot( std::unique_ptr<DDRotationMatrix> rot )
178 {
179  return DDRotation( std::move( rot ));
180 }
Definition: DDBase.h:10
def_type isDefined() const
Definition: DDBase.h:107
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
ROOT::Math::Rotation3D DDRotationMatrix
A DDRotationMatrix is currently implemented with a ROOT Rotation3D.
DDName is used to identify DDD entities uniquely.
Definition: DDName.h:15
constexpr NumType convertRadToDeg(NumType radians)
Definition: GeantUnits.h:98
friend DDRotation DDanonymousRot(std::unique_ptr< DDRotationMatrix >)
Defines a anonymous rotation or rotation-reflection matrix.
Definition: DDRotation.cc:177
Represents a uniquely identifyable rotation matrix.
Definition: DDTransform.h:68
std::ostream & operator<<(std::ostream &os, const DDRotation &r)
Definition: DDRotation.cc:21
friend std::unique_ptr< DDRotation > DDrotPtr(const DDName &, std::unique_ptr< DDRotationMatrix >)
Definition: DDRotation.cc:87
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
friend DDRotation DDrotReflect(const DDName &, double, double, double, double, double, double)
Defines a rotation-reflection in the Geant3 way.
Definition: DDRotation.cc:124
std::unique_ptr< DDRotationMatrix > DDcreateRotationMatrix(double thetaX, double phiX, double thetaY, double phiY, double thetaZ, double phiZ)
create a new DDRotationMatrix in the GEANT3 style.
Definition: DDRotation.cc:149
std::pair< const N *, bool > def_type
Definition: DDBase.h:66
const DDRotationMatrix & rotation() const
Returns the read-only rotation-matrix.
Definition: DDTransform.h:93
DDRotation()
refers to the unit-rotation (no rotation at all)
Definition: DDRotation.cc:43
def check(config)
Definition: trackerTree.py:14
rm
Definition: submit.py:77
const std::string & name() const
Returns the name.
Definition: DDName.cc:53
def move(src, dest)
Definition: eostools.py:511
ROOT::Math::AxisAngle DDAxisAngle
#define constexpr
friend DDRotation DDrot(const DDName &, std::unique_ptr< DDRotationMatrix >)
Definition of a uniquely identifiable rotation matrix named by DDName name.
Definition: DDRotation.cc:80
void create(const DDName &name, std::unique_ptr< DDRotationMatrix > vals)
Definition: DDBase.h:121