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 static std::string baseName("DdBlNa");
00050 static int countBlank;
00051 static std::ostringstream ostr;
00052 ostr << countBlank++;
00053 prep_ = StoreT::instance().create(DDName(baseName+ostr.str(),baseName), new DDRotationMatrix );
00054
00055 ostr.clear();
00056 ostr.str("");
00057 }
00058
00059
00060 DDRotation::DDRotation(const DDName & name) : DDBase<DDName,DDRotationMatrix*>()
00061 {
00062 prep_ = StoreT::instance().create(name);
00063
00064 }
00065
00066
00067 DDRotation::DDRotation(const DDName & name, DDRotationMatrix * rot)
00068 : DDBase<DDName,DDRotationMatrix*>()
00069 {
00070 prep_ = StoreT::instance().create(name,rot);
00071
00072 }
00073
00074
00075 DDRotation::DDRotation(DDRotationMatrix * rot)
00076 : DDBase<DDName,DDRotationMatrix*>()
00077 {
00078 static std::string baseNoName("DdNoNa");
00079 static int countNN;
00080 static std::ostringstream ostr2;
00081 ostr2 << countNN++;
00082 prep_ = StoreT::instance().create(DDName(baseNoName+ostr2.str(), baseNoName), rot);
00083
00084 ostr2.clear();
00085 ostr2.str("");
00086 }
00087
00088
00089
00090
00091
00092
00093 DDRotation DDrot(const DDName & ddname, DDRotationMatrix * rot)
00094 {
00095
00096
00097
00098 return DDRotation(ddname, rot);
00099 }
00100
00101
00102 DDRotation DDrot(const DDName & ddname,
00103 double thetaX, double phiX,
00104 double thetaY, double phiY,
00105 double thetaZ, double phiZ)
00106 {
00107
00108 DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
00109 DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
00110 DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
00111
00112 double tol = 1.0e-3;
00113 double check = (x.Cross(y)).Dot(z);
00114 if (fabs(1.-check)>tol) {
00115 edm::LogError("DDRotation") << ddname << " is not a RIGHT-handed orthonormal matrix!" << std::endl;
00116 throw cms::Exception("DDException") << ddname.name() << " is not RIGHT-handed!";
00117 }
00118
00119 DDRotationMatrix* rot = new DDRotationMatrix(x.x(),y.x(),z.x(),
00120 x.y(),y.y(),z.y(),
00121 x.z(),y.z(),z.z());
00122
00123 return DDRotation(ddname, rot);
00124
00125 }
00126
00127
00128 DDRotation DDrotReflect(const DDName & ddname, DDRotationMatrix * rot)
00129 {
00130
00131
00132
00133 return DDRotation(ddname, rot);
00134 }
00135
00136
00137
00138 DDRotation DDrotReflect(const DDName & ddname,
00139 double thetaX, double phiX,
00140 double thetaY, double phiY,
00141 double thetaZ, double phiZ)
00142 {
00143
00144
00145 DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
00146 DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
00147 DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
00148
00149 double tol = 1.0e-3;
00150 double check = (x.Cross(y)).Dot(z);
00151 if (fabs(1.+check)>tol) {
00152 edm::LogError("DDRotation") << ddname << " is not a LEFT-handed orthonormal matrix!" << std::endl;
00153 throw cms::Exception("DDException") << ddname.name() << " is not LEFT-handed!";
00154 }
00155
00156 DDRotationMatrix* rot = new DDRotationMatrix(x.x(),y.x(),z.x(),
00157 x.y(),y.y(),z.y(),
00158 x.z(),y.z(),z.z());
00159
00160
00161
00162 return DDRotation(ddname, rot);
00163
00164 }
00165
00166
00167
00168 DDRotationMatrix * DDcreateRotationMatrix(double thetaX, double phiX,
00169 double thetaY, double phiY,
00170 double thetaZ, double phiZ)
00171 {
00172
00173 DD3Vector x(cos(phiX)*sin(thetaX), sin(phiX)*sin(thetaX), cos(thetaX));
00174 DD3Vector y(cos(phiY)*sin(thetaY), sin(phiY)*sin(thetaY), cos(thetaY));
00175 DD3Vector z(cos(phiZ)*sin(thetaZ), sin(phiZ)*sin(thetaZ), cos(thetaZ));
00176
00177 double tol = 1.0e-3;
00178 double check = (x.Cross(y)).Dot(z);
00179 if ((1.-fabs(check))>tol) {
00180 std::ostringstream o;
00181 o << "matrix is not an (left or right handed) orthonormal matrix! (in deg)" << std::endl
00182 << " thetaX=" << thetaX/deg << " phiX=" << phiX/deg << std::endl
00183 << " thetaY=" << thetaY/deg << " phiY=" << phiY/deg << std::endl
00184 << " thetaZ=" << thetaZ/deg << " phiZ=" << phiZ/deg << std::endl;
00185 edm::LogError("DDRotation") << o.str() << std::endl;
00186
00187
00188 throw cms::Exception("DDException") << o.str();
00189 }
00190
00191 return new DDRotationMatrix(x.x(),y.x(),z.x(),
00192 x.y(),y.y(),z.y(),
00193 x.z(),y.z(),z.z());
00194 }
00195
00196
00197 DDRotation DDanonymousRot(DDRotationMatrix * rot)
00198 {
00199 return DDRotation(rot);
00200 }