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