Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 11:56:26

0001 
0002 #include "Alignment/LaserAlignment/interface/LASGeometryUpdater.h"
0003 #include "Alignment/CommonAlignment/interface/Utilities.h"
0004 
0005 ///
0006 /// constructor providing access to the nominal coordinates and the constants -
0007 /// for the moment, both objects are passed here, later it
0008 /// should be sufficient to pass only the constants and to fill
0009 /// the nominalCoordinates locally from that
0010 ///
0011 LASGeometryUpdater::LASGeometryUpdater(LASGlobalData<LASCoordinateSet>& aNominalCoordinates,
0012                                        LASConstants& aLasConstants) {
0013   nominalCoordinates = aNominalCoordinates;
0014   isReverseDirection = false;
0015   isMisalignmentFromRefGeometry = false;
0016   lasConstants = aLasConstants;
0017 }
0018 
0019 ///
0020 /// this function reads the beam kinks from the lasConstants
0021 /// and applies them to the set of measured global phi positions
0022 ///
0023 void LASGeometryUpdater::ApplyBeamKinkCorrections(LASGlobalData<LASCoordinateSet>& measuredCoordinates) const {
0024   /// first we apply the endcap beamsplitter kink corrections
0025   /// for TEC+/- in one go
0026   for (unsigned int det = 0; det < 2; ++det) {
0027     for (unsigned int ring = 0; ring < 2; ++ring) {
0028       for (unsigned int beam = 0; beam < 8; ++beam) {
0029         // corrections have different sign for TEC+/-
0030         const double endcapSign = det == 0 ? 1. : -1.;
0031 
0032         // the correction is applied to the last 4 disks
0033         for (unsigned int disk = 5; disk < 9; ++disk) {
0034           measuredCoordinates.GetTECEntry(det, ring, beam, disk)
0035               .SetPhi(measuredCoordinates.GetTECEntry(det, ring, beam, disk).GetPhi() -
0036                       tan(lasConstants.GetEndcapBsKink(det, ring, beam)) / lasConstants.GetTecRadius(ring) *
0037                           (lasConstants.GetTecZPosition(det, disk) - endcapSign * lasConstants.GetTecBsZPosition(det)));
0038         }
0039       }
0040     }
0041   }
0042 
0043   /// alignment tube beamsplitter & mirror kink corrections
0044   /// TBD.
0045 }
0046 
0047 ///
0048 /// apply the endcap alignment parameters in the LASEndcapAlignmentParameterSet
0049 /// to the Measurements (TEC2TEC only)
0050 /// and the AlignableTracker object
0051 ///
0052 void LASGeometryUpdater::EndcapUpdate(LASEndcapAlignmentParameterSet& endcapParameters,
0053                                       LASGlobalData<LASCoordinateSet>& measuredCoordinates) {
0054   // radius of TEC ring4 laser in mm
0055   const double radius = 564.;
0056 
0057   // loop objects and its variables
0058   LASGlobalLoop moduleLoop;
0059   int det = 0, beam = 0, disk = 0;
0060 
0061   // update the TEC2TEC measurements
0062   do {
0063     // the measured phi value for this module
0064     const double currentPhi = measuredCoordinates.GetTEC2TECEntry(det, beam, disk).GetPhi();
0065 
0066     // the correction to phi from the endcap algorithm;
0067     // it is defined such that the correction is to be subtracted
0068     double phiCorrection = 0.;
0069 
0070     // plain phi component
0071     phiCorrection -= endcapParameters.GetDiskParameter(det, disk, 0).first;
0072 
0073     // phi component from x deviation
0074     phiCorrection += sin(nominalCoordinates.GetTEC2TECEntry(det, beam, disk).GetPhi()) / radius *
0075                      endcapParameters.GetDiskParameter(det, disk, 1).first;
0076 
0077     // phi component from y deviation
0078     phiCorrection -= cos(nominalCoordinates.GetTEC2TECEntry(det, beam, disk).GetPhi()) / radius *
0079                      endcapParameters.GetDiskParameter(det, disk, 2).first;
0080 
0081     measuredCoordinates.GetTEC2TECEntry(det, beam, disk).SetPhi(currentPhi - phiCorrection);
0082 
0083   } while (moduleLoop.TEC2TECLoop(det, beam, disk));
0084 }
0085 
0086 ///
0087 /// merge the output from endcap and barrel algorithms
0088 /// and update the AlignableTracker object
0089 ///
0090 /// the AlignableTracker input object is expected to be perfectly aligned!!
0091 ///
0092 void LASGeometryUpdater::TrackerUpdate(LASEndcapAlignmentParameterSet& endcapParameters,
0093                                        LASBarrelAlignmentParameterSet& barrelParameters,
0094                                        AlignableTracker& theAlignableTracker) {
0095   // this constant defines the sense of *ALL* translations/rotations
0096   // of the alignables in the AlignableTracker object
0097   const int direction = (isReverseDirection || isMisalignmentFromRefGeometry) ? -1 : 1;
0098 
0099   // first, we access the half barrels of TIB and TOB
0100   const align::Alignables& theOuterHalfBarrels = theAlignableTracker.outerHalfBarrels();
0101   const align::Alignables& theInnerHalfBarrels = theAlignableTracker.innerHalfBarrels();
0102 
0103   // then the TECs and treat them also as half barrels
0104   const align::Alignables& theEndcaps = theAlignableTracker.endCaps();
0105 
0106   // re-arrange to match the structure in LASBarrelAlignmentParameterSet and simplify the loop
0107   // 2 (TIB+), 3 (TIB-), 4 (TOB+), 5 (TOB-)
0108   align::Alignables theHalfBarrels(6);
0109   theHalfBarrels.at(0) = theEndcaps.at(0);           // TEC+
0110   theHalfBarrels.at(1) = theEndcaps.at(1);           // TEC-
0111   theHalfBarrels.at(2) = theInnerHalfBarrels.at(1);  // TIB+
0112   theHalfBarrels.at(3) = theInnerHalfBarrels.at(0);  // TIB-
0113   theHalfBarrels.at(4) = theOuterHalfBarrels.at(1);  // TOB+
0114   theHalfBarrels.at(5) = theOuterHalfBarrels.at(0);  // TOB-
0115 
0116   // the z positions of the lower/upper-z halfbarrel_end_faces / outer_TEC_disks (in mm)
0117   // indices are: halfbarrel (0-5), endface(0=lowerZ,1=upperZ)
0118   std::vector<std::vector<double> > halfbarrelEndfaceZPositions(6, std::vector<double>(2, 0.));
0119   halfbarrelEndfaceZPositions.at(0).at(0) = 1322.5;
0120   halfbarrelEndfaceZPositions.at(0).at(1) = 2667.5;
0121   halfbarrelEndfaceZPositions.at(1).at(0) = -2667.5;
0122   halfbarrelEndfaceZPositions.at(1).at(1) = -1322.5;
0123   halfbarrelEndfaceZPositions.at(2).at(0) = 300.;
0124   halfbarrelEndfaceZPositions.at(2).at(1) = 700.;
0125   halfbarrelEndfaceZPositions.at(3).at(0) = -700.;
0126   halfbarrelEndfaceZPositions.at(3).at(1) = -300.;
0127   halfbarrelEndfaceZPositions.at(4).at(0) = 300.;
0128   halfbarrelEndfaceZPositions.at(4).at(1) = 1090.;
0129   halfbarrelEndfaceZPositions.at(5).at(0) = -1090.;
0130   halfbarrelEndfaceZPositions.at(5).at(1) = -300.;
0131 
0132   // z difference of half barrel end faces (= hb-length) in mm
0133   // do all this geometry stuff more intelligent later..
0134   std::vector<double> theBarrelLength(6, 0.);
0135   theBarrelLength.at(0) = 1345.;  // TEC
0136   theBarrelLength.at(1) = 1345.;
0137   theBarrelLength.at(2) = 400.;  // TIB
0138   theBarrelLength.at(3) = 400.;
0139   theBarrelLength.at(4) = 790.;  // TOB
0140   theBarrelLength.at(5) = 790.;
0141 
0142   // the halfbarrel centers as defined in the AlignableTracker object,
0143   // needed for offset corrections; code to be improved later
0144   std::vector<double> theHalfbarrelCenters(6, 0.);
0145   for (int halfbarrel = 0; halfbarrel < 6; ++halfbarrel) {
0146     theHalfbarrelCenters.at(halfbarrel) = theHalfBarrels.at(halfbarrel)->globalPosition().z() * 10.;  // in mm
0147   }
0148 
0149   // mm to cm conversion factor (use by division)
0150   const double fromMmToCm = 10.;
0151 
0152   // half barrel loop (no TECs -> det>1)
0153   for (int halfBarrel = 2; halfBarrel < 6; ++halfBarrel) {
0154     // A word on the factors of -1 in the below move/rotate statements:
0155     //
0156     // Since it is not possible to misalign simulated low-level objects like SiStripDigis in CMSSW,
0157     // LAS monte carlo digis are always ideally aligned, and misalignment is introduced
0158     // by displacing the reference geometry (AlignableTracker) instead which is used for stripNumber->phi conversion.
0159     // Hence, in case MC are used in that way, factors of -1 must be introduced
0160     // for rotations around x,y and translations in x,y. The variable "xyDirection" takes care of this.
0161     //
0162     // However, for rotations around z (phi) there is a complication:
0163     // in the analytical AlignmentTubeAlgorithm, the alignment parameter phi (z-rotation)
0164     // is defined such that a positive value results in a positive contribution to the residual. In the real detector,
0165     // the opposite is true. The resulting additional factor of -1 thus compensates for the abovementioned reference geometry effect.
0166     //
0167     // this behavior can be reversed using the "direction" factor.
0168 
0169     // rotation around x axis = (dy1-dy2)/L
0170     const align::Scalar rxLocal = (barrelParameters.GetParameter(halfBarrel, 0, 2).first -
0171                                    barrelParameters.GetParameter(halfBarrel, 1, 2).first) /
0172                                   theBarrelLength.at(halfBarrel);
0173     theHalfBarrels.at(halfBarrel)->rotateAroundLocalX(direction * rxLocal);
0174 
0175     // rotation around y axis = (dx2-dx1)/L
0176     const align::Scalar ryLocal = (barrelParameters.GetParameter(halfBarrel, 1, 1).first -
0177                                    barrelParameters.GetParameter(halfBarrel, 0, 1).first) /
0178                                   theBarrelLength.at(halfBarrel);
0179     theHalfBarrels.at(halfBarrel)->rotateAroundLocalY(direction * ryLocal);
0180 
0181     // average rotation around z axis = (dphi1+dphi2)/2
0182     const align::Scalar rzLocal = (barrelParameters.GetParameter(halfBarrel, 0, 0).first +
0183                                    barrelParameters.GetParameter(halfBarrel, 1, 0).first) /
0184                                   2.;
0185     theHalfBarrels.at(halfBarrel)
0186         ->rotateAroundLocalZ(-1. * direction * rzLocal);  // this is phi, additional -1 here, see comment above
0187 
0188     // now that the rotational displacements are removed, the remaining translational offsets can be corrected for.
0189     // for this, the effect of the rotations is subtracted from the measured endface offsets
0190 
0191     // @@@ the +/-/-/+ signs for the correction parameters are not yet fully understood -
0192     // @@@ do they flip when switching from reference-geometry-misalignment to true misalignment???
0193     std::vector<double> correctedEndfaceOffsetsX(2, 0.);  // lowerZ/upperZ endface
0194     correctedEndfaceOffsetsX.at(0) =
0195         barrelParameters.GetParameter(halfBarrel, 0, 1).first +
0196         (theHalfbarrelCenters.at(halfBarrel) - halfbarrelEndfaceZPositions.at(halfBarrel).at(0)) * ryLocal;
0197     correctedEndfaceOffsetsX.at(1) =
0198         barrelParameters.GetParameter(halfBarrel, 1, 1).first -
0199         (halfbarrelEndfaceZPositions.at(halfBarrel).at(1) - theHalfbarrelCenters.at(halfBarrel)) * ryLocal;
0200 
0201     std::vector<double> correctedEndfaceOffsetsY(2, 0.);  // lowerZ/upperZ endface
0202     correctedEndfaceOffsetsY.at(0) =
0203         barrelParameters.GetParameter(halfBarrel, 0, 2).first -
0204         (theHalfbarrelCenters.at(halfBarrel) - halfbarrelEndfaceZPositions.at(halfBarrel).at(0)) * rxLocal;
0205     correctedEndfaceOffsetsY.at(1) =
0206         barrelParameters.GetParameter(halfBarrel, 1, 2).first +
0207         (halfbarrelEndfaceZPositions.at(halfBarrel).at(1) - theHalfbarrelCenters.at(halfBarrel)) * rxLocal;
0208 
0209     // average x displacement = (cd1+cd2)/2
0210     const align::GlobalVector dxLocal(
0211         (correctedEndfaceOffsetsX.at(0) + correctedEndfaceOffsetsX.at(1)) / 2. / fromMmToCm, 0., 0.);
0212     theHalfBarrels.at(halfBarrel)->move(direction * (dxLocal));
0213 
0214     // average y displacement = (cd1+cd2)/s
0215     const align::GlobalVector dyLocal(
0216         0., (correctedEndfaceOffsetsY.at(0) + correctedEndfaceOffsetsY.at(1)) / 2. / fromMmToCm, 0.);
0217     theHalfBarrels.at(halfBarrel)->move(direction * (dyLocal));
0218   }
0219 
0220   // now fit the endcaps into that alignment tube frame. the strategy is the following:
0221   //
0222   // 1. apply the parameters from the endcap algorithm to the individual disks
0223   // 2. the tec as a whole is rotated and moved such that the innermost disk (1) (= halfbarrel inner endface)
0224   //    reaches the position determined by the barrel algorithm.
0225   // 3. then, the TEC is twisted and sheared until the outermost disk (9) reaches nominal position
0226   //    (since it has been fixed there in the alignment tube frame). this resolves any common
0227   //    shear and torsion within the TEC coordinate frame.
0228 
0229   // shortcut to the z positions of the disks' mechanical structures (TEC+/-, 9*disk)
0230   std::vector<std::vector<double> > wheelZPositions(2, std::vector<double>(9, 0.));
0231   for (int wheel = 0; wheel < 9; ++wheel) {
0232     wheelZPositions.at(0).at(wheel) = theEndcaps.at(0)->components().at(wheel)->globalPosition().z();
0233     wheelZPositions.at(1).at(wheel) = theEndcaps.at(1)->components().at(wheel)->globalPosition().z();
0234   }
0235 
0236   // we can do this for both TECs in one go;
0237   // only real difference is the index change in the second argument to barrelParameters::GetParameter:
0238   // here the disk index changes from 0(+) to 1(-), since the end faces are sorted according to z (-->side=det)
0239 
0240   for (int det = 0; det < 2; ++det) {
0241     const int& side = det;
0242 
0243     // step 1: apply the endcap algorithm parameters
0244 
0245     // factors of -1. within the move/rotate statements: see comment above.
0246     // difference here: in the the endcap algorithm, the alignment parameter phi (z-rotation) is defined
0247     // in the opposite sense compared with the AT algorithm, thus the factor of -1 applies also to phi rotations.
0248 
0249     for (int wheel = 0; wheel < 9; ++wheel) {
0250       theEndcaps.at(det)->components().at(wheel)->rotateAroundLocalZ(
0251           direction * endcapParameters.GetDiskParameter(det, wheel, 0).first);
0252       const align::GlobalVector dXY(endcapParameters.GetDiskParameter(det, wheel, 1).first / fromMmToCm,
0253                                     endcapParameters.GetDiskParameter(det, wheel, 2).first / fromMmToCm,
0254                                     0.);
0255       theEndcaps.at(det)->components().at(wheel)->move(direction * dXY);
0256     }
0257 
0258     // step 2: attach the innermost disk (disk 1) by rotating/moving the complete endcap
0259 
0260     // rotation around z of disk 1
0261     const align::Scalar dphi1 = barrelParameters.GetParameter(det, side, 0).first;
0262     theEndcaps.at(det)->rotateAroundLocalZ(-1. * direction *
0263                                            dphi1);  // dphi1 is from the AT algorithm, so additional sign (s.above)
0264 
0265     // displacement in x,y of disk 1
0266     const align::GlobalVector dxy1(barrelParameters.GetParameter(det, side, 1).first / fromMmToCm,
0267                                    barrelParameters.GetParameter(det, side, 2).first / fromMmToCm,
0268                                    0.);
0269     theEndcaps.at(det)->move(direction * dxy1);
0270 
0271     // determine the resulting phi, x, y of disk 9 after step 2
0272     // the wrong sign for TEC- is soaked up by the reducedZ in step 3
0273     const align::Scalar resultingPhi9 =
0274         barrelParameters.GetParameter(det, 1, 0).first - barrelParameters.GetParameter(det, 0, 0).first;
0275     const align::GlobalVector resultingXY9(
0276         (barrelParameters.GetParameter(det, 1, 1).first - barrelParameters.GetParameter(det, 0, 1).first) / fromMmToCm,
0277         (barrelParameters.GetParameter(det, 1, 2).first - barrelParameters.GetParameter(det, 0, 2).first) / fromMmToCm,
0278         0.);
0279 
0280     // step 3: twist and shear back
0281 
0282     // the individual rotation/movement of the wheels is a function of their z-position
0283     for (int wheel = 0; wheel < 9; ++wheel) {
0284       const double reducedZ =
0285           (wheelZPositions.at(det).at(wheel) - wheelZPositions.at(det).at(0)) / theBarrelLength.at(det) * fromMmToCm;
0286       theEndcaps.at(det)->components().at(wheel)->rotateAroundLocalZ(-1. * direction * reducedZ *
0287                                                                      resultingPhi9);          // twist
0288       theEndcaps.at(det)->components().at(wheel)->move(direction * reducedZ * resultingXY9);  // shear
0289     }
0290   }
0291 }
0292 
0293 ///
0294 ///
0295 ///
0296 void LASGeometryUpdater::SetReverseDirection(bool isSet) { isReverseDirection = isSet; }
0297 
0298 ///
0299 ///
0300 ///
0301 void LASGeometryUpdater::SetMisalignmentFromRefGeometry(bool isSet) { isMisalignmentFromRefGeometry = isSet; }