Improving the time performance of the TPC clusterer. The idea is to use an auxiliary...
[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>
30
31#include "AliGeomManager.h"
32#include "AliLog.h"
33#include "AliAlignObj.h"
34#include "AliAlignObjAngles.h"
35#include "AliCDBManager.h"
36#include "AliCDBStorage.h"
37#include "AliCDBEntry.h"
38
39ClassImp(AliGeomManager)
40
41Int_t AliGeomManager::fgLayerSize[kLastLayer - kFirstLayer] = {
42 80, 160, // ITS SPD first and second layer
43 84, 176, // ITS SDD first and second layer
44 748, 950, // ITS SSD first and second layer
45 36, 36, // TPC inner and outer chambers
46 90, 90, 90, 90, 90, 90, // 6 TRD chambers' layers
47 1638, // TOF
df117114 48 5, 5, // PHOS,CPV
67dd5535 49 7, // HMPID ??
50 1 // MUON ??
51};
52
53const char* AliGeomManager::fgLayerName[kLastLayer - kFirstLayer] = {
54 "ITS inner pixels layer", "ITS outer pixels layer",
55 "ITS inner drifts layer", "ITS outer drifts layer",
56 "ITS inner strips layer", "ITS outer strips layer",
57 "TPC inner chambers layer", "TPC outer chambers layer",
58 "TRD chambers layer 1", "TRD chambers layer 2", "TRD chambers layer 3",
59 "TRD chambers layer 4", "TRD chambers layer 5", "TRD chambers layer 6",
60 "TOF layer",
df117114 61 "PHOS EMC layer","PHOS CPV layer",
67dd5535 62 "HMPID layer",
63 "?"
64};
65
66TString* AliGeomManager::fgSymName[kLastLayer - kFirstLayer] = {
67 0x0,0x0,
68 0x0,0x0,
69 0x0,0x0,
70 0x0,0x0,
71 0x0,0x0,0x0,
72 0x0,0x0,0x0,
73 0x0,
74 0x0,0x0,
75 0x0,
76 0x0
77};
78
79TGeoPNEntry** AliGeomManager::fgPNEntry[kLastLayer - kFirstLayer] = {
80 0x0,0x0,
81 0x0,0x0,
82 0x0,0x0,
83 0x0,0x0,
84 0x0,0x0,0x0,
85 0x0,0x0,0x0,
86 0x0,
87 0x0,0x0,
88 0x0,
89 0x0
90};
91
92AliAlignObj** AliGeomManager::fgAlignObjs[kLastLayer - kFirstLayer] = {
93 0x0,0x0,
94 0x0,0x0,
95 0x0,0x0,
96 0x0,0x0,
97 0x0,0x0,0x0,
98 0x0,0x0,0x0,
99 0x0,
100 0x0,0x0,
101 0x0,
102 0x0
103};
104
105AliGeomManager* AliGeomManager::fgInstance = 0x0;
106
107TGeoManager* AliGeomManager::fgGeometry = 0x0;
108
109//_____________________________________________________________________________
110AliGeomManager* AliGeomManager::Instance()
111{
112// returns AliGeomManager instance (singleton)
113
114 if (!fgInstance) {
115 fgInstance = new AliGeomManager();
116 fgInstance->Init();
117 }
118 return fgInstance;
119}
120
121//_____________________________________________________________________________
122void AliGeomManager::Init()
123{
124// initialization
125 if(!gGeoManager) AliFatal("Impossible to initialize AliGeomManager without an active geometry");
126 fgGeometry = gGeoManager;
127 InitSymNamesLUT();
128 InitPNEntriesLUT();
129}
130
131//_____________________________________________________________________________
132AliGeomManager::AliGeomManager():
133 TObject(),
134
67dd5535 135 fAlignObjArray(NULL)
136{
137 // default constructor
138}
139
140//_____________________________________________________________________________
141AliGeomManager::~AliGeomManager()
142{
143 // dummy destructor
144 if(fAlignObjArray) fAlignObjArray->Delete();
145 delete fAlignObjArray;
146}
147
148//_____________________________________________________________________________
149Int_t AliGeomManager::LayerSize(Int_t layerId)
150{
151 // Get the layer size for layer corresponding to layerId.
152 // Implemented only for ITS,TPC,TRD,TOF and HMPID
153 //
154 if (layerId < kFirstLayer || layerId >= kLastLayer) {
155 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
156 return 0;
157 }
158 else {
159 return fgLayerSize[layerId - kFirstLayer];
160 }
161}
162
163//_____________________________________________________________________________
164const char* AliGeomManager::LayerName(Int_t layerId)
165{
166 // Get the layer name corresponding to layerId.
167 // Implemented only for ITS,TPC,TRD,TOF and HMPID
168 //
169 if (layerId < kFirstLayer || layerId >= kLastLayer) {
170 AliErrorClass(Form("Invalid layer index %d ! Layer range is (%d -> %d) !",layerId,kFirstLayer,kLastLayer));
171 return "Invalid Layer!";
172 }
173 else {
174 return fgLayerName[layerId - kFirstLayer];
175 }
176}
177
178//_____________________________________________________________________________
179UShort_t AliGeomManager::LayerToVolUID(ELayerID layerId, Int_t modId)
180{
181 // From detector (layer) name and module number (according to detector
182 // internal numbering) build the unique numerical identity of that volume
183 // inside ALICE
184 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
185 // remaining 11 for module ID inside det (2048 possible values).
186 // NO check for validity of given modId inside the layer for speed's sake.
187 //
188 return ((UShort_t(layerId) << 11) | UShort_t(modId));
189}
190
191//_____________________________________________________________________________
192UShort_t AliGeomManager::LayerToVolUID(Int_t layerId, Int_t modId)
193{
194 // From detector (layer) name and module number (according to detector
195 // internal numbering) build the unique numerical identity of that volume
196 // inside ALICE
197 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
198 // remaining 11 for module ID inside det (2048 possible values).
199 // NO check for validity of given modId inside the layer for speed's sake.
200 //
201 return ((UShort_t(layerId) << 11) | UShort_t(modId));
202}
203
204//_____________________________________________________________________________
205UShort_t AliGeomManager::LayerToVolUIDSafe(ELayerID layerId, Int_t modId)
206{
207 // From detector (layer) name and module number (according to detector
208 // internal numbering) build the unique numerical identity of that volume
209 // inside ALICE
210 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
211 // remaining 11 for module ID inside det (2048 possible values).
212 // Check validity of given modId inside the layer.
213 //
214 if(modId < 0 || modId >= LayerSize(layerId)){
215 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
216 return 0;
217 }
218 return ((UShort_t(layerId) << 11) | UShort_t(modId));
219}
220
221//_____________________________________________________________________________
222UShort_t AliGeomManager::LayerToVolUIDSafe(Int_t layerId, Int_t modId)
223{
224 // From detector (layer) name and module number (according to detector
225 // internal numbering) build the unique numerical identity of that volume
226 // inside ALICE
227 // fVolUID is 16 bits, first 5 reserved for layerID (32 possible values),
228 // remaining 11 for module ID inside det (2048 possible values).
229 // Check validity of given modId inside the layer.
230 //
231 if(modId < 0 || modId >= LayerSize(layerId)){
232 AliErrorClass(Form("Invalid volume id %d ! Range of valid ids for layer \"%s\" is [0, %d] !",modId,LayerName(layerId),LayerSize(layerId)-1));
233 return 0;
234 }
235 return ((UShort_t(layerId) << 11) | UShort_t(modId));
236}
237
238//_____________________________________________________________________________
239AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid, Int_t &modId)
240{
241 // From voluid, unique numerical identity of that volume inside ALICE,
242 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
243 // remaining 11 for module ID inside det (2048 possible values)), return
244 // the identity of the layer to which that volume belongs and sets the
245 // argument modId to the identity of that volume internally to the layer.
246 // NO check for validity of given voluid for speed's sake.
247 //
248 modId = voluid & 0x7ff;
249
250 return VolUIDToLayer(voluid);
251}
252
253//_____________________________________________________________________________
254AliGeomManager::ELayerID AliGeomManager::VolUIDToLayer(UShort_t voluid)
255{
256 // From voluid, unique numerical identity of that volume inside ALICE,
257 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
258 // remaining 11 for module ID inside det (2048 possible values)), return
259 // the identity of the layer to which that volume belongs
260 // NO check for validity of given voluid for speed's sake.
261 //
262 return ELayerID(voluid >> 11);
263}
264
265//_____________________________________________________________________________
266AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid, Int_t &modId)
267{
268 // From voluid, unique numerical identity of that volume inside ALICE,
269 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
270 // remaining 11 for module ID inside det (2048 possible values)), returns
271 // the identity of the layer to which that volume belongs and sets the
272 // argument modId to the identity of that volume internally to the layer.
273 // Checks the validity of the given voluid
274 //
275 ELayerID layId = VolUIDToLayerSafe(voluid);
276 if(layId){
277 Int_t mId = Int_t(voluid & 0x7ff);
278 if( mId>=0 && mId<LayerSize(layId)){
279 modId = mId;
280 return layId;
281 }
282 }
283
284 AliErrorClass(Form("Invalid unique volume id: %d !",voluid));
285 modId = -1;
286 return kInvalidLayer;
287
288}
289
290//_____________________________________________________________________________
291AliGeomManager::ELayerID AliGeomManager::VolUIDToLayerSafe(UShort_t voluid)
292{
293 // From voluid, unique numerical identity of that volume inside ALICE,
294 // (voluid is 16 bits, first 5 reserved for layerID (32 possible values),
295 // remaining 11 for module ID inside det (2048 possible values)), returns
296 // the identity of the layer to which that volume belongs
297 // Checks the validity of the given voluid
298 //
299 if( (voluid >> 11) < kLastLayer) return ELayerID(voluid >> 11);
300
301 AliErrorClass(Form("Invalid layer id: %d !",(voluid >> 11)));
302 return kInvalidLayer;
303
304}
305
306//_____________________________________________________________________________
307Bool_t AliGeomManager::GetFromGeometry(const char *symname, AliAlignObj &alobj)
308{
309 // Get the alignment object which corresponds to the symbolic volume name
310 // symname (in case equal to the TGeo volume path)
311 // The method is extremely slow due to the searching by string,
312 // therefore it should be used with great care!!
313 // This method returns FALSE if the symname of the object was not
314 // valid neither to get a TGeoPEntry nor as a volume path, or if the path
315 // associated to the TGeoPNEntry was not valid.
316 //
317
318 // Reset the alignment object
319 alobj.SetPars(0,0,0,0,0,0);
320 alobj.SetSymName(symname);
321
322 if (!gGeoManager || !gGeoManager->IsClosed()) {
323 AliErrorClass("Can't get the alignment object! gGeoManager doesn't exist or it is still opened!");
324 return kFALSE;
325 }
326
327 if (!gGeoManager->GetListOfPhysicalNodes()) {
328 AliErrorClass("Can't get the alignment object! gGeoManager doesn't contain any aligned nodes!");
329 return kFALSE;
330 }
331
67dd5535 332 const char *path;
333 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
334 if(pne){
335 path = pne->GetTitle();
336 }else{
337 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
338 path = symname;
339 }
340 TObjArray* nodesArr = gGeoManager->GetListOfPhysicalNodes();
341 TGeoPhysicalNode* node = NULL;
342 for (Int_t iNode = 0; iNode < nodesArr->GetEntriesFast(); iNode++) {
343 TGeoPhysicalNode* tempNode = (TGeoPhysicalNode*) nodesArr->UncheckedAt(iNode);
344 const char *nodePath = tempNode->GetName();
345 if (strcmp(path,nodePath) == 0) {
346 node = tempNode;
347 break;
348 }
349 }
350
351 if (!node) {
352 if (!gGeoManager->cd(path)) {
353 AliErrorClass(Form("%s not valid neither as symbolic volume name nor as volume path!",path));
354 return kFALSE;
355 }
356 else {
357 AliWarningClass(Form("Volume (%s) has not been misaligned!",path));
358 return kTRUE;
359 }
360 }
361
362 TGeoHMatrix align,gprime,g,ginv,l;
363 gprime = *node->GetMatrix();
364 l = *node->GetOriginalMatrix();
365 g = *node->GetMatrix(node->GetLevel()-1);
366 g *= l;
367 ginv = g.Inverse();
368 align = gprime * ginv;
369
370 return alobj.SetMatrix(align);
371}
372
373
374//_____________________________________________________________________________
375void AliGeomManager::InitAlignObjFromGeometry()
376{
377 // Loop over all alignable volumes and extract
378 // the corresponding alignment objects from
379 // the TGeo geometry
380
381 if(fgAlignObjs[0]) return;
382
67dd5535 383 for (Int_t iLayer = kFirstLayer; iLayer < AliGeomManager::kLastLayer; iLayer++) {
384 fgAlignObjs[iLayer-kFirstLayer] = new AliAlignObj*[LayerSize(iLayer)];
385 for (Int_t iModule = 0; iModule < LayerSize(iLayer); iModule++) {
386 UShort_t volid = LayerToVolUID(iLayer,iModule);
387 fgAlignObjs[iLayer-kFirstLayer][iModule] = new AliAlignObjAngles("",volid,0,0,0,0,0,0,kTRUE);
388 const char *symname = SymName(volid);
389 if (!GetFromGeometry(symname, *fgAlignObjs[iLayer-kFirstLayer][iModule]))
390 AliErrorClass(Form("Failed to extract the alignment object for the volume (ID=%d and path=%s) !",volid,symname));
391 }
392 }
393
394}
395
396//_____________________________________________________________________________
397AliAlignObj* AliGeomManager::GetAlignObj(UShort_t voluid) {
398 // Returns the alignment object for given volume ID
399 //
400 Int_t modId;
401 ELayerID layerId = VolUIDToLayer(voluid,modId);
402 return GetAlignObj(layerId,modId);
403}
404
405//_____________________________________________________________________________
406AliAlignObj* AliGeomManager::GetAlignObj(ELayerID layerId, Int_t modId)
407{
408 // Returns pointer to alignment object given its layer and module ID
409 //
410 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
411 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
412 return NULL;
413 }
414 InitAlignObjFromGeometry();
415
416 return fgAlignObjs[layerId-kFirstLayer][modId];
417}
418
419//_____________________________________________________________________________
420const char* AliGeomManager::SymName(UShort_t voluid) {
421 // Returns the symbolic volume name for given volume ID
422 //
423 Int_t modId;
424 ELayerID layerId = VolUIDToLayer(voluid,modId);
425 return SymName(layerId,modId);
426}
427
428//_____________________________________________________________________________
429const char* AliGeomManager::SymName(ELayerID layerId, Int_t modId)
430{
431 // Returns the symbolic volume name given for a given layer
432 // and module ID
433 //
434 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
435 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
436 return NULL;
437 }
25fad4e5 438 InitSymNamesLUT();
67dd5535 439
440 return fgSymName[layerId-kFirstLayer][modId].Data();
441}
442
443//_____________________________________________________________________________
444void AliGeomManager::InitSymNamesLUT()
445{
446 // Initialize the look-up table which associates the unique
447 // numerical identity of each alignable volume to the
448 // corresponding symbolic volume name
449 // The LUTs are static; they are created at the creation of the
450 // AliGeomManager instance and recreated if the geometry has changed
451 //
452
25fad4e5 453 if(fgSymName[0]) return;
454
67dd5535 455 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
456 if(!fgSymName[iLayer]) fgSymName[iLayer]=new TString[fgLayerSize[iLayer]];
457 }
458
459 TString symname;
460 Int_t modnum; // in the following, set it to 0 at the start of each layer
461
462 /********************* ITS layers ***********************/
463 TString strSPD = "ITS/SPD";
464 TString strSDD = "ITS/SDD";
465 TString strSSD = "ITS/SSD";
466 TString strStave = "/Stave";
467 TString strLadder = "/Ladder";
468 TString strSector = "/Sector";
469 TString strSensor = "/Sensor";
470 TString strEntryName1;
471 TString strEntryName2;
472
473
474 /********************* SPD layer1 ***********************/
475 {
476 modnum = 0;
477
478 for(Int_t c1 = 1; c1<=10; c1++){
479 strEntryName1 = strSPD;
480 strEntryName1 += 0;
481 strEntryName1 += strSector;
482 strEntryName1 += (c1-1);
483 for(Int_t c2 =1; c2<=2; c2++){
484 strEntryName2 = strEntryName1;
485 strEntryName2 += strStave;
486 strEntryName2 += (c2-1);
487 for(Int_t c3 =1; c3<=4; c3++){
488 symname = strEntryName2;
489 symname += strLadder;
490 symname += (c3-1);
491 fgSymName[kSPD1-kFirstLayer][modnum] = symname.Data();
492 modnum++;
493 }
494 }
495 }
496 }
497
498 /********************* SPD layer2 ***********************/
499 {
500 modnum = 0;
501
502 for(Int_t c1 = 1; c1<=10; c1++){
503 strEntryName1 = strSPD;
504 strEntryName1 += 1;
505 strEntryName1 += strSector;
506 strEntryName1 += (c1-1);
507 for(Int_t c2 =1; c2<=4; c2++){
508 strEntryName2 = strEntryName1;
509 strEntryName2 += strStave;
510 strEntryName2 += (c2-1);
511 for(Int_t c3 =1; c3<=4; c3++){
512 symname = strEntryName2;
513 symname += strLadder;
514 symname += (c3-1);
515 fgSymName[kSPD2-kFirstLayer][modnum] = symname.Data();
516 modnum++;
517 }
518 }
519 }
520 }
521
522 /********************* SDD layer1 ***********************/
523 {
524 modnum=0;
525
526 for(Int_t c1 = 1; c1<=14; c1++){
527 strEntryName1 = strSDD;
528 strEntryName1 += 2;
529 strEntryName1 +=strLadder;
530 strEntryName1 += (c1-1);
531 for(Int_t c2 =1; c2<=6; c2++){
532 symname = strEntryName1;
533 symname += strSensor;
534 symname += (c2-1);
535 fgSymName[kSDD1-kFirstLayer][modnum] = symname.Data();
536 modnum++;
537 }
538 }
539 }
540
541 /********************* SDD layer2 ***********************/
542 {
543 modnum=0;
544
545 for(Int_t c1 = 1; c1<=22; c1++){
546 strEntryName1 = strSDD;
547 strEntryName1 += 3;
548 strEntryName1 +=strLadder;
549 strEntryName1 += (c1-1);
550 for(Int_t c2 = 1; c2<=8; c2++){
551 symname = strEntryName1;
552 symname += strSensor;
553 symname += (c2-1);
554 fgSymName[kSDD2-kFirstLayer][modnum] = symname.Data();
555 modnum++;
556 }
557 }
558 }
559
560 /********************* SSD layer1 ***********************/
561 {
562 modnum=0;
563
564 for(Int_t c1 = 1; c1<=34; c1++){
565 strEntryName1 = strSSD;
566 strEntryName1 += 4;
567 strEntryName1 +=strLadder;
568 strEntryName1 += (c1-1);
569 for(Int_t c2 = 1; c2<=22; c2++){
570 symname = strEntryName1;
571 symname += strSensor;
572 symname += (c2-1);
573 fgSymName[kSSD1-kFirstLayer][modnum] = symname.Data();
574 modnum++;
575 }
576 }
577 }
578
579 /********************* SSD layer2 ***********************/
580 {
581 modnum=0;
582
583 for(Int_t c1 = 1; c1<=38; c1++){
584 strEntryName1 = strSSD;
585 strEntryName1 += 5;
586 strEntryName1 +=strLadder;
587 strEntryName1 += (c1-1);
588 for(Int_t c2 = 1; c2<=25; c2++){
589 symname = strEntryName1;
590 symname += strSensor;
591 symname += (c2-1);
592 fgSymName[kSSD2-kFirstLayer][modnum] = symname.Data();
593 modnum++;
594 }
595 }
596 }
597
598
599 /*************** TPC inner and outer layers ****************/
600 TString sAsector="TPC/EndcapA/Sector";
601 TString sCsector="TPC/EndcapC/Sector";
602 TString sInner="/InnerChamber";
603 TString sOuter="/OuterChamber";
604
605 /*************** TPC inner chambers' layer ****************/
606 {
607 modnum = 0;
608
609 for(Int_t cnt=1; cnt<=18; cnt++){
610 symname = sAsector;
611 symname += cnt;
612 symname += sInner;
613 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
614 modnum++;
615 }
616 for(Int_t cnt=1; cnt<=18; cnt++){
617 symname = sCsector;
618 symname += cnt;
619 symname += sInner;
620 fgSymName[kTPC1-kFirstLayer][modnum] = symname.Data();
621 modnum++;
622 }
623 }
624
625 /*************** TPC outer chambers' layer ****************/
626 {
627 modnum = 0;
628
629 for(Int_t cnt=1; cnt<=18; cnt++){
630 symname = sAsector;
631 symname += cnt;
632 symname += sOuter;
633 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
634 modnum++;
635 }
636 for(Int_t cnt=1; cnt<=18; cnt++){
637 symname = sCsector;
638 symname += cnt;
639 symname += sOuter;
640 fgSymName[kTPC2-kFirstLayer][modnum] = symname.Data();
641 modnum++;
642 }
643 }
644
645 /********************* TOF layer ***********************/
646 {
647 modnum=0;
648
649 Int_t nstrA=15;
650 Int_t nstrB=19;
651 Int_t nstrC=19;
652 Int_t nSectors=18;
653 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
654
655 TString snSM = "TOF/sm";
656 TString snSTRIP = "/strip";
657
658 for (Int_t isect = 0; isect < nSectors; isect++) {
659 for (Int_t istr = 1; istr <= nStrips; istr++) {
660 symname = snSM;
661 symname += Form("%02d",isect);
662 symname += snSTRIP;
663 symname += Form("%02d",istr);
664 fgSymName[kTOF-kFirstLayer][modnum] = symname.Data();
665 modnum++;
666 }
667 }
668 }
669
670 /********************* HMPID layer ***********************/
671 {
672 TString str = "/HMPID/Chamber";
673
674 for (modnum=0; modnum < 7; modnum++) {
675 symname = str;
676 symname += modnum;
677 fgSymName[kHMPID-kFirstLayer][modnum] = symname.Data();
678 }
679 }
680
681 /********************* TRD layers 1-6 *******************/
682 //!! 6 layers with index increasing in outwards direction
683 {
684 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
685
686 TString snStr = "TRD/sm";
687 TString snApp1 = "/st";
688 TString snApp2 = "/pl";
689
690 for(Int_t layer=0; layer<6; layer++){
691 modnum=0;
692 for (Int_t isect = 0; isect < 18; isect++) {
693 for (Int_t icham = 0; icham < 5; icham++) {
694 symname = snStr;
695 symname += Form("%02d",isect);
696 symname += snApp1;
697 symname += icham;
698 symname += snApp2;
699 symname += layer;
700 fgSymName[arTRDlayId[layer]-kFirstLayer][modnum] = symname.Data();
701 modnum++;
702 }
703 }
704 }
705 }
df117114 706
707 /********************* PHOS EMC layer ***********************/
708 {
709 TString str = "PHOS/Module";
710 modnum=0;
711
712 for (Int_t iModule=1; iModule <= 5; iModule++) {
713 symname = str;
714 symname += iModule;
715 modnum = iModule-1;
716 fgSymName[kPHOS1-kFirstLayer][modnum] = symname.Data();
717 }
718 }
719
f47b9233 720 /********************* PHOS CPV layer ***********************/
721 {
722 TString str = "PHOS/Module";
723 modnum=0;
724
725 for (Int_t iModule=1; iModule <= 5; iModule++) {
726 symname = str;
727 symname += iModule;
728 symname += "/CPV";
729 modnum = iModule-1;
730 fgSymName[kPHOS2-kFirstLayer][modnum] = symname.Data();
731 }
732 }
733
734
67dd5535 735}
736
737//_____________________________________________________________________________
738void AliGeomManager::InitPNEntriesLUT()
739{
740 // Initialize the look-up table which associates the unique
741 // numerical identity of each alignable volume to the
742 // corresponding TGeoPNEntry.
743 // The LUTs are static; they are created at the creation of the
744 // AliGeomManager instance and recreated if the geometry has changed
745 //
746
25fad4e5 747 if(!gGeoManager) AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
748
749 InitSymNamesLUT();
750
67dd5535 751 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
752 if(!fgPNEntry[iLayer]) fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
753 }
754
755 for (Int_t iLayer = 0; iLayer < (kLastLayer-kFirstLayer); iLayer++){
25fad4e5 756 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
757 fgPNEntry[iLayer][modnum] = gGeoManager->GetAlignableEntry(fgSymName[iLayer][modnum].Data());
67dd5535 758 }
759 }
760}
761
762//______________________________________________________________________
763TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
764{
765 // Get the transformation matrix for a given PNEntry
766 // by quering the TGeoManager
767
25fad4e5 768 if (!gGeoManager || !gGeoManager->IsClosed()) {
769 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
770 return NULL;
771 }
772
67dd5535 773 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
774 if (pnode) return pnode->GetMatrix();
775
776 const char* path = pne->GetTitle();
777 if (!gGeoManager->cd(path)) {
778 AliErrorClass(Form("Volume path %s not valid!",path));
779 return NULL;
780 }
781 return gGeoManager->GetCurrentMatrix();
782}
783
784//______________________________________________________________________
785TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
786{
787 // Get the global transformation matrix for a given alignable volume
788 // identified by its unique ID 'index' by quering the TGeoManager
789
67dd5535 790 TGeoPNEntry *pne = GetPNEntry(index);
791 if (!pne) return NULL;
792
793 return GetMatrix(pne);
794}
795
796//______________________________________________________________________
797TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
798{
799 // Get the global transformation matrix for a given alignable volume
800 // identified by its symbolic name 'symname' by quering the TGeoManager
801
25fad4e5 802 if(!ReactIfChangedGeom()) return NULL;
67dd5535 803 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
804 if (!pne) return NULL;
805
806 return GetMatrix(pne);
807}
808
809//______________________________________________________________________
810Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
811{
812 // Get the translation vector for a given module 'index'
813 // by quering the TGeoManager
814
815 TGeoHMatrix *m = GetMatrix(index);
816 if (!m) return kFALSE;
817
818 Double_t *trans = m->GetTranslation();
819 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
820
821 return kTRUE;
822}
823
824//______________________________________________________________________
825Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
826{
827 // Get the rotation matrix for a given module 'index'
828 // by quering the TGeoManager
829
830 TGeoHMatrix *m = GetMatrix(index);
831 if (!m) return kFALSE;
832
833 Double_t *rot = m->GetRotationMatrix();
834 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
835
836 return kTRUE;
837}
838
839//_____________________________________________________________________________
840Bool_t AliGeomManager::GetOrigGlobalMatrix(const char *symname, TGeoHMatrix &m)
841{
842 // The method returns global matrix for the ideal detector geometry
843 // Symname identifies either the corresponding TGeoPNEntry or directly
844 // the volume path. The output global matrix is stored in 'm'.
845 // Returns kFALSE in case TGeo has not been initialized or the symname
846 // is invalid.
847 //
848
849 if (!gGeoManager || !gGeoManager->IsClosed()) {
850 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
851 return kFALSE;
852 }
853
854 if (!gGeoManager->GetListOfPhysicalNodes()) {
855 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
856 if (!gGeoManager->cd(symname)) {
857 AliErrorClass(Form("Volume path %s not valid!",symname));
858 return kFALSE;
859 }
860 else {
861 m = *gGeoManager->GetCurrentMatrix();
862 return kTRUE;
863 }
864 }
865
866 const char* path = NULL;
867 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(symname);
868 if(pne){
869 path = pne->GetTitle();
870 }else{
871 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
872 path=symname;
873 }
874
875 if (!gGeoManager->CheckPath(path)) {
876 AliErrorClass(Form("Volume path %s not valid!",path));
877 return kFALSE;
878 }
879
880 m.Clear();
881
882 TIter next(gGeoManager->GetListOfPhysicalNodes());
883 gGeoManager->cd(path);
884
885 while(gGeoManager->GetLevel()){
886
887 TGeoPhysicalNode *physNode = NULL;
888 next.Reset();
889 TGeoNode *node = gGeoManager->GetCurrentNode();
890 while ((physNode=(TGeoPhysicalNode*)next()))
891 if (physNode->GetNode() == node) break;
892
893 TGeoMatrix *lm = NULL;
894 if (physNode) {
895 lm = physNode->GetOriginalMatrix();
896 if (!lm) lm = node->GetMatrix();
897 } else
898 lm = node->GetMatrix();
899
900 m.MultiplyLeft(lm);
901
902 gGeoManager->CdUp();
903 }
904
905 return kTRUE;
906}
907
908//______________________________________________________________________
909Bool_t AliGeomManager::GetOrigGlobalMatrix(Int_t index, TGeoHMatrix &m)
910{
911 // Get the original (ideal geometry) TGeo matrix for
912 // a given module identified by 'index'.
913 // The method is slow, so it should be used
914 // with great care.
915
916 m.Clear();
917
67dd5535 918 const char *symname = SymName(index);
919 if (!symname) return kFALSE;
920
921 return GetOrigGlobalMatrix(symname,m);
922}
923
924//______________________________________________________________________
925Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
926{
927 // Get the original translation vector (ideal geometry)
928 // for a given module 'index' by quering the TGeoManager
929
930 TGeoHMatrix m;
931 if (!GetOrigGlobalMatrix(index,m)) return kFALSE;
932
933 Double_t *trans = m.GetTranslation();
934 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
935
936 return kTRUE;
937}
938
939//______________________________________________________________________
940Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
941{
942 // Get the original rotation matrix (ideal geometry)
943 // for a given module 'index' by quering the TGeoManager
944
945 TGeoHMatrix m;
946 if (!GetOrigGlobalMatrix(index,m)) return kFALSE;
947
948 Double_t *rot = m.GetRotationMatrix();
949 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
950
951 return kTRUE;
952}
953
954//______________________________________________________________________
955const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
956{
25fad4e5 957 // Get the matrix which transforms from the tracking to the local RS
67dd5535 958 // The method queries directly the TGeoPNEntry
959
67dd5535 960 TGeoPNEntry *pne = GetPNEntry(index);
961 if (!pne) return NULL;
962
963 const TGeoHMatrix *m = pne->GetMatrix();
964 if (!m)
965 AliErrorClass(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
966
967 return m;
968}
969
970//______________________________________________________________________
971Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
972{
973 // Get the matrix which transforms from the tracking r.s. to
974 // the global one.
975 // Returns kFALSE in case of error.
976
977 m.Clear();
978
979 TGeoHMatrix *m1 = GetMatrix(index);
980 if (!m1) return kFALSE;
981
982 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
983 if (!m2) return kFALSE;
984
985 m = *m1;
986 m.Multiply(m2);
987
988 return kTRUE;
989}
990
991//_____________________________________________________________________________
992TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
993 // Returns the TGeoPNEntry for the given global volume ID "voluid"
994 //
995 Int_t modId;
996 ELayerID layerId = VolUIDToLayer(voluid,modId);
997 return GetPNEntry(layerId,modId);
998}
999
1000//_____________________________________________________________________________
1001TGeoPNEntry* AliGeomManager::GetPNEntry(UShort_t voluid) {
1002 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1003 //
1004 Int_t modId;
1005 ELayerID layerId = VolUIDToLayer(voluid,modId);
1006 return GetPNEntry(layerId,modId);
1007}
1008
1009//_____________________________________________________________________________
1010TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1011{
1012 // Returns the TGeoPNEntry for a given layer
1013 // and module ID
1014 //
25fad4e5 1015
1016 if(!fgPNEntry[0]) InitPNEntriesLUT();
1017 if(!ReactIfChangedGeom()) return NULL;
1018
67dd5535 1019 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1020 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1021 return NULL;
1022 }
1023
1024 return fgPNEntry[layerId-kFirstLayer][modId];
1025}
1026
1027//_____________________________________________________________________________
1028Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1029{
1030 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1031 // the list passed as argument (called by AliSimulation and
1032 // AliReconstruction)
1033 // Read the alignment objects from CDB.
1034 // Each detector is supposed to have the
1035 // alignment objects in DET/Align/Data CDB path.
1036 // All the detector objects are then collected,
1037 // sorted by geometry level (starting from ALIC) and
1038 // then applied to the TGeo geometry.
1039 // Finally an overlaps check is performed.
1040 //
1041
1042 if(!fAlignObjArray) fAlignObjArray = new TObjArray();
1043 fAlignObjArray->Clear();
1044 fAlignObjArray->SetOwner(0);
1045
1046 TString alObjsNotLoaded="";
1047 TString alObjsLoaded="";
1048
1049 TString AlignDetsString(AlignDetsList);
1050 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1051 TIter iter(detsarr);
1052 TObjString *str = 0;
1053
1054 while((str = (TObjString*) iter.Next())){
1055 TString det(str->String());
1056 AliInfo(Form("Loading alignment objs for %s",det.Data()));
1057 if(!LoadAlignObjsFromCDBSingleDet(det.Data())){
1058 alObjsNotLoaded += det.Data();
1059 alObjsNotLoaded += " ";
1060 } else {
1061 alObjsLoaded += det.Data();
1062 alObjsLoaded += " ";
1063 }
1064 }
1065
1066 if(!alObjsLoaded.IsNull()) AliInfo(Form("Alignment objects loaded for: %s",
1067 alObjsLoaded.Data()));
1068 if(!alObjsNotLoaded.IsNull()) AliInfo(Form("Didn't/couldn't load alignment objects for: %s",
1069 alObjsNotLoaded.Data()));
1070
1071 return(ApplyAlignObjsToGeom(fAlignObjArray));
1072}
1073
1074//_____________________________________________________________________________
1075Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName)
1076{
1077 // Adds the alignable objects found in the CDBEntry for the detector
1078 // passed as argument to the array of all alignment objects to be applyed
1079 // to geometry
1080 //
1081 // Fills array of single detector's alignable objects from CDB
1082
1083 AliDebug(2, Form("Loading alignment objs for detector: %s",detName));
1084
1085 AliCDBEntry *entry;
1086
1087 AliCDBPath path(detName,"Align","Data");
1088
1089 entry=AliCDBManager::Instance()->Get(path.GetPath());
1090 if(!entry){
1091 AliDebug(2,Form("Couldn't load alignment data for detector %s",detName));
1092 return kFALSE;
1093 }
1094 entry->SetOwner(1);
1095 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1096 alignArray->SetOwner(0);
1097 AliDebug(2,Form("Found %d alignment objects for %s",
1098 alignArray->GetEntries(),detName));
1099
1100 AliAlignObj *alignObj=0;
1101 TIter iter(alignArray);
1102
1103 // loop over align objects in detector
1104 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
1105 fAlignObjArray->Add(alignObj);
1106 }
1107 // delete entry --- Don't delete, it is cached!
1108
1109 AliDebug(2, Form("fAlignObjArray entries: %d",fAlignObjArray->GetEntries() ));
1110 return kTRUE;
1111
1112}
1113
1114//_____________________________________________________________________________
1115Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray* alObjArray)
1116{
1117 // Read collection of alignment objects (AliAlignObj derived) saved
1118 // in the TClonesArray alObjArray and apply them to gGeoManager
1119 //
1120 ReactIfChangedGeom();
1121
1122 alObjArray->Sort();
1123 Int_t nvols = alObjArray->GetEntriesFast();
1124
1125 Bool_t flag = kTRUE;
1126
1127 for(Int_t j=0; j<nvols; j++)
1128 {
1129 AliAlignObj* alobj = (AliAlignObj*) alObjArray->UncheckedAt(j);
1130 if (alobj->ApplyToGeometry() == kFALSE) flag = kFALSE;
1131 }
1132
1133 if (AliDebugLevelClass() >= 1) {
1134 gGeoManager->GetTopNode()->CheckOverlaps(1);
1135 TObjArray* ovexlist = gGeoManager->GetListOfOverlaps();
1136 if(ovexlist->GetEntriesFast()){
1137 AliError("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
1138 }
1139 }
1140
1141 return flag;
1142
1143}
1144
1145//_____________________________________________________________________________
1146Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1147{
1148 // read collection of alignment objects (AliAlignObj derived) saved
1149 // in the TClonesArray ClArrayName in the file fileName and apply
1150 // them to the geometry
1151 //
1152
1153 TFile* inFile = TFile::Open(fileName,"READ");
1154 if (!inFile || !inFile->IsOpen()) {
1155 AliErrorClass(Form("Could not open file %s !",fileName));
1156 return kFALSE;
1157 }
1158
1159 TClonesArray* alObjArray = ((TClonesArray*) inFile->Get(clArrayName));
1160 inFile->Close();
1161 if (!alObjArray) {
1162 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1163 return kFALSE;
1164 }
1165
1166 return ApplyAlignObjsToGeom(alObjArray);
1167
1168}
1169
1170//_____________________________________________________________________________
1171Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1172{
1173 // read collection of alignment objects (AliAlignObj derived) saved
1174 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1175 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1176 // to the geometry
1177 //
1178
1179 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1180 AliCDBEntry* entry = storage->Get(Id);
1181 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
1182
1183 return ApplyAlignObjsToGeom(AlObjArray);
1184
1185}
1186
1187//_____________________________________________________________________________
1188Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1189{
1190 // read collection of alignment objects (AliAlignObj derived) saved
1191 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1192 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1193 // to the geometry
1194 //
1195
1196 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1197 AliCDBId id(path, runnum, runnum, version, sversion);
1198
1199 return ApplyAlignObjsToGeom(param, id);
1200
1201}
1202
1203//_____________________________________________________________________________
1204Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1205{
1206 // read collection of alignment objects (AliAlignObj derived) saved
1207 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1208 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1209 // to the geometry
1210 //
1211
1212 AliCDBPath path(detName,"Align","Data");
1213 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1214
1215 if(!entry) return kFALSE;
1216 TClonesArray* AlObjArray = ((TClonesArray*) entry->GetObject());
1217
1218 return ApplyAlignObjsToGeom(AlObjArray);
1219}
1220
1221//_____________________________________________________________________________
25fad4e5 1222Bool_t AliGeomManager::ReactIfChangedGeom()
67dd5535 1223{
1224 // Check if the TGeo geometry has changed. In that case reinitialize the
25fad4e5 1225 // look-up table mapping volume indexes to TGeoPNEntries
67dd5535 1226 //
25fad4e5 1227
1228 if (!gGeoManager || !gGeoManager->IsClosed()) {
1229 AliErrorClass("No active geometry or geometry not yet closed!");
1230 return kFALSE;
1231 }
1232
67dd5535 1233 if(HasGeomChanged())
1234 {
1235 fgGeometry = gGeoManager;
67dd5535 1236 InitPNEntriesLUT();
1237 }
25fad4e5 1238
1239 return kTRUE;
67dd5535 1240}