1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
/** \file ParametersToParametersDerivatives.cc
*
* $Date: 2010/12/09 19:53:42 $
* $Revision: 1.1 $
*/
#include "Alignment/CommonAlignmentParametrization/interface/ParametersToParametersDerivatives.h"
#include "Alignment/CommonAlignment/interface/Alignable.h"
#include "Alignment/CommonAlignment/interface/AlignmentParameters.h"
#include "Alignment/CommonAlignmentParametrization/interface/AlignmentParametersFactory.h"
#include "Alignment/CommonAlignmentParametrization/interface/BowedSurfaceAlignmentDerivatives.h"
#include "Alignment/CommonAlignmentParametrization/interface/FrameToFrameDerivative.h"
#include "Alignment/CommonAlignmentParametrization/interface/TwoBowedSurfacesAlignmentParameters.h"
#include "CondFormats/Alignment/interface/Definitions.h"
#include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
// already in header:
// #include "DataFormats/Math/interface/AlgebraicROOTObjects.h"
//_________________________________________________________________________________________________
ParametersToParametersDerivatives ::ParametersToParametersDerivatives(const Alignable &component,
const Alignable &mother)
: isOK_(component.alignmentParameters() && mother.alignmentParameters()) {
if (isOK_) {
isOK_ =
this->init(component, component.alignmentParameters()->type(), mother, mother.alignmentParameters()->type());
}
}
//_________________________________________________________________________________________________
bool ParametersToParametersDerivatives::init(const Alignable &component,
int typeComponent,
const Alignable &mother,
int typeMother) {
using namespace AlignmentParametersFactory; // for kRigidBody etc.
if ((typeMother == kRigidBody || typeMother == kRigidBody4D) &&
(typeComponent == kRigidBody || typeComponent == kRigidBody4D)) {
return this->initRigidRigid(component, mother);
} else if ((typeMother == kRigidBody || typeMother == kRigidBody4D) && typeComponent == kBowedSurface) {
return this->initBowedRigid(component, mother);
} else if ((typeMother == kRigidBody || typeMother == kRigidBody4D) && typeComponent == kTwoBowedSurfaces) {
return this->init2BowedRigid(component, mother);
} else {
// missing: mother with bows and component without, i.e. having 'common' bow
// parameters
edm::LogError("Alignment") << "@SUB=ParametersToParametersDerivatives::init"
<< "Mother " << parametersTypeName(parametersType(typeMother)) << ", component "
<< parametersTypeName(parametersType(typeComponent)) << ": not supported.";
return false;
}
}
//_________________________________________________________________________________________________
bool ParametersToParametersDerivatives::initRigidRigid(const Alignable &component, const Alignable &mother) {
// See G. Flucke's presentation from 20 Feb 2007
// https://indico.cern.ch/contributionDisplay.py?contribId=15&sessionId=1&confId=10930
// and C. Kleinwort's one from 14 Feb 2013
// https://indico.cern.ch/contributionDisplay.py?contribId=14&sessionId=1&confId=224472
FrameToFrameDerivative f2f;
// frame2frame returns dcomponent/dmother for both being rigid body, so we
// have to invert
AlgebraicMatrix66 m(asSMatrix<6, 6>(f2f.frameToFrameDerivative(&component, &mother)));
if (m.Invert()) { // now matrix is d(rigid_mother)/d(rigid_component)
// copy to TMatrix
derivatives_.ResizeTo(6, 6);
derivatives_.SetMatrixArray(m.begin());
return true;
} else {
return false;
}
}
//_________________________________________________________________________________________________
bool ParametersToParametersDerivatives::initBowedRigid(const Alignable &component, const Alignable &mother) {
// component is bowed surface, mother rigid body
FrameToFrameDerivative f2f;
// frame2frame returns dcomponent/dmother for both being rigid body, so we
// have to invert
AlgebraicMatrix66 rigM2rigC(asSMatrix<6, 6>(f2f.frameToFrameDerivative(&component, &mother)));
if (rigM2rigC.Invert()) { // now matrix is d(rigid_mother)/d(rigid_component)
const double halfWidth = 0.5 * component.surface().width();
const double halfLength = 0.5 * component.surface().length();
const AlgebraicMatrix69 m(this->dRigid_dBowed(rigM2rigC, halfWidth, halfLength));
// copy to TMatrix
derivatives_.ResizeTo(6, 9);
derivatives_.SetMatrixArray(m.begin());
return true;
} else {
return false;
}
}
//_________________________________________________________________________________________________
bool ParametersToParametersDerivatives::init2BowedRigid(const Alignable &component, const Alignable &mother) {
// component is two bowed surfaces, mother rigid body
const TwoBowedSurfacesAlignmentParameters *aliPar =
dynamic_cast<TwoBowedSurfacesAlignmentParameters *>(component.alignmentParameters());
if (!aliPar) {
edm::LogError("Alignment") << "@SUB=ParametersToParametersDerivatives::init2BowedRigid"
<< "dynamic_cast to TwoBowedSurfacesAlignmentParameters failed.";
return false;
}
// We treat the two surfaces as independent objects, i.e.
// 1) get the global position of each surface, depending on the ySplit value,
const double ySplit = aliPar->ySplit();
const double halfWidth = 0.5 * component.surface().width();
const double halfLength = 0.5 * component.surface().length();
const double halfLength1 = 0.5 * (halfLength + ySplit);
const double halfLength2 = 0.5 * (halfLength - ySplit);
const double yM1 = 0.5 * (ySplit - halfLength); // y_mean of surface 1
const double yM2 = yM1 + halfLength; // y_mean of surface 2
// The sensor positions and orientations could be adjusted using
// TwoBowedSurfacesDeformation attached to the component,
// but that should be 2nd order effect.
const align::GlobalPoint posSurf1(component.surface().toGlobal(align::LocalPoint(0., yM1, 0.)));
const align::GlobalPoint posSurf2(component.surface().toGlobal(align::LocalPoint(0., yM2, 0.)));
// 2) get derivatives for both,
// getDerivative(..) returns dcomponent/dmother for both being rigid body
FrameToFrameDerivative f2fMaker;
AlgebraicMatrix66 f2fSurf1(
f2fMaker.getDerivative(component.globalRotation(), mother.globalRotation(), posSurf1, mother.globalPosition()));
AlgebraicMatrix66 f2fSurf2(
f2fMaker.getDerivative(component.globalRotation(), mother.globalRotation(), posSurf2, mother.globalPosition()));
// We have to invert matrices to get d(rigid_mother)/d(rigid_component):
if (!f2fSurf1.Invert() || !f2fSurf2.Invert())
return false; // bail out if bad inversion
// Now get d(rigid_mother)/d(bowed_component):
const AlgebraicMatrix69 derivs1(this->dRigid_dBowed(f2fSurf1, halfWidth, halfLength1));
const AlgebraicMatrix69 derivs2(this->dRigid_dBowed(f2fSurf2, halfWidth, halfLength2));
// 3) fill the common matrix by merging the two.
typedef ROOT::Math::SMatrix<double, 6, 18, ROOT::Math::MatRepStd<double, 6, 18>> AlgebraicMatrix6_18;
AlgebraicMatrix6_18 derivs;
derivs.Place_at(derivs1, 0, 0); // left half
derivs.Place_at(derivs2, 0, 9); // right half
// copy to TMatrix
derivatives_.ResizeTo(6, 18);
derivatives_.SetMatrixArray(derivs.begin());
return true;
}
//_________________________________________________________________________________________________
ParametersToParametersDerivatives::AlgebraicMatrix69 ParametersToParametersDerivatives::dRigid_dBowed(
const AlgebraicMatrix66 &dRigidM2dRigidC, double halfWidth, double halfLength) {
typedef BowedSurfaceAlignmentDerivatives BowedDerivs;
const double gammaScale = BowedDerivs::gammaScale(2. * halfWidth, 2. * halfLength);
// 'dRigidM2dRigidC' is dmother/dcomponent for both being rigid body
// final matrix will be dmother/dcomponent for mother as rigid body, component
// with bows 1st index (row) is parameter of the mother (0..5), 2nd index
// (column) that of component (0..8):
AlgebraicMatrix69 derivs;
if (0. == gammaScale || 0. == halfWidth || 0. == halfLength) {
isOK_ = false; // bad input - we would have to devide by that in the following!
edm::LogError("Alignment") << "@SUB=ParametersToParametersDerivatives::dRigid_dBowed"
<< "Some zero length as input.";
return derivs;
}
for (unsigned int iRow = 0; iRow < AlgebraicMatrix69::kRows; ++iRow) {
// loop on 6 rigid body parameters of mother
// First copy the common rigid body part, e.g.:
// (0,0): du_moth/du_comp, (0,1): dv_moth/du_comp, (1,2): dw_moth/dv_comp
for (unsigned int iCol = 0; iCol < 3; ++iCol) { // 3 movements of component
derivs(iRow, iCol) = dRigidM2dRigidC(iRow, iCol);
}
// Now we have to take care of order, signs and scales for rotation-like
// parameters, see CMS AN-2011/531: slopeX = w10 = -halfWidth * beta
// => dpar_m/dslopeX_comp = dpar_m/d(-hw * beta_comp) =
// -(dpar_m/dbeta_comp)/hw
derivs(iRow, 3) = -dRigidM2dRigidC(iRow, 4) / halfWidth;
// slopeY = w10 = +halfLength * alpha
// => dpar_m/dslopeY_comp = dpar_m/d(+hl * alpha_comp) =
// (dpar_m/dalpha_comp)/hl
derivs(iRow, 4) = dRigidM2dRigidC(iRow, 3) / halfLength;
// rotZ = gammaScale * gamma
// => dpar_m/drotZ_comp = dpar_m/d(gamma_comp * gscale) =
// (dpar_m/dgamma)/gscale
derivs(iRow, 5) = dRigidM2dRigidC(iRow, 5) / gammaScale;
// Finally, sensor internals like their curvatures have no influence on
// mother:
for (unsigned int iCol = 6; iCol < AlgebraicMatrix69::kCols; ++iCol) {
derivs(iRow, iCol) = 0.; // 3 sagittae of component
}
}
return derivs;
}
//_________________________________________________________________________________________________
double ParametersToParametersDerivatives::operator()(unsigned int indParMother, unsigned int indParComp) const {
// Do range checks?
return derivatives_(indParMother, indParComp);
}
|