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 TGeoHMatrix** AliGeomManager::fgOrigMatrix[kLastLayer - kFirstLayer] = {
105 AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
118 TGeoManager* AliGeomManager::fgGeometry = 0x0;
120 //_____________________________________________________________________________
121 void AliGeomManager::LoadGeometry(const char *geomFileName)
126 if (geomFileName && (!gSystem->AccessPathName(geomFileName))) { // gemotry.root exists
127 fgGeometry = TGeoManager::Import(geomFileName);
128 AliInfoClass("Using custom geometry.root file");
132 AliInfoClass("Using geometry from CDB");
134 AliCDBPath path("GRP","Geometry","Data");
136 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
137 if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
140 fgGeometry = (TGeoManager*) entry->GetObject();
141 if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
146 InitOrigMatricesLUT();
149 //_____________________________________________________________________________
150 AliGeomManager::AliGeomManager():
153 // default constructor
156 //_____________________________________________________________________________
157 AliGeomManager::~AliGeomManager()
162 //_____________________________________________________________________________
163 Int_t AliGeomManager::LayerSize(Int_t layerId)
165 // Get the layer size for layer corresponding to layerId.
166 // Implemented only for ITS,TPC,TRD,TOF and HMPID
168 if (layerId < kFirstLayer || layerId >= kLastLayer) {
169 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
173 return fgLayerSize[layerId - kFirstLayer];
177 //_____________________________________________________________________________
178 const char* AliGeomManager::LayerName(Int_t layerId)
180 // Get the layer name corresponding to layerId.
181 // Implemented only for ITS,TPC,TRD,TOF and HMPID
183 if (layerId < kFirstLayer || layerId >= kLastLayer) {
184 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
185 return "Invalid Layer!";
188 return fgLayerName[layerId - kFirstLayer];
192 //_____________________________________________________________________________
193 UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
195 // From detector (layer) name and module number (according to detector
196 // internal numbering) build the unique numerical identity of that volume
198 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
199 // remaining 11 for module ID inside det (2048 possible values).
200 // NO check for validity of given modId inside the layer for speed's sake.
202 return ((UShort_t(layerId) << 11) | UShort_t(modId));
205 //_____________________________________________________________________________
206 UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
208 // From detector (layer) name and module number (according to detector
209 // internal numbering) build the unique numerical identity of that volume
211 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
212 // remaining 11 for module ID inside det (2048 possible values).
213 // NO check for validity of given modId inside the layer for speed's sake.
215 return ((UShort_t(layerId) << 11) | UShort_t(modId));
218 //_____________________________________________________________________________
219 UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
221 // From detector (layer) name and module number (according to detector
222 // internal numbering) build the unique numerical identity of that volume
224 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
225 // remaining 11 for module ID inside det (2048 possible values).
226 // Check validity of given modId inside the layer.
228 if(modId < 0 || modId >= LayerSize(layerId)){
229 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
232 return ((UShort_t(layerId) << 11) | UShort_t(modId));
235 //_____________________________________________________________________________
236 UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
238 // From detector (layer) name and module number (according to detector
239 // internal numbering) build the unique numerical identity of that volume
241 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
242 // remaining 11 for module ID inside det (2048 possible values).
243 // Check validity of given modId inside the layer.
245 if(modId < 0 || modId >= LayerSize(layerId)){
246 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
249 return ((UShort_t(layerId) << 11) | UShort_t(modId));
252 //_____________________________________________________________________________
253 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
255 // From voluid, unique numerical identity of that volume inside ALICE,
256 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
257 // remaining 11 for module ID inside det (2048 possible values)), return
258 // the identity of the layer to which that volume belongs and sets the
259 // argument modId to the identity of that volume internally to the layer.
260 // NO check for validity of given voluid for speed's sake.
262 modId = voluid & 0x7ff;
264 return VolUIDToLayer(voluid);
267 //_____________________________________________________________________________
268 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
270 // From voluid, unique numerical identity of that volume inside ALICE,
271 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
272 // remaining 11 for module ID inside det (2048 possible values)), return
273 // the identity of the layer to which that volume belongs
274 // NO check for validity of given voluid for speed's sake.
276 return ELayerID(voluid >> 11);
279 //_____________________________________________________________________________
280 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
282 // From voluid, unique numerical identity of that volume inside ALICE,
283 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
284 // remaining 11 for module ID inside det (2048 possible values)), returns
285 // the identity of the layer to which that volume belongs and sets the
286 // argument modId to the identity of that volume internally to the layer.
287 // Checks the validity of the given voluid
289 ELayerID layId = VolUIDToLayerSafe(voluid);
291 Int_t mId = Int_t(voluid & 0x7ff);
292 if( mId>=0 && mId<LayerSize(layId)){
298 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
300 return kInvalidLayer;
304 //_____________________________________________________________________________
305 AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
307 // From voluid, unique numerical identity of that volume inside ALICE,
308 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
309 // remaining 11 for module ID inside det (2048 possible values)), returns
310 // the identity of the layer to which that volume belongs
311 // Checks the validity of the given voluid
313 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
315 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
316 return kInvalidLayer;
320 //_____________________________________________________________________________
321 Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
323 // Get the alignment object which corresponds to the symbolic volume name
324 // symname (in case equal to the TGeo volume path)
325 // The method is extremely slow due to the searching by string,
326 // therefore it should be used with great care!!
327 // This method returns FALSE if the symname of the object was not
328 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
329 // associated to the TGeoPNEntry was not valid.
332 // Reset the alignment object
333 alobj.SetPars(0,0,0,0,0,0);
334 alobj.SetSymName(symname);
336 if (!fgGeometry || !fgGeometry->IsClosed()) {
337 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
341 if (!fgGeometry->GetListOfPhysicalNodes()) {
342 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
347 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
349 path = pne->GetTitle();
351 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
354 TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
355 TGeoPhysicalNode* node = NULL;
356 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
357 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
358 const char *nodePath = tempNode->GetName();
359 if (strcmp(path,nodePath) == 0) {
366 if (!fgGeometry->cd(path)) {
367 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
371 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
376 TGeoHMatrix align,gprime,g,ginv,l;
377 gprime = *node->GetMatrix();
378 l = *node->GetOriginalMatrix();
379 g = *node->GetMatrix(node->GetLevel()-1);
382 align = gprime * ginv;
384 return alobj.SetMatrix(align);
388 //_____________________________________________________________________________
389 void AliGeomManager::InitAlignObjFromGeometry()
391 // Loop over all alignable volumes and extract
392 // the corresponding alignment objects from
395 if(fgAlignObjs[0]) return;
397 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
398 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
399 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
400 UShort_t volid = LayerToVolUID(iLayer,iModule);
401 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
402 const char *symname = SymName(volid);
403 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
404 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
410 //_____________________________________________________________________________
411 AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
412 // Returns the alignment object for given volume ID
415 ELayerID layerId = VolUIDToLayer(voluid,modId);
416 return GetAlignObj(layerId,modId);
419 //_____________________________________________________________________________
420 AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
422 // Returns pointer to alignment object given its layer and module ID
424 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
425 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
428 InitAlignObjFromGeometry();
430 return fgAlignObjs[layerId-kFirstLayer][modId];
433 //_____________________________________________________________________________
434 const char* AliGeomManager::SymName(UShort_t voluid) {
435 // Returns the symbolic volume name for given volume ID
438 ELayerID layerId = VolUIDToLayer(voluid,modId);
439 return SymName(layerId,modId);
442 //_____________________________________________________________________________
443 const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
445 // Returns the symbolic volume name given for a given layer
448 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
449 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
454 return fgSymName[layerId-kFirstLayer][modId].Data();
457 //_____________________________________________________________________________
458 void AliGeomManager::InitSymNamesLUT()
460 // Initialize the look-up table which associates the unique
461 // numerical identity of each alignable volume to the
462 // corresponding symbolic volume name
463 // The LUTs are static; they are created at the creation of the
464 // AliGeomManager instance and recreated if the geometry has changed
467 if(fgSymName[0]) return;
469 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
470 if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
474 Int_t modnum; // in the following, set it to 0 at the start of each layer
476 /********************* ITS layers ***********************/
477 TString strSPD = "ITS/SPD";
478 TString strSDD = "ITS/SDD";
479 TString strSSD = "ITS/SSD";
480 TString strStave = "/Stave";
481 TString strLadder = "/Ladder";
482 TString strSector = "/Sector";
483 TString strSensor = "/Sensor";
484 TString strEntryName1;
485 TString strEntryName2;
488 /********************* SPD layer1 ***********************/
492 for(Int_t c1 = 1; c1<=10; c1++){
493 strEntryName1 = strSPD;
495 strEntryName1 += strSector;
496 strEntryName1 += (c1-1);
497 for(Int_t c2 =1; c2<=2; c2++){
498 strEntryName2 = strEntryName1;
499 strEntryName2 += strStave;
500 strEntryName2 += (c2-1);
501 for(Int_t c3 =1; c3<=4; c3++){
502 symname = strEntryName2;
503 symname += strLadder;
505 fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
512 /********************* SPD layer2 ***********************/
516 for(Int_t c1 = 1; c1<=10; c1++){
517 strEntryName1 = strSPD;
519 strEntryName1 += strSector;
520 strEntryName1 += (c1-1);
521 for(Int_t c2 =1; c2<=4; c2++){
522 strEntryName2 = strEntryName1;
523 strEntryName2 += strStave;
524 strEntryName2 += (c2-1);
525 for(Int_t c3 =1; c3<=4; c3++){
526 symname = strEntryName2;
527 symname += strLadder;
529 fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
536 /********************* SDD layer1 ***********************/
540 for(Int_t c1 = 1; c1<=14; c1++){
541 strEntryName1 = strSDD;
543 strEntryName1 +=strLadder;
544 strEntryName1 += (c1-1);
545 for(Int_t c2 =1; c2<=6; c2++){
546 symname = strEntryName1;
547 symname += strSensor;
549 fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
555 /********************* SDD layer2 ***********************/
559 for(Int_t c1 = 1; c1<=22; c1++){
560 strEntryName1 = strSDD;
562 strEntryName1 +=strLadder;
563 strEntryName1 += (c1-1);
564 for(Int_t c2 = 1; c2<=8; c2++){
565 symname = strEntryName1;
566 symname += strSensor;
568 fgSymName[kSDD2-kFirstLayer][modnum] = symname.Data();
574 /********************* SSD layer1 ***********************/
578 for(Int_t c1 = 1; c1<=34; c1++){
579 strEntryName1 = strSSD;
581 strEntryName1 +=strLadder;
582 strEntryName1 += (c1-1);
583 for(Int_t c2 = 1; c2<=22; c2++){
584 symname = strEntryName1;
585 symname += strSensor;
587 fgSymName[kSSD1-kFirstLayer][modnum] = symname.Data();
593 /********************* SSD layer2 ***********************/
597 for(Int_t c1 = 1; c1<=38; c1++){
598 strEntryName1 = strSSD;
600 strEntryName1 +=strLadder;
601 strEntryName1 += (c1-1);
602 for(Int_t c2 = 1; c2<=25; c2++){
603 symname = strEntryName1;
604 symname += strSensor;
606 fgSymName[kSSD2-kFirstLayer][modnum] = symname.Data();
613 /*************** TPC inner and outer layers ****************/
614 TString sAsector="TPC/EndcapA/Sector";
615 TString sCsector="TPC/EndcapC/Sector";
616 TString sInner="/InnerChamber";
617 TString sOuter="/OuterChamber";
619 /*************** TPC inner chambers' layer ****************/
623 for(Int_t cnt=1; cnt<=18; cnt++){
627 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
630 for(Int_t cnt=1; cnt<=18; cnt++){
634 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
639 /*************** TPC outer chambers' layer ****************/
643 for(Int_t cnt=1; cnt<=18; cnt++){
647 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
650 for(Int_t cnt=1; cnt<=18; cnt++){
654 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
659 /********************* TOF layer ***********************/
667 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
669 TString snSM = "TOF/sm";
670 TString snSTRIP = "/strip";
672 for (Int_t isect = 0; isect < nSectors; isect++) {
673 for (Int_t istr = 1; istr <= nStrips; istr++) {
675 symname += Form("%02d",isect);
677 symname += Form("%02d",istr);
678 fgSymName[kTOF-kFirstLayer][modnum] = symname.Data();
684 /********************* HMPID layer ***********************/
686 TString str = "/HMPID/Chamber";
688 for (modnum=0; modnum < 7; modnum++) {
691 fgSymName[kHMPID-kFirstLayer][modnum] = symname.Data();
695 /********************* TRD layers 1-6 *******************/
696 //!! 6 layers with index increasing in outwards direction
698 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
700 TString snStr = "TRD/sm";
701 TString snApp1 = "/st";
702 TString snApp2 = "/pl";
704 for(Int_t layer=0; layer<6; layer++){
706 for (Int_t isect = 0; isect < 18; isect++) {
707 for (Int_t icham = 0; icham < 5; icham++) {
709 symname += Form("%02d",isect);
714 fgSymName[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();
721 /********************* PHOS EMC layer ***********************/
723 TString str = "PHOS/Module";
726 for (Int_t iModule=1; iModule <= 5; iModule++) {
730 fgSymName[kPHOS1-kFirstLayer][modnum] = symname.Data();
734 /********************* PHOS CPV layer ***********************/
736 TString str = "PHOS/Module";
739 for (Int_t iModule=1; iModule <= 5; iModule++) {
744 fgSymName[kPHOS2-kFirstLayer][modnum] = symname.Data();
751 //_____________________________________________________________________________
752 void AliGeomManager::InitPNEntriesLUT()
754 // Initialize the look-up table which associates the unique
755 // numerical identity of each alignable volume to the
756 // corresponding TGeoPNEntry.
757 // The LUTs are static; they are created at the creation of the
758 // AliGeomManager instance and recreated if the geometry has changed
760 if (fgPNEntry[0]) return;
763 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
767 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
768 fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
769 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
770 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntry(fgSymName[iLayer][modnum]);
775 //_____________________________________________________________________________
776 void AliGeomManager::InitOrigMatricesLUT()
778 // Initialize the storage for the look-up table with the original global
779 // matrices for each alignable volume.
780 // The LUTs are static; the matrices are created on demand and recreated
781 // if the geometry has changed.
782 if (fgOrigMatrix[0]) return;
784 if (!fgGeometry || !fgGeometry->IsClosed()) {
785 AliErrorClass("Impossible to initialize orignal matrices LUT without an active geometry");
789 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
790 fgOrigMatrix[iLayer] = new TGeoHMatrix*[fgLayerSize[iLayer]];
791 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
792 if (!fgPNEntry[iLayer][modnum]) continue;
793 TGeoHMatrix *m = GetOrigGlobalMatrix(fgPNEntry[iLayer][modnum]);
795 fgOrigMatrix[iLayer][modnum] = new TGeoHMatrix(*m);
801 //______________________________________________________________________
802 TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
804 // Get the transformation matrix for a given PNEntry
805 // by quering the TGeoManager
807 if (!fgGeometry || !fgGeometry->IsClosed()) {
808 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
812 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
813 if (pnode) return pnode->GetMatrix();
815 const char* path = pne->GetTitle();
816 if (!fgGeometry->cd(path)) {
817 AliErrorClass(Form("Volume path %s not valid!",path));
820 return fgGeometry->GetCurrentMatrix();
823 //______________________________________________________________________
824 TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
826 // Get the global transformation matrix for a given alignable volume
827 // identified by its unique ID 'index' by quering the TGeoManager
829 TGeoPNEntry *pne = GetPNEntry(index);
830 if (!pne) return NULL;
832 return GetMatrix(pne);
835 //______________________________________________________________________
836 TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
838 // Get the global transformation matrix for a given alignable volume
839 // identified by its symbolic name 'symname' by quering the TGeoManager
841 if (!fgGeometry || !fgGeometry->IsClosed()) {
842 AliErrorClass("No active geometry or geometry not yet closed!");
846 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
847 if (!pne) return NULL;
849 return GetMatrix(pne);
852 //______________________________________________________________________
853 Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
855 // Get the translation vector for a given module 'index'
856 // by quering the TGeoManager
858 TGeoHMatrix *m = GetMatrix(index);
859 if (!m) return kFALSE;
861 Double_t *trans = m->GetTranslation();
862 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
867 //______________________________________________________________________
868 Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
870 // Get the rotation matrix for a given module 'index'
871 // by quering the TGeoManager
873 TGeoHMatrix *m = GetMatrix(index);
874 if (!m) return kFALSE;
876 Double_t *rot = m->GetRotationMatrix();
877 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
882 //______________________________________________________________________
883 Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
885 // Get the global transformation matrix (ideal geometry) for a given alignable volume
886 // identified by its symbolic name 'symname' by quering the TGeoManager
889 if (!fgGeometry || !fgGeometry->IsClosed()) {
890 AliErrorClass("No active geometry or geometry not yet closed!");
893 if (!fgGeometry->GetListOfPhysicalNodes()) {
894 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
895 if (!fgGeometry->cd(symname)) {
896 AliErrorClass(Form("Volume path %s not valid!",symname));
900 m = *fgGeometry->GetCurrentMatrix();
905 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
906 const char* path = NULL;
908 path = pne->GetTitle();
910 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
914 return GetOrigGlobalMatrixFromPath(path,m);
917 //_____________________________________________________________________________
918 Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
920 // The method returns global matrix for the ideal detector geometry
921 // Symname identifies either the corresponding TGeoPNEntry or directly
922 // the volume path. The output global matrix is stored in 'm'.
923 // Returns kFALSE in case TGeo has not been initialized or the symname
928 if (!fgGeometry || !fgGeometry->IsClosed()) {
929 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
933 if (!fgGeometry->CheckPath(path)) {
934 AliErrorClass(Form("Volume path %s not valid!",path));
938 TIter next(fgGeometry->GetListOfPhysicalNodes());
939 fgGeometry->cd(path);
941 while(fgGeometry->GetLevel()){
943 TGeoPhysicalNode *physNode = NULL;
945 TGeoNode *node = fgGeometry->GetCurrentNode();
946 while ((physNode=(TGeoPhysicalNode*)next()))
947 if (physNode->GetNode() == node) break;
949 TGeoMatrix *lm = NULL;
951 lm = physNode->GetOriginalMatrix();
952 if (!lm) lm = node->GetMatrix();
954 lm = node->GetMatrix();
964 //_____________________________________________________________________________
965 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
967 // The method returns global matrix for the ideal detector geometry
968 // using the corresponding TGeoPNEntry as an input.
969 // The method creates a new matrix, so it has to be used carefully in order
970 // to avoid memory leaks.
971 // In case of missing TGeoManager the method return NULL.
973 if (!fgGeometry || !fgGeometry->IsClosed()) {
974 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
978 const char* path = pne->GetTitle();
979 static TGeoHMatrix m;
980 if (!GetOrigGlobalMatrixFromPath(path,m))
986 //______________________________________________________________________
987 TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
989 // Get the original (ideal geometry) TGeo matrix for
990 // a given module identified by 'index'.
991 // In general the method is slow, so we use
992 // LUT for fast access. The LUT is reset in case of
993 // new geometry is loaded.
995 ELayerID layerId = VolUIDToLayer(index,modId);
997 if (fgOrigMatrix[layerId-kFirstLayer][modId])
998 return fgOrigMatrix[layerId-kFirstLayer][modId];
1000 TGeoPNEntry *pne = GetPNEntry(index);
1001 if (!pne) return NULL;
1002 return GetOrigGlobalMatrix(pne);
1006 //______________________________________________________________________
1007 Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1009 // Get the original translation vector (ideal geometry)
1010 // for a given module 'index' by quering the TGeoManager
1012 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1013 if (!m) return kFALSE;
1015 Double_t *trans = m->GetTranslation();
1016 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1021 //______________________________________________________________________
1022 Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1024 // Get the original rotation matrix (ideal geometry)
1025 // for a given module 'index' by quering the TGeoManager
1027 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1028 if (!m) return kFALSE;
1030 Double_t *rot = m->GetRotationMatrix();
1031 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1036 //______________________________________________________________________
1037 const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1039 // Get the matrix which transforms from the tracking to the local RS
1040 // The method queries directly the TGeoPNEntry
1042 TGeoPNEntry *pne = GetPNEntry(index);
1043 if (!pne) return NULL;
1045 const TGeoHMatrix *m = pne->GetMatrix();
1047 AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
1052 //______________________________________________________________________
1053 Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1055 // Get the matrix which transforms from the tracking r.s. to
1057 // Returns kFALSE in case of error.
1061 TGeoHMatrix *m1 = GetMatrix(index);
1062 if (!m1) return kFALSE;
1064 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1065 if (!m2) return kFALSE;
1073 //_____________________________________________________________________________
1074 TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1075 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1078 ELayerID layerId = VolUIDToLayer(voluid,modId);
1079 return GetPNEntry(layerId,modId);
1082 //_____________________________________________________________________________
1083 TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1085 // Returns the TGeoPNEntry for a given layer
1089 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1090 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1094 return fgPNEntry[layerId-kFirstLayer][modId];
1097 //_____________________________________________________________________________
1098 Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1100 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1101 // the list passed as argument (called by AliSimulation and
1102 // AliReconstruction)
1103 // Read the alignment objects from CDB.
1104 // Each detector is supposed to have the
1105 // alignment objects in DET/Align/Data CDB path.
1106 // All the detector objects are then collected,
1107 // sorted by geometry level (starting from ALIC) and
1108 // then applied to the TGeo geometry.
1109 // Finally an overlaps check is performed.
1112 TObjArray alignObjArray;
1113 alignObjArray.Clear();
1114 alignObjArray.SetOwner(0);
1116 TString alObjsNotLoaded="";
1117 TString alObjsLoaded="";
1119 TString AlignDetsString(AlignDetsList);
1120 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1121 TIter iter(detsarr);
1122 TObjString *str = 0;
1124 while((str = (TObjString*) iter.Next())){
1125 TString det(str->String());
1126 AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1127 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
1128 alObjsNotLoaded += det.Data();
1129 alObjsNotLoaded += " ";
1131 alObjsLoaded += det.Data();
1132 alObjsLoaded += " ";
1136 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1137 alObjsLoaded.Data()));
1138 if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1139 alObjsNotLoaded.Data()));
1141 return ApplyAlignObjsToGeom(alignObjArray);
1144 //_____________________________________________________________________________
1145 Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
1147 // Adds the alignable objects found in the CDBEntry for the detector
1148 // passed as argument to the array of all alignment objects to be applyed
1151 // Fills array of single detector's alignable objects from CDB
1153 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
1157 AliCDBPath path(detName,"Align","Data");
1159 entry=AliCDBManager::Instance()->Get(path.GetPath());
1161 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
1165 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1166 alignArray->SetOwner(0);
1167 AliDebugClass(2,Form("Found %d alignment objects for %s",
1168 alignArray->GetEntries(),detName));
1170 AliAlignObj *alignObj=0;
1171 TIter iter(alignArray);
1173 // loop over align objects in detector
1174 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1175 alignObjArray.Add(alignObj);
1177 // delete entry --- Don't delete, it is cached!
1179 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
1184 //_____________________________________________________________________________
1185 Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray)
1187 // Read collection of alignment objects (AliAlignObj derived) saved
1188 // in the TClonesArray alObjArray and apply them to gGeoManager
1190 alignObjArray.Sort();
1191 Int_t nvols = alignObjArray.GetEntriesFast();
1193 Bool_t flag = kTRUE;
1195 for(Int_t j=0; j<nvols; j++)
1197 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1198 if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
1201 if (AliDebugLevelClass() >= 1) {
1202 fgGeometry->GetTopNode()->CheckOverlaps(1);
1203 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
1204 if(ovexlist->GetEntriesFast()){
1205 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1209 // Update the TGeoPhysicalNodes
1210 fgGeometry->RefreshPhysicalNodes();
1216 //_____________________________________________________________________________
1217 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1219 // read collection of alignment objects (AliAlignObj derived) saved
1220 // in the TClonesArray ClArrayName in the file fileName and apply
1221 // them to the geometry
1224 TFile* inFile = TFile::Open(fileName,"READ");
1225 if (!inFile || !inFile->IsOpen()) {
1226 AliErrorClass(Form("Could not open file %s !",fileName));
1230 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1232 if (!alignObjArray) {
1233 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1237 return ApplyAlignObjsToGeom(*alignObjArray);
1241 //_____________________________________________________________________________
1242 Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1244 // read collection of alignment objects (AliAlignObj derived) saved
1245 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1246 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1250 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1251 AliCDBEntry* entry = storage->Get(Id);
1252 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1254 return ApplyAlignObjsToGeom(*alignObjArray);
1258 //_____________________________________________________________________________
1259 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1261 // read collection of alignment objects (AliAlignObj derived) saved
1262 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1263 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1267 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1268 AliCDBId id(path, runnum, runnum, version, sversion);
1270 return ApplyAlignObjsToGeom(param, id);
1274 //_____________________________________________________________________________
1275 Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, 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 AliCDBPath path(detName,"Align","Data");
1284 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1286 if(!entry) return kFALSE;
1287 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
1289 return ApplyAlignObjsToGeom(*alignObjArray);