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