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