Project
Loading...
Searching...
No Matches
MisAligner.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
12// $Id$
13//
14//-----------------------------------------------------------------------------
41//-----------------------------------------------------------------------------
42
44
45#include <TGeoMatrix.h>
46#include <TMath.h>
47#include <TRandom.h>
48#include <Riostream.h>
49
51
52#include "Framework/Logger.h"
53
55
56namespace o2::mch::geo
57{
58
59bool MisAligner::isMatrixConvertedToAngles(const double* rot, double& psi, double& theta, double& phi) const
60{
65 //
66 if (std::abs(rot[0]) < 1e-7 || std::abs(rot[8]) < 1e-7) {
67 LOG(error) << "Failed to extract roll-pitch-yall angles!";
68 return false;
69 }
70 psi = std::atan2(-rot[5], rot[8]);
71 theta = std::asin(rot[2]);
72 phi = std::atan2(-rot[1], rot[0]);
73 return true;
74}
75//______________________________________________________________________________
76MisAligner::MisAligner(double cartXMisAligM, double cartXMisAligW, double cartYMisAligM, double cartYMisAligW, double angMisAligM, double angMisAligW)
77 : TObject(), mUseUni(kFALSE), mUseGaus(kTRUE), mXYAngMisAligFactor(0.0), mZCartMisAligFactor(0.0)
78{
80 for (int i = 0; i < 6; i++) {
81 for (int j = 0; j < 2; j++) {
82 mDetElemMisAlig[i][j] = 0.0;
83 mModuleMisAlig[i][j] = 0.0;
84 }
85 }
86 mDetElemMisAlig[0][0] = cartXMisAligM;
87 mDetElemMisAlig[0][1] = cartXMisAligW;
88 mDetElemMisAlig[1][0] = cartYMisAligM;
89 mDetElemMisAlig[1][1] = cartYMisAligW;
90 mDetElemMisAlig[5][0] = angMisAligM;
91 mDetElemMisAlig[5][1] = angMisAligW;
92}
93
94//______________________________________________________________________________
95MisAligner::MisAligner(double cartMisAligM, double cartMisAligW, double angMisAligM, double angMisAligW)
96 : TObject(), mUseUni(kFALSE), mUseGaus(kTRUE), mXYAngMisAligFactor(0.0), mZCartMisAligFactor(0.0)
97{
99 for (int i = 0; i < 6; i++) {
100 for (int j = 0; j < 2; j++) {
101 mDetElemMisAlig[i][j] = 0.0;
102 mModuleMisAlig[i][j] = 0.0;
103 }
104 }
105 mDetElemMisAlig[0][0] = cartMisAligM;
106 mDetElemMisAlig[0][1] = cartMisAligW;
107 mDetElemMisAlig[1][0] = cartMisAligM;
108 mDetElemMisAlig[1][1] = cartMisAligW;
109 mDetElemMisAlig[5][0] = angMisAligM;
110 mDetElemMisAlig[5][1] = angMisAligW;
111}
112
113//______________________________________________________________________________
114MisAligner::MisAligner(double cartMisAlig, double angMisAlig)
115 : TObject(),
116 mUseUni(kTRUE),
117 mUseGaus(kFALSE),
118 mXYAngMisAligFactor(0.0),
119 mZCartMisAligFactor(0.0)
120{
122 for (int i = 0; i < 6; i++) {
123 for (int j = 0; j < 2; j++) {
124 mDetElemMisAlig[i][j] = 0.0;
125 mModuleMisAlig[i][j] = 0.0;
126 }
127 }
128 mDetElemMisAlig[0][1] = cartMisAlig;
129 mDetElemMisAlig[1][1] = cartMisAlig;
130 mDetElemMisAlig[5][1] = angMisAlig;
131}
132
133//_____________________________________________________________________________
135 : TObject(),
136 mUseUni(kFALSE),
137 mUseGaus(kTRUE),
138 mXYAngMisAligFactor(0.0),
139 mZCartMisAligFactor(0.0)
140{
142 for (int i = 0; i < 6; i++) {
143 for (int j = 0; j < 2; j++) {
144 mDetElemMisAlig[i][j] = 0.0;
145 mModuleMisAlig[i][j] = 0.0;
146 }
147 }
148}
149
150/*
151//______________________________________________________________________________
152MisAligner::~MisAligner()
153{
155}
156 */
157
158//_________________________________________________________________________
160{
162
163 if (TMath::Abs(factor) > 1.0 && factor > 0.) {
164 mXYAngMisAligFactor = factor;
165 mDetElemMisAlig[3][0] = mDetElemMisAlig[5][0] * factor; // These lines were
166 mDetElemMisAlig[3][1] = mDetElemMisAlig[5][1] * factor; // added to keep
167 mDetElemMisAlig[4][0] = mDetElemMisAlig[5][0] * factor; // backward
168 mDetElemMisAlig[4][1] = mDetElemMisAlig[5][1] * factor; // compatibility
169 } else {
170 LOG(error) << "Invalid XY angular misalign factor, " << factor;
171 }
172}
173
174//_________________________________________________________________________
176{
178 if (TMath::Abs(factor) < 1.0 && factor > 0.) {
179 mZCartMisAligFactor = factor;
180 mDetElemMisAlig[2][0] = mDetElemMisAlig[0][0]; // These lines were added to
181 mDetElemMisAlig[2][1] = mDetElemMisAlig[0][1] * factor; // keep backward compatibility
182 } else {
183 LOG(error) << Form("Invalid Z cartesian misalign factor, %f", factor);
184 }
185}
186
187//_________________________________________________________________________
188void MisAligner::getUniMisAlign(double cartMisAlig[3], double angMisAlig[3], const double lParMisAlig[6][2]) const
189{
191
200 cartMisAlig[0] = gRandom->Uniform(-lParMisAlig[0][1] + lParMisAlig[0][0], lParMisAlig[0][0] + lParMisAlig[0][1]);
201 cartMisAlig[1] = gRandom->Uniform(-lParMisAlig[1][1] + lParMisAlig[1][0], lParMisAlig[1][0] + lParMisAlig[1][1]);
202 cartMisAlig[2] = gRandom->Uniform(-lParMisAlig[2][1] + lParMisAlig[2][0], lParMisAlig[2][0] + lParMisAlig[2][1]);
203
204 angMisAlig[0] = gRandom->Uniform(-lParMisAlig[3][1] + lParMisAlig[3][0], lParMisAlig[3][0] + lParMisAlig[3][1]);
205 angMisAlig[1] = gRandom->Uniform(-lParMisAlig[4][1] + lParMisAlig[4][0], lParMisAlig[4][0] + lParMisAlig[4][1]);
206 angMisAlig[2] = gRandom->Uniform(-lParMisAlig[5][1] + lParMisAlig[5][0], lParMisAlig[5][0] + lParMisAlig[5][1]); // degrees
207}
208
209//_________________________________________________________________________
210void MisAligner::getGausMisAlign(double cartMisAlig[3], double angMisAlig[3], const double lParMisAlig[6][2]) const
211{
213
222 cartMisAlig[0] = gRandom->Gaus(lParMisAlig[0][0], lParMisAlig[0][1]); //, 3. * lParMisAlig[0][1]);
223 cartMisAlig[1] = gRandom->Gaus(lParMisAlig[1][0], lParMisAlig[1][1]); //, 3. * lParMisAlig[1][1]);
224 cartMisAlig[2] = gRandom->Gaus(lParMisAlig[2][0], lParMisAlig[2][1]); //, 3. * lParMisAlig[2][1]);
225
226 angMisAlig[0] = gRandom->Gaus(lParMisAlig[3][0], lParMisAlig[3][1]); //, 3. * lParMisAlig[3][1]);
227 angMisAlig[1] = gRandom->Gaus(lParMisAlig[4][0], lParMisAlig[4][1]); //, 3. * lParMisAlig[4][1]);
228 angMisAlig[2] = gRandom->Gaus(lParMisAlig[5][0], lParMisAlig[5][1]); //, 3. * lParMisAlig[5][1]); // degrees
229}
230
231//_________________________________________________________________________
232TGeoCombiTrans MisAligner::misAlignDetElem() const
233{
239
240 double cartMisAlig[3] = {0, 0, 0};
241 double angMisAlig[3] = {0, 0, 0};
242
243 if (mUseUni) {
244 getUniMisAlign(cartMisAlig, angMisAlig, mDetElemMisAlig);
245 } else {
246 if (!mUseGaus) {
247 LOG(warn) << Form("Neither uniform nor gausian distribution is set! Will use gausian...");
248 }
249 getGausMisAlign(cartMisAlig, angMisAlig, mDetElemMisAlig);
250 }
251
252 TGeoTranslation deltaTrans(cartMisAlig[0], cartMisAlig[1], cartMisAlig[2]);
253 TGeoRotation deltaRot;
254 deltaRot.RotateX(angMisAlig[0]);
255 deltaRot.RotateY(angMisAlig[1]);
256 deltaRot.RotateZ(angMisAlig[2]);
257
258 TGeoCombiTrans deltaTransf(deltaTrans, deltaRot);
259
260 LOG(info) << Form("Rotated DE by %f about Z axis.", angMisAlig[2]);
261
262 return TGeoCombiTrans(deltaTransf);
263}
264
265//_________________________________________________________________________
266TGeoCombiTrans MisAligner::misAlignModule() const
267{
272
273 double cartMisAlig[3] = {0, 0, 0};
274 double angMisAlig[3] = {0, 0, 0};
275
276 if (mUseUni) {
277 getUniMisAlign(cartMisAlig, angMisAlig, mModuleMisAlig);
278 } else {
279 if (!mUseGaus) {
280 LOG(warn) << Form("Neither uniform nor gausian distribution is set! Will use gausian...");
281 }
282 getGausMisAlign(cartMisAlig, angMisAlig, mModuleMisAlig);
283 }
284
285 TGeoTranslation deltaTrans(cartMisAlig[0], cartMisAlig[1], cartMisAlig[2]);
286 TGeoRotation deltaRot;
287 deltaRot.RotateX(angMisAlig[0]);
288 deltaRot.RotateY(angMisAlig[1]);
289 deltaRot.RotateZ(angMisAlig[2]);
290
291 TGeoCombiTrans deltaTransf(deltaTrans, deltaRot);
292
293 LOG(info) << Form("Rotated Module by %f about Z axis.", angMisAlig[2]);
294
295 return TGeoCombiTrans(deltaTransf);
296}
297
298//______________________________________________________________________
299// void MisAligner::MisAlign(Bool_t verbose) const
300void MisAligner::misAlign(std::vector<o2::detectors::AlignParam>& params, Bool_t verbose) const
301{
306
307 std::vector<std::vector<int>> DEofHC{{100, 103},
308 {101, 102},
309 {200, 203},
310 {201, 202},
311 {300, 303},
312 {301, 302},
313 {400, 403},
314 {401, 402},
315 {500, 501, 502, 503, 504, 514, 515, 516, 517},
316 {505, 506, 507, 508, 509, 510, 511, 512, 513},
317 {600, 601, 602, 603, 604, 614, 615, 616, 617},
318 {605, 606, 607, 608, 609, 610, 611, 612, 613},
319 {700, 701, 702, 703, 704, 705, 706, 720, 721, 722, 723, 724, 725},
320 {707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719},
321 {800, 801, 802, 803, 804, 805, 806, 820, 821, 822, 823, 824, 825},
322 {807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819},
323 {900, 901, 902, 903, 904, 905, 906, 920, 921, 922, 923, 924, 925},
324 {907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919},
325 {1000, 1001, 1002, 1003, 1004, 1005, 1006, 1020, 1021, 1022, 1023, 1024, 1025},
326 {1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 1018, 1019}};
327
329 for (int hc = 0; hc < 20; hc++) {
330
331 TGeoCombiTrans localDeltaTransform = misAlignModule();
332 // localDeltaTransform.Print();
333
334 std::string sname = fmt::format("MCH/HC{}", hc);
335 lAP.setSymName(sname.c_str());
336
337 double lPsi, lTheta, lPhi = 0.;
338 if (!isMatrixConvertedToAngles(localDeltaTransform.GetRotationMatrix(), lPsi, lTheta, lPhi)) {
339 LOG(error) << "Problem extracting angles!";
340 }
341
342 LOG(debug) << fmt::format("Module {} is {} : {} : Local Delta | X: {:+f} Y: {:+f} Z: {:+f} | pitch: {:+f} roll: {:+f} yaw: {:+f}\n", hc, lAP.getSymName(), lAP.getAlignableID(), localDeltaTransform.GetTranslation()[0],
343 localDeltaTransform.GetTranslation()[1], localDeltaTransform.GetTranslation()[2], lPsi, lTheta, lPhi);
344 if (!lAP.setLocalParams(localDeltaTransform)) {
345 LOG(error) << "Could not set local params for " << sname.c_str();
346 }
347 LOG(debug) << fmt::format("Module {} is {} : {} : Global Delta | X: {:+f} Y: {:+f} Z: {:+f} | pitch: {:+f} roll: {:+f} yaw: {:+f}\n", hc, lAP.getSymName(), lAP.getAlignableID(), lAP.getX(),
348 lAP.getY(), lAP.getZ(), lAP.getPsi(), lAP.getTheta(), lAP.getPhi());
349 // lAP.print();
350 lAP.applyToGeometry();
351 params.emplace_back(lAP);
352 for (int de = 0; de < DEofHC[hc].size(); de++) {
353
354 localDeltaTransform = misAlignDetElem();
355
356 sname = fmt::format("MCH/HC{}/DE{}", hc, DEofHC[hc][de]);
357 lAP.setSymName(sname.c_str());
358
359 if (!isMatrixConvertedToAngles(localDeltaTransform.GetRotationMatrix(), lPsi, lTheta, lPhi)) {
360 LOG(error) << "Problem extracting angles for " << sname.c_str();
361 }
362 LOG(debug) << fmt::format("DetElem {} is {} : {} : Local Delta| X: {:+f} Y: {:+f} Z: {:+f} | pitch: {:+f} roll: {:+f} yaw: {:+f}\n", de, lAP.getSymName(), lAP.getAlignableID(), localDeltaTransform.GetTranslation()[0],
363 localDeltaTransform.GetTranslation()[1], localDeltaTransform.GetTranslation()[2], lPsi, lTheta, lPhi);
364 if (!lAP.setLocalParams(localDeltaTransform)) {
365 LOG(error) << " Could not set local params for " << sname.c_str();
366 }
367 LOG(debug) << fmt::format("DetElem {} is {} : {} : Global Delta | X: {:+f} Y: {:+f} Z: {:+f} | pitch: {:+f} roll: {:+f} yaw: {:+f}\n", de, lAP.getSymName(), lAP.getAlignableID(), lAP.getX(),
368 lAP.getY(), lAP.getZ(), lAP.getPsi(), lAP.getTheta(), lAP.getPhi());
369 lAP.applyToGeometry();
370 params.emplace_back(lAP);
371 }
372
373 if (verbose) {
374 LOG(info) << "MisAligned half chamber " << hc;
375 }
376 }
377}
378
379void MisAligner::setAlignmentResolution(const TClonesArray* misAlignArray, int rChId, double rChResX, double rChResY, double rDeResX, double rDeResY)
380{
383}
384
385} // namespace o2::mch::geo
Definition of the base alignment parameters class.
int32_t i
ClassImp(o2::mch::geo::MisAligner)
uint32_t j
Definition RawData.h:0
std::ostringstream debug
int getAlignableID() const
return alignable entry ID
Definition AlignParam.h:67
double getTheta() const
Definition AlignParam.h:49
void setSymName(const char *m)
set symbolic name of the volume
Definition AlignParam.h:64
const std::string & getSymName() const
return symbolic name of the volume
Definition AlignParam.h:45
double getPhi() const
iparamater's getters
Definition AlignParam.h:47
bool setLocalParams(double x, double y, double z, double psi, double theta, double phi)
================ methods for setting global delta params from local delta
double getPsi() const
Definition AlignParam.h:48
bool applyToGeometry() const
apply object to geoemetry
void setAlignmentResolution(const TClonesArray *misAlignArray, int chId=-1, double chResX=-1., double chResY=-1., double deResX=-1., double deResY=-1.)
Set alignment resolution to misalign objects to be stored in CDB.
void misAlign(std::vector< o2::detectors::AlignParam > &arr, bool verbose=false) const
void setZCartMisAligFactor(double factor)
void setXYAngMisAligFactor(double factor)
GLenum const GLfloat * params
Definition glcorearb.h:272
get the local-to-global transformation for a given detection element
Definition Geometry.h:25
uint16_t de
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"