CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Geometry/TrackingGeometryAligner/interface/GeometryAligner.h

Go to the documentation of this file.
00001 #ifndef Geometry_TrackingGeometryAligner_GeometryAligner_h
00002 #define Geometry_TrackingGeometryAligner_GeometryAligner_h
00003 
00004 #include <vector>
00005 #include <algorithm>
00006 #include <iterator>
00007 
00008 #include "FWCore/Utilities/interface/Exception.h"
00009 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00010 
00011 #include "Geometry/CommonDetUnit/interface/DetPositioner.h"
00012 
00013 #include "CondFormats/Alignment/interface/Alignments.h"
00014 #include "CondFormats/Alignment/interface/AlignmentErrors.h"
00015 #include "CondFormats/Alignment/interface/AlignTransform.h"
00016 #include "CondFormats/Alignment/interface/AlignTransformError.h"
00017 #include "CondFormats/Alignment/interface/AlignmentSurfaceDeformations.h"
00018 
00019 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00020 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00021 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00022 #include "DataFormats/GeometryCommonDetAlgo/interface/GlobalError.h"
00023 #include "DataFormats/GeometrySurface/interface/Surface.h"
00024 #include "Geometry/CommonTopologies/interface/SurfaceDeformationFactory.h"
00025 #include "Geometry/CommonTopologies/interface/SurfaceDeformation.h"
00026 
00027 class Alignments;
00028 class AlignmentSurfaceDeformations;
00029 
00031 
00032 class GeometryAligner : public DetPositioner { 
00033 
00034 public:
00035   template<class C> 
00036   void applyAlignments( C* geometry,
00037                         const Alignments* alignments,
00038                         const AlignmentErrors* alignmentErrors,
00039                         const AlignTransform& globalCoordinates );
00040 
00041   template<class C> 
00042   void attachSurfaceDeformations( C* geometry,
00043                                   const AlignmentSurfaceDeformations* surfaceDeformations );
00044 
00045   inline void removeGlobalTransform( const Alignments* alignments,
00046                                      const AlignmentErrors* alignmentErrors,
00047                                      const AlignTransform& globalCoordinates,
00048                                      Alignments* newAlignments,
00049                                      AlignmentErrors* newAlignmentErrors );
00050 };
00051 
00052 
00053 template<class C>
00054 void GeometryAligner::applyAlignments( C* geometry,
00055                                        const Alignments* alignments,
00056                                        const AlignmentErrors* alignmentErrors,
00057                                        const AlignTransform& globalCoordinates )
00058 {
00059 
00060   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::applyAlignments" 
00061                             << "Starting to apply alignments.";
00062 
00063   // Preliminary checks (or we can't loop!)
00064   if ( alignments->m_align.size() != geometry->theMap.size() )
00065         throw cms::Exception("GeometryMismatch") 
00066           << "Size mismatch between geometry (size=" << geometry->theMap.size() 
00067           << ") and alignments (size=" << alignments->m_align.size() << ")";
00068   if ( alignments->m_align.size() != alignmentErrors->m_alignError.size() )
00069         throw cms::Exception("GeometryMismatch") 
00070           << "Size mismatch between geometry (size=" << geometry->theMap.size() 
00071           << ") and alignment errors (size=" << alignmentErrors->m_alignError.size() << ")";
00072 
00073   const AlignTransform::Translation &globalShift = globalCoordinates.translation();
00074   const AlignTransform::Rotation globalRotation = globalCoordinates.rotation(); // by value!
00075   const AlignTransform::Rotation inverseGlobalRotation = globalRotation.inverse();
00076 
00077   // Parallel loop on alignments, alignment errors and geomdets
00078   std::vector<AlignTransform>::const_iterator iAlign = alignments->m_align.begin();
00079   std::vector<AlignTransformError>::const_iterator 
00080         iAlignError = alignmentErrors->m_alignError.begin();
00081   //copy  geometry->theMap to a real map to order it....
00082   std::map<unsigned int, GeomDet*> theMap;
00083   std::copy(geometry->theMap.begin(), geometry->theMap.end(), std::inserter(theMap,theMap.begin()));
00084   unsigned int nAPE = 0;
00085   for ( std::map<unsigned int, GeomDet*>::const_iterator iPair = theMap.begin(); 
00086         iPair != theMap.end(); ++iPair, ++iAlign, ++iAlignError )
00087         {
00088           // Check DetIds
00089           if ( (*iPair).first != (*iAlign).rawId() )
00090             throw cms::Exception("GeometryMismatch") 
00091               << "DetId mismatch between geometry (rawId=" << (*iPair).first
00092               << ") and alignments (rawId=" << (*iAlign).rawId();
00093           
00094           if ( (*iPair).first != (*iAlignError).rawId() )
00095             throw cms::Exception("GeometryMismatch") 
00096               << "DetId mismatch between geometry (rawId=" << (*iPair).first
00097               << ") and alignment errors (rawId=" << (*iAlignError).rawId();
00098 
00099           // Apply global correction
00100           CLHEP::Hep3Vector positionHep = globalRotation * CLHEP::Hep3Vector( (*iAlign).translation() ) + globalShift;
00101           CLHEP::HepRotation rotationHep = CLHEP::HepRotation( (*iAlign).rotation() )  * inverseGlobalRotation;
00102 
00103           // Define new position/rotation objects and apply
00104           Surface::PositionType position( positionHep.x(), positionHep.y(), positionHep.z() );
00105           Surface::RotationType rotation( rotationHep.xx(), rotationHep.xy(), rotationHep.xz(), 
00106                                           rotationHep.yx(), rotationHep.yy(), rotationHep.yz(), 
00107                                           rotationHep.zx(), rotationHep.zy(), rotationHep.zz() );
00108           GeomDet* iGeomDet = (*iPair).second;
00109           this->setGeomDetPosition( *iGeomDet, position, rotation );
00110 
00111           // Alignment Position Error only if non-zero to save memory
00112           GlobalError error( asSMatrix<3>((*iAlignError).matrix()) );
00113 
00114           AlignmentPositionError ape( error );
00115           if (this->setAlignmentPositionError( *iGeomDet, ape ))
00116             ++nAPE;
00117           
00118         }
00119 
00120   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::applyAlignments" 
00121                             << "Finished to apply " << theMap.size() << " alignments with "
00122                             << nAPE << " non-zero APE.";
00123 }
00124 
00125 
00126 template<class C>
00127 void GeometryAligner::attachSurfaceDeformations( C* geometry,
00128                                                  const AlignmentSurfaceDeformations* surfaceDeformations )
00129 {
00130   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::attachSurfaceDeformations" 
00131                             << "Starting to attach surface deformations.";
00132 
00133   //copy geometry->theMapUnit to a real map to order it....
00134   std::map<unsigned int, GeomDetUnit*> theMap;
00135   std::copy(geometry->theMapUnit.begin(), geometry->theMapUnit.end(), std::inserter(theMap, theMap.begin()));
00136   
00137   unsigned int nSurfDef = 0;
00138   unsigned int itemIndex = 0;
00139   std::map<unsigned int, GeomDetUnit*>::const_iterator iPair = theMap.begin();
00140   for ( std::vector<AlignmentSurfaceDeformations::Item>::const_iterator iItem = surfaceDeformations->items().begin();
00141         iItem != surfaceDeformations->items().end();
00142         ++iItem, ++iPair) {
00143     
00144     // Check DetIds
00145     // go forward in map of GeomDetUnits until DetId is found
00146     while ( (*iPair).first != (*iItem).m_rawId ) {
00147 
00148       // remove SurfaceDeformation from GeomDetUnit (i.e. set NULL pointer)
00149       GeomDetUnit* geomDetUnit = (*iPair).second;
00150       this->setSurfaceDeformation( *geomDetUnit, 0 );
00151 
00152       ++iPair;
00153       if ( iPair==theMap.end() )
00154         throw cms::Exception("GeometryMismatch") 
00155           << "GeomDetUnit with rawId=" << (*iItem).m_rawId
00156           << " not found in geometry";
00157     }
00158     
00159     // get the parameters and put them into a vector
00160     AlignmentSurfaceDeformations::ParametersConstIteratorPair iteratorPair = surfaceDeformations->parameters(itemIndex);
00161     std::vector<double> parameters;
00162     std::copy(iteratorPair.first, iteratorPair.second, std::back_inserter(parameters));
00163     
00164     // create SurfaceDeformation via factory
00165     SurfaceDeformation * surfDef = SurfaceDeformationFactory::create( (*iItem).m_parametrizationType, parameters);
00166     GeomDetUnit* geomDetUnit = (*iPair).second;
00167     this->setSurfaceDeformation( *geomDetUnit, surfDef );
00168     // delete is not needed since SurfaceDeformation is passed as a
00169     // DeepCopyPointerByClone which takes over ownership. Needs to be
00170     // cleaned up and checked once SurfaceDeformation are moved to
00171     // proxy topology classes
00172     //delete surfDef; 
00173 
00174     ++nSurfDef;
00175     
00176     ++itemIndex;
00177   }
00178   
00179   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::attachSurfaceDeformations" 
00180                             << "Finished to attach " << nSurfDef << " surface deformations.";
00181 }
00182 
00183 void GeometryAligner::removeGlobalTransform( const Alignments* alignments,
00184                                              const AlignmentErrors* alignmentErrors,
00185                                              const AlignTransform& globalCoordinates,
00186                                              Alignments* newAlignments,
00187                                              AlignmentErrors* newAlignmentErrors )
00188 {
00189   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::removeGlobalTransform" 
00190                             << "Starting to remove global position from alignments and errors";
00191   
00192   if ( alignments->m_align.size() != alignmentErrors->m_alignError.size() )
00193     throw cms::Exception("GeometryMismatch") 
00194       << "Size mismatch between alignments (size=" << alignments->m_align.size()
00195       << ") and alignment errors (size=" << alignmentErrors->m_alignError.size() << ")";
00196   
00197   const AlignTransform::Translation &globalShift = globalCoordinates.translation();
00198   const AlignTransform::Rotation globalRotation = globalCoordinates.rotation(); // by value!
00199   const AlignTransform::Rotation inverseGlobalRotation = globalRotation.inverse();
00200   
00201   AlignTransform::Translation newPosition;
00202   AlignTransform::Rotation newRotation;
00203   
00204   std::vector<AlignTransform>::const_iterator iAlign = alignments->m_align.begin();
00205   std::vector<AlignTransformError>::const_iterator iAlignError = alignmentErrors->m_alignError.begin();
00206   unsigned int nAPE = 0;
00207   for ( iAlign = alignments->m_align.begin();
00208         iAlign != alignments->m_align.end();
00209         ++iAlign, ++iAlignError ) {
00210     
00211     // Remove global position transformation from alignment
00212     newPosition = inverseGlobalRotation * ( (*iAlign).translation() - globalShift );
00213     newRotation = (*iAlign).rotation() * globalRotation;
00214     
00215     newAlignments->m_align.push_back( AlignTransform(newPosition,
00216                                                      newRotation,
00217                                                      (*iAlign).rawId()) );
00218     
00219     // Don't remove global position transformation from APE
00220     // as it wasn't applied. Just fill vector with original
00221     // values
00222     GlobalError error( asSMatrix<3>((*iAlignError).matrix()) );
00223     newAlignmentErrors->m_alignError.push_back( AlignTransformError( (*iAlignError).matrix(),
00224                                                                      (*iAlignError).rawId() ) );
00225     if ( error.cxx() || error.cyy() || error.czz() ||
00226          error.cyx() || error.czx() || error.czy() ) {
00227       ++nAPE;
00228     }
00229 
00230     // Code that removes the global postion transformation
00231     // from the APE.
00232     //     
00233     //AlgebraicSymMatrix as(3,0);
00234     //as[0][0] = error.cxx();
00235     //as[1][0] = error.cyx(); as[1][1] = error.cyy();
00236     //as[2][0] = error.czx(); as[2][1] = error.czy(); as[2][2] = error.czz();
00237     
00238     //AlgebraicMatrix am(3,3);
00239     //am[0][0] = inverseGlobalRotation.xx(); am[0][1] = inverseGlobalRotation.xy(); am[0][2] = inverseGlobalRotation.xz();
00240     //am[1][0] = inverseGlobalRotation.yx(); am[1][1] = inverseGlobalRotation.yy(); am[1][2] = inverseGlobalRotation.yz();
00241     //am[2][0] = inverseGlobalRotation.zx(); am[2][1] = inverseGlobalRotation.zy(); am[2][2] = inverseGlobalRotation.zz();
00242     //as = as.similarityT( am );
00243     
00244     //GlobalError newError( as );
00245     //newAlignmentErrors->m_alignError.push_back( AlignTransformError( newError.matrix(),
00246     //                                                                 (*iAlignError).rawId() ) );
00247     //++nAPE;
00248   }
00249 
00250   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::removeGlobalTransform" 
00251                             << "Finished to remove global transformation from " 
00252                             << alignments->m_align.size() << " alignments with "
00253                             << nAPE << " non-zero APE.";
00254 }
00255 
00256 #endif