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