CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/Alignment/LaserAlignment/src/LASGeometryUpdater.cc

Go to the documentation of this file.
00001 
00002 #include "Alignment/LaserAlignment/interface/LASGeometryUpdater.h"
00003 
00004 
00011 LASGeometryUpdater::LASGeometryUpdater( LASGlobalData<LASCoordinateSet>& aNominalCoordinates, LASConstants& aLasConstants ) {
00012   
00013   nominalCoordinates = aNominalCoordinates;
00014   isReverseDirection = false;
00015   isMisalignmentFromRefGeometry = false;
00016   lasConstants = aLasConstants;
00017 
00018 }
00019 
00020 
00021 
00022 
00023 
00028 void LASGeometryUpdater::ApplyBeamKinkCorrections( LASGlobalData<LASCoordinateSet>& measuredCoordinates ) const {
00029 
00032   for( unsigned int det = 0; det < 2; ++det ) {
00033     for( unsigned int ring = 0; ring < 2; ++ring ) {
00034       for( unsigned int beam = 0; beam < 8; ++beam ) {
00035 
00036         // corrections have different sign for TEC+/-
00037         const double endcapSign = det==0 ? 1.: -1.;
00038 
00039         // the correction is applied to the last 4 disks
00040         for( unsigned int disk = 5; disk < 9; ++disk ) {
00041 
00042           measuredCoordinates.GetTECEntry( det, ring, beam, disk ).SetPhi(
00043              measuredCoordinates.GetTECEntry( det, ring, beam, disk ).GetPhi() - 
00044              tan( lasConstants.GetEndcapBsKink( det, ring, beam ) ) / lasConstants.GetTecRadius( ring ) *
00045              ( lasConstants.GetTecZPosition( det, disk ) - endcapSign * lasConstants.GetTecBsZPosition( det ) )
00046           );
00047         
00048         }
00049       }
00050     }
00051   }
00052 
00053 
00056 
00057 }
00058 
00059 
00060 
00061 
00062 
00068 void LASGeometryUpdater::EndcapUpdate( LASEndcapAlignmentParameterSet& endcapParameters,  LASGlobalData<LASCoordinateSet>& measuredCoordinates ) {
00069 
00070   // radius of TEC ring4 laser in mm
00071   const double radius = 564.;
00072   
00073   // loop objects and its variables
00074   LASGlobalLoop moduleLoop;
00075   int det = 0, beam = 0, disk = 0;
00076 
00077 
00078 
00079   // update the TEC2TEC measurements
00080   do {
00081 
00082     // the measured phi value for this module
00083     const double currentPhi = measuredCoordinates.GetTEC2TECEntry( det, beam, disk ).GetPhi();
00084 
00085     // the correction to phi from the endcap algorithm;
00086     // it is defined such that the correction is to be subtracted
00087     double phiCorrection = 0.;
00088 
00089     // plain phi component
00090     phiCorrection -= endcapParameters.GetDiskParameter( det, disk, 0 ).first;
00091 
00092     // phi component from x deviation
00093     phiCorrection += sin( nominalCoordinates.GetTEC2TECEntry( det, beam, disk ).GetPhi() ) / radius * endcapParameters.GetDiskParameter( det, disk, 1 ).first;
00094 
00095     // phi component from y deviation
00096     phiCorrection -= cos( nominalCoordinates.GetTEC2TECEntry( det, beam, disk ).GetPhi() ) / radius * endcapParameters.GetDiskParameter( det, disk, 2 ).first;
00097 
00098     measuredCoordinates.GetTEC2TECEntry( det, beam, disk ).SetPhi( currentPhi - phiCorrection );
00099 
00100   } while( moduleLoop.TEC2TECLoop( det, beam, disk ) );
00101 
00102 }
00103 
00104 
00105 
00106 
00107 
00114 void LASGeometryUpdater::TrackerUpdate( LASEndcapAlignmentParameterSet& endcapParameters,
00115                                         LASBarrelAlignmentParameterSet& barrelParameters, 
00116                                         AlignableTracker& theAlignableTracker ) {
00117   
00118 
00119   // this constant defines the sense of *ALL* translations/rotations
00120   // of the alignables in the AlignableTracker object
00121   const int direction = ( isReverseDirection || isMisalignmentFromRefGeometry ) ? -1 : 1;
00122 
00123   // first, we access the half barrels of TIB and TOB
00124   const align::Alignables& theOuterHalfBarrels = theAlignableTracker.outerHalfBarrels();
00125   const align::Alignables& theInnerHalfBarrels = theAlignableTracker.innerHalfBarrels();
00126 
00127   // then the TECs and treat them also as half barrels 
00128   const align::Alignables& theEndcaps = theAlignableTracker.endCaps();
00129 
00130   // re-arrange to match the structure in LASBarrelAlignmentParameterSet and simplify the loop
00131   // 2 (TIB+), 3 (TIB-), 4 (TOB+), 5 (TOB-)
00132   std::vector<Alignable*> theHalfBarrels( 6 );
00133   theHalfBarrels.at( 0 ) = theEndcaps.at( 0 ); // TEC+
00134   theHalfBarrels.at( 1 ) = theEndcaps.at( 1 ); // TEC-
00135   theHalfBarrels.at( 2 ) = theInnerHalfBarrels.at( 1 ); // TIB+
00136   theHalfBarrels.at( 3 ) = theInnerHalfBarrels.at( 0 ); // TIB-
00137   theHalfBarrels.at( 4 ) = theOuterHalfBarrels.at( 1 ); // TOB+
00138   theHalfBarrels.at( 5 ) = theOuterHalfBarrels.at( 0 ); // TOB-
00139 
00140   // the z positions of the lower/upper-z halfbarrel_end_faces / outer_TEC_disks (in mm)
00141   // indices are: halfbarrel (0-5), endface(0=lowerZ,1=upperZ)
00142   std::vector<std::vector<double> > halfbarrelEndfaceZPositions( 6, std::vector<double>( 2, 0. ) );
00143   halfbarrelEndfaceZPositions.at( 0 ).at( 0 ) = 1322.5;
00144   halfbarrelEndfaceZPositions.at( 0 ).at( 1 ) = 2667.5;
00145   halfbarrelEndfaceZPositions.at( 1 ).at( 0 ) = -2667.5;
00146   halfbarrelEndfaceZPositions.at( 1 ).at( 1 ) = -1322.5;
00147   halfbarrelEndfaceZPositions.at( 2 ).at( 0 ) = 300.; 
00148   halfbarrelEndfaceZPositions.at( 2 ).at( 1 ) = 700.;
00149   halfbarrelEndfaceZPositions.at( 3 ).at( 0 ) = -700.;  
00150   halfbarrelEndfaceZPositions.at( 3 ).at( 1 ) = -300.;
00151   halfbarrelEndfaceZPositions.at( 4 ).at( 0 ) = 300.;
00152   halfbarrelEndfaceZPositions.at( 4 ).at( 1 ) = 1090.;
00153   halfbarrelEndfaceZPositions.at( 5 ).at( 0 ) = -1090.;  
00154   halfbarrelEndfaceZPositions.at( 5 ).at( 1 ) = -300.;
00155 
00156   // z difference of half barrel end faces (= hb-length) in mm
00157   // do all this geometry stuff more intelligent later..
00158   std::vector<double> theBarrelLength( 6, 0. );
00159   theBarrelLength.at( 0 ) = 1345.; // TEC
00160   theBarrelLength.at( 1 ) = 1345.;
00161   theBarrelLength.at( 2 ) =  400.; // TIB
00162   theBarrelLength.at( 3 ) =  400.;
00163   theBarrelLength.at( 4 ) =  790.; // TOB
00164   theBarrelLength.at( 5 ) =  790.;
00165 
00166 
00167   // the halfbarrel centers as defined in the AlignableTracker object,
00168   // needed for offset corrections; code to be improved later
00169   std::vector<double> theHalfbarrelCenters( 6, 0. );
00170   for( int halfbarrel = 0; halfbarrel < 6; ++halfbarrel ) {
00171     theHalfbarrelCenters.at( halfbarrel ) = theHalfBarrels.at( halfbarrel )->globalPosition().z() * 10.; // in mm
00172   }
00173 
00174   
00175 
00176   // mm to cm conversion factor (use by division)
00177   const double fromMmToCm = 10.;
00178 
00179   // half barrel loop (no TECs -> det>1)
00180   for( int halfBarrel = 2; halfBarrel < 6; ++halfBarrel ) {
00181     
00182     // A word on the factors of -1 in the below move/rotate statements:
00183     //
00184     // Since it is not possible to misalign simulated low-level objects like SiStripDigis in CMSSW,
00185     // LAS monte carlo digis are always ideally aligned, and misalignment is introduced
00186     // by displacing the reference geometry (AlignableTracker) instead which is used for stripNumber->phi conversion.
00187     // Hence, in case MC are used in that way, factors of -1 must be introduced
00188     // for rotations around x,y and translations in x,y. The variable "xyDirection" takes care of this.
00189     // 
00190     // However, for rotations around z (phi) there is a complication:
00191     // in the analytical AlignmentTubeAlgorithm, the alignment parameter phi (z-rotation)
00192     // is defined such that a positive value results in a positive contribution to the residual. In the real detector,
00193     // the opposite is true. The resulting additional factor of -1 thus compensates for the abovementioned reference geometry effect.
00194     //
00195     // this behavior can be reversed using the "direction" factor.
00196 
00197 
00198     // rotation around x axis = (dy1-dy2)/L
00199     const align::Scalar rxLocal = ( barrelParameters.GetParameter( halfBarrel, 0, 2 ).first - barrelParameters.GetParameter( halfBarrel, 1, 2 ).first ) / theBarrelLength.at( halfBarrel );
00200     theHalfBarrels.at( halfBarrel )->rotateAroundLocalX( direction * rxLocal );
00201 
00202     // rotation around y axis = (dx2-dx1)/L
00203     const align::Scalar ryLocal = ( barrelParameters.GetParameter( halfBarrel, 1, 1 ).first - barrelParameters.GetParameter( halfBarrel, 0, 1 ).first ) / theBarrelLength.at( halfBarrel );
00204     theHalfBarrels.at( halfBarrel )->rotateAroundLocalY( direction * ryLocal );
00205 
00206     // average rotation around z axis = (dphi1+dphi2)/2
00207     const align::Scalar rzLocal = ( barrelParameters.GetParameter( halfBarrel, 0, 0 ).first + barrelParameters.GetParameter( halfBarrel, 1, 0 ).first ) / 2.;
00208     theHalfBarrels.at( halfBarrel )->rotateAroundLocalZ( -1. * direction * rzLocal ); // this is phi, additional -1 here, see comment above
00209 
00210     // now that the rotational displacements are removed, the remaining translational offsets can be corrected for.
00211     // for this, the effect of the rotations is subtracted from the measured endface offsets
00212 
00213     // @@@ the +/-/-/+ signs for the correction parameters are not yet fully understood - 
00214     // @@@ do they flip when switching from reference-geometry-misalignment to true misalignment???
00215     std::vector<double> correctedEndfaceOffsetsX( 2, 0. ); // lowerZ/upperZ endface
00216     correctedEndfaceOffsetsX.at( 0 ) = barrelParameters.GetParameter( halfBarrel, 0, 1 ).first
00217       + ( theHalfbarrelCenters.at( halfBarrel ) - halfbarrelEndfaceZPositions.at( halfBarrel ).at( 0 ) ) * ryLocal;
00218     correctedEndfaceOffsetsX.at( 1 ) = barrelParameters.GetParameter( halfBarrel, 1, 1 ).first
00219       - ( halfbarrelEndfaceZPositions.at( halfBarrel ).at( 1 ) - theHalfbarrelCenters.at( halfBarrel ) ) * ryLocal;
00220 
00221     std::vector<double> correctedEndfaceOffsetsY( 2, 0. ); // lowerZ/upperZ endface
00222     correctedEndfaceOffsetsY.at( 0 ) = barrelParameters.GetParameter( halfBarrel, 0, 2 ).first
00223       - ( theHalfbarrelCenters.at( halfBarrel ) - halfbarrelEndfaceZPositions.at( halfBarrel ).at( 0 ) ) * rxLocal;
00224     correctedEndfaceOffsetsY.at( 1 ) = barrelParameters.GetParameter( halfBarrel, 1, 2 ).first
00225       + ( halfbarrelEndfaceZPositions.at( halfBarrel ).at( 1 ) - theHalfbarrelCenters.at( halfBarrel ) ) * rxLocal;
00226     
00227     // average x displacement = (cd1+cd2)/2
00228     const align::GlobalVector dxLocal( ( correctedEndfaceOffsetsX.at( 0 ) + correctedEndfaceOffsetsX.at( 1 ) ) / 2. / fromMmToCm, 0., 0. );
00229     theHalfBarrels.at( halfBarrel )->move( direction * ( dxLocal ) );
00230       
00231     // average y displacement = (cd1+cd2)/s
00232     const align::GlobalVector dyLocal( 0., ( correctedEndfaceOffsetsY.at( 0 ) + correctedEndfaceOffsetsY.at( 1 ) ) / 2. / fromMmToCm, 0. );
00233     theHalfBarrels.at( halfBarrel )->move( direction * ( dyLocal ) );
00234 
00235   }
00236 
00237 
00238   // now fit the endcaps into that alignment tube frame. the strategy is the following:
00239   //
00240   // 1. apply the parameters from the endcap algorithm to the individual disks
00241   // 2. the tec as a whole is rotated and moved such that the innermost disk (1) (= halfbarrel inner endface) 
00242   //    reaches the position determined by the barrel algorithm. 
00243   // 3. then, the TEC is twisted and sheared until the outermost disk (9) reaches nominal position 
00244   //    (since it has been fixed there in the alignment tube frame). this resolves any common
00245   //    shear and torsion within the TEC coordinate frame.
00246 
00247 
00248   // shortcut to the z positions of the disks' mechanical structures (TEC+/-, 9*disk)
00249   std::vector<std::vector<double> > wheelZPositions( 2, std::vector<double>( 9, 0. ) );
00250   for( int wheel = 0; wheel < 9; ++wheel ) {
00251     wheelZPositions.at( 0 ).at( wheel ) = theEndcaps.at( 0 )->components().at( wheel )->globalPosition().z();
00252     wheelZPositions.at( 1 ).at( wheel ) = theEndcaps.at( 1 )->components().at( wheel )->globalPosition().z();
00253   }
00254 
00255 
00256   // we can do this for both TECs in one go;
00257   // only real difference is the index change in the second argument to barrelParameters::GetParameter:
00258   // here the disk index changes from 0(+) to 1(-), since the end faces are sorted according to z (-->side=det)
00259 
00260   for( int det = 0; det < 2; ++det ) {
00261 
00262     const int& side = det;
00263 
00264     // step 1: apply the endcap algorithm parameters
00265 
00266     // factors of -1. within the move/rotate statements: see comment above.
00267     // difference here: in the the endcap algorithm, the alignment parameter phi (z-rotation) is defined
00268     // in the opposite sense compared with the AT algorithm, thus the factor of -1 applies also to phi rotations.
00269 
00270     for( int wheel = 0; wheel < 9; ++wheel ) {
00271       theEndcaps.at( det )->components().at( wheel )->rotateAroundLocalZ( direction * endcapParameters.GetDiskParameter( det, wheel, 0 ).first );
00272       const align::GlobalVector dXY( endcapParameters.GetDiskParameter( det, wheel, 1 ).first / fromMmToCm, endcapParameters.GetDiskParameter( det, wheel, 2 ).first / fromMmToCm, 0. );
00273       theEndcaps.at( det )->components().at( wheel )->move( direction * dXY );
00274     }
00275 
00276 
00277 
00278     // step 2: attach the innermost disk (disk 1) by rotating/moving the complete endcap
00279     
00280     // rotation around z of disk 1
00281     const align::Scalar dphi1 = barrelParameters.GetParameter( det, side, 0 ).first;
00282     theEndcaps.at( det )->rotateAroundLocalZ( -1. * direction * dphi1 ); // dphi1 is from the AT algorithm, so additional sign (s.above)
00283     
00284     // displacement in x,y of disk 1
00285     const align::GlobalVector dxy1( barrelParameters.GetParameter( det, side, 1 ).first / fromMmToCm, 
00286                                     barrelParameters.GetParameter( det, side, 2 ).first / fromMmToCm,
00287                                     0. );
00288     theEndcaps.at( det )->move( direction * dxy1 );
00289 
00290 
00291 
00292 
00293     // determine the resulting phi, x, y of disk 9 after step 2
00294     // the wrong sign for TEC- is soaked up by the reducedZ in step 3
00295     const align::Scalar resultingPhi9 = barrelParameters.GetParameter( det, 1, 0 ).first - barrelParameters.GetParameter( det, 0, 0 ).first;
00296     const align::GlobalVector resultingXY9( ( barrelParameters.GetParameter( det, 1, 1 ).first - barrelParameters.GetParameter( det, 0, 1 ).first ) / fromMmToCm,
00297                                             ( barrelParameters.GetParameter( det, 1, 2 ).first - barrelParameters.GetParameter( det, 0, 2 ).first ) / fromMmToCm,
00298                                             0. );
00299     
00300     // step 3: twist and shear back
00301     
00302     // the individual rotation/movement of the wheels is a function of their z-position
00303     for( int wheel = 0; wheel < 9; ++wheel ) {
00304       const double reducedZ = ( wheelZPositions.at( det ).at( wheel ) - wheelZPositions.at( det ).at( 0 ) ) / theBarrelLength.at( det ) * fromMmToCm;
00305       theEndcaps.at( det )->components().at( wheel )->rotateAroundLocalZ( -1. * direction * reducedZ * resultingPhi9 ); // twist
00306       theEndcaps.at( det )->components().at( wheel )->move( direction * reducedZ * resultingXY9 ); // shear
00307     }
00308 
00309   } 
00310 
00311 }
00312 
00313 
00314 
00315 
00316 
00320 void LASGeometryUpdater::SetReverseDirection( bool isSet ) {
00321 
00322   isReverseDirection = isSet;
00323 
00324 }
00325 
00326 
00327 
00328 
00329 
00333 void LASGeometryUpdater::SetMisalignmentFromRefGeometry( bool isSet ) {
00334 
00335   isMisalignmentFromRefGeometry = isSet;
00336 
00337 }