CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/DetectorDescription/Parser/src/DDLRotationAndReflection.cc

Go to the documentation of this file.
00001 /***************************************************************************
00002                           DDLRotationAndReflection.cc  -  description
00003                              -------------------
00004     begin                : Tue Aug 6 2002
00005     email                : case@ucdhep.ucdavis.edu
00006 ***************************************************************************/
00007 
00008 /***************************************************************************
00009  *                                                                         *
00010  *           DDDParser sub-component of DDD                                *
00011  *                                                                         *
00012  ***************************************************************************/
00013 
00014 #include "DetectorDescription/Parser/src/DDLRotationAndReflection.h"
00015 
00016 #include "DetectorDescription/Core/interface/DDName.h"
00017 #include "DetectorDescription/Core/interface/DDTransform.h"
00018 #include "DetectorDescription/Base/interface/DDdebug.h"
00019 
00020 #include "DetectorDescription/ExprAlgo/interface/ExprEvalSingleton.h"
00021 
00022 //CLHEP dependency
00023 #include "CLHEP/Units/GlobalSystemOfUnits.h"
00024 
00025 #include <cmath>
00026 
00027 DDLRotationAndReflection::DDLRotationAndReflection( DDLElementRegistry* myreg )
00028   : DDXMLElement( myreg ) 
00029 {}
00030 
00031 DDLRotationAndReflection::~DDLRotationAndReflection( void )
00032 {}
00033 
00034 void
00035 DDLRotationAndReflection::processElement( const std::string& name, const std::string& nmspace, DDCompactView& cpv )
00036 {
00037 
00038   DCOUT_V('P', "DDLRotationAndReflection::processElement started " << name);
00039 
00040   DD3Vector x = makeX(nmspace);
00041   DD3Vector y = makeY(nmspace);
00042   DD3Vector z = makeZ(nmspace);
00043 
00044   DDXMLAttribute atts = getAttributeSet();
00045 
00046 
00047   if ((name == "Rotation") && isLeftHanded(x, y, z, nmspace) == 0)
00048   {
00049     DDRotationMatrix* ddr = new DDRotationMatrix(x, y, z);
00050     DDRotation ddrot = DDrot(getDDName(nmspace), ddr);
00051     DCOUT_V ('p', "Rotation created: " << ddrot << std::endl);
00052   }
00053   else if ((name == "Rotation")  && isLeftHanded(x, y, z, nmspace) == 1)
00054   {
00055     std::string msg("\nDDLRotationAndReflection attempted to make a");
00056     msg += " left-handed rotation with a Rotation element. If";
00057     msg += " you meant to make a reflection, use ReflectionRotation";
00058     msg += " elements, otherwise, please check your matrix.  Other";
00059     msg += " errors may follow.  Rotation  matrix not created.";
00060     edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could become a throwWarning or something.
00061   }
00062   else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 1) 
00063   {
00064     ExprEvalInterface & ev = ExprEvalSingleton::instance();
00065     DDRotation ddrot = 
00066       DDrotReflect(getDDName(nmspace)
00067                    , ev.eval(nmspace, atts.find("thetaX")->second)
00068                    , ev.eval(nmspace, atts.find("phiX")->second)
00069                    , ev.eval(nmspace, atts.find("thetaY")->second)
00070                    , ev.eval(nmspace, atts.find("phiY")->second)
00071                    , ev.eval(nmspace, atts.find("thetaZ")->second)
00072                    , ev.eval(nmspace, atts.find("phiZ")->second));
00073     DCOUT_V ('p', "Rotation created: " << ddrot << std::endl);
00074   }
00075   else if (name == "ReflectionRotation" && isLeftHanded(x, y, z, nmspace) == 0)
00076   {
00077     std::string msg("WARNING:  Attempted to make a right-handed");
00078     msg += " rotation using a ReflectionRotation element. ";
00079     msg += " If you meant to make a Rotation, use Rotation";
00080     msg += " elements, otherwise, please check your matrix.";
00081     msg += "  Other errors may follow.  ReflectionRotation";
00082     msg += " matrix not created.";
00083     edm::LogError("DetectorDescription_Parser_Rotation_and_Reflection") << msg << std::endl; // this could be a throwWarning or something.
00084   }
00085   else
00086   {
00087     std::string msg = "\nDDLRotationAndReflection::processElement tried to process wrong element.";
00088     throwError(msg);
00089   }
00090   // after a rotation or reflection rotation has been processed, clear it
00091   clear();
00092 
00093   DCOUT_V('P', "DDLRotationAndReflection::processElement completed");
00094 }
00095 
00096 
00097 // returns 1 if it is a left-handed CLHEP rotation matrix, 0 if not, but is okay, -1 if 
00098 // it is not an orthonormal matrix.
00099 //
00100 // Upon encountering the end tag of a Rotation element, we've got to feed
00101 // the appropriate rotation in to the DDCore.  This is an attempt to do so.
00102 //
00103 // Basically, I cannibalized code from g3tog4 (see http link below) and then
00104 // provided the information from our DDL to the same calls.  Tim Cox showed me
00105 // how to build the rotation matrix (mathematically) and the g3tog4 code basically
00106 // did the rest.
00107 //
00108 
00109 int
00110 DDLRotationAndReflection::isLeftHanded (DD3Vector x, DD3Vector y, DD3Vector z, const std::string & nmspace)
00111 {
00112   DCOUT_V('P', "DDLRotation::isLeftHanded started");
00113 
00114   int ret = 0;
00115 
00116   /**************** copied and cannibalized code:
00117  
00118   from g3tog4
00119  
00120   http://atlassw1.phy.bnl.gov/lxr/source/external/geant4.3.1/source/g3tog4/src/G4gsrotm.cc
00121 
00122  48         // Construct unit std::vectors 
00123  49     
00124  50     G4ThreeVector x(sin(th1r)*cos(phi1r), sin(th1r)*sin(phi1r), cos(th1r)->second;
00125  51     G4ThreeVector y(sin(th2r)*cos(phi2r), sin(th2r)*sin(phi2r), cos(th2r));
00126  52     G4ThreeVector z(sin(th3r)*cos(phi3r), sin(th3r)*sin(phi3r), cos(th3r));
00127  53 
00128  54         // check for orthonormality and left-handedness
00129  55 
00130  56     G4double check = (x.cross(y))*z;
00131  57     G4double tol = 1.0e-3;
00132  58         
00133  59     if (1-abs(check)>tol) {
00134  60         G4cerr << "Coordinate axes forming rotation matrix "
00135  61                << irot << " are not orthonormal.(" << 1-abs(check) << ")" 
00136  62          << G4std::endl;
00137  63         G4cerr << " thetaX=" << theta1;
00138  64         G4cerr << " phiX=" << phi1;
00139  65         G4cerr << " thetaY=" << theta2;
00140  66         G4cerr << " phiY=" << phi2;
00141  67         G4cerr << " thetaZ=" << theta3;
00142  68         G4cerr << " phiZ=" << phi3;
00143  69         G4cerr << G4std::endl;
00144  70         G4Exception("G4gsrotm error");
00145  71     }
00146  72     else if (1+check<=tol) {
00147  73         G4cerr << "G4gsrotm warning: coordinate axes forming rotation "
00148  74                << "matrix " << irot << " are left-handed" << G4std::endl;
00149  75     }   
00150  76
00151  77     G3toG4RotationMatrix* rotp = new G3toG4RotationMatrix;
00152  78 
00153  79     rotp->SetRotationMatrixByRow(x, y, z);
00154 
00155   ****************/
00156 
00157 
00158   // check for orthonormality and left-handedness
00159   
00160   double check = (x.Cross(y)).Dot(z);
00161   double tol = 1.0e-3;
00162   ExprEvalInterface & ev = ExprEvalSingleton::instance();
00163   DDXMLAttribute atts = getAttributeSet();
00164   
00165   if (1.0-std::abs(check)>tol) {
00166     std::cout << "DDLRotationAndReflection Coordinate axes forming rotation matrix "
00167               << getDDName(nmspace) 
00168               << " are not orthonormal.(tolerance=" << tol 
00169               << " check=" << std::abs(check)  << ")" 
00170               << std::endl
00171               << " thetaX=" << (atts.find("thetaX")->second) 
00172               << ' ' << ev.eval(nmspace, atts.find("thetaX")->second)/deg << std::endl
00173               << " phiX=" << (atts.find("phiX")->second) 
00174               << ' ' << ev.eval(nmspace, atts.find("phiX")->second)/deg << std::endl
00175               << " thetaY=" << (atts.find("thetaY")->second) 
00176               << ' ' << ev.eval(nmspace, atts.find("thetaY")->second)/deg << std::endl
00177               << " phiY=" << (atts.find("phiY")->second)
00178               << ' ' << ev.eval(nmspace, atts.find("phiY")->second)/deg << std::endl
00179               << " thetaZ=" << (atts.find("thetaZ")->second)
00180               << ' ' << ev.eval(nmspace, atts.find("thetaZ")->second)/deg << std::endl
00181               << " phiZ=" << (atts.find("phiZ")->second)
00182               << ' ' << ev.eval(nmspace, atts.find("phiZ")->second)/deg 
00183               << std::endl
00184               << "  WAS NOT CREATED!" << std::endl;
00185     ret = -1;
00186   }
00187   else if (1.0+check<=tol) {
00188     ret = 1;    
00189   }
00190   DCOUT_V('P', "DDLRotation::isLeftHanded completed");
00191   return ret;
00192 }
00193 
00194 DD3Vector
00195 DDLRotationAndReflection::makeX(std::string nmspace)
00196 {
00197   DD3Vector x;
00198   DDXMLAttribute atts = getAttributeSet();
00199   if (atts.find("thetaX") != atts.end())
00200   {
00201     ExprEvalInterface & ev = ExprEvalSingleton::instance(); 
00202     double thetaX = ev.eval(nmspace, atts.find("thetaX")->second.c_str());
00203     double phiX = ev.eval(nmspace, atts.find("phiX")->second.c_str());
00204     // colx
00205     x.SetX(sin(thetaX) * cos(phiX));
00206     x.SetY(sin(thetaX) * sin(phiX));
00207     x.SetZ(cos(thetaX));
00208   }
00209   return x;
00210 }
00211 
00212 DD3Vector
00213 DDLRotationAndReflection::makeY(std::string nmspace)
00214 {
00215   DD3Vector y;
00216   DDXMLAttribute atts = getAttributeSet();
00217   if (atts.find("thetaY") != atts.end())
00218   {
00219     ExprEvalInterface & ev = ExprEvalSingleton::instance(); 
00220     double thetaY = ev.eval(nmspace, atts.find("thetaY")->second.c_str());
00221     double phiY = ev.eval(nmspace, atts.find("phiY")->second.c_str());
00222       
00223     // coly
00224     y.SetX(sin(thetaY) * cos(phiY));
00225     y.SetY(sin(thetaY) * sin(phiY));
00226     y.SetZ(cos(thetaY));
00227   }
00228   return y;
00229 }
00230 
00231 DD3Vector DDLRotationAndReflection::makeZ(std::string nmspace)
00232 {
00233   DD3Vector z;
00234   DDXMLAttribute atts = getAttributeSet();
00235   if (atts.find("thetaZ") != atts.end())
00236   {
00237     ExprEvalInterface & ev = ExprEvalSingleton::instance(); 
00238     double thetaZ = ev.eval(nmspace, atts.find("thetaZ")->second.c_str());
00239     double phiZ = ev.eval(nmspace, atts.find("phiZ")->second.c_str());
00240       
00241     // colz
00242     z.SetX(sin(thetaZ) * cos(phiZ));
00243     z.SetY(sin(thetaZ) * sin(phiZ));
00244     z.SetZ(cos(thetaZ));
00245   }
00246   return z;
00247 }