]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliAlignObj.cxx
Transformations for rotated geometry of st345 (Gines)
[u/mrichter/AliRoot.git] / STEER / AliAlignObj.cxx
CommitLineData
c18195b9 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16//-----------------------------------------------------------------
befe2c08 17// Implementation of the alignment object class through the abstract
18// class AliAlignObj. From it two derived concrete representation of
19// alignment object class (AliAlignObjAngles, AliAlignObjMatrix) are
20// derived in separate files.
c18195b9 21//-----------------------------------------------------------------
fdf65bb5 22/*****************************************************************************
23 * AliAlignObjAngles: derived alignment class storing alignment information *
24 * for a single volume in form of three doubles for the translation *
25 * and three doubles for the rotation expressed with the euler angles *
26 * in the xyz-convention (http://mathworld.wolfram.com/EulerAngles.html), *
27 * also known as roll, pitch, yaw. PLEASE NOTE THE ANGLES SIGNS ARE *
28 * INVERSE WITH RESPECT TO THIS REFERENCE!!! In this way the representation*
29 * is fully consistent with the TGeo Rotation methods. *
30 *****************************************************************************/
c18195b9 31
995ad051 32#include <TGeoManager.h>
33#include <TGeoPhysicalNode.h>
34
c18195b9 35#include "AliAlignObj.h"
03b18860 36#include "AliTrackPointArray.h"
37#include "AliLog.h"
98937d93 38
c18195b9 39ClassImp(AliAlignObj)
40
98937d93 41Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = {
42 80, 160, // ITS SPD
43 84, 176, // ITS SDD
44 748, 950, // ITS SSD
45 36, 36, // TPC
46 90, 90, 90, 90, 90, 90, // TRD
9abb5d7b 47 1674, // TOF
98937d93 48 1, 1, // PHOS ??
03b18860 49 7, // RICH ??
98937d93 50 1 // MUON ??
51};
52
53const char* AliAlignObj::fgLayerName[kLastLayer - kFirstLayer] = {
54 "ITS inner pixels layer", "ITS outer pixels layer",
55 "ITS inner drifts layer", "ITS outer drifts layer",
56 "ITS inner strips layer", "ITS outer strips layer",
57 "TPC inner chambers layer", "TPC outer chambers layer",
58 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
59 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
60 "TOF layer",
61 "?","?",
03b18860 62 "RICH layer",
98937d93 63 "?"
64};
65
7604a026 66TString* AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = {
03b18860 67 0x0,0x0,
68 0x0,0x0,
69 0x0,0x0,
70 0x0,0x0,
71 0x0,0x0,0x0,
72 0x0,0x0,0x0,
73 0x0,
74 0x0,0x0,
75 0x0,
76 0x0
77};
78
c18195b9 79//_____________________________________________________________________________
80AliAlignObj::AliAlignObj():
81 fVolUID(0)
82{
03b18860 83 // default constructor
84 InitVolPaths();
c18195b9 85}
86
87//_____________________________________________________________________________
88AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
89 TObject(theAlignObj)
90{
91 //copy constructor
92 fVolPath = theAlignObj.GetVolPath();
93 fVolUID = theAlignObj.GetVolUID();
94}
95
96//_____________________________________________________________________________
97AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
98{
99 // assignment operator
100 if(this==&theAlignObj) return *this;
101 fVolPath = theAlignObj.GetVolPath();
102 fVolUID = theAlignObj.GetVolUID();
103 return *this;
104}
105
106//_____________________________________________________________________________
107AliAlignObj::~AliAlignObj()
108{
109 // dummy destructor
110}
111
befe2c08 112//_____________________________________________________________________________
113void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
114{
115 // From detector name and module number (according to detector numbering)
116 // build fVolUID, unique numerical identity of that volume inside ALICE
117 // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
118 // remaining 11 for module ID inside det (2048 possible values).
119 //
120 fVolUID = LayerToVolUID(detId,modId);
121}
122
123//_____________________________________________________________________________
124void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
125{
126 // From detector name and module number (according to detector numbering)
127 // build fVolUID, unique numerical identity of that volume inside ALICE
128 // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
129 // remaining 11 for module ID inside det (2048 possible values).
130 //
131 layerId = VolUIDToLayer(fVolUID,modId);
132}
133
c18195b9 134//_____________________________________________________________________________
135void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
136{
fdf65bb5 137 // Calculates the rotation matrix using the
138 // Euler angles in "x y z" notation
c18195b9 139 Double_t degrad = TMath::DegToRad();
140 Double_t sinpsi = TMath::Sin(degrad*angles[0]);
141 Double_t cospsi = TMath::Cos(degrad*angles[0]);
142 Double_t sinthe = TMath::Sin(degrad*angles[1]);
143 Double_t costhe = TMath::Cos(degrad*angles[1]);
144 Double_t sinphi = TMath::Sin(degrad*angles[2]);
145 Double_t cosphi = TMath::Cos(degrad*angles[2]);
146
147 rot[0] = costhe*cosphi;
148 rot[1] = -costhe*sinphi;
149 rot[2] = sinthe;
150 rot[3] = sinpsi*sinthe*cosphi + cospsi*sinphi;
151 rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
152 rot[5] = -costhe*sinpsi;
153 rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
154 rot[7] = cospsi*sinthe*sinphi + sinpsi*cosphi;
155 rot[8] = costhe*cospsi;
156}
157
158//_____________________________________________________________________________
159Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
160{
fdf65bb5 161 // Calculates the Euler angles in "x y z" notation
162 // using the rotation matrix
c18195b9 163 if(rot[0]<1e-7 || rot[8]<1e-7) return kFALSE;
164 Double_t raddeg = TMath::RadToDeg();
165 angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
166 angles[1]=raddeg*TMath::ASin(rot[2]);
167 angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
168 return kTRUE;
169}
170
03b18860 171//______________________________________________________________________________
172void AliAlignObj::Transform(AliTrackPoint &p) const
173{
174 // The method transforms the space-point coordinates using the
175 // transformation matrix provided by the AliAlignObj
176 // The covariance matrix is not affected since we assume
177 // that the transformations are sufficiently small
178
179 if (fVolUID != p.GetVolumeID())
180 AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID()));
181
182 TGeoHMatrix m;
183 GetMatrix(m);
184 Double_t *rot = m.GetRotationMatrix();
185 Double_t *tr = m.GetTranslation();
186
187 Float_t xyzin[3],xyzout[3];
188 p.GetXYZ(xyzin);
189 for (Int_t i = 0; i < 3; i++)
190 xyzout[i] = tr[i]+
191 xyzin[0]*rot[3*i]+
192 xyzin[1]*rot[3*i+1]+
193 xyzin[2]*rot[3*i+2];
194 p.SetXYZ(xyzout);
195
196}
197
198//______________________________________________________________________________
199void AliAlignObj::Transform(AliTrackPointArray &array) const
200{
201 AliTrackPoint p;
202 for (Int_t i = 0; i < array.GetNPoints(); i++) {
203 array.GetPoint(p,i);
204 Transform(p);
205 array.AddPoint(i,&p);
206 }
207}
208
c18195b9 209//_____________________________________________________________________________
210void AliAlignObj::Print(Option_t *) const
211{
212 // Print the contents of the
213 // alignment object in angles and
214 // matrix representations
215 Double_t tr[3];
216 GetTranslation(tr);
217 Double_t angles[3];
218 GetAngles(angles);
219 TGeoHMatrix m;
220 GetMatrix(m);
221 const Double_t *rot = m.GetRotationMatrix();
befe2c08 222// printf("Volume=%s ID=%u\n", GetVolPath(),GetVolUID());
b1f9140d 223 ELayerID layerId;
224 Int_t modId;
225 GetVolUID(layerId,modId);
226 printf("Volume=%s LayerID=%d ModuleID=%d\n", GetVolPath(),layerId,modId);
c18195b9 227 printf("%12.6f%12.6f%12.6f Tx = %12.6f Psi = %12.6f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
228 printf("%12.6f%12.6f%12.6f Ty = %12.6f Theta = %12.6f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
229 printf("%12.6f%12.6f%12.6f Tz = %12.6f Phi = %12.6f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
230
231}
232
c18195b9 233//_____________________________________________________________________________
befe2c08 234UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
c18195b9 235{
befe2c08 236 // From detector (layer) name and module number (according to detector numbering)
237 // build fVolUID, unique numerical identity of that volume inside ALICE
238 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
239 // remaining 11 for module ID inside det (2048 possible values).
c18195b9 240 //
befe2c08 241 return ((UShort_t(layerId) << 11) | UShort_t(modId));
c18195b9 242}
243
244//_____________________________________________________________________________
befe2c08 245AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
c18195b9 246{
befe2c08 247 // From detector (layer) name and module number (according to detector numbering)
248 // build fVolUID, unique numerical identity of that volume inside ALICE
249 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
250 // remaining 11 for module ID inside det (2048 possible values).
251 //
252 modId = voluid & 0x7ff;
c18195b9 253
befe2c08 254 return VolUIDToLayer(voluid);
c18195b9 255}
256
257//_____________________________________________________________________________
befe2c08 258AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
c18195b9 259{
befe2c08 260 // From detector (layer) name and module number (according to detector numbering)
261 // build fVolUID, unique numerical identity of that volume inside ALICE
262 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
263 // remaining 11 for module ID inside det (2048 possible values).
264 //
265 return ELayerID((voluid >> 11) & 0x1f);
c18195b9 266}
03b18860 267
995ad051 268//_____________________________________________________________________________
269Bool_t AliAlignObj::ApplyToGeometry()
270{
271 // Apply the current alignment object
272 // to the TGeo geometry
273
274 if (!gGeoManager || !gGeoManager->IsClosed()) {
275 AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!");
276 return kFALSE;
277 }
278
279 const char* volpath = GetVolPath();
280 TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
281 if (!node) {
282 AliError(Form("Volume path %s not valid!",volpath));
283 return kFALSE;
284 }
285 if (node->IsAligned()) {
286 AliWarning(Form("Volume %s has been already misaligned!",volpath));
287 return kFALSE;
288 }
289
290 TGeoHMatrix align,gprime;
291 gprime = *node->GetMatrix();
292 GetMatrix(align);
293 gprime.MultiplyLeft(&align);
294 TGeoHMatrix *ginv = new TGeoHMatrix;
295 TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1);
296 *ginv = g->Inverse();
297 *ginv *= gprime;
298 AliAlignObj::ELayerID layerId; // unique identity for volume in the alobj
299 Int_t modId; // unique identity for volume in the alobj
300 GetVolUID(layerId, modId);
301 AliInfo(Form("Aligning volume %s of detector layer %d with local ID %d",volpath,layerId,modId));
302 node->Align(ginv);
303
304 return kTRUE;
305}
306
307//_____________________________________________________________________________
308Bool_t AliAlignObj::GetFromGeometry(const char *path, AliAlignObj &alobj)
309{
310 // Get the alignment object which correspond
311 // to the TGeo volume defined by the 'path'.
312 // The method is extremely slow due to the
313 // searching by string. Therefore it should
314 // be used with great care!!
315
316 // Reset the alignment object
317 alobj.SetPars(0,0,0,0,0,0);
318 alobj.SetVolPath(path);
319
320 if (!gGeoManager || !gGeoManager->IsClosed()) {
321 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
322 return kFALSE;
323 }
324
325 if (!gGeoManager->GetListOfPhysicalNodes()) {
326 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
327 return kFALSE;
328 }
329
330 TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
331 TGeoPhysicalNode* node = NULL;
332 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
333 node = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
334 const char *nodePath = node->GetName();
335 if (strcmp(path,nodePath) == 0) break;
336 }
337 if (!node) {
338 AliWarningClass(Form("Volume path %s not found!",path));
339 return kFALSE;
340 }
341
342 TGeoHMatrix align,gprime,g,ginv,l;
343 gprime = *node->GetMatrix();
344 l = *node->GetOriginalMatrix();
345 g = *node->GetMatrix(node->GetLevel()-1);
346 g *= l;
347 ginv = g.Inverse();
348 align = gprime * ginv;
349 alobj.SetMatrix(align);
350
351 return kTRUE;
352}
353
03b18860 354//_____________________________________________________________________________
355void AliAlignObj::InitVolPaths()
356{
357 // Initialize the LUTs which contain
358 // the TGeo volume paths for each
359 // alignable volume. The LUTs are
360 // static, so they are created during
361 // the creation of the first intance
362 // of AliAlignObj
363
364 if (fgVolPath[0]) return;
365
366 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
7604a026 367 fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]];
03b18860 368
369 /********************* SPD layer1 ***********************/
370 {
371 Int_t modnum = 0;
372 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
373 TString str1 = "/I10B_"; //"/I10A_";
374 TString str2 = "/I107_"; //"/I103_"
995ad051 375 // TString str3 = "/I101_1/ITS1_1";
03b18860 376 TString volpath, volpath1, volpath2;
377
378 for(Int_t c1 = 1; c1<=10; c1++){
379 volpath = str0;
380 volpath += c1;
381 volpath += str1;
382 for(Int_t c2 =1; c2<=2; c2++){
383 volpath1 = volpath;
384 volpath1 += c2;
385 volpath1 += str2;
386 for(Int_t c3 =1; c3<=4; c3++){
387 volpath2 = volpath1;
388 volpath2 += c3;
995ad051 389 // volpath2 += str3;
03b18860 390 fgVolPath[kSPD1-kFirstLayer][modnum] = volpath2.Data();
391 modnum++;
392 }
393 }
394 }
395 }
396
397 /********************* SPD layer2 ***********************/
398 {
399 Int_t modnum = 0;
400 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
401 TString str1 = "/I20B_"; //"/I20A"
402 TString str2 = "/I1D7_"; //"/I1D3"
995ad051 403 // TString str3 = "/I1D1_1/ITS2_1";
03b18860 404 TString volpath, volpath1, volpath2;
405
406 for(Int_t c1 = 1; c1<=10; c1++){
407 volpath = str0;
408 volpath += c1;
409 volpath += str1;
410 for(Int_t c2 =1; c2<=4; c2++){
411 volpath1 = volpath;
412 volpath1 += c2;
413 volpath1 += str2;
414 for(Int_t c3 =1; c3<=4; c3++){
415 volpath2 = volpath1;
416 volpath2 += c3;
995ad051 417 // volpath2 += str3;
03b18860 418 fgVolPath[kSPD2-kFirstLayer][modnum] = volpath2.Data();
419 modnum++;
420 }
421 }
422 }
423 }
424
425 /********************* SDD layer1 ***********************/
426 {
427 Int_t modnum=0;
428 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
429 TString str1 = "/I302_";
995ad051 430 // TString str2 = "/ITS3_1";
03b18860 431 TString volpath, volpath1;
432
433 for(Int_t c1 = 1; c1<=14; c1++){
434 volpath = str0;
435 volpath += c1;
436 volpath += str1;
437 for(Int_t c2 =1; c2<=6; c2++){
438 volpath1 = volpath;
439 volpath1 += c2;
995ad051 440 // volpath1 += str2;
03b18860 441 fgVolPath[kSDD1-kFirstLayer][modnum] = volpath1.Data();
442 modnum++;
443 }
444 }
445 }
446
447 /********************* SDD layer2 ***********************/
448 {
449 Int_t modnum=0;
450 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
451 TString str1 = "/I402_";
995ad051 452 // TString str2 = "/ITS4_1";
03b18860 453 TString volpath, volpath1;
454
455 for(Int_t c1 = 1; c1<=22; c1++){
456 volpath = str0;
457 volpath += c1;
458 volpath += str1;
459 for(Int_t c2 = 1; c2<=8; c2++){
460 volpath1 = volpath;
461 volpath1 += c2;
995ad051 462 // volpath1 += str2;
03b18860 463 fgVolPath[kSDD2-kFirstLayer][modnum] = volpath1.Data();
464 modnum++;
465 }
466 }
467 }
468
469 /********************* SSD layer1 ***********************/
470 {
471 Int_t modnum=0;
472 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
473 TString str1 = "/I562_";
995ad051 474 // TString str2 = "/ITS5_1";
03b18860 475 TString volpath, volpath1;
476
477 for(Int_t c1 = 1; c1<=34; c1++){
478 volpath = str0;
479 volpath += c1;
480 volpath += str1;
481 for(Int_t c2 = 1; c2<=22; c2++){
482 volpath1 = volpath;
483 volpath1 += c2;
995ad051 484 // volpath1 += str2;
03b18860 485 fgVolPath[kSSD1-kFirstLayer][modnum] = volpath1.Data();
486 modnum++;
487 }
488 }
489 }
490
491 /********************* SSD layer1 ***********************/
492 {
493 Int_t modnum=0;
494 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
495 TString str1 = "/I566_";
995ad051 496 // TString str2 = "/ITS6_1";
03b18860 497 TString volpath, volpath1;
498
499 for(Int_t c1 = 1; c1<=38; c1++){
500 volpath = str0;
501 volpath += c1;
502 volpath += str1;
503 for(Int_t c2 = 1; c2<=25; c2++){
504 volpath1 = volpath;
505 volpath1 += c2;
995ad051 506 // volpath1 += str2;
03b18860 507 fgVolPath[kSSD2-kFirstLayer][modnum] = volpath1.Data();
508 modnum++;
509 }
510 }
511 }
512
9abb5d7b 513 /********************* TOF layer ***********************/
514 {
515 Int_t nstrA=15;
516 Int_t nstrB=19;
517 Int_t nstrC=20;
518 Int_t nStripSec=nstrA+2*nstrB+2*nstrC;
519
520 for (Int_t modnum=0; modnum < 1674; modnum++) {
521
522 Int_t sector = modnum/nStripSec;
523
524 Char_t string1[100];
525 Char_t string2[100];
526
527 Int_t icopy=-1;
528 if(sector<2){
529 icopy=sector+1;
530 sprintf(string1,"/ALIC_1/B077_1/B075_%i/BTO3_1",icopy);
531 }
532 else if(sector<11){
533 icopy=sector-2;
534 sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
535 }
536 else if(sector==11 || sector==12){
537 icopy=sector-10;
538 sprintf(string1,"/ALIC_1/B077_1/B074_%i/BTO2_1",icopy);
539 }
540 else {
541 icopy=sector-4;
542 sprintf(string1,"/ALIC_1/B077_1/B071_%i/BTO1_1",icopy);
543 }
544
545 Int_t strInSec=modnum%nStripSec;
546
547 if( strInSec < nstrC){
548 icopy= strInSec+1;
549 sprintf(string2,"FTOC_1/FLTC_1/FSTR_%i",icopy);
550 }
551 else if(strInSec< nstrC+nstrB){
03b18860 552
9abb5d7b 553 icopy= strInSec-nstrC+1;
554 sprintf(string2,"FTOB_1/FLTB_1/FSTR_%i",icopy);
555
556 }
557 else if(strInSec< nstrC+nstrB+nstrA){
558
559 icopy= strInSec-(nstrC+nstrB)+1;
560 sprintf(string2,"FTOA_1/FLTA_1/FSTR_%i",icopy);
561
562 }
563 else if(strInSec< nstrC+2*nstrB+nstrA){
564
565 icopy= strInSec-(nstrC+nstrB+nstrA)+1;
566 sprintf(string2,"FTOB_2/FLTB_2/FSTR_%i",icopy);
567
568 }
569 else {
570
571 icopy= strInSec-(nstrC+2*nstrB+nstrA)+1;
572 sprintf(string2,"FTOC_2/FLTC_2/FSTR_%i",icopy);
573
574 }
575
576 Char_t path[100];
577 sprintf(path,"%s/%s",string1,string2);
578 // printf("%d %s\n",modnum,path);
579 fgVolPath[kTOF-kFirstLayer][modnum] = path;
580 }
581 }
03b18860 582}