1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
16 ///////////////////////////////////////////////////////////////////////////
17 // AliITSUGeomTGeo is a simple interface class to TGeoManager //
18 // It is used in the simulation and reconstruction in order to //
19 // query the TGeo ITS geometry //
21 // author - cvetan.cheshkov@cern.ch //
23 // adapted to ITSupg 18/07/2012 - ruben.shahoyan@cern.ch //
25 // ATTENTION: In opposite to ols AliITSgeomTGeo, all indices start //
26 // from 0, not from 1!!! //
28 ///////////////////////////////////////////////////////////////////////////
32 #include <TGeoManager.h>
33 #include <TGeoPhysicalNode.h>
36 #include "AliITSUGeomTGeo.h"
38 #include "AliAlignObj.h"
40 ClassImp(AliITSUGeomTGeo)
43 const char* AliITSUGeomTGeo::fgkITSVolName = "ITSV";
44 const char* AliITSUGeomTGeo::fgkITSLrName = "ITSULayer";
45 const char* AliITSUGeomTGeo::fgkITSLadName = "ITSULadder";
46 const char* AliITSUGeomTGeo::fgkITSModName = "ITSUModule";
47 const char* AliITSUGeomTGeo::fgkITSSensName ="ITSUSensor";
48 const char* AliITSUGeomTGeo::fgkITSDetTypeName[AliITSUGeomTGeo::kNDetTypes] = {"Pix"};
50 TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root";
52 //______________________________________________________________________
53 AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build)
65 if (build) BuildITS();
68 //______________________________________________________________________
69 AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
71 ,fVersion(src.fVersion)
72 ,fNLayers(src.fNLayers)
73 ,fNModules(src.fNModules)
83 fNLadders = new Int_t[fNLayers];
84 fNDetectors = new Int_t[fNLayers];
85 fLrDetType = new Int_t[fNLayers];
86 fLastModIndex = new Int_t[fNLayers];
87 for (int i=fNLayers;i--;) {
88 fNLadders[i] = src.fNLadders[i];
89 fNDetectors[i] = src.fNDetectors[i];
90 fLrDetType[i] = src.fLrDetType[i];
91 fLastModIndex[i] = src.fLastModIndex[i];
94 fMatSens = new TObjArray(fNModules);
95 fMatSens->SetOwner(kTRUE);
96 for (int i=0;i<fNModules;i++) {
97 const TGeoHMatrix* mat = (TGeoHMatrix*)src.fMatSens->At(i);
98 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
102 fMatT2L = new TObjArray(fNModules);
103 fMatT2L->SetOwner(kTRUE);
104 for (int i=0;i<fNModules;i++) {
105 const TGeoHMatrix* mat =(TGeoHMatrix*) src.fMatT2L->At(i);
106 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
112 //______________________________________________________________________
113 AliITSUGeomTGeo::~AliITSUGeomTGeo()
118 delete[] fNDetectors;
119 delete[] fLastModIndex;
125 //______________________________________________________________________
126 AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
132 delete[] fNDetectors;
133 delete[] fLastModIndex;
134 fNLadders = fLrDetType = fNDetectors = fLastModIndex = 0;
135 fVersion = src.fVersion;
136 fNLayers = src.fNLayers;
137 fNModules = src.fNModules;
140 fMatSens = new TObjArray(fNModules);
141 fMatSens->SetOwner(kTRUE);
142 for (int i=0;i<fNModules;i++) {
143 const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatSens->At(i);
144 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
149 fMatT2L = new TObjArray(fNModules);
150 fMatT2L->SetOwner(kTRUE);
151 for (int i=0;i<fNModules;i++) {
152 const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatT2L->At(i);
153 fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
158 fNLadders = new Int_t[fNLayers];
159 fNDetectors = new Int_t[fNLayers];
160 fLrDetType = new Int_t[fNLayers];
161 fLastModIndex = new Int_t[fNLayers];
162 for (int i=fNLayers;i--;) {
163 fNLadders[i] = src.fNLadders[i];
164 fNDetectors[i] = src.fNDetectors[i];
165 fLrDetType[i] = src.fLrDetType[i];
166 fLastModIndex[i] = src.fLastModIndex[i];
173 //______________________________________________________________________
174 Int_t AliITSUGeomTGeo::GetModuleIndex(Int_t lay,Int_t lad,Int_t det) const
176 // This routine computes the module index number from the layer,
177 // ladder, and detector numbers. The number of ladders and detectors
178 // per layer is set statically
179 // see above for details.
181 // Int_t lay The layer number. Starting from 0.
182 // Int_t lad The ladder number. Starting from 0
183 // Int_t det The detector number in the ladder. Starting from 0
185 return GetFirstModIndex(lay) + fNDetectors[lay]*lad + det;
188 //______________________________________________________________________
189 Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &index2) const
191 // This routine computes the layer number for a
192 // given the module index. The
194 // Int_t index The module index number, starting from zero.
196 // Int_t index2 The module index inside a layer, starting from zero.
197 // Int_t lay The layer number. Starting from 0.
199 lay = GetLayer(index);
200 index2 = index - GetFirstModIndex(lay);
205 //______________________________________________________________________
206 Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const
208 // Get module layer, from 0
211 while(index>fLastModIndex[lay]) lay++;
215 //______________________________________________________________________
216 Int_t AliITSUGeomTGeo::GetLadder(Int_t index) const
218 // Get module ladder, from 0
221 while(index>fLastModIndex[lay]) lay++;
222 index -= GetFirstModIndex(lay);
223 return index/fNDetectors[lay];
226 //______________________________________________________________________
227 Int_t AliITSUGeomTGeo::GetModIdInLayer(Int_t index) const
229 // Get module number within layer, from 0
232 while(index>fLastModIndex[lay]) lay++;
233 index -= GetFirstModIndex(lay);
237 //______________________________________________________________________
238 Int_t AliITSUGeomTGeo::GetModIdInLadder(Int_t index) const
240 // Get module number within ladder, from 0
243 while(index>fLastModIndex[lay]) lay++;
244 index -= GetFirstModIndex(lay);
245 return index%fNDetectors[lay];
248 //______________________________________________________________________
249 Bool_t AliITSUGeomTGeo::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det) const
251 // The method is taken from the old AliITSgeom class by Bjorn Nilsen
253 // This routine computes the layer, ladder and detector number
254 // given the module index number.
256 // Int_t index The module index number, starting from zero.
258 // Int_t lay The layer number. Starting from 0
259 // Int_t lad The ladder number. Starting from 0
260 // Int_t det The detector number. Starting from 0
262 lay = GetLayer(index);
263 index -= GetFirstModIndex(lay);
264 lad = index/fNDetectors[lay];
265 det = index%fNDetectors[lay];
269 //______________________________________________________________________
270 const char* AliITSUGeomTGeo::GetSymName(Int_t index) const
272 // Get the TGeoPNEntry symbolic name
273 // for a given module identified by 'index'
276 if (!GetLayer(index,lay,index2)) return NULL;
277 // return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
278 // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers
279 // TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay+1,index2) );
280 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ModuleVolUID(index) );
282 AliError(Form("Failed to find alignable entry with index %d: (Lr%d Mod:%d) !",index,lay,index2));
285 return pne->GetName();
288 //______________________________________________________________________
289 TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index) const
291 // Get the transformation matrix for a given module 'index'
292 // by quering the TGeoManager
293 TGeoPNEntry *pne = GetPNEntry(index);
294 if (!pne) return NULL;
296 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
297 if (pnode) return pnode->GetMatrix();
299 const char* path = pne->GetTitle();
300 gGeoManager->PushPath(); // Preserve the modeler state.
301 if (!gGeoManager->cd(path)) {
302 gGeoManager->PopPath();
303 AliError(Form("Volume path %s not valid!",path));
306 TGeoHMatrix *mat = gGeoManager->GetCurrentMatrix();
307 gGeoManager->PopPath();
311 //______________________________________________________________________
312 Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3]) const
314 // Get the translation vector for a given module 'index'
315 // by quering the TGeoManager
316 TGeoHMatrix *m = GetMatrix(index);
317 if (!m) return kFALSE;
319 Double_t *trans = m->GetTranslation();
320 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
325 //______________________________________________________________________
326 Bool_t AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9]) const
328 // Get the rotation matrix for a given module 'index'
329 // by quering the TGeoManager
330 TGeoHMatrix *m = GetMatrix(index);
331 if (!m) return kFALSE;
333 Double_t *rot = m->GetRotationMatrix();
334 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
339 //______________________________________________________________________
340 Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const
342 // Get the original (ideal geometry) TGeo matrix for
343 // a given module identified by 'index'.
344 // The method is slow, so it should be used
348 const char *symname = GetSymName(index);
349 if (!symname) return kFALSE;
351 return AliGeomManager::GetOrigGlobalMatrix(symname,m);
354 //______________________________________________________________________
355 Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) const
357 // Get the original translation vector (ideal geometry)
358 // for a given module 'index' by quering the TGeoManager
360 if (!GetOrigMatrix(index,m)) return kFALSE;
362 Double_t *trans = m.GetTranslation();
363 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
368 //______________________________________________________________________
369 Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) const
371 // Get the original rotation matrix (ideal geometry)
372 // for a given module 'index' by quering the TGeoManager
374 if (!GetOrigMatrix(index,m)) return kFALSE;
376 Double_t *rot = m.GetRotationMatrix();
377 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
382 //______________________________________________________________________
383 TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixT2L(Int_t index) const
385 // Get the matrix which transforms from the tracking to local r.s.
386 // The method queries directly the TGeoPNEntry
387 TGeoPNEntry *pne = GetPNEntry(index);
388 if (!pne) return NULL;
390 TGeoHMatrix *m = (TGeoHMatrix*) pne->GetMatrix();
391 if (!m) AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
396 //______________________________________________________________________
397 Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
399 // Get the matrix which transforms from the tracking r.s. to
401 // Returns kFALSE in case of error.
404 TGeoHMatrix *m1 = GetMatrix(index);
405 if (!m1) return kFALSE;
407 const TGeoHMatrix *m2 = GetMatrixT2L(index);
408 if (!m2) return kFALSE;
416 //______________________________________________________________________
417 TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const
419 // Get the transformation matrix of the SENSOR (not ncessary the same as the module)
420 // for a given module 'index' by quering the TGeoManager
421 const TString kPathBase = Form("/ALIC_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern());
422 const TString kNames = Form("%%s%s%%d_1/%s%%d_%%d/%s%%d_%%d/%s%%d_%%d"
423 ,AliITSUGeomTGeo::GetITSLayerPattern()
424 ,AliITSUGeomTGeo::GetITSLadderPattern()
425 ,AliITSUGeomTGeo::GetITSModulePattern()
426 ,AliITSUGeomTGeo::GetITSSensorPattern());
428 Int_t lay,ladd,detInLad;
429 GetModuleId(index,lay,ladd,detInLad);
431 path.Form(kNames.Data(),kPathBase.Data(),lay,lay,ladd,lay,detInLad,lay,1);
432 gGeoManager->PushPath();
433 if (!gGeoManager->cd(path.Data())) {
434 gGeoManager->PopPath();
435 AliError(Form("Error in cd-ing to %s",path.Data()));
437 } // end if !gGeoManager
438 TGeoHMatrix* mat = gGeoManager->GetCurrentMatrix();
440 // printf("%d/%d/%d %s\n",lay,ladd,detInLad,path.Data());
442 // Retstore the modeler state.
443 gGeoManager->PopPath();
448 //______________________________________________________________________
449 TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const
451 // Get a pointer to the TGeoPNEntry of a module
452 // identified by 'index'
453 // Returns NULL in case of invalid index,
454 // missing TGeoManager or invalid symbolic name
456 if (index >= fNModules) {
457 AliError(Form("Invalid ITS module index: %d (0 -> %d) !",index,fNModules));
461 if (!gGeoManager || !gGeoManager->IsClosed()) {
462 AliError("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
466 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
467 if (!pne) AliError(Form("The symbolic volume name %s does not correspond to a physical entry!",GetSymName(index)));
472 //______________________________________________________________________
473 void AliITSUGeomTGeo::BuildITS()
475 // exract upg ITS parameters from TGeo
476 if (fVersion!=kITSVNA) {AliWarning("Already built"); return; // already initialized}
477 if (!gGeoManager) AliFatal("Geometry is not loaded");
479 fNLayers = ExtractNumberOfLayers();
480 if (!fNLayers) return;
482 fNLadders = new Int_t[fNLayers];
483 fNDetectors = new Int_t[fNLayers];
484 fLrDetType = new Int_t[fNLayers];
485 fLastModIndex = new Int_t[fNLayers];
487 for (int i=0;i<fNLayers;i++) {
488 fNLadders[i] = ExtractNumberOfLadders(i);
489 fNDetectors[i] = ExtractNumberOfDetectors(i);
490 fLrDetType[i] = ExtractLayerDetType(i);
491 fNModules += fNLadders[i]*fNDetectors[i];
492 fLastModIndex[i] = fNModules-1;
500 //______________________________________________________________________
501 Int_t AliITSUGeomTGeo::ExtractNumberOfLayers() const
503 // Determines the number of layers in the Upgrade Geometry
505 Int_t numberOfLayers = 0;
507 TGeoVolume *itsV = gGeoManager->GetVolume(fgkITSVolName);
508 if (!itsV) AliFatal(Form("ITS volume %s is not in the geometry",fgkITSVolName));
510 // Loop on all ITSV nodes, count Layer volumes by checking names
511 Int_t nNodes = itsV->GetNodes()->GetEntries();
512 for (Int_t j=0; j<nNodes; j++) if (strstr(itsV->GetNodes()->At(j)->GetName(),fgkITSLrName)) numberOfLayers++;
514 return numberOfLayers;
517 //______________________________________________________________________
518 Int_t AliITSUGeomTGeo::ExtractNumberOfLadders(Int_t lay) const
520 // Determines the number of layers in the Upgrade Geometry
523 // lay: layer number, starting from 0
526 Int_t numberOfLadders = 0;
528 snprintf(laynam, 30, "%s%d",fgkITSLrName,lay);
529 TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
530 if (!volLr) AliFatal(Form("can't find %s volume",laynam));
532 // Loop on all layer nodes, count Ladder volumes by checking names
533 Int_t nNodes = volLr->GetNodes()->GetEntries();
534 for (Int_t j=0; j<nNodes; j++) if (strstr(volLr->GetNodes()->At(j)->GetName(),fgkITSLadName)) numberOfLadders++;
536 return numberOfLadders;
540 //______________________________________________________________________
541 Int_t AliITSUGeomTGeo::ExtractNumberOfDetectors(Int_t lay) const
543 // Determines the number of detectors per ladder in the Upgrade Geometry
546 // lay: layer number from 0
548 Int_t numberOfModules = 0;
550 snprintf(laddnam, 30, "%s%d", fgkITSLadName,lay);
551 TGeoVolume* volLd = gGeoManager->GetVolume(laddnam);
552 if (!volLd) AliFatal(Form("can't find %s volume",laddnam));
554 // Loop on all ladder nodes, count Module volumes by checking names
555 Int_t nNodes = volLd->GetNodes()->GetEntries();
556 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),fgkITSModName)) numberOfModules++;
558 return numberOfModules;
562 //______________________________________________________________________
563 Int_t AliITSUGeomTGeo::ExtractLayerDetType(Int_t lay) const
565 // Determines the layer detector type the Upgrade Geometry
568 // lay: layer number from 0
572 // detector type id for the layer
575 snprintf(laddnam, 30, "%s%d", fgkITSLrName,lay);
576 TGeoVolume* volLd = gGeoManager->GetVolume(laddnam);
577 if (!volLd) {AliFatal(Form("can't find %s volume",laddnam)); return -1;}
579 return volLd->GetUniqueID();
583 //______________________________________________________________________
584 UInt_t AliITSUGeomTGeo::ComposeDetTypeID(UInt_t segmId)
586 if (segmId>=kMaxSegmPerDetType) AliFatalClass(Form("Id=%d is >= max.allowed %d",segmId,kMaxSegmPerDetType));
587 return segmId + kDetTypePix*kMaxSegmPerDetType;
590 //______________________________________________________________________
591 void AliITSUGeomTGeo::Print(Option_t *) const
594 printf("Geometry version %d, NLayers:%d NModules:%d\n",fVersion,fNLayers,fNModules);
595 if (fVersion==kITSVNA) return;
596 for (int i=0;i<fNLayers;i++) {
597 printf("Lr%2d\tNLadd:%2d\tNDet:%2d\tDetType:%3d\tMod#:%4d:%4d\n",
598 i,fNLadders[i],fNDetectors[i],fLrDetType[i],GetFirstModIndex(i),GetLastModIndex(i));
602 //______________________________________________________________________
603 void AliITSUGeomTGeo::FetchMatrices()
605 // store pointer on often used matrices for faster access
606 if (!gGeoManager) AliFatal("Geometry is not loaded");
607 fMatSens = new TObjArray(fNModules);
608 fMatSens->SetOwner(kTRUE);
609 fMatT2L = new TObjArray(fNModules);
610 fMatT2L->SetOwner(kTRUE);
611 for (int i=0;i<fNModules;i++) {
612 fMatSens->AddAt(new TGeoHMatrix(*ExtractMatrixSens(i)),i);
613 fMatT2L->AddAt(new TGeoHMatrix(*ExtractMatrixT2L(i)),i);