CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Alignment/TrackerAlignment/src/AlignableSiStripDet.cc

Go to the documentation of this file.
00001 /* 
00002  *  $Date: 2010/07/12 11:09:37 $
00003  *  $Revision: 1.8 $
00004  */
00005 
00006 #include "Alignment/TrackerAlignment/interface/AlignableSiStripDet.h"
00007  
00008 #include "Alignment/CommonAlignment/interface/AlignableSurface.h"
00009 
00010 #include "CondFormats/Alignment/interface/AlignmentErrors.h"
00011 #include "CondFormats/Alignment/interface/AlignTransformError.h"
00012 
00013 #include "DataFormats/GeometrySurface/interface/Bounds.h"
00014 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00015 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
00016 #include "DataFormats/GeometrySurface/interface/BoundPlane.h"
00017 #include "DataFormats/GeometrySurface/interface/OpenBounds.h"
00018 #include "DataFormats/GeometrySurface/interface/BoundingBox.h"
00019 #include "DataFormats/GeometrySurface/interface/MediumProperties.h"
00020 #include "Geometry/TrackerGeometryBuilder/interface/PlaneBuilderForGluedDet.h"
00021 #include "Geometry/TrackerGeometryBuilder/interface/GluedGeomDet.h"
00022 #include "Geometry/TrackerGeometryBuilder/interface/StripGeomDetUnit.h"
00023 
00024 #include "FWCore/Utilities/interface/Exception.h"
00025 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00026 
00027 #include <math.h>
00028 
00029 AlignableSiStripDet::AlignableSiStripDet(const GluedGeomDet *gluedDet) 
00030   : AlignableDet(gluedDet, true), // true: adding DetUnits
00031     theMonoBounds  (gluedDet->monoDet()  ->surface().bounds().clone()),
00032     theStereoBounds(gluedDet->stereoDet()->surface().bounds().clone()),
00033     theMonoType  (static_cast<const StripGeomDetUnit*>(gluedDet->monoDet())  ->specificType()),
00034     theStereoType(static_cast<const StripGeomDetUnit*>(gluedDet->stereoDet())->specificType())
00035 {
00036   // It is not allowed to store a pointer to GeomDet within objects with a life time
00037   // longer than an Event: 
00038   // GeomDet comes from TrackerGeometry that is created from GeometricDet that depends on
00039   // IdealGeometryRecord from EventSetup, so it could change in next event!
00040   //  ==> Need to store directly what I need from it. 
00041   // Unfortunately the current way with references for the type does not solve that,
00042   // either. But currently no way out, see header file.
00043 
00044   // check order mono/stereo
00045   const Alignables units(this->components());
00046   if (units.size() != 2
00047       || gluedDet->monoDet()->geographicalId() != units[0]->geomDetId()
00048       || gluedDet->stereoDet()->geographicalId() != units[1]->geomDetId()) {
00049     throw cms::Exception("LogicError")
00050       << "[AlignableSiStripDet] " << "Either != 2 components or "
00051       << "mono/stereo in wrong order for consistifyAlignments.";
00052   }
00053 }
00054 
00055 //__________________________________________________________________________________________________
00056 AlignableSiStripDet::~AlignableSiStripDet()
00057 {
00058   delete theMonoBounds;
00059   delete theStereoBounds;
00060 }
00061 
00062 //__________________________________________________________________________________________________
00063 Alignments* AlignableSiStripDet::alignments() const
00064 {
00065   const_cast<AlignableSiStripDet*>(this)->consistifyAlignments();
00066 
00067   return this->AlignableDet::alignments();
00068 }
00069 
00070 //__________________________________________________________________________________________________
00071 void AlignableSiStripDet::consistifyAlignments()
00072 {
00073   // make alignments consistent with daughters, calling method from geometry
00074 
00075   // The aim of all this gymnastics is to have the alignments calculated the same way as
00076   // in PlaneBuilderForGluedDet::plane(const std::vector<const GeomDetUnit*> &detComps);
00077   // 
00078   // So we take the (new) position and orientation from the AligableDetUnits,
00079   // but bounds and GeomDetType from original GeomDetUnits to create new a new glued
00080   // surface.
00081 
00082   const PositionType oldPos(theSurface.position()); // From old surface for keeping...
00083   const RotationType oldRot(theSurface.rotation()); // ...track of changes.
00084 
00085   const Alignables aliUnits(this->components()); // order mono==0, stereo==1 checked in ctr.
00086   
00087   BoundPlane::BoundPlanePointer monoPlane
00088     = BoundPlane::build(aliUnits[0]->globalPosition(), aliUnits[0]->globalRotation(),
00089                         *theMonoBounds);
00090 
00091   BoundPlane::BoundPlanePointer stereoPlane
00092     = BoundPlane::build(aliUnits[1]->globalPosition(), aliUnits[1]->globalRotation(),
00093                         *theStereoBounds);
00094   
00095   Surface::PositionType::BasicVectorType posSum = monoPlane->position().basicVector();
00096   posSum += stereoPlane->position().basicVector();
00097   Surface::PositionType meanPos(posSum/(float)aliUnits.size());
00098   Surface::RotationType rotation =  monoPlane->rotation();
00099   
00100   BoundPlane::BoundPlanePointer tmpPlane = BoundPlane::build(meanPos, rotation, OpenBounds());
00101 
00102   const MediumProperties* mp = monoPlane->mediumProperties();
00103   MediumProperties newmp(0,0);
00104   if (mp != 0) newmp = MediumProperties(mp->radLen()*2.0,mp->xi()*2.0);
00105 
00106   std::vector<GlobalPoint> corners;
00107   std::vector<GlobalPoint> monoDC = BoundingBox().corners(*monoPlane);
00108   corners.insert(corners.end(), monoDC.begin(), monoDC.end());
00109   std::vector<GlobalPoint> stereoDC = BoundingBox().corners(*stereoPlane);
00110   corners.insert(corners.end(), stereoDC.begin(), stereoDC.end());
00111 
00112   float xmin(0), xmax(0), ymin(0), ymax(0), zmin(0), zmax(0);
00113   for (std::vector<GlobalPoint>::const_iterator i=corners.begin();
00114        i!=corners.end();
00115        ++i) {
00116     LocalPoint p = tmpPlane->toLocal(*i);
00117     if (p.x() < xmin) xmin = p.x();
00118     if (p.x() > xmax) xmax = p.x();
00119     if (p.y() < ymin) ymin = p.y();
00120     if (p.y() > ymax) ymax = p.y();
00121     if (p.z() < zmin) zmin = p.z();
00122     if (p.z() > zmax) zmax = p.z();
00123   }
00124  
00125   LocalVector localOffset((xmin+xmax)/2., (ymin+ymax)/2., (zmin+zmax)/2.);
00126   GlobalVector offset(tmpPlane->toGlobal(localOffset));
00127 
00128   theSurface = AlignableSurface(BoundPlane(meanPos+offset, rotation, 
00129                                            RectangularPlaneBounds((xmax-xmin)/2, (ymax-ymin)/2, (zmax-zmin)/2),
00130                                            &newmp));
00131   
00132   // But do not forget to keep track of movements/rotations:
00133   const GlobalVector theMovement(theSurface.position().basicVector() - oldPos.basicVector());
00134   // Seems to be correct down to delta angles 4.*1e-8:
00135   const RotationType theRotation(oldRot.multiplyInverse(theSurface.rotation()));
00136   this->addDisplacement(theMovement);
00137   this->addRotation(theRotation);
00138   
00139 //   this->dumpCompareEuler(oldRot, theSurface.rotation());
00140 
00141 //   if (movement.mag2()) { // > 1.e-10) { 
00142 //     edm::LogWarning("Alignment") << "@SUB=consistifyAlignments" 
00143 //                               << "Delta: " << movement.x() << " " << movement.y() << " " << movement.z()
00144 //                               << "\nPos: " << oldPos.perp() << " " << oldPos.phi() << " " << oldPos.z();
00145 //   }
00146 }
00147 
00148 // #include "CLHEP/Vector/EulerAngles.h"
00149 // #include "CLHEP/Vector/Rotation.h"
00150 // //__________________________________________________________________________________________________
00151 // void AlignableSiStripDet::dumpCompareEuler(const RotationType &oldRot,
00152 //                                         const RotationType &newRot) const
00153 // {
00154 //   // 
00155 //   const HepRotation oldClhep(HepRep3x3(oldRot.xx(), oldRot.xy(), oldRot.xz(),
00156 //                                     oldRot.yx(), oldRot.yy(), oldRot.yz(),
00157 //                                     oldRot.zx(), oldRot.zy(), oldRot.zz()));
00158 //
00159 //   const HepRotation newClhep(HepRep3x3(newRot.xx(), newRot.xy(), newRot.xz(),
00160 //                                     newRot.yx(), newRot.yy(), newRot.yz(),
00161 //                                     newRot.zx(), newRot.zy(), newRot.zz()));
00162 //
00163 //   const RotationType rotationGlob(oldRot.multiplyInverse(newRot));
00164 //   const RotationType rotation(theSurface.toLocal(rotationGlob)); // not 100% correct: new global...
00165 //   const HepRotation diff(HepRep3x3(rotation.xx(), rotation.xy(), rotation.xz(),
00166 //                                     rotation.yx(), rotation.yy(), rotation.yz(),
00167 //                                     rotation.zx(), rotation.zy(), rotation.zz()));
00168 //
00169 //   edm::LogWarning("Alignment") << "@SUB=dumpCompareEuler" 
00170 //                             << "oldEuler " << oldClhep.eulerAngles()
00171 //                             << "\nnewEuler " << newClhep.eulerAngles()
00172 //                             << "\n diff_euler " << diff.eulerAngles()
00173 //                             << "\n diff_diag (" << diff.xx() << ", " << diff.yy() 
00174 //                             <<         ", " << diff.zz() << ")";
00175 // }