CMS 3D CMS Logo

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