Updated path to the TRD alignable volumes (Dariusz)
[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"
c5304981 38#include "AliAlignObjAngles.h"
98937d93 39
c18195b9 40ClassImp(AliAlignObj)
41
98937d93 42Int_t AliAlignObj::fgLayerSize[kLastLayer - kFirstLayer] = {
43 80, 160, // ITS SPD
44 84, 176, // ITS SDD
45 748, 950, // ITS SSD
46 36, 36, // TPC
47 90, 90, 90, 90, 90, 90, // TRD
da027ef2 48 1638, // TOF
98937d93 49 1, 1, // PHOS ??
03b18860 50 7, // RICH ??
98937d93 51 1 // MUON ??
52};
53
54const char* AliAlignObj::fgLayerName[kLastLayer - kFirstLayer] = {
55 "ITS inner pixels layer", "ITS outer pixels layer",
56 "ITS inner drifts layer", "ITS outer drifts layer",
57 "ITS inner strips layer", "ITS outer strips layer",
58 "TPC inner chambers layer", "TPC outer chambers layer",
59 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
60 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
61 "TOF layer",
62 "?","?",
03b18860 63 "RICH layer",
98937d93 64 "?"
65};
66
7604a026 67TString* AliAlignObj::fgVolPath[kLastLayer - kFirstLayer] = {
03b18860 68 0x0,0x0,
69 0x0,0x0,
70 0x0,0x0,
71 0x0,0x0,
72 0x0,0x0,0x0,
73 0x0,0x0,0x0,
74 0x0,
75 0x0,0x0,
76 0x0,
77 0x0
78};
79
c5304981 80AliAlignObj** AliAlignObj::fgAlignObjs[kLastLayer - kFirstLayer] = {
81 0x0,0x0,
82 0x0,0x0,
83 0x0,0x0,
84 0x0,0x0,
85 0x0,0x0,0x0,
86 0x0,0x0,0x0,
87 0x0,
88 0x0,0x0,
89 0x0,
90 0x0
91};
92
c18195b9 93//_____________________________________________________________________________
94AliAlignObj::AliAlignObj():
95 fVolUID(0)
96{
03b18860 97 // default constructor
98 InitVolPaths();
c18195b9 99}
100
101//_____________________________________________________________________________
d9cc42ed 102AliAlignObj::AliAlignObj(const char* volpath, UShort_t voluid) : TObject()
103{
104 // standard constructor
105 //
106 fVolPath=volpath;
107 fVolUID=voluid;
108}
109
110AliAlignObj::AliAlignObj(const char* volpath, ELayerID detId, Int_t volId) : TObject()
111{
112 // standard constructor
113 //
114 fVolPath=volpath;
115 SetVolUID(detId,volId);
116}
117
118//_____________________________________________________________________________
c18195b9 119AliAlignObj::AliAlignObj(const AliAlignObj& theAlignObj) :
120 TObject(theAlignObj)
121{
122 //copy constructor
123 fVolPath = theAlignObj.GetVolPath();
124 fVolUID = theAlignObj.GetVolUID();
125}
126
127//_____________________________________________________________________________
128AliAlignObj &AliAlignObj::operator =(const AliAlignObj& theAlignObj)
129{
130 // assignment operator
131 if(this==&theAlignObj) return *this;
132 fVolPath = theAlignObj.GetVolPath();
133 fVolUID = theAlignObj.GetVolUID();
134 return *this;
135}
136
38b3a170 137//_____________________________________________________________________________
138AliAlignObj &AliAlignObj::operator*=(const AliAlignObj& theAlignObj)
139{
140 // multiplication operator
141 // The operator can be used to 'combine'
142 // two alignment objects
143 TGeoHMatrix m1;
144 GetMatrix(m1);
145 TGeoHMatrix m2;
146 theAlignObj.GetMatrix(m2);
147 m1.MultiplyLeft(&m2);
148 SetMatrix(m1);
149 return *this;
150}
151
c18195b9 152//_____________________________________________________________________________
153AliAlignObj::~AliAlignObj()
154{
155 // dummy destructor
156}
157
befe2c08 158//_____________________________________________________________________________
159void AliAlignObj::SetVolUID(ELayerID detId, Int_t modId)
160{
161 // From detector name and module number (according to detector numbering)
162 // build fVolUID, unique numerical identity of that volume inside ALICE
163 // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
164 // remaining 11 for module ID inside det (2048 possible values).
165 //
166 fVolUID = LayerToVolUID(detId,modId);
167}
168
169//_____________________________________________________________________________
170void AliAlignObj::GetVolUID(ELayerID &layerId, Int_t &modId) const
171{
172 // From detector name and module number (according to detector numbering)
173 // build fVolUID, unique numerical identity of that volume inside ALICE
174 // fVolUID is 16 bits, first 5 reserved for detID (32 possible values),
175 // remaining 11 for module ID inside det (2048 possible values).
176 //
177 layerId = VolUIDToLayer(fVolUID,modId);
178}
179
4b94e753 180//_____________________________________________________________________________
181Int_t AliAlignObj::GetLevel() const
182{
183 // Return the geometry level of
184 // the alignable volume to which
185 // the alignment object is associated
186 TString volpath = fVolPath;
187 return (volpath.CountChar('/')+1);
188}
189
190//_____________________________________________________________________________
191Int_t AliAlignObj::Compare(const TObject *obj) const
192{
193 // Compare the levels of two
194 // alignment objects
195 // Used in the sorting during
196 // the application of alignment
197 // objects to the geometry
198 Int_t level = GetLevel();
199 Int_t level2 = ((AliAlignObj *)obj)->GetLevel();
200 if (level == level2)
201 return 0;
202 else
203 return ((level > level2) ? 1 : -1);
204}
205
c18195b9 206//_____________________________________________________________________________
207void AliAlignObj::AnglesToMatrix(const Double_t *angles, Double_t *rot) const
208{
fdf65bb5 209 // Calculates the rotation matrix using the
210 // Euler angles in "x y z" notation
c18195b9 211 Double_t degrad = TMath::DegToRad();
212 Double_t sinpsi = TMath::Sin(degrad*angles[0]);
213 Double_t cospsi = TMath::Cos(degrad*angles[0]);
214 Double_t sinthe = TMath::Sin(degrad*angles[1]);
215 Double_t costhe = TMath::Cos(degrad*angles[1]);
216 Double_t sinphi = TMath::Sin(degrad*angles[2]);
217 Double_t cosphi = TMath::Cos(degrad*angles[2]);
218
219 rot[0] = costhe*cosphi;
220 rot[1] = -costhe*sinphi;
221 rot[2] = sinthe;
222 rot[3] = sinpsi*sinthe*cosphi + cospsi*sinphi;
223 rot[4] = -sinpsi*sinthe*sinphi + cospsi*cosphi;
224 rot[5] = -costhe*sinpsi;
225 rot[6] = -cospsi*sinthe*cosphi + sinpsi*sinphi;
226 rot[7] = cospsi*sinthe*sinphi + sinpsi*cosphi;
227 rot[8] = costhe*cospsi;
228}
229
230//_____________________________________________________________________________
231Bool_t AliAlignObj::MatrixToAngles(const Double_t *rot, Double_t *angles) const
232{
fdf65bb5 233 // Calculates the Euler angles in "x y z" notation
234 // using the rotation matrix
900d2087 235 if(TMath::Abs(rot[0])<1e-7 || TMath::Abs(rot[8])<1e-7) return kFALSE;
c18195b9 236 Double_t raddeg = TMath::RadToDeg();
237 angles[0]=raddeg*TMath::ATan2(-rot[5],rot[8]);
238 angles[1]=raddeg*TMath::ASin(rot[2]);
239 angles[2]=raddeg*TMath::ATan2(-rot[1],rot[0]);
240 return kTRUE;
241}
242
03b18860 243//______________________________________________________________________________
244void AliAlignObj::Transform(AliTrackPoint &p) const
245{
246 // The method transforms the space-point coordinates using the
247 // transformation matrix provided by the AliAlignObj
248 // The covariance matrix is not affected since we assume
249 // that the transformations are sufficiently small
250
251 if (fVolUID != p.GetVolumeID())
252 AliWarning(Form("Alignment object ID is not equal to the space-point ID (%d != %d)",fVolUID,p.GetVolumeID()));
253
254 TGeoHMatrix m;
255 GetMatrix(m);
256 Double_t *rot = m.GetRotationMatrix();
257 Double_t *tr = m.GetTranslation();
258
259 Float_t xyzin[3],xyzout[3];
260 p.GetXYZ(xyzin);
261 for (Int_t i = 0; i < 3; i++)
262 xyzout[i] = tr[i]+
263 xyzin[0]*rot[3*i]+
264 xyzin[1]*rot[3*i+1]+
265 xyzin[2]*rot[3*i+2];
266 p.SetXYZ(xyzout);
267
268}
269
79e21da6 270//_____________________________________________________________________________
03b18860 271void AliAlignObj::Transform(AliTrackPointArray &array) const
272{
e1e6896f 273 // This method is used to transform all the track points
274 // from the input AliTrackPointArray
03b18860 275 AliTrackPoint p;
276 for (Int_t i = 0; i < array.GetNPoints(); i++) {
277 array.GetPoint(p,i);
278 Transform(p);
279 array.AddPoint(i,&p);
280 }
281}
282
c18195b9 283//_____________________________________________________________________________
284void AliAlignObj::Print(Option_t *) const
285{
286 // Print the contents of the
287 // alignment object in angles and
288 // matrix representations
289 Double_t tr[3];
290 GetTranslation(tr);
291 Double_t angles[3];
292 GetAngles(angles);
293 TGeoHMatrix m;
294 GetMatrix(m);
295 const Double_t *rot = m.GetRotationMatrix();
c18195b9 296
c041444f 297 printf("Volume=%s\n",GetVolPath());
298 if (GetVolUID() != 0) {
299 ELayerID layerId;
300 Int_t modId;
301 GetVolUID(layerId,modId);
302 printf("VolumeID=%d LayerID=%d ( %s ) ModuleID=%d\n", GetVolUID(),layerId,LayerName(layerId),modId);
303 }
304 printf("%12.8f%12.8f%12.8f Tx = %12.8f Psi = %12.8f\n", rot[0], rot[1], rot[2], tr[0], angles[0]);
305 printf("%12.8f%12.8f%12.8f Ty = %12.8f Theta = %12.8f\n", rot[3], rot[4], rot[5], tr[1], angles[1]);
306 printf("%12.8f%12.8f%12.8f Tz = %12.8f Phi = %12.8f\n", rot[6], rot[7], rot[8], tr[2], angles[2]);
307
308}
309
310//_____________________________________________________________________________
311Int_t AliAlignObj::LayerSize(Int_t layerId)
312{
313 // Get the corresponding layer size.
314 // Implemented only for ITS,TPC,TRD,TOF and RICH
315 if (layerId < kFirstLayer || layerId >= kLastLayer) {
316 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
317 return 0;
318 }
319 else {
320 return fgLayerSize[layerId - kFirstLayer];
321 }
322}
323
324//_____________________________________________________________________________
325const char* AliAlignObj::LayerName(Int_t layerId)
326{
327 // Get the corresponding layer name.
328 // Implemented only for ITS,TPC,TRD,TOF and RICH
329 if (layerId < kFirstLayer || layerId >= kLastLayer) {
330 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
331 return "Invalid Layer!";
332 }
333 else {
334 return fgLayerName[layerId - kFirstLayer];
335 }
c18195b9 336}
337
c18195b9 338//_____________________________________________________________________________
befe2c08 339UShort_t AliAlignObj::LayerToVolUID(ELayerID layerId, Int_t modId)
c18195b9 340{
befe2c08 341 // From detector (layer) name and module number (according to detector numbering)
342 // build fVolUID, unique numerical identity of that volume inside ALICE
343 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
344 // remaining 11 for module ID inside det (2048 possible values).
c18195b9 345 //
befe2c08 346 return ((UShort_t(layerId) << 11) | UShort_t(modId));
c18195b9 347}
348
46ae650f 349//_____________________________________________________________________________
350UShort_t AliAlignObj::LayerToVolUID(Int_t layerId, Int_t modId)
351{
352 // From detector (layer) index and module number (according to detector numbering)
353 // build fVolUID, unique numerical identity of that volume inside ALICE
354 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
355 // remaining 11 for module ID inside det (2048 possible values).
356 //
357 return ((UShort_t(layerId) << 11) | UShort_t(modId));
358}
359
c18195b9 360//_____________________________________________________________________________
befe2c08 361AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid, Int_t &modId)
c18195b9 362{
befe2c08 363 // From detector (layer) name and module number (according to detector numbering)
364 // build fVolUID, unique numerical identity of that volume inside ALICE
365 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
366 // remaining 11 for module ID inside det (2048 possible values).
367 //
368 modId = voluid & 0x7ff;
c18195b9 369
befe2c08 370 return VolUIDToLayer(voluid);
c18195b9 371}
372
373//_____________________________________________________________________________
befe2c08 374AliAlignObj::ELayerID AliAlignObj::VolUIDToLayer(UShort_t voluid)
c18195b9 375{
befe2c08 376 // From detector (layer) name and module number (according to detector numbering)
377 // build fVolUID, unique numerical identity of that volume inside ALICE
378 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
379 // remaining 11 for module ID inside det (2048 possible values).
380 //
381 return ELayerID((voluid >> 11) & 0x1f);
c18195b9 382}
03b18860 383
1bfe7ffc 384//_____________________________________________________________________________
385Bool_t AliAlignObj::SetLocalPars(Double_t x, Double_t y, Double_t z,
386 Double_t psi, Double_t theta, Double_t phi)
387{
388 // Set the translations and angles by using parameters
389 // defined in the local (in TGeo means) coordinate system
390 // of the alignable volume. In case that the TGeo was
391 // initialized, returns false and the object parameters are
392 // not set.
393 if (!gGeoManager || !gGeoManager->IsClosed()) {
394 AliError("Can't set the alignment object parameters! gGeoManager doesn't exist or it is still opened!");
395 return kFALSE;
396 }
397
398 const char* volpath = GetVolPath();
399 TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
400 if (!node) {
401 AliError(Form("Volume path %s not valid!",volpath));
402 return kFALSE;
403 }
404 if (node->IsAligned())
405 AliWarning(Form("Volume %s has been already misaligned!",volpath));
406
407 TGeoHMatrix m;
408 Double_t tr[3];
409 tr[0]=x; tr[1]=y; tr[2]=z;
410 m.SetTranslation(tr);
411 Double_t angles[3] = {psi, theta, phi};
412 Double_t rot[9];
413 AnglesToMatrix(angles,rot);
414 m.SetRotation(rot);
415
416 TGeoHMatrix align,gprime,gprimeinv;
417 gprime = *node->GetMatrix();
418 gprimeinv = gprime.Inverse();
419 m.Multiply(&gprimeinv);
420 m.MultiplyLeft(&gprime);
421
422 SetMatrix(m);
423
424 return kTRUE;
425}
426
995ad051 427//_____________________________________________________________________________
428Bool_t AliAlignObj::ApplyToGeometry()
429{
430 // Apply the current alignment object
431 // to the TGeo geometry
432
433 if (!gGeoManager || !gGeoManager->IsClosed()) {
434 AliError("Can't apply the alignment object! gGeoManager doesn't exist or it is still opened!");
435 return kFALSE;
436 }
437
438 const char* volpath = GetVolPath();
48cac49d 439
440 if (gGeoManager->GetListOfPhysicalNodes()->FindObject(volpath)) {
441 AliError(Form("Volume %s has been already misaligned!",volpath));
442 return kFALSE;
443 }
444
445 if (!gGeoManager->cd(volpath)) {
995ad051 446 AliError(Form("Volume path %s not valid!",volpath));
447 return kFALSE;
448 }
48cac49d 449
450 TGeoPhysicalNode* node = (TGeoPhysicalNode*) gGeoManager->MakePhysicalNode(volpath);
451 if (!node) {
452 AliError(Form("Volume path %s not valid!",volpath));
995ad051 453 return kFALSE;
454 }
455
456 TGeoHMatrix align,gprime;
457 gprime = *node->GetMatrix();
458 GetMatrix(align);
459 gprime.MultiplyLeft(&align);
460 TGeoHMatrix *ginv = new TGeoHMatrix;
461 TGeoHMatrix *g = node->GetMatrix(node->GetLevel()-1);
462 *ginv = g->Inverse();
463 *ginv *= gprime;
464 AliAlignObj::ELayerID layerId; // unique identity for volume in the alobj
465 Int_t modId; // unique identity for volume in the alobj
466 GetVolUID(layerId, modId);
79e21da6 467 AliDebug(2,Form("Aligning volume %s of detector layer %d with local ID %d",volpath,layerId,modId));
995ad051 468 node->Align(ginv);
469
470 return kTRUE;
471}
472
473//_____________________________________________________________________________
474Bool_t AliAlignObj::GetFromGeometry(const char *path, AliAlignObj &alobj)
475{
476 // Get the alignment object which correspond
477 // to the TGeo volume defined by the 'path'.
478 // The method is extremely slow due to the
479 // searching by string. Therefore it should
480 // be used with great care!!
481
482 // Reset the alignment object
483 alobj.SetPars(0,0,0,0,0,0);
484 alobj.SetVolPath(path);
485
486 if (!gGeoManager || !gGeoManager->IsClosed()) {
487 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
488 return kFALSE;
489 }
490
491 if (!gGeoManager->GetListOfPhysicalNodes()) {
492 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
493 return kFALSE;
494 }
495
496 TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
497 TGeoPhysicalNode* node = NULL;
498 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
499 node = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
500 const char *nodePath = node->GetName();
501 if (strcmp(path,nodePath) == 0) break;
502 }
503 if (!node) {
e1c4b551 504 if (!gGeoManager->cd(path)) {
505 AliErrorClass(Form("Volume path %s not found!",path));
506 return kFALSE;
507 }
508 else {
509 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
510 return kTRUE;
511 }
995ad051 512 }
513
514 TGeoHMatrix align,gprime,g,ginv,l;
515 gprime = *node->GetMatrix();
516 l = *node->GetOriginalMatrix();
517 g = *node->GetMatrix(node->GetLevel()-1);
518 g *= l;
519 ginv = g.Inverse();
520 align = gprime * ginv;
521 alobj.SetMatrix(align);
522
523 return kTRUE;
524}
525
79e21da6 526//_____________________________________________________________________________
c5304981 527void AliAlignObj::InitAlignObjFromGeometry()
528{
529 // Loop over all alignable volumes and extract
530 // the corresponding alignment objects from
531 // the TGeo geometry
25b4e81e 532
533 if(fgAlignObjs[0]) return;
c5304981 534
535 InitVolPaths();
536
c041444f 537 for (Int_t iLayer = kFirstLayer; iLayer < AliAlignObj::kLastLayer; iLayer++) {
538 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[AliAlignObj::LayerSize(iLayer)];
c5304981 539 for (Int_t iModule = 0; iModule < AliAlignObj::LayerSize(iLayer); iModule++) {
c041444f 540 UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,iModule);
541 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0);
c5304981 542 const char *path = GetVolPath(volid);
c041444f 543 if (!GetFromGeometry(path, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
c5304981 544 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,path));
545 }
546 }
547
548}
549
e1e6896f 550//_____________________________________________________________________________
551AliAlignObj* AliAlignObj::GetAlignObj(UShort_t voluid) {
552 // Returns the alignment object for given volume ID
553 Int_t modId;
554 ELayerID layerId = VolUIDToLayer(voluid,modId);
555 return GetAlignObj(layerId,modId);
556}
557
c5304981 558//_____________________________________________________________________________
559AliAlignObj* AliAlignObj::GetAlignObj(ELayerID layerId, Int_t modId)
560{
e1e6896f 561 // Returns pointer to alignment object givent its layer and module ID
c5304981 562 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
563 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
564 return NULL;
565 }
566 return fgAlignObjs[layerId-kFirstLayer][modId];
567}
568
e1e6896f 569//_____________________________________________________________________________
570const char* AliAlignObj::GetVolPath(UShort_t voluid) {
571 // Returns the volume path for given volume ID
572 Int_t modId;
573 ELayerID layerId = VolUIDToLayer(voluid,modId);
574 return GetVolPath(layerId,modId);
575}
576
e7570944 577//_____________________________________________________________________________
578const char* AliAlignObj::GetVolPath(ELayerID layerId, Int_t modId)
579{
e1e6896f 580 // Returns volume path to alignment object givent its layer and module ID
e7570944 581 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
582 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
583 return NULL;
584 }
585 return fgVolPath[layerId-kFirstLayer][modId].Data();
586}
587
03b18860 588//_____________________________________________________________________________
589void AliAlignObj::InitVolPaths()
590{
591 // Initialize the LUTs which contain
592 // the TGeo volume paths for each
593 // alignable volume. The LUTs are
594 // static, so they are created during
595 // the creation of the first intance
596 // of AliAlignObj
597
598 if (fgVolPath[0]) return;
599
600 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++)
7604a026 601 fgVolPath[iLayer] = new TString[fgLayerSize[iLayer]];
03b18860 602
603 /********************* SPD layer1 ***********************/
604 {
605 Int_t modnum = 0;
606 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
607 TString str1 = "/I10B_"; //"/I10A_";
608 TString str2 = "/I107_"; //"/I103_"
995ad051 609 // TString str3 = "/I101_1/ITS1_1";
03b18860 610 TString volpath, volpath1, volpath2;
611
612 for(Int_t c1 = 1; c1<=10; c1++){
613 volpath = str0;
614 volpath += c1;
615 volpath += str1;
616 for(Int_t c2 =1; c2<=2; c2++){
617 volpath1 = volpath;
618 volpath1 += c2;
619 volpath1 += str2;
620 for(Int_t c3 =1; c3<=4; c3++){
621 volpath2 = volpath1;
622 volpath2 += c3;
995ad051 623 // volpath2 += str3;
03b18860 624 fgVolPath[kSPD1-kFirstLayer][modnum] = volpath2.Data();
625 modnum++;
626 }
627 }
628 }
629 }
630
631 /********************* SPD layer2 ***********************/
632 {
633 Int_t modnum = 0;
634 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT12_1/I12B_"; //".../I12A_"
635 TString str1 = "/I20B_"; //"/I20A"
636 TString str2 = "/I1D7_"; //"/I1D3"
995ad051 637 // TString str3 = "/I1D1_1/ITS2_1";
03b18860 638 TString volpath, volpath1, volpath2;
639
640 for(Int_t c1 = 1; c1<=10; c1++){
641 volpath = str0;
642 volpath += c1;
643 volpath += str1;
644 for(Int_t c2 =1; c2<=4; c2++){
645 volpath1 = volpath;
646 volpath1 += c2;
647 volpath1 += str2;
648 for(Int_t c3 =1; c3<=4; c3++){
649 volpath2 = volpath1;
650 volpath2 += c3;
995ad051 651 // volpath2 += str3;
03b18860 652 fgVolPath[kSPD2-kFirstLayer][modnum] = volpath2.Data();
653 modnum++;
654 }
655 }
656 }
657 }
658
659 /********************* SDD layer1 ***********************/
660 {
661 Int_t modnum=0;
662 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I004_";
663 TString str1 = "/I302_";
995ad051 664 // TString str2 = "/ITS3_1";
03b18860 665 TString volpath, volpath1;
666
667 for(Int_t c1 = 1; c1<=14; c1++){
668 volpath = str0;
669 volpath += c1;
670 volpath += str1;
671 for(Int_t c2 =1; c2<=6; c2++){
672 volpath1 = volpath;
673 volpath1 += c2;
995ad051 674 // volpath1 += str2;
03b18860 675 fgVolPath[kSDD1-kFirstLayer][modnum] = volpath1.Data();
676 modnum++;
677 }
678 }
679 }
680
681 /********************* SDD layer2 ***********************/
682 {
683 Int_t modnum=0;
684 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT34_1/I005_";
685 TString str1 = "/I402_";
995ad051 686 // TString str2 = "/ITS4_1";
03b18860 687 TString volpath, volpath1;
688
689 for(Int_t c1 = 1; c1<=22; c1++){
690 volpath = str0;
691 volpath += c1;
692 volpath += str1;
693 for(Int_t c2 = 1; c2<=8; c2++){
694 volpath1 = volpath;
695 volpath1 += c2;
995ad051 696 // volpath1 += str2;
03b18860 697 fgVolPath[kSDD2-kFirstLayer][modnum] = volpath1.Data();
698 modnum++;
699 }
700 }
701 }
702
703 /********************* SSD layer1 ***********************/
704 {
705 Int_t modnum=0;
706 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I565_";
707 TString str1 = "/I562_";
995ad051 708 // TString str2 = "/ITS5_1";
03b18860 709 TString volpath, volpath1;
710
711 for(Int_t c1 = 1; c1<=34; c1++){
712 volpath = str0;
713 volpath += c1;
714 volpath += str1;
715 for(Int_t c2 = 1; c2<=22; c2++){
716 volpath1 = volpath;
717 volpath1 += c2;
995ad051 718 // volpath1 += str2;
03b18860 719 fgVolPath[kSSD1-kFirstLayer][modnum] = volpath1.Data();
720 modnum++;
721 }
722 }
723 }
724
725 /********************* SSD layer1 ***********************/
726 {
727 Int_t modnum=0;
728 TString str0 = "ALIC_1/ITSV_1/ITSD_1/IT56_1/I569_";
729 TString str1 = "/I566_";
995ad051 730 // TString str2 = "/ITS6_1";
03b18860 731 TString volpath, volpath1;
732
733 for(Int_t c1 = 1; c1<=38; c1++){
734 volpath = str0;
735 volpath += c1;
736 volpath += str1;
737 for(Int_t c2 = 1; c2<=25; c2++){
738 volpath1 = volpath;
739 volpath1 += c2;
995ad051 740 // volpath1 += str2;
03b18860 741 fgVolPath[kSSD2-kFirstLayer][modnum] = volpath1.Data();
742 modnum++;
743 }
744 }
745 }
746
e7570944 747 /*************** TPC inner chambers' layer ****************/
748 {
749 Int_t modnum = 0;
750 TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
751 TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
e1e6896f 752 TString strIn = "/TPC_IROC_1";
e7570944 753 TString volpath;
754
755 for(Int_t cnt=1; cnt<=18; cnt++){
756 volpath = str1;
757 volpath += cnt;
e1e6896f 758 volpath += strIn;
e7570944 759 fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
760 modnum++;
761 }
762 for(Int_t cnt=1; cnt<=18; cnt++){
763 volpath = str2;
764 volpath += cnt;
e1e6896f 765 volpath += strIn;
e7570944 766 fgVolPath[kTPC1-kFirstLayer][modnum] = volpath.Data();
767 modnum++;
768 }
769 }
770
771 /*************** TPC outer chambers' layer ****************/
772 {
773 Int_t modnum = 0;
774 TString str1 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_1/TPC_SECT_";
775 TString str2 = "ALIC_1/TPC_M_1/TPC_Drift_1/TPC_ENDCAP_2/TPC_SECT_";
e1e6896f 776 TString strOut = "/TPC_OROC_1";
e7570944 777 TString volpath;
778
779 for(Int_t cnt=1; cnt<=18; cnt++){
780 volpath = str1;
781 volpath += cnt;
e1e6896f 782 volpath += strOut;
e7570944 783 fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
784 modnum++;
785 }
786 for(Int_t cnt=1; cnt<=18; cnt++){
787 volpath = str2;
788 volpath += cnt;
e1e6896f 789 volpath += strOut;
e7570944 790 fgVolPath[kTPC2-kFirstLayer][modnum] = volpath.Data();
791 modnum++;
792 }
793 }
794
9abb5d7b 795 /********************* TOF layer ***********************/
796 {
797 Int_t nstrA=15;
798 Int_t nstrB=19;
da027ef2 799 Int_t nstrC=19;
800 Int_t nsec=18;
9abb5d7b 801 Int_t nStripSec=nstrA+2*nstrB+2*nstrC;
da027ef2 802 Int_t nStrip=nStripSec*nsec;
9abb5d7b 803
da027ef2 804 for (Int_t modnum=0; modnum < nStrip; modnum++) {
9abb5d7b 805
806 Int_t sector = modnum/nStripSec;
9abb5d7b 807 Char_t string1[100];
808 Char_t string2[100];
9abb5d7b 809 Int_t icopy=-1;
06e24a91 810 if(sector<13){
811 icopy=sector+5;}
812 else{ icopy=sector-13;}
38b3a170 813
06e24a91 814 sprintf(string1,"/ALIC_1/B077_1/BSEGMO%i_1/BTOF%i_1/FTOA_0/FLTA_0",sector,sector);
da027ef2 815
9abb5d7b 816 Int_t strInSec=modnum%nStripSec;
da027ef2 817 icopy= strInSec;
818 icopy++;
819 sprintf(string2,"FSTR_%i",icopy);
9abb5d7b 820 Char_t path[100];
821 sprintf(path,"%s/%s",string1,string2);
822 // printf("%d %s\n",modnum,path);
823 fgVolPath[kTOF-kFirstLayer][modnum] = path;
824 }
825 }
c8874495 826
827 /********************* RICH layer ***********************/
828 {
829 TString str = "ALIC_1/RICH_";
830 TString volpath;
831
832 for (Int_t modnum=0; modnum < 7; modnum++) {
833 volpath = str;
834 volpath += (modnum+1);
835 fgVolPath[kRICH-kFirstLayer][modnum] = volpath.Data();
836 }
837 }
274fcc1a 838
839 /********************* TRD layers 0-6 *******************/
840 {
9ce7d00f 841 TString strSM[18]={"ALIC_1/B077_1/BSEGMO5_1/BTRD5_1/UTR1_1/UTS1_1/UTI1_1/UT",
842 "ALIC_1/B077_1/BSEGMO6_1/BTRD6_1/UTR1_1/UTS1_1/UTI1_1/UT",
843 "ALIC_1/B077_1/BSEGMO7_1/BTRD7_1/UTR1_1/UTS1_1/UTI1_1/UT",
844 "ALIC_1/B077_1/BSEGMO8_1/BTRD8_1/UTR1_1/UTS1_1/UTI1_1/UT",
845 "ALIC_1/B077_1/BSEGMO9_1/BTRD9_1/UTR1_1/UTS1_1/UTI1_1/UT",
846 "ALIC_1/B077_1/BSEGMO10_1/BTRD10_1/UTR1_1/UTS1_1/UTI1_1/UT",
847 "ALIC_1/B077_1/BSEGMO11_1/BTRD11_1/UTR1_1/UTS1_1/UTI1_1/UT",
848 "ALIC_1/B077_1/BSEGMO12_1/BTRD12_1/UTR1_1/UTS1_1/UTI1_1/UT",
849 "ALIC_1/B077_1/BSEGMO13_1/BTRD13_1/UTR1_1/UTS1_1/UTI1_1/UT",
850 "ALIC_1/B077_1/BSEGMO14_1/BTRD14_1/UTR1_1/UTS1_1/UTI1_1/UT",
851 "ALIC_1/B077_1/BSEGMO15_1/BTRD15_1/UTR1_1/UTS1_1/UTI1_1/UT",
852 "ALIC_1/B077_1/BSEGMO16_1/BTRD16_1/UTR1_1/UTS1_1/UTI1_1/UT",
853 "ALIC_1/B077_1/BSEGMO17_1/BTRD17_1/UTR1_1/UTS1_1/UTI1_1/UT",
854 "ALIC_1/B077_1/BSEGMO0_1/BTRD0_1/UTR1_1/UTS1_1/UTI1_1/UT",
855 "ALIC_1/B077_1/BSEGMO1_1/BTRD1_1/UTR1_1/UTS1_1/UTI1_1/UT",
856 "ALIC_1/B077_1/BSEGMO2_1/BTRD2_1/UTR1_1/UTS1_1/UTI1_1/UT",
857 "ALIC_1/B077_1/BSEGMO3_1/BTRD3_1/UTR1_1/UTS1_1/UTI1_1/UT",
858 "ALIC_1/B077_1/BSEGMO4_1/BTRD4_1/UTR1_1/UTS1_1/UTI1_1/UT"};
274fcc1a 859 TString strPost = "_1";
a1a23a88 860 TString zeroStr = "0";
274fcc1a 861 TString volpath;
a1a23a88 862
e1e6896f 863 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
274fcc1a 864
a1a23a88 865 for(Int_t layer=0; layer<6; layer++){
866 Int_t modnum=0;
867 for(Int_t sm = 0; sm < 18; sm++){
868 for(Int_t stacknum = 0; stacknum < 5; stacknum++){
869 Int_t chnum = layer + stacknum*6;
274fcc1a 870 volpath = strSM[sm];
a1a23a88 871 if(chnum<10) volpath += zeroStr;
274fcc1a 872 volpath += chnum;
873 volpath += strPost;
e1e6896f 874 fgVolPath[arTRDlayId[layer]-kFirstLayer][modnum] = volpath.Data();
274fcc1a 875 modnum++;
876 }
877 }
878 }
879 }
880
03b18860 881}