CMS 3D CMS Logo

TwoBowedSurfacesAlignmentParameters.cc
Go to the documentation of this file.
1 
10 
12 
18 //#include "DataFormats/Alignment/interface/SurfaceDeformation.h"
20 
21 // This class's header
23 
24 #include <cmath>
25 #include <iostream>
26 //_________________________________________________________________________________________________
28  : AlignmentParameters(ali, AlgebraicVector(N_PARAM), AlgebraicSymMatrix(N_PARAM, 0)),
29  ySplit_(this->ySplitFromAlignable(ali)) {}
30 
31 //_________________________________________________________________________________________________
34  const AlgebraicSymMatrix &covMatrix)
35  : AlignmentParameters(alignable, parameters, covMatrix), ySplit_(this->ySplitFromAlignable(alignable)) {
36  if (parameters.num_row() != N_PARAM) {
37  throw cms::Exception("BadParameters") << "in TwoBowedSurfacesAlignmentParameters(): " << parameters.num_row()
38  << " instead of " << N_PARAM << " parameters.";
39  }
40 }
41 
42 //_________________________________________________________________________________________________
45  const AlgebraicSymMatrix &covMatrix,
46  const std::vector<bool> &selection)
47  : AlignmentParameters(alignable, parameters, covMatrix, selection), ySplit_(this->ySplitFromAlignable(alignable)) {
48  if (parameters.num_row() != N_PARAM) {
49  throw cms::Exception("BadParameters") << "in TwoBowedSurfacesAlignmentParameters(): " << parameters.num_row()
50  << " instead of " << N_PARAM << " parameters.";
51  }
52 }
53 
54 //_________________________________________________________________________________________________
56  const AlgebraicVector &parameters, const AlgebraicSymMatrix &covMatrix) const {
58  new TwoBowedSurfacesAlignmentParameters(this->alignable(), parameters, covMatrix, selector());
59 
60  if (this->userVariables())
61  rbap->setUserVariables(this->userVariables()->clone());
62  rbap->setValid(this->isValid());
63 
64  return rbap;
65 }
66 
67 //_________________________________________________________________________________________________
69  const AlgebraicVector &parameters, const AlgebraicSymMatrix &covMatrix) const {
70  return this->clone(this->expandVector(parameters, this->selector()),
71  this->expandSymMatrix(covMatrix, this->selector()));
72 }
73 
74 //_________________________________________________________________________________________________
76  const AlignableDetOrUnitPtr &alidet) const {
77  const Alignable *ali = this->alignable(); // Alignable of these parameters
78  AlgebraicMatrix result(N_PARAM, 2); // initialised with zeros
79 
80  if (ali == alidet) {
81  const AlignableSurface &surf = ali->surface();
82 
83  // matrix of dimension BowedDerivs::N_PARAM x 2
84  const AlgebraicMatrix derivs(BowedDerivs()(tsos, surf.width(), surf.length(), true, ySplit_)); // split at ySplit_!
85 
86  // Parameters belong to surface part with y < ySplit_ or y >= ySplit_?
87  const double localY = tsos.localParameters().mixedFormatVector()[4];
88  const unsigned int indexOffset = (localY < ySplit_ ? 0 : dx2);
89  // Copy derivatives to relevant part of result
90  for (unsigned int i = BowedDerivs::dx; i < BowedDerivs::N_PARAM; ++i) {
91  result[indexOffset + i][0] = derivs[i][0];
92  result[indexOffset + i][1] = derivs[i][1];
93  }
94  } else {
95  // The following is even more difficult for
96  // TwoBowedSurfacesAlignmentParameters than for
97  // BowedSurfaceAlignmentParameters where this text comes from:
98  //
99  // We could give this a meaning by applying frame-to-frame derivatives
100  // to the rigid body part of the parameters (be careful that alpha ~=
101  // dslopeY and beta ~= -dslopeX, but with changed scale!) and keep the
102  // surface structure parameters untouched in local meaning. In this way we
103  // could do higher level alignment and determine 'average' surface
104  // structures for the components.
105  throw cms::Exception("MisMatch") << "TwoBowedSurfacesAlignmentParameters::derivatives: The hit "
106  "alignable must match the "
107  << "aligned one (i.e. bowed surface parameters cannot be used for "
108  "composed alignables)\n";
109  }
110 
111  return result;
112 }
113 
114 //_________________________________________________________________________________________________
116  Alignable *alignable = this->alignable();
117  if (!alignable) {
118  throw cms::Exception("BadParameters") << "TwoBowedSurfacesAlignmentParameters::apply: parameters without "
119  "alignable";
120  }
121 
122  // Some repeatedly needed variables
123  const AlignableSurface &surface = alignable->surface();
124  const double halfLength = surface.length() * 0.5; // full module
125  const double halfLength1 = (halfLength + ySplit_) * 0.5; // low-y surface
126  const double halfLength2 = (halfLength - ySplit_) * 0.5; // high-y surface
127 
128  // first copy the parameters into separate parts for the two surfaces
129  const AlgebraicVector &params = theData->parameters();
130  std::vector<double> rigidBowPar1(BowedDerivs::N_PARAM); // 1st surface (y < ySplit_)
131  std::vector<double> rigidBowPar2(BowedDerivs::N_PARAM); // 2nd surface (y >= ySplit_)
132  for (unsigned int i = 0; i < BowedDerivs::N_PARAM; ++i) {
133  rigidBowPar1[i] = params[i];
134  rigidBowPar2[i] = params[i + BowedDerivs::N_PARAM];
135  }
136  // Now adjust slopes to angles, note that dslopeX <-> -beta & dslopeY <->
137  // alpha, see BowedSurfaceAlignmentParameters::rotation(): FIXME: use atan?
138  rigidBowPar1[3] = params[dslopeY1] / halfLength1; // alpha1
139  rigidBowPar2[3] = params[dslopeY2] / halfLength2; // alpha2
140  rigidBowPar1[4] = -params[dslopeX1] / (surface.width() * 0.5); // beta1
141  rigidBowPar2[4] = -params[dslopeX2] / (surface.width() * 0.5); // beta2
142  // gamma is simply scaled
143  const double gammaScale1 = BowedDerivs::gammaScale(surface.width(), 2.0 * halfLength1);
144  rigidBowPar1[5] = params[drotZ1] / gammaScale1;
145  // const double gammaScale2 = std::sqrt(halfLength2 * halfLength2
146  // + surface.width() * surface.width()/4.);
147  const double gammaScale2 = BowedDerivs::gammaScale(surface.width(), 2.0 * halfLength2);
148  rigidBowPar2[5] = params[drotZ2] / gammaScale2;
149 
150  // Get rigid body rotations of full module as mean of the two surfaces:
151  align::EulerAngles angles(3); // to become 'common' rotation in local frame
152  for (unsigned int i = 0; i < 3; ++i) {
153  angles[i] = (rigidBowPar1[i + 3] + rigidBowPar2[i + 3]) * 0.5;
154  }
155  // Module rotations are around other axes than the one we determined,
156  // so we have to correct that the surfaces are shifted by the rotation around
157  // the module axis - in linear approximation just an additional shift:
158  const double yMean1 = -halfLength + halfLength1; // y of alpha1 rotation axis in module frame
159  const double yMean2 = halfLength - halfLength2; // y of alpha2 rotation axis in module frame
160  rigidBowPar1[dz1] -= angles[0] * yMean1; // correct w1 for alpha
161  rigidBowPar2[dz1] -= angles[0] * yMean2; // correct w2 for alpha
162  // Nothing for beta1/2 since anyway both around the y-axis of the module.
163  rigidBowPar1[dx1] += angles[2] * yMean1; // correct x1 for gamma
164  rigidBowPar2[dx1] += angles[2] * yMean2; // correct x1 for gamma
165 
166  // Get rigid body shifts of full module as mean of the two surfaces:
167  const align::LocalVector shift((rigidBowPar1[dx1] + rigidBowPar2[dx1]) * 0.5, // dx1!
168  (rigidBowPar1[dy1] + rigidBowPar2[dy1]) * 0.5, // dy1!
169  (rigidBowPar1[dz1] + rigidBowPar2[dz1]) * 0.5); // dz1!
170  // Apply module shift and rotation:
171  alignable->move(surface.toGlobal(shift));
172  // original code:
173  // alignable->rotateInLocalFrame( align::toMatrix(angles) );
174  // correct for rounding errors:
178 
179  // only update the surface deformations if they were selected for alignment
182  // Fill surface structures with mean bows and half differences for all
183  // parameters:
184  std::vector<align::Scalar> deformations;
185  deformations.reserve(13);
186  // first part: average bows
187  deformations.push_back((params[dsagittaX1] + params[dsagittaX2]) * 0.5);
188  deformations.push_back((params[dsagittaXY1] + params[dsagittaXY2]) * 0.5);
189  deformations.push_back((params[dsagittaY1] + params[dsagittaY2]) * 0.5);
190  // second part: half difference of all corrections
191  for (unsigned int i = 0; i < BowedDerivs::N_PARAM; ++i) {
192  // sign means that we have to apply e.g.
193  // - sagittaX for sensor 1: deformations[0] + deformations[9]
194  // - sagittaX for sensor 2: deformations[0] - deformations[9]
195  // - additional dx for sensor 1: deformations[3]
196  // - additional dx for sensor 2: -deformations[3]
197  deformations.push_back((rigidBowPar1[i] - rigidBowPar2[i]) * 0.5);
198  }
199  // finally: keep track of where we have split the module
200  deformations.push_back(ySplit_); // index is 12
201 
202  const TwoBowedSurfacesDeformation deform{deformations};
203 
204  // FIXME: true to propagate down?
205  // Needed for hierarchy with common deformation parameter,
206  // but that is not possible now anyway.
207  alignable->addSurfaceDeformation(&deform, false);
208  }
209 }
210 
211 //_________________________________________________________________________________________________
213 
214 //_________________________________________________________________________________________________
216  std::cout << "Contents of TwoBowedSurfacesAlignmentParameters:"
217  << "\nParameters: " << theData->parameters() << "\nCovariance: " << theData->covariance() << std::endl;
218 }
219 
220 //_________________________________________________________________________________________________
222  if (!ali)
223  return 0.;
224 
225  const align::PositionType pos(ali->globalPosition());
226  const double r = pos.perp();
227 
228  // The returned numbers for TEC are calculated as stated below from
229  // what is found in CMS-NOTE 2003/20.
230  // Note that at that time it was planned to use ST sensors for the outer TEC
231  // while in the end there are only a few of them in the tracker - the others
232  // are HPK. No idea whether there are subtle changes in geometry. The numbers
233  // have been cross checked with y-residuals in data, see
234  // https://hypernews.cern.ch/HyperNews/CMS/get/recoTracking/1018/1/1/2/1/1/1/2/1.html.
235 
236  if (r < 58.) { // Pixel, TIB, TID or TEC ring 1-4
237  edm::LogError("Alignment") << "@SUB=TwoBowedSurfacesAlignmentParameters::ySplitFromAlignable"
238  << "There are no split modules for radii < 58, but r = " << r;
239  return 0.;
240  } else if (fabs(pos.z()) < 118.) { // TOB
241  return 0.;
242  } else if (r > 90.) { // TEC ring 7
243  // W7a Height active= 106.900mm (Tab. 2) (but 106.926 mm p. 40!?)
244  // W7a R min active = 888.400mm (Paragraph 5.5.7)
245  // W7a R max active = W7a R min active + W7a Height active =
246  // = 888.400mm + 106.900mm = 995.300mm
247  // W7b Height active= 94.900mm (Tab. 2) (but 94.876 mm p. 41!?)
248  // W7b R min active = 998.252mm (Paragraph 5.5.8)
249  // W7b R max active = 998.252mm + 94.900mm = 1093.152mm
250  // mean radius module = 0.5*(1093.152mm + 888.400mm) = 990.776mm
251  // mean radius gap = 0.5*(998.252mm + 995.300mm) = 996.776mm
252  // ySplit = (mean radius gap - mean radius module) // local y and r have
253  // same directions!
254  // = 996.776mm - 990.776mm = 6mm
255  return 0.6;
256  } else if (r > 75.) { // TEC ring 6
257  // W6a Height active= 96.100mm (Tab. 2) (but 96.136 mm p. 38!?)
258  // W6a R min active = 727.000mm (Paragraph 5.5.5)
259  // W6a R max active = W6a R min active + W6a Height active =
260  // = 727.000mm + 96.100mm = 823.100mm
261  // W6b Height active= 84.900mm (Tab. 2) (but 84.936 mm p. 39!?)
262  // W6b R min active = 826.060mm (Paragraph 5.5.6)
263  // W6b R max active = 826.060mm + 84.900mm = 910.960mm
264  // mean radius module = 0.5*(910.960mm + 727.000mm) = 818.980mm
265  // mean radius gap = 0.5*(826.060mm + 823.100mm) = 824.580mm
266  // -1: local y and r have opposite directions!
267  // ySplit = -1*(mean radius gap - mean radius module)
268  // = -1*(824.580mm - 818.980mm) = -5.6mm
269  return -0.56;
270  } else { // TEC ring 5 - smaller radii alreay excluded before
271  // W5a Height active= 81.200mm (Tab. 2) (but 81.169 mm p. 36!?)
272  // W5a R min active = 603.200mm (Paragraph 5.5.3)
273  // W5a R max active = W5a R min active + W5a Height active =
274  // = 603.200mm + 81.200mm = 684.400mm
275  // W5b Height active= 63.200mm (Tab. 2) (63.198 mm on p. 37)
276  // W5b R min active = 687.293mm (Abschnitt 5.5.4 der note)
277  // W5b R max active = 687.293mm + 63.200mm = 750.493mm
278  // mean radius module = 0.5*(750.493mm + 603.200mm) = 676.8465mm
279  // mean radius gap = 0.5*(687.293mm + 684.400mm) = 685.8465mm
280  // -1: local y and r have opposite directions!
281  // ySplit = -1*(mean radius gap - mean radius module)
282  // = -1*(685.8465mm - 676.8465mm) = -9mm
283  return -0.9;
284  }
285  // return 0.;
286 }
align::GlobalPoints toGlobal(const align::LocalPoints &) const
Return in global coord given a set of local points.
const AlignableSurface & surface() const
Return the Surface (global position and orientation) of the object.
Definition: Alignable.h:132
Alignable * alignable(void) const
Get pointer to corresponding alignable.
selection
main part
Definition: corrVsCorr.py:100
int type() const override
tell type (AlignmentParametersFactory::ParametersType - but no circular dependency) ...
align::Scalar width() const
const AlgebraicVector & parameters(void) const
Get alignment parameters.
const LocalTrajectoryParameters & localParameters() const
virtual void move(const GlobalVector &displacement)=0
Movement with respect to the global reference frame.
void apply() override
apply parameters to alignable
Log< level::Error, false > LogError
AlgebraicVector expandVector(const AlgebraicVector &m, const std::vector< bool > &sel) const
AlgebraicSymMatrix expandSymMatrix(const AlgebraicSymMatrix &m, const std::vector< bool > &sel) const
TwoBowedSurfacesAlignmentParameters * cloneFromSelected(const AlgebraicVector &parameters, const AlgebraicSymMatrix &covMatrix) const override
Clone selected parameters (for update of parameters)
const PositionType & globalPosition() const
Return the global position of the object.
Definition: Alignable.h:135
CLHEP::HepMatrix AlgebraicMatrix
void rectify(RotationType &)
Correct a rotation matrix for rounding errors.
Definition: Utilities.cc:185
void setValid(bool v)
Set validity flag.
virtual void addSurfaceDeformation(const SurfaceDeformation *deformation, bool propagateDown)=0
AlignmentUserVariables * userVariables(void) const
Get pointer to user variables.
TwoBowedSurfacesAlignmentParameters * clone(const AlgebraicVector &parameters, const AlgebraicSymMatrix &covMatrix) const override
Clone all parameters (for update of parameters)
static double gammaScale(double width, double splitLength)
bool isValid(void) const
Get validity flag.
CLHEP::HepVector AlgebraicVector
AlgebraicVector5 mixedFormatVector() const
AlgebraicVector EulerAngles
Definition: Definitions.h:34
BowedSurfaceAlignmentDerivatives BowedDerivs
Give parameters a name (do not change order, see derivatives(..)!)
void setUserVariables(AlignmentUserVariables *auv)
Set pointer to user variables.
virtual void rotateInGlobalFrame(const RotationType &rotation)=0
align::Scalar length() const
virtual void print() const
print parameters to screen
const std::vector< bool > & selector(void) const
Get alignment parameter selector vector.
AlgebraicMatrix derivatives(const TrajectoryStateOnSurface &tsos, const AlignableDetOrUnitPtr &aliDet) const override
Get all derivatives.
RotationType toMatrix(const EulerAngles &)
Convert rotation angles about x-, y-, z-axes to matrix.
Definition: Utilities.cc:34
CLHEP::HepSymMatrix AlgebraicSymMatrix
static unsigned int const shift
double ySplitFromAlignable(const Alignable *ali) const
TwoBowedSurfacesAlignmentParameters(Alignable *alignable)
Constructor with empty parameters/covariance.