Project
Loading...
Searching...
No Matches
AlignableSensor.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
18#include "Framework/Logger.h"
22#include <vector>
23
25
26using namespace o2::align::utils;
27using namespace TMath;
28
29namespace o2
30{
31namespace align
32{
33
34//_________________________________________________________
35AlignableSensor::AlignableSensor(const char* name, int vid, int iid, Controller* ctr)
36 : AlignableVolume(name, iid, ctr), mSID(0), mDet(nullptr), mMatClAlg(), mMatClAlgReco()
37{
38 // def c-tor
39 setVolID(vid);
40 mAddError[0] = mAddError[1] = 0;
41 mConstrChild = 0; // sensors don't have children
42}
43
44//_________________________________________________________
45void AlignableSensor::dPosTraDParGeomLOC(const AlignmentPoint* pnt, double* deriv) const
46{
47 // Jacobian of position in sensor tracking frame (tra) vs sensor LOCAL frame
48 // parameters in TGeoHMatrix convention.
49 // Result is stored in array deriv as linearized matrix 6x3
50 const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians
51 double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3];
52 TGeoHMatrix matMod;
53 //
54 memset(delta, 0, kNDOFGeom * sizeof(double));
55 memset(deriv, 0, kNDOFGeom * 3 * sizeof(double));
56 const double* tra = pnt->getXYZTracking();
57 //
58 for (int ip = kNDOFGeom; ip--;) {
59 //
60 if (!isFreeDOF(ip)) {
61 continue;
62 }
63 //
64 double var = kDelta[ip];
65 delta[ip] -= var;
66 // variation matrix in tracking frame for variation in sensor LOCAL frame
67 getDeltaT2LmodLOC(matMod, delta);
68 matMod.LocalToMaster(tra, pos0); // varied position in tracking frame
69 //
70 delta[ip] += 0.5 * var;
71 getDeltaT2LmodLOC(matMod, delta);
72 matMod.LocalToMaster(tra, pos1); // varied position in tracking frame
73 //
74 delta[ip] += var;
75 getDeltaT2LmodLOC(matMod, delta);
76 matMod.LocalToMaster(tra, pos2); // varied position in tracking frame
77 //
78 delta[ip] += 0.5 * var;
79 getDeltaT2LmodLOC(matMod, delta);
80 matMod.LocalToMaster(tra, pos3); // varied position in tracking frame
81 //
82 delta[ip] = 0;
83 double* curd = deriv + ip * 3;
84 for (int i = 3; i--;) {
85 curd[i] = (8. * (pos2[i] - pos1[i]) - (pos3[i] - pos0[i])) / 6. / var;
86 }
87 }
88 //
89}
90
91//_________________________________________________________
92void AlignableSensor::dPosTraDParGeomLOC(const AlignmentPoint* pnt, double* deriv, const AlignableVolume* parent) const
93{
94 // Jacobian of position in sensor tracking frame (tra) vs parent volume LOCAL frame parameters.
95 // NO check of parentship is done!
96 // Result is stored in array deriv as linearized matrix 6x3
97 const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians
98 double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3];
99 TGeoHMatrix matMod;
100 // this is the matrix for transition from sensor to parent volume local frames: LOC=matRel*loc
101 TGeoHMatrix matRel = parent->getMatrixL2GIdeal().Inverse();
102 matRel *= getMatrixL2GIdeal();
103 //
104 memset(delta, 0, kNDOFGeom * sizeof(double));
105 memset(deriv, 0, kNDOFGeom * 3 * sizeof(double));
106 const double* tra = pnt->getXYZTracking();
107 //
108 for (int ip = kNDOFGeom; ip--;) {
109 //
110 if (!parent->isFreeDOF(ip)) { // RSCHANGE: was isFreeDOF(ip)
111 continue;
112 }
113 //
114 double var = kDelta[ip];
115 delta[ip] -= var;
116 getDeltaT2LmodLOC(matMod, delta, matRel);
117 matMod.LocalToMaster(tra, pos0); // varied position in tracking frame
118 //
119 delta[ip] += 0.5 * var;
120 getDeltaT2LmodLOC(matMod, delta, matRel);
121 matMod.LocalToMaster(tra, pos1); // varied position in tracking frame
122 //
123 delta[ip] += var;
124 getDeltaT2LmodLOC(matMod, delta, matRel);
125 matMod.LocalToMaster(tra, pos2); // varied position in tracking frame
126 //
127 delta[ip] += 0.5 * var;
128 getDeltaT2LmodLOC(matMod, delta, matRel);
129 matMod.LocalToMaster(tra, pos3); // varied position in tracking frame
130 //
131 delta[ip] = 0;
132 double* curd = deriv + ip * 3;
133 for (int i = 3; i--;) {
134 curd[i] = (8. * (pos2[i] - pos1[i]) - (pos3[i] - pos0[i])) / 6. / var;
135 }
136 }
137 //
138}
139
140//_________________________________________________________
141void AlignableSensor::dPosTraDParGeomTRA(const AlignmentPoint* pnt, double* deriv) const
142{
143 // Jacobian of position in sensor tracking frame (tra) vs sensor TRACKING
144 // frame parameters in TGeoHMatrix convention, i.e. the modified parameter is
145 // tra' = tau*tra
146 //
147 // Result is stored in array deriv as linearized matrix 6x3
148 const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians
149 double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3];
150 TGeoHMatrix matMod;
151 //
152 memset(delta, 0, kNDOFGeom * sizeof(double));
153 memset(deriv, 0, kNDOFGeom * 3 * sizeof(double));
154 const double* tra = pnt->getXYZTracking();
155 //
156 for (int ip = kNDOFGeom; ip--;) {
157 //
158 if (!isFreeDOF(ip)) {
159 continue;
160 }
161 //
162 double var = kDelta[ip];
163 delta[ip] -= var;
164 getDeltaT2LmodTRA(matMod, delta);
165 matMod.LocalToMaster(tra, pos0); // varied position in tracking frame
166 //
167 delta[ip] += 0.5 * var;
168 getDeltaT2LmodTRA(matMod, delta);
169 matMod.LocalToMaster(tra, pos1); // varied position in tracking frame
170 //
171 delta[ip] += var;
172 getDeltaT2LmodTRA(matMod, delta);
173 matMod.LocalToMaster(tra, pos2); // varied position in tracking frame
174 //
175 delta[ip] += 0.5 * var;
176 getDeltaT2LmodTRA(matMod, delta);
177 matMod.LocalToMaster(tra, pos3); // varied position in tracking frame
178 //
179 delta[ip] = 0;
180 double* curd = deriv + ip * 3;
181 for (int i = 3; i--;) {
182 curd[i] = (8. * (pos2[i] - pos1[i]) - (pos3[i] - pos0[i])) / 6. / var;
183 }
184 }
185 //
186}
187
188//_________________________________________________________
189void AlignableSensor::dPosTraDParGeomTRA(const AlignmentPoint* pnt, double* deriv, const AlignableVolume* parent) const
190{
191 // Jacobian of position in sensor tracking frame (tra) vs parent TRACKING
192 // frame parameters in TGeoHMatrix convention, i.e. the modified parameter is
193 // tra' = tau*tra
194 //
195 // Result is stored in array deriv as linearized matrix 6x3
196 const double kDelta[kNDOFGeom] = {0.1, 0.1, 0.1, 0.5 * DegToRad(), 0.5 * DegToRad(), 0.5 * DegToRad()}; // changed angles to radians
197 double delta[kNDOFGeom], pos0[3], pos1[3], pos2[3], pos3[3];
198 TGeoHMatrix matMod;
199 //
200 // 1st we need a matrix for transition between child and parent TRACKING frames
201 // Let TRA,LOC are positions in tracking and local frame of parent, linked as LOC=T2L*TRA
202 // and tra,loc are positions in tracking and local frame of child, linked as loc=t2l*tra
203 // The loc and LOC are linked as LOC=R*loc, where R = L2G^-1*l2g, with L2G and l2g
204 // local2global matrices for parent and child
205 //
206 // Then, TRA = T2L^-1*LOC = T2L^-1*R*loc = T2L^-1*R*t2l*tra
207 // -> TRA = matRel*tra, with matRel = T2L^-1*L2G^-1 * l2g*t2l
208 // Note that l2g*t2l are tracking to global matrices
209 TGeoHMatrix matRel, t2gP;
210 getMatrixT2G(matRel); // t2g matrix of child
211 parent->getMatrixT2G(t2gP); // t2g matrix of parent
212 const TGeoHMatrix& t2gpi = t2gP.Inverse();
213 matRel.MultiplyLeft(&t2gpi);
214 //
215 memset(delta, 0, kNDOFGeom * sizeof(double));
216 memset(deriv, 0, kNDOFGeom * 3 * sizeof(double));
217 const double* tra = pnt->getXYZTracking();
218 //
219 for (int ip = kNDOFGeom; ip--;) {
220 //
221 if (!parent->isFreeDOF(ip)) { // RSCHANGE: was isFreeDOF(ip)
222 continue;
223 }
224 //
225 double var = kDelta[ip];
226 delta[ip] -= var;
227 getDeltaT2LmodTRA(matMod, delta, matRel);
228 matMod.LocalToMaster(tra, pos0); // varied position in tracking frame
229 //
230 delta[ip] += 0.5 * var;
231 getDeltaT2LmodTRA(matMod, delta, matRel);
232 matMod.LocalToMaster(tra, pos1); // varied position in tracking frame
233 //
234 delta[ip] += var;
235 getDeltaT2LmodTRA(matMod, delta, matRel);
236 matMod.LocalToMaster(tra, pos2); // varied position in tracking frame
237 //
238 delta[ip] += 0.5 * var;
239 getDeltaT2LmodTRA(matMod, delta, matRel);
240 matMod.LocalToMaster(tra, pos3); // varied position in tracking frame
241 //
242 delta[ip] = 0;
243 double* curd = deriv + ip * 3;
244 for (int i = 3; i--;) {
245 curd[i] = (8. * (pos2[i] - pos1[i]) - (pos3[i] - pos0[i])) / 6. / var;
246 }
247 }
248 //
249}
250
251//_________________________________________________________
252void AlignableSensor::dPosTraDParGeom(const AlignmentPoint* pnt, double* deriv, const AlignableVolume* parent) const
253{
254 // calculate point position derivatives in tracking frame of sensor
255 // vs standard geometrical DOFs of its parent volume (if parent!=0) or sensor itself
256 Frame_t frame = parent ? parent->getVarFrame() : getVarFrame();
257 switch (frame) {
258 case kLOC:
259 parent ? dPosTraDParGeomLOC(pnt, deriv, parent) : dPosTraDParGeomLOC(pnt, deriv);
260 break;
261 case kTRA:
262 parent ? dPosTraDParGeomTRA(pnt, deriv, parent) : dPosTraDParGeomTRA(pnt, deriv);
263 break;
264 default:
265 LOG(error) << "Alignment frame " << parent->getVarFrame() << " is not implemented";
266 break;
267 }
268}
269
270//__________________________________________________________________
271void AlignableSensor::getModifiedMatrixT2LmodLOC(TGeoHMatrix& matMod, const double* delta) const
272{
273 // prepare the sensitive module tracking2local matrix from its current T2L matrix
274 // by applying local delta of modification of LOCAL frame:
275 // loc' = delta*loc = T2L'*tra = T2L'*T2L^-1*loc -> T2L' = delta*T2L
276 delta2Matrix(matMod, delta);
277 matMod.Multiply(&getMatrixT2L());
278}
279
280//__________________________________________________________________
281void AlignableSensor::getModifiedMatrixT2LmodTRA(TGeoHMatrix& matMod, const double* delta) const
282{
283 // prepare the sensitive module tracking2local matrix from its current T2L matrix
284 // by applying local delta of modification of TRACKING frame:
285 // loc' = T2L'*tra = T2L*delta*tra -> T2L' = T2L*delta
286 delta2Matrix(matMod, delta);
287 matMod.MultiplyLeft(&getMatrixT2L());
288}
289
290//__________________________________________________________________
292{
293 LOG(fatal) << "Sensor volume cannot have children: id=" << getVolID() << " " << GetName();
294}
295
296//__________________________________________________________________
298{
299 // compare VolIDs
300 return GetUniqueID() < b->GetUniqueID() ? -1 : 1;
301}
302
303//__________________________________________________________________
304/* // RS FIXME REM
305void AlignableSensor::setTrackingFrame()
306{
307 // define tracking frame of the sensor
308 // AliWarningF("Generic method called for %s",getSymName());
309 double tra[3] = {0}, glo[3];
310 TGeoHMatrix t2g;
311 getMatrixT2G(t2g);
312 t2g.LocalToMaster(tra, glo);
313 mX = Sqrt(glo[0] * glo[0] + glo[1] * glo[1]);
314 mAlp = ATan2(glo[1], glo[0]);
315 utils::bringToPiPM(mAlp);
316 //
317}
318*/
319//____________________________________________
320void AlignableSensor::Print(const Option_t* opt) const
321{
322 // print info
323 TString opts = opt;
324 opts.ToLower();
325 printf("Lev:%2d IntID:%7d %s VId:%6d X:%8.4f Alp:%+.4f | Err: %.4e %.4e | Used Points: %d\n",
328 printf(" DOFs: Tot: %d (offs: %5d) Free: %d Geom: %d {", mNDOFs, mFirstParGloID, mNDOFsFree, mNDOFGeomFree);
329 for (int i = 0; i < kNDOFGeom; i++) {
330 printf("%d", isFreeDOF(i) ? 1 : 0);
331 }
332 printf("} in %s frame\n", sFrameName[mVarFrame]);
333 //
334 //
335 //
336 if (opts.Contains("par") && mFirstParGloID >= 0) {
337 printf(" Lb: ");
338 for (int i = 0; i < mNDOFs; i++) {
339 printf("%10d ", getParLab(i));
340 }
341 printf("\n");
342 printf(" Vl: ");
343 for (int i = 0; i < mNDOFs; i++) {
344 printf("%+9.3e ", getParVal(i));
345 }
346 printf("\n");
347 printf(" Er: ");
348 for (int i = 0; i < mNDOFs; i++) {
349 printf("%+9.3e ", getParErr(i));
350 }
351 printf("\n");
352 }
353 //
354 if (opts.Contains("mat")) { // print matrices
355 printf("L2G ideal : ");
356 getMatrixL2GIdeal().Print();
357 printf("L2G misalign: ");
358 getMatrixL2G().Print();
359 printf("L2G RecoTime: ");
360 getMatrixL2GReco().Print();
361 printf("T2L : ");
362 getMatrixT2L().Print();
363 printf("ClAlg : ");
364 getMatrixClAlg().Print();
365 printf("ClAlgReco: ");
366 getMatrixClAlgReco().Print();
367 }
368 //
369}
370
371//____________________________________________
373{
374 // prepare alignment matrix in the LOCAL frame: delta = Gideal^-1 * G
375 TGeoHMatrix ma = getMatrixL2GIdeal().Inverse();
376 ma *= getMatrixL2G();
377 setMatrixClAlg(ma);
378 //
379}
380
381//____________________________________________
383{
384 // prepare alignment matrix used at reco time
385 TGeoHMatrix ma = getMatrixL2GIdeal().Inverse();
386 ma *= getMatrixL2GReco();
388 //
389}
390
391//____________________________________________
393{
394 // update
396}
397
398//____________________________________________
399void AlignableSensor::dPosTraDParCalib(const AlignmentPoint* pnt, double* deriv, int calibID, const AlignableVolume* parent) const
400{
401 // calculate point position X,Y,Z derivatives wrt calibration parameter calibID of given parent
402 // parent=0 means top detector object calibration
403 //
404 deriv[0] = deriv[1] = deriv[2] = 0;
405}
406
407//______________________________________________________
409{
410 // finalize statistics on processed points
411 return mNProcPoints;
412}
413
414//_________________________________________________________________
415void AlignableSensor::updateL2GRecoMatrices(const std::vector<o2::detectors::AlignParam>& algArr, const TGeoHMatrix* cumulDelta)
416{
417 // recreate mMatL2GReco matrices from ideal L2G matrix and alignment objects
418 // used during data reconstruction.
419 // On top of what each volume does, also update misalignment matrix inverse
420 //
421 AlignableVolume::updateL2GRecoMatrices(algArr, cumulDelta);
423 //
424}
425
426//_________________________________________________________________
428{
429 // apply to the tracking coordinates in the sensor frame the full chain
430 // of alignments found by MP for this sensor and its parents
431 //
432 const AlignableVolume* vol = this;
433 TGeoHMatrix deltaG;
434 // create global combined delta:
435 // DeltaG = deltaG_0*...*deltaG_j, where delta_i is global delta of each member of hierarchy
436 while (vol) {
437 TGeoHMatrix deltaGJ;
438 vol->createAlignmenMatrix(deltaGJ);
439 deltaG.MultiplyLeft(&deltaGJ);
440 vol = vol->getParent();
441 }
442 //
443 // update misaligned L2G matrix
444 deltaG *= getMatrixL2GIdeal();
445 setMatrixL2G(deltaG);
446 //
447 // update local misalignment matrix
449 //
450}
451/*
452//_________________________________________________________________
453void AlignableSensor::applyAlignmentFromMPSol()
454{
455 // apply to the tracking coordinates in the sensor frame the full chain
456 // of alignments found by MP for this sensor and its parents
457 double delta[kNDOFGeom]={0};
458 //
459 TGeoHMatrix matMod;
460 //
461 // sensor proper variation
462 getParValGeom(delta);
463 isFrameTRA() ? getDeltaT2LmodTRA(matMod,delta) : getDeltaT2LmodLOC(matMod,delta);
464 mMatClAlg.MultiplyLeft(&matMod);
465 //
466 AlignableVolume* parent = this;
467 while ((parent==parent->getParent())) {
468 // this is the matrix for transition from sensor to parent volume frame
469 parent->getParValGeom(delta);
470 TGeoHMatrix matRel,t2gP;
471 if (parent->isFrameTRA()) {
472 getMatrixT2G(matRel); // t2g matrix of child
473 parent->getMatrixT2G(t2gP); // t2g matrix of parent
474 matRel.MultiplyLeft(&t2gP.Inverse());
475 getDeltaT2LmodTRA(matMod, delta, matRel);
476 }
477 else {
478 matRel = parent->getMatrixL2GIdeal().Inverse();
479 matRel *= getMatrixL2GIdeal();
480 getDeltaT2LmodLOC(matMod, delta, matRel);
481 }
482 mMatClAlg.MultiplyLeft(&matMod);
483 }
484 //
485}
486*/
487
488} // namespace align
489} // namespace o2
Base class for detector: wrapper for set of volumes.
ClassImp(o2::align::AlignableSensor)
End-chain alignment volume in detector branch, where the actual measurement is done.
Meausered point in the sensor.
Definition of the GeometryManager class.
int32_t i
virtual void updatePointByTrackInfo(AlignmentPoint *pnt, const trackParam_t *t) const
void addChild(AlignableVolume *) override
const TGeoHMatrix & getMatrixClAlg() const
virtual void updatePointByTrackInfo(AlignmentPoint *pnt, const trackParam_t *t) const
void setMatrixClAlgReco(const TGeoHMatrix &m)
void getModifiedMatrixT2LmodLOC(TGeoHMatrix &matMod, const double *delta) const
int Compare(const TObject *a) const override
virtual void dPosTraDParCalib(const AlignmentPoint *pnt, double *deriv, int calibID, const AlignableVolume *parent=nullptr) const
virtual void dPosTraDParGeomTRA(const AlignmentPoint *pnt, double *deriv) const
void updateL2GRecoMatrices(const std::vector< o2::detectors::AlignParam > &algArr, const TGeoHMatrix *cumulDelta) override
void Print(const Option_t *opt="") const override
void setMatrixClAlg(const TGeoHMatrix &m)
virtual void dPosTraDParGeomLOC(const AlignmentPoint *pnt, double *deriv) const
virtual void dPosTraDParGeom(const AlignmentPoint *pnt, double *deriv, const AlignableVolume *parent=nullptr) const
void getModifiedMatrixT2LmodTRA(TGeoHMatrix &matMod, const double *delta) const
const TGeoHMatrix & getMatrixClAlgReco() const
virtual void updateL2GRecoMatrices(const std::vector< o2::detectors::AlignParam > &algArr, const TGeoHMatrix *cumulDelta)
static const char * sFrameName[kNVarFrames]
const TGeoHMatrix & getMatrixT2L() const
void getDeltaT2LmodLOC(TGeoHMatrix &matMod, const double *delta) const
void delta2Matrix(TGeoHMatrix &deltaM, const double *delta) const
void getDeltaT2LmodTRA(TGeoHMatrix &matMod, const double *delta) const
const TGeoHMatrix & getMatrixL2G() const
const TGeoHMatrix & getMatrixL2GReco() const
bool isFreeDOF(int dof) const
void createAlignmenMatrix(TGeoHMatrix &alg, const TGeoHMatrix *envelopeDelta=nullptr) const
void getMatrixT2G(TGeoHMatrix &m) const
void setMatrixL2G(const TGeoHMatrix &m)
const TGeoHMatrix & getMatrixL2GIdeal() const
AlignableVolume * getParent() const
const char * getSymName() const
const double * getXYZTracking() const
float getParVal(int par) const
Definition DOFSet.h:39
float getParErr(int par) const
Definition DOFSet.h:40
int getParLab(int par) const
Definition DOFSet.h:41
GLuint const GLchar * name
Definition glcorearb.h:781
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
typename track::TrackParametrizationWithError< double > trackParam_t
Definition utils.h:29
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"