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