00001 #include <cmath>
00002 #include "DetectorDescription/Core/interface/DDTransform.h"
00003 #include "DetectorDescription/Base/interface/DDTranslation.h"
00004 #include "DetectorDescription/Base/interface/DDdebug.h"
00005 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00006 #include <Math/AxisAngle.h>
00007
00008 #include <sstream>
00009 #include <cstdlib>
00010
00011
00012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00013
00014
00015
00016
00017
00018
00019 std::ostream & operator<<(std::ostream & os, const DDRotation & r)
00020 {
00021 DDBase<DDName,DDRotationMatrix*>::def_type defined(r.isDefined());
00022 if (defined.first) {
00023 os << *(defined.first) << " ";
00024 if (defined.second) {
00025 const DDRotationMatrix & rm = *(r.rotation());
00026 DDAxisAngle ra(rm);
00027 os << "t=" << ra.Axis().Theta()/deg << "deg "
00028 << "p=" << ra.Axis().Phi()/deg << "deg "
00029 << "a=" << ra.Angle()/deg << "deg";
00030 DCOUT_V('R', rm);
00031 }
00032 else {
00033 os << "* rotation not defined * ";
00034 }
00035 }
00036 else {
00037 os << "* rotation not declared * ";
00038 }
00039 return os;
00040 }
00041
00042
00043 DDRotation::DDRotation() : DDBase<DDName,DDRotationMatrix*>()
00044 {
00045
00046
00047
00048
00049 constexpr char const* baseName = "DdBlNa";
00050 static int countBlank;
00051 char buf[64];
00052 snprintf(buf, 64, "%s%i", baseName, countBlank++);
00053 prep_ = StoreT::instance().create(DDName(buf,baseName), new DDRotationMatrix );
00054
00055 }
00056
00057
00058 DDRotation::DDRotation(const DDName & name) : DDBase<DDName,DDRotationMatrix*>()
00059 {
00060 prep_ = StoreT::instance().create(name);
00061
00062 }
00063
00064
00065 DDRotation::DDRotation(const DDName & name, DDRotationMatrix * rot)
00066 : DDBase<DDName,DDRotationMatrix*>()
00067 {
00068 prep_ = StoreT::instance().create(name,rot);
00069
00070 }
00071
00072
00073 DDRotation::DDRotation(DDRotationMatrix * rot)
00074 : DDBase<DDName,DDRotationMatrix*>()
00075 {
00076 static std::string baseNoName("DdNoNa");
00077 static int countNN;
00078 static std::ostringstream ostr2;
00079 ostr2 << countNN++;
00080 prep_ = StoreT::instance().create(DDName(baseNoName+ostr2.str(), baseNoName), rot);
00081
00082 ostr2.clear();
00083 ostr2.str("");
00084 }
00085
00086
00087
00088
00089
00090
00091 DDRotation DDrot(const DDName & ddname, DDRotationMatrix * rot)
00092 {
00093
00094
00095
00096 return DDRotation(ddname, rot);
00097 }
00098
00099
00100 DDRotation DDrot(const DDName & ddname,
00101 double thetaX, double phiX,
00102 double thetaY, double phiY,
00103 double thetaZ, double phiZ)
00104 {
00105
00106 DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
00107 DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
00108 DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
00109
00110 double tol = 1.0e-3;
00111 double check = (x.Cross(y)).Dot(z);
00112 if (fabs(1.-check)>tol) {
00113 edm::LogError("DDRotation") << ddname << " is not a RIGHT-handed orthonormal matrix!" << std::endl;
00114 throw cms::Exception("DDException") << ddname.name() << " is not RIGHT-handed!";
00115 }
00116
00117 DDRotationMatrix* rot = new DDRotationMatrix(x.x(),y.x(),z.x(),
00118 x.y(),y.y(),z.y(),
00119 x.z(),y.z(),z.z());
00120
00121 return DDRotation(ddname, rot);
00122
00123 }
00124
00125
00126 DDRotation DDrotReflect(const DDName & ddname, DDRotationMatrix * rot)
00127 {
00128
00129
00130
00131 return DDRotation(ddname, rot);
00132 }
00133
00134
00135
00136 DDRotation DDrotReflect(const DDName & ddname,
00137 double thetaX, double phiX,
00138 double thetaY, double phiY,
00139 double thetaZ, double phiZ)
00140 {
00141
00142
00143 DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
00144 DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
00145 DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
00146
00147 double tol = 1.0e-3;
00148 double check = (x.Cross(y)).Dot(z);
00149 if (fabs(1.+check)>tol) {
00150 edm::LogError("DDRotation") << ddname << " is not a LEFT-handed orthonormal matrix!" << std::endl;
00151 throw cms::Exception("DDException") << ddname.name() << " is not LEFT-handed!";
00152 }
00153
00154 DDRotationMatrix* rot = new DDRotationMatrix(x.x(),y.x(),z.x(),
00155 x.y(),y.y(),z.y(),
00156 x.z(),y.z(),z.z());
00157
00158
00159
00160 return DDRotation(ddname, rot);
00161
00162 }
00163
00164
00165
00166 DDRotationMatrix * DDcreateRotationMatrix(double thetaX, double phiX,
00167 double thetaY, double phiY,
00168 double thetaZ, double phiZ)
00169 {
00170
00171 DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
00172 DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
00173 DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
00174
00175 double tol = 1.0e-3;
00176 double check = (x.Cross(y)).Dot(z);
00177 if ((1.-fabs(check))>tol) {
00178 std::ostringstream o;
00179 o << "matrix is not an (left or right handed) orthonormal matrix! (in deg)" << std::endl
00180 << " thetaX=" << thetaX/deg << " phiX=" << phiX/deg << std::endl
00181 << " thetaY=" << thetaY/deg << " phiY=" << phiY/deg << std::endl
00182 << " thetaZ=" << thetaZ/deg << " phiZ=" << phiZ/deg << std::endl;
00183 edm::LogError("DDRotation") << o.str() << std::endl;
00184
00185
00186 throw cms::Exception("DDException") << o.str();
00187 }
00188
00189 return new DDRotationMatrix(x.x(),y.x(),z.x(),
00190 x.y(),y.y(),z.y(),
00191 x.z(),y.z(),z.z());
00192 }
00193
00194
00195 DDRotation DDanonymousRot(DDRotationMatrix * rot)
00196 {
00197 return DDRotation(rot);
00198 }