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>
32 #include "AliGeomManager.h"
34 #include "AliAlignObj.h"
35 #include "AliAlignObjAngles.h"
36 #include "AliCDBManager.h"
37 #include "AliCDBStorage.h"
38 #include "AliCDBEntry.h"
40 ClassImp(AliGeomManager)
42 Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
43 80, 160, // ITS SPD first and second layer
44 84, 176, // ITS SDD first and second layer
45 748, 950, // ITS SSD first and second layer
46 36, 36, // TPC inner and outer chambers
47 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
54 const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
55 "ITS inner pixels layer", "ITS outer pixels layer",
56 "ITS inner drifts layer", "ITS outer drifts layer",
57 "ITS inner strips layer", "ITS outer strips layer",
58 "TPC inner chambers layer", "TPC outer chambers layer",
59 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
60 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
62 "PHOS EMC layer","PHOS CPV layer",
67 TString* AliGeomManager::fgSymName[kLastLayer - kFirstLayer] = {
80 TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
93 TGeoHMatrix** AliGeomManager::fgOrigMatrix[kLastLayer - kFirstLayer] = {
106 AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
119 TGeoManager* AliGeomManager::fgGeometry = 0x0;
121 //_____________________________________________________________________________
122 void AliGeomManager::LoadGeometry(const char *geomFileName)
125 // Load geometry either from a file
126 // or from the corresponding CDB entry
129 if (geomFileName && (!gSystem->AccessPathName(geomFileName))) { // gemotry.root exists
130 fgGeometry = TGeoManager::Import(geomFileName);
131 AliInfoClass("Using custom geometry.root file");
135 AliInfoClass("Using geometry from CDB");
137 AliCDBPath path("GRP","Geometry","Data");
139 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
140 if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
143 fgGeometry = (TGeoManager*) entry->GetObject();
144 if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
149 InitOrigMatricesLUT();
152 //_____________________________________________________________________________
153 void AliGeomManager::SetGeometry(TGeoManager *geom)
155 // Load already active geometry
156 if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
162 InitOrigMatricesLUT();
165 //_____________________________________________________________________________
166 AliGeomManager::AliGeomManager():
169 // default constructor
172 //_____________________________________________________________________________
173 AliGeomManager::~AliGeomManager()
178 //_____________________________________________________________________________
179 Int_t AliGeomManager::LayerSize(Int_t layerId)
181 // Get the layer size for layer corresponding to layerId.
182 // Implemented only for ITS,TPC,TRD,TOF and HMPID
184 if (layerId < kFirstLayer || layerId >= kLastLayer) {
185 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
189 return fgLayerSize[layerId - kFirstLayer];
193 //_____________________________________________________________________________
194 const char* AliGeomManager::LayerName(Int_t layerId)
196 // Get the layer name corresponding to layerId.
197 // Implemented only for ITS,TPC,TRD,TOF and HMPID
199 if (layerId < kFirstLayer || layerId >= kLastLayer) {
200 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
201 return "Invalid Layer!";
204 return fgLayerName[layerId - kFirstLayer];
208 //_____________________________________________________________________________
209 UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
211 // From detector (layer) name and module number (according to detector
212 // internal numbering) build the unique numerical identity of that volume
214 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
215 // remaining 11 for module ID inside det (2048 possible values).
216 // NO check for validity of given modId inside the layer for speed's sake.
218 return ((UShort_t(layerId) << 11) | UShort_t(modId));
221 //_____________________________________________________________________________
222 UShort_t AliGeomManager::LayerToVolUID(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 // NO check for validity of given modId inside the layer for speed's sake.
231 return ((UShort_t(layerId) << 11) | UShort_t(modId));
234 //_____________________________________________________________________________
235 UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
237 // From detector (layer) name and module number (according to detector
238 // internal numbering) build the unique numerical identity of that volume
240 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
241 // remaining 11 for module ID inside det (2048 possible values).
242 // Check validity of given modId inside the layer.
244 if(modId < 0 || modId >= LayerSize(layerId)){
245 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
248 return ((UShort_t(layerId) << 11) | UShort_t(modId));
251 //_____________________________________________________________________________
252 UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
254 // From detector (layer) name and module number (according to detector
255 // internal numbering) build the unique numerical identity of that volume
257 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
258 // remaining 11 for module ID inside det (2048 possible values).
259 // Check validity of given modId inside the layer.
261 if(modId < 0 || modId >= LayerSize(layerId)){
262 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
265 return ((UShort_t(layerId) << 11) | UShort_t(modId));
268 //_____________________________________________________________________________
269 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
271 // From voluid, unique numerical identity of that volume inside ALICE,
272 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
273 // remaining 11 for module ID inside det (2048 possible values)), return
274 // the identity of the layer to which that volume belongs and sets the
275 // argument modId to the identity of that volume internally to the layer.
276 // NO check for validity of given voluid for speed's sake.
278 modId = voluid & 0x7ff;
280 return VolUIDToLayer(voluid);
283 //_____________________________________________________________________________
284 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
286 // From voluid, unique numerical identity of that volume inside ALICE,
287 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
288 // remaining 11 for module ID inside det (2048 possible values)), return
289 // the identity of the layer to which that volume belongs
290 // NO check for validity of given voluid for speed's sake.
292 return ELayerID(voluid >> 11);
295 //_____________________________________________________________________________
296 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
298 // From voluid, unique numerical identity of that volume inside ALICE,
299 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
300 // remaining 11 for module ID inside det (2048 possible values)), returns
301 // the identity of the layer to which that volume belongs and sets the
302 // argument modId to the identity of that volume internally to the layer.
303 // Checks the validity of the given voluid
305 ELayerID layId = VolUIDToLayerSafe(voluid);
307 Int_t mId = Int_t(voluid & 0x7ff);
308 if( mId>=0 && mId<LayerSize(layId)){
314 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
316 return kInvalidLayer;
320 //_____________________________________________________________________________
321 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
323 // From voluid, unique numerical identity of that volume inside ALICE,
324 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
325 // remaining 11 for module ID inside det (2048 possible values)), returns
326 // the identity of the layer to which that volume belongs
327 // Checks the validity of the given voluid
329 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
331 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
332 return kInvalidLayer;
336 //_____________________________________________________________________________
337 Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
339 // Get the alignment object which corresponds to the symbolic volume name
340 // symname (in case equal to the TGeo volume path)
341 // The method is extremely slow due to the searching by string,
342 // therefore it should be used with great care!!
343 // This method returns FALSE if the symname of the object was not
344 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
345 // associated to the TGeoPNEntry was not valid.
348 // Reset the alignment object
349 alobj.SetPars(0,0,0,0,0,0);
350 alobj.SetSymName(symname);
352 if (!fgGeometry || !fgGeometry->IsClosed()) {
353 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
357 if (!fgGeometry->GetListOfPhysicalNodes()) {
358 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
363 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
365 path = pne->GetTitle();
367 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
370 TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
371 TGeoPhysicalNode* node = NULL;
372 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
373 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
374 const char *nodePath = tempNode->GetName();
375 if (strcmp(path,nodePath) == 0) {
382 if (!fgGeometry->cd(path)) {
383 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
387 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
392 TGeoHMatrix align,gprime,g,ginv,l;
393 gprime = *node->GetMatrix();
394 l = *node->GetOriginalMatrix();
395 g = *node->GetMatrix(node->GetLevel()-1);
398 align = gprime * ginv;
400 return alobj.SetMatrix(align);
404 //_____________________________________________________________________________
405 void AliGeomManager::InitAlignObjFromGeometry()
407 // Loop over all alignable volumes and extract
408 // the corresponding alignment objects from
411 if(fgAlignObjs[0]) return;
413 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
414 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
415 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
416 UShort_t volid = LayerToVolUID(iLayer,iModule);
417 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
418 const char *symname = SymName(volid);
419 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
420 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
426 //_____________________________________________________________________________
427 AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
428 // Returns the alignment object for given volume ID
431 ELayerID layerId = VolUIDToLayer(voluid,modId);
432 return GetAlignObj(layerId,modId);
435 //_____________________________________________________________________________
436 AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
438 // Returns pointer to alignment object given its layer and module ID
440 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
441 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
444 InitAlignObjFromGeometry();
446 return fgAlignObjs[layerId-kFirstLayer][modId];
449 //_____________________________________________________________________________
450 const char* AliGeomManager::SymName(UShort_t voluid) {
451 // Returns the symbolic volume name for given volume ID
454 ELayerID layerId = VolUIDToLayer(voluid,modId);
455 return SymName(layerId,modId);
458 //_____________________________________________________________________________
459 const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
461 // Returns the symbolic volume name given for a given layer
464 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
465 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
470 return fgSymName[layerId-kFirstLayer][modId].Data();
473 //_____________________________________________________________________________
474 void AliGeomManager::InitSymNamesLUT()
476 // Initialize the look-up table which associates the unique
477 // numerical identity of each alignable volume to the
478 // corresponding symbolic volume name
479 // The LUTs are static; they are created at the creation of the
480 // AliGeomManager instance and recreated if the geometry has changed
483 if(fgSymName[0]) return;
485 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
486 if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
490 Int_t modnum; // in the following, set it to 0 at the start of each layer
492 /********************* ITS layers ***********************/
493 TString strSPD = "ITS/SPD";
494 TString strSDD = "ITS/SDD";
495 TString strSSD = "ITS/SSD";
496 TString strStave = "/Stave";
497 TString strLadder = "/Ladder";
498 TString strSector = "/Sector";
499 TString strSensor = "/Sensor";
500 TString strEntryName1;
501 TString strEntryName2;
504 /********************* SPD layer1 ***********************/
508 for(Int_t c1 = 1; c1<=10; c1++){
509 strEntryName1 = strSPD;
511 strEntryName1 += strSector;
512 strEntryName1 += (c1-1);
513 for(Int_t c2 =1; c2<=2; c2++){
514 strEntryName2 = strEntryName1;
515 strEntryName2 += strStave;
516 strEntryName2 += (c2-1);
517 for(Int_t c3 =1; c3<=4; c3++){
518 symname = strEntryName2;
519 symname += strLadder;
521 fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
528 /********************* SPD layer2 ***********************/
532 for(Int_t c1 = 1; c1<=10; c1++){
533 strEntryName1 = strSPD;
535 strEntryName1 += strSector;
536 strEntryName1 += (c1-1);
537 for(Int_t c2 =1; c2<=4; c2++){
538 strEntryName2 = strEntryName1;
539 strEntryName2 += strStave;
540 strEntryName2 += (c2-1);
541 for(Int_t c3 =1; c3<=4; c3++){
542 symname = strEntryName2;
543 symname += strLadder;
545 fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
552 /********************* SDD layer1 ***********************/
556 for(Int_t c1 = 1; c1<=14; c1++){
557 strEntryName1 = strSDD;
559 strEntryName1 +=strLadder;
560 strEntryName1 += (c1-1);
561 for(Int_t c2 =1; c2<=6; c2++){
562 symname = strEntryName1;
563 symname += strSensor;
565 fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
571 /********************* SDD layer2 ***********************/
575 for(Int_t c1 = 1; c1<=22; c1++){
576 strEntryName1 = strSDD;
578 strEntryName1 +=strLadder;
579 strEntryName1 += (c1-1);
580 for(Int_t c2 = 1; c2<=8; c2++){
581 symname = strEntryName1;
582 symname += strSensor;
584 fgSymName[kSDD2-kFirstLayer][modnum] = symname.Data();
590 /********************* SSD layer1 ***********************/
594 for(Int_t c1 = 1; c1<=34; c1++){
595 strEntryName1 = strSSD;
597 strEntryName1 +=strLadder;
598 strEntryName1 += (c1-1);
599 for(Int_t c2 = 1; c2<=22; c2++){
600 symname = strEntryName1;
601 symname += strSensor;
603 fgSymName[kSSD1-kFirstLayer][modnum] = symname.Data();
609 /********************* SSD layer2 ***********************/
613 for(Int_t c1 = 1; c1<=38; c1++){
614 strEntryName1 = strSSD;
616 strEntryName1 +=strLadder;
617 strEntryName1 += (c1-1);
618 for(Int_t c2 = 1; c2<=25; c2++){
619 symname = strEntryName1;
620 symname += strSensor;
622 fgSymName[kSSD2-kFirstLayer][modnum] = symname.Data();
629 /*************** TPC inner and outer layers ****************/
630 TString sAsector="TPC/EndcapA/Sector";
631 TString sCsector="TPC/EndcapC/Sector";
632 TString sInner="/InnerChamber";
633 TString sOuter="/OuterChamber";
635 /*************** TPC inner chambers' layer ****************/
639 for(Int_t cnt=1; cnt<=18; cnt++){
643 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
646 for(Int_t cnt=1; cnt<=18; cnt++){
650 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
655 /*************** TPC outer chambers' layer ****************/
659 for(Int_t cnt=1; cnt<=18; cnt++){
663 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
666 for(Int_t cnt=1; cnt<=18; cnt++){
670 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
675 /********************* TOF layer ***********************/
683 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
685 TString snSM = "TOF/sm";
686 TString snSTRIP = "/strip";
688 for (Int_t isect = 0; isect < nSectors; isect++) {
689 for (Int_t istr = 1; istr <= nStrips; istr++) {
691 symname += Form("%02d",isect);
693 symname += Form("%02d",istr);
694 fgSymName[kTOF-kFirstLayer][modnum] = symname.Data();
700 /********************* HMPID layer ***********************/
702 TString str = "/HMPID/Chamber";
704 for (modnum=0; modnum < 7; modnum++) {
707 fgSymName[kHMPID-kFirstLayer][modnum] = symname.Data();
711 /********************* TRD layers 1-6 *******************/
712 //!! 6 layers with index increasing in outwards direction
714 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
716 TString snStr = "TRD/sm";
717 TString snApp1 = "/st";
718 TString snApp2 = "/pl";
720 for(Int_t layer=0; layer<6; layer++){
722 for (Int_t isect = 0; isect < 18; isect++) {
723 for (Int_t icham = 0; icham < 5; icham++) {
725 symname += Form("%02d",isect);
730 fgSymName[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();
737 /********************* PHOS EMC layer ***********************/
739 TString str = "PHOS/Module";
742 for (Int_t iModule=1; iModule <= 5; iModule++) {
746 fgSymName[kPHOS1-kFirstLayer][modnum] = symname.Data();
750 /********************* PHOS CPV layer ***********************/
752 TString str = "PHOS/Module";
755 for (Int_t iModule=1; iModule <= 5; iModule++) {
760 fgSymName[kPHOS2-kFirstLayer][modnum] = symname.Data();
767 //_____________________________________________________________________________
768 void AliGeomManager::InitPNEntriesLUT()
770 // Initialize the look-up table which associates the unique
771 // numerical identity of each alignable volume to the
772 // corresponding TGeoPNEntry.
773 // The LUTs are static; they are created at the creation of the
774 // AliGeomManager instance and recreated if the geometry has changed
776 if (fgPNEntry[0]) return;
779 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
783 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
784 fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
785 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
786 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntry(fgSymName[iLayer][modnum]);
791 //_____________________________________________________________________________
792 void AliGeomManager::InitOrigMatricesLUT()
794 // Initialize the storage for the look-up table with the original global
795 // matrices for each alignable volume.
796 // The LUTs are static; the matrices are created on demand and recreated
797 // if the geometry has changed.
798 if (fgOrigMatrix[0]) return;
800 if (!fgGeometry || !fgGeometry->IsClosed()) {
801 AliErrorClass("Impossible to initialize orignal matrices LUT without an active geometry");
805 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
806 fgOrigMatrix[iLayer] = new TGeoHMatrix*[fgLayerSize[iLayer]];
807 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
808 if (!fgPNEntry[iLayer][modnum]) continue;
809 TGeoHMatrix *m = GetOrigGlobalMatrix(fgPNEntry[iLayer][modnum]);
811 fgOrigMatrix[iLayer][modnum] = new TGeoHMatrix(*m);
817 //______________________________________________________________________
818 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
820 // Get the transformation matrix for a given PNEntry
821 // by quering the TGeoManager
823 if (!fgGeometry || !fgGeometry->IsClosed()) {
824 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
828 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
829 if (pnode) return pnode->GetMatrix();
831 const char* path = pne->GetTitle();
832 if (!fgGeometry->cd(path)) {
833 AliErrorClass(Form("Volume path %s not valid!",path));
836 return fgGeometry->GetCurrentMatrix();
839 //______________________________________________________________________
840 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
842 // Get the global transformation matrix for a given alignable volume
843 // identified by its unique ID 'index' by quering the TGeoManager
845 TGeoPNEntry *pne = GetPNEntry(index);
846 if (!pne) return NULL;
848 return GetMatrix(pne);
851 //______________________________________________________________________
852 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
854 // Get the global transformation matrix for a given alignable volume
855 // identified by its symbolic name 'symname' by quering the TGeoManager
857 if (!fgGeometry || !fgGeometry->IsClosed()) {
858 AliErrorClass("No active geometry or geometry not yet closed!");
862 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
863 if (!pne) return NULL;
865 return GetMatrix(pne);
868 //______________________________________________________________________
869 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
871 // Get the translation vector for a given module 'index'
872 // by quering the TGeoManager
874 TGeoHMatrix *m = GetMatrix(index);
875 if (!m) return kFALSE;
877 Double_t *trans = m->GetTranslation();
878 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
883 //______________________________________________________________________
884 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
886 // Get the rotation matrix for a given module 'index'
887 // by quering the TGeoManager
889 TGeoHMatrix *m = GetMatrix(index);
890 if (!m) return kFALSE;
892 Double_t *rot = m->GetRotationMatrix();
893 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
898 //______________________________________________________________________
899 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
901 // Get the global transformation matrix (ideal geometry) for a given alignable volume
902 // identified by its symbolic name 'symname' by quering the TGeoManager
905 if (!fgGeometry || !fgGeometry->IsClosed()) {
906 AliErrorClass("No active geometry or geometry not yet closed!");
909 if (!fgGeometry->GetListOfPhysicalNodes()) {
910 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
911 if (!fgGeometry->cd(symname)) {
912 AliErrorClass(Form("Volume path %s not valid!",symname));
916 m = *fgGeometry->GetCurrentMatrix();
921 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
922 const char* path = NULL;
924 path = pne->GetTitle();
926 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
930 return GetOrigGlobalMatrixFromPath(path,m);
933 //_____________________________________________________________________________
934 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
936 // The method returns global matrix for the ideal detector geometry
937 // Symname identifies either the corresponding TGeoPNEntry or directly
938 // the volume path. The output global matrix is stored in 'm'.
939 // Returns kFALSE in case TGeo has not been initialized or the symname
944 if (!fgGeometry || !fgGeometry->IsClosed()) {
945 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
949 if (!fgGeometry->CheckPath(path)) {
950 AliErrorClass(Form("Volume path %s not valid!",path));
954 TIter next(fgGeometry->GetListOfPhysicalNodes());
955 fgGeometry->cd(path);
957 while(fgGeometry->GetLevel()){
959 TGeoPhysicalNode *physNode = NULL;
961 TGeoNode *node = fgGeometry->GetCurrentNode();
962 while ((physNode=(TGeoPhysicalNode*)next()))
963 if (physNode->GetNode() == node) break;
965 TGeoMatrix *lm = NULL;
967 lm = physNode->GetOriginalMatrix();
968 if (!lm) lm = node->GetMatrix();
970 lm = node->GetMatrix();
980 //_____________________________________________________________________________
981 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
983 // The method returns global matrix for the ideal detector geometry
984 // using the corresponding TGeoPNEntry as an input.
985 // The method creates a new matrix, so it has to be used carefully in order
986 // to avoid memory leaks.
987 // In case of missing TGeoManager the method return NULL.
989 if (!fgGeometry || !fgGeometry->IsClosed()) {
990 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
994 const char* path = pne->GetTitle();
995 static TGeoHMatrix m;
996 if (!GetOrigGlobalMatrixFromPath(path,m))
1002 //______________________________________________________________________
1003 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
1005 // Get the original (ideal geometry) TGeo matrix for
1006 // a given module identified by 'index'.
1007 // In general the method is slow, so we use
1008 // LUT for fast access. The LUT is reset in case of
1009 // new geometry is loaded.
1011 ELayerID layerId = VolUIDToLayer(index,modId);
1013 if (fgOrigMatrix[layerId-kFirstLayer][modId])
1014 return fgOrigMatrix[layerId-kFirstLayer][modId];
1016 TGeoPNEntry *pne = GetPNEntry(index);
1017 if (!pne) return NULL;
1018 return GetOrigGlobalMatrix(pne);
1022 //______________________________________________________________________
1023 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1025 // Get the original translation vector (ideal geometry)
1026 // for a given module 'index' by quering the TGeoManager
1028 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1029 if (!m) return kFALSE;
1031 Double_t *trans = m->GetTranslation();
1032 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1037 //______________________________________________________________________
1038 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1040 // Get the original rotation matrix (ideal geometry)
1041 // for a given module 'index' by quering the TGeoManager
1043 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1044 if (!m) return kFALSE;
1046 Double_t *rot = m->GetRotationMatrix();
1047 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1052 //______________________________________________________________________
1053 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1055 // Get the matrix which transforms from the tracking to the local RS
1056 // The method queries directly the TGeoPNEntry
1058 TGeoPNEntry *pne = GetPNEntry(index);
1059 if (!pne) return NULL;
1061 const TGeoHMatrix *m = pne->GetMatrix();
1063 AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
1068 //______________________________________________________________________
1069 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1071 // Get the matrix which transforms from the tracking r.s. to
1073 // Returns kFALSE in case of error.
1077 TGeoHMatrix *m1 = GetMatrix(index);
1078 if (!m1) return kFALSE;
1080 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1081 if (!m2) return kFALSE;
1089 //_____________________________________________________________________________
1090 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1091 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1094 ELayerID layerId = VolUIDToLayer(voluid,modId);
1095 return GetPNEntry(layerId,modId);
1098 //_____________________________________________________________________________
1099 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1101 // Returns the TGeoPNEntry for a given layer
1105 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1106 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1110 return fgPNEntry[layerId-kFirstLayer][modId];
1113 //_____________________________________________________________________________
1114 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1116 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1117 // the list passed as argument (called by AliSimulation and
1118 // AliReconstruction)
1119 // Read the alignment objects from CDB.
1120 // Each detector is supposed to have the
1121 // alignment objects in DET/Align/Data CDB path.
1122 // All the detector objects are then collected,
1123 // sorted by geometry level (starting from ALIC) and
1124 // then applied to the TGeo geometry.
1125 // Finally an overlaps check is performed.
1128 TObjArray alignObjArray;
1129 alignObjArray.Clear();
1130 alignObjArray.SetOwner(0);
1132 TString alObjsNotLoaded="";
1133 TString alObjsLoaded="";
1135 TString AlignDetsString(AlignDetsList);
1136 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1137 TIter iter(detsarr);
1138 TObjString *str = 0;
1140 while((str = (TObjString*) iter.Next())){
1141 TString det(str->String());
1142 AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1143 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
1144 alObjsNotLoaded += det.Data();
1145 alObjsNotLoaded += " ";
1147 alObjsLoaded += det.Data();
1148 alObjsLoaded += " ";
1152 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1153 alObjsLoaded.Data()));
1154 if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1155 alObjsNotLoaded.Data()));
1157 return ApplyAlignObjsToGeom(alignObjArray);
1160 //_____________________________________________________________________________
1161 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
1163 // Adds the alignable objects found in the CDBEntry for the detector
1164 // passed as argument to the array of all alignment objects to be applyed
1167 // Fills array of single detector's alignable objects from CDB
1169 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
1173 AliCDBPath path(detName,"Align","Data");
1175 entry=AliCDBManager::Instance()->Get(path.GetPath());
1177 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
1181 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1182 alignArray->SetOwner(0);
1183 AliDebugClass(2,Form("Found %d alignment objects for %s",
1184 alignArray->GetEntries(),detName));
1186 AliAlignObj *alignObj=0;
1187 TIter iter(alignArray);
1189 // loop over align objects in detector
1190 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1191 alignObjArray.Add(alignObj);
1193 // delete entry --- Don't delete, it is cached!
1195 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
1200 //_____________________________________________________________________________
1201 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray)
1203 // Read collection of alignment objects (AliAlignObj derived) saved
1204 // in the TClonesArray alObjArray and apply them to gGeoManager
1206 alignObjArray.Sort();
1207 Int_t nvols = alignObjArray.GetEntriesFast();
1209 Bool_t flag = kTRUE;
1211 for(Int_t j=0; j<nvols; j++)
1213 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1214 if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
1217 if (AliDebugLevelClass() >= 1) {
1218 fgGeometry->GetTopNode()->CheckOverlaps(1);
1219 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
1220 if(ovexlist->GetEntriesFast()){
1221 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1225 // Update the TGeoPhysicalNodes
1226 fgGeometry->RefreshPhysicalNodes();
1232 //_____________________________________________________________________________
1233 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1235 // read collection of alignment objects (AliAlignObj derived) saved
1236 // in the TClonesArray ClArrayName in the file fileName and apply
1237 // them to the geometry
1240 TFile* inFile = TFile::Open(fileName,"READ");
1241 if (!inFile || !inFile->IsOpen()) {
1242 AliErrorClass(Form("Could not open file %s !",fileName));
1246 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1248 if (!alignObjArray) {
1249 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1253 return ApplyAlignObjsToGeom(*alignObjArray);
1257 //_____________________________________________________________________________
1258 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1260 // read collection of alignment objects (AliAlignObj derived) saved
1261 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1262 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1266 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1267 AliCDBEntry* entry = storage->Get(Id);
1268 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1270 return ApplyAlignObjsToGeom(*alignObjArray);
1274 //_____________________________________________________________________________
1275 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1277 // read collection of alignment objects (AliAlignObj derived) saved
1278 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1279 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1283 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1284 AliCDBId id(path, runnum, runnum, version, sversion);
1286 return ApplyAlignObjsToGeom(param, id);
1290 //_____________________________________________________________________________
1291 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1293 // read collection of alignment objects (AliAlignObj derived) saved
1294 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1295 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1299 AliCDBPath path(detName,"Align","Data");
1300 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1302 if(!entry) return kFALSE;
1303 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1305 return ApplyAlignObjsToGeom(*alignObjArray);