1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 //-------------------------------------------------------------------------
24 #include <TGeoManager.h>
25 #include <TObjString.h>
26 #include <TGeoPhysicalNode.h>
27 #include <TClonesArray.h>
28 #include <TGeoMatrix.h>
29 #include <TGeoPhysicalNode.h>
31 #include <TStopwatch.h>
32 #include <TGeoOverlap.h>
33 #include <TPluginManager.h>
36 #include "AliGeomManager.h"
38 #include "AliAlignObj.h"
39 #include "AliAlignObjParams.h"
40 #include "AliCDBManager.h"
41 #include "AliCDBStorage.h"
42 #include "AliCDBEntry.h"
44 ClassImp(AliGeomManager)
46 Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
47 80, 160, // ITS SPD first and second layer
48 84, 176, // ITS SDD first and second layer
49 748, 950, // ITS SSD first and second layer
50 36, 36, // TPC inner and outer chambers
51 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
59 const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
60 "ITS inner pixels layer", "ITS outer pixels layer",
61 "ITS inner drifts layer", "ITS outer drifts layer",
62 "ITS inner strips layer", "ITS outer strips layer",
63 "TPC inner chambers layer", "TPC outer chambers layer",
64 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
65 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
67 "PHOS EMC layer","PHOS CPV layer",
73 TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
87 AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
101 const char* AliGeomManager::fgkDetectorName[AliGeomManager::fgkNDetectors] = {"GRP","ITS","TPC","TRD","TOF","PHOS","HMPID","EMCAL","MUON","FMD","ZDC","PMD","T0","VZERO","ACORDE"};
102 Int_t AliGeomManager::fgNalignable[fgkNDetectors] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
105 TGeoManager* AliGeomManager::fgGeometry = 0x0;
107 //_____________________________________________________________________________
108 void AliGeomManager::LoadGeometry(const char *geomFileName)
111 // Load geometry either from a file
112 // or from the corresponding CDB entry
114 if(fgGeometry->IsLocked()){
115 AliErrorClass("Cannot load a new geometry, the current one being locked. Setting internal geometry to null!!");
121 if (geomFileName && (!gSystem->AccessPathName(geomFileName))) {
122 fgGeometry = TGeoManager::Import(geomFileName);
123 AliInfoClass(Form("From now on using geometry from custom geometry file \"%s\"",geomFileName));
127 AliCDBPath path("GRP","Geometry","Data");
129 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
130 if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
133 fgGeometry = (TGeoManager*) entry->GetObject();
134 if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
136 AliInfoClass(Form("From now on using geometry from CDB base folder \"%s\"",
137 AliCDBManager::Instance()->GetURI("Geometry/Align/Data")));
144 //_____________________________________________________________________________
145 void AliGeomManager::SetGeometry(TGeoManager * const geom)
147 // Load already active geometry
148 if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
155 //_____________________________________________________________________________
156 AliGeomManager::AliGeomManager():
159 // default constructor
162 //_____________________________________________________________________________
163 AliGeomManager::~AliGeomManager()
168 //_____________________________________________________________________________
169 Int_t AliGeomManager::LayerSize(Int_t layerId)
171 // Get the layer size for layer corresponding to layerId.
172 // Implemented only for ITS,TPC,TRD,TOF and HMPID
174 if (layerId < kFirstLayer || layerId >= kLastLayer) {
175 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
179 return fgLayerSize[layerId - kFirstLayer];
183 //_____________________________________________________________________________
184 const char* AliGeomManager::LayerName(Int_t layerId)
186 // Get the layer name corresponding to layerId.
187 // Implemented only for ITS,TPC,TRD,TOF and HMPID
189 if (layerId < kFirstLayer || layerId >= kLastLayer) {
190 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
191 return "Invalid Layer!";
194 return fgLayerName[layerId - kFirstLayer];
198 //_____________________________________________________________________________
199 UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
201 // From detector (layer) name and module number (according to detector
202 // internal numbering) build the unique numerical identity of that volume
204 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
205 // remaining 11 for module ID inside det (2048 possible values).
206 // NO check for validity of given modId inside the layer for speed's sake.
208 return ((UShort_t(layerId) << 11) | UShort_t(modId));
211 //_____________________________________________________________________________
212 UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
214 // From detector (layer) name and module number (according to detector
215 // internal numbering) build the unique numerical identity of that volume
217 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
218 // remaining 11 for module ID inside det (2048 possible values).
219 // NO check for validity of given modId inside the layer for speed's sake.
221 return ((UShort_t(layerId) << 11) | UShort_t(modId));
224 //_____________________________________________________________________________
225 UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
227 // From detector (layer) name and module number (according to detector
228 // internal numbering) build the unique numerical identity of that volume
230 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
231 // remaining 11 for module ID inside det (2048 possible values).
232 // Check validity of given modId inside the layer.
234 if(modId < 0 || modId >= LayerSize(layerId)){
235 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
238 return ((UShort_t(layerId) << 11) | UShort_t(modId));
241 //_____________________________________________________________________________
242 UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
244 // From detector (layer) name and module number (according to detector
245 // internal numbering) build the unique numerical identity of that volume
247 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
248 // remaining 11 for module ID inside det (2048 possible values).
249 // Check validity of given modId inside the layer.
251 if(modId < 0 || modId >= LayerSize(layerId)){
252 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
255 return ((UShort_t(layerId) << 11) | UShort_t(modId));
258 //_____________________________________________________________________________
259 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
261 // From voluid, unique numerical identity of that volume inside ALICE,
262 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
263 // remaining 11 for module ID inside det (2048 possible values)), return
264 // the identity of the layer to which that volume belongs and sets the
265 // argument modId to the identity of that volume internally to the layer.
266 // NO check for validity of given voluid for speed's sake.
268 modId = voluid & 0x7ff;
270 return VolUIDToLayer(voluid);
273 //_____________________________________________________________________________
274 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
276 // From voluid, unique numerical identity of that volume inside ALICE,
277 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
278 // remaining 11 for module ID inside det (2048 possible values)), return
279 // the identity of the layer to which that volume belongs
280 // NO check for validity of given voluid for speed's sake.
282 return ELayerID(voluid >> 11);
285 //_____________________________________________________________________________
286 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
288 // From voluid, unique numerical identity of that volume inside ALICE,
289 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
290 // remaining 11 for module ID inside det (2048 possible values)), returns
291 // the identity of the layer to which that volume belongs and sets the
292 // argument modId to the identity of that volume internally to the layer.
293 // Checks the validity of the given voluid
295 ELayerID layId = VolUIDToLayerSafe(voluid);
297 Int_t mId = Int_t(voluid & 0x7ff);
298 if( mId>=0 && mId<LayerSize(layId)){
304 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
306 return kInvalidLayer;
310 //_____________________________________________________________________________
311 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
313 // From voluid, unique numerical identity of that volume inside ALICE,
314 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
315 // remaining 11 for module ID inside det (2048 possible values)), returns
316 // the identity of the layer to which that volume belongs
317 // Checks the validity of the given voluid
319 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
321 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
322 return kInvalidLayer;
326 //_____________________________________________________________________________
327 Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
329 // Get the alignment object which corresponds to the symbolic volume name
330 // symname (in case equal to the TGeo volume path)
331 // The method is extremely slow due to the searching by string,
332 // therefore it should be used with great care!!
333 // This method returns FALSE if the symname of the object was not
334 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
335 // associated to the TGeoPNEntry was not valid.
338 // Reset the alignment object
339 alobj.SetPars(0,0,0,0,0,0);
340 alobj.SetSymName(symname);
342 if (!fgGeometry || !fgGeometry->IsClosed()) {
343 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
347 if (!fgGeometry->GetListOfPhysicalNodes()) {
348 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
353 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
355 path = pne->GetTitle();
357 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
360 TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
361 TGeoPhysicalNode* node = NULL;
362 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
363 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
364 const char *nodePath = tempNode->GetName();
365 if (strcmp(path,nodePath) == 0) {
372 if (!fgGeometry->cd(path)) {
373 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
377 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
382 TGeoHMatrix align,gprime,g,ginv,l;
383 gprime = *node->GetMatrix();
384 l = *node->GetOriginalMatrix();
385 g = *node->GetMatrix(node->GetLevel()-1);
388 align = gprime * ginv;
390 return alobj.SetMatrix(align);
394 //_____________________________________________________________________________
395 void AliGeomManager::InitAlignObjFromGeometry()
397 // Loop over all alignable volumes and extract
398 // the corresponding alignment objects from
401 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
402 if (!fgAlignObjs[iLayer-kFirstLayer]) {
403 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
405 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
406 UShort_t volid = LayerToVolUID(iLayer,iModule);
407 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjParams("",volid,0,0,0,0,0,0,kTRUE);
408 const char *symname = SymName(volid);
409 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
410 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
416 //_____________________________________________________________________________
417 AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid)
419 // Returns the alignment object for given volume ID
422 ELayerID layerId = VolUIDToLayer(voluid,modId);
423 return GetAlignObj(layerId,modId);
426 //_____________________________________________________________________________
427 AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
429 // Returns pointer to alignment object given its layer and module ID
431 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
432 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
435 InitAlignObjFromGeometry();
437 return fgAlignObjs[layerId-kFirstLayer][modId];
440 //_____________________________________________________________________________
441 const char* AliGeomManager::SymName(UShort_t voluid)
443 // Returns the symbolic volume name for given volume ID
446 ELayerID layerId = VolUIDToLayer(voluid,modId);
447 return SymName(layerId,modId);
450 //_____________________________________________________________________________
451 const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
453 // Returns the symbolic volume name given for a given layer
457 AliErrorClass("No geometry instance loaded yet!");
460 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
461 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
465 TGeoPNEntry* pne = fgPNEntry[layerId-kFirstLayer][modId];
468 AliWarningClass(Form("Module %d of layer %s is not activated!",modId,LayerName(layerId)));
471 return pne->GetName();
475 //_____________________________________________________________________________
476 Bool_t AliGeomManager::CheckSymNamesLUT(const char* /*detsToBeChecked*/)
478 // Check the look-up table which associates the unique numerical identity of
479 // each alignable volume to the corresponding symbolic volume name.
480 // The LUT is now hold inside the geometry and handled by TGeo.
481 // The method is meant to be launched when loading a geometry to verify that
482 // no changes in the symbolic names have been introduced, which would prevent
483 // backward compatibility with alignment objects.
484 // To accept both complete and partial geometry, this method skips the check
485 // for TRD and TOF volumes which are missing in the partial geometry.
488 // TString detsString(detsToBeChecked);
489 // if(detsString.Contains("ALL")) detsString="ITS TPC TOF TRD HMPID PHOS EMCAL";
491 // Temporary measure to face the case of reconstruction over detectors not present in the geometry
492 TString detsString = "";
493 if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
494 if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
497 TString baseTof("ALIC_1/B077_1/BSEGMO");
498 TString middleTof("_1/BTOF");
499 TString trailTof("_1/FTOA_0");
500 Bool_t tofActive=kFALSE;
502 for(Int_t sm=0; sm<18; sm++)
510 if(fgGeometry->CheckPath(tofsm.Data()))
516 if(tofActive) detsString+="TOF ";
519 TString baseTrd("ALIC_1/B077_1/BSEGMO");
520 TString middleTrd("_1/BTRD");
521 TString trailTrd("_1/UTR1_1");
522 Bool_t trdActive=kFALSE;
524 for(Int_t sm=0; sm<18; sm++)
532 if(fgGeometry->CheckPath(trdsm.Data()))
538 if(trdActive) detsString+="TRD ";
540 if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
542 TString phosMod, cpvMod;
543 TString basePhos("ALIC_1/PHOS_");
544 Bool_t phosActive=kFALSE;
545 Bool_t cpvActive=kFALSE;
547 for(Int_t pmod=0; pmod<5; pmod++)
549 phosMods[pmod]=kFALSE;
554 if(fgGeometry->CheckPath(phosMod.Data()))
557 phosMods[pmod]=kTRUE;
558 if(fgGeometry->CheckPath(cpvMod.Data())) cpvActive=kTRUE;
561 if(phosActive) detsString+="PHOS ";
563 if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
567 TGeoPNEntry* pne = 0x0;
568 Int_t uid; // global unique identity
569 Int_t modnum; // unique id inside layer; in the following, set it to 0 at the start of each layer
571 if(detsString.Contains("ITS")){
572 /********************* ITS layers ***********************/
573 AliDebugClass(2,"Checking consistency of symbolic names for ITS layers");
574 TString strSPD = "ITS/SPD";
575 TString strSDD = "ITS/SDD";
576 TString strSSD = "ITS/SSD";
577 TString strStave = "/Stave";
578 TString strHalfStave = "/HalfStave";
579 TString strLadder = "/Ladder";
580 TString strSector = "/Sector";
581 TString strSensor = "/Sensor";
582 TString strEntryName1;
583 TString strEntryName2;
584 TString strEntryName3;
586 /********************* SPD layer1 ***********************/
590 for(Int_t cSect = 0; cSect<10; cSect++){
591 strEntryName1 = strSPD;
593 strEntryName1 += strSector;
594 strEntryName1 += cSect;
596 for(Int_t cStave =0; cStave<2; cStave++){
597 strEntryName2 = strEntryName1;
598 strEntryName2 += strStave;
599 strEntryName2 += cStave;
601 for (Int_t cHS=0; cHS<2; cHS++) {
602 strEntryName3 = strEntryName2;
603 strEntryName3 += strHalfStave;
604 strEntryName3 += cHS;
606 for(Int_t cLad =0; cLad<2; cLad++){
607 symname = strEntryName3;
608 symname += strLadder;
609 symname += cLad+cHS*2;
610 uid = LayerToVolUID(kSPD1,modnum++);
611 pne = fgGeometry->GetAlignableEntryByUID(uid);
614 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
617 sname = pne->GetName();
618 if(symname.CompareTo(sname))
620 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
621 "Expected was %s, found was %s!", uid, symname.Data(), sname));
630 /********************* SPD layer2 ***********************/
634 for(Int_t cSect = 0; cSect<10; cSect++){
635 strEntryName1 = strSPD;
637 strEntryName1 += strSector;
638 strEntryName1 += cSect;
640 for(Int_t cStave =0; cStave<4; cStave++){
641 strEntryName2 = strEntryName1;
642 strEntryName2 += strStave;
643 strEntryName2 += cStave;
645 for (Int_t cHS=0; cHS<2; cHS++) {
646 strEntryName3 = strEntryName2;
647 strEntryName3 += strHalfStave;
648 strEntryName3 += cHS;
650 for(Int_t cLad =0; cLad<2; cLad++){
651 symname = strEntryName3;
652 symname += strLadder;
653 symname += cLad+cHS*2;
654 uid = LayerToVolUID(kSPD2,modnum++);
655 pne = fgGeometry->GetAlignableEntryByUID(uid);
658 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
661 sname = pne->GetName();
662 if(symname.CompareTo(sname))
664 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
665 "Expected was %s, found was %s!", uid, symname.Data(), sname));
674 /********************* SDD layer1 ***********************/
678 for(Int_t c1 = 1; c1<=14; c1++){
679 strEntryName1 = strSDD;
681 strEntryName1 +=strLadder;
682 strEntryName1 += (c1-1);
683 for(Int_t c2 =1; c2<=6; c2++){
684 symname = strEntryName1;
685 symname += strSensor;
687 uid = LayerToVolUID(kSDD1,modnum++);
688 pne = fgGeometry->GetAlignableEntryByUID(uid);
691 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
694 sname = pne->GetName();
695 if(symname.CompareTo(sname))
697 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
698 "Expected was %s, found was %s!", uid, symname.Data(), sname));
705 /********************* SDD layer2 ***********************/
709 for(Int_t c1 = 1; c1<=22; c1++){
710 strEntryName1 = strSDD;
712 strEntryName1 +=strLadder;
713 strEntryName1 += (c1-1);
714 for(Int_t c2 = 1; c2<=8; c2++){
715 symname = strEntryName1;
716 symname += strSensor;
718 uid = LayerToVolUID(kSDD2,modnum++);
719 pne = fgGeometry->GetAlignableEntryByUID(uid);
722 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
725 sname = pne->GetName();
726 if(symname.CompareTo(sname))
728 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
729 "Expected was %s, found was %s!", uid, symname.Data(), sname));
736 /********************* SSD layer1 ***********************/
740 for(Int_t c1 = 1; c1<=34; c1++){
741 strEntryName1 = strSSD;
743 strEntryName1 +=strLadder;
744 strEntryName1 += (c1-1);
745 for(Int_t c2 = 1; c2<=22; c2++){
746 symname = strEntryName1;
747 symname += strSensor;
749 uid = LayerToVolUID(kSSD1,modnum++);
750 pne = fgGeometry->GetAlignableEntryByUID(uid);
753 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
756 sname = pne->GetName();
757 if(symname.CompareTo(sname))
759 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
760 "Expected was %s, found was %s!", uid, symname.Data(), sname));
767 /********************* SSD layer2 ***********************/
771 for(Int_t c1 = 1; c1<=38; c1++){
772 strEntryName1 = strSSD;
774 strEntryName1 +=strLadder;
775 strEntryName1 += (c1-1);
776 for(Int_t c2 = 1; c2<=25; c2++){
777 symname = strEntryName1;
778 symname += strSensor;
780 uid = LayerToVolUID(kSSD2,modnum++);
781 pne = fgGeometry->GetAlignableEntryByUID(uid);
784 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
787 sname = pne->GetName();
788 if(symname.CompareTo(sname))
790 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
791 "Expected was %s, found was %s!", uid, symname.Data(), sname));
798 AliDebugClass(2,"Consistency check for ITS symbolic names finished successfully.");
801 if(detsString.Contains("TPC"))
803 /*************** TPC inner and outer layers ****************/
805 AliDebugClass(2,"Checking consistency of symbolic names for TPC layers");
806 TString sAsector="TPC/EndcapA/Sector";
807 TString sCsector="TPC/EndcapC/Sector";
808 TString sInner="/InnerChamber";
809 TString sOuter="/OuterChamber";
811 /*************** TPC inner chambers' layer ****************/
815 for(Int_t cnt=1; cnt<=18; cnt++)
820 uid = LayerToVolUID(kTPC1,modnum++);
821 pne = fgGeometry->GetAlignableEntryByUID(uid);
824 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
827 sname = pne->GetName();
828 if(symname.CompareTo(sname))
830 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
831 "Expected was %s, found was %s!", uid, symname.Data(), sname));
836 for(Int_t cnt=1; cnt<=18; cnt++)
841 uid = LayerToVolUID(kTPC1,modnum++);
842 pne = fgGeometry->GetAlignableEntryByUID(uid);
845 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
848 sname = pne->GetName();
849 if(symname.CompareTo(sname))
851 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
852 "Expected was %s, found was %s!", uid, symname.Data(), sname));
858 /*************** TPC outer chambers' layer ****************/
862 for(Int_t cnt=1; cnt<=18; cnt++)
867 uid = LayerToVolUID(kTPC2,modnum++);
868 pne = fgGeometry->GetAlignableEntryByUID(uid);
871 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
874 sname = pne->GetName();
875 if(symname.CompareTo(sname))
877 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
878 "Expected was %s, found was %s!", uid, symname.Data(), sname));
883 for(Int_t cnt=1; cnt<=18; cnt++)
888 uid = LayerToVolUID(kTPC2,modnum++);
889 pne = fgGeometry->GetAlignableEntryByUID(uid);
892 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
895 sname = pne->GetName();
896 if(symname.CompareTo(sname))
898 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
899 "Expected was %s, found was %s!", uid, symname.Data(), sname));
905 AliDebugClass(2,"Consistency check for TPC symbolic names finished successfully.");
908 if(detsString.Contains("TOF"))
910 /********************* TOF layer ***********************/
912 AliDebugClass(2,"Checking consistency of symbolic names for TOF layers");
919 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
921 TString snSM = "TOF/sm";
922 TString snSTRIP = "/strip";
924 for (Int_t isect = 0; isect < nSectors; isect++) {
925 for (Int_t istr = 1; istr <= nStrips; istr++) {
927 symname += Form("%02d",isect);
929 symname += Form("%02d",istr);
930 uid = LayerToVolUID(kTOF,modnum++);
931 if(!tofSMs[isect]) continue; // taking possible missing TOF sectors (partial geometry) into account
932 AliDebugClass(2,Form("Consistency check for symnames of TOF supermodule %d.",isect));
933 if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue; //taking holes into account
934 pne = fgGeometry->GetAlignableEntryByUID(uid);
937 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
940 sname = pne->GetName();
941 if(symname.CompareTo(sname))
943 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
944 "Expected was %s, found was %s!", uid, symname.Data(), sname));
950 AliDebugClass(2,"Consistency check for TOF symbolic names finished successfully.");
953 if(detsString.Contains("HMPID"))
955 /********************* HMPID layer ***********************/
957 AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
958 TString str = "/HMPID/Chamber";
960 for (modnum=0; modnum < 7; modnum++) {
963 uid = LayerToVolUID(kHMPID,modnum);
964 pne = fgGeometry->GetAlignableEntryByUID(uid);
967 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
970 sname = pne->GetName();
971 if(symname.CompareTo(sname))
973 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
974 "Expected was %s, found was %s!", uid, symname.Data(), sname));
979 AliDebugClass(2,"Consistency check for HMPID symbolic names finished successfully.");
982 if(detsString.Contains("TRD"))
984 /********************* TRD layers 1-6 *******************/
985 //!! 6 layers with index increasing in outwards direction
987 AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
988 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
990 TString snStr = "TRD/sm";
991 TString snApp1 = "/st";
992 TString snApp2 = "/pl";
994 for(Int_t layer=0; layer<6; layer++){
996 for (Int_t isect = 0; isect < 18; isect++) {
997 for (Int_t icham = 0; icham < 5; icham++) {
999 symname += Form("%02d",isect);
1004 uid = LayerToVolUID(arTRDlayId[layer],modnum++);
1005 if(!trdSMs[isect]) continue;
1006 AliDebugClass(2,Form("Consistency check for symnames of TRD supermodule %d.",isect));
1007 if ((isect==13 || isect==14 || isect==15) && icham==2) continue; //keeping holes into account
1008 pne = fgGeometry->GetAlignableEntryByUID(uid);
1011 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1014 sname = pne->GetName();
1015 if(symname.CompareTo(sname))
1017 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1018 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1025 AliDebugClass(2,"Consistency check for TRD symbolic names finished successfully.");
1028 if(detsString.Contains("PHOS"))
1030 /********************* PHOS EMC layer ***********************/
1032 AliDebugClass(2,"Checking consistency of symbolic names for PHOS layers");
1034 TString str = "PHOS/Module";
1037 for (Int_t iModule=0; iModule < 5; iModule++) {
1038 if(!phosMods[iModule]) continue;
1040 symname += (iModule+1);
1041 uid = LayerToVolUID(kPHOS1,iModule);
1042 pne = fgGeometry->GetAlignableEntryByUID(uid);
1045 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1048 sname = pne->GetName();
1049 if(symname.CompareTo(sname))
1051 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1052 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1055 /********************* PHOS CPV layer ***********************/
1056 if(!cpvActive) continue;
1058 uid = LayerToVolUID(kPHOS2,iModule);
1059 pne = fgGeometry->GetAlignableEntryByUID(uid);
1062 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1065 sname = pne->GetName();
1066 if(symname.CompareTo(sname))
1068 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1069 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1073 AliDebugClass(2,"Consistency check for PHOS symbolic names finished successfully.");
1076 if(detsString.Contains("EMCAL"))
1078 /********************* EMCAL layer ***********************/
1080 AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
1081 TString str = "EMCAL/FullSupermodule";
1084 for (Int_t iModule=1; iModule <= 12; iModule++) {
1088 symname = "EMCAL/HalfSupermodule";
1089 symname += iModule-10;
1092 uid = LayerToVolUID(kEMCAL,modnum);
1093 pne = fgGeometry->GetAlignableEntryByUID(uid);
1096 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1099 sname = pne->GetName();
1100 if(symname.CompareTo(sname))
1102 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1103 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1108 AliDebugClass(2,"Consistency check for EMCAL symbolic names finished successfully.");
1115 //_____________________________________________________________________________
1116 void AliGeomManager::InitPNEntriesLUT()
1118 // Initialize the look-up table which associates the unique
1119 // numerical identity of each alignable volume to the
1120 // corresponding TGeoPNEntry.
1121 // The LUTs are static; they are created at the creation of the
1122 // AliGeomManager instance and recreated if the geometry has changed
1125 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
1129 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
1130 if (!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
1131 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
1132 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
1137 //______________________________________________________________________
1138 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry * const pne)
1140 // Get the global transformation matrix for a given PNEntry
1141 // by quering the TGeoManager
1143 if (!fgGeometry || !fgGeometry->IsClosed()) {
1144 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1148 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
1149 if (pnode) return pnode->GetMatrix();
1151 const char* path = pne->GetTitle();
1152 if (!fgGeometry->cd(path)) {
1153 AliErrorClass(Form("Volume path %s not valid!",path));
1156 return fgGeometry->GetCurrentMatrix();
1159 //______________________________________________________________________
1160 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
1162 // Get the global transformation matrix for a given alignable volume
1163 // identified by its unique ID 'index' by quering the TGeoManager
1165 TGeoPNEntry *pne = GetPNEntry(index);
1166 if (!pne) return NULL;
1168 return GetMatrix(pne);
1171 //______________________________________________________________________
1172 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
1174 // Get the global transformation matrix for a given alignable volume
1175 // identified by its symbolic name 'symname' by quering the TGeoManager
1177 if (!fgGeometry || !fgGeometry->IsClosed()) {
1178 AliErrorClass("No active geometry or geometry not yet closed!");
1182 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
1183 if (!pne) return NULL;
1185 return GetMatrix(pne);
1188 //______________________________________________________________________
1189 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
1191 // Get the translation vector for a given module 'index'
1192 // by quering the TGeoManager
1194 TGeoHMatrix *m = GetMatrix(index);
1195 if (!m) return kFALSE;
1197 Double_t *trans = m->GetTranslation();
1198 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1203 //______________________________________________________________________
1204 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
1206 // Get the rotation matrix for a given module 'index'
1207 // by quering the TGeoManager
1209 TGeoHMatrix *m = GetMatrix(index);
1210 if (!m) return kFALSE;
1212 Double_t *rot = m->GetRotationMatrix();
1213 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1218 //_____________________________________________________________________________
1219 Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
1221 // The method sets the matrix passed as argument as the global delta
1222 // (for the volume referred by the unique index) including the displacements
1223 // of all parent volumes in the branch.
1226 TGeoHMatrix go,invgo;
1227 go = *GetOrigGlobalMatrix(index);
1228 invgo = go.Inverse();
1229 inclusiveD = *GetMatrix(index);
1230 inclusiveD.Multiply(&invgo);
1235 //_____________________________________________________________________________
1236 Bool_t AliGeomManager::GetDeltaForBranch(AliAlignObj& aao, TGeoHMatrix &inclusiveD)
1238 // The method sets the matrix passed as argument as the global delta
1239 // (for the volume referred by the alignment object) including the displacements
1240 // of all parent volumes in the brach.
1242 Int_t index = aao.GetVolUID();
1244 AliErrorClass("Either the alignment object or its index are not valid");
1247 return GetDeltaForBranch(index, inclusiveD);
1250 //______________________________________________________________________
1251 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
1253 // Get the global transformation matrix (ideal geometry) for a given alignable volume
1254 // The alignable volume is identified by 'symname' which has to be either a valid symbolic
1255 // name, the query being performed after alignment, or a valid volume path if the query is
1256 // performed before alignment.
1260 if (!fgGeometry || !fgGeometry->IsClosed()) {
1261 AliErrorClass("No active geometry or geometry not yet closed!");
1264 if (!fgGeometry->GetListOfPhysicalNodes()) {
1265 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
1266 if (!fgGeometry->cd(symname)) {
1267 AliErrorClass(Form("Volume path %s not valid!",symname));
1271 m = *fgGeometry->GetCurrentMatrix();
1276 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
1277 const char* path = NULL;
1279 m = *pne->GetGlobalOrig();
1282 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
1286 return GetOrigGlobalMatrixFromPath(path,m);
1289 //_____________________________________________________________________________
1290 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
1292 // The method returns the global matrix for the volume identified by
1293 // 'path' in the ideal detector geometry.
1294 // The output global matrix is stored in 'm'.
1295 // Returns kFALSE in case TGeo has not been initialized or the volume
1296 // path is not valid.
1300 if (!fgGeometry || !fgGeometry->IsClosed()) {
1301 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
1305 if (!fgGeometry->CheckPath(path)) {
1306 AliErrorClass(Form("Volume path %s not valid!",path));
1310 TIter next(fgGeometry->GetListOfPhysicalNodes());
1311 fgGeometry->cd(path);
1313 while(fgGeometry->GetLevel()){
1315 TGeoPhysicalNode *physNode = NULL;
1317 TGeoNode *node = fgGeometry->GetCurrentNode();
1318 while ((physNode=(TGeoPhysicalNode*)next()))
1319 if (physNode->GetNode() == node) break;
1321 TGeoMatrix *lm = NULL;
1323 lm = physNode->GetOriginalMatrix();
1324 if (!lm) lm = node->GetMatrix();
1326 lm = node->GetMatrix();
1336 //_____________________________________________________________________________
1337 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry * const pne)
1339 // The method returns global matrix for the ideal detector geometry
1340 // using the corresponding TGeoPNEntry as an input.
1341 // The returned pointer should be copied by the user, since its content could
1342 // be overwritten by a following call to the method.
1343 // In case of missing TGeoManager the method returns NULL.
1345 if (!fgGeometry || !fgGeometry->IsClosed()) {
1346 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1350 return pne->GetGlobalOrig();
1353 //______________________________________________________________________
1354 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
1356 // The method returns global matrix from the ideal detector geometry
1357 // for the volume identified by its index.
1358 // The returned pointer should be copied by the user, since its content could
1359 // be overwritten by a following call to the method.
1360 // In case of missing TGeoManager the method returns NULL.
1361 // If possible, the method uses the LUT of original ideal matrices
1362 // for fast access. The LUT is reset in case a
1363 // new geometry is loaded.
1365 TGeoPNEntry* pne = GetPNEntry(index);
1366 return pne->GetGlobalOrig();
1369 //______________________________________________________________________
1370 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1372 // Get the original translation vector (ideal geometry)
1373 // for a given module 'index' by quering the TGeoManager
1375 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1376 if (!m) return kFALSE;
1378 Double_t *trans = m->GetTranslation();
1379 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1384 //______________________________________________________________________
1385 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1387 // Get the original rotation matrix (ideal geometry)
1388 // for a given module 'index' by quering the TGeoManager
1390 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1391 if (!m) return kFALSE;
1393 Double_t *rot = m->GetRotationMatrix();
1394 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1399 //______________________________________________________________________
1400 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1402 // Get the matrix which transforms from the tracking to the local RS
1403 // The method queries directly the TGeoPNEntry
1405 TGeoPNEntry *pne = GetPNEntry(index);
1406 if (!pne) return NULL;
1408 const TGeoHMatrix *m = pne->GetMatrix();
1410 AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
1415 //______________________________________________________________________
1416 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1418 // Get the matrix which transforms from the tracking r.s. to
1420 // Returns kFALSE in case of error.
1424 TGeoHMatrix *m1 = GetMatrix(index);
1425 if (!m1) return kFALSE;
1427 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1428 if (!m2) return kFALSE;
1436 //_____________________________________________________________________________
1437 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1438 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1441 ELayerID layerId = VolUIDToLayer(voluid,modId);
1442 return GetPNEntry(layerId,modId);
1445 //_____________________________________________________________________________
1446 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1448 // Returns the TGeoPNEntry for a given layer
1452 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1453 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1457 return fgPNEntry[layerId-kFirstLayer][modId];
1460 //_____________________________________________________________________________
1461 void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
1463 // Check for overlaps/extrusions on physical nodes only;
1464 // this overlap-checker is meant to be used to check overlaps/extrusions
1465 // originated by the application of alignment objects.
1468 TObjArray* ovexlist = new TObjArray(64);
1470 AliInfoClass("********* Checking overlaps/extrusions over physical nodes only *********");
1471 TObjArray* pnList = gGeoManager->GetListOfPhysicalNodes();
1472 TGeoVolume* mvol = 0;
1473 TGeoPhysicalNode* pn;
1474 TObjArray* overlaps = new TObjArray(64);
1475 overlaps->SetOwner();
1479 for(Int_t pni=0; pni<pnList->GetEntriesFast(); pni++){
1480 pn = (TGeoPhysicalNode*) pnList->UncheckedAt(pni);
1481 // checking the volume of the mother (go upper in the tree in case it is an assembly)
1483 while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
1484 //Printf("Going to upper level");
1485 mvol = pn->GetVolume(pn->GetLevel()-levup);
1486 if(!mvol->IsSelected()){
1487 AliInfoClass(Form("Checking overlaps for volume %s",mvol->GetName()));
1488 mvol->CheckOverlaps(threshold);
1489 ovexlist = gGeoManager->GetListOfOverlaps();
1490 TIter next(ovexlist);
1492 while ((ov=(TGeoOverlap*)next())) overlaps->Add(ov->Clone());
1493 mvol->SelectVolume();
1496 mvol->SelectVolume(kTRUE); // clears the list of selected volumes
1498 AliInfoClass(Form("Number of overlapping/extruding PNs: %d",overlaps->GetEntriesFast()));
1502 TIter nextN(overlaps);
1504 while ((ovlp=(TGeoOverlap*)nextN())) ovlp->PrintInfo();
1510 //_____________________________________________________________________________
1511 Int_t AliGeomManager::GetNalignable(const char* module)
1513 // Get number of declared alignable volumes for given detector in current geometry
1516 // return the detector index corresponding to detector
1518 for (index = 0; index < fgkNDetectors ; index++) {
1519 if ( strcmp(module, fgkDetectorName[index]) == 0 )
1522 return fgNalignable[index];
1525 //_____________________________________________________________________________
1526 void AliGeomManager::InitNalignable()
1528 // Set number of declared alignable volumes for given detector in current geometry
1529 // by looping on the list of PNEntries
1532 Int_t nAlE = gGeoManager->GetNAlignable(); // total number of alignable entries
1533 TGeoPNEntry *pne = 0;
1534 const char* detName;
1536 for (Int_t iDet = 0; iDet < fgkNDetectors ; iDet++) {
1537 detName = fgkDetectorName[iDet];
1540 for(Int_t iE = 0; iE < nAlE; iE++)
1542 pne = gGeoManager->GetAlignableEntry(iE);
1543 TString pneName = pne->GetName();
1544 if(pneName.Contains(detName)) nAlDet++;
1545 if(!strcmp(detName,"GRP")) if(pneName.Contains("ABSO") || pneName.Contains("DIPO") ||
1546 pneName.Contains("FRAME") || pneName.Contains("PIPE") ||
1547 pneName.Contains("SHIL")) nAlDet++;
1549 fgNalignable[iDet] = nAlDet;
1554 //_____________________________________________________________________________
1555 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1557 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1558 // the list passed as argument (called by AliSimulation and
1559 // AliReconstruction)
1560 // Read the alignment objects from CDB.
1561 // Each detector is supposed to have the
1562 // alignment objects in DET/Align/Data CDB path.
1563 // All the detector objects are then collected,
1564 // sorted by geometry level (starting from ALIC) and
1565 // then applied to the TGeo geometry.
1566 // Finally an overlaps check is performed.
1569 TObjArray alignObjArray;
1570 alignObjArray.Clear();
1571 alignObjArray.SetOwner(0);
1573 TString alObjsNotLoaded="";
1574 TString alObjsLoaded="";
1576 TString AlignDetsString(AlignDetsList);
1577 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1578 TIter iter(detsarr);
1579 TObjString *str = 0;
1581 while((str = (TObjString*) iter.Next())){
1582 TString det(str->String());
1583 AliDebugClass(5,Form("Loading alignment objs for %s",det.Data()));
1584 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
1585 alObjsNotLoaded += det.Data();
1586 alObjsNotLoaded += " ";
1588 alObjsLoaded += det.Data();
1589 alObjsLoaded += " ";
1595 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1596 alObjsLoaded.Data()));
1597 if(!alObjsNotLoaded.IsNull())
1598 AliFatalClass(Form("Could not load alignment objects from OCDB for: %s",
1599 alObjsNotLoaded.Data()));
1601 return ApplyAlignObjsToGeom(alignObjArray);
1604 //_____________________________________________________________________________
1605 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
1607 // Adds the alignable objects found in the CDBEntry for the detector
1608 // passed as argument to the array of all alignment objects to be applyed
1611 // Fills array of single detector's alignable objects from CDB
1613 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
1617 AliCDBPath path(detName,"Align","Data");
1619 entry=AliCDBManager::Instance()->Get(path.GetPath());
1621 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
1625 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1626 alignArray->SetOwner(0);
1627 Int_t nAlObjs = alignArray->GetEntries();
1628 AliDebugClass(2,Form("Found %d alignment objects for %s",nAlObjs,detName));
1629 Int_t nAlVols = GetNalignable(detName);
1630 if(nAlObjs!=nAlVols) AliWarningClass(Form("%d alignment objects loaded for %s, which has %d alignable volumes",nAlObjs,detName,GetNalignable(detName)));
1632 AliAlignObj *alignObj=0;
1633 TIter iter(alignArray);
1635 // loop over align objects in detector
1636 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1637 alignObjArray.Add(alignObj);
1639 // delete entry --- Don't delete, it is cached!
1641 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
1646 //_____________________________________________________________________________
1647 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
1649 // Read collection of alignment objects (AliAlignObj derived) saved
1650 // in the TClonesArray alObjArray and apply them to gGeoManager
1652 alignObjArray.Sort();
1653 Int_t nvols = alignObjArray.GetEntriesFast();
1655 Bool_t flag = kTRUE;
1657 for(Int_t j=0; j<nvols; j++)
1659 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1660 if(!alobj->ApplyToGeometry(ovlpcheck))
1663 AliDebugClass(5,Form("Error applying alignment object for volume %s !",alobj->GetSymName()));
1665 AliDebugClass(5,Form("Alignment object for volume %s applied successfully",alobj->GetSymName()));
1670 if (AliDebugLevelClass() > 5) {
1671 fgGeometry->CheckOverlaps(0.001);
1672 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
1673 if(ovexlist->GetEntriesFast()){
1674 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1675 fgGeometry->PrintOverlaps();
1679 // Update the TGeoPhysicalNodes
1680 fgGeometry->RefreshPhysicalNodes();
1686 //_____________________________________________________________________________
1687 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1689 // read collection of alignment objects (AliAlignObj derived) saved
1690 // in the TClonesArray ClArrayName in the file fileName and apply
1691 // them to the geometry
1694 TFile* inFile = TFile::Open(fileName,"READ");
1695 if (!inFile || !inFile->IsOpen()) {
1696 AliErrorClass(Form("Could not open file %s !",fileName));
1700 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1702 if (!alignObjArray) {
1703 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1707 return ApplyAlignObjsToGeom(*alignObjArray);
1711 //_____________________________________________________________________________
1712 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1714 // read collection of alignment objects (AliAlignObj derived) saved
1715 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1716 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1720 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1721 AliCDBEntry* entry = storage->Get(Id);
1722 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1724 return ApplyAlignObjsToGeom(*alignObjArray);
1728 //_____________________________________________________________________________
1729 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1731 // read collection of alignment objects (AliAlignObj derived) saved
1732 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1733 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1737 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1738 AliCDBId id(path, runnum, runnum, version, sversion);
1740 return ApplyAlignObjsToGeom(param, id);
1744 //_____________________________________________________________________________
1745 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1747 // read collection of alignment objects (AliAlignObj derived) saved
1748 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1749 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1753 AliCDBPath path(detName,"Align","Data");
1754 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1756 if(!entry) return kFALSE;
1757 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1759 return ApplyAlignObjsToGeom(*alignObjArray);
1762 //_____________________________________________________________________________
1763 void AliGeomManager::ResetPNEntriesLUT()
1765 // cleans static arrays containing the information on currently loaded geometry
1767 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
1768 if (!fgPNEntry[iLayer]) continue;
1769 for (Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++) fgPNEntry[iLayer][modnum] = 0;