CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/Alignment/CommonAlignment/src/AlignableComposite.cc

Go to the documentation of this file.
00001 // Framework
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 #include "CondFormats/Alignment/interface/Alignments.h"
00006 #include "CondFormats/Alignment/interface/AlignmentErrors.h"
00007 #include "DataFormats/TrackingRecHit/interface/AlignmentPositionError.h"
00008 #include "Geometry/CommonDetUnit/interface/GeomDet.h"
00009 
00010 #include "Alignment/CommonAlignment/interface/AlignableComposite.h"
00011 
00012 
00013 //__________________________________________________________________________________________________
00014 AlignableComposite::AlignableComposite( const GeomDet* geomDet ) : 
00015   Alignable( geomDet->geographicalId().rawId(), geomDet->surface() ),
00016   theStructureType(align::AlignableDet)
00017 {
00018 }
00019 
00020 AlignableComposite::AlignableComposite(align::ID id,
00021                                        StructureType type,
00022                                        const RotationType& rot):
00023   Alignable(id, rot),
00024   theStructureType(type)
00025 {
00026 }
00027 
00028 AlignableComposite::~AlignableComposite()
00029 {
00030   for (unsigned int i = 0; i < theComponents.size(); ++i) delete theComponents[i];
00031 }
00032 
00033 void AlignableComposite::addComponent(Alignable* ali)
00034 {
00035   const Alignables& newComps = ali->deepComponents();
00036 
00037   theDeepComponents.insert( theDeepComponents.end(), newComps.begin(), newComps.end() );
00038 
00039   Scalar k = static_cast<Scalar>( newComps.size() ) / theDeepComponents.size();
00040 
00041   theSurface.move( ( ali->globalPosition() - globalPosition() ) * k );
00042 
00043   ali->setMother(this);
00044   theComponents.push_back(ali);
00045 }
00046 
00047 //__________________________________________________________________________________________________
00048 void AlignableComposite::recursiveComponents(Alignables &result) const
00049 {
00050 
00051   Alignables components = this->components();
00052   if (this->alignableObjectId() == align::AlignableDet 
00053       && components.size() <= 1) { // Non-glued AlignableDets (still) contain themselves
00054     return; // (would be better to implement AlignableDet::recursiveComponents!)
00055   }
00056   for (Alignables::const_iterator iter = components.begin();
00057        iter != components.end(); ++iter) {
00058     result.push_back(*iter); // could use std::copy(..), but here we build a real hierarchy
00059     (*iter)->recursiveComponents(result);
00060   }
00061 }
00062 
00063 //__________________________________________________________________________________________________
00064 void AlignableComposite::move( const GlobalVector& displacement ) 
00065 {
00066   
00067   // Move components
00068   Alignables comp = this->components();
00069   for ( Alignables::iterator i=comp.begin(); i!=comp.end(); i++ )
00070     (**i).move( displacement);
00071 
00072   // Move surface
00073   this->addDisplacement( displacement );
00074   theSurface.move( displacement );
00075 
00076 }
00077 
00078 
00079 //__________________________________________________________________________________________________
00080 void AlignableComposite::moveComponentsLocal( const LocalVector& localDisplacement )
00081 {
00082 
00083   this->move( this->surface().toGlobal(localDisplacement) );
00084 
00085 }
00086 
00087 //__________________________________________________________________________________________________
00088 void AlignableComposite::moveComponentLocal( const int i, const LocalVector& localDisplacement )
00089 {
00090 
00091   if (i >= size() ) 
00092     throw cms::Exception("LogicError")
00093       << "AlignableComposite index (" << i << ") out of range";
00094 
00095   Alignables comp = this->components();
00096   comp[i]->move( this->surface().toGlobal( localDisplacement ) );
00097 
00098 }
00099 
00100 
00101 //__________________________________________________________________________________________________
00106 void AlignableComposite::rotateInGlobalFrame( const RotationType& rotation )
00107 {
00108   
00109   Alignables comp = this->components();
00110   
00111   PositionType myPosition = this->globalPosition();
00112   
00113   for ( Alignables::iterator i=comp.begin(); i!=comp.end(); i++ )
00114     {
00115       
00116       // It is much simpler to calculate the local position given in coordinates 
00117       // of the GLOBAL frame and then just apply the rotation matrix given in the 
00118       // GLOBAL frame as well. ONLY this is somewhat tricky... as Teddy's frames 
00119       // don't like this kind of mixing...
00120       
00121       // Rotations are defined for "Basic3DVector" types, without any FrameTAG,
00122       // because Rotations usually switch between different frames. You get
00123       // this by using the method .basicVector()
00124     
00125       // localPosition = globalPosition (Component) - globalPosition(Composite)
00126       // moveVector = rotated localPosition  - original localposition
00127       // LocalVector localPositionVector = (**i).globalPosition()-myPosition;
00128     
00129     
00130       // Local Position given in coordinates of the GLOBAL Frame
00131       const GlobalVector localPositionVector = (**i).globalPosition() - myPosition;
00132       GlobalVector::BasicVectorType lpvgf = localPositionVector.basicVector();
00133 
00134       // rotate with GLOBAL rotation matrix  and subtract => moveVector in 
00135       // global Coordinates
00136       // apparently... you have to use the inverse of the rotation here
00137       // (rotate the VECTOR rather than the frame) 
00138       GlobalVector moveVector( rotation.multiplyInverse(lpvgf) - lpvgf );
00139     
00140     
00141       (**i).move( moveVector );
00142       (**i).rotateInGlobalFrame( rotation );
00143 
00144     }
00145 
00146   this->addRotation( rotation );
00147   
00148   theSurface.rotate( rotation );
00149 
00150 }
00151 
00152 
00153 //__________________________________________________________________________________________________
00154 void AlignableComposite::setAlignmentPositionError( const AlignmentPositionError& ape,
00155                                                     bool propagateDown )
00156 {
00157 
00158   // Since no geomDet is attached, alignable composites do not have an APE
00159   // The APE is, therefore, just propagated down
00160   if (!propagateDown) return;
00161 
00162   Alignables comp = this->components();
00163   for (Alignables::const_iterator i = comp.begin(); i != comp.end(); ++i) {
00164     (*i)->setAlignmentPositionError(ape, propagateDown);
00165   }
00166 }
00167 
00168 
00169 //__________________________________________________________________________________________________
00170 void 
00171 AlignableComposite::addAlignmentPositionError( const AlignmentPositionError& ape,
00172                                                bool propagateDown )
00173 {
00174 
00175   // Since no geomDet is attached, alignable composites do not have an APE
00176   // The APE is, therefore, just propagated down
00177   if (!propagateDown) return;
00178 
00179   Alignables comp = this->components();
00180   for (Alignables::const_iterator i = comp.begin(); i != comp.end(); ++i) {
00181     (*i)->addAlignmentPositionError(ape, propagateDown);
00182   }
00183   
00184 }
00185 
00186 
00187 //__________________________________________________________________________________________________
00191 void AlignableComposite::addAlignmentPositionErrorFromRotation( const RotationType& rotation,
00192                                                                 bool propagateDown )
00193 {
00194 
00195   if (!propagateDown) return;
00196 
00197   Alignables comp = this->components();
00198   PositionType myPosition=this->globalPosition();
00199 
00200   for ( Alignables::const_iterator i=comp.begin(); i!=comp.end(); i++ )
00201     {
00202 
00203       // It is just similar to to the "movement" that results to the components
00204       // when the composite is rotated. 
00205       // Local Position given in coordinates of the GLOBAL Frame
00206       const GlobalVector localPositionVector = (**i).globalPosition()-myPosition;
00207       GlobalVector::BasicVectorType lpvgf = localPositionVector.basicVector();
00208 
00209       // rotate with GLOBAL rotation matrix  and subtract => moveVector in global coordinates
00210       // apparently... you have to use the inverse of the rotation here
00211       // (rotate the VECTOR rather than the frame) 
00212       GlobalVector moveVector( rotation.multiplyInverse(lpvgf) - lpvgf );    
00213       
00214       AlignmentPositionError ape( moveVector.x(), moveVector.y(), moveVector.z() );
00215       (*i)->addAlignmentPositionError( ape, propagateDown );
00216       (*i)->addAlignmentPositionErrorFromRotation( rotation, propagateDown );
00217           
00218     }
00219 
00220 }
00221 
00222 
00223 //__________________________________________________________________________________________________
00227 void AlignableComposite::addAlignmentPositionErrorFromLocalRotation( const RotationType& rot,
00228                                                                      bool propagateDown )
00229 {
00230   // if (!propagateDown) return; // No! Cannot yet jump out since
00231   // addAlignmentPositionErrorFromRotation(..) below might be overwritten in derived
00232   // classes to do something on 'this' (and in fact does so in AlignableDet).
00233 
00234   RotationType globalRot = globalRotation().multiplyInverse(rot*globalRotation());
00235   this->addAlignmentPositionErrorFromRotation(globalRot, propagateDown);
00236 
00237 }
00238 
00239 //__________________________________________________________________________________________________
00240 void AlignableComposite::setSurfaceDeformation(const SurfaceDeformation *deformation,
00241                                                bool propagateDown)
00242 {
00243   // Only DetUnits have surface deformations.
00244   // The parameters are, therefore, just propagated down.
00245   if (!propagateDown) return;
00246 
00247   Alignables comp(this->components());
00248   for (Alignables::const_iterator i = comp.begin(); i != comp.end(); ++i) {
00249     (*i)->setSurfaceDeformation(deformation, propagateDown);
00250   }
00251 }
00252 
00253 //__________________________________________________________________________________________________
00254 void AlignableComposite::addSurfaceDeformation(const SurfaceDeformation *deformation,
00255                                                bool propagateDown)
00256 {
00257   // Only DetUnits have surface deformations.
00258   // The parameters are, therefore, just propagated down.
00259   if (!propagateDown) return;
00260 
00261   Alignables comp(this->components());
00262   for (Alignables::const_iterator i = comp.begin(); i != comp.end(); ++i) {
00263     (*i)->addSurfaceDeformation(deformation, propagateDown);
00264   }
00265 }
00266 
00267 //__________________________________________________________________________________________________
00268 void AlignableComposite::dump( void ) const
00269 {
00270 
00271   // A simple printout method. Could be specialized in the implementation classes.
00272 
00273   Alignables comp = this->components();
00274 
00275   // Dump this
00276   edm::LogInfo("AlignableDump") 
00277     << " Alignable of type " << this->alignableObjectId() 
00278     << " has " << comp.size() << " components" << std::endl
00279     << " position = " << this->globalPosition() << ", orientation:" << std::endl
00280     << this->globalRotation();
00281 
00282   // Dump components
00283   for ( Alignables::iterator i=comp.begin(); i!=comp.end(); i++ )
00284     (*i)->dump();
00285 
00286 }
00287 
00288 
00289 
00290 //__________________________________________________________________________________________________
00291 Alignments* AlignableComposite::alignments( void ) const
00292 {
00293 
00294   // Recursively call alignments, until we get to an AlignableDetUnit
00295   Alignables comp = this->components();
00296 
00297   Alignments* m_alignments = new Alignments();
00298 
00299   // Add components recursively
00300   for ( Alignables::iterator i=comp.begin(); i!=comp.end(); i++ )
00301     {
00302       Alignments* tmpAlignments = (*i)->alignments();
00303       std::copy( tmpAlignments->m_align.begin(), tmpAlignments->m_align.end(), 
00304                  std::back_inserter(m_alignments->m_align) );
00305           delete tmpAlignments;
00306     }
00307 
00308   
00309   return m_alignments;
00310 
00311 }
00312 
00313 
00314 //__________________________________________________________________________________________________
00315 AlignmentErrors* AlignableComposite::alignmentErrors( void ) const
00316 {
00317 
00318   // Recursively call alignmentsErrors, until we get to an AlignableDetUnit
00319   Alignables comp = this->components();
00320 
00321   AlignmentErrors* m_alignmentErrors = new AlignmentErrors();
00322 
00323   // Add components recursively
00324   for ( Alignables::iterator i=comp.begin(); i!=comp.end(); i++ )
00325     {
00326       AlignmentErrors* tmpAlignmentErrors = (*i)->alignmentErrors();
00327       std::copy( tmpAlignmentErrors->m_alignError.begin(), tmpAlignmentErrors->m_alignError.end(), 
00328                  std::back_inserter(m_alignmentErrors->m_alignError) );
00329           delete tmpAlignmentErrors;
00330     }
00331 
00332   
00333   return m_alignmentErrors;
00334 
00335 }
00336 
00337 
00338 //__________________________________________________________________________________________________
00339 int AlignableComposite::surfaceDeformationIdPairs(std::vector<std::pair<int,SurfaceDeformation*> > & result) const
00340 {
00341 
00342   Alignables comp = this->components();
00343 
00344   int count = 0;
00345 
00346   // Add components recursively
00347   for ( Alignables::iterator i=comp.begin(); i!=comp.end(); ++i) {
00348     count += (*i)->surfaceDeformationIdPairs(result);
00349   }
00350   
00351   return count;
00352 
00353 }