CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/DetectorDescription/Core/src/DDRotation.cc

Go to the documentation of this file.
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 // Message logger.
00013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00014 
00015 //static DDRotationMatrix GLOBAL_UNIT;
00016 
00017 //DDBase<DDName,DDRotationMatrix*>::StoreT::pointer_type 
00018 //  DDBase<DDName,DDRotationMatrix*>::StoreT::instance_ = 0;
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   //static bool onlyOnce=true;
00047   //if (onlyOnce) {
00048   //  static DDRotationMatrix* rm_ = new DDRotationMatrix;
00049   //  prep_ = StoreT::instance().create(DDName("",""), rm_ );
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   //  std::cout << "making a BLANK " << baseName+ostr.str() << " named rotation, " << prep_->second << std::endl;
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   //  std::cout << "making a NO-NAME " << baseNoName+ostr2.str() << " named rotation, " << prep_->second << std::endl;
00085   ostr2.clear();
00086   ostr2.str("");
00087 }
00088 
00089 // void DDRotation::clear()
00090 // {
00091 //   StoreT::instance().clear();
00092 // }
00093 
00094 DDRotation DDrot(const DDName & ddname, DDRotationMatrix * rot)
00095 {
00096    // memory of rot goes sto DDRotationImpl!!
00097    //DCOUT('c', "DDrot: new rotation " << ddname);
00098    //if (rot) rot->invert();
00099    return DDRotation(ddname, rot);
00100 }
00101  
00102 // makes sure that the DDRotationMatrix constructed is right-handed and orthogonal.
00103 DDRotation DDrot(const DDName & ddname,
00104                          double thetaX, double phiX,
00105                          double thetaY, double phiY,
00106                          double thetaZ, double phiZ)
00107 {
00108    // define 3 unit std::vectors
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; // Geant4 compatible
00114    double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
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    // memory of rot goes sto DDRotationImpl!!
00132    //DCOUT('c', "DDrot: new rotation " << ddname);
00133 //    if (rot) rot->invert();
00134    return DDRotation(ddname, rot);
00135 }
00136 
00137 
00138 // makes sure that the DDRotationMatrix built is LEFT-handed coordinate system (i.e. reflected)
00139 DDRotation DDrotReflect(const DDName & ddname,
00140                          double thetaX, double phiX,
00141                          double thetaY, double phiY,
00142                          double thetaZ, double phiZ)
00143 {
00144    
00145    // define 3 unit std::vectors forming the new left-handed axes 
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; // Geant4 compatible
00151    double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
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    //DCOUT('c', "DDrotReflect: new reflection " << ddname);
00162    //rot->invert();
00163    return DDRotation(ddname, rot);  
00164                                                                                          
00165 }               
00166 
00167 
00168 // does NOT check LEFT or Right handed coordinate system takes either.
00169 DDRotationMatrix * DDcreateRotationMatrix(double thetaX, double phiX,
00170                          double thetaY, double phiY,
00171                          double thetaZ, double phiZ)
00172 {
00173    // define 3 unit std::vectors forming the new left-handed axes 
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; // Geant4 compatible
00179    double check = (x.Cross(y)).Dot(z);// in case of a LEFT-handed orthogonal system this must be -1, RIGHT-handed: +1
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 }