Updated list of files
[u/mrichter/AliRoot.git] / STEER / AliGeomManager.cxx
CommitLineData
67dd5535 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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//-------------------------------------------------------------------------
21
22#include <TClass.h>
23#include <TFile.h>
24#include <TGeoManager.h>
25#include <TObjString.h>
26#include <TGeoPhysicalNode.h>
27#include <TClonesArray.h>
28#include <TGeoMatrix.h>
29#include <TGeoPhysicalNode.h>
99de26a3 30#include <TSystem.h>
5590c6c3 31#include <TStopwatch.h>
32#include <TGeoOverlap.h>
33#include <TPluginManager.h>
34#include <TROOT.h>
67dd5535 35
36#include "AliGeomManager.h"
37#include "AliLog.h"
38#include "AliAlignObj.h"
90dbf5fb 39#include "AliAlignObjParams.h"
67dd5535 40#include "AliCDBManager.h"
41#include "AliCDBStorage.h"
42#include "AliCDBEntry.h"
43
44ClassImp(AliGeomManager)
45
46Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
47 80, 160, // ITS SPD first and second layer
48 84, 176, // ITS SDD first and second layer
49 748, 950, // ITS SSD first and second layer
50 36, 36, // TPC inner and outer chambers
51 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
52 1638, // TOF
df117114 53 5, 5, // PHOS,CPV
67dd5535 54 7, // HMPID ??
3dfc15c0 55 1, // MUON ??
56 12 // EMCAL
67dd5535 57};
58
59const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
60 "ITS inner pixels layer", "ITS outer pixels layer",
61 "ITS inner drifts layer", "ITS outer drifts layer",
62 "ITS inner strips layer", "ITS outer strips layer",
63 "TPC inner chambers layer", "TPC outer chambers layer",
64 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
65 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
66 "TOF layer",
df117114 67 "PHOS EMC layer","PHOS CPV layer",
3dfc15c0 68 "HMPID layer",
69 "MUON ?",
70 "EMCAL layer"
67dd5535 71};
72
67dd5535 73TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
74 0x0,0x0,
75 0x0,0x0,
76 0x0,0x0,
77 0x0,0x0,
78 0x0,0x0,0x0,
79 0x0,0x0,0x0,
80 0x0,
81 0x0,0x0,
82 0x0,
3dfc15c0 83 0x0,
67dd5535 84 0x0
85};
86
36b010bf 87AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
88 0x0,0x0,
89 0x0,0x0,
90 0x0,0x0,
91 0x0,0x0,
92 0x0,0x0,0x0,
93 0x0,0x0,0x0,
94 0x0,
95 0x0,0x0,
96 0x0,
3dfc15c0 97 0x0,
36b010bf 98 0x0
99};
67dd5535 100
101TGeoManager* AliGeomManager::fgGeometry = 0x0;
102
103//_____________________________________________________________________________
36b010bf 104void AliGeomManager::LoadGeometry(const char *geomFileName)
67dd5535 105{
9d47e237 106 // initialization
107 // Load geometry either from a file
108 // or from the corresponding CDB entry
67dd5535 109
36b010bf 110 fgGeometry = NULL;
b8cf7791 111 if (geomFileName && (!gSystem->AccessPathName(geomFileName))) {
36b010bf 112 fgGeometry = TGeoManager::Import(geomFileName);
b8cf7791 113 AliInfoClass(Form("From now on using geometry from custom geometry file %s",geomFileName));
36b010bf 114 }
115
116 if (!fgGeometry) {
36b010bf 117 AliCDBPath path("GRP","Geometry","Data");
118
119 AliCDBEntry *entry=AliCDBManager::Instance()->Get(path.GetPath());
120 if(!entry) AliFatalClass("Couldn't load geometry data from CDB!");
121
122 entry->SetOwner(0);
123 fgGeometry = (TGeoManager*) entry->GetObject();
124 if (!fgGeometry) AliFatalClass("Couldn't find TGeoManager in the specified CDB entry!");
b8cf7791 125
126 AliInfoClass(Form("From now on using geometry from CDB base folder %s",
127 AliCDBManager::Instance()->GetURI("Geometry/Align/Data")));
36b010bf 128 }
67dd5535 129
67dd5535 130 InitPNEntriesLUT();
131}
132
133//_____________________________________________________________________________
9d47e237 134void AliGeomManager::SetGeometry(TGeoManager *geom)
135{
136 // Load already active geometry
137 if (!geom) AliFatalClass("Pointer to the active geometry is 0x0!");
138
139 fgGeometry = geom;
9d47e237 140 InitPNEntriesLUT();
9d47e237 141}
142
143//_____________________________________________________________________________
67dd5535 144AliGeomManager::AliGeomManager():
36b010bf 145 TObject()
67dd5535 146{
147 // default constructor
148}
149
150//_____________________________________________________________________________
151AliGeomManager::~AliGeomManager()
152{
153 // dummy destructor
67dd5535 154}
155
156//_____________________________________________________________________________
157Int_t AliGeomManager::LayerSize(Int_t layerId)
158{
159 // Get the layer size for layer corresponding to layerId.
160 // Implemented only for ITS,TPC,TRD,TOF and HMPID
161 //
162 if (layerId < kFirstLayer || layerId >= kLastLayer) {
163 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
164 return 0;
165 }
166 else {
167 return fgLayerSize[layerId - kFirstLayer];
5aedd709 168 }
67dd5535 169}
170
171//_____________________________________________________________________________
172const char* AliGeomManager::LayerName(Int_t layerId)
173{
174 // Get the layer name corresponding to layerId.
175 // Implemented only for ITS,TPC,TRD,TOF and HMPID
176 //
177 if (layerId < kFirstLayer || layerId >= kLastLayer) {
178 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
179 return "Invalid Layer!";
180 }
181 else {
182 return fgLayerName[layerId - kFirstLayer];
5aedd709 183 }
67dd5535 184}
185
186//_____________________________________________________________________________
187UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
188{
189 // From detector (layer) name and module number (according to detector
190 // internal numbering) build the unique numerical identity of that volume
191 // inside ALICE
192 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
193 // remaining 11 for module ID inside det (2048 possible values).
194 // NO check for validity of given modId inside the layer for speed's sake.
195 //
196 return ((UShort_t(layerId) << 11) | UShort_t(modId));
197}
198
199//_____________________________________________________________________________
200UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
201{
202 // From detector (layer) name and module number (according to detector
203 // internal numbering) build the unique numerical identity of that volume
204 // inside ALICE
205 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
206 // remaining 11 for module ID inside det (2048 possible values).
207 // NO check for validity of given modId inside the layer for speed's sake.
208 //
209 return ((UShort_t(layerId) << 11) | UShort_t(modId));
210}
211
212//_____________________________________________________________________________
213UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
214{
215 // From detector (layer) name and module number (according to detector
216 // internal numbering) build the unique numerical identity of that volume
217 // inside ALICE
218 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
219 // remaining 11 for module ID inside det (2048 possible values).
220 // Check validity of given modId inside the layer.
221 //
222 if(modId < 0 || modId >= LayerSize(layerId)){
223 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
224 return 0;
225 }
226 return ((UShort_t(layerId) << 11) | UShort_t(modId));
227}
228
229//_____________________________________________________________________________
230UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
231{
232 // From detector (layer) name and module number (according to detector
233 // internal numbering) build the unique numerical identity of that volume
234 // inside ALICE
235 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
236 // remaining 11 for module ID inside det (2048 possible values).
237 // Check validity of given modId inside the layer.
238 //
239 if(modId < 0 || modId >= LayerSize(layerId)){
240 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
241 return 0;
242 }
243 return ((UShort_t(layerId) << 11) | UShort_t(modId));
244}
245
246//_____________________________________________________________________________
247AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
248{
249 // From voluid, unique numerical identity of that volume inside ALICE,
250 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
251 // remaining 11 for module ID inside det (2048 possible values)), return
252 // the identity of the layer to which that volume belongs and sets the
253 // argument modId to the identity of that volume internally to the layer.
254 // NO check for validity of given voluid for speed's sake.
255 //
256 modId = voluid & 0x7ff;
257
258 return VolUIDToLayer(voluid);
259}
260
261//_____________________________________________________________________________
262AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
263{
264 // From voluid, unique numerical identity of that volume inside ALICE,
265 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
266 // remaining 11 for module ID inside det (2048 possible values)), return
267 // the identity of the layer to which that volume belongs
268 // NO check for validity of given voluid for speed's sake.
269 //
270 return ELayerID(voluid >> 11);
271}
272
273//_____________________________________________________________________________
274AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
275{
276 // From voluid, unique numerical identity of that volume inside ALICE,
277 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
278 // remaining 11 for module ID inside det (2048 possible values)), returns
279 // the identity of the layer to which that volume belongs and sets the
280 // argument modId to the identity of that volume internally to the layer.
281 // Checks the validity of the given voluid
282 //
283 ELayerID layId = VolUIDToLayerSafe(voluid);
284 if(layId){
285 Int_t mId = Int_t(voluid & 0x7ff);
286 if( mId>=0 && mId<LayerSize(layId)){
287 modId = mId;
288 return layId;
289 }
290 }
291
292 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
293 modId = -1;
294 return kInvalidLayer;
295
296}
297
298//_____________________________________________________________________________
299AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
300{
301 // From voluid, unique numerical identity of that volume inside ALICE,
302 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
303 // remaining 11 for module ID inside det (2048 possible values)), returns
304 // the identity of the layer to which that volume belongs
305 // Checks the validity of the given voluid
306 //
307 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
308
309 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
310 return kInvalidLayer;
311
312}
313
314//_____________________________________________________________________________
315Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
316{
317 // Get the alignment object which corresponds to the symbolic volume name
318 // symname (in case equal to the TGeo volume path)
319 // The method is extremely slow due to the searching by string,
320 // therefore it should be used with great care!!
321 // This method returns FALSE if the symname of the object was not
322 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
323 // associated to the TGeoPNEntry was not valid.
324 //
325
326 // Reset the alignment object
327 alobj.SetPars(0,0,0,0,0,0);
328 alobj.SetSymName(symname);
329
36b010bf 330 if (!fgGeometry || !fgGeometry->IsClosed()) {
67dd5535 331 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
332 return kFALSE;
333 }
334
36b010bf 335 if (!fgGeometry->GetListOfPhysicalNodes()) {
67dd5535 336 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
337 return kFALSE;
338 }
339
67dd5535 340 const char *path;
36b010bf 341 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 342 if(pne){
343 path = pne->GetTitle();
344 }else{
345 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
346 path = symname;
347 }
36b010bf 348 TObjArray* nodesArr = fgGeometry->GetListOfPhysicalNodes();
67dd5535 349 TGeoPhysicalNode* node = NULL;
350 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
351 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
352 const char *nodePath = tempNode->GetName();
353 if (strcmp(path,nodePath) == 0) {
354 node = tempNode;
355 break;
356 }
357 }
358
359 if (!node) {
36b010bf 360 if (!fgGeometry->cd(path)) {
67dd5535 361 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
362 return kFALSE;
363 }
364 else {
365 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
366 return kTRUE;
367 }
368 }
369
370 TGeoHMatrix align,gprime,g,ginv,l;
371 gprime = *node->GetMatrix();
372 l = *node->GetOriginalMatrix();
373 g = *node->GetMatrix(node->GetLevel()-1);
374 g *= l;
375 ginv = g.Inverse();
376 align = gprime * ginv;
377
378 return alobj.SetMatrix(align);
379}
380
381
382//_____________________________________________________________________________
383void AliGeomManager::InitAlignObjFromGeometry()
384{
5aedd709 385 // Loop over all alignable volumes and extract
386 // the corresponding alignment objects from
387 // the TGeo geometry
67dd5535 388
389 if(fgAlignObjs[0]) return;
5aedd709 390
67dd5535 391 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
392 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
393 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
394 UShort_t volid = LayerToVolUID(iLayer,iModule);
90dbf5fb 395 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjParams("",volid,0,0,0,0,0,0,kTRUE);
67dd5535 396 const char *symname = SymName(volid);
397 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
398 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
399 }
400 }
5aedd709 401
67dd5535 402}
403
404//_____________________________________________________________________________
5aedd709 405AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid)
406{
67dd5535 407 // Returns the alignment object for given volume ID
408 //
409 Int_t modId;
410 ELayerID layerId = VolUIDToLayer(voluid,modId);
411 return GetAlignObj(layerId,modId);
412}
413
414//_____________________________________________________________________________
415AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
416{
417 // Returns pointer to alignment object given its layer and module ID
418 //
419 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
420 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
421 return NULL;
422 }
423 InitAlignObjFromGeometry();
424
425 return fgAlignObjs[layerId-kFirstLayer][modId];
426}
427
428//_____________________________________________________________________________
5aedd709 429const char* AliGeomManager::SymName(UShort_t voluid)
430{
67dd5535 431 // Returns the symbolic volume name for given volume ID
432 //
433 Int_t modId;
434 ELayerID layerId = VolUIDToLayer(voluid,modId);
435 return SymName(layerId,modId);
436}
437
438//_____________________________________________________________________________
439const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
440{
441 // Returns the symbolic volume name given for a given layer
442 // and module ID
443 //
ff5970a3 444 if(!fgGeometry){
445 AliErrorClass("No geometry instance loaded yet!");
446 return NULL;
447 }
67dd5535 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));
450 return NULL;
451 }
67dd5535 452
a8629c62 453 TGeoPNEntry* pne = fgPNEntry[layerId-kFirstLayer][modId];
454 if(!pne)
455 {
456 AliWarningClass(Form("Module %d of layer %s is not activated!",modId,LayerName(layerId)));
457 return NULL;
458 }
459 return pne->GetName();
460
67dd5535 461}
462
463//_____________________________________________________________________________
9257a1bd 464Bool_t AliGeomManager::CheckSymNamesLUT(const char* /*detsToBeChecked*/)
67dd5535 465{
0bf7aade 466 // Check the look-up table which associates the unique numerical identity of
467 // each alignable volume to the corresponding symbolic volume name.
468 // The LUT is now hold inside the geometry and handled by TGeo.
469 // The method is meant to be launched when loading a geometry to verify that
470 // no changes in the symbolic names have been introduced, which would prevent
471 // backward compatibility with alignment objects.
472 // To accept both complete and partial geometry, this method skips the check
473 // for TRD and TOF volumes which are missing in the partial geometry.
474 //
67dd5535 475
ff5970a3 476// TString detsString(detsToBeChecked);
477// if(detsString.Contains("ALL")) detsString="ITS TPC TOF TRD HMPID PHOS EMCAL";
478
479 // Temporary measure to face the case of reconstruction over detectors not present in the geometry
480 TString detsString = "";
481 if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
482 if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
83364444 483
484 TString tofsm;
485 TString baseTof("ALIC_1/B077_1/BSEGMO");
486 TString middleTof("_1/BTOF");
487 TString trailTof("_1/FTOA_0");
488 Bool_t tofActive=kFALSE;
489 Bool_t tofSMs[18];
490 for(Int_t sm=0; sm<18; sm++)
491 {
492 tofSMs[sm]=kFALSE;
493 tofsm=baseTof;
494 tofsm += sm;
495 tofsm += middleTof;
496 tofsm += sm;
497 tofsm += trailTof;
498 if(fgGeometry->CheckPath(tofsm.Data()))
499 {
500 tofActive=kTRUE;
501 tofSMs[sm]=kTRUE;
502 }
503 }
504 if(tofActive) detsString+="TOF ";
505
506 TString trdsm;
507 TString baseTrd("ALIC_1/B077_1/BSEGMO");
508 TString middleTrd("_1/BTRD");
509 TString trailTrd("_1/UTR1_1");
510 Bool_t trdActive=kFALSE;
511 Bool_t trdSMs[18];
512 for(Int_t sm=0; sm<18; sm++)
513 {
514 trdSMs[sm]=kFALSE;
515 trdsm=baseTrd;
516 trdsm += sm;
517 trdsm += middleTrd;
518 trdsm += sm;
519 trdsm += trailTrd;
520 if(fgGeometry->CheckPath(trdsm.Data()))
521 {
522 trdActive=kTRUE;
523 trdSMs[sm]=kTRUE;
524 }
525 }
526 if(trdActive) detsString+="TRD ";
527
ff5970a3 528 if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
6ead0654 529
530 TString phosMod, cpvMod;
531 TString basePhos("ALIC_1/PHOS_");
532 Bool_t phosActive=kFALSE;
533 Bool_t cpvActive=kFALSE;
534 Bool_t phosMods[5];
535 for(Int_t pmod=0; pmod<5; pmod++)
536 {
537 phosMods[pmod]=kFALSE;
538 phosMod = basePhos;
539 phosMod += (pmod+1);
540 cpvMod = phosMod;
541 cpvMod += "/PCPV_1";
542 if(fgGeometry->CheckPath(phosMod.Data()))
543 {
544 phosActive=kTRUE;
545 phosMods[pmod]=kTRUE;
546 if(fgGeometry->CheckPath(cpvMod.Data())) cpvActive=kTRUE;
547 }
548 }
549 if(phosActive) detsString+="PHOS ";
550
ff5970a3 551 if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
552
67dd5535 553 TString symname;
0bf7aade 554 const char* sname;
555 TGeoPNEntry* pne = 0x0;
556 Int_t uid; // global unique identity
557 Int_t modnum; // unique id inside layer; in the following, set it to 0 at the start of each layer
67dd5535 558
ff5970a3 559 if(detsString.Contains("ITS")){
67dd5535 560 /********************* ITS layers ***********************/
ff5970a3 561 AliDebugClass(2,"Checking consistency of symbolic names for ITS layers");
562 TString strSPD = "ITS/SPD";
563 TString strSDD = "ITS/SDD";
564 TString strSSD = "ITS/SSD";
565 TString strStave = "/Stave";
566 TString strHalfStave = "/HalfStave";
567 TString strLadder = "/Ladder";
568 TString strSector = "/Sector";
569 TString strSensor = "/Sensor";
570 TString strEntryName1;
571 TString strEntryName2;
572 TString strEntryName3;
573
574 /********************* SPD layer1 ***********************/
575 {
576 modnum = 0;
577
578 for(Int_t cSect = 0; cSect<10; cSect++){
579 strEntryName1 = strSPD;
580 strEntryName1 += 0;
581 strEntryName1 += strSector;
582 strEntryName1 += cSect;
583
584 for(Int_t cStave =0; cStave<2; cStave++){
585 strEntryName2 = strEntryName1;
586 strEntryName2 += strStave;
587 strEntryName2 += cStave;
588
589 for (Int_t cHS=0; cHS<2; cHS++) {
590 strEntryName3 = strEntryName2;
591 strEntryName3 += strHalfStave;
592 strEntryName3 += cHS;
593
594 for(Int_t cLad =0; cLad<2; cLad++){
595 symname = strEntryName3;
596 symname += strLadder;
597 symname += cLad+cHS*2;
598 uid = LayerToVolUID(kSPD1,modnum++);
599 pne = fgGeometry->GetAlignableEntryByUID(uid);
600 if(!pne)
601 {
602 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
603 return kFALSE;
604 }
605 sname = pne->GetName();
606 if(symname.CompareTo(sname))
607 {
608 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
609 "Expected was %s, found was %s!", uid, symname.Data(), sname));
610 return kFALSE;
611 }
0bf7aade 612 }
8f8273a4 613 }
67dd5535 614 }
615 }
616 }
ff5970a3 617
618 /********************* SPD layer2 ***********************/
619 {
620 modnum = 0;
621
622 for(Int_t cSect = 0; cSect<10; cSect++){
623 strEntryName1 = strSPD;
624 strEntryName1 += 1;
625 strEntryName1 += strSector;
626 strEntryName1 += cSect;
627
628 for(Int_t cStave =0; cStave<4; cStave++){
629 strEntryName2 = strEntryName1;
630 strEntryName2 += strStave;
631 strEntryName2 += cStave;
632
633 for (Int_t cHS=0; cHS<2; cHS++) {
634 strEntryName3 = strEntryName2;
635 strEntryName3 += strHalfStave;
636 strEntryName3 += cHS;
637
638 for(Int_t cLad =0; cLad<2; cLad++){
639 symname = strEntryName3;
640 symname += strLadder;
641 symname += cLad+cHS*2;
642 uid = LayerToVolUID(kSPD2,modnum++);
643 pne = fgGeometry->GetAlignableEntryByUID(uid);
644 if(!pne)
645 {
646 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
647 return kFALSE;
648 }
649 sname = pne->GetName();
650 if(symname.CompareTo(sname))
651 {
652 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
653 "Expected was %s, found was %s!", uid, symname.Data(), sname));
654 return kFALSE;
655 }
0bf7aade 656 }
8f8273a4 657 }
67dd5535 658 }
659 }
660 }
ff5970a3 661
662 /********************* SDD layer1 ***********************/
663 {
664 modnum=0;
665
666 for(Int_t c1 = 1; c1<=14; c1++){
667 strEntryName1 = strSDD;
668 strEntryName1 += 2;
669 strEntryName1 +=strLadder;
670 strEntryName1 += (c1-1);
671 for(Int_t c2 =1; c2<=6; c2++){
672 symname = strEntryName1;
673 symname += strSensor;
674 symname += (c2-1);
675 uid = LayerToVolUID(kSDD1,modnum++);
676 pne = fgGeometry->GetAlignableEntryByUID(uid);
677 if(!pne)
678 {
679 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
680 return kFALSE;
681 }
682 sname = pne->GetName();
683 if(symname.CompareTo(sname))
684 {
685 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
686 "Expected was %s, found was %s!", uid, symname.Data(), sname));
687 return kFALSE;
688 }
689 }
690 }
691 }
692
693 /********************* SDD layer2 ***********************/
694 {
695 modnum=0;
696
697 for(Int_t c1 = 1; c1<=22; c1++){
698 strEntryName1 = strSDD;
699 strEntryName1 += 3;
700 strEntryName1 +=strLadder;
701 strEntryName1 += (c1-1);
702 for(Int_t c2 = 1; c2<=8; c2++){
703 symname = strEntryName1;
704 symname += strSensor;
705 symname += (c2-1);
706 uid = LayerToVolUID(kSDD2,modnum++);
707 pne = fgGeometry->GetAlignableEntryByUID(uid);
708 if(!pne)
709 {
710 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
711 return kFALSE;
712 }
713 sname = pne->GetName();
714 if(symname.CompareTo(sname))
715 {
716 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
717 "Expected was %s, found was %s!", uid, symname.Data(), sname));
718 return kFALSE;
719 }
720 }
721 }
722 }
723
724 /********************* SSD layer1 ***********************/
725 {
726 modnum=0;
727
728 for(Int_t c1 = 1; c1<=34; c1++){
729 strEntryName1 = strSSD;
730 strEntryName1 += 4;
731 strEntryName1 +=strLadder;
732 strEntryName1 += (c1-1);
733 for(Int_t c2 = 1; c2<=22; c2++){
734 symname = strEntryName1;
735 symname += strSensor;
736 symname += (c2-1);
737 uid = LayerToVolUID(kSSD1,modnum++);
738 pne = fgGeometry->GetAlignableEntryByUID(uid);
739 if(!pne)
740 {
741 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
742 return kFALSE;
743 }
744 sname = pne->GetName();
745 if(symname.CompareTo(sname))
746 {
747 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
748 "Expected was %s, found was %s!", uid, symname.Data(), sname));
749 return kFALSE;
750 }
751 }
752 }
753 }
754
755 /********************* SSD layer2 ***********************/
756 {
757 modnum=0;
758
759 for(Int_t c1 = 1; c1<=38; c1++){
760 strEntryName1 = strSSD;
761 strEntryName1 += 5;
762 strEntryName1 +=strLadder;
763 strEntryName1 += (c1-1);
764 for(Int_t c2 = 1; c2<=25; c2++){
765 symname = strEntryName1;
766 symname += strSensor;
767 symname += (c2-1);
768 uid = LayerToVolUID(kSSD2,modnum++);
769 pne = fgGeometry->GetAlignableEntryByUID(uid);
770 if(!pne)
771 {
772 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
773 return kFALSE;
774 }
775 sname = pne->GetName();
776 if(symname.CompareTo(sname))
777 {
778 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
779 "Expected was %s, found was %s!", uid, symname.Data(), sname));
780 return kFALSE;
781 }
782 }
783 }
784 }
785
786 AliDebugClass(2,"Consistency check for ITS symbolic names finished successfully.");
67dd5535 787 }
788
ff5970a3 789 if(detsString.Contains("TPC"))
67dd5535 790 {
ff5970a3 791 /*************** TPC inner and outer layers ****************/
792
793 AliDebugClass(2,"Checking consistency of symbolic names for TPC layers");
794 TString sAsector="TPC/EndcapA/Sector";
795 TString sCsector="TPC/EndcapC/Sector";
796 TString sInner="/InnerChamber";
797 TString sOuter="/OuterChamber";
798
799 /*************** TPC inner chambers' layer ****************/
800 {
801 modnum = 0;
67dd5535 802
ff5970a3 803 for(Int_t cnt=1; cnt<=18; cnt++)
804 {
805 symname = sAsector;
806 symname += cnt;
807 symname += sInner;
808 uid = LayerToVolUID(kTPC1,modnum++);
0bf7aade 809 pne = fgGeometry->GetAlignableEntryByUID(uid);
810 if(!pne)
811 {
812 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
813 return kFALSE;
814 }
815 sname = pne->GetName();
816 if(symname.CompareTo(sname))
817 {
818 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
819 "Expected was %s, found was %s!", uid, symname.Data(), sname));
820 return kFALSE;
821 }
67dd5535 822 }
67dd5535 823
ff5970a3 824 for(Int_t cnt=1; cnt<=18; cnt++)
825 {
826 symname = sCsector;
827 symname += cnt;
828 symname += sInner;
829 uid = LayerToVolUID(kTPC1,modnum++);
0bf7aade 830 pne = fgGeometry->GetAlignableEntryByUID(uid);
831 if(!pne)
832 {
833 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
834 return kFALSE;
835 }
836 sname = pne->GetName();
837 if(symname.CompareTo(sname))
838 {
839 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
840 "Expected was %s, found was %s!", uid, symname.Data(), sname));
841 return kFALSE;
842 }
67dd5535 843 }
844 }
67dd5535 845
ff5970a3 846 /*************** TPC outer chambers' layer ****************/
847 {
848 modnum = 0;
67dd5535 849
ff5970a3 850 for(Int_t cnt=1; cnt<=18; cnt++)
851 {
852 symname = sAsector;
853 symname += cnt;
854 symname += sOuter;
855 uid = LayerToVolUID(kTPC2,modnum++);
0bf7aade 856 pne = fgGeometry->GetAlignableEntryByUID(uid);
857 if(!pne)
858 {
859 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
860 return kFALSE;
861 }
862 sname = pne->GetName();
863 if(symname.CompareTo(sname))
864 {
865 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
866 "Expected was %s, found was %s!", uid, symname.Data(), sname));
867 return kFALSE;
868 }
67dd5535 869 }
67dd5535 870
ff5970a3 871 for(Int_t cnt=1; cnt<=18; cnt++)
872 {
873 symname = sCsector;
874 symname += cnt;
875 symname += sOuter;
876 uid = LayerToVolUID(kTPC2,modnum++);
0bf7aade 877 pne = fgGeometry->GetAlignableEntryByUID(uid);
878 if(!pne)
879 {
880 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
881 return kFALSE;
882 }
883 sname = pne->GetName();
884 if(symname.CompareTo(sname))
885 {
886 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
887 "Expected was %s, found was %s!", uid, symname.Data(), sname));
888 return kFALSE;
889 }
67dd5535 890 }
891 }
67dd5535 892
ff5970a3 893 AliDebugClass(2,"Consistency check for TPC symbolic names finished successfully.");
67dd5535 894 }
895
ff5970a3 896 if(detsString.Contains("TOF"))
67dd5535 897 {
ff5970a3 898 /********************* TOF layer ***********************/
67dd5535 899
ff5970a3 900 AliDebugClass(2,"Checking consistency of symbolic names for TOF layers");
67dd5535 901 modnum=0;
ff5970a3 902
67dd5535 903 Int_t nstrA=15;
904 Int_t nstrB=19;
905 Int_t nstrC=19;
906 Int_t nSectors=18;
907 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
0bf7aade 908
67dd5535 909 TString snSM = "TOF/sm";
910 TString snSTRIP = "/strip";
911
912 for (Int_t isect = 0; isect < nSectors; isect++) {
913 for (Int_t istr = 1; istr <= nStrips; istr++) {
914 symname = snSM;
915 symname += Form("%02d",isect);
916 symname += snSTRIP;
917 symname += Form("%02d",istr);
0bf7aade 918 uid = LayerToVolUID(kTOF,modnum++);
83364444 919 if(!tofSMs[isect]) continue; // taking possible missing TOF sectors (partial geometry) into account
920 AliDebugClass(2,Form("Consistency check for symnames of TOF supermodule %d.",isect));
0bf7aade 921 if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue; //taking holes into account
922 pne = fgGeometry->GetAlignableEntryByUID(uid);
923 if(!pne)
924 {
925 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
926 return kFALSE;
927 }
928 sname = pne->GetName();
929 if(symname.CompareTo(sname))
930 {
931 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
932 "Expected was %s, found was %s!", uid, symname.Data(), sname));
933 return kFALSE;
934 }
67dd5535 935 }
936 }
ff5970a3 937
938 AliDebugClass(2,"Consistency check for TOF symbolic names finished successfully.");
67dd5535 939 }
940
ff5970a3 941 if(detsString.Contains("HMPID"))
67dd5535 942 {
ff5970a3 943 /********************* HMPID layer ***********************/
944
945 AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
67dd5535 946 TString str = "/HMPID/Chamber";
947
948 for (modnum=0; modnum < 7; modnum++) {
949 symname = str;
950 symname += modnum;
0bf7aade 951 uid = LayerToVolUID(kHMPID,modnum);
952 pne = fgGeometry->GetAlignableEntryByUID(uid);
953 if(!pne)
954 {
955 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
956 return kFALSE;
957 }
958 sname = pne->GetName();
959 if(symname.CompareTo(sname))
960 {
961 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
962 "Expected was %s, found was %s!", uid, symname.Data(), sname));
963 return kFALSE;
964 }
67dd5535 965 }
ff5970a3 966
967 AliDebugClass(2,"Consistency check for HMPID symbolic names finished successfully.");
67dd5535 968 }
969
ff5970a3 970 if(detsString.Contains("TRD"))
67dd5535 971 {
ff5970a3 972 /********************* TRD layers 1-6 *******************/
973 //!! 6 layers with index increasing in outwards direction
974
975 AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
67dd5535 976 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
977
978 TString snStr = "TRD/sm";
979 TString snApp1 = "/st";
980 TString snApp2 = "/pl";
981
982 for(Int_t layer=0; layer<6; layer++){
983 modnum=0;
984 for (Int_t isect = 0; isect < 18; isect++) {
985 for (Int_t icham = 0; icham < 5; icham++) {
986 symname = snStr;
987 symname += Form("%02d",isect);
988 symname += snApp1;
989 symname += icham;
990 symname += snApp2;
991 symname += layer;
0bf7aade 992 uid = LayerToVolUID(arTRDlayId[layer],modnum++);
83364444 993 if(!trdSMs[isect]) continue;
994 AliDebugClass(2,Form("Consistency check for symnames of TRD supermodule %d.",isect));
0bf7aade 995 if ((isect==13 || isect==14 || isect==15) && icham==2) continue; //keeping holes into account
996 pne = fgGeometry->GetAlignableEntryByUID(uid);
997 if(!pne)
998 {
999 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1000 return kFALSE;
1001 }
1002 sname = pne->GetName();
1003 if(symname.CompareTo(sname))
1004 {
1005 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1006 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1007 return kFALSE;
1008 }
67dd5535 1009 }
1010 }
1011 }
ff5970a3 1012
1013 AliDebugClass(2,"Consistency check for TRD symbolic names finished successfully.");
67dd5535 1014 }
df117114 1015
ff5970a3 1016 if(detsString.Contains("PHOS"))
df117114 1017 {
ff5970a3 1018 /********************* PHOS EMC layer ***********************/
df117114 1019
ff5970a3 1020 AliDebugClass(2,"Checking consistency of symbolic names for PHOS layers");
1021
ff5970a3 1022 TString str = "PHOS/Module";
1023 modnum=0;
1024
6ead0654 1025 for (Int_t iModule=0; iModule < 5; iModule++) {
1026 if(!phosMods[iModule]) continue;
ff5970a3 1027 symname = str;
6ead0654 1028 symname += (iModule+1);
1029 uid = LayerToVolUID(kPHOS1,iModule);
ff5970a3 1030 pne = fgGeometry->GetAlignableEntryByUID(uid);
1031 if(!pne)
1032 {
1033 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1034 return kFALSE;
1035 }
1036 sname = pne->GetName();
1037 if(symname.CompareTo(sname))
1038 {
1039 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1040 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1041 return kFALSE;
1042 }
6ead0654 1043 /********************* PHOS CPV layer ***********************/
1044 if(!cpvActive) continue;
ff5970a3 1045 symname += "/CPV";
6ead0654 1046 uid = LayerToVolUID(kPHOS2,iModule);
ff5970a3 1047 pne = fgGeometry->GetAlignableEntryByUID(uid);
1048 if(!pne)
1049 {
1050 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1051 return kFALSE;
1052 }
1053 sname = pne->GetName();
1054 if(symname.CompareTo(sname))
1055 {
1056 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1057 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1058 return kFALSE;
1059 }
0bf7aade 1060 }
ff5970a3 1061 AliDebugClass(2,"Consistency check for PHOS symbolic names finished successfully.");
f47b9233 1062 }
1063
ff5970a3 1064 if(detsString.Contains("EMCAL"))
3dfc15c0 1065 {
ff5970a3 1066 /********************* EMCAL layer ***********************/
1067
1068 AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
3dfc15c0 1069 TString str = "EMCAL/FullSupermodule";
1070 modnum=0;
1071
1072 for (Int_t iModule=1; iModule <= 12; iModule++) {
1073 symname = str;
1074 symname += iModule;
1075 if(iModule >10) {
1076 symname = "EMCAL/HalfSupermodule";
1077 symname += iModule-10;
1078 }
1079 modnum = iModule-1;
0bf7aade 1080 uid = LayerToVolUID(kEMCAL,modnum);
1081 pne = fgGeometry->GetAlignableEntryByUID(uid);
1082 if(!pne)
1083 {
1084 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1085 return kFALSE;
1086 }
1087 sname = pne->GetName();
1088 if(symname.CompareTo(sname))
1089 {
1090 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1091 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1092 return kFALSE;
1093 }
3dfc15c0 1094 }
ff5970a3 1095
1096 AliDebugClass(2,"Consistency check for EMCAL symbolic names finished successfully.");
3dfc15c0 1097 }
0bf7aade 1098
1099 return kTRUE;
f47b9233 1100
67dd5535 1101}
1102
1103//_____________________________________________________________________________
1104void AliGeomManager::InitPNEntriesLUT()
1105{
1106 // Initialize the look-up table which associates the unique
1107 // numerical identity of each alignable volume to the
1108 // corresponding TGeoPNEntry.
1109 // The LUTs are static; they are created at the creation of the
1110 // AliGeomManager instance and recreated if the geometry has changed
1111 //
36b010bf 1112 if (fgPNEntry[0]) return;
67dd5535 1113
36b010bf 1114 if(!fgGeometry) {
1115 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
1116 return;
1117 }
25fad4e5 1118
67dd5535 1119 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
36b010bf 1120 fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
1121 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
0bf7aade 1122 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
36b010bf 1123 }
1124 }
1125}
1126
67dd5535 1127//______________________________________________________________________
1128TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
1129{
5aedd709 1130 // Get the global transformation matrix for a given PNEntry
67dd5535 1131 // by quering the TGeoManager
1132
36b010bf 1133 if (!fgGeometry || !fgGeometry->IsClosed()) {
25fad4e5 1134 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1135 return NULL;
1136 }
5aedd709 1137
67dd5535 1138 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
1139 if (pnode) return pnode->GetMatrix();
1140
1141 const char* path = pne->GetTitle();
36b010bf 1142 if (!fgGeometry->cd(path)) {
67dd5535 1143 AliErrorClass(Form("Volume path %s not valid!",path));
1144 return NULL;
1145 }
36b010bf 1146 return fgGeometry->GetCurrentMatrix();
67dd5535 1147}
1148
1149//______________________________________________________________________
1150TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
1151{
1152 // Get the global transformation matrix for a given alignable volume
1153 // identified by its unique ID 'index' by quering the TGeoManager
1154
67dd5535 1155 TGeoPNEntry *pne = GetPNEntry(index);
1156 if (!pne) return NULL;
1157
1158 return GetMatrix(pne);
1159}
1160
1161//______________________________________________________________________
1162TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
1163{
1164 // Get the global transformation matrix for a given alignable volume
1165 // identified by its symbolic name 'symname' by quering the TGeoManager
1166
36b010bf 1167 if (!fgGeometry || !fgGeometry->IsClosed()) {
1168 AliErrorClass("No active geometry or geometry not yet closed!");
1169 return NULL;
1170 }
1171
1172 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 1173 if (!pne) return NULL;
1174
1175 return GetMatrix(pne);
1176}
1177
1178//______________________________________________________________________
1179Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
1180{
1181 // Get the translation vector for a given module 'index'
1182 // by quering the TGeoManager
1183
1184 TGeoHMatrix *m = GetMatrix(index);
1185 if (!m) return kFALSE;
1186
1187 Double_t *trans = m->GetTranslation();
1188 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1189
1190 return kTRUE;
1191}
1192
1193//______________________________________________________________________
1194Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
1195{
1196 // Get the rotation matrix for a given module 'index'
1197 // by quering the TGeoManager
1198
1199 TGeoHMatrix *m = GetMatrix(index);
1200 if (!m) return kFALSE;
1201
1202 Double_t *rot = m->GetRotationMatrix();
1203 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1204
1205 return kTRUE;
1206}
1207
5d534fe3 1208//_____________________________________________________________________________
1209Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
1210{
1211 // The method sets the matrix passed as argument as the global delta
1212 // (for the volume referred by the unique index) including the displacements
1213 // of all parent volumes in the branch.
1214 //
5d534fe3 1215
1216 TGeoHMatrix go,invgo;
1217 go = *GetOrigGlobalMatrix(index);
1218 invgo = go.Inverse();
5aedd709 1219 inclusiveD = *GetMatrix(index);
5d534fe3 1220 inclusiveD.Multiply(&invgo);
1221
1222 return kTRUE;
1223}
1224
1225//_____________________________________________________________________________
1226Bool_t AliGeomManager::GetDeltaForBranch(AliAlignObj& aao, TGeoHMatrix &inclusiveD)
1227{
1228 // The method sets the matrix passed as argument as the global delta
1229 // (for the volume referred by the alignment object) including the displacements
1230 // of all parent volumes in the brach.
1231 //
1232 Int_t index = aao.GetVolUID();
1233 if(!index){
1234 AliErrorClass("Either the alignment object or its index are not valid");
1235 return kFALSE;
1236 }
1237 return GetDeltaForBranch(index, inclusiveD);
1238}
1239
36b010bf 1240//______________________________________________________________________
1241Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
67dd5535 1242{
36b010bf 1243 // Get the global transformation matrix (ideal geometry) for a given alignable volume
0bf7aade 1244 // The alignable volume is identified by 'symname' which has to be either a valid symbolic
1245 // name, the query being performed after alignment, or a valid volume path if the query is
1246 // performed before alignment.
1247 //
36b010bf 1248 m.Clear();
67dd5535 1249
36b010bf 1250 if (!fgGeometry || !fgGeometry->IsClosed()) {
1251 AliErrorClass("No active geometry or geometry not yet closed!");
67dd5535 1252 return kFALSE;
1253 }
36b010bf 1254 if (!fgGeometry->GetListOfPhysicalNodes()) {
67dd5535 1255 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
36b010bf 1256 if (!fgGeometry->cd(symname)) {
67dd5535 1257 AliErrorClass(Form("Volume path %s not valid!",symname));
1258 return kFALSE;
1259 }
1260 else {
36b010bf 1261 m = *fgGeometry->GetCurrentMatrix();
67dd5535 1262 return kTRUE;
1263 }
1264 }
1265
36b010bf 1266 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 1267 const char* path = NULL;
67dd5535 1268 if(pne){
0bf7aade 1269 m = *pne->GetGlobalOrig();
1270 return kTRUE;
67dd5535 1271 }else{
1272 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
1273 path=symname;
1274 }
1275
36b010bf 1276 return GetOrigGlobalMatrixFromPath(path,m);
1277}
1278
1279//_____________________________________________________________________________
1280Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
1281{
5aedd709 1282 // The method returns the global matrix for the volume identified by
1283 // 'path' in the ideal detector geometry.
1284 // The output global matrix is stored in 'm'.
1285 // Returns kFALSE in case TGeo has not been initialized or the volume
1286 // path is not valid.
36b010bf 1287 //
1288 m.Clear();
1289
1290 if (!fgGeometry || !fgGeometry->IsClosed()) {
1291 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
67dd5535 1292 return kFALSE;
1293 }
1294
36b010bf 1295 if (!fgGeometry->CheckPath(path)) {
1296 AliErrorClass(Form("Volume path %s not valid!",path));
1297 return kFALSE;
1298 }
67dd5535 1299
36b010bf 1300 TIter next(fgGeometry->GetListOfPhysicalNodes());
1301 fgGeometry->cd(path);
67dd5535 1302
36b010bf 1303 while(fgGeometry->GetLevel()){
67dd5535 1304
1305 TGeoPhysicalNode *physNode = NULL;
1306 next.Reset();
36b010bf 1307 TGeoNode *node = fgGeometry->GetCurrentNode();
67dd5535 1308 while ((physNode=(TGeoPhysicalNode*)next()))
1309 if (physNode->GetNode() == node) break;
1310
1311 TGeoMatrix *lm = NULL;
1312 if (physNode) {
5aedd709 1313 lm = physNode->GetOriginalMatrix();
1314 if (!lm) lm = node->GetMatrix();
67dd5535 1315 } else
1316 lm = node->GetMatrix();
1317
1318 m.MultiplyLeft(lm);
1319
36b010bf 1320 fgGeometry->CdUp();
67dd5535 1321 }
1322
1323 return kTRUE;
1324}
1325
36b010bf 1326//_____________________________________________________________________________
1327TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
1328{
1329 // The method returns global matrix for the ideal detector geometry
1330 // using the corresponding TGeoPNEntry as an input.
5aedd709 1331 // The returned pointer should be copied by the user, since its content could
1332 // be overwritten by a following call to the method.
1333 // In case of missing TGeoManager the method returns NULL.
1334 //
36b010bf 1335 if (!fgGeometry || !fgGeometry->IsClosed()) {
1336 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1337 return NULL;
1338 }
1339
0bf7aade 1340 return pne->GetGlobalOrig();
36b010bf 1341}
1342
67dd5535 1343//______________________________________________________________________
36b010bf 1344TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
67dd5535 1345{
5aedd709 1346 // The method returns global matrix from the ideal detector geometry
1347 // for the volume identified by its index.
1348 // The returned pointer should be copied by the user, since its content could
1349 // be overwritten by a following call to the method.
1350 // In case of missing TGeoManager the method returns NULL.
1351 // If possible, the method uses the LUT of original ideal matrices
1352 // for fast access. The LUT is reset in case a
36b010bf 1353 // new geometry is loaded.
5aedd709 1354 //
0bf7aade 1355 TGeoPNEntry* pne = GetPNEntry(index);
1356 return pne->GetGlobalOrig();
67dd5535 1357}
1358
1359//______________________________________________________________________
1360Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1361{
1362 // Get the original translation vector (ideal geometry)
1363 // for a given module 'index' by quering the TGeoManager
1364
36b010bf 1365 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1366 if (!m) return kFALSE;
67dd5535 1367
36b010bf 1368 Double_t *trans = m->GetTranslation();
67dd5535 1369 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1370
1371 return kTRUE;
1372}
1373
1374//______________________________________________________________________
1375Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1376{
1377 // Get the original rotation matrix (ideal geometry)
1378 // for a given module 'index' by quering the TGeoManager
1379
36b010bf 1380 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1381 if (!m) return kFALSE;
67dd5535 1382
36b010bf 1383 Double_t *rot = m->GetRotationMatrix();
67dd5535 1384 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1385
1386 return kTRUE;
1387}
1388
1389//______________________________________________________________________
1390const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1391{
25fad4e5 1392 // Get the matrix which transforms from the tracking to the local RS
67dd5535 1393 // The method queries directly the TGeoPNEntry
1394
67dd5535 1395 TGeoPNEntry *pne = GetPNEntry(index);
1396 if (!pne) return NULL;
1397
1398 const TGeoHMatrix *m = pne->GetMatrix();
1399 if (!m)
5aedd709 1400 AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
67dd5535 1401
1402 return m;
1403}
1404
1405//______________________________________________________________________
1406Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1407{
1408 // Get the matrix which transforms from the tracking r.s. to
1409 // the global one.
1410 // Returns kFALSE in case of error.
1411
1412 m.Clear();
1413
1414 TGeoHMatrix *m1 = GetMatrix(index);
1415 if (!m1) return kFALSE;
1416
1417 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1418 if (!m2) return kFALSE;
1419
1420 m = *m1;
1421 m.Multiply(m2);
1422
1423 return kTRUE;
1424}
1425
1426//_____________________________________________________________________________
1427TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1428 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1429 //
1430 Int_t modId;
1431 ELayerID layerId = VolUIDToLayer(voluid,modId);
1432 return GetPNEntry(layerId,modId);
1433}
1434
1435//_____________________________________________________________________________
67dd5535 1436TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1437{
1438 // Returns the TGeoPNEntry for a given layer
1439 // and module ID
1440 //
25fad4e5 1441
67dd5535 1442 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1443 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1444 return NULL;
1445 }
1446
1447 return fgPNEntry[layerId-kFirstLayer][modId];
1448}
1449
1450//_____________________________________________________________________________
5590c6c3 1451void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
1452{
1453 // Check for overlaps/extrusions on physical nodes only;
1454 // this overlap-checker is meant to be used to check overlaps/extrusions
1455 // originated by the application of alignment objects.
1456 //
1457
1458 TObjArray* ovexlist = new TObjArray(64);
1459
1460 AliInfoClass("********* Checking overlaps/extrusions over physical nodes only *********");
1461 TObjArray* pnList = gGeoManager->GetListOfPhysicalNodes();
0cd61c1d 1462 TGeoVolume* mvol = 0;
5590c6c3 1463 TGeoPhysicalNode* pn;
1464 TObjArray* overlaps = new TObjArray(64);
1465 overlaps->SetOwner();
1466
1467 TStopwatch timer2;
1468 timer2.Start();
1469 for(Int_t pni=0; pni<pnList->GetEntriesFast(); pni++){
1470 pn = (TGeoPhysicalNode*) pnList->UncheckedAt(pni);
1471 // checking the volume of the mother (go upper in the tree in case it is an assembly)
1472 Int_t levup=1;
1473 while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
1474 //Printf("Going to upper level");
1475 mvol = pn->GetVolume(pn->GetLevel()-levup);
1476 if(!mvol->IsSelected()){
1477 AliInfoClass(Form("Checking overlaps for volume %s",mvol->GetName()));
1478 mvol->CheckOverlaps(threshold);
1479 ovexlist = gGeoManager->GetListOfOverlaps();
1480 TIter next(ovexlist);
1481 TGeoOverlap *ov;
1482 while ((ov=(TGeoOverlap*)next())) overlaps->Add(ov->Clone());
1483 mvol->SelectVolume();
1484 }
1485 }
1486 mvol->SelectVolume(kTRUE); // clears the list of selected volumes
1487
1488 AliInfoClass(Form("Number of overlapping/extruding PNs: %d",overlaps->GetEntriesFast()));
1489 timer2.Stop();
1490 timer2.Print();
1491
1492 TIter nextN(overlaps);
1493 TGeoOverlap *ovlp;
1494 while ((ovlp=(TGeoOverlap*)nextN())) ovlp->PrintInfo();
1495
1496 overlaps->Delete();
1497 delete overlaps;
1498}
1499
1500//_____________________________________________________________________________
8cb26cdf 1501Bool_t AliGeomManager::IsModuleInGeom(const char* module)
1502{
1503 // Return true if the module passed as argument is present in the current geometry
1504 //
1505
1506 TString subdet(module);
1507
1508 if(subdet==TString("ACORDE"))
1509 {
1510 if(fgGeometry->GetAlignableEntry("ACORDE/Array1")) return kTRUE;
1511 }else if(subdet==TString("EMCAL"))
1512 {
1513 if(fgGeometry->GetAlignableEntry("EMCAL/FullSupermodule0") || fgGeometry->GetAlignableEntry("EMCAL/CosmicTestSupermodule0")) return kTRUE;
1514 }else if(subdet==TString("FMD"))
1515 {
1516 if(fgGeometry->GetAlignableEntry("FMD/FMD1_T")) return kTRUE;
1517 }else if(subdet==TString("HMPID"))
1518 {
1519 if(fgGeometry->GetAlignableEntry("/HMPID/Chamber0")) return kTRUE;
1520 }else if(subdet==TString("ITS"))
1521 {
1522 if(fgGeometry->GetAlignableEntry("ITS")) return kTRUE;
1523 }else if(subdet==TString("MUON"))
1524 {
1525 if(fgGeometry->GetAlignableEntry("/MUON/GM0")) return kTRUE;
1526 }else if(subdet==TString("PMD"))
1527 {
1528 if(fgGeometry->GetAlignableEntry("PMD/Sector1")) return kTRUE;
1529 }else if(subdet==TString("PHOS"))
1530 {
1531 if(fgGeometry->GetAlignableEntry("PHOS/Cradle0")) return kTRUE;
1532 }else if(subdet==TString("T0"))
1533 {
1534 if(fgGeometry->GetAlignableEntry("/ALIC_1/0STR_1")) return kTRUE;
1535 }else if(subdet==TString("TRD"))
1536 {
1537 if(fgGeometry->GetAlignableEntry("TRD/sm00")) return kTRUE;
1538 }else if(subdet==TString("TPC"))
1539 {
1540 if(fgGeometry->GetAlignableEntry("TPC/EndcapA/Sector1/InnerChamber")) return kTRUE;
1541 }else if(subdet==TString("TOF"))
1542 {
1543 if(fgGeometry->GetAlignableEntry("TOF/sm00/strip01")) return kTRUE;
1544 }else if(subdet==TString("VZERO"))
1545 {
1546 if(fgGeometry->GetAlignableEntry("VZERO/V0C")) return kTRUE;
1547 }else if(subdet==TString("ZDC"))
1548 {
1549 if(fgGeometry->GetAlignableEntry("ZDC/NeutronZDC_C")) return kTRUE;
1550 }else if(subdet==TString("FRAME"))
1551 {
1552 if(fgGeometry->GetAlignableEntry("FRAME/Sector0")) return kTRUE;
1553 }else
1554 AliErrorClass(Form("%s is not a valid ALICE module name",module));
1555
1556 return kFALSE;
1557}
1558
1559//_____________________________________________________________________________
67dd5535 1560Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1561{
1562 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1563 // the list passed as argument (called by AliSimulation and
1564 // AliReconstruction)
1565 // Read the alignment objects from CDB.
1566 // Each detector is supposed to have the
1567 // alignment objects in DET/Align/Data CDB path.
1568 // All the detector objects are then collected,
1569 // sorted by geometry level (starting from ALIC) and
1570 // then applied to the TGeo geometry.
1571 // Finally an overlaps check is performed.
1572 //
1573
36b010bf 1574 TObjArray alignObjArray;
1575 alignObjArray.Clear();
1576 alignObjArray.SetOwner(0);
67dd5535 1577
1578 TString alObjsNotLoaded="";
1579 TString alObjsLoaded="";
1580
1581 TString AlignDetsString(AlignDetsList);
1582 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1583 TIter iter(detsarr);
1584 TObjString *str = 0;
1585
1586 while((str = (TObjString*) iter.Next())){
1587 TString det(str->String());
36b010bf 1588 AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1589 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
67dd5535 1590 alObjsNotLoaded += det.Data();
1591 alObjsNotLoaded += " ";
1592 } else {
1593 alObjsLoaded += det.Data();
1594 alObjsLoaded += " ";
1595 }
1596 }
b80b98e1 1597 detsarr->Delete();
1598 delete detsarr;
67dd5535 1599
36b010bf 1600 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1601 alObjsLoaded.Data()));
1602 if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1603 alObjsNotLoaded.Data()));
67dd5535 1604
9cb4fe0b 1605 return ApplyAlignObjsToGeom(alignObjArray);
67dd5535 1606}
1607
1608//_____________________________________________________________________________
36b010bf 1609Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
67dd5535 1610{
1611 // Adds the alignable objects found in the CDBEntry for the detector
1612 // passed as argument to the array of all alignment objects to be applyed
1613 // to geometry
1614 //
1615 // Fills array of single detector's alignable objects from CDB
1616
36b010bf 1617 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
67dd5535 1618
1619 AliCDBEntry *entry;
1620
1621 AliCDBPath path(detName,"Align","Data");
1622
1623 entry=AliCDBManager::Instance()->Get(path.GetPath());
1624 if(!entry){
36b010bf 1625 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
67dd5535 1626 return kFALSE;
1627 }
1628 entry->SetOwner(1);
1629 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1630 alignArray->SetOwner(0);
36b010bf 1631 AliDebugClass(2,Form("Found %d alignment objects for %s",
1632 alignArray->GetEntries(),detName));
67dd5535 1633
1634 AliAlignObj *alignObj=0;
1635 TIter iter(alignArray);
1636
1637 // loop over align objects in detector
1638 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
36b010bf 1639 alignObjArray.Add(alignObj);
67dd5535 1640 }
1641 // delete entry --- Don't delete, it is cached!
1642
36b010bf 1643 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
67dd5535 1644 return kTRUE;
1645
1646}
1647
1648//_____________________________________________________________________________
5590c6c3 1649Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
67dd5535 1650{
1651 // Read collection of alignment objects (AliAlignObj derived) saved
1652 // in the TClonesArray alObjArray and apply them to gGeoManager
1653 //
36b010bf 1654 alignObjArray.Sort();
1655 Int_t nvols = alignObjArray.GetEntriesFast();
67dd5535 1656
1657 Bool_t flag = kTRUE;
1658
1659 for(Int_t j=0; j<nvols; j++)
bb1970d8 1660 {
1661 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
1662 flag = alobj->ApplyToGeometry(ovlpcheck);
1663 if(!flag)
67dd5535 1664 {
027ef5c5 1665 AliWarningClass(Form("Error applying alignment object for volume %s !",alobj->GetSymName()));
bb1970d8 1666 }else{
1667 AliDebugClass(5,Form("Alignment object for volume %s applied successfully",alobj->GetSymName()));
67dd5535 1668 }
1669
bb1970d8 1670 }
1671
1672 if (AliDebugLevelClass() > 5) {
1673 fgGeometry->CheckOverlaps(0.001);
36b010bf 1674 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
67dd5535 1675 if(ovexlist->GetEntriesFast()){
36b010bf 1676 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
bb1970d8 1677 fgGeometry->PrintOverlaps();
67dd5535 1678 }
1679 }
1680
36b010bf 1681 // Update the TGeoPhysicalNodes
1682 fgGeometry->RefreshPhysicalNodes();
1683
67dd5535 1684 return flag;
1685
1686}
1687
1688//_____________________________________________________________________________
1689Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1690{
1691 // read collection of alignment objects (AliAlignObj derived) saved
1692 // in the TClonesArray ClArrayName in the file fileName and apply
1693 // them to the geometry
1694 //
1695
1696 TFile* inFile = TFile::Open(fileName,"READ");
1697 if (!inFile || !inFile->IsOpen()) {
1698 AliErrorClass(Form("Could not open file %s !",fileName));
1699 return kFALSE;
1700 }
1701
36b010bf 1702 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
67dd5535 1703 inFile->Close();
36b010bf 1704 if (!alignObjArray) {
67dd5535 1705 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1706 return kFALSE;
1707 }
1708
36b010bf 1709 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1710
1711}
1712
1713//_____________________________________________________________________________
1714Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1715{
1716 // read collection of alignment objects (AliAlignObj derived) saved
1717 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1718 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1719 // to the geometry
1720 //
1721
1722 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1723 AliCDBEntry* entry = storage->Get(Id);
36b010bf 1724 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
67dd5535 1725
36b010bf 1726 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1727
1728}
1729
1730//_____________________________________________________________________________
1731Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1732{
1733 // read collection of alignment objects (AliAlignObj derived) saved
1734 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1735 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1736 // to the geometry
1737 //
1738
1739 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1740 AliCDBId id(path, runnum, runnum, version, sversion);
1741
1742 return ApplyAlignObjsToGeom(param, id);
1743
1744}
1745
1746//_____________________________________________________________________________
1747Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1748{
1749 // read collection of alignment objects (AliAlignObj derived) saved
1750 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1751 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1752 // to the geometry
1753 //
1754
1755 AliCDBPath path(detName,"Align","Data");
1756 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1757
1758 if(!entry) return kFALSE;
36b010bf 1759 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
25fad4e5 1760
36b010bf 1761 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1762}
171c4ef9 1763
171c4ef9 1764