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