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();
720 /********************* PHOS CPV layer ***********************/
722 TString str = "PHOS/Module";
725 for (Int_t iModule=1; iModule <= 5; iModule++) {
730 fgSymName[kPHOS2-kFirstLayer][modnum] = symname.Data();
737 //_____________________________________________________________________________
738 void AliGeomManager::InitPNEntriesLUT()
740 // Initialize the look-up table which associates the unique
741 // numerical identity of each alignable volume to the
742 // corresponding TGeoPNEntry.
743 // The LUTs are static; they are created at the creation of the
744 // AliGeomManager instance and recreated if the geometry has changed
747 if(!gGeoManager) AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
751 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
752 if(!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
755 for (Int_t iLayer = 0; iLayer < (kLastLayer-kFirstLayer); iLayer++){
756 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
757 fgPNEntry[iLayer][modnum] = gGeoManager->GetAlignableEntry(fgSymName[iLayer][modnum].Data());
762 //______________________________________________________________________
763 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
765 // Get the transformation matrix for a given PNEntry
766 // by quering the TGeoManager
768 if (!gGeoManager || !gGeoManager->IsClosed()) {
769 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
773 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
774 if (pnode) return pnode->GetMatrix();
776 const char* path = pne->GetTitle();
777 if (!gGeoManager->cd(path)) {
778 AliErrorClass(Form("Volume path %s not valid!",path));
781 return gGeoManager->GetCurrentMatrix();
784 //______________________________________________________________________
785 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
787 // Get the global transformation matrix for a given alignable volume
788 // identified by its unique ID 'index' by quering the TGeoManager
790 TGeoPNEntry *pne = GetPNEntry(index);
791 if (!pne) return NULL;
793 return GetMatrix(pne);
796 //______________________________________________________________________
797 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
799 // Get the global transformation matrix for a given alignable volume
800 // identified by its symbolic name 'symname' by quering the TGeoManager
802 if(!ReactIfChangedGeom()) return NULL;
803 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
804 if (!pne) return NULL;
806 return GetMatrix(pne);
809 //______________________________________________________________________
810 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
812 // Get the translation vector for a given module 'index'
813 // by quering the TGeoManager
815 TGeoHMatrix *m = GetMatrix(index);
816 if (!m) return kFALSE;
818 Double_t *trans = m->GetTranslation();
819 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
824 //______________________________________________________________________
825 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
827 // Get the rotation matrix for a given module 'index'
828 // by quering the TGeoManager
830 TGeoHMatrix *m = GetMatrix(index);
831 if (!m) return kFALSE;
833 Double_t *rot = m->GetRotationMatrix();
834 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
839 //_____________________________________________________________________________
840 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char *symname, TGeoHMatrix &m)
842 // The method returns global matrix for the ideal detector geometry
843 // Symname identifies either the corresponding TGeoPNEntry or directly
844 // the volume path. The output global matrix is stored in 'm'.
845 // Returns kFALSE in case TGeo has not been initialized or the symname
849 if (!gGeoManager || !gGeoManager->IsClosed()) {
850 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
854 if (!gGeoManager->GetListOfPhysicalNodes()) {
855 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
856 if (!gGeoManager->cd(symname)) {
857 AliErrorClass(Form("Volume path %s not valid!",symname));
861 m = *gGeoManager->GetCurrentMatrix();
866 const char* path = NULL;
867 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
869 path = pne->GetTitle();
871 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
875 if (!gGeoManager->CheckPath(path)) {
876 AliErrorClass(Form("Volume path %s not valid!",path));
882 TIter next(gGeoManager->GetListOfPhysicalNodes());
883 gGeoManager->cd(path);
885 while(gGeoManager->GetLevel()){
887 TGeoPhysicalNode *physNode = NULL;
889 TGeoNode *node = gGeoManager->GetCurrentNode();
890 while ((physNode=(TGeoPhysicalNode*)next()))
891 if (physNode->GetNode() == node) break;
893 TGeoMatrix *lm = NULL;
895 lm = physNode->GetOriginalMatrix();
896 if (!lm) lm = node->GetMatrix();
898 lm = node->GetMatrix();
908 //______________________________________________________________________
909 Bool_t AliGeomManager::GetOrigGlobalMatrix(Int_t index, TGeoHMatrix &m)
911 // Get the original (ideal geometry) TGeo matrix for
912 // a given module identified by 'index'.
913 // The method is slow, so it should be used
918 const char *symname = SymName(index);
919 if (!symname) return kFALSE;
921 return GetOrigGlobalMatrix(symname,m);
924 //______________________________________________________________________
925 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
927 // Get the original translation vector (ideal geometry)
928 // for a given module 'index' by quering the TGeoManager
931 if (!GetOrigGlobalMatrix(index,m)) return kFALSE;
933 Double_t *trans = m.GetTranslation();
934 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
939 //______________________________________________________________________
940 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
942 // Get the original rotation matrix (ideal geometry)
943 // for a given module 'index' by quering the TGeoManager
946 if (!GetOrigGlobalMatrix(index,m)) return kFALSE;
948 Double_t *rot = m.GetRotationMatrix();
949 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
954 //______________________________________________________________________
955 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
957 // Get the matrix which transforms from the tracking to the local RS
958 // The method queries directly the TGeoPNEntry
960 TGeoPNEntry *pne = GetPNEntry(index);
961 if (!pne) return NULL;
963 const TGeoHMatrix *m = pne->GetMatrix();
965 AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
970 //______________________________________________________________________
971 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
973 // Get the matrix which transforms from the tracking r.s. to
975 // Returns kFALSE in case of error.
979 TGeoHMatrix *m1 = GetMatrix(index);
980 if (!m1) return kFALSE;
982 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
983 if (!m2) return kFALSE;
991 //_____________________________________________________________________________
992 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
993 // Returns the TGeoPNEntry for the given global volume ID "voluid"
996 ELayerID layerId = VolUIDToLayer(voluid,modId);
997 return GetPNEntry(layerId,modId);
1000 //_____________________________________________________________________________
1001 TGeoPNEntry* AliGeomManager::GetPNEntry(UShort_t voluid) {
1002 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1005 ELayerID layerId = VolUIDToLayer(voluid,modId);
1006 return GetPNEntry(layerId,modId);
1009 //_____________________________________________________________________________
1010 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1012 // Returns the TGeoPNEntry for a given layer
1016 if(!fgPNEntry[0]) InitPNEntriesLUT();
1017 if(!ReactIfChangedGeom()) return NULL;
1019 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1020 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1024 return fgPNEntry[layerId-kFirstLayer][modId];
1027 //_____________________________________________________________________________
1028 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1030 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1031 // the list passed as argument (called by AliSimulation and
1032 // AliReconstruction)
1033 // Read the alignment objects from CDB.
1034 // Each detector is supposed to have the
1035 // alignment objects in DET/Align/Data CDB path.
1036 // All the detector objects are then collected,
1037 // sorted by geometry level (starting from ALIC) and
1038 // then applied to the TGeo geometry.
1039 // Finally an overlaps check is performed.
1042 if(!fAlignObjArray) fAlignObjArray = new TObjArray();
1043 fAlignObjArray->Clear();
1044 fAlignObjArray->SetOwner(0);
1046 TString alObjsNotLoaded="";
1047 TString alObjsLoaded="";
1049 TString AlignDetsString(AlignDetsList);
1050 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1051 TIter iter(detsarr);
1052 TObjString *str = 0;
1054 while((str = (TObjString*) iter.Next())){
1055 TString det(str->String());
1056 AliInfo(Form("Loading alignment objs for %s",det.Data()));
1057 if(!LoadAlignObjsFromCDBSingleDet(det.Data())){
1058 alObjsNotLoaded += det.Data();
1059 alObjsNotLoaded += " ";
1061 alObjsLoaded += det.Data();
1062 alObjsLoaded += " ";
1066 if(!alObjsLoaded.IsNull()) AliInfo(Form("Alignment objects loaded for: %s",
1067 alObjsLoaded.Data()));
1068 if(!alObjsNotLoaded.IsNull()) AliInfo(Form("Didn't/couldn't load alignment objects for: %s",
1069 alObjsNotLoaded.Data()));
1071 return(ApplyAlignObjsToGeom(fAlignObjArray));
1074 //_____________________________________________________________________________
1075 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName)
1077 // Adds the alignable objects found in the CDBEntry for the detector
1078 // passed as argument to the array of all alignment objects to be applyed
1081 // Fills array of single detector's alignable objects from CDB
1083 AliDebug(2, Form("Loading alignment objs for detector: %s",detName));
1087 AliCDBPath path(detName,"Align","Data");
1089 entry=AliCDBManager::Instance()->Get(path.GetPath());
1091 AliDebug(2,Form("Couldn't load alignment data for detector %s",detName));
1095 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1096 alignArray->SetOwner(0);
1097 AliDebug(2,Form("Found %d alignment objects for %s",
1098 alignArray->GetEntries(),detName));
1100 AliAlignObj *alignObj=0;
1101 TIter iter(alignArray);
1103 // loop over align objects in detector
1104 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1105 fAlignObjArray->Add(alignObj);
1107 // delete entry --- Don't delete, it is cached!
1109 AliDebug(2, Form("fAlignObjArray entries: %d",fAlignObjArray->GetEntries() ));
1114 //_____________________________________________________________________________
1115 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray* alObjArray)
1117 // Read collection of alignment objects (AliAlignObj derived) saved
1118 // in the TClonesArray alObjArray and apply them to gGeoManager
1120 ReactIfChangedGeom();
1123 Int_t nvols = alObjArray->GetEntriesFast();
1125 Bool_t flag = kTRUE;
1127 for(Int_t j=0; j<nvols; j++)
1129 AliAlignObj* alobj = (AliAlignObj*) alObjArray->UncheckedAt(j);
1130 if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
1133 if (AliDebugLevelClass() >= 1) {
1134 gGeoManager->GetTopNode()->CheckOverlaps(1);
1135 TObjArray* ovexlist = gGeoManager->GetListOfOverlaps();
1136 if(ovexlist->GetEntriesFast()){
1137 AliError("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1145 //_____________________________________________________________________________
1146 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1148 // read collection of alignment objects (AliAlignObj derived) saved
1149 // in the TClonesArray ClArrayName in the file fileName and apply
1150 // them to the geometry
1153 TFile* inFile = TFile::Open(fileName,"READ");
1154 if (!inFile || !inFile->IsOpen()) {
1155 AliErrorClass(Form("Could not open file %s !",fileName));
1159 TClonesArray* alObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1162 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1166 return ApplyAlignObjsToGeom(alObjArray);
1170 //_____________________________________________________________________________
1171 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1173 // read collection of alignment objects (AliAlignObj derived) saved
1174 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1175 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1179 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1180 AliCDBEntry* entry = storage->Get(Id);
1181 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
1183 return ApplyAlignObjsToGeom(AlObjArray);
1187 //_____________________________________________________________________________
1188 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1190 // read collection of alignment objects (AliAlignObj derived) saved
1191 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1192 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1196 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1197 AliCDBId id(path, runnum, runnum, version, sversion);
1199 return ApplyAlignObjsToGeom(param, id);
1203 //_____________________________________________________________________________
1204 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1206 // read collection of alignment objects (AliAlignObj derived) saved
1207 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1208 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1212 AliCDBPath path(detName,"Align","Data");
1213 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1215 if(!entry) return kFALSE;
1216 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
1218 return ApplyAlignObjsToGeom(AlObjArray);
1221 //_____________________________________________________________________________
1222 Bool_t AliGeomManager::ReactIfChangedGeom()
1224 // Check if the TGeo geometry has changed. In that case reinitialize the
1225 // look-up table mapping volume indexes to TGeoPNEntries
1228 if (!gGeoManager || !gGeoManager->IsClosed()) {
1229 AliErrorClass("No active geometry or geometry not yet closed!");
1233 if(HasGeomChanged())
1235 fgGeometry = gGeoManager;