]> git.uio.no Git - u/mrichter/AliRoot.git/blob - STEER/AliGeomManager.cxx
AliAlignObjAngles becomes AliAlignObjParams (Raffaele)
[u/mrichter/AliRoot.git] / STEER / AliGeomManager.cxx
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 //   Implementation of AliGeomManager, the geometry manager class 
17 //   which interfaces to TGeo and the look-up table mapping unique
18 //   volume indices to symbolic volume names. For that it collects
19 //   several static methods.
20 //-------------------------------------------------------------------------
21
22 #include <TClass.h>
23 #include <TFile.h>
24 #include <TGeoManager.h>
25 #include <TObjString.h>
26 #include <TGeoPhysicalNode.h>
27 #include <TClonesArray.h>
28 #include <TGeoMatrix.h>
29 #include <TGeoPhysicalNode.h>
30 #include <TSystem.h>
31
32 #include "AliGeomManager.h"
33 #include "AliLog.h"
34 #include "AliAlignObj.h"
35 #include "AliAlignObjParams.h"
36 #include "AliCDBManager.h"
37 #include "AliCDBStorage.h"
38 #include "AliCDBEntry.h"
39
40 ClassImp(AliGeomManager)
41   
42 Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
43   80, 160,  // ITS SPD first and second layer
44   84, 176,  // ITS SDD first and second layer
45   748, 950, // ITS SSD first and second layer
46   36, 36,   // TPC inner and outer chambers
47   90, 90, 90, 90, 90, 90,  // 6 TRD chambers' layers
48   1638,     // TOF
49   5, 5,     // PHOS,CPV
50   7,        // HMPID ??
51   1         // MUON ??
52 };
53
54 const char* AliGeomManager::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   "PHOS EMC layer","PHOS CPV layer",
63   "HMPID layer",
64   "?"
65 };
66
67 TString* AliGeomManager::fgSymName[kLastLayer - kFirstLayer] = {
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
80 TGeoPNEntry** AliGeomManager::fgPNEntry[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
93 TGeoHMatrix** AliGeomManager::fgOrigMatrix[kLastLayer - kFirstLayer] = {
94   0x0,0x0,
95   0x0,0x0,
96   0x0,0x0,
97   0x0,0x0,
98   0x0,0x0,0x0,
99   0x0,0x0,0x0,
100   0x0,
101   0x0,0x0,
102   0x0,
103   0x0
104 };
105
106 AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
107   0x0,0x0,
108   0x0,0x0,
109   0x0,0x0,
110   0x0,0x0,
111   0x0,0x0,0x0,
112   0x0,0x0,0x0,
113   0x0,
114   0x0,0x0,
115   0x0,
116   0x0
117 };
118
119 TGeoManager* AliGeomManager::fgGeometry = 0x0;
120
121 //_____________________________________________________________________________
122 void AliGeomManager::LoadGeometry(const char *geomFileName)
123 {
124   // initialization
125   // Load geometry either from a file
126   // or from the corresponding CDB entry
127
128   fgGeometry = NULL;
129   if (geomFileName && (!gSystem->AccessPathName(geomFileName))) { // gemotry.root exists
130     fgGeometry = TGeoManager::Import(geomFileName);
131     AliInfoClass("Using custom geometry.root file");
132   }
133
134   if (!fgGeometry) {
135     AliInfoClass("Using geometry from CDB");
136
137     AliCDBPath path("GRP","Geometry","Data");
138         
139     AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
140     if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
141
142     entry->SetOwner(0);
143     fgGeometry = (TGeoManager*) entry->GetObject();
144     if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
145   }
146
147   InitSymNamesLUT();
148   InitPNEntriesLUT();
149   InitOrigMatricesLUT();
150 }
151
152 //_____________________________________________________________________________
153 void AliGeomManager::SetGeometry(TGeoManager *geom)
154 {
155   // Load already active geometry
156   if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
157
158   fgGeometry = geom;
159
160   InitSymNamesLUT();
161   InitPNEntriesLUT();
162   InitOrigMatricesLUT();
163 }
164
165 //_____________________________________________________________________________
166 AliGeomManager::AliGeomManager():
167   TObject()
168 {
169   // default constructor
170 }
171
172 //_____________________________________________________________________________
173 AliGeomManager::~AliGeomManager()
174 {
175   // dummy destructor
176 }
177
178 //_____________________________________________________________________________
179 Int_t AliGeomManager::LayerSize(Int_t layerId)
180 {
181   // Get the layer size for layer corresponding to layerId.
182   // Implemented only for ITS,TPC,TRD,TOF and HMPID
183   //
184   if (layerId < kFirstLayer || layerId >= kLastLayer) {
185     AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
186     return 0;
187   }
188   else {
189     return fgLayerSize[layerId - kFirstLayer];
190  }
191 }
192
193 //_____________________________________________________________________________
194 const char* AliGeomManager::LayerName(Int_t layerId)
195 {
196   // Get the layer name corresponding to layerId.
197   // Implemented only for ITS,TPC,TRD,TOF and HMPID
198   //
199   if (layerId < kFirstLayer || layerId >= kLastLayer) {
200     AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
201     return "Invalid Layer!";
202   }
203   else {
204     return fgLayerName[layerId - kFirstLayer];
205  }
206 }
207
208 //_____________________________________________________________________________
209 UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
210 {
211   // From detector (layer) name and module number (according to detector
212   // internal numbering) build the unique numerical identity of that volume
213   // inside ALICE
214   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
215   // remaining 11 for module ID inside det (2048 possible values).
216   // NO check for validity of given modId inside the layer for speed's sake.
217   //
218   return ((UShort_t(layerId) << 11) | UShort_t(modId));
219 }
220
221 //_____________________________________________________________________________
222 UShort_t AliGeomManager::LayerToVolUID(Int_t   layerId, Int_t modId)
223 {
224   // From detector (layer) name and module number (according to detector
225   // internal numbering) build the unique numerical identity of that volume
226   // inside ALICE
227   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
228   // remaining 11 for module ID inside det (2048 possible values).
229   // NO check for validity of given modId inside the layer for speed's sake.
230   //
231   return ((UShort_t(layerId) << 11) | UShort_t(modId));
232 }
233
234 //_____________________________________________________________________________
235 UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
236 {
237   // From detector (layer) name and module number (according to detector
238   // internal numbering) build the unique numerical identity of that volume
239   // inside ALICE
240   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
241   // remaining 11 for module ID inside det (2048 possible values).
242   // Check validity of given modId inside the layer.
243   //
244   if(modId < 0 || modId >= LayerSize(layerId)){
245     AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
246     return 0;
247   }
248   return ((UShort_t(layerId) << 11) | UShort_t(modId));
249 }
250
251 //_____________________________________________________________________________
252 UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
253 {
254   // From detector (layer) name and module number (according to detector
255   // internal numbering) build the unique numerical identity of that volume
256   // inside ALICE
257   // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
258   // remaining 11 for module ID inside det (2048 possible values).
259   // Check validity of given modId inside the layer.
260   //
261   if(modId < 0 || modId >= LayerSize(layerId)){
262     AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
263     return 0;
264   }
265   return ((UShort_t(layerId) << 11) | UShort_t(modId));
266 }
267
268 //_____________________________________________________________________________
269 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
270 {
271   // From voluid, unique numerical identity of that volume inside ALICE,
272   // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
273   // remaining 11 for module ID inside det (2048 possible values)), return
274   // the identity of the layer to which that volume belongs and sets the
275   // argument modId to the identity of that volume internally to the layer.
276   // NO check for validity of given voluid for speed's sake.
277   //
278   modId = voluid & 0x7ff;
279
280   return VolUIDToLayer(voluid);
281 }
282
283 //_____________________________________________________________________________
284 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
285 {
286   // From voluid, unique numerical identity of that volume inside ALICE,
287   // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
288   // remaining 11 for module ID inside det (2048 possible values)), return
289   // the identity of the layer to which that volume belongs
290   // NO check for validity of given voluid for speed's sake.
291   //
292   return ELayerID(voluid >> 11);
293 }
294
295 //_____________________________________________________________________________
296 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
297 {
298   // From voluid, unique numerical identity of that volume inside ALICE,
299   // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
300   // remaining 11 for module ID inside det (2048 possible values)), returns
301   // the identity of the layer to which that volume belongs and sets the
302   // argument modId to the identity of that volume internally to the layer.
303   // Checks the validity of the given voluid
304   //
305   ELayerID layId = VolUIDToLayerSafe(voluid);
306   if(layId){
307     Int_t mId = Int_t(voluid & 0x7ff);
308     if( mId>=0 && mId<LayerSize(layId)){
309       modId = mId;
310       return layId;
311     }
312   }
313
314   AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
315   modId = -1;
316   return kInvalidLayer;
317
318 }
319
320 //_____________________________________________________________________________
321 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
322 {
323   // From voluid, unique numerical identity of that volume inside ALICE,
324   // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
325   // remaining 11 for module ID inside det (2048 possible values)), returns
326   // the identity of the layer to which that volume belongs
327   // Checks the validity of the given voluid
328   //
329   if( (voluid >> 11) < kLastLayer)  return ELayerID(voluid >> 11);
330
331   AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
332   return kInvalidLayer;
333
334 }
335
336 //_____________________________________________________________________________
337 Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
338 {
339   // Get the alignment object which corresponds to the symbolic volume name
340   // symname (in case equal to the TGeo volume path)
341   // The method is extremely slow due to the searching by string,
342   // therefore it should be used with great care!!
343   // This method returns FALSE if the symname of the object was not
344   // valid neither to get a TGeoPEntry nor as a volume path, or if the path
345   // associated to the TGeoPNEntry was not valid.
346   //
347
348   // Reset the alignment object
349   alobj.SetPars(0,0,0,0,0,0);
350   alobj.SetSymName(symname);
351
352   if (!fgGeometry || !fgGeometry->IsClosed()) {
353     AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
354     return kFALSE;
355   }
356
357   if (!fgGeometry->GetListOfPhysicalNodes()) {
358     AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
359     return kFALSE;
360   }
361
362   const char *path;
363   TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
364   if(pne){
365     path = pne->GetTitle();
366   }else{
367     AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
368     path = symname;
369   }
370   TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
371   TGeoPhysicalNode* node = NULL;
372   for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
373     TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
374     const char *nodePath = tempNode->GetName();
375     if (strcmp(path,nodePath) == 0) {
376       node = tempNode;
377       break;
378     }
379   }
380
381   if (!node) {
382     if (!fgGeometry->cd(path)) {
383       AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
384       return kFALSE;
385     }
386     else {
387       AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
388       return kTRUE;
389     }
390   }
391
392   TGeoHMatrix align,gprime,g,ginv,l;
393   gprime = *node->GetMatrix();
394   l = *node->GetOriginalMatrix();
395   g = *node->GetMatrix(node->GetLevel()-1);
396   g *= l;
397   ginv = g.Inverse();
398   align = gprime * ginv;
399
400   return alobj.SetMatrix(align);
401 }
402
403
404 //_____________________________________________________________________________
405 void  AliGeomManager::InitAlignObjFromGeometry()
406 {
407  // Loop over all alignable volumes and extract
408  // the corresponding alignment objects from
409  // the TGeo geometry
410
411   if(fgAlignObjs[0]) return;
412   
413   for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
414     fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
415     for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
416       UShort_t volid = LayerToVolUID(iLayer,iModule);
417       fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjParams("",volid,0,0,0,0,0,0,kTRUE);
418       const char *symname = SymName(volid);
419       if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
420         AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
421     }
422   }
423   
424 }
425
426 //_____________________________________________________________________________
427 AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
428   // Returns the alignment object for given volume ID
429   //
430   Int_t modId;
431   ELayerID layerId = VolUIDToLayer(voluid,modId);
432   return GetAlignObj(layerId,modId);
433 }
434
435 //_____________________________________________________________________________
436 AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
437 {
438   // Returns pointer to alignment object given its layer and module ID
439   //
440   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
441     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
442     return NULL;
443   }
444   InitAlignObjFromGeometry();
445
446   return fgAlignObjs[layerId-kFirstLayer][modId];
447 }
448
449 //_____________________________________________________________________________
450 const char* AliGeomManager::SymName(UShort_t voluid) {
451   // Returns the symbolic volume name for given volume ID
452   //
453   Int_t modId;
454   ELayerID layerId = VolUIDToLayer(voluid,modId);
455   return SymName(layerId,modId);
456 }
457
458 //_____________________________________________________________________________
459 const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
460 {
461   // Returns the symbolic volume name given for a given layer
462   // and module ID
463   //
464   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
465     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
466     return NULL;
467   }
468   InitSymNamesLUT();
469
470   return fgSymName[layerId-kFirstLayer][modId].Data();
471 }
472
473 //_____________________________________________________________________________
474 void AliGeomManager::InitSymNamesLUT()
475 {
476   // Initialize the look-up table which associates the unique
477   // numerical identity of each alignable volume to the 
478   // corresponding symbolic volume name
479   // The LUTs are static; they are created at the creation of the
480   // AliGeomManager instance and recreated if the geometry has changed
481   //
482
483   if(fgSymName[0]) return;
484
485   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
486     if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
487   }
488
489   TString symname;
490   Int_t modnum; // in the following, set it to 0 at the start of each layer
491
492   /*********************       ITS layers  ***********************/
493   TString strSPD = "ITS/SPD";
494   TString strSDD = "ITS/SDD";
495   TString strSSD = "ITS/SSD";
496   TString strStave = "/Stave";
497   TString strHalfStave = "/HalfStave";
498   TString strLadder = "/Ladder";
499   TString strSector = "/Sector";
500   TString strSensor = "/Sensor";
501   TString strEntryName1;
502   TString strEntryName2;
503   TString strEntryName3;
504
505   /*********************       SPD layer1  ***********************/
506   {
507     modnum = 0;
508     
509     for(Int_t cSect = 0; cSect<10; cSect++){
510       strEntryName1 = strSPD;
511       strEntryName1 += 0;
512       strEntryName1 += strSector;
513       strEntryName1 += cSect;
514       
515       for(Int_t cStave =0; cStave<2; cStave++){
516         strEntryName2 = strEntryName1;
517         strEntryName2 += strStave;
518         strEntryName2 += cStave;
519
520         for (Int_t cHS=0; cHS<2; cHS++) {
521           strEntryName3 = strEntryName2;
522           strEntryName3 += strHalfStave;
523           strEntryName3 += cHS;
524           
525           for(Int_t cLad =0; cLad<2; cLad++){
526             symname = strEntryName3;
527             symname += strLadder;
528             symname += cLad+cHS*2;
529             fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
530             modnum++;
531           }
532         }
533       }
534     }
535   }
536   
537   /*********************       SPD layer2  ***********************/
538   {
539     modnum = 0;
540
541     for(Int_t cSect = 0; cSect<10; cSect++){
542       strEntryName1 = strSPD;
543       strEntryName1 += 1;
544       strEntryName1 += strSector;
545       strEntryName1 += cSect;
546
547       for(Int_t cStave =0; cStave<4; cStave++){
548         strEntryName2 = strEntryName1;
549         strEntryName2 += strStave;
550         strEntryName2 += cStave;
551
552         for (Int_t cHS=0; cHS<2; cHS++) {
553           strEntryName3 = strEntryName2;
554           strEntryName3 += strHalfStave;
555           strEntryName3 += cHS;
556
557           for(Int_t cLad =0; cLad<2; cLad++){
558             symname = strEntryName3;
559             symname += strLadder;
560             symname += cLad+cHS*2;
561             fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
562             modnum++;
563           }
564         }
565       }
566     }
567   }
568
569 //   /*********************       SPD layer1  ***********************/
570 //   {
571 //     modnum = 0;
572
573 //     for(Int_t c1 = 1; c1<=10; c1++){
574 //       strEntryName1 = strSPD;
575 //       strEntryName1 += 0;
576 //       strEntryName1 += strSector;
577 //       strEntryName1 += (c1-1);
578 //       for(Int_t c2 =1; c2<=2; c2++){
579 //      strEntryName2 = strEntryName1;
580 //      strEntryName2 += strStave;
581 //      strEntryName2 += (c2-1);
582 //      for(Int_t c3 =1; c3<=4; c3++){
583 //        symname = strEntryName2;
584 //        symname += strLadder;
585 //        symname += (c3-1);
586 //        fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
587 //        modnum++;
588 //      }
589 //       }
590 //     }
591 //   }
592   
593 //   /*********************       SPD layer2  ***********************/
594 //   {
595 //     modnum = 0;
596
597 //     for(Int_t c1 = 1; c1<=10; c1++){
598 //       strEntryName1 = strSPD;
599 //       strEntryName1 += 1;
600 //       strEntryName1 += strSector;
601 //       strEntryName1 += (c1-1);
602 //       for(Int_t c2 =1; c2<=4; c2++){
603 //      strEntryName2 = strEntryName1;
604 //      strEntryName2 += strStave;
605 //      strEntryName2 += (c2-1);
606 //      for(Int_t c3 =1; c3<=4; c3++){
607 //        symname = strEntryName2;
608 //        symname += strLadder;
609 //        symname += (c3-1);
610 //        fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
611 //        modnum++;
612 //      }
613 //       }
614 //     }
615 //   }
616
617
618
619
620
621
622
623
624
625   /*********************       SDD layer1  ***********************/
626   {
627     modnum=0;
628
629     for(Int_t c1 = 1; c1<=14; c1++){
630       strEntryName1 = strSDD;
631       strEntryName1 += 2;
632       strEntryName1 +=strLadder;
633       strEntryName1 += (c1-1);
634       for(Int_t c2 =1; c2<=6; c2++){
635         symname = strEntryName1;
636         symname += strSensor;
637         symname += (c2-1);
638         fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
639         modnum++;
640       }
641     }
642   }
643
644   /*********************       SDD layer2  ***********************/
645   {
646     modnum=0;
647
648     for(Int_t c1 = 1; c1<=22; c1++){
649       strEntryName1 = strSDD;
650       strEntryName1 += 3;
651       strEntryName1 +=strLadder;
652       strEntryName1 += (c1-1);
653       for(Int_t c2 = 1; c2<=8; c2++){
654         symname = strEntryName1;
655         symname += strSensor;
656         symname += (c2-1);
657         fgSymName[kSDD2-kFirstLayer][modnum] = symname.Data();
658         modnum++;
659       }
660     }
661   }
662
663   /*********************       SSD layer1  ***********************/
664   {
665     modnum=0;
666
667     for(Int_t c1 = 1; c1<=34; c1++){
668       strEntryName1 = strSSD;
669       strEntryName1 += 4;
670       strEntryName1 +=strLadder;
671       strEntryName1 += (c1-1);
672       for(Int_t c2 = 1; c2<=22; c2++){
673         symname = strEntryName1;
674         symname += strSensor;
675         symname += (c2-1);
676         fgSymName[kSSD1-kFirstLayer][modnum] = symname.Data();
677         modnum++;
678       }
679     }
680   }
681
682   /*********************       SSD layer2  ***********************/
683   {
684     modnum=0;
685
686     for(Int_t c1 = 1; c1<=38; c1++){
687       strEntryName1 = strSSD;
688       strEntryName1 += 5;
689       strEntryName1 +=strLadder;
690       strEntryName1 += (c1-1);
691       for(Int_t c2 = 1; c2<=25; c2++){
692         symname = strEntryName1;
693         symname += strSensor;
694         symname += (c2-1);
695         fgSymName[kSSD2-kFirstLayer][modnum] = symname.Data();
696         modnum++;
697       }
698     }
699   }
700
701
702   /***************    TPC inner and outer layers    ****************/
703   TString sAsector="TPC/EndcapA/Sector";
704   TString sCsector="TPC/EndcapC/Sector";
705   TString sInner="/InnerChamber";
706   TString sOuter="/OuterChamber";
707   
708   /***************    TPC inner chambers' layer    ****************/
709   {
710     modnum = 0;
711     
712     for(Int_t cnt=1; cnt<=18; cnt++){
713       symname = sAsector;
714       symname += cnt;
715       symname += sInner;
716       fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
717       modnum++;
718     }
719     for(Int_t cnt=1; cnt<=18; cnt++){
720       symname = sCsector;
721       symname += cnt;
722       symname += sInner;
723       fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
724       modnum++;
725     }
726   }
727
728   /***************    TPC outer chambers' layer    ****************/
729   {
730     modnum = 0;
731     
732     for(Int_t cnt=1; cnt<=18; cnt++){
733       symname = sAsector;
734       symname += cnt;
735       symname += sOuter;
736       fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
737       modnum++;
738     }
739     for(Int_t cnt=1; cnt<=18; cnt++){
740       symname = sCsector;
741       symname += cnt;
742       symname += sOuter;
743       fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
744       modnum++;
745     }
746   }    
747
748   /*********************       TOF layer   ***********************/
749   {
750     modnum=0;
751     
752     Int_t nstrA=15;
753     Int_t nstrB=19;
754     Int_t nstrC=19;
755     Int_t nSectors=18;
756     Int_t nStrips=nstrA+2*nstrB+2*nstrC;
757     
758     TString snSM  = "TOF/sm";
759     TString snSTRIP = "/strip";
760     
761     for (Int_t isect = 0; isect < nSectors; isect++) {
762       for (Int_t istr = 1; istr <= nStrips; istr++) {   
763         symname  = snSM;
764         symname += Form("%02d",isect);
765         symname += snSTRIP;
766         symname += Form("%02d",istr);
767         fgSymName[kTOF-kFirstLayer][modnum] = symname.Data();   
768         modnum++;
769       }
770     }
771   } 
772
773   /*********************      HMPID layer   ***********************/
774   {
775     TString str = "/HMPID/Chamber";
776
777     for (modnum=0; modnum < 7; modnum++) {
778       symname = str;
779       symname += modnum;
780       fgSymName[kHMPID-kFirstLayer][modnum] = symname.Data();
781     }
782   }
783
784   /*********************      TRD layers 1-6   *******************/
785   //!! 6 layers with index increasing in outwards direction
786   {
787     Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
788
789     TString snStr  = "TRD/sm";
790     TString snApp1 = "/st";
791     TString snApp2 = "/pl";
792     
793     for(Int_t layer=0; layer<6; layer++){
794       modnum=0;
795       for (Int_t isect = 0; isect < 18; isect++) {
796         for (Int_t icham = 0; icham < 5; icham++) {
797           symname  = snStr;
798           symname += Form("%02d",isect);
799           symname += snApp1;
800           symname += icham;
801           symname += snApp2;
802           symname += layer;
803           fgSymName[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();
804           modnum++;
805         }
806       }
807     }
808   }
809
810   /*********************      PHOS EMC layer   ***********************/
811   {
812     TString str = "PHOS/Module";
813     modnum=0;
814
815     for (Int_t iModule=1; iModule <= 5; iModule++) {
816       symname = str;
817       symname += iModule;
818       modnum = iModule-1;
819       fgSymName[kPHOS1-kFirstLayer][modnum] = symname.Data();
820     }
821   }
822
823   /*********************      PHOS CPV layer   ***********************/
824   {
825     TString str = "PHOS/Module";
826     modnum=0;
827
828     for (Int_t iModule=1; iModule <= 5; iModule++) {
829       symname = str;
830       symname += iModule;
831       symname += "/CPV";
832       modnum = iModule-1;
833       fgSymName[kPHOS2-kFirstLayer][modnum] = symname.Data();
834     }
835   }
836
837
838 }
839
840 //_____________________________________________________________________________
841 void AliGeomManager::InitPNEntriesLUT()
842 {
843   // Initialize the look-up table which associates the unique
844   // numerical identity of each alignable volume to the
845   // corresponding TGeoPNEntry.
846   // The LUTs are static; they are created at the creation of the
847   // AliGeomManager instance and recreated if the geometry has changed
848   //
849   if (fgPNEntry[0]) return;
850
851   if(!fgGeometry) {
852     AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
853     return;
854   }
855
856   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
857     fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
858     for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
859       fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntry(fgSymName[iLayer][modnum]);
860     }
861   }
862 }
863
864 //_____________________________________________________________________________
865 void AliGeomManager::InitOrigMatricesLUT()
866 {
867   // Initialize the storage for the look-up table with the original global
868   // matrices for each alignable volume.
869   // The LUTs are static; the matrices are created on demand and recreated
870   // if the geometry has changed.
871   if (fgOrigMatrix[0]) return;
872
873   if (!fgGeometry || !fgGeometry->IsClosed()) {
874     AliErrorClass("Impossible to initialize orignal matrices LUT without an active geometry");
875     return;
876   }
877
878   for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
879     fgOrigMatrix[iLayer] = new TGeoHMatrix*[fgLayerSize[iLayer]];
880     for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
881       if (!fgPNEntry[iLayer][modnum]) continue;
882       TGeoHMatrix *m = GetOrigGlobalMatrix(fgPNEntry[iLayer][modnum]);
883       if (!m) continue;
884       fgOrigMatrix[iLayer][modnum] = new TGeoHMatrix(*m);
885     }
886   }
887
888 }
889
890 //______________________________________________________________________
891 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne) 
892 {
893   // Get the transformation matrix for a given PNEntry
894   // by quering the TGeoManager
895
896   if (!fgGeometry || !fgGeometry->IsClosed()) {
897     AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
898     return NULL;
899   }
900   
901   TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
902   if (pnode) return pnode->GetMatrix();
903
904   const char* path = pne->GetTitle();
905   if (!fgGeometry->cd(path)) {
906     AliErrorClass(Form("Volume path %s not valid!",path));
907     return NULL;
908   }
909   return fgGeometry->GetCurrentMatrix();
910 }
911
912 //______________________________________________________________________
913 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index) 
914 {
915   // Get the global transformation matrix for a given alignable volume
916   // identified by its unique ID 'index' by quering the TGeoManager
917
918   TGeoPNEntry *pne = GetPNEntry(index);
919   if (!pne) return NULL;
920
921   return GetMatrix(pne);
922 }
923
924 //______________________________________________________________________
925 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname) 
926 {
927   // Get the global transformation matrix for a given alignable volume
928   //  identified by its symbolic name 'symname' by quering the TGeoManager
929
930   if (!fgGeometry || !fgGeometry->IsClosed()) {
931     AliErrorClass("No active geometry or geometry not yet closed!");
932     return NULL;
933   }
934
935   TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
936   if (!pne) return NULL;
937
938   return GetMatrix(pne);
939 }
940
941 //______________________________________________________________________
942 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3]) 
943 {
944   // Get the translation vector for a given module 'index'
945   // by quering the TGeoManager
946
947   TGeoHMatrix *m = GetMatrix(index);
948   if (!m) return kFALSE;
949
950   Double_t *trans = m->GetTranslation();
951   for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
952
953   return kTRUE;
954 }
955
956 //______________________________________________________________________
957 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9]) 
958 {
959   // Get the rotation matrix for a given module 'index'
960   // by quering the TGeoManager
961
962   TGeoHMatrix *m = GetMatrix(index);
963   if (!m) return kFALSE;
964
965   Double_t *rot = m->GetRotationMatrix();
966   for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
967
968   return kTRUE;
969 }
970
971 //______________________________________________________________________
972 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m) 
973 {
974   // Get the global transformation matrix (ideal geometry) for a given alignable volume
975   //  identified by its symbolic name 'symname' by quering the TGeoManager
976   m.Clear();
977
978   if (!fgGeometry || !fgGeometry->IsClosed()) {
979     AliErrorClass("No active geometry or geometry not yet closed!");
980     return kFALSE;
981   }
982   if (!fgGeometry->GetListOfPhysicalNodes()) {
983     AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
984     if (!fgGeometry->cd(symname)) {
985       AliErrorClass(Form("Volume path %s not valid!",symname));
986       return kFALSE;
987     }
988     else {
989       m = *fgGeometry->GetCurrentMatrix();
990       return kTRUE;
991     }
992   }
993
994   TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
995   const char* path = NULL;
996   if(pne){
997     path = pne->GetTitle();
998   }else{
999     AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
1000     path=symname;
1001   }
1002
1003   return GetOrigGlobalMatrixFromPath(path,m);
1004 }
1005
1006 //_____________________________________________________________________________
1007 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
1008 {
1009   // The method returns global matrix for the ideal detector geometry
1010   // Symname identifies either the corresponding TGeoPNEntry or directly
1011   // the volume path. The output global matrix is stored in 'm'.
1012   // Returns kFALSE in case TGeo has not been initialized or the symname
1013   // is invalid.
1014   //
1015   m.Clear();
1016
1017   if (!fgGeometry || !fgGeometry->IsClosed()) {
1018     AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
1019     return kFALSE;
1020   }
1021
1022   if (!fgGeometry->CheckPath(path)) {
1023     AliErrorClass(Form("Volume path %s not valid!",path));
1024     return kFALSE;
1025   }
1026
1027   TIter next(fgGeometry->GetListOfPhysicalNodes());
1028   fgGeometry->cd(path);
1029
1030   while(fgGeometry->GetLevel()){
1031
1032     TGeoPhysicalNode *physNode = NULL;
1033     next.Reset();
1034     TGeoNode *node = fgGeometry->GetCurrentNode();
1035     while ((physNode=(TGeoPhysicalNode*)next())) 
1036       if (physNode->GetNode() == node) break;
1037
1038     TGeoMatrix *lm = NULL;
1039     if (physNode) {
1040         lm = physNode->GetOriginalMatrix();
1041         if (!lm) lm = node->GetMatrix();
1042     } else
1043       lm = node->GetMatrix();
1044
1045     m.MultiplyLeft(lm);
1046
1047     fgGeometry->CdUp();
1048   }
1049
1050   return kTRUE;
1051 }
1052
1053 //_____________________________________________________________________________
1054 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
1055 {
1056   // The method returns global matrix for the ideal detector geometry
1057   // using the corresponding TGeoPNEntry as an input.
1058   // The method creates a new matrix, so it has to be used carefully in order
1059   // to avoid memory leaks.
1060   // In case of missing TGeoManager the method return NULL.
1061
1062   if (!fgGeometry || !fgGeometry->IsClosed()) {
1063     AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1064     return NULL;
1065   }
1066
1067   const char* path = pne->GetTitle();
1068   static TGeoHMatrix m;
1069   if (!GetOrigGlobalMatrixFromPath(path,m))
1070     return NULL;
1071
1072   return &m;
1073 }
1074
1075 //______________________________________________________________________
1076 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
1077 {
1078   // Get the original (ideal geometry) TGeo matrix for
1079   // a given module identified by 'index'.
1080   // In general the method is slow, so we use
1081   // LUT for fast access. The LUT is reset in case of
1082   // new geometry is loaded.
1083   Int_t modId;
1084   ELayerID layerId = VolUIDToLayer(index,modId);
1085
1086   if (fgOrigMatrix[layerId-kFirstLayer][modId])
1087     return fgOrigMatrix[layerId-kFirstLayer][modId];
1088   else {
1089     TGeoPNEntry *pne = GetPNEntry(index);
1090     if (!pne) return NULL;
1091     return GetOrigGlobalMatrix(pne);
1092   }
1093 }
1094
1095 //______________________________________________________________________
1096 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3]) 
1097 {
1098   // Get the original translation vector (ideal geometry)
1099   // for a given module 'index' by quering the TGeoManager
1100
1101   TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1102   if (!m) return kFALSE;
1103
1104   Double_t *trans = m->GetTranslation();
1105   for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1106
1107   return kTRUE;
1108 }
1109
1110 //______________________________________________________________________
1111 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9]) 
1112 {
1113   // Get the original rotation matrix (ideal geometry)
1114   // for a given module 'index' by quering the TGeoManager
1115
1116   TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1117   if (!m) return kFALSE;
1118
1119   Double_t *rot = m->GetRotationMatrix();
1120   for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1121
1122   return kTRUE;
1123 }
1124
1125 //______________________________________________________________________
1126 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1127 {
1128   // Get the matrix which transforms from the tracking to the local RS
1129   // The method queries directly the TGeoPNEntry
1130
1131   TGeoPNEntry *pne = GetPNEntry(index);
1132   if (!pne) return NULL;
1133
1134   const TGeoHMatrix *m = pne->GetMatrix();
1135   if (!m)
1136     AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
1137
1138   return m;
1139 }
1140
1141 //______________________________________________________________________
1142 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1143 {
1144   // Get the matrix which transforms from the tracking r.s. to
1145   // the global one.
1146   // Returns kFALSE in case of error.
1147
1148   m.Clear();
1149
1150   TGeoHMatrix *m1 = GetMatrix(index);
1151   if (!m1) return kFALSE;
1152
1153   const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1154   if (!m2) return kFALSE;
1155
1156   m = *m1;
1157   m.Multiply(m2);
1158
1159   return kTRUE;
1160 }
1161
1162 //_____________________________________________________________________________
1163 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1164   // Returns the TGeoPNEntry for the given global volume ID "voluid"
1165   //
1166   Int_t modId;
1167   ELayerID layerId = VolUIDToLayer(voluid,modId);
1168   return GetPNEntry(layerId,modId);
1169 }
1170
1171 //_____________________________________________________________________________
1172 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1173 {
1174   // Returns the TGeoPNEntry for a given layer
1175   // and module ID
1176   //
1177
1178   if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1179     AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1180     return NULL;
1181   }
1182
1183   return fgPNEntry[layerId-kFirstLayer][modId];
1184 }
1185
1186 //_____________________________________________________________________________
1187 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1188 {
1189   // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1190   // the list passed as argument (called by AliSimulation and
1191   // AliReconstruction)
1192   // Read the alignment objects from CDB.
1193   // Each detector is supposed to have the
1194   // alignment objects in DET/Align/Data CDB path.
1195   // All the detector objects are then collected,
1196   // sorted by geometry level (starting from ALIC) and
1197   // then applied to the TGeo geometry.
1198   // Finally an overlaps check is performed.
1199   //
1200  
1201   TObjArray alignObjArray;
1202   alignObjArray.Clear();        
1203   alignObjArray.SetOwner(0);
1204
1205   TString alObjsNotLoaded="";
1206   TString alObjsLoaded="";
1207
1208   TString AlignDetsString(AlignDetsList);
1209   TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1210   TIter iter(detsarr);
1211   TObjString *str = 0;
1212   
1213   while((str = (TObjString*) iter.Next())){
1214     TString det(str->String());
1215     AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1216     if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
1217       alObjsNotLoaded += det.Data();
1218       alObjsNotLoaded += " ";
1219     } else {
1220       alObjsLoaded += det.Data();
1221       alObjsLoaded += " ";
1222     }
1223   }
1224
1225   if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1226                                                alObjsLoaded.Data()));
1227   if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1228                                                   alObjsNotLoaded.Data()));
1229  
1230   return ApplyAlignObjsToGeom(alignObjArray);
1231 }
1232
1233 //_____________________________________________________________________________
1234 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
1235 {
1236   // Adds the alignable objects found in the CDBEntry for the detector
1237   // passed as argument to the array of all alignment objects to be applyed
1238   // to geometry
1239   //
1240   // Fills array of single detector's alignable objects from CDB
1241   
1242   AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
1243   
1244   AliCDBEntry *entry;
1245         
1246   AliCDBPath path(detName,"Align","Data");
1247         
1248   entry=AliCDBManager::Instance()->Get(path.GetPath());
1249   if(!entry){ 
1250         AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
1251         return kFALSE;
1252   }
1253   entry->SetOwner(1);
1254   TClonesArray *alignArray = (TClonesArray*) entry->GetObject();        
1255   alignArray->SetOwner(0);
1256   AliDebugClass(2,Form("Found %d alignment objects for %s",
1257                        alignArray->GetEntries(),detName));
1258
1259   AliAlignObj *alignObj=0;
1260   TIter iter(alignArray);
1261         
1262   // loop over align objects in detector
1263   while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1264         alignObjArray.Add(alignObj);
1265   }
1266   // delete entry --- Don't delete, it is cached!
1267         
1268   AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
1269   return kTRUE;
1270
1271 }
1272
1273 //_____________________________________________________________________________
1274 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray)
1275 {
1276   // Read collection of alignment objects (AliAlignObj derived) saved
1277   // in the TClonesArray alObjArray and apply them to gGeoManager
1278   //
1279   alignObjArray.Sort();
1280   Int_t nvols = alignObjArray.GetEntriesFast();
1281
1282   Bool_t flag = kTRUE;
1283
1284   for(Int_t j=0; j<nvols; j++)
1285     {
1286       AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1287       if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
1288     }
1289
1290   if (AliDebugLevelClass() >= 1) {
1291     fgGeometry->GetTopNode()->CheckOverlaps(1);
1292     TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
1293     if(ovexlist->GetEntriesFast()){  
1294       AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1295    }
1296   }
1297
1298   // Update the TGeoPhysicalNodes
1299   fgGeometry->RefreshPhysicalNodes();
1300
1301   return flag;
1302
1303 }
1304
1305 //_____________________________________________________________________________
1306 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1307 {
1308   // read collection of alignment objects (AliAlignObj derived) saved
1309   // in the TClonesArray ClArrayName in the file fileName and apply
1310   // them to the geometry
1311   //
1312
1313   TFile* inFile = TFile::Open(fileName,"READ");
1314   if (!inFile || !inFile->IsOpen()) {
1315     AliErrorClass(Form("Could not open file %s !",fileName));
1316     return kFALSE;
1317   }
1318
1319   TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1320   inFile->Close();
1321   if (!alignObjArray) {
1322     AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1323     return kFALSE;
1324   }
1325
1326   return ApplyAlignObjsToGeom(*alignObjArray);
1327
1328 }
1329
1330 //_____________________________________________________________________________
1331 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1332 {
1333   // read collection of alignment objects (AliAlignObj derived) saved
1334   // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1335   // param (to get the AliCDBStorage) and Id; apply the alignment objects
1336   // to the geometry
1337   //
1338
1339   AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1340   AliCDBEntry* entry = storage->Get(Id);
1341   TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1342
1343   return ApplyAlignObjsToGeom(*alignObjArray);
1344
1345 }
1346
1347 //_____________________________________________________________________________
1348 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1349 {
1350   // read collection of alignment objects (AliAlignObj derived) saved
1351   // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1352   // param (to get the AliCDBStorage) and Id; apply the alignment objects
1353   // to the geometry
1354   //
1355
1356   AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1357   AliCDBId id(path, runnum, runnum, version, sversion);
1358
1359   return ApplyAlignObjsToGeom(param, id);
1360
1361 }
1362
1363 //_____________________________________________________________________________
1364 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1365 {
1366   // read collection of alignment objects (AliAlignObj derived) saved
1367   // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1368   // param (to get the AliCDBStorage) and Id; apply the alignment objects
1369   // to the geometry
1370   //
1371
1372   AliCDBPath path(detName,"Align","Data");
1373   AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1374
1375   if(!entry) return kFALSE;
1376   TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1377
1378   return ApplyAlignObjsToGeom(*alignObjArray);
1379 }