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