]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AliGeomManager.cxx
- added the pad status regarding the calibration and the saturation to the TObject...
[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
9d47e237 133//_____________________________________________________________________________
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
67dd5535 143//_____________________________________________________________________________
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 //
ff5970a3 444 if(!fgGeometry){
445 AliErrorClass("No geometry instance loaded yet!");
446 return NULL;
447 }
67dd5535 448 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
449 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
450 return NULL;
451 }
67dd5535 452
a8629c62 453 TGeoPNEntry* pne = fgPNEntry[layerId-kFirstLayer][modId];
454 if(!pne)
455 {
456 AliWarningClass(Form("Module %d of layer %s is not activated!",modId,LayerName(layerId)));
457 return NULL;
458 }
459 return pne->GetName();
460
67dd5535 461}
462
463//_____________________________________________________________________________
ff5970a3 464Bool_t AliGeomManager::CheckSymNamesLUT(const char* detsToBeChecked)
67dd5535 465{
0bf7aade 466 // Check the look-up table which associates the unique numerical identity of
467 // each alignable volume to the corresponding symbolic volume name.
468 // The LUT is now hold inside the geometry and handled by TGeo.
469 // The method is meant to be launched when loading a geometry to verify that
470 // no changes in the symbolic names have been introduced, which would prevent
471 // backward compatibility with alignment objects.
472 // To accept both complete and partial geometry, this method skips the check
473 // for TRD and TOF volumes which are missing in the partial geometry.
474 //
67dd5535 475
ff5970a3 476// TString detsString(detsToBeChecked);
477// if(detsString.Contains("ALL")) detsString="ITS TPC TOF TRD HMPID PHOS EMCAL";
478
479 // Temporary measure to face the case of reconstruction over detectors not present in the geometry
480 TString detsString = "";
481 if(fgGeometry->CheckPath("ALIC_1/ITSV_1")) detsString+="ITS ";
482 if(fgGeometry->CheckPath("ALIC_1/TPC_M_1")) detsString+="TPC ";
483 if(fgGeometry->CheckPath("ALIC_1/B077_1/BSEGMO0_1/BTOF0_1/FTOA_0")) detsString+="TOF ";
484 if(fgGeometry->CheckPath("ALIC_1/B077_1/BSEGMO0_1/BTRD0_1/UTR1_1")) detsString+="TRD ";
485 if(fgGeometry->CheckPath("ALIC_1/Hmp0_0")) detsString+="HMPID ";
486 if(fgGeometry->CheckPath("ALIC_1/PHOS_1")) detsString+="PHOS ";
487 if(fgGeometry->CheckPath("ALIC_1/XEN1_1")) detsString+="EMCAL";
488
489
67dd5535 490 TString symname;
0bf7aade 491 const char* sname;
492 TGeoPNEntry* pne = 0x0;
493 Int_t uid; // global unique identity
494 Int_t modnum; // unique id inside layer; in the following, set it to 0 at the start of each layer
67dd5535 495
ff5970a3 496 if(detsString.Contains("ITS")){
67dd5535 497 /********************* ITS layers ***********************/
ff5970a3 498 AliDebugClass(2,"Checking consistency of symbolic names for ITS layers");
499 TString strSPD = "ITS/SPD";
500 TString strSDD = "ITS/SDD";
501 TString strSSD = "ITS/SSD";
502 TString strStave = "/Stave";
503 TString strHalfStave = "/HalfStave";
504 TString strLadder = "/Ladder";
505 TString strSector = "/Sector";
506 TString strSensor = "/Sensor";
507 TString strEntryName1;
508 TString strEntryName2;
509 TString strEntryName3;
510
511 /********************* SPD layer1 ***********************/
512 {
513 modnum = 0;
514
515 for(Int_t cSect = 0; cSect<10; cSect++){
516 strEntryName1 = strSPD;
517 strEntryName1 += 0;
518 strEntryName1 += strSector;
519 strEntryName1 += cSect;
520
521 for(Int_t cStave =0; cStave<2; cStave++){
522 strEntryName2 = strEntryName1;
523 strEntryName2 += strStave;
524 strEntryName2 += cStave;
525
526 for (Int_t cHS=0; cHS<2; cHS++) {
527 strEntryName3 = strEntryName2;
528 strEntryName3 += strHalfStave;
529 strEntryName3 += cHS;
530
531 for(Int_t cLad =0; cLad<2; cLad++){
532 symname = strEntryName3;
533 symname += strLadder;
534 symname += cLad+cHS*2;
535 uid = LayerToVolUID(kSPD1,modnum++);
536 pne = fgGeometry->GetAlignableEntryByUID(uid);
537 if(!pne)
538 {
539 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
540 return kFALSE;
541 }
542 sname = pne->GetName();
543 if(symname.CompareTo(sname))
544 {
545 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
546 "Expected was %s, found was %s!", uid, symname.Data(), sname));
547 return kFALSE;
548 }
0bf7aade 549 }
8f8273a4 550 }
67dd5535 551 }
552 }
553 }
ff5970a3 554
555 /********************* SPD layer2 ***********************/
556 {
557 modnum = 0;
558
559 for(Int_t cSect = 0; cSect<10; cSect++){
560 strEntryName1 = strSPD;
561 strEntryName1 += 1;
562 strEntryName1 += strSector;
563 strEntryName1 += cSect;
564
565 for(Int_t cStave =0; cStave<4; cStave++){
566 strEntryName2 = strEntryName1;
567 strEntryName2 += strStave;
568 strEntryName2 += cStave;
569
570 for (Int_t cHS=0; cHS<2; cHS++) {
571 strEntryName3 = strEntryName2;
572 strEntryName3 += strHalfStave;
573 strEntryName3 += cHS;
574
575 for(Int_t cLad =0; cLad<2; cLad++){
576 symname = strEntryName3;
577 symname += strLadder;
578 symname += cLad+cHS*2;
579 uid = LayerToVolUID(kSPD2,modnum++);
580 pne = fgGeometry->GetAlignableEntryByUID(uid);
581 if(!pne)
582 {
583 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
584 return kFALSE;
585 }
586 sname = pne->GetName();
587 if(symname.CompareTo(sname))
588 {
589 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d."
590 "Expected was %s, found was %s!", uid, symname.Data(), sname));
591 return kFALSE;
592 }
0bf7aade 593 }
8f8273a4 594 }
67dd5535 595 }
596 }
597 }
ff5970a3 598
599 /********************* SDD layer1 ***********************/
600 {
601 modnum=0;
602
603 for(Int_t c1 = 1; c1<=14; c1++){
604 strEntryName1 = strSDD;
605 strEntryName1 += 2;
606 strEntryName1 +=strLadder;
607 strEntryName1 += (c1-1);
608 for(Int_t c2 =1; c2<=6; c2++){
609 symname = strEntryName1;
610 symname += strSensor;
611 symname += (c2-1);
612 uid = LayerToVolUID(kSDD1,modnum++);
613 pne = fgGeometry->GetAlignableEntryByUID(uid);
614 if(!pne)
615 {
616 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
617 return kFALSE;
618 }
619 sname = pne->GetName();
620 if(symname.CompareTo(sname))
621 {
622 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
623 "Expected was %s, found was %s!", uid, symname.Data(), sname));
624 return kFALSE;
625 }
626 }
627 }
628 }
629
630 /********************* SDD layer2 ***********************/
631 {
632 modnum=0;
633
634 for(Int_t c1 = 1; c1<=22; c1++){
635 strEntryName1 = strSDD;
636 strEntryName1 += 3;
637 strEntryName1 +=strLadder;
638 strEntryName1 += (c1-1);
639 for(Int_t c2 = 1; c2<=8; c2++){
640 symname = strEntryName1;
641 symname += strSensor;
642 symname += (c2-1);
643 uid = LayerToVolUID(kSDD2,modnum++);
644 pne = fgGeometry->GetAlignableEntryByUID(uid);
645 if(!pne)
646 {
647 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
648 return kFALSE;
649 }
650 sname = pne->GetName();
651 if(symname.CompareTo(sname))
652 {
653 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
654 "Expected was %s, found was %s!", uid, symname.Data(), sname));
655 return kFALSE;
656 }
657 }
658 }
659 }
660
661 /********************* SSD layer1 ***********************/
662 {
663 modnum=0;
664
665 for(Int_t c1 = 1; c1<=34; c1++){
666 strEntryName1 = strSSD;
667 strEntryName1 += 4;
668 strEntryName1 +=strLadder;
669 strEntryName1 += (c1-1);
670 for(Int_t c2 = 1; c2<=22; c2++){
671 symname = strEntryName1;
672 symname += strSensor;
673 symname += (c2-1);
674 uid = LayerToVolUID(kSSD1,modnum++);
675 pne = fgGeometry->GetAlignableEntryByUID(uid);
676 if(!pne)
677 {
678 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
679 return kFALSE;
680 }
681 sname = pne->GetName();
682 if(symname.CompareTo(sname))
683 {
684 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
685 "Expected was %s, found was %s!", uid, symname.Data(), sname));
686 return kFALSE;
687 }
688 }
689 }
690 }
691
692 /********************* SSD layer2 ***********************/
693 {
694 modnum=0;
695
696 for(Int_t c1 = 1; c1<=38; c1++){
697 strEntryName1 = strSSD;
698 strEntryName1 += 5;
699 strEntryName1 +=strLadder;
700 strEntryName1 += (c1-1);
701 for(Int_t c2 = 1; c2<=25; c2++){
702 symname = strEntryName1;
703 symname += strSensor;
704 symname += (c2-1);
705 uid = LayerToVolUID(kSSD2,modnum++);
706 pne = fgGeometry->GetAlignableEntryByUID(uid);
707 if(!pne)
708 {
709 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
710 return kFALSE;
711 }
712 sname = pne->GetName();
713 if(symname.CompareTo(sname))
714 {
715 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
716 "Expected was %s, found was %s!", uid, symname.Data(), sname));
717 return kFALSE;
718 }
719 }
720 }
721 }
722
723 AliDebugClass(2,"Consistency check for ITS symbolic names finished successfully.");
67dd5535 724 }
725
ff5970a3 726 if(detsString.Contains("TPC"))
67dd5535 727 {
ff5970a3 728 /*************** TPC inner and outer layers ****************/
729
730 AliDebugClass(2,"Checking consistency of symbolic names for TPC layers");
731 TString sAsector="TPC/EndcapA/Sector";
732 TString sCsector="TPC/EndcapC/Sector";
733 TString sInner="/InnerChamber";
734 TString sOuter="/OuterChamber";
735
736 /*************** TPC inner chambers' layer ****************/
737 {
738 modnum = 0;
67dd5535 739
ff5970a3 740 for(Int_t cnt=1; cnt<=18; cnt++)
741 {
742 symname = sAsector;
743 symname += cnt;
744 symname += sInner;
745 uid = LayerToVolUID(kTPC1,modnum++);
0bf7aade 746 pne = fgGeometry->GetAlignableEntryByUID(uid);
747 if(!pne)
748 {
749 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
750 return kFALSE;
751 }
752 sname = pne->GetName();
753 if(symname.CompareTo(sname))
754 {
755 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
756 "Expected was %s, found was %s!", uid, symname.Data(), sname));
757 return kFALSE;
758 }
67dd5535 759 }
67dd5535 760
ff5970a3 761 for(Int_t cnt=1; cnt<=18; cnt++)
762 {
763 symname = sCsector;
764 symname += cnt;
765 symname += sInner;
766 uid = LayerToVolUID(kTPC1,modnum++);
0bf7aade 767 pne = fgGeometry->GetAlignableEntryByUID(uid);
768 if(!pne)
769 {
770 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
771 return kFALSE;
772 }
773 sname = pne->GetName();
774 if(symname.CompareTo(sname))
775 {
776 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
777 "Expected was %s, found was %s!", uid, symname.Data(), sname));
778 return kFALSE;
779 }
67dd5535 780 }
781 }
67dd5535 782
ff5970a3 783 /*************** TPC outer chambers' layer ****************/
784 {
785 modnum = 0;
67dd5535 786
ff5970a3 787 for(Int_t cnt=1; cnt<=18; cnt++)
788 {
789 symname = sAsector;
790 symname += cnt;
791 symname += sOuter;
792 uid = LayerToVolUID(kTPC2,modnum++);
0bf7aade 793 pne = fgGeometry->GetAlignableEntryByUID(uid);
794 if(!pne)
795 {
796 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
797 return kFALSE;
798 }
799 sname = pne->GetName();
800 if(symname.CompareTo(sname))
801 {
802 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
803 "Expected was %s, found was %s!", uid, symname.Data(), sname));
804 return kFALSE;
805 }
67dd5535 806 }
67dd5535 807
ff5970a3 808 for(Int_t cnt=1; cnt<=18; cnt++)
809 {
810 symname = sCsector;
811 symname += cnt;
812 symname += sOuter;
813 uid = LayerToVolUID(kTPC2,modnum++);
0bf7aade 814 pne = fgGeometry->GetAlignableEntryByUID(uid);
815 if(!pne)
816 {
817 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
818 return kFALSE;
819 }
820 sname = pne->GetName();
821 if(symname.CompareTo(sname))
822 {
823 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
824 "Expected was %s, found was %s!", uid, symname.Data(), sname));
825 return kFALSE;
826 }
67dd5535 827 }
828 }
67dd5535 829
ff5970a3 830 AliDebugClass(2,"Consistency check for TPC symbolic names finished successfully.");
67dd5535 831 }
832
ff5970a3 833 if(detsString.Contains("TOF"))
67dd5535 834 {
ff5970a3 835 /********************* TOF layer ***********************/
67dd5535 836
ff5970a3 837 AliDebugClass(2,"Checking consistency of symbolic names for TOF layers");
67dd5535 838 modnum=0;
ff5970a3 839
67dd5535 840 Int_t nstrA=15;
841 Int_t nstrB=19;
842 Int_t nstrC=19;
843 Int_t nSectors=18;
844 Int_t nStrips=nstrA+2*nstrB+2*nstrC;
0bf7aade 845
846 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 847
848 TString snSM = "TOF/sm";
849 TString snSTRIP = "/strip";
850
851 for (Int_t isect = 0; isect < nSectors; isect++) {
852 for (Int_t istr = 1; istr <= nStrips; istr++) {
853 symname = snSM;
854 symname += Form("%02d",isect);
855 symname += snSTRIP;
856 symname += Form("%02d",istr);
0bf7aade 857 uid = LayerToVolUID(kTOF,modnum++);
858 if(!activeSectors[isect]) continue; // taking possible missing TOF sectors (partial geometry) into account
859 if ((isect==13 || isect==14 || isect==15) && (istr >= 39 && istr <= 53)) continue; //taking holes into account
860 pne = fgGeometry->GetAlignableEntryByUID(uid);
861 if(!pne)
862 {
863 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
864 return kFALSE;
865 }
866 sname = pne->GetName();
867 if(symname.CompareTo(sname))
868 {
869 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
870 "Expected was %s, found was %s!", uid, symname.Data(), sname));
871 return kFALSE;
872 }
67dd5535 873 }
874 }
ff5970a3 875
876 AliDebugClass(2,"Consistency check for TOF symbolic names finished successfully.");
67dd5535 877 }
878
ff5970a3 879 if(detsString.Contains("HMPID"))
67dd5535 880 {
ff5970a3 881 /********************* HMPID layer ***********************/
882
883 AliDebugClass(2,"Checking consistency of symbolic names for HMPID layers");
67dd5535 884 TString str = "/HMPID/Chamber";
885
886 for (modnum=0; modnum < 7; modnum++) {
887 symname = str;
888 symname += modnum;
0bf7aade 889 uid = LayerToVolUID(kHMPID,modnum);
890 pne = fgGeometry->GetAlignableEntryByUID(uid);
891 if(!pne)
892 {
893 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
894 return kFALSE;
895 }
896 sname = pne->GetName();
897 if(symname.CompareTo(sname))
898 {
899 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
900 "Expected was %s, found was %s!", uid, symname.Data(), sname));
901 return kFALSE;
902 }
67dd5535 903 }
ff5970a3 904
905 AliDebugClass(2,"Consistency check for HMPID symbolic names finished successfully.");
67dd5535 906 }
907
ff5970a3 908 if(detsString.Contains("TRD"))
67dd5535 909 {
ff5970a3 910 /********************* TRD layers 1-6 *******************/
911 //!! 6 layers with index increasing in outwards direction
912
913 AliDebugClass(2,"Checking consistency of symbolic names for TRD layers");
67dd5535 914 Int_t arTRDlayId[6] = {kTRD1, kTRD2, kTRD3, kTRD4, kTRD5, kTRD6};
915
0bf7aade 916 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
917
67dd5535 918 TString snStr = "TRD/sm";
919 TString snApp1 = "/st";
920 TString snApp2 = "/pl";
921
922 for(Int_t layer=0; layer<6; layer++){
923 modnum=0;
924 for (Int_t isect = 0; isect < 18; isect++) {
925 for (Int_t icham = 0; icham < 5; icham++) {
926 symname = snStr;
927 symname += Form("%02d",isect);
928 symname += snApp1;
929 symname += icham;
930 symname += snApp2;
931 symname += layer;
0bf7aade 932 uid = LayerToVolUID(arTRDlayId[layer],modnum++);
933 if(!activeSectors[isect]) continue;
934 if ((isect==13 || isect==14 || isect==15) && icham==2) continue; //keeping holes into account
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 }
67dd5535 948 }
949 }
950 }
ff5970a3 951
952 AliDebugClass(2,"Consistency check for TRD symbolic names finished successfully.");
67dd5535 953 }
df117114 954
ff5970a3 955 if(detsString.Contains("PHOS"))
df117114 956 {
ff5970a3 957 /********************* PHOS EMC layer ***********************/
df117114 958
ff5970a3 959 AliDebugClass(2,"Checking consistency of symbolic names for PHOS layers");
960
961 {
962 TString str = "PHOS/Module";
963 modnum=0;
964
965 for (Int_t iModule=1; iModule <= 5; iModule++) {
966 symname = str;
967 symname += iModule;
968 modnum = iModule-1;
969 uid = LayerToVolUID(kPHOS1,modnum);
970 pne = fgGeometry->GetAlignableEntryByUID(uid);
971 if(!pne)
972 {
973 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
974 return kFALSE;
975 }
976 sname = pne->GetName();
977 if(symname.CompareTo(sname))
978 {
979 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
980 "Expected was %s, found was %s!", uid, symname.Data(), sname));
981 return kFALSE;
982 }
0bf7aade 983 }
df117114 984 }
df117114 985
ff5970a3 986 /********************* PHOS CPV layer ***********************/
987 {
988 TString str = "PHOS/Module";
989 modnum=0;
f47b9233 990
ff5970a3 991 for (Int_t iModule=1; iModule <= 5; iModule++) {
992 symname = str;
993 symname += iModule;
994 symname += "/CPV";
995 modnum = iModule-1;
996 uid = LayerToVolUID(kPHOS2,modnum);
997 pne = fgGeometry->GetAlignableEntryByUID(uid);
998 if(!pne)
999 {
1000 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1001 return kFALSE;
1002 }
1003 sname = pne->GetName();
1004 if(symname.CompareTo(sname))
1005 {
1006 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1007 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1008 return kFALSE;
1009 }
0bf7aade 1010 }
f47b9233 1011 }
ff5970a3 1012
1013 AliDebugClass(2,"Consistency check for PHOS symbolic names finished successfully.");
f47b9233 1014 }
1015
ff5970a3 1016 if(detsString.Contains("EMCAL"))
3dfc15c0 1017 {
ff5970a3 1018 /********************* EMCAL layer ***********************/
1019
1020 AliDebugClass(2,"Checking consistency of symbolic names for EMCAL layers");
3dfc15c0 1021 TString str = "EMCAL/FullSupermodule";
1022 modnum=0;
1023
1024 for (Int_t iModule=1; iModule <= 12; iModule++) {
1025 symname = str;
1026 symname += iModule;
1027 if(iModule >10) {
1028 symname = "EMCAL/HalfSupermodule";
1029 symname += iModule-10;
1030 }
1031 modnum = iModule-1;
0bf7aade 1032 uid = LayerToVolUID(kEMCAL,modnum);
1033 pne = fgGeometry->GetAlignableEntryByUID(uid);
1034 if(!pne)
1035 {
1036 AliErrorClass(Form("In the currently loaded geometry there is no TGeoPNEntry with unique id %d",uid));
1037 return kFALSE;
1038 }
1039 sname = pne->GetName();
1040 if(symname.CompareTo(sname))
1041 {
1042 AliErrorClass(Form("Current loaded geometry differs in the definition of symbolic name for uid %d"
1043 "Expected was %s, found was %s!", uid, symname.Data(), sname));
1044 return kFALSE;
1045 }
3dfc15c0 1046 }
ff5970a3 1047
1048 AliDebugClass(2,"Consistency check for EMCAL symbolic names finished successfully.");
3dfc15c0 1049 }
0bf7aade 1050
1051 return kTRUE;
f47b9233 1052
67dd5535 1053}
1054
1055//_____________________________________________________________________________
1056void AliGeomManager::InitPNEntriesLUT()
1057{
1058 // Initialize the look-up table which associates the unique
1059 // numerical identity of each alignable volume to the
1060 // corresponding TGeoPNEntry.
1061 // The LUTs are static; they are created at the creation of the
1062 // AliGeomManager instance and recreated if the geometry has changed
1063 //
36b010bf 1064 if (fgPNEntry[0]) return;
67dd5535 1065
36b010bf 1066 if(!fgGeometry) {
1067 AliErrorClass("Impossible to initialize PNEntries LUT without an active geometry");
1068 return;
1069 }
25fad4e5 1070
67dd5535 1071 for (Int_t iLayer = 0; iLayer < (kLastLayer - kFirstLayer); iLayer++){
36b010bf 1072 fgPNEntry[iLayer] = new TGeoPNEntry*[fgLayerSize[iLayer]];
1073 for(Int_t modnum=0; modnum<fgLayerSize[iLayer]; modnum++){
0bf7aade 1074 fgPNEntry[iLayer][modnum] = fgGeometry->GetAlignableEntryByUID(LayerToVolUID(iLayer+1,modnum));
36b010bf 1075 }
1076 }
1077}
1078
67dd5535 1079//______________________________________________________________________
1080TGeoHMatrix* AliGeomManager::GetMatrix(TGeoPNEntry* pne)
1081{
5aedd709 1082 // Get the global transformation matrix for a given PNEntry
67dd5535 1083 // by quering the TGeoManager
1084
36b010bf 1085 if (!fgGeometry || !fgGeometry->IsClosed()) {
25fad4e5 1086 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1087 return NULL;
1088 }
5aedd709 1089
67dd5535 1090 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
1091 if (pnode) return pnode->GetMatrix();
1092
1093 const char* path = pne->GetTitle();
36b010bf 1094 if (!fgGeometry->cd(path)) {
67dd5535 1095 AliErrorClass(Form("Volume path %s not valid!",path));
1096 return NULL;
1097 }
36b010bf 1098 return fgGeometry->GetCurrentMatrix();
67dd5535 1099}
1100
1101//______________________________________________________________________
1102TGeoHMatrix* AliGeomManager::GetMatrix(Int_t index)
1103{
1104 // Get the global transformation matrix for a given alignable volume
1105 // identified by its unique ID 'index' by quering the TGeoManager
1106
67dd5535 1107 TGeoPNEntry *pne = GetPNEntry(index);
1108 if (!pne) return NULL;
1109
1110 return GetMatrix(pne);
1111}
1112
1113//______________________________________________________________________
1114TGeoHMatrix* AliGeomManager::GetMatrix(const char* symname)
1115{
1116 // Get the global transformation matrix for a given alignable volume
1117 // identified by its symbolic name 'symname' by quering the TGeoManager
1118
36b010bf 1119 if (!fgGeometry || !fgGeometry->IsClosed()) {
1120 AliErrorClass("No active geometry or geometry not yet closed!");
1121 return NULL;
1122 }
1123
1124 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 1125 if (!pne) return NULL;
1126
1127 return GetMatrix(pne);
1128}
1129
1130//______________________________________________________________________
1131Bool_t AliGeomManager::GetTranslation(Int_t index, Double_t t[3])
1132{
1133 // Get the translation vector for a given module 'index'
1134 // by quering the TGeoManager
1135
1136 TGeoHMatrix *m = GetMatrix(index);
1137 if (!m) return kFALSE;
1138
1139 Double_t *trans = m->GetTranslation();
1140 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1141
1142 return kTRUE;
1143}
1144
1145//______________________________________________________________________
1146Bool_t AliGeomManager::GetRotation(Int_t index, Double_t r[9])
1147{
1148 // Get the rotation matrix for a given module 'index'
1149 // by quering the TGeoManager
1150
1151 TGeoHMatrix *m = GetMatrix(index);
1152 if (!m) return kFALSE;
1153
1154 Double_t *rot = m->GetRotationMatrix();
1155 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1156
1157 return kTRUE;
1158}
1159
5d534fe3 1160//_____________________________________________________________________________
1161Bool_t AliGeomManager::GetDeltaForBranch(Int_t index, TGeoHMatrix &inclusiveD)
1162{
1163 // The method sets the matrix passed as argument as the global delta
1164 // (for the volume referred by the unique index) including the displacements
1165 // of all parent volumes in the branch.
1166 //
5d534fe3 1167
1168 TGeoHMatrix go,invgo;
1169 go = *GetOrigGlobalMatrix(index);
1170 invgo = go.Inverse();
5aedd709 1171 inclusiveD = *GetMatrix(index);
5d534fe3 1172 inclusiveD.Multiply(&invgo);
1173
1174 return kTRUE;
1175}
1176
1177//_____________________________________________________________________________
1178Bool_t AliGeomManager::GetDeltaForBranch(AliAlignObj& aao, TGeoHMatrix &inclusiveD)
1179{
1180 // The method sets the matrix passed as argument as the global delta
1181 // (for the volume referred by the alignment object) including the displacements
1182 // of all parent volumes in the brach.
1183 //
1184 Int_t index = aao.GetVolUID();
1185 if(!index){
1186 AliErrorClass("Either the alignment object or its index are not valid");
1187 return kFALSE;
1188 }
1189 return GetDeltaForBranch(index, inclusiveD);
1190}
1191
36b010bf 1192//______________________________________________________________________
1193Bool_t AliGeomManager::GetOrigGlobalMatrix(const char* symname, TGeoHMatrix &m)
67dd5535 1194{
36b010bf 1195 // Get the global transformation matrix (ideal geometry) for a given alignable volume
0bf7aade 1196 // The alignable volume is identified by 'symname' which has to be either a valid symbolic
1197 // name, the query being performed after alignment, or a valid volume path if the query is
1198 // performed before alignment.
1199 //
36b010bf 1200 m.Clear();
67dd5535 1201
36b010bf 1202 if (!fgGeometry || !fgGeometry->IsClosed()) {
1203 AliErrorClass("No active geometry or geometry not yet closed!");
67dd5535 1204 return kFALSE;
1205 }
36b010bf 1206 if (!fgGeometry->GetListOfPhysicalNodes()) {
67dd5535 1207 AliWarningClass("gGeoManager doesn't contain any aligned nodes!");
36b010bf 1208 if (!fgGeometry->cd(symname)) {
67dd5535 1209 AliErrorClass(Form("Volume path %s not valid!",symname));
1210 return kFALSE;
1211 }
1212 else {
36b010bf 1213 m = *fgGeometry->GetCurrentMatrix();
67dd5535 1214 return kTRUE;
1215 }
1216 }
1217
36b010bf 1218 TGeoPNEntry* pne = fgGeometry->GetAlignableEntry(symname);
67dd5535 1219 const char* path = NULL;
67dd5535 1220 if(pne){
0bf7aade 1221 m = *pne->GetGlobalOrig();
1222 return kTRUE;
67dd5535 1223 }else{
1224 AliWarningClass(Form("The symbolic volume name %s does not correspond to a physical entry. Using it as a volume path!",symname));
1225 path=symname;
1226 }
1227
36b010bf 1228 return GetOrigGlobalMatrixFromPath(path,m);
1229}
1230
1231//_____________________________________________________________________________
1232Bool_t AliGeomManager::GetOrigGlobalMatrixFromPath(const char *path, TGeoHMatrix &m)
1233{
5aedd709 1234 // The method returns the global matrix for the volume identified by
1235 // 'path' in the ideal detector geometry.
1236 // The output global matrix is stored in 'm'.
1237 // Returns kFALSE in case TGeo has not been initialized or the volume
1238 // path is not valid.
36b010bf 1239 //
1240 m.Clear();
1241
1242 if (!fgGeometry || !fgGeometry->IsClosed()) {
1243 AliErrorClass("Can't get the original global matrix! gGeoManager doesn't exist or it is still opened!");
67dd5535 1244 return kFALSE;
1245 }
1246
36b010bf 1247 if (!fgGeometry->CheckPath(path)) {
1248 AliErrorClass(Form("Volume path %s not valid!",path));
1249 return kFALSE;
1250 }
67dd5535 1251
36b010bf 1252 TIter next(fgGeometry->GetListOfPhysicalNodes());
1253 fgGeometry->cd(path);
67dd5535 1254
36b010bf 1255 while(fgGeometry->GetLevel()){
67dd5535 1256
1257 TGeoPhysicalNode *physNode = NULL;
1258 next.Reset();
36b010bf 1259 TGeoNode *node = fgGeometry->GetCurrentNode();
67dd5535 1260 while ((physNode=(TGeoPhysicalNode*)next()))
1261 if (physNode->GetNode() == node) break;
1262
1263 TGeoMatrix *lm = NULL;
1264 if (physNode) {
5aedd709 1265 lm = physNode->GetOriginalMatrix();
1266 if (!lm) lm = node->GetMatrix();
67dd5535 1267 } else
1268 lm = node->GetMatrix();
1269
1270 m.MultiplyLeft(lm);
1271
36b010bf 1272 fgGeometry->CdUp();
67dd5535 1273 }
1274
1275 return kTRUE;
1276}
1277
36b010bf 1278//_____________________________________________________________________________
1279TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(TGeoPNEntry* pne)
1280{
1281 // The method returns global matrix for the ideal detector geometry
1282 // using the corresponding TGeoPNEntry as an input.
5aedd709 1283 // The returned pointer should be copied by the user, since its content could
1284 // be overwritten by a following call to the method.
1285 // In case of missing TGeoManager the method returns NULL.
1286 //
36b010bf 1287 if (!fgGeometry || !fgGeometry->IsClosed()) {
1288 AliErrorClass("Can't get the global matrix! gGeoManager doesn't exist or it is still opened!");
1289 return NULL;
1290 }
1291
0bf7aade 1292 return pne->GetGlobalOrig();
36b010bf 1293}
1294
67dd5535 1295//______________________________________________________________________
36b010bf 1296TGeoHMatrix* AliGeomManager::GetOrigGlobalMatrix(Int_t index)
67dd5535 1297{
5aedd709 1298 // The method returns global matrix from the ideal detector geometry
1299 // for the volume identified by its index.
1300 // The returned pointer should be copied by the user, since its content could
1301 // be overwritten by a following call to the method.
1302 // In case of missing TGeoManager the method returns NULL.
1303 // If possible, the method uses the LUT of original ideal matrices
1304 // for fast access. The LUT is reset in case a
36b010bf 1305 // new geometry is loaded.
5aedd709 1306 //
0bf7aade 1307 TGeoPNEntry* pne = GetPNEntry(index);
1308 return pne->GetGlobalOrig();
67dd5535 1309}
1310
1311//______________________________________________________________________
1312Bool_t AliGeomManager::GetOrigTranslation(Int_t index, Double_t t[3])
1313{
1314 // Get the original translation vector (ideal geometry)
1315 // for a given module 'index' by quering the TGeoManager
1316
36b010bf 1317 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1318 if (!m) return kFALSE;
67dd5535 1319
36b010bf 1320 Double_t *trans = m->GetTranslation();
67dd5535 1321 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
1322
1323 return kTRUE;
1324}
1325
1326//______________________________________________________________________
1327Bool_t AliGeomManager::GetOrigRotation(Int_t index, Double_t r[9])
1328{
1329 // Get the original rotation matrix (ideal geometry)
1330 // for a given module 'index' by quering the TGeoManager
1331
36b010bf 1332 TGeoHMatrix *m = GetOrigGlobalMatrix(index);
1333 if (!m) return kFALSE;
67dd5535 1334
36b010bf 1335 Double_t *rot = m->GetRotationMatrix();
67dd5535 1336 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
1337
1338 return kTRUE;
1339}
1340
1341//______________________________________________________________________
1342const TGeoHMatrix* AliGeomManager::GetTracking2LocalMatrix(Int_t index)
1343{
25fad4e5 1344 // Get the matrix which transforms from the tracking to the local RS
67dd5535 1345 // The method queries directly the TGeoPNEntry
1346
67dd5535 1347 TGeoPNEntry *pne = GetPNEntry(index);
1348 if (!pne) return NULL;
1349
1350 const TGeoHMatrix *m = pne->GetMatrix();
1351 if (!m)
5aedd709 1352 AliErrorClass(Form("TGeoPNEntry (%s) contains no tracking-to-local matrix !",pne->GetName()));
67dd5535 1353
1354 return m;
1355}
1356
1357//______________________________________________________________________
1358Bool_t AliGeomManager::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
1359{
1360 // Get the matrix which transforms from the tracking r.s. to
1361 // the global one.
1362 // Returns kFALSE in case of error.
1363
1364 m.Clear();
1365
1366 TGeoHMatrix *m1 = GetMatrix(index);
1367 if (!m1) return kFALSE;
1368
1369 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
1370 if (!m2) return kFALSE;
1371
1372 m = *m1;
1373 m.Multiply(m2);
1374
1375 return kTRUE;
1376}
1377
1378//_____________________________________________________________________________
1379TGeoPNEntry* AliGeomManager::GetPNEntry(Int_t voluid) {
1380 // Returns the TGeoPNEntry for the given global volume ID "voluid"
1381 //
1382 Int_t modId;
1383 ELayerID layerId = VolUIDToLayer(voluid,modId);
1384 return GetPNEntry(layerId,modId);
1385}
1386
67dd5535 1387//_____________________________________________________________________________
1388TGeoPNEntry* AliGeomManager::GetPNEntry(ELayerID layerId, Int_t modId)
1389{
1390 // Returns the TGeoPNEntry for a given layer
1391 // and module ID
1392 //
25fad4e5 1393
67dd5535 1394 if(modId<0 || modId>=fgLayerSize[layerId-kFirstLayer]){
1395 AliWarningClass(Form("Module number %d not in the valid range (0->%d) !",modId,fgLayerSize[layerId-kFirstLayer]-1));
1396 return NULL;
1397 }
1398
1399 return fgPNEntry[layerId-kFirstLayer][modId];
1400}
1401
5590c6c3 1402//_____________________________________________________________________________
1403void AliGeomManager::CheckOverlapsOverPNs(Double_t threshold)
1404{
1405 // Check for overlaps/extrusions on physical nodes only;
1406 // this overlap-checker is meant to be used to check overlaps/extrusions
1407 // originated by the application of alignment objects.
1408 //
1409
1410 TObjArray* ovexlist = new TObjArray(64);
1411
1412 AliInfoClass("********* Checking overlaps/extrusions over physical nodes only *********");
1413 TObjArray* pnList = gGeoManager->GetListOfPhysicalNodes();
0cd61c1d 1414 TGeoVolume* mvol = 0;
5590c6c3 1415 TGeoPhysicalNode* pn;
1416 TObjArray* overlaps = new TObjArray(64);
1417 overlaps->SetOwner();
1418
1419 TStopwatch timer2;
1420 timer2.Start();
1421 for(Int_t pni=0; pni<pnList->GetEntriesFast(); pni++){
1422 pn = (TGeoPhysicalNode*) pnList->UncheckedAt(pni);
1423 // checking the volume of the mother (go upper in the tree in case it is an assembly)
1424 Int_t levup=1;
1425 while(((TGeoVolume*)pn->GetVolume(pn->GetLevel()-levup))->IsAssembly()) levup++;
1426 //Printf("Going to upper level");
1427 mvol = pn->GetVolume(pn->GetLevel()-levup);
1428 if(!mvol->IsSelected()){
1429 AliInfoClass(Form("Checking overlaps for volume %s",mvol->GetName()));
1430 mvol->CheckOverlaps(threshold);
1431 ovexlist = gGeoManager->GetListOfOverlaps();
1432 TIter next(ovexlist);
1433 TGeoOverlap *ov;
1434 while ((ov=(TGeoOverlap*)next())) overlaps->Add(ov->Clone());
1435 mvol->SelectVolume();
1436 }
1437 }
1438 mvol->SelectVolume(kTRUE); // clears the list of selected volumes
1439
1440 AliInfoClass(Form("Number of overlapping/extruding PNs: %d",overlaps->GetEntriesFast()));
1441 timer2.Stop();
1442 timer2.Print();
1443
1444 TIter nextN(overlaps);
1445 TGeoOverlap *ovlp;
1446 while ((ovlp=(TGeoOverlap*)nextN())) ovlp->PrintInfo();
1447
1448 overlaps->Delete();
1449 delete overlaps;
1450}
1451
67dd5535 1452//_____________________________________________________________________________
1453Bool_t AliGeomManager::ApplyAlignObjsFromCDB(const char* AlignDetsList)
1454{
1455 // Calls AddAlignObjsFromCDBSingleDet for the detectors appearing in
1456 // the list passed as argument (called by AliSimulation and
1457 // AliReconstruction)
1458 // Read the alignment objects from CDB.
1459 // Each detector is supposed to have the
1460 // alignment objects in DET/Align/Data CDB path.
1461 // All the detector objects are then collected,
1462 // sorted by geometry level (starting from ALIC) and
1463 // then applied to the TGeo geometry.
1464 // Finally an overlaps check is performed.
1465 //
1466
36b010bf 1467 TObjArray alignObjArray;
1468 alignObjArray.Clear();
1469 alignObjArray.SetOwner(0);
67dd5535 1470
1471 TString alObjsNotLoaded="";
1472 TString alObjsLoaded="";
1473
1474 TString AlignDetsString(AlignDetsList);
1475 TObjArray *detsarr = AlignDetsString.Tokenize(' ');
1476 TIter iter(detsarr);
1477 TObjString *str = 0;
1478
1479 while((str = (TObjString*) iter.Next())){
1480 TString det(str->String());
36b010bf 1481 AliInfoClass(Form("Loading alignment objs for %s",det.Data()));
1482 if(!LoadAlignObjsFromCDBSingleDet(det.Data(),alignObjArray)){
67dd5535 1483 alObjsNotLoaded += det.Data();
1484 alObjsNotLoaded += " ";
1485 } else {
1486 alObjsLoaded += det.Data();
1487 alObjsLoaded += " ";
1488 }
1489 }
b80b98e1 1490 detsarr->Delete();
1491 delete detsarr;
67dd5535 1492
36b010bf 1493 if(!alObjsLoaded.IsNull()) AliInfoClass(Form("Alignment objects loaded for: %s",
1494 alObjsLoaded.Data()));
1495 if(!alObjsNotLoaded.IsNull()) AliInfoClass(Form("Didn't/couldn't load alignment objects for: %s",
1496 alObjsNotLoaded.Data()));
67dd5535 1497
9cb4fe0b 1498 return ApplyAlignObjsToGeom(alignObjArray);
67dd5535 1499}
1500
1501//_____________________________________________________________________________
36b010bf 1502Bool_t AliGeomManager::LoadAlignObjsFromCDBSingleDet(const char* detName, TObjArray& alignObjArray)
67dd5535 1503{
1504 // Adds the alignable objects found in the CDBEntry for the detector
1505 // passed as argument to the array of all alignment objects to be applyed
1506 // to geometry
1507 //
1508 // Fills array of single detector's alignable objects from CDB
1509
36b010bf 1510 AliDebugClass(2, Form("Loading alignment objs for detector: %s",detName));
67dd5535 1511
1512 AliCDBEntry *entry;
1513
1514 AliCDBPath path(detName,"Align","Data");
1515
1516 entry=AliCDBManager::Instance()->Get(path.GetPath());
1517 if(!entry){
36b010bf 1518 AliDebugClass(2,Form("Couldn't load alignment data for detector %s",detName));
67dd5535 1519 return kFALSE;
1520 }
1521 entry->SetOwner(1);
1522 TClonesArray *alignArray = (TClonesArray*) entry->GetObject();
1523 alignArray->SetOwner(0);
36b010bf 1524 AliDebugClass(2,Form("Found %d alignment objects for %s",
1525 alignArray->GetEntries(),detName));
67dd5535 1526
1527 AliAlignObj *alignObj=0;
1528 TIter iter(alignArray);
1529
1530 // loop over align objects in detector
1531 while( ( alignObj=(AliAlignObj *) iter.Next() ) ){
36b010bf 1532 alignObjArray.Add(alignObj);
67dd5535 1533 }
1534 // delete entry --- Don't delete, it is cached!
1535
36b010bf 1536 AliDebugClass(2, Form("fAlignObjArray entries: %d",alignObjArray.GetEntries() ));
67dd5535 1537 return kTRUE;
1538
1539}
1540
1541//_____________________________________________________________________________
5590c6c3 1542Bool_t AliGeomManager::ApplyAlignObjsToGeom(TObjArray& alignObjArray, Bool_t ovlpcheck)
67dd5535 1543{
1544 // Read collection of alignment objects (AliAlignObj derived) saved
1545 // in the TClonesArray alObjArray and apply them to gGeoManager
1546 //
36b010bf 1547 alignObjArray.Sort();
1548 Int_t nvols = alignObjArray.GetEntriesFast();
67dd5535 1549
1550 Bool_t flag = kTRUE;
1551
1552 for(Int_t j=0; j<nvols; j++)
1553 {
36b010bf 1554 AliAlignObj* alobj = (AliAlignObj*) alignObjArray.UncheckedAt(j);
5590c6c3 1555 if (alobj->ApplyToGeometry(ovlpcheck) == kFALSE) flag = kFALSE;
67dd5535 1556 }
1557
1558 if (AliDebugLevelClass() >= 1) {
36b010bf 1559 fgGeometry->GetTopNode()->CheckOverlaps(1);
1560 TObjArray* ovexlist = fgGeometry->GetListOfOverlaps();
67dd5535 1561 if(ovexlist->GetEntriesFast()){
36b010bf 1562 AliErrorClass("The application of alignment objects to the geometry caused huge overlaps/extrusions!");
67dd5535 1563 }
1564 }
1565
36b010bf 1566 // Update the TGeoPhysicalNodes
1567 fgGeometry->RefreshPhysicalNodes();
1568
67dd5535 1569 return flag;
1570
1571}
1572
1573//_____________________________________________________________________________
1574Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* fileName, const char* clArrayName)
1575{
1576 // read collection of alignment objects (AliAlignObj derived) saved
1577 // in the TClonesArray ClArrayName in the file fileName and apply
1578 // them to the geometry
1579 //
1580
1581 TFile* inFile = TFile::Open(fileName,"READ");
1582 if (!inFile || !inFile->IsOpen()) {
1583 AliErrorClass(Form("Could not open file %s !",fileName));
1584 return kFALSE;
1585 }
1586
36b010bf 1587 TClonesArray* alignObjArray = ((TClonesArray*) inFile->Get(clArrayName));
67dd5535 1588 inFile->Close();
36b010bf 1589 if (!alignObjArray) {
67dd5535 1590 AliErrorClass(Form("Could not get array (%s) from file (%s) !",clArrayName,fileName));
1591 return kFALSE;
1592 }
1593
36b010bf 1594 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1595
1596}
1597
1598//_____________________________________________________________________________
1599Bool_t AliGeomManager::ApplyAlignObjsToGeom(AliCDBParam* param, AliCDBId& Id)
1600{
1601 // read collection of alignment objects (AliAlignObj derived) saved
1602 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1603 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1604 // to the geometry
1605 //
1606
1607 AliCDBStorage* storage = AliCDBManager::Instance()->GetStorage(param);
1608 AliCDBEntry* entry = storage->Get(Id);
36b010bf 1609 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
67dd5535 1610
36b010bf 1611 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1612
1613}
1614
1615//_____________________________________________________________________________
1616Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* uri, const char* path, Int_t runnum, Int_t version, Int_t sversion)
1617{
1618 // read collection of alignment objects (AliAlignObj derived) saved
1619 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1620 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1621 // to the geometry
1622 //
1623
1624 AliCDBParam* param = AliCDBManager::Instance()->CreateParameter(uri);
1625 AliCDBId id(path, runnum, runnum, version, sversion);
1626
1627 return ApplyAlignObjsToGeom(param, id);
1628
1629}
1630
1631//_____________________________________________________________________________
1632Bool_t AliGeomManager::ApplyAlignObjsToGeom(const char* detName, Int_t runnum, Int_t version, Int_t sversion)
1633{
1634 // read collection of alignment objects (AliAlignObj derived) saved
1635 // in the TClonesArray ClArrayName in the AliCDBEntry identified by
1636 // param (to get the AliCDBStorage) and Id; apply the alignment objects
1637 // to the geometry
1638 //
1639
1640 AliCDBPath path(detName,"Align","Data");
1641 AliCDBEntry* entry = AliCDBManager::Instance()->Get(path.GetPath(),runnum,version,sversion);
1642
1643 if(!entry) return kFALSE;
36b010bf 1644 TClonesArray* alignObjArray = ((TClonesArray*) entry->GetObject());
25fad4e5 1645
36b010bf 1646 return ApplyAlignObjsToGeom(*alignObjArray);
67dd5535 1647}