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
115 if (geomFileName && (!gSystem->AccessPathName(geomFileName))) {
116 fgGeometry = TGeoManager::Import(geomFileName);
117 AliInfoClass(Form("From now on using geometry from custom geometry file \"%s\"",geomFileName));
121 AliCDBPath path("GRP","Geometry","Data");
123 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
124 if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
127 fgGeometry = (TGeoManager*) entry->GetObject();
128 if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
130 AliInfoClass(Form("From now on using geometry from CDB base folder \"%s\"",
131 AliCDBManager::Instance()->GetURI("Geometry/Align/Data")));
138 //_____________________________________________________________________________
139 void AliGeomManager::SetGeometry(TGeoManager * const geom)
141 // Load already active geometry
142 if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
149 //_____________________________________________________________________________
150 AliGeomManager::AliGeomManager():
153 // default constructor
156 //_____________________________________________________________________________
157 AliGeomManager::~AliGeomManager()
162 //_____________________________________________________________________________
163 Int_t AliGeomManager::LayerSize(Int_t layerId)
165 // Get the layer size for layer corresponding to layerId.
166 // Implemented only for ITS,TPC,TRD,TOF and HMPID
168 if (layerId < kFirstLayer || layerId >= kLastLayer) {
169 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
173 return fgLayerSize[layerId - kFirstLayer];
177 //_____________________________________________________________________________
178 const char* AliGeomManager::LayerName(Int_t layerId)
180 // Get the layer name corresponding to layerId.
181 // Implemented only for ITS,TPC,TRD,TOF and HMPID
183 if (layerId < kFirstLayer || layerId >= kLastLayer) {
184 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
185 return "Invalid Layer!";
188 return fgLayerName[layerId - kFirstLayer];
192 //_____________________________________________________________________________
193 UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
195 // From detector (layer) name and module number (according to detector
196 // internal numbering) build the unique numerical identity of that volume
198 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
199 // remaining 11 for module ID inside det (2048 possible values).
200 // NO check for validity of given modId inside the layer for speed's sake.
202 return ((UShort_t(layerId) << 11) | UShort_t(modId));
205 //_____________________________________________________________________________
206 UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
208 // From detector (layer) name and module number (according to detector
209 // internal numbering) build the unique numerical identity of that volume
211 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
212 // remaining 11 for module ID inside det (2048 possible values).
213 // NO check for validity of given modId inside the layer for speed's sake.
215 return ((UShort_t(layerId) << 11) | UShort_t(modId));
218 //_____________________________________________________________________________
219 UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
221 // From detector (layer) name and module number (according to detector
222 // internal numbering) build the unique numerical identity of that volume
224 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
225 // remaining 11 for module ID inside det (2048 possible values).
226 // Check validity of given modId inside the layer.
228 if(modId < 0 || modId >= LayerSize(layerId)){
229 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
232 return ((UShort_t(layerId) << 11) | UShort_t(modId));
235 //_____________________________________________________________________________
236 UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
238 // From detector (layer) name and module number (according to detector
239 // internal numbering) build the unique numerical identity of that volume
241 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
242 // remaining 11 for module ID inside det (2048 possible values).
243 // Check validity of given modId inside the layer.
245 if(modId < 0 || modId >= LayerSize(layerId)){
246 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
249 return ((UShort_t(layerId) << 11) | UShort_t(modId));
252 //_____________________________________________________________________________
253 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
255 // From voluid, unique numerical identity of that volume inside ALICE,
256 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
257 // remaining 11 for module ID inside det (2048 possible values)), return
258 // the identity of the layer to which that volume belongs and sets the
259 // argument modId to the identity of that volume internally to the layer.
260 // NO check for validity of given voluid for speed's sake.
262 modId = voluid & 0x7ff;
264 return VolUIDToLayer(voluid);
267 //_____________________________________________________________________________
268 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
270 // From voluid, unique numerical identity of that volume inside ALICE,
271 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
272 // remaining 11 for module ID inside det (2048 possible values)), return
273 // the identity of the layer to which that volume belongs
274 // NO check for validity of given voluid for speed's sake.
276 return ELayerID(voluid >> 11);
279 //_____________________________________________________________________________
280 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
282 // From voluid, unique numerical identity of that volume inside ALICE,
283 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
284 // remaining 11 for module ID inside det (2048 possible values)), returns
285 // the identity of the layer to which that volume belongs and sets the
286 // argument modId to the identity of that volume internally to the layer.
287 // Checks the validity of the given voluid
289 ELayerID layId = VolUIDToLayerSafe(voluid);
291 Int_t mId = Int_t(voluid & 0x7ff);
292 if( mId>=0 && mId<LayerSize(layId)){
298 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
300 return kInvalidLayer;
304 //_____________________________________________________________________________
305 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
307 // From voluid, unique numerical identity of that volume inside ALICE,
308 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
309 // remaining 11 for module ID inside det (2048 possible values)), returns
310 // the identity of the layer to which that volume belongs
311 // Checks the validity of the given voluid
313 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
315 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
316 return kInvalidLayer;
320 //_____________________________________________________________________________
321 Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
323 // Get the alignment object which corresponds to the symbolic volume name
324 // symname (in case equal to the TGeo volume path)
325 // The method is extremely slow due to the searching by string,
326 // therefore it should be used with great care!!
327 // This method returns FALSE if the symname of the object was not
328 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
329 // associated to the TGeoPNEntry was not valid.
332 // Reset the alignment object
333 alobj.SetPars(0,0,0,0,0,0);
334 alobj.SetSymName(symname);
336 if (!fgGeometry || !fgGeometry->IsClosed()) {
337 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
341 if (!fgGeometry->GetListOfPhysicalNodes()) {
342 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
347 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
349 path = pne->GetTitle();
351 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
354 TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
355 TGeoPhysicalNode* node = NULL;
356 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
357 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
358 const char *nodePath = tempNode->GetName();
359 if (strcmp(path,nodePath) == 0) {
366 if (!fgGeometry->cd(path)) {
367 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
371 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
376 TGeoHMatrix align,gprime,g,ginv,l;
377 gprime = *node->GetMatrix();
378 l = *node->GetOriginalMatrix();
379 g = *node->GetMatrix(node->GetLevel()-1);
382 align = gprime * ginv;
384 return alobj.SetMatrix(align);
388 //_____________________________________________________________________________
389 void AliGeomManager::InitAlignObjFromGeometry()
391 // Loop over all alignable volumes and extract
392 // the corresponding alignment objects from
395 if(fgAlignObjs[0]) return;
397 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
398 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
399 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
400 UShort_t volid = LayerToVolUID(iLayer,iModule);
401 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjParams("",volid,0,0,0,0,0,0,kTRUE);
402 const char *symname = SymName(volid);
403 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
404 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
410 //_____________________________________________________________________________
411 AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid)
413 // Returns the alignment object for given volume ID
416 ELayerID layerId = VolUIDToLayer(voluid,modId);
417 return GetAlignObj(layerId,modId);
420 //_____________________________________________________________________________
421 AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
423 // Returns pointer to alignment object given its layer and module ID
425 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
426 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
429 InitAlignObjFromGeometry();
431 return fgAlignObjs[layerId-kFirstLayer][modId];
434 //_____________________________________________________________________________
435 const char* AliGeomManager::SymName(UShort_t voluid)
437 // Returns the symbolic volume name for given volume ID
440 ELayerID layerId = VolUIDToLayer(voluid,modId);
441 return SymName(layerId,modId);
444 //_____________________________________________________________________________
445 const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
447 // Returns the symbolic volume name given for a given layer
451 AliErrorClass("No geometry instance loaded yet!");
454 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
455 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
459 TGeoPNEntry* pne = fgPNEntry[layerId-kFirstLayer][modId];
462 AliWarningClass(Form("Module %d of layer %s is not activated!",modId,LayerName(layerId)));
465 return pne->GetName();
469 //_____________________________________________________________________________
470 Bool_t AliGeomManager::CheckSymNamesLUT(const char* /*detsToBeChecked*/)
472 // Check the look-up table which associates the unique numerical identity of
473 // each alignable volume to the corresponding symbolic volume name.
474 // The LUT is now hold inside the geometry and handled by TGeo.
475 // The method is meant to be launched when loading a geometry to verify that
476 // no changes in the symbolic names have been introduced, which would prevent
477 // backward compatibility with alignment objects.
478 // To accept both complete and partial geometry, this method skips the check
479 // for TRD and TOF volumes which are missing in the partial geometry.
482 // TString detsString(detsToBeChecked);
483 // if(detsString.Contains("ALL")) detsString="ITS TPC TOF TRD HMPID PHOS EMCAL";
485 // Temporary measure to face the case of reconstruction over detectors not present in the geometry
486 TString detsString = "";
487 if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
488 if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
491 TString baseTof("ALIC_1/B077_1/BSEGMO");
492 TString middleTof("_1/BTOF");
493 TString trailTof("_1/FTOA_0");
494 Bool_t tofActive=kFALSE;
496 for(Int_t sm=0; sm<18; sm++)
504 if(fgGeometry->CheckPath(tofsm.Data()))
510 if(tofActive) detsString+="TOF ";
513 TString baseTrd("ALIC_1/B077_1/BSEGMO");
514 TString middleTrd("_1/BTRD");
515 TString trailTrd("_1/UTR1_1");
516 Bool_t trdActive=kFALSE;
518 for(Int_t sm=0; sm<18; sm++)
526 if(fgGeometry->CheckPath(trdsm.Data()))
532 if(trdActive) detsString+="TRD ";
534 if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
536 TString phosMod, cpvMod;
537 TString basePhos("ALIC_1/PHOS_");
538 Bool_t phosActive=kFALSE;
539 Bool_t cpvActive=kFALSE;
541 for(Int_t pmod=0; pmod<5; pmod++)
543 phosMods[pmod]=kFALSE;
548 if(fgGeometry->CheckPath(phosMod.Data()))
551 phosMods[pmod]=kTRUE;
552 if(fgGeometry->CheckPath(cpvMod.Data())) cpvActive=kTRUE;
555 if(phosActive) detsString+="PHOS ";
557 if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
561 TGeoPNEntry* pne = 0x0;
562 Int_t uid; // global unique identity
563 Int_t modnum; // unique id inside layer; in the following, set it to 0 at the start of each layer
565 if(detsString.Contains("ITS")){
566 /********************* ITS layers ***********************/
567 AliDebugClass(2,"Checking consistency of symbolic names for ITS layers");
568 TString strSPD = "ITS/SPD";
569 TString strSDD = "ITS/SDD";
570 TString strSSD = "ITS/SSD";
571 TString strStave = "/Stave";
572 TString strHalfStave = "/HalfStave";
573 TString strLadder = "/Ladder";
574 TString strSector = "/Sector";
575 TString strSensor = "/Sensor";
576 TString strEntryName1;
577 TString strEntryName2;
578 TString strEntryName3;
580 /********************* SPD layer1 ***********************/
584 for(Int_t cSect = 0; cSect<10; cSect++){
585 strEntryName1 = strSPD;
587 strEntryName1 += strSector;
588 strEntryName1 += cSect;
590 for(Int_t cStave =0; cStave<2; cStave++){
591 strEntryName2 = strEntryName1;
592 strEntryName2 += strStave;
593 strEntryName2 += cStave;
595 for (Int_t cHS=0; cHS<2; cHS++) {
596 strEntryName3 = strEntryName2;
597 strEntryName3 += strHalfStave;
598 strEntryName3 += cHS;
600 for(Int_t cLad =0; cLad<2; cLad++){
601 symname = strEntryName3;
602 symname += strLadder;
603 symname += cLad+cHS*2;
604 uid = LayerToVolUID(kSPD1,modnum++);
605 pne = fgGeometry->GetAlignableEntryByUID(uid);
608 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
611 sname = pne->GetName();
612 if(symname.CompareTo(sname))
614 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
615 "Expected was %s, found was %s!", uid, symname.Data(), sname));
624 /********************* SPD layer2 ***********************/
628 for(Int_t cSect = 0; cSect<10; cSect++){
629 strEntryName1 = strSPD;
631 strEntryName1 += strSector;
632 strEntryName1 += cSect;
634 for(Int_t cStave =0; cStave<4; cStave++){
635 strEntryName2 = strEntryName1;
636 strEntryName2 += strStave;
637 strEntryName2 += cStave;
639 for (Int_t cHS=0; cHS<2; cHS++) {
640 strEntryName3 = strEntryName2;
641 strEntryName3 += strHalfStave;
642 strEntryName3 += cHS;
644 for(Int_t cLad =0; cLad<2; cLad++){
645 symname = strEntryName3;
646 symname += strLadder;
647 symname += cLad+cHS*2;
648 uid = LayerToVolUID(kSPD2,modnum++);
649 pne = fgGeometry->GetAlignableEntryByUID(uid);
652 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
655 sname = pne->GetName();
656 if(symname.CompareTo(sname))
658 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
659 "Expected was %s, found was %s!", uid, symname.Data(), sname));
668 /********************* SDD layer1 ***********************/
672 for(Int_t c1 = 1; c1<=14; c1++){
673 strEntryName1 = strSDD;
675 strEntryName1 +=strLadder;
676 strEntryName1 += (c1-1);
677 for(Int_t c2 =1; c2<=6; c2++){
678 symname = strEntryName1;
679 symname += strSensor;
681 uid = LayerToVolUID(kSDD1,modnum++);
682 pne = fgGeometry->GetAlignableEntryByUID(uid);
685 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
688 sname = pne->GetName();
689 if(symname.CompareTo(sname))
691 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
692 "Expected was %s, found was %s!", uid, symname.Data(), sname));
699 /********************* SDD layer2 ***********************/
703 for(Int_t c1 = 1; c1<=22; c1++){
704 strEntryName1 = strSDD;
706 strEntryName1 +=strLadder;
707 strEntryName1 += (c1-1);
708 for(Int_t c2 = 1; c2<=8; c2++){
709 symname = strEntryName1;
710 symname += strSensor;
712 uid = LayerToVolUID(kSDD2,modnum++);
713 pne = fgGeometry->GetAlignableEntryByUID(uid);
716 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
719 sname = pne->GetName();
720 if(symname.CompareTo(sname))
722 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
723 "Expected was %s, found was %s!", uid, symname.Data(), sname));
730 /********************* SSD layer1 ***********************/
734 for(Int_t c1 = 1; c1<=34; c1++){
735 strEntryName1 = strSSD;
737 strEntryName1 +=strLadder;
738 strEntryName1 += (c1-1);
739 for(Int_t c2 = 1; c2<=22; c2++){
740 symname = strEntryName1;
741 symname += strSensor;
743 uid = LayerToVolUID(kSSD1,modnum++);
744 pne = fgGeometry->GetAlignableEntryByUID(uid);
747 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
750 sname = pne->GetName();
751 if(symname.CompareTo(sname))
753 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
754 "Expected was %s, found was %s!", uid, symname.Data(), sname));
761 /********************* SSD layer2 ***********************/
765 for(Int_t c1 = 1; c1<=38; c1++){
766 strEntryName1 = strSSD;
768 strEntryName1 +=strLadder;
769 strEntryName1 += (c1-1);
770 for(Int_t c2 = 1; c2<=25; c2++){
771 symname = strEntryName1;
772 symname += strSensor;
774 uid = LayerToVolUID(kSSD2,modnum++);
775 pne = fgGeometry->GetAlignableEntryByUID(uid);
778 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
781 sname = pne->GetName();
782 if(symname.CompareTo(sname))
784 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
785 "Expected was %s, found was %s!", uid, symname.Data(), sname));
792 AliDebugClass(2,"Consistency check for ITS symbolic names finished successfully.");
795 if(detsString.Contains("TPC"))
797 /*************** TPC inner and outer layers ****************/
799 AliDebugClass(2,"Checking consistency of symbolic names for TPC layers");
800 TString sAsector="TPC/EndcapA/Sector";
801 TString sCsector="TPC/EndcapC/Sector";
802 TString sInner="/InnerChamber";
803 TString sOuter="/OuterChamber";
805 /*************** TPC inner chambers' layer ****************/
809 for(Int_t cnt=1; cnt<=18; cnt++)
814 uid = LayerToVolUID(kTPC1,modnum++);
815 pne = fgGeometry->GetAlignableEntryByUID(uid);
818 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
821 sname = pne->GetName();
822 if(symname.CompareTo(sname))
824 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
825 "Expected was %s, found was %s!", uid, symname.Data(), sname));
830 for(Int_t cnt=1; cnt<=18; cnt++)
835 uid = LayerToVolUID(kTPC1,modnum++);
836 pne = fgGeometry->GetAlignableEntryByUID(uid);
839 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
842 sname = pne->GetName();
843 if(symname.CompareTo(sname))
845 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
846 "Expected was %s, found was %s!", uid, symname.Data(), sname));
852 /*************** TPC outer chambers' layer ****************/
856 for(Int_t cnt=1; cnt<=18; cnt++)
861 uid = LayerToVolUID(kTPC2,modnum++);
862 pne = fgGeometry->GetAlignableEntryByUID(uid);
865 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
868 sname = pne->GetName();
869 if(symname.CompareTo(sname))
871 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
872 "Expected was %s, found was %s!", uid, symname.Data(), sname));
877 for(Int_t cnt=1; cnt<=18; cnt++)
882 uid = LayerToVolUID(kTPC2,modnum++);
883 pne = fgGeometry->GetAlignableEntryByUID(uid);
886 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
889 sname = pne->GetName();
890 if(symname.CompareTo(sname))
892 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
893 "Expected was %s, found was %s!", uid, symname.Data(), sname));
899 AliDebugClass(2,"Consistency check for TPC symbolic names finished successfully.");
902 if(detsString.Contains("TOF"))
904 /********************* TOF layer ***********************/
906 AliDebugClass(2,"Checking consistency of symbolic names for TOF layers");
913 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
915 TString snSM = "TOF/sm";
916 TString snSTRIP = "/strip";
918 for (Int_t isect = 0; isect < nSectors; isect++) {
919 for (Int_t istr = 1; istr <= nStrips; istr++) {
921 symname += Form("%02d",isect);
923 symname += Form("%02d",istr);
924 uid = LayerToVolUID(kTOF,modnum++);
925 if(!tofSMs[isect]) continue; // taking possible missing TOF sectors (partial geometry) into account
926 AliDebugClass(2,Form("Consistency check for symnames of TOF supermodule %d.",isect));
927 if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue; //taking holes into account
928 pne = fgGeometry->GetAlignableEntryByUID(uid);
931 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
934 sname = pne->GetName();
935 if(symname.CompareTo(sname))
937 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
938 "Expected was %s, found was %s!", uid, symname.Data(), sname));
944 AliDebugClass(2,"Consistency check for TOF symbolic names finished successfully.");
947 if(detsString.Contains("HMPID"))
949 /********************* HMPID layer ***********************/
951 AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
952 TString str = "/HMPID/Chamber";
954 for (modnum=0; modnum < 7; modnum++) {
957 uid = LayerToVolUID(kHMPID,modnum);
958 pne = fgGeometry->GetAlignableEntryByUID(uid);
961 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
964 sname = pne->GetName();
965 if(symname.CompareTo(sname))
967 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
968 "Expected was %s, found was %s!", uid, symname.Data(), sname));
973 AliDebugClass(2,"Consistency check for HMPID symbolic names finished successfully.");
976 if(detsString.Contains("TRD"))
978 /********************* TRD layers 1-6 *******************/
979 //!! 6 layers with index increasing in outwards direction
981 AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
982 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
984 TString snStr = "TRD/sm";
985 TString snApp1 = "/st";
986 TString snApp2 = "/pl";
988 for(Int_t layer=0; layer<6; layer++){
990 for (Int_t isect = 0; isect < 18; isect++) {
991 for (Int_t icham = 0; icham < 5; icham++) {
993 symname += Form("%02d",isect);
998 uid = LayerToVolUID(arTRDlayId[layer],modnum++);
999 if(!trdSMs[isect]) continue;
1000 AliDebugClass(2,Form("Consistency check for symnames of TRD supermodule %d.",isect));
1001 if ((isect==13 || isect==14 || isect==15) && icham==2) continue; //keeping holes into account
1002 pne = fgGeometry->GetAlignableEntryByUID(uid);
1005 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1008 sname = pne->GetName();
1009 if(symname.CompareTo(sname))
1011 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1012 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1019 AliDebugClass(2,"Consistency check for TRD symbolic names finished successfully.");
1022 if(detsString.Contains("PHOS"))
1024 /********************* PHOS EMC layer ***********************/
1026 AliDebugClass(2,"Checking consistency of symbolic names for PHOS layers");
1028 TString str = "PHOS/Module";
1031 for (Int_t iModule=0; iModule < 5; iModule++) {
1032 if(!phosMods[iModule]) continue;
1034 symname += (iModule+1);
1035 uid = LayerToVolUID(kPHOS1,iModule);
1036 pne = fgGeometry->GetAlignableEntryByUID(uid);
1039 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1042 sname = pne->GetName();
1043 if(symname.CompareTo(sname))
1045 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1046 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1049 /********************* PHOS CPV layer ***********************/
1050 if(!cpvActive) continue;
1052 uid = LayerToVolUID(kPHOS2,iModule);
1053 pne = fgGeometry->GetAlignableEntryByUID(uid);
1056 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1059 sname = pne->GetName();
1060 if(symname.CompareTo(sname))
1062 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1063 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1067 AliDebugClass(2,"Consistency check for PHOS symbolic names finished successfully.");
1070 if(detsString.Contains("EMCAL"))
1072 /********************* EMCAL layer ***********************/
1074 AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
1075 TString str = "EMCAL/FullSupermodule";
1078 for (Int_t iModule=1; iModule <= 12; iModule++) {
1082 symname = "EMCAL/HalfSupermodule";
1083 symname += iModule-10;
1086 uid = LayerToVolUID(kEMCAL,modnum);
1087 pne = fgGeometry->GetAlignableEntryByUID(uid);
1090 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1093 sname = pne->GetName();
1094 if(symname.CompareTo(sname))
1096 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1097 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1102 AliDebugClass(2,"Consistency check for EMCAL symbolic names finished successfully.");
1109 //_____________________________________________________________________________
1110 void AliGeomManager::InitPNEntriesLUT()
1112 // Initialize the look-up table which associates the unique
1113 // numerical identity of each alignable volume to the
1114 // corresponding TGeoPNEntry.
1115 // The LUTs are static; they are created at the creation of the
1116 // AliGeomManager instance and recreated if the geometry has changed
1118 if (fgPNEntry[0]) return;
1121 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
1125 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
1126 fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
1127 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
1128 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
1133 //______________________________________________________________________
1134 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry * const pne)
1136 // Get the global transformation matrix for a given PNEntry
1137 // by quering the TGeoManager
1139 if (!fgGeometry || !fgGeometry->IsClosed()) {
1140 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1144 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
1145 if (pnode) return pnode->GetMatrix();
1147 const char* path = pne->GetTitle();
1148 if (!fgGeometry->cd(path)) {
1149 AliErrorClass(Form("Volume path %s not valid!",path));
1152 return fgGeometry->GetCurrentMatrix();
1155 //______________________________________________________________________
1156 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
1158 // Get the global transformation matrix for a given alignable volume
1159 // identified by its unique ID 'index' by quering the TGeoManager
1161 TGeoPNEntry *pne = GetPNEntry(index);
1162 if (!pne) return NULL;
1164 return GetMatrix(pne);
1167 //______________________________________________________________________
1168 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
1170 // Get the global transformation matrix for a given alignable volume
1171 // identified by its symbolic name 'symname' by quering the TGeoManager
1173 if (!fgGeometry || !fgGeometry->IsClosed()) {
1174 AliErrorClass("No active geometry or geometry not yet closed!");
1178 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
1179 if (!pne) return NULL;
1181 return GetMatrix(pne);
1184 //______________________________________________________________________
1185 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
1187 // Get the translation vector for a given module 'index'
1188 // by quering the TGeoManager
1190 TGeoHMatrix *m = GetMatrix(index);
1191 if (!m) return kFALSE;
1193 Double_t *trans = m->GetTranslation();
1194 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1199 //______________________________________________________________________
1200 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
1202 // Get the rotation matrix for a given module 'index'
1203 // by quering the TGeoManager
1205 TGeoHMatrix *m = GetMatrix(index);
1206 if (!m) return kFALSE;
1208 Double_t *rot = m->GetRotationMatrix();
1209 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1214 //_____________________________________________________________________________
1215 Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
1217 // The method sets the matrix passed as argument as the global delta
1218 // (for the volume referred by the unique index) including the displacements
1219 // of all parent volumes in the branch.
1222 TGeoHMatrix go,invgo;
1223 go = *GetOrigGlobalMatrix(index);
1224 invgo = go.Inverse();
1225 inclusiveD = *GetMatrix(index);
1226 inclusiveD.Multiply(&invgo);
1231 //_____________________________________________________________________________
1232 Bool_t AliGeomManager::GetDeltaForBranch(AliAlignObj& aao, TGeoHMatrix &inclusiveD)
1234 // The method sets the matrix passed as argument as the global delta
1235 // (for the volume referred by the alignment object) including the displacements
1236 // of all parent volumes in the brach.
1238 Int_t index = aao.GetVolUID();
1240 AliErrorClass("Either the alignment object or its index are not valid");
1243 return GetDeltaForBranch(index, inclusiveD);
1246 //______________________________________________________________________
1247 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
1249 // Get the global transformation matrix (ideal geometry) for a given alignable volume
1250 // The alignable volume is identified by 'symname' which has to be either a valid symbolic
1251 // name, the query being performed after alignment, or a valid volume path if the query is
1252 // performed before alignment.
1256 if (!fgGeometry || !fgGeometry->IsClosed()) {
1257 AliErrorClass("No active geometry or geometry not yet closed!");
1260 if (!fgGeometry->GetListOfPhysicalNodes()) {
1261 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
1262 if (!fgGeometry->cd(symname)) {
1263 AliErrorClass(Form("Volume path %s not valid!",symname));
1267 m = *fgGeometry->GetCurrentMatrix();
1272 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
1273 const char* path = NULL;
1275 m = *pne->GetGlobalOrig();
1278 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
1282 return GetOrigGlobalMatrixFromPath(path,m);
1285 //_____________________________________________________________________________
1286 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
1288 // The method returns the global matrix for the volume identified by
1289 // 'path' in the ideal detector geometry.
1290 // The output global matrix is stored in 'm'.
1291 // Returns kFALSE in case TGeo has not been initialized or the volume
1292 // path is not valid.
1296 if (!fgGeometry || !fgGeometry->IsClosed()) {
1297 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
1301 if (!fgGeometry->CheckPath(path)) {
1302 AliErrorClass(Form("Volume path %s not valid!",path));
1306 TIter next(fgGeometry->GetListOfPhysicalNodes());
1307 fgGeometry->cd(path);
1309 while(fgGeometry->GetLevel()){
1311 TGeoPhysicalNode *physNode = NULL;
1313 TGeoNode *node = fgGeometry->GetCurrentNode();
1314 while ((physNode=(TGeoPhysicalNode*)next()))
1315 if (physNode->GetNode() == node) break;
1317 TGeoMatrix *lm = NULL;
1319 lm = physNode->GetOriginalMatrix();
1320 if (!lm) lm = node->GetMatrix();
1322 lm = node->GetMatrix();
1332 //_____________________________________________________________________________
1333 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry * const pne)
1335 // The method returns global matrix for the ideal detector geometry
1336 // using the corresponding TGeoPNEntry as an input.
1337 // The returned pointer should be copied by the user, since its content could
1338 // be overwritten by a following call to the method.
1339 // In case of missing TGeoManager the method returns NULL.
1341 if (!fgGeometry || !fgGeometry->IsClosed()) {
1342 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1346 return pne->GetGlobalOrig();
1349 //______________________________________________________________________
1350 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
1352 // The method returns global matrix from the ideal detector geometry
1353 // for the volume identified by its index.
1354 // The returned pointer should be copied by the user, since its content could
1355 // be overwritten by a following call to the method.
1356 // In case of missing TGeoManager the method returns NULL.
1357 // If possible, the method uses the LUT of original ideal matrices
1358 // for fast access. The LUT is reset in case a
1359 // new geometry is loaded.
1361 TGeoPNEntry* pne = GetPNEntry(index);
1362 return pne->GetGlobalOrig();
1365 //______________________________________________________________________
1366 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1368 // Get the original translation vector (ideal geometry)
1369 // for a given module 'index' by quering the TGeoManager
1371 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1372 if (!m) return kFALSE;
1374 Double_t *trans = m->GetTranslation();
1375 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1380 //______________________________________________________________________
1381 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1383 // Get the original rotation matrix (ideal geometry)
1384 // for a given module 'index' by quering the TGeoManager
1386 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1387 if (!m) return kFALSE;
1389 Double_t *rot = m->GetRotationMatrix();
1390 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1395 //______________________________________________________________________
1396 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1398 // Get the matrix which transforms from the tracking to the local RS
1399 // The method queries directly the TGeoPNEntry
1401 TGeoPNEntry *pne = GetPNEntry(index);
1402 if (!pne) return NULL;
1404 const TGeoHMatrix *m = pne->GetMatrix();
1406 AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
1411 //______________________________________________________________________
1412 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1414 // Get the matrix which transforms from the tracking r.s. to
1416 // Returns kFALSE in case of error.
1420 TGeoHMatrix *m1 = GetMatrix(index);
1421 if (!m1) return kFALSE;
1423 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1424 if (!m2) return kFALSE;
1432 //_____________________________________________________________________________
1433 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1434 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1437 ELayerID layerId = VolUIDToLayer(voluid,modId);
1438 return GetPNEntry(layerId,modId);
1441 //_____________________________________________________________________________
1442 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1444 // Returns the TGeoPNEntry for a given layer
1448 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1449 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1453 return fgPNEntry[layerId-kFirstLayer][modId];
1456 //_____________________________________________________________________________
1457 void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
1459 // Check for overlaps/extrusions on physical nodes only;
1460 // this overlap-checker is meant to be used to check overlaps/extrusions
1461 // originated by the application of alignment objects.
1464 TObjArray* ovexlist = new TObjArray(64);
1466 AliInfoClass("********* Checking overlaps/extrusions over physical nodes only *********");
1467 TObjArray* pnList = gGeoManager->GetListOfPhysicalNodes();
1468 TGeoVolume* mvol = 0;
1469 TGeoPhysicalNode* pn;
1470 TObjArray* overlaps = new TObjArray(64);
1471 overlaps->SetOwner();
1475 for(Int_t pni=0; pni<pnList->GetEntriesFast(); pni++){
1476 pn = (TGeoPhysicalNode*) pnList->UncheckedAt(pni);
1477 // checking the volume of the mother (go upper in the tree in case it is an assembly)
1479 while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
1480 //Printf("Going to upper level");
1481 mvol = pn->GetVolume(pn->GetLevel()-levup);
1482 if(!mvol->IsSelected()){
1483 AliInfoClass(Form("Checking overlaps for volume %s",mvol->GetName()));
1484 mvol->CheckOverlaps(threshold);
1485 ovexlist = gGeoManager->GetListOfOverlaps();
1486 TIter next(ovexlist);
1488 while ((ov=(TGeoOverlap*)next())) overlaps->Add(ov->Clone());
1489 mvol->SelectVolume();
1492 mvol->SelectVolume(kTRUE); // clears the list of selected volumes
1494 AliInfoClass(Form("Number of overlapping/extruding PNs: %d",overlaps->GetEntriesFast()));
1498 TIter nextN(overlaps);
1500 while ((ovlp=(TGeoOverlap*)nextN())) ovlp->PrintInfo();
1506 //_____________________________________________________________________________
1507 Int_t AliGeomManager::GetNalignable(const char* module)
1509 // Get number of declared alignable volumes for given detector in current geometry
1512 // return the detector index corresponding to detector
1514 for (index = 0; index < fgkNDetectors ; index++) {
1515 if ( strcmp(module, fgkDetectorName[index]) == 0 )
1518 return fgNalignable[index];
1521 //_____________________________________________________________________________
1522 void AliGeomManager::InitNalignable()
1524 // Set number of declared alignable volumes for given detector in current geometry
1525 // by looping on the list of PNEntries
1528 Int_t nAlE = gGeoManager->GetNAlignable(); // total number of alignable entries
1529 TGeoPNEntry *pne = 0;
1530 TString *pneName = 0;
1531 const char* detName;
1533 for (Int_t iDet = 0; iDet < fgkNDetectors ; iDet++) {
1534 detName = fgkDetectorName[iDet];
1537 for(Int_t iE = 0; iE < nAlE; iE++)
1539 pne = gGeoManager->GetAlignableEntry(iE);
1540 pneName = new TString(pne->GetName());
1541 if(pneName->Contains(detName)) nAlDet++;
1542 if(!strcmp(detName,"GRP")) if(pneName->Contains("ABSO") || pneName->Contains("DIPO") || pneName->Contains("FRAME") || pneName->Contains("PIPE") || pneName->Contains("SHIL")) nAlDet++;
1544 fgNalignable[iDet] = nAlDet;
1549 //_____________________________________________________________________________
1550 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1552 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1553 // the list passed as argument (called by AliSimulation and
1554 // AliReconstruction)
1555 // Read the alignment objects from CDB.
1556 // Each detector is supposed to have the
1557 // alignment objects in DET/Align/Data CDB path.
1558 // All the detector objects are then collected,
1559 // sorted by geometry level (starting from ALIC) and
1560 // then applied to the TGeo geometry.
1561 // Finally an overlaps check is performed.
1564 TObjArray alignObjArray;
1565 alignObjArray.Clear();
1566 alignObjArray.SetOwner(0);
1568 TString alObjsNotLoaded="";
1569 TString alObjsLoaded="";
1571 TString AlignDetsString(AlignDetsList);
1572 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1573 TIter iter(detsarr);
1574 TObjString *str = 0;
1576 while((str = (TObjString*) iter.Next())){
1577 TString det(str->String());
1578 AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1579 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
1580 alObjsNotLoaded += det.Data();
1581 alObjsNotLoaded += " ";
1583 alObjsLoaded += det.Data();
1584 alObjsLoaded += " ";
1590 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1591 alObjsLoaded.Data()));
1592 if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1593 alObjsNotLoaded.Data()));
1595 return ApplyAlignObjsToGeom(alignObjArray);
1598 //_____________________________________________________________________________
1599 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
1601 // Adds the alignable objects found in the CDBEntry for the detector
1602 // passed as argument to the array of all alignment objects to be applyed
1605 // Fills array of single detector's alignable objects from CDB
1607 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
1611 AliCDBPath path(detName,"Align","Data");
1613 entry=AliCDBManager::Instance()->Get(path.GetPath());
1615 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
1619 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1620 alignArray->SetOwner(0);
1621 Int_t nAlObjs = alignArray->GetEntries();
1622 AliDebugClass(2,Form("Found %d alignment objects for %s",nAlObjs,detName));
1623 Int_t nAlVols = GetNalignable(detName);
1624 if(nAlObjs!=nAlVols) AliWarningClass(Form("%d alignment objects loaded for %s, which has %d alignable volumes",nAlObjs,detName,GetNalignable(detName)));
1626 AliAlignObj *alignObj=0;
1627 TIter iter(alignArray);
1629 // loop over align objects in detector
1630 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1631 alignObjArray.Add(alignObj);
1633 // delete entry --- Don't delete, it is cached!
1635 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
1640 //_____________________________________________________________________________
1641 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
1643 // Read collection of alignment objects (AliAlignObj derived) saved
1644 // in the TClonesArray alObjArray and apply them to gGeoManager
1646 alignObjArray.Sort();
1647 Int_t nvols = alignObjArray.GetEntriesFast();
1649 Bool_t flag = kTRUE;
1651 for(Int_t j=0; j<nvols; j++)
1653 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1654 flag = alobj->ApplyToGeometry(ovlpcheck);
1657 AliDebugClass(5,Form("Error applying alignment object for volume %s !",alobj->GetSymName()));
1659 AliDebugClass(5,Form("Alignment object for volume %s applied successfully",alobj->GetSymName()));
1664 if (AliDebugLevelClass() > 5) {
1665 fgGeometry->CheckOverlaps(0.001);
1666 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
1667 if(ovexlist->GetEntriesFast()){
1668 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1669 fgGeometry->PrintOverlaps();
1673 // Update the TGeoPhysicalNodes
1674 fgGeometry->RefreshPhysicalNodes();
1680 //_____________________________________________________________________________
1681 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1683 // read collection of alignment objects (AliAlignObj derived) saved
1684 // in the TClonesArray ClArrayName in the file fileName and apply
1685 // them to the geometry
1688 TFile* inFile = TFile::Open(fileName,"READ");
1689 if (!inFile || !inFile->IsOpen()) {
1690 AliErrorClass(Form("Could not open file %s !",fileName));
1694 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1696 if (!alignObjArray) {
1697 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1701 return ApplyAlignObjsToGeom(*alignObjArray);
1705 //_____________________________________________________________________________
1706 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1708 // read collection of alignment objects (AliAlignObj derived) saved
1709 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1710 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1714 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1715 AliCDBEntry* entry = storage->Get(Id);
1716 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1718 return ApplyAlignObjsToGeom(*alignObjArray);
1722 //_____________________________________________________________________________
1723 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1725 // read collection of alignment objects (AliAlignObj derived) saved
1726 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1727 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1731 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1732 AliCDBId id(path, runnum, runnum, version, sversion);
1734 return ApplyAlignObjsToGeom(param, id);
1738 //_____________________________________________________________________________
1739 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1741 // read collection of alignment objects (AliAlignObj derived) saved
1742 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1743 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1747 AliCDBPath path(detName,"Align","Data");
1748 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1750 if(!entry) return kFALSE;
1751 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1753 return ApplyAlignObjsToGeom(*alignObjArray);