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)
63 if (build) BuildITS();
66 //______________________________________________________________________
67 AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
69 ,fVersion(src.fVersion)
70 ,fNLayers(src.fNLayers)
71 ,fNModules(src.fNModules)
79 fNLadders = new Int_t[fNLayers];
80 fNDetectors = new Int_t[fNLayers];
81 fLrDetType = new Int_t[fNLayers];
82 fLastModIndex = new Int_t[fNLayers];
83 for (int i=fNLayers;i--;) {
84 fNLadders[i] = src.fNLadders[i];
85 fNDetectors[i] = src.fNDetectors[i];
86 fLrDetType[i] = src.fLrDetType[i];
87 fLastModIndex[i] = src.fLastModIndex[i];
92 //______________________________________________________________________
93 AliITSUGeomTGeo::~AliITSUGeomTGeo()
99 delete[] fLastModIndex;
103 //______________________________________________________________________
104 AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
110 delete[] fNDetectors;
111 delete[] fLastModIndex;
112 fNLadders = fLrDetType = fNDetectors = fLastModIndex = 0;
113 fVersion = src.fVersion;
114 fNLayers = src.fNLayers;
115 fNModules = src.fNModules;
117 fNLadders = new Int_t[fNLayers];
118 fNDetectors = new Int_t[fNLayers];
119 fLrDetType = new Int_t[fNLayers];
120 fLastModIndex = new Int_t[fNLayers];
121 for (int i=fNLayers;i--;) {
122 fNLadders[i] = src.fNLadders[i];
123 fNDetectors[i] = src.fNDetectors[i];
124 fLrDetType[i] = src.fLrDetType[i];
125 fLastModIndex[i] = src.fLastModIndex[i];
132 //______________________________________________________________________
133 Int_t AliITSUGeomTGeo::GetModuleIndex(Int_t lay,Int_t lad,Int_t det) const
135 // This routine computes the module index number from the layer,
136 // ladder, and detector numbers. The number of ladders and detectors
137 // per layer is set statically
138 // see above for details.
140 // Int_t lay The layer number. Starting from 0.
141 // Int_t lad The ladder number. Starting from 0
142 // Int_t det The detector number in the ladder. Starting from 0
144 return GetFirstModIndex(lay) + fNDetectors[lay]*lad + det;
147 //______________________________________________________________________
148 Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &index2) const
150 // This routine computes the layer number for a
151 // given the module index. The
153 // Int_t index The module index number, starting from zero.
155 // Int_t index2 The module index inside a layer, starting from zero.
156 // Int_t lay The layer number. Starting from 0.
158 lay = GetLayer(index);
159 index2 = index - GetFirstModIndex(lay);
164 //______________________________________________________________________
165 Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const
167 // Get module layer, from 0
170 while(index>fLastModIndex[lay]) lay++;
174 //______________________________________________________________________
175 Int_t AliITSUGeomTGeo::GetLadder(Int_t index) const
177 // Get module ladder, from 0
180 while(index>fLastModIndex[lay]) lay++;
181 index -= GetFirstModIndex(lay);
182 return index/fNDetectors[lay];
185 //______________________________________________________________________
186 Int_t AliITSUGeomTGeo::GetModIdInLayer(Int_t index) const
188 // Get module number within layer, from 0
191 while(index>fLastModIndex[lay]) lay++;
192 index -= GetFirstModIndex(lay);
196 //______________________________________________________________________
197 Int_t AliITSUGeomTGeo::GetModIdInLadder(Int_t index) const
199 // Get module number within ladder, from 0
202 while(index>fLastModIndex[lay]) lay++;
203 index -= GetFirstModIndex(lay);
204 return index%fNDetectors[lay];
207 //______________________________________________________________________
208 Bool_t AliITSUGeomTGeo::GetModuleId(Int_t index,Int_t &lay,Int_t &lad,Int_t &det) const
210 // The method is taken from the old AliITSgeom class by Bjorn Nilsen
212 // This routine computes the layer, ladder and detector number
213 // given the module index number.
215 // Int_t index The module index number, starting from zero.
217 // Int_t lay The layer number. Starting from 0
218 // Int_t lad The ladder number. Starting from 0
219 // Int_t det The detector number. Starting from 0
221 lay = GetLayer(index);
222 index -= GetFirstModIndex(lay);
223 lad = index/fNDetectors[lay];
224 det = index%fNDetectors[lay];
228 //______________________________________________________________________
229 const char* AliITSUGeomTGeo::GetSymName(Int_t index) const
231 // Get the TGeoPNEntry symbolic name
232 // for a given module identified by 'index'
235 if (!GetLayer(index,lay,index2)) return NULL;
236 // return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
237 // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers
238 // TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay+1,index2) );
239 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ModuleVolUID(index) );
241 AliError(Form("Failed to find alignable entry with index %d: (Lr%d Mod:%d) !",index,lay,index2));
244 return pne->GetName();
247 //______________________________________________________________________
248 TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index) const
250 // Get the transformation matrix for a given module 'index'
251 // by quering the TGeoManager
252 TGeoPNEntry *pne = GetPNEntry(index);
253 if (!pne) return NULL;
255 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
256 if (pnode) return pnode->GetMatrix();
258 const char* path = pne->GetTitle();
259 gGeoManager->PushPath(); // Preserve the modeler state.
260 if (!gGeoManager->cd(path)) {
261 gGeoManager->PopPath();
262 AliError(Form("Volume path %s not valid!",path));
265 TGeoHMatrix *mat = gGeoManager->GetCurrentMatrix();
266 gGeoManager->PopPath();
270 //______________________________________________________________________
271 Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3]) const
273 // Get the translation vector for a given module 'index'
274 // by quering the TGeoManager
275 TGeoHMatrix *m = GetMatrix(index);
276 if (!m) return kFALSE;
278 Double_t *trans = m->GetTranslation();
279 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
284 //______________________________________________________________________
285 Bool_t AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9]) const
287 // Get the rotation matrix for a given module 'index'
288 // by quering the TGeoManager
289 TGeoHMatrix *m = GetMatrix(index);
290 if (!m) return kFALSE;
292 Double_t *rot = m->GetRotationMatrix();
293 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
298 //______________________________________________________________________
299 Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const
301 // Get the original (ideal geometry) TGeo matrix for
302 // a given module identified by 'index'.
303 // The method is slow, so it should be used
307 const char *symname = GetSymName(index);
308 if (!symname) return kFALSE;
310 return AliGeomManager::GetOrigGlobalMatrix(symname,m);
313 //______________________________________________________________________
314 Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) const
316 // Get the original translation vector (ideal geometry)
317 // for a given module 'index' by quering the TGeoManager
319 if (!GetOrigMatrix(index,m)) return kFALSE;
321 Double_t *trans = m.GetTranslation();
322 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
327 //______________________________________________________________________
328 Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) const
330 // Get the original rotation matrix (ideal geometry)
331 // for a given module 'index' by quering the TGeoManager
333 if (!GetOrigMatrix(index,m)) return kFALSE;
335 Double_t *rot = m.GetRotationMatrix();
336 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
341 //______________________________________________________________________
342 const TGeoHMatrix* AliITSUGeomTGeo::GetTracking2LocalMatrix(Int_t index) const
344 // Get the matrix which transforms from the tracking to local r.s.
345 // The method queries directly the TGeoPNEntry
346 TGeoPNEntry *pne = GetPNEntry(index);
347 if (!pne) return NULL;
349 const TGeoHMatrix *m = pne->GetMatrix();
351 AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
356 //______________________________________________________________________
357 Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m) const
359 // Get the matrix which transforms from the tracking r.s. to
361 // Returns kFALSE in case of error.
364 TGeoHMatrix *m1 = GetMatrix(index);
365 if (!m1) return kFALSE;
367 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
368 if (!m2) return kFALSE;
376 //______________________________________________________________________
377 TGeoHMatrix* AliITSUGeomTGeo::GetMatrixSens(Int_t lay, Int_t ladd, Int_t detInLad) const
379 // Get the transformation matrix of the SENSOR (not ncessary the same as the module) for a given module 'index'
380 // by quering the TGeoManager
381 const TString kPathBase = Form("/ALIC_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern());
382 const TString kNames = Form("%%s%s%%d_1/%s%%d_%%d/%s%%d_%%d/%s%%d_%%d"
383 ,AliITSUGeomTGeo::GetITSLayerPattern()
384 ,AliITSUGeomTGeo::GetITSLadderPattern()
385 ,AliITSUGeomTGeo::GetITSModulePattern()
386 ,AliITSUGeomTGeo::GetITSSensorPattern());
389 path.Form(kNames.Data(),kPathBase.Data(),lay,lay,ladd,lay,detInLad,lay,1);
390 gGeoManager->PushPath();
391 if (!gGeoManager->cd(path.Data())) {
392 gGeoManager->PopPath();
393 AliError(Form("Error in cd-ing to %s",path.Data()));
395 } // end if !gGeoManager
396 TGeoHMatrix* mat = gGeoManager->GetCurrentMatrix();
397 // Retstore the modeler state.
398 gGeoManager->PopPath();
403 //______________________________________________________________________
404 TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const
406 // Get a pointer to the TGeoPNEntry of a module
407 // identified by 'index'
408 // Returns NULL in case of invalid index,
409 // missing TGeoManager or invalid symbolic name
411 if (index >= fNModules) {
412 AliError(Form("Invalid ITS module index: %d (0 -> %d) !",index,fNModules));
416 if (!gGeoManager || !gGeoManager->IsClosed()) {
417 AliError("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
421 TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
422 if (!pne) AliError(Form("The symbolic volume name %s does not correspond to a physical entry!",GetSymName(index)));
427 //______________________________________________________________________
428 Bool_t AliITSUGeomTGeo::LocalToGlobal(Int_t index,const Double_t *loc, Double_t *glob) const
430 // Make the conversion from the local sensitive reference system to the global
431 // reference system, for an arbitrary local position. The input is the pointer
432 // to the array of local coordinates, the result is sent to the glob pointer.
434 // Please don't use this method to get the global coordinates of clusters, use
435 // the direct method of AliCluster instead.
437 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
438 if (!m2) return kFALSE;
440 // The shift (in local y only) between alignable and sensitive volume
441 // is extracted directly from the Tracking2Local matrix
442 Double_t locSens[] = {loc[0], loc[1]+m2->GetTranslation()[1], loc[2]};
444 TGeoHMatrix *ml = GetMatrix(index);
445 if (!ml) return kFALSE;
446 ml->LocalToMaster(locSens,glob);
450 //______________________________________________________________________
451 Bool_t AliITSUGeomTGeo::GlobalToLocal(Int_t index, const Double_t *glob, Double_t *loc) const
453 // Make the conversion from the global reference system to the sensitive local
454 // reference system, for an arbitrary global position. The input is the pointer
455 // to the array of global coordinates, the result is sent to the loc pointer.
457 TGeoHMatrix *ml = GetMatrix(index);
458 if (!ml) return kFALSE;
460 const TGeoHMatrix *m2 = GetTracking2LocalMatrix(index);
461 if (!m2) return kFALSE;
462 ml->MasterToLocal(glob,loc);
463 // The shift (in local y only) between alignable and sensitive volume
464 // is extracted directly from the Tracking2Local matrix
465 loc[1] -= m2->GetTranslation()[1];
470 //______________________________________________________________________
471 Bool_t AliITSUGeomTGeo::LocalToGlobalVect(Int_t index, const Double_t *loc, Double_t *glob) const
473 // Make the conversion from the local sensitive reference system to the global
474 // reference system, for an arbitrary vector. The input is the pointer to the
475 // array of local coordinates, the result is sent to the glob pointer.
477 TGeoHMatrix *ml = GetMatrix(index);
478 if (!ml) return kFALSE;
479 ml->LocalToMasterVect(loc,glob);
483 //______________________________________________________________________
484 Bool_t AliITSUGeomTGeo::GlobalToLocalVect(Int_t index, const Double_t *glob, Double_t *loc) const
486 // Make the conversion from the global reference system to the sensitive local
487 // reference system, for an arbitrary vector. The input is the pointer to the
488 // array of global coordinates, the result is sent to the loc pointer.
489 TGeoHMatrix *ml = GetMatrix(index);
490 if (!ml) return kFALSE;
491 ml->MasterToLocalVect(glob,loc);
495 //______________________________________________________________________
496 void AliITSUGeomTGeo::BuildITS()
498 // exract upg ITS parameters from TGeo
499 if (fVersion!=kITSVNA) {AliWarning("Already built"); return; // already initialized}
500 if (!gGeoManager) AliFatal("Geometry is not loaded");
502 fNLayers = ExtractNumberOfLayers();
503 if (!fNLayers) return;
505 fNLadders = new Int_t[fNLayers];
506 fNDetectors = new Int_t[fNLayers];
507 fLrDetType = new Int_t[fNLayers];
508 fLastModIndex = new Int_t[fNLayers];
510 for (int i=0;i<fNLayers;i++) {
511 fNLadders[i] = ExtractNumberOfLadders(i);
512 fNDetectors[i] = ExtractNumberOfDetectors(i);
513 fLrDetType[i] = ExtractLayerDetType(i);
514 fNModules += fNLadders[i]*fNDetectors[i];
515 fLastModIndex[i] = fNModules-1;
522 //______________________________________________________________________
523 Int_t AliITSUGeomTGeo::ExtractNumberOfLayers() const
525 // Determines the number of layers in the Upgrade Geometry
527 Int_t numberOfLayers = 0;
529 TGeoVolume *itsV = gGeoManager->GetVolume(fgkITSVolName);
530 if (!itsV) AliFatal(Form("ITS volume %s is not in the geometry",fgkITSVolName));
532 // Loop on all ITSV nodes, count Layer volumes by checking names
533 Int_t nNodes = itsV->GetNodes()->GetEntries();
534 for (Int_t j=0; j<nNodes; j++) if (strstr(itsV->GetNodes()->At(j)->GetName(),fgkITSLrName)) numberOfLayers++;
536 return numberOfLayers;
539 //______________________________________________________________________
540 Int_t AliITSUGeomTGeo::ExtractNumberOfLadders(Int_t lay) const
542 // Determines the number of layers in the Upgrade Geometry
545 // lay: layer number, starting from 0
548 Int_t numberOfLadders = 0;
550 snprintf(laynam, 30, "%s%d",fgkITSLrName,lay);
551 TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
552 if (!volLr) AliFatal(Form("can't find %s volume",laynam));
554 // Loop on all layer nodes, count Ladder volumes by checking names
555 Int_t nNodes = volLr->GetNodes()->GetEntries();
556 for (Int_t j=0; j<nNodes; j++) if (strstr(volLr->GetNodes()->At(j)->GetName(),fgkITSLadName)) numberOfLadders++;
558 return numberOfLadders;
562 //______________________________________________________________________
563 Int_t AliITSUGeomTGeo::ExtractNumberOfDetectors(Int_t lay) const
565 // Determines the number of detectors per ladder in the Upgrade Geometry
568 // lay: layer number from 0
570 Int_t numberOfModules = 0;
572 snprintf(laddnam, 30, "%s%d", fgkITSLadName,lay);
573 TGeoVolume* volLd = gGeoManager->GetVolume(laddnam);
574 if (!volLd) AliFatal(Form("can't find %s volume",laddnam));
576 // Loop on all ladder nodes, count Module volumes by checking names
577 Int_t nNodes = volLd->GetNodes()->GetEntries();
578 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),fgkITSModName)) numberOfModules++;
580 return numberOfModules;
584 //______________________________________________________________________
585 Int_t AliITSUGeomTGeo::ExtractLayerDetType(Int_t lay) const
587 // Determines the layer detector type the Upgrade Geometry
590 // lay: layer number from 1
594 // detector type id for the layer
597 snprintf(laddnam, 30, "%s%d", fgkITSLrName,lay);
598 TGeoVolume* volLd = gGeoManager->GetVolume(laddnam);
599 if (!volLd) {AliFatal(Form("can't find %s volume",laddnam)); return -1;}
601 return volLd->GetUniqueID();
605 //______________________________________________________________________
606 UInt_t AliITSUGeomTGeo::ComposeDetTypeID(UInt_t segmId)
608 if (segmId>=kMaxSegmPerDetType) AliFatalClass(Form("Id=%d is >= max.allowed %d",segmId,kMaxSegmPerDetType));
609 return segmId + kDetTypePix*kMaxSegmPerDetType;
612 //______________________________________________________________________
613 void AliITSUGeomTGeo::Print(Option_t *) const
616 printf("Geometry version %d, NLayers:%d NModules:%d\n",fVersion,fNLayers,fNModules);
617 if (fVersion==kITSVNA) return;
618 for (int i=0;i<fNLayers;i++) {
619 printf("Lr%2d\tNLadd:%2d\tNDet:%2d\tDetType:%3d\tMod#:%4d:%4d\n",
620 i,fNLadders[i],fNDetectors[i],fLrDetType[i],GetFirstModIndex(i),GetLastModIndex(i));