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