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 "AliGeomManager.h"
33 #include "AliAlignObj.h"
34 #include "AliAlignObjAngles.h"
35 #include "AliCDBManager.h"
36 #include "AliCDBStorage.h"
37 #include "AliCDBEntry.h"
39 ClassImp(AliGeomManager)
41 Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
42 80, 160, // ITS SPD first and second layer
43 84, 176, // ITS SDD first and second layer
44 748, 950, // ITS SSD first and second layer
45 36, 36, // TPC inner and outer chambers
46 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
53 const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
54 "ITS inner pixels layer", "ITS outer pixels layer",
55 "ITS inner drifts layer", "ITS outer drifts layer",
56 "ITS inner strips layer", "ITS outer strips layer",
57 "TPC inner chambers layer", "TPC outer chambers layer",
58 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
59 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
61 "PHOS EMC layer","PHOS CPV layer",
66 TString* AliGeomManager::fgSymName[kLastLayer - kFirstLayer] = {
79 TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
92 AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
105 AliGeomManager* AliGeomManager::fgInstance = 0x0;
107 TGeoManager* AliGeomManager::fgGeometry = 0x0;
109 //_____________________________________________________________________________
110 AliGeomManager* AliGeomManager::Instance()
112 // returns AliGeomManager instance (singleton)
115 fgInstance = new AliGeomManager();
121 //_____________________________________________________________________________
122 void AliGeomManager::Init()
125 if(!gGeoManager) AliFatal("Impossible to initialize AliGeomManager without an active geometry");
126 fgGeometry = gGeoManager;
131 //_____________________________________________________________________________
132 AliGeomManager::AliGeomManager():
137 // default constructor
140 //_____________________________________________________________________________
141 AliGeomManager::~AliGeomManager()
144 if(fAlignObjArray) fAlignObjArray->Delete();
145 delete fAlignObjArray;
148 //_____________________________________________________________________________
149 Int_t AliGeomManager::LayerSize(Int_t layerId)
151 // Get the layer size for layer corresponding to layerId.
152 // Implemented only for ITS,TPC,TRD,TOF and HMPID
154 if (layerId < kFirstLayer || layerId >= kLastLayer) {
155 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
159 return fgLayerSize[layerId - kFirstLayer];
163 //_____________________________________________________________________________
164 const char* AliGeomManager::LayerName(Int_t layerId)
166 // Get the layer name corresponding to layerId.
167 // Implemented only for ITS,TPC,TRD,TOF and HMPID
169 if (layerId < kFirstLayer || layerId >= kLastLayer) {
170 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
171 return "Invalid Layer!";
174 return fgLayerName[layerId - kFirstLayer];
178 //_____________________________________________________________________________
179 UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
181 // From detector (layer) name and module number (according to detector
182 // internal numbering) build the unique numerical identity of that volume
184 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
185 // remaining 11 for module ID inside det (2048 possible values).
186 // NO check for validity of given modId inside the layer for speed's sake.
188 return ((UShort_t(layerId) << 11) | UShort_t(modId));
191 //_____________________________________________________________________________
192 UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
194 // From detector (layer) name and module number (according to detector
195 // internal numbering) build the unique numerical identity of that volume
197 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
198 // remaining 11 for module ID inside det (2048 possible values).
199 // NO check for validity of given modId inside the layer for speed's sake.
201 return ((UShort_t(layerId) << 11) | UShort_t(modId));
204 //_____________________________________________________________________________
205 UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
207 // From detector (layer) name and module number (according to detector
208 // internal numbering) build the unique numerical identity of that volume
210 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
211 // remaining 11 for module ID inside det (2048 possible values).
212 // Check validity of given modId inside the layer.
214 if(modId < 0 || modId >= LayerSize(layerId)){
215 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
218 return ((UShort_t(layerId) << 11) | UShort_t(modId));
221 //_____________________________________________________________________________
222 UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
224 // From detector (layer) name and module number (according to detector
225 // internal numbering) build the unique numerical identity of that volume
227 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
228 // remaining 11 for module ID inside det (2048 possible values).
229 // Check validity of given modId inside the layer.
231 if(modId < 0 || modId >= LayerSize(layerId)){
232 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
235 return ((UShort_t(layerId) << 11) | UShort_t(modId));
238 //_____________________________________________________________________________
239 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
241 // From voluid, unique numerical identity of that volume inside ALICE,
242 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
243 // remaining 11 for module ID inside det (2048 possible values)), return
244 // the identity of the layer to which that volume belongs and sets the
245 // argument modId to the identity of that volume internally to the layer.
246 // NO check for validity of given voluid for speed's sake.
248 modId = voluid & 0x7ff;
250 return VolUIDToLayer(voluid);
253 //_____________________________________________________________________________
254 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
256 // From voluid, unique numerical identity of that volume inside ALICE,
257 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
258 // remaining 11 for module ID inside det (2048 possible values)), return
259 // the identity of the layer to which that volume belongs
260 // NO check for validity of given voluid for speed's sake.
262 return ELayerID(voluid >> 11);
265 //_____________________________________________________________________________
266 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
268 // From voluid, unique numerical identity of that volume inside ALICE,
269 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
270 // remaining 11 for module ID inside det (2048 possible values)), returns
271 // the identity of the layer to which that volume belongs and sets the
272 // argument modId to the identity of that volume internally to the layer.
273 // Checks the validity of the given voluid
275 ELayerID layId = VolUIDToLayerSafe(voluid);
277 Int_t mId = Int_t(voluid & 0x7ff);
278 if( mId>=0 && mId<LayerSize(layId)){
284 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
286 return kInvalidLayer;
290 //_____________________________________________________________________________
291 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
293 // From voluid, unique numerical identity of that volume inside ALICE,
294 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
295 // remaining 11 for module ID inside det (2048 possible values)), returns
296 // the identity of the layer to which that volume belongs
297 // Checks the validity of the given voluid
299 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
301 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
302 return kInvalidLayer;
306 //_____________________________________________________________________________
307 Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
309 // Get the alignment object which corresponds to the symbolic volume name
310 // symname (in case equal to the TGeo volume path)
311 // The method is extremely slow due to the searching by string,
312 // therefore it should be used with great care!!
313 // This method returns FALSE if the symname of the object was not
314 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
315 // associated to the TGeoPNEntry was not valid.
318 // Reset the alignment object
319 alobj.SetPars(0,0,0,0,0,0);
320 alobj.SetSymName(symname);
322 if (!gGeoManager || !gGeoManager->IsClosed()) {
323 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
327 if (!gGeoManager->GetListOfPhysicalNodes()) {
328 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
333 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
335 path = pne->GetTitle();
337 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
340 TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
341 TGeoPhysicalNode* node = NULL;
342 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
343 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
344 const char *nodePath = tempNode->GetName();
345 if (strcmp(path,nodePath) == 0) {
352 if (!gGeoManager->cd(path)) {
353 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
357 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
362 TGeoHMatrix align,gprime,g,ginv,l;
363 gprime = *node->GetMatrix();
364 l = *node->GetOriginalMatrix();
365 g = *node->GetMatrix(node->GetLevel()-1);
368 align = gprime * ginv;
370 return alobj.SetMatrix(align);
374 //_____________________________________________________________________________
375 void AliGeomManager::InitAlignObjFromGeometry()
377 // Loop over all alignable volumes and extract
378 // the corresponding alignment objects from
381 if(fgAlignObjs[0]) return;
383 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
384 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
385 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
386 UShort_t volid = LayerToVolUID(iLayer,iModule);
387 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
388 const char *symname = SymName(volid);
389 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
390 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
396 //_____________________________________________________________________________
397 AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
398 // Returns the alignment object for given volume ID
401 ELayerID layerId = VolUIDToLayer(voluid,modId);
402 return GetAlignObj(layerId,modId);
405 //_____________________________________________________________________________
406 AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
408 // Returns pointer to alignment object given its layer and module ID
410 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
411 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
414 InitAlignObjFromGeometry();
416 return fgAlignObjs[layerId-kFirstLayer][modId];
419 //_____________________________________________________________________________
420 const char* AliGeomManager::SymName(UShort_t voluid) {
421 // Returns the symbolic volume name for given volume ID
424 ELayerID layerId = VolUIDToLayer(voluid,modId);
425 return SymName(layerId,modId);
428 //_____________________________________________________________________________
429 const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
431 // Returns the symbolic volume name given for a given layer
434 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
435 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
440 return fgSymName[layerId-kFirstLayer][modId].Data();
443 //_____________________________________________________________________________
444 void AliGeomManager::InitSymNamesLUT()
446 // Initialize the look-up table which associates the unique
447 // numerical identity of each alignable volume to the
448 // corresponding symbolic volume name
449 // The LUTs are static; they are created at the creation of the
450 // AliGeomManager instance and recreated if the geometry has changed
453 if(fgSymName[0]) return;
455 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
456 if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
460 Int_t modnum; // in the following, set it to 0 at the start of each layer
462 /********************* ITS layers ***********************/
463 TString strSPD = "ITS/SPD";
464 TString strSDD = "ITS/SDD";
465 TString strSSD = "ITS/SSD";
466 TString strStave = "/Stave";
467 TString strLadder = "/Ladder";
468 TString strSector = "/Sector";
469 TString strSensor = "/Sensor";
470 TString strEntryName1;
471 TString strEntryName2;
474 /********************* SPD layer1 ***********************/
478 for(Int_t c1 = 1; c1<=10; c1++){
479 strEntryName1 = strSPD;
481 strEntryName1 += strSector;
482 strEntryName1 += (c1-1);
483 for(Int_t c2 =1; c2<=2; c2++){
484 strEntryName2 = strEntryName1;
485 strEntryName2 += strStave;
486 strEntryName2 += (c2-1);
487 for(Int_t c3 =1; c3<=4; c3++){
488 symname = strEntryName2;
489 symname += strLadder;
491 fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
498 /********************* SPD layer2 ***********************/
502 for(Int_t c1 = 1; c1<=10; c1++){
503 strEntryName1 = strSPD;
505 strEntryName1 += strSector;
506 strEntryName1 += (c1-1);
507 for(Int_t c2 =1; c2<=4; c2++){
508 strEntryName2 = strEntryName1;
509 strEntryName2 += strStave;
510 strEntryName2 += (c2-1);
511 for(Int_t c3 =1; c3<=4; c3++){
512 symname = strEntryName2;
513 symname += strLadder;
515 fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
522 /********************* SDD layer1 ***********************/
526 for(Int_t c1 = 1; c1<=14; c1++){
527 strEntryName1 = strSDD;
529 strEntryName1 +=strLadder;
530 strEntryName1 += (c1-1);
531 for(Int_t c2 =1; c2<=6; c2++){
532 symname = strEntryName1;
533 symname += strSensor;
535 fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
541 /********************* SDD layer2 ***********************/
545 for(Int_t c1 = 1; c1<=22; c1++){
546 strEntryName1 = strSDD;
548 strEntryName1 +=strLadder;
549 strEntryName1 += (c1-1);
550 for(Int_t c2 = 1; c2<=8; c2++){
551 symname = strEntryName1;
552 symname += strSensor;
554 fgSymName[kSDD2-kFirstLayer][modnum] = symname.Data();
560 /********************* SSD layer1 ***********************/
564 for(Int_t c1 = 1; c1<=34; c1++){
565 strEntryName1 = strSSD;
567 strEntryName1 +=strLadder;
568 strEntryName1 += (c1-1);
569 for(Int_t c2 = 1; c2<=22; c2++){
570 symname = strEntryName1;
571 symname += strSensor;
573 fgSymName[kSSD1-kFirstLayer][modnum] = symname.Data();
579 /********************* SSD layer2 ***********************/
583 for(Int_t c1 = 1; c1<=38; c1++){
584 strEntryName1 = strSSD;
586 strEntryName1 +=strLadder;
587 strEntryName1 += (c1-1);
588 for(Int_t c2 = 1; c2<=25; c2++){
589 symname = strEntryName1;
590 symname += strSensor;
592 fgSymName[kSSD2-kFirstLayer][modnum] = symname.Data();
599 /*************** TPC inner and outer layers ****************/
600 TString sAsector="TPC/EndcapA/Sector";
601 TString sCsector="TPC/EndcapC/Sector";
602 TString sInner="/InnerChamber";
603 TString sOuter="/OuterChamber";
605 /*************** TPC inner chambers' layer ****************/
609 for(Int_t cnt=1; cnt<=18; cnt++){
613 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
616 for(Int_t cnt=1; cnt<=18; cnt++){
620 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
625 /*************** TPC outer chambers' layer ****************/
629 for(Int_t cnt=1; cnt<=18; cnt++){
633 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
636 for(Int_t cnt=1; cnt<=18; cnt++){
640 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
645 /********************* TOF layer ***********************/
653 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
655 TString snSM = "TOF/sm";
656 TString snSTRIP = "/strip";
658 for (Int_t isect = 0; isect < nSectors; isect++) {
659 for (Int_t istr = 1; istr <= nStrips; istr++) {
661 symname += Form("%02d",isect);
663 symname += Form("%02d",istr);
664 fgSymName[kTOF-kFirstLayer][modnum] = symname.Data();
670 /********************* HMPID layer ***********************/
672 TString str = "/HMPID/Chamber";
674 for (modnum=0; modnum < 7; modnum++) {
677 fgSymName[kHMPID-kFirstLayer][modnum] = symname.Data();
681 /********************* TRD layers 1-6 *******************/
682 //!! 6 layers with index increasing in outwards direction
684 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
686 TString snStr = "TRD/sm";
687 TString snApp1 = "/st";
688 TString snApp2 = "/pl";
690 for(Int_t layer=0; layer<6; layer++){
692 for (Int_t isect = 0; isect < 18; isect++) {
693 for (Int_t icham = 0; icham < 5; icham++) {
695 symname += Form("%02d",isect);
700 fgSymName[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();
707 /********************* PHOS EMC layer ***********************/
709 TString str = "PHOS/Module";
712 for (Int_t iModule=1; iModule <= 5; iModule++) {
716 fgSymName[kPHOS1-kFirstLayer][modnum] = symname.Data();
722 //_____________________________________________________________________________
723 void AliGeomManager::InitPNEntriesLUT()
725 // Initialize the look-up table which associates the unique
726 // numerical identity of each alignable volume to the
727 // corresponding TGeoPNEntry.
728 // The LUTs are static; they are created at the creation of the
729 // AliGeomManager instance and recreated if the geometry has changed
732 if(!gGeoManager) AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
736 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
737 if(!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
740 for (Int_t iLayer = 0; iLayer < (kLastLayer-kFirstLayer); iLayer++){
741 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
742 fgPNEntry[iLayer][modnum] = gGeoManager->GetAlignableEntry(fgSymName[iLayer][modnum].Data());
747 //______________________________________________________________________
748 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
750 // Get the transformation matrix for a given PNEntry
751 // by quering the TGeoManager
753 if (!gGeoManager || !gGeoManager->IsClosed()) {
754 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
758 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
759 if (pnode) return pnode->GetMatrix();
761 const char* path = pne->GetTitle();
762 if (!gGeoManager->cd(path)) {
763 AliErrorClass(Form("Volume path %s not valid!",path));
766 return gGeoManager->GetCurrentMatrix();
769 //______________________________________________________________________
770 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
772 // Get the global transformation matrix for a given alignable volume
773 // identified by its unique ID 'index' by quering the TGeoManager
775 TGeoPNEntry *pne = GetPNEntry(index);
776 if (!pne) return NULL;
778 return GetMatrix(pne);
781 //______________________________________________________________________
782 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
784 // Get the global transformation matrix for a given alignable volume
785 // identified by its symbolic name 'symname' by quering the TGeoManager
787 if(!ReactIfChangedGeom()) return NULL;
788 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
789 if (!pne) return NULL;
791 return GetMatrix(pne);
794 //______________________________________________________________________
795 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
797 // Get the translation vector for a given module 'index'
798 // by quering the TGeoManager
800 TGeoHMatrix *m = GetMatrix(index);
801 if (!m) return kFALSE;
803 Double_t *trans = m->GetTranslation();
804 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
809 //______________________________________________________________________
810 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
812 // Get the rotation matrix for a given module 'index'
813 // by quering the TGeoManager
815 TGeoHMatrix *m = GetMatrix(index);
816 if (!m) return kFALSE;
818 Double_t *rot = m->GetRotationMatrix();
819 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
824 //_____________________________________________________________________________
825 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char *symname, TGeoHMatrix &m)
827 // The method returns global matrix for the ideal detector geometry
828 // Symname identifies either the corresponding TGeoPNEntry or directly
829 // the volume path. The output global matrix is stored in 'm'.
830 // Returns kFALSE in case TGeo has not been initialized or the symname
834 if (!gGeoManager || !gGeoManager->IsClosed()) {
835 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
839 if (!gGeoManager->GetListOfPhysicalNodes()) {
840 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
841 if (!gGeoManager->cd(symname)) {
842 AliErrorClass(Form("Volume path %s not valid!",symname));
846 m = *gGeoManager->GetCurrentMatrix();
851 const char* path = NULL;
852 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
854 path = pne->GetTitle();
856 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
860 if (!gGeoManager->CheckPath(path)) {
861 AliErrorClass(Form("Volume path %s not valid!",path));
867 TIter next(gGeoManager->GetListOfPhysicalNodes());
868 gGeoManager->cd(path);
870 while(gGeoManager->GetLevel()){
872 TGeoPhysicalNode *physNode = NULL;
874 TGeoNode *node = gGeoManager->GetCurrentNode();
875 while ((physNode=(TGeoPhysicalNode*)next()))
876 if (physNode->GetNode() == node) break;
878 TGeoMatrix *lm = NULL;
880 lm = physNode->GetOriginalMatrix();
881 if (!lm) lm = node->GetMatrix();
883 lm = node->GetMatrix();
893 //______________________________________________________________________
894 Bool_t AliGeomManager::GetOrigGlobalMatrix(Int_t index, TGeoHMatrix &m)
896 // Get the original (ideal geometry) TGeo matrix for
897 // a given module identified by 'index'.
898 // The method is slow, so it should be used
903 const char *symname = SymName(index);
904 if (!symname) return kFALSE;
906 return GetOrigGlobalMatrix(symname,m);
909 //______________________________________________________________________
910 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
912 // Get the original translation vector (ideal geometry)
913 // for a given module 'index' by quering the TGeoManager
916 if (!GetOrigGlobalMatrix(index,m)) return kFALSE;
918 Double_t *trans = m.GetTranslation();
919 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
924 //______________________________________________________________________
925 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
927 // Get the original rotation matrix (ideal geometry)
928 // for a given module 'index' by quering the TGeoManager
931 if (!GetOrigGlobalMatrix(index,m)) return kFALSE;
933 Double_t *rot = m.GetRotationMatrix();
934 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
939 //______________________________________________________________________
940 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
942 // Get the matrix which transforms from the tracking to the local RS
943 // The method queries directly the TGeoPNEntry
945 TGeoPNEntry *pne = GetPNEntry(index);
946 if (!pne) return NULL;
948 const TGeoHMatrix *m = pne->GetMatrix();
950 AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
955 //______________________________________________________________________
956 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
958 // Get the matrix which transforms from the tracking r.s. to
960 // Returns kFALSE in case of error.
964 TGeoHMatrix *m1 = GetMatrix(index);
965 if (!m1) return kFALSE;
967 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
968 if (!m2) return kFALSE;
976 //_____________________________________________________________________________
977 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
978 // Returns the TGeoPNEntry for the given global volume ID "voluid"
981 ELayerID layerId = VolUIDToLayer(voluid,modId);
982 return GetPNEntry(layerId,modId);
985 //_____________________________________________________________________________
986 TGeoPNEntry* AliGeomManager::GetPNEntry(UShort_t voluid) {
987 // Returns the TGeoPNEntry for the given global volume ID "voluid"
990 ELayerID layerId = VolUIDToLayer(voluid,modId);
991 return GetPNEntry(layerId,modId);
994 //_____________________________________________________________________________
995 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
997 // Returns the TGeoPNEntry for a given layer
1001 if(!fgPNEntry[0]) InitPNEntriesLUT();
1002 if(!ReactIfChangedGeom()) return NULL;
1004 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1005 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1009 return fgPNEntry[layerId-kFirstLayer][modId];
1012 //_____________________________________________________________________________
1013 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1015 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1016 // the list passed as argument (called by AliSimulation and
1017 // AliReconstruction)
1018 // Read the alignment objects from CDB.
1019 // Each detector is supposed to have the
1020 // alignment objects in DET/Align/Data CDB path.
1021 // All the detector objects are then collected,
1022 // sorted by geometry level (starting from ALIC) and
1023 // then applied to the TGeo geometry.
1024 // Finally an overlaps check is performed.
1027 if(!fAlignObjArray) fAlignObjArray = new TObjArray();
1028 fAlignObjArray->Clear();
1029 fAlignObjArray->SetOwner(0);
1031 TString alObjsNotLoaded="";
1032 TString alObjsLoaded="";
1034 TString AlignDetsString(AlignDetsList);
1035 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1036 TIter iter(detsarr);
1037 TObjString *str = 0;
1039 while((str = (TObjString*) iter.Next())){
1040 TString det(str->String());
1041 AliInfo(Form("Loading alignment objs for %s",det.Data()));
1042 if(!LoadAlignObjsFromCDBSingleDet(det.Data())){
1043 alObjsNotLoaded += det.Data();
1044 alObjsNotLoaded += " ";
1046 alObjsLoaded += det.Data();
1047 alObjsLoaded += " ";
1051 if(!alObjsLoaded.IsNull()) AliInfo(Form("Alignment objects loaded for: %s",
1052 alObjsLoaded.Data()));
1053 if(!alObjsNotLoaded.IsNull()) AliInfo(Form("Didn't/couldn't load alignment objects for: %s",
1054 alObjsNotLoaded.Data()));
1056 return(ApplyAlignObjsToGeom(fAlignObjArray));
1059 //_____________________________________________________________________________
1060 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName)
1062 // Adds the alignable objects found in the CDBEntry for the detector
1063 // passed as argument to the array of all alignment objects to be applyed
1066 // Fills array of single detector's alignable objects from CDB
1068 AliDebug(2, Form("Loading alignment objs for detector: %s",detName));
1072 AliCDBPath path(detName,"Align","Data");
1074 entry=AliCDBManager::Instance()->Get(path.GetPath());
1076 AliDebug(2,Form("Couldn't load alignment data for detector %s",detName));
1080 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1081 alignArray->SetOwner(0);
1082 AliDebug(2,Form("Found %d alignment objects for %s",
1083 alignArray->GetEntries(),detName));
1085 AliAlignObj *alignObj=0;
1086 TIter iter(alignArray);
1088 // loop over align objects in detector
1089 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1090 fAlignObjArray->Add(alignObj);
1092 // delete entry --- Don't delete, it is cached!
1094 AliDebug(2, Form("fAlignObjArray entries: %d",fAlignObjArray->GetEntries() ));
1099 //_____________________________________________________________________________
1100 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray* alObjArray)
1102 // Read collection of alignment objects (AliAlignObj derived) saved
1103 // in the TClonesArray alObjArray and apply them to gGeoManager
1105 ReactIfChangedGeom();
1108 Int_t nvols = alObjArray->GetEntriesFast();
1110 Bool_t flag = kTRUE;
1112 for(Int_t j=0; j<nvols; j++)
1114 AliAlignObj* alobj = (AliAlignObj*) alObjArray->UncheckedAt(j);
1115 if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
1118 if (AliDebugLevelClass() >= 1) {
1119 gGeoManager->GetTopNode()->CheckOverlaps(1);
1120 TObjArray* ovexlist = gGeoManager->GetListOfOverlaps();
1121 if(ovexlist->GetEntriesFast()){
1122 AliError("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1130 //_____________________________________________________________________________
1131 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1133 // read collection of alignment objects (AliAlignObj derived) saved
1134 // in the TClonesArray ClArrayName in the file fileName and apply
1135 // them to the geometry
1138 TFile* inFile = TFile::Open(fileName,"READ");
1139 if (!inFile || !inFile->IsOpen()) {
1140 AliErrorClass(Form("Could not open file %s !",fileName));
1144 TClonesArray* alObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1147 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1151 return ApplyAlignObjsToGeom(alObjArray);
1155 //_____________________________________________________________________________
1156 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1158 // read collection of alignment objects (AliAlignObj derived) saved
1159 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1160 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1164 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1165 AliCDBEntry* entry = storage->Get(Id);
1166 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
1168 return ApplyAlignObjsToGeom(AlObjArray);
1172 //_____________________________________________________________________________
1173 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1175 // read collection of alignment objects (AliAlignObj derived) saved
1176 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1177 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1181 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1182 AliCDBId id(path, runnum, runnum, version, sversion);
1184 return ApplyAlignObjsToGeom(param, id);
1188 //_____________________________________________________________________________
1189 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1191 // read collection of alignment objects (AliAlignObj derived) saved
1192 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1193 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1197 AliCDBPath path(detName,"Align","Data");
1198 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1200 if(!entry) return kFALSE;
1201 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
1203 return ApplyAlignObjsToGeom(AlObjArray);
1206 //_____________________________________________________________________________
1207 Bool_t AliGeomManager::ReactIfChangedGeom()
1209 // Check if the TGeo geometry has changed. In that case reinitialize the
1210 // look-up table mapping volume indexes to TGeoPNEntries
1213 if (!gGeoManager || !gGeoManager->IsClosed()) {
1214 AliErrorClass("No active geometry or geometry not yet closed!");
1218 if(HasGeomChanged())
1220 fgGeometry = gGeoManager;