CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/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( (*iAlignError).matrix() );
00113           if ( error.cxx() || error.cyy() || error.czz() ||
00114                error.cyx() || error.czx() || error.czy() ||
00115                iGeomDet->alignmentPositionError() ) {
00116 
00117             // FIXME (AM): The check on the existence of a pointer to an AlignmentPositionError
00118             // in iGoemDet is needed to make sure that a previously set APE is reset to all zeros
00119             // in case the new APE is all zero. Ideally the checking of an all zero value APE
00120             // should go into GeomDet::setAlignmentPositionError.
00121             
00122             // Apply transformation to APE
00123             //
00124             //AlgebraicSymMatrix as(3,0);
00125             //as[0][0] = error.cxx();
00126             //as[1][0] = error.cyx(); as[1][1] = error.cyy();
00127             //as[2][0] = error.czx(); as[2][1] = error.czy(); as[2][2] = error.czz();
00128             
00129             //AlgebraicMatrix am(3,3);
00130             //am[0][0] = globalRotation.xx(); am[0][1] = globalRotation.xy(); am[0][2] = globalRotation.xz();
00131             //am[1][0] = globalRotation.yx(); am[1][1] = globalRotation.yy(); am[1][2] = globalRotation.yz();
00132             //am[2][0] = globalRotation.zx(); am[2][1] = globalRotation.zy(); am[2][2] = globalRotation.zz();
00133             //as = as.similarityT( am );
00134             
00135             //GlobalError newError( as );
00136             //AlignmentPositionError ape( newError );
00137 
00138             AlignmentPositionError ape( error );
00139             this->setAlignmentPositionError( *iGeomDet, ape );
00140             ++nAPE;
00141           }
00142         }
00143 
00144   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::applyAlignments" 
00145                             << "Finished to apply " << theMap.size() << " alignments with "
00146                             << nAPE << " non-zero APE.";
00147 }
00148 
00149 
00150 template<class C>
00151 void GeometryAligner::attachSurfaceDeformations( C* geometry,
00152                                                  const AlignmentSurfaceDeformations* surfaceDeformations )
00153 {
00154   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::attachSurfaceDeformations" 
00155                             << "Starting to attach surface deformations.";
00156 
00157   //copy geometry->theMapUnit to a real map to order it....
00158   std::map<unsigned int, GeomDetUnit*> theMap;
00159   std::copy(geometry->theMapUnit.begin(), geometry->theMapUnit.end(), std::inserter(theMap, theMap.begin()));
00160   
00161   unsigned int nSurfDef = 0;
00162   unsigned int itemIndex = 0;
00163   std::map<unsigned int, GeomDetUnit*>::const_iterator iPair = theMap.begin();
00164   for ( std::vector<AlignmentSurfaceDeformations::Item>::const_iterator iItem = surfaceDeformations->items().begin();
00165         iItem != surfaceDeformations->items().end();
00166         ++iItem, ++iPair) {
00167     
00168     // Check DetIds
00169     // go forward in map of GeomDetUnits until DetId is found
00170     while ( (*iPair).first != (*iItem).m_rawId ) {
00171 
00172       // remove SurfaceDeformation from GeomDetUnit (i.e. set NULL pointer)
00173       GeomDetUnit* geomDetUnit = (*iPair).second;
00174       this->setSurfaceDeformation( *geomDetUnit, 0 );
00175 
00176       ++iPair;
00177       if ( iPair==theMap.end() )
00178         throw cms::Exception("GeometryMismatch") 
00179           << "GeomDetUnit with rawId=" << (*iItem).m_rawId
00180           << " not found in geometry";
00181     }
00182     
00183     // get the parameters and put them into a vector
00184     AlignmentSurfaceDeformations::ParametersConstIteratorPair iteratorPair = surfaceDeformations->parameters(itemIndex);
00185     std::vector<double> parameters;
00186     std::copy(iteratorPair.first, iteratorPair.second, std::back_inserter(parameters));
00187     
00188     // create SurfaceDeformation via factory
00189     SurfaceDeformation * surfDef = SurfaceDeformationFactory::create( (*iItem).m_parametrizationType, parameters);
00190     GeomDetUnit* geomDetUnit = (*iPair).second;
00191     this->setSurfaceDeformation( *geomDetUnit, surfDef );
00192     // delete is not needed since SurfaceDeformation is passed as a
00193     // DeepCopyPointerByClone which takes over ownership. Needs to be
00194     // cleaned up and checked once SurfaceDeformation are moved to
00195     // proxy topology classes
00196     //delete surfDef; 
00197 
00198     ++nSurfDef;
00199     
00200     ++itemIndex;
00201   }
00202   
00203   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::attachSurfaceDeformations" 
00204                             << "Finished to attach " << nSurfDef << " surface deformations.";
00205 }
00206 
00207 void GeometryAligner::removeGlobalTransform( const Alignments* alignments,
00208                                              const AlignmentErrors* alignmentErrors,
00209                                              const AlignTransform& globalCoordinates,
00210                                              Alignments* newAlignments,
00211                                              AlignmentErrors* newAlignmentErrors )
00212 {
00213   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::removeGlobalTransform" 
00214                             << "Starting to remove global position from alignments and errors";
00215   
00216   if ( alignments->m_align.size() != alignmentErrors->m_alignError.size() )
00217     throw cms::Exception("GeometryMismatch") 
00218       << "Size mismatch between alignments (size=" << alignments->m_align.size()
00219       << ") and alignment errors (size=" << alignmentErrors->m_alignError.size() << ")";
00220   
00221   const AlignTransform::Translation &globalShift = globalCoordinates.translation();
00222   const AlignTransform::Rotation globalRotation = globalCoordinates.rotation(); // by value!
00223   const AlignTransform::Rotation inverseGlobalRotation = globalRotation.inverse();
00224   
00225   AlignTransform::Translation newPosition;
00226   AlignTransform::Rotation newRotation;
00227   
00228   std::vector<AlignTransform>::const_iterator iAlign = alignments->m_align.begin();
00229   std::vector<AlignTransformError>::const_iterator iAlignError = alignmentErrors->m_alignError.begin();
00230   unsigned int nAPE = 0;
00231   for ( iAlign = alignments->m_align.begin();
00232         iAlign != alignments->m_align.end();
00233         ++iAlign, ++iAlignError ) {
00234     
00235     // Remove global position transformation from alignment
00236     newPosition = inverseGlobalRotation * ( (*iAlign).translation() - globalShift );
00237     newRotation = (*iAlign).rotation() * globalRotation;
00238     
00239     newAlignments->m_align.push_back( AlignTransform(newPosition,
00240                                                      newRotation,
00241                                                      (*iAlign).rawId()) );
00242     
00243     // Don't remove global position transformation from APE
00244     // as it wasn't applied. Just fill vector with original
00245     // values
00246     GlobalError error( (*iAlignError).matrix() );
00247     newAlignmentErrors->m_alignError.push_back( AlignTransformError( error.matrix(),
00248                                                                      (*iAlignError).rawId() ) );
00249     if ( error.cxx() || error.cyy() || error.czz() ||
00250          error.cyx() || error.czx() || error.czy() ) {
00251       ++nAPE;
00252     }
00253 
00254     // Code that removes the global postion transformation
00255     // from the APE.
00256     //     
00257     //AlgebraicSymMatrix as(3,0);
00258     //as[0][0] = error.cxx();
00259     //as[1][0] = error.cyx(); as[1][1] = error.cyy();
00260     //as[2][0] = error.czx(); as[2][1] = error.czy(); as[2][2] = error.czz();
00261     
00262     //AlgebraicMatrix am(3,3);
00263     //am[0][0] = inverseGlobalRotation.xx(); am[0][1] = inverseGlobalRotation.xy(); am[0][2] = inverseGlobalRotation.xz();
00264     //am[1][0] = inverseGlobalRotation.yx(); am[1][1] = inverseGlobalRotation.yy(); am[1][2] = inverseGlobalRotation.yz();
00265     //am[2][0] = inverseGlobalRotation.zx(); am[2][1] = inverseGlobalRotation.zy(); am[2][2] = inverseGlobalRotation.zz();
00266     //as = as.similarityT( am );
00267     
00268     //GlobalError newError( as );
00269     //newAlignmentErrors->m_alignError.push_back( AlignTransformError( newError.matrix(),
00270     //                                                                 (*iAlignError).rawId() ) );
00271     //++nAPE;
00272   }
00273 
00274   edm::LogInfo("Alignment") << "@SUB=GeometryAligner::removeGlobalTransform" 
00275                             << "Finished to remove global transformation from " 
00276                             << alignments->m_align.size() << " alignments with "
00277                             << nAPE << " non-zero APE.";
00278 }
00279 
00280 #endif