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