CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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   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   //  std::cout << "making a BLANK " << buf << " named rotation, " << prep_->second << std::endl;
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   //  std::cout << "making a NO-NAME " << baseNoName+ostr2.str() << " named rotation, " << prep_->second << std::endl;
00082   ostr2.clear();
00083   ostr2.str("");
00084 }
00085 
00086 // void DDRotation::clear()
00087 // {
00088 //   StoreT::instance().clear();
00089 // }
00090 
00091 DDRotation DDrot(const DDName & ddname, DDRotationMatrix * rot)
00092 {
00093    // memory of rot goes sto DDRotationImpl!!
00094    //DCOUT('c', "DDrot: new rotation " << ddname);
00095    //if (rot) rot->invert();
00096    return DDRotation(ddname, rot);
00097 }
00098  
00099 // makes sure that the DDRotationMatrix constructed is right-handed and orthogonal.
00100 DDRotation DDrot(const DDName & ddname,
00101                          double thetaX, double phiX,
00102                          double thetaY, double phiY,
00103                          double thetaZ, double phiZ)
00104 {
00105    // define 3 unit std::vectors
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; // Geant4 compatible
00111    double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
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    // memory of rot goes sto DDRotationImpl!!
00129    //DCOUT('c', "DDrot: new rotation " << ddname);
00130 //    if (rot) rot->invert();
00131    return DDRotation(ddname, rot);
00132 }
00133 
00134 
00135 // makes sure that the DDRotationMatrix built is LEFT-handed coordinate system (i.e. reflected)
00136 DDRotation DDrotReflect(const DDName & ddname,
00137                          double thetaX, double phiX,
00138                          double thetaY, double phiY,
00139                          double thetaZ, double phiZ)
00140 {
00141    
00142    // define 3 unit std::vectors forming the new left-handed axes 
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; // Geant4 compatible
00148    double check = (x.Cross(y)).Dot(z); // in case of a LEFT-handed orthogonal system this must be -1
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    //DCOUT('c', "DDrotReflect: new reflection " << ddname);
00159    //rot->invert();
00160    return DDRotation(ddname, rot);  
00161                                                                                          
00162 }               
00163 
00164 
00165 // does NOT check LEFT or Right handed coordinate system takes either.
00166 DDRotationMatrix * DDcreateRotationMatrix(double thetaX, double phiX,
00167                          double thetaY, double phiY,
00168                          double thetaZ, double phiZ)
00169 {
00170    // define 3 unit std::vectors forming the new left-handed axes 
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; // Geant4 compatible
00176    double check = (x.Cross(y)).Dot(z);// in case of a LEFT-handed orthogonal system this must be -1, RIGHT-handed: +1
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 }