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>
38 #include "AliITSUGeomTGeo.h"
40 #include "AliAlignObj.h"
41 #include "AliITSsegmentation.h"
42 #include "AliITSUSegmentationPix.h"
43 using namespace TMath;
45 ClassImp(AliITSUGeomTGeo)
47 UInt_t AliITSUGeomTGeo::fgUIDShift = 16; // bit shift to go from mod.id to modUUID for TGeo
48 TString AliITSUGeomTGeo::fgITSVolName = "ITSV";
49 TString AliITSUGeomTGeo::fgITSLrName = "ITSULayer";
50 TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave";
51 TString AliITSUGeomTGeo::fgITSSubStaveName = "ITSUSubStave";
52 TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModuleName";
53 TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip";
54 TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor";
55 TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol";
56 TString AliITSUGeomTGeo::fgITSChipTypeName[AliITSUGeomTGeo::kNChipTypes] = {"Pix"};
58 TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root";
60 //______________________________________________________________________
61 AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build, Bool_t loadSegm)
69 ,fNChipsPerSubStave(0)
79 for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = -1;
80 if (build) BuildITS(loadSegm);
83 //______________________________________________________________________
84 AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
86 ,fVersion(src.fVersion)
87 ,fNLayers(src.fNLayers)
93 ,fNChipsPerSubStave(0)
104 fNStaves = new Int_t[fNLayers];
105 fNSubStaves= new Int_t[fNLayers];
106 fNChipsPerModule = new Int_t[fNLayers];
107 fLrChipType = new Int_t[fNLayers];
108 fLastChipIndex = new Int_t[fNLayers];
109 fNChipsPerSubStave = new Int_t[fNLayers];
110 fNChipsPerStave = new Int_t[fNLayers];
111 fNChipsPerLayer = new Int_t[fNLayers];
113 for (int i=fNLayers;i--;) {
114 fNStaves[i] = src.fNStaves[i];
115 fNSubStaves[i] = src.fNSubStaves[i];
116 fNModules[i] = src.fNModules[i];
117 fNChipsPerModule[i] = src.fNChipsPerModule[i];
118 fNChipsPerSubStave[i] = src.fNChipsPerSubStave[i];
119 fNChipsPerStave[i] = src.fNChipsPerStave[i];
120 fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
121 fLrChipType[i] = src.fLrChipType[i];
122 fLastChipIndex[i] = src.fLastChipIndex[i];
125 fMatSens = new TObjArray(fNChips);
126 fMatSens->SetOwner(kTRUE);
127 for (int i=0;i<fNChips;i++) {
128 const TGeoHMatrix* mat = (TGeoHMatrix*)src.fMatSens->At(i);
129 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
133 fMatT2L = new TObjArray(fNChips);
134 fMatT2L->SetOwner(kTRUE);
135 for (int i=0;i<fNChips;i++) {
136 const TGeoHMatrix* mat =(TGeoHMatrix*) src.fMatT2L->At(i);
137 fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
141 int sz = src.fSegm->GetEntriesFast();
142 fSegm = new TObjArray(sz);
143 fSegm->SetOwner(kTRUE);
144 for (int i=0;i<sz;i++) {
145 AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
147 fSegm->AddAt(sg->Clone(),i);
151 for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = src.fLr2Wrapper[i];
154 //______________________________________________________________________
155 AliITSUGeomTGeo::~AliITSUGeomTGeo()
159 delete[] fNSubStaves;
161 delete[] fLrChipType;
162 delete[] fNChipsPerModule;
163 delete[] fNChipsPerSubStave;
164 delete[] fNChipsPerStave;
165 delete[] fNChipsPerLayer;
166 delete[] fLastChipIndex;
173 //______________________________________________________________________
174 AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
179 delete[] fNSubStaves;
181 delete[] fLrChipType;
182 delete[] fNChipsPerModule;
183 delete[] fNChipsPerSubStave;
184 delete[] fNChipsPerStave;
185 delete[] fNChipsPerLayer;
186 delete[] fLastChipIndex;
187 fNStaves = fNSubStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0;
188 fVersion = src.fVersion;
189 fNLayers = src.fNLayers;
190 fNChips = src.fNChips;
193 fMatSens = new TObjArray(fNChips);
194 fMatSens->SetOwner(kTRUE);
195 for (int i=0;i<fNChips;i++) {
196 const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatSens->At(i);
197 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
202 fMatT2L = new TObjArray(fNChips);
203 fMatT2L->SetOwner(kTRUE);
204 for (int i=0;i<fNChips;i++) {
205 const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatT2L->At(i);
206 fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
210 int sz = src.fSegm->GetEntriesFast();
211 fSegm = new TObjArray(sz);
212 fSegm->SetOwner(kTRUE);
213 for (int i=0;i<sz;i++) {
214 AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
216 fSegm->AddAt(sg->Clone(),i);
221 fNStaves = new Int_t[fNLayers];
222 fNSubStaves = new Int_t[fNLayers];
223 fNModules = new Int_t[fNLayers];
224 fNChipsPerModule = new Int_t[fNLayers];
225 fNChipsPerSubStave = new Int_t[fNLayers];
226 fNChipsPerStave = new Int_t[fNLayers];
227 fNChipsPerLayer = new Int_t[fNLayers];
228 fLrChipType = new Int_t[fNLayers];
229 fLastChipIndex = new Int_t[fNLayers];
230 for (int i=fNLayers;i--;) {
231 fNStaves[i] = src.fNStaves[i];
232 fNSubStaves[i] = src.fNSubStaves[i];
233 fNModules[i] = src.fNModules[i];
234 fNChipsPerModule[i] = src.fNChipsPerModule[i];
235 fNChipsPerSubStave[i] = src.fNChipsPerSubStave[i];
236 fNChipsPerStave[i] = src.fNChipsPerStave[i];
237 fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
238 fLrChipType[i] = src.fLrChipType[i];
239 fLastChipIndex[i] = src.fLastChipIndex[i];
246 //______________________________________________________________________
247 Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta,Int_t chipInStave) const
249 // This routine computes the chip index number from the layer,
250 // stave, and chip number in stave.
252 // Int_t lay The layer number. Starting from 0.
253 // Int_t sta The stave number. Starting from 0
254 // Int_t chipInStave The chip number in the stave. Starting from 0
256 return GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInStave;
259 //______________________________________________________________________
260 Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t chipInSStave) const
262 // This routine computes the chip index number from the layer,
263 // stave, substave and chip number in substave.
265 // Int_t lay The layer number. Starting from 0.
266 // Int_t sta The stave number. Starting from 0
267 // Int_t substa The substave number. Starting from 0
268 // Int_t chipInSStave The chip number in the sub stave. Starting from 0
270 int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInSStave;
271 if (fNSubStaves[lay] && substa>0) n += fNChipsPerSubStave[lay]*substa;
275 //______________________________________________________________________
276 Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t md, Int_t chipInMod) const
278 // This routine computes the chip index number from the layer,
279 // stave, substave module and chip number in module.
281 // Int_t lay The layer number. Starting from 0.
282 // Int_t sta The stave number. Starting from 0
283 // Int_t substa The substave number. Starting from 0
284 // Int_t module The module number ...
285 // Int_t chipInSStave The chip number in the module. Starting from 0
287 int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInMod;
288 if (fNSubStaves[lay] && substa>0) n += fNChipsPerSubStave[lay]*substa;
289 if (fNModules[lay] && md>0) n += fNChipsPerModule[lay]*md;
293 //______________________________________________________________________
294 Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &indexInLr) const
296 // This routine computes the layer number a
297 // given the chip index. The
299 // Int_t index The chip index number, starting from zero.
301 // Int_t indexInLr The chip index inside a layer, starting from zero.
302 // Int_t lay The layer number. Starting from 0.
304 lay = GetLayer(index);
305 indexInLr = index - GetFirstChipIndex(lay);
310 //______________________________________________________________________
311 Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const
313 // Get chip layer, from 0
316 while(index>fLastChipIndex[lay]) lay++;
320 //______________________________________________________________________
321 Int_t AliITSUGeomTGeo::GetStave(Int_t index) const
323 // Get chip stave, from 0
326 while(index>fLastChipIndex[lay]) lay++;
327 index -= GetFirstChipIndex(lay);
328 return index/fNChipsPerStave[lay];
331 //______________________________________________________________________
332 Int_t AliITSUGeomTGeo::GetSubStave(Int_t index) const
334 // Get chip substave id in stave, from 0
337 while(index>fLastChipIndex[lay]) lay++;
338 if (fNSubStaves[lay]<0) return -1;
339 index -= GetFirstChipIndex(lay);
340 index %= fNChipsPerStave[lay];
341 return index/fNChipsPerSubStave[lay];
344 //______________________________________________________________________
345 Int_t AliITSUGeomTGeo::GetModule(Int_t index) const
347 // Get chip module id in substave, from 0
350 while(index>fLastChipIndex[lay]) lay++;
351 if (fNModules[lay]<0) return 0;
352 index -= GetFirstChipIndex(lay);
353 index %= fNChipsPerStave[lay];
354 if (fNSubStaves[lay]) index %= fNChipsPerSubStave[lay];
355 return index/fNChipsPerModule[lay];
358 //______________________________________________________________________
359 Int_t AliITSUGeomTGeo::GetChipIdInLayer(Int_t index) const
361 // Get chip number within layer, from 0
364 while(index>fLastChipIndex[lay]) lay++;
365 index -= GetFirstChipIndex(lay);
369 //______________________________________________________________________
370 Int_t AliITSUGeomTGeo::GetChipIdInStave(Int_t index) const
372 // Get chip number within stave, from 0
375 while(index>fLastChipIndex[lay]) lay++;
376 index -= GetFirstChipIndex(lay);
377 return index%fNChipsPerStave[lay];
380 //______________________________________________________________________
381 Int_t AliITSUGeomTGeo::GetChipIdInSubStave(Int_t index) const
383 // Get chip number within stave, from 0
386 while(index>fLastChipIndex[lay]) lay++;
387 index -= GetFirstChipIndex(lay);
388 return index%fNChipsPerSubStave[lay];
391 //______________________________________________________________________
392 Int_t AliITSUGeomTGeo::GetChipIdInModule(Int_t index) const
394 // Get chip number within module, from 0
397 while(index>fLastChipIndex[lay]) lay++;
398 index -= GetFirstChipIndex(lay);
399 return index%fNChipsPerModule[lay];
402 //______________________________________________________________________
403 Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &ssta, Int_t &mod, Int_t &chip) const
406 // This routine computes the layer, stave, substave, module and chip number
407 // given the chip index number.
409 // Int_t index The chip index number, starting from zero.
411 // Int_t lay The layer number. Starting from 0
412 // Int_t sta The stave number. Starting from 0
413 // Int_t ssta The substave number. Starting from 0
414 // Int_t mod The module number. Starting from 0
415 // Int_t chip The detector number. Starting from 0
417 lay = GetLayer(index);
418 index -= GetFirstChipIndex(lay);
419 sta = index/fNChipsPerStave[lay];
420 index %= fNChipsPerStave[lay];
421 ssta = fNSubStaves[lay]>0 ? index/fNChipsPerSubStave[lay] : -1;
422 index %= fNChipsPerSubStave[lay];
423 mod = fNModules[lay]>0 ? index/fNChipsPerModule[lay] : -1;
424 chip = index%fNChipsPerModule[lay];
429 //______________________________________________________________________
430 const char* AliITSUGeomTGeo::GetSymName(Int_t index) const
432 // Get the TGeoPNEntry symbolic name
433 // for a given chip identified by 'index'
436 if (!GetLayer(index,lay,index2)) return NULL;
437 // return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
438 // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers
439 // TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay+1,index2) );
440 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
442 AliError(Form("Failed to find alignable entry with index %d: (Lr%d Chip:%d) !",index,lay,index2));
445 return pne->GetName();
448 //______________________________________________________________________
449 const char* AliITSUGeomTGeo::ComposeSymNameITS()
451 // sym name of the layer
455 //______________________________________________________________________
456 const char* AliITSUGeomTGeo::ComposeSymNameLayer(Int_t lr)
458 // sym name of the layer
459 return Form("%s/%s%d",ComposeSymNameITS(),GetITSLayerPattern(),lr);
462 //______________________________________________________________________
463 const char* AliITSUGeomTGeo::ComposeSymNameStave(Int_t lr, Int_t stave)
465 // sym name of the stave at given layer
466 return Form("%s/%s%d",ComposeSymNameLayer(lr),GetITSStavePattern(),stave);
469 //______________________________________________________________________
470 const char* AliITSUGeomTGeo::ComposeSymNameSubStave(Int_t lr, Int_t stave, Int_t substave)
472 // sym name of the stave at given layer
474 Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSSubStavePattern(),substave) :
475 ComposeSymNameStave(lr,stave);
478 //______________________________________________________________________
479 const char* AliITSUGeomTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t substave, Int_t mod)
481 // sym name of the substave at given layer/stave
483 Form("%s/%s%d",ComposeSymNameSubStave(lr,stave,substave),GetITSModulePattern(),mod) :
484 ComposeSymNameSubStave(lr,stave,substave);
487 //______________________________________________________________________
488 const char* AliITSUGeomTGeo::ComposeSymNameChip(Int_t lr, Int_t sta, Int_t substave, Int_t mod, Int_t chip)
490 // sym name of the chip in the given layer/stave/substave/module
491 return Form("%s/%s%d",ComposeSymNameModule(lr,sta,substave,mod),GetITSChipPattern(),chip);
494 //______________________________________________________________________
495 TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index) const
497 // Get the transformation matrix for a given chip 'index'
498 // by quering the TGeoManager
499 static TGeoHMatrix matTmp;
500 TGeoPNEntry *pne = GetPNEntry(index);
501 if (!pne) return NULL;
503 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
504 if (pnode) return pnode->GetMatrix();
506 const char* path = pne->GetTitle();
507 gGeoManager->PushPath(); // Preserve the modeler state.
508 if (!gGeoManager->cd(path)) {
509 gGeoManager->PopPath();
510 AliError(Form("Volume path %s not valid!",path));
513 matTmp = *gGeoManager->GetCurrentMatrix();
514 gGeoManager->PopPath();
518 //______________________________________________________________________
519 Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3]) const
521 // Get the translation vector for a given chip 'index'
522 // by quering the TGeoManager
523 TGeoHMatrix *m = GetMatrix(index);
524 if (!m) return kFALSE;
526 Double_t *trans = m->GetTranslation();
527 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
532 //______________________________________________________________________
533 Bool_t AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9]) const
535 // Get the rotation matrix for a given chip 'index'
536 // by quering the TGeoManager
537 TGeoHMatrix *m = GetMatrix(index);
538 if (!m) return kFALSE;
540 Double_t *rot = m->GetRotationMatrix();
541 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
546 //______________________________________________________________________
547 Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const
549 // Get the original (ideal geometry) TGeo matrix for
550 // a given chip identified by 'index'.
551 // The method is slow, so it should be used
555 const char *symname = GetSymName(index);
556 if (!symname) return kFALSE;
558 return AliGeomManager::GetOrigGlobalMatrix(symname,m);
561 //______________________________________________________________________
562 Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) const
564 // Get the original translation vector (ideal geometry)
565 // for a given chip 'index' by quering the TGeoManager
567 if (!GetOrigMatrix(index,m)) return kFALSE;
569 Double_t *trans = m.GetTranslation();
570 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
575 //______________________________________________________________________
576 Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) const
578 // Get the original rotation matrix (ideal geometry)
579 // for a given chip 'index' by quering the TGeoManager
581 if (!GetOrigMatrix(index,m)) return kFALSE;
583 Double_t *rot = m.GetRotationMatrix();
584 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
589 //______________________________________________________________________
590 TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixT2L(Int_t index) const
592 // Get the matrix which transforms from the tracking to local r.s.
593 // The method queries directly the TGeoPNEntry
594 TGeoPNEntry *pne = GetPNEntry(index);
595 if (!pne) return NULL;
597 TGeoHMatrix *m = (TGeoHMatrix*) pne->GetMatrix();
598 if (!m) AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
603 //______________________________________________________________________
604 Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
606 // Get the matrix which transforms from the tracking r.s. to
608 // Returns kFALSE in case of error.
611 TGeoHMatrix *m1 = GetMatrix(index);
612 if (!m1) return kFALSE;
614 const TGeoHMatrix *m2 = GetMatrixT2L(index);
615 if (!m2) return kFALSE;
623 //______________________________________________________________________
624 TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const
626 // Get the transformation matrix of the SENSOR (not ncessary the same as the chip)
627 // for a given chip 'index' by quering the TGeoManager
628 Int_t lay,stav,sstav,mod,chipInMod;
629 GetChipId(index,lay,stav,sstav,mod,chipInMod);
630 int wrID = fLr2Wrapper[lay];
631 TString path = Form("/ALIC_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern());
632 if (wrID>=0) path += Form("%s%d_1/",GetITSWrapVolPattern(),wrID);
633 path += Form("%s%d_1/%s%d_%d/",AliITSUGeomTGeo::GetITSLayerPattern(),lay,AliITSUGeomTGeo::GetITSStavePattern(),lay,stav);
634 if (fNSubStaves[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSSubStavePattern(),lay,sstav);
635 if (fNModules[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSModulePattern(),lay,mod);
636 path += Form("%s%d_%d/%s%d_1",AliITSUGeomTGeo::GetITSChipPattern(),lay,chipInMod,AliITSUGeomTGeo::GetITSSensorPattern(),lay);
637 static TGeoHMatrix matTmp;
638 gGeoManager->PushPath();
639 if (!gGeoManager->cd(path.Data())) {
640 gGeoManager->PopPath();
641 AliError(Form("Error in cd-ing to %s",path.Data()));
643 } // end if !gGeoManager
644 matTmp = *gGeoManager->GetCurrentMatrix(); // matrix may change after cd
646 // printf("%d/%d/%d %s\n",lay,stav,detInSta,path.Data());
648 // Retstore the modeler state.
649 gGeoManager->PopPath();
654 //______________________________________________________________________
655 TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const
657 // Get a pointer to the TGeoPNEntry of a chip
658 // identified by 'index'
659 // Returns NULL in case of invalid index,
660 // missing TGeoManager or invalid symbolic name
662 if (index >= fNChips) {
663 AliError(Form("Invalid ITS chip index: %d (0 -> %d) !",index,fNChips));
667 if (!gGeoManager || !gGeoManager->IsClosed()) {
668 AliError("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
671 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
672 // TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
673 if (!pne) AliError(Form("The index %d does not correspond to a physical entry!",index));
678 //______________________________________________________________________
679 void AliITSUGeomTGeo::BuildITS(Bool_t loadSegm)
681 // exract upg ITS parameters from TGeo
682 if (fVersion!=kITSVNA) {AliWarning("Already built"); return; // already initialized}
683 if (!gGeoManager) AliFatal("Geometry is not loaded");
685 fNLayers = ExtractNumberOfLayers();
686 if (!fNLayers) return;
688 fNStaves = new Int_t[fNLayers];
689 fNSubStaves = new Int_t[fNLayers];
690 fNModules = new Int_t[fNLayers];
691 fNChipsPerModule = new Int_t[fNLayers];
692 fNChipsPerSubStave = new Int_t[fNLayers];
693 fNChipsPerStave = new Int_t[fNLayers];
694 fNChipsPerLayer = new Int_t[fNLayers];
695 fLrChipType = new Int_t[fNLayers];
696 fLastChipIndex = new Int_t[fNLayers];
698 for (int i=0;i<fNLayers;i++) {
699 fLrChipType[i] = ExtractLayerChipType(i);
700 fNStaves[i] = ExtractNumberOfStaves(i);
701 fNSubStaves[i] = ExtractNumberOfSubStaves(i);
702 fNModules[i] = ExtractNumberOfModules(i);
703 fNChipsPerModule[i] = ExtractNChipsPerModule(i);
704 fNChipsPerSubStave[i] = fNChipsPerModule[i]*Max(1,fNModules[i]);
705 fNChipsPerStave[i] = fNChipsPerSubStave[i]*Max(1,fNSubStaves[i]);
706 fNChipsPerLayer[i] = fNChipsPerStave[i]*fNStaves[i];
707 fNChips += fNChipsPerLayer[i];
708 fLastChipIndex[i] = fNChips-1;
714 if (loadSegm) { // fetch segmentations
715 fSegm = new TObjArray();
716 AliITSUSegmentationPix::LoadSegmentations(fSegm,GetITSsegmentationFileName());
721 //______________________________________________________________________
722 Int_t AliITSUGeomTGeo::ExtractNumberOfLayers()
724 // Determines the number of layers in the Upgrade Geometry
726 Int_t numberOfLayers = 0;
728 TGeoVolume *itsV = gGeoManager->GetVolume(GetITSVolPattern());
729 if (!itsV) AliFatal(Form("ITS volume %s is not in the geometry",GetITSVolPattern()));
730 SetUIDShift(itsV->GetUniqueID());
732 // Loop on all ITSV nodes, count Layer volumes by checking names
733 // Build on the fly layer - wrapper correspondence
734 TObjArray* nodes = itsV->GetNodes();
735 Int_t nNodes = nodes->GetEntriesFast();
738 for (Int_t j=0; j<nNodes; j++) {
739 TGeoNode* nd = (TGeoNode*)nodes->At(j);
740 const char* name = nd->GetName();
741 if (strstr(name,GetITSLayerPattern())) numberOfLayers++;
742 else if (strstr(name,GetITSWrapVolPattern())) { // this is a wrapper volume, may cointain layers
743 TObjArray* nodesW = nd->GetNodes();
744 int nNodesW = nodesW->GetEntriesFast();
745 for (Int_t jw=0; jw<nNodesW; jw++) {
746 TGeoNode* ndW = (TGeoNode*)nodesW->At(jw);
747 if (strstr(ndW->GetName(),GetITSLayerPattern())) fLr2Wrapper[numberOfLayers++] = nWrp;
753 return numberOfLayers;
756 //______________________________________________________________________
757 Int_t AliITSUGeomTGeo::ExtractNumberOfStaves(Int_t lay) const
759 // Determines the number of layers in the Upgrade Geometry
762 // lay: layer number, starting from 0
765 Int_t numberOfStaves = 0;
767 snprintf(laynam, 30, "%s%d",GetITSLayerPattern(),lay);
768 TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
769 if (!volLr) AliFatal(Form("can't find %s volume",laynam));
771 // Loop on all layer nodes, count Stave volumes by checking names
772 Int_t nNodes = volLr->GetNodes()->GetEntries();
773 for (Int_t j=0; j<nNodes; j++) {
774 // AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern(),numberOfStaves));
775 if (strstr(volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern())) numberOfStaves++;
778 return numberOfStaves;
782 //______________________________________________________________________
783 Int_t AliITSUGeomTGeo::ExtractNumberOfSubStaves(Int_t lay) const
785 // Determines the number of substaves in the stave of the layer
788 // lay: layer number, starting from 0
791 if (fgITSSubStaveName.IsNull()) return 0; // for the setup w/o substave defined the stave and the substave is the same thing
794 snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
795 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
796 if (!volLd) AliFatal(Form("can't find %s volume",stavnam));
798 // Loop on all stave nodes, count Chip volumes by checking names
799 Int_t nNodes = volLd->GetNodes()->GetEntries();
800 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSSubStavePattern())) nSS++;
806 //______________________________________________________________________
807 Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const
809 // Determines the number of modules in substave in the stave of the layer
812 // lay: layer number, starting from 0
814 // for the setup w/o modules defined the module and the stave or the substave is the same thing
815 if (fgITSModuleName.IsNull()) return 0;
817 TGeoVolume* volLd = 0;
818 if (!fgITSSubStaveName.IsNull()) {
819 snprintf(stavnam, 30, "%s%d", GetITSSubStavePattern(),lay);
820 volLd = gGeoManager->GetVolume(stavnam);
822 if (!volLd) { // no substaves, check staves
823 snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
824 volLd = gGeoManager->GetVolume(stavnam);
826 if (!volLd) return 0;
829 // Loop on all substave nodes, count module volumes by checking names
830 Int_t nNodes = volLd->GetNodes()->GetEntries();
831 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSModulePattern())) nMod++;
837 //______________________________________________________________________
838 Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay) const
840 // Determines the number of chips per module on the (sub)stave in the Upgrade Geometry
843 // lay: layer number from 0
845 Int_t numberOfChips = 0;
847 TGeoVolume* volLd = 0;
848 if (!fgITSModuleName.IsNull()) {
849 snprintf(stavnam, 30, "%s%d", GetITSModulePattern(),lay);
850 volLd = gGeoManager->GetVolume(stavnam);
852 if (!volLd) { // no modules on this layer, check substaves
853 if (!fgITSSubStaveName.IsNull()) {
854 snprintf(stavnam, 30, "%s%d", GetITSSubStavePattern(),lay);
855 volLd = gGeoManager->GetVolume(stavnam);
858 if (!volLd) { // no substaves on this layer, check staves
859 snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
860 volLd = gGeoManager->GetVolume(stavnam);
862 if (!volLd) AliFatal(Form("can't find volume containing chips on layer %d",lay));
864 // Loop on all stave nodes, count Chip volumes by checking names
865 Int_t nNodes = volLd->GetNodes()->GetEntries();
866 for (Int_t j=0; j<nNodes; j++) {
867 // AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern(),numberOfChips));
868 if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern())) numberOfChips++;
871 return numberOfChips;
875 //______________________________________________________________________
876 Int_t AliITSUGeomTGeo::ExtractLayerChipType(Int_t lay) const
878 // Determines the layer detector type the Upgrade Geometry
881 // lay: layer number from 0
885 // detector type id for the layer
888 snprintf(stavnam, 30, "%s%d", GetITSLayerPattern(),lay);
889 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
890 if (!volLd) {AliFatal(Form("can't find %s volume",stavnam)); return -1;}
892 return volLd->GetUniqueID();
896 //______________________________________________________________________
897 UInt_t AliITSUGeomTGeo::ComposeChipTypeID(UInt_t segmId)
899 if (segmId>=kMaxSegmPerChipType) AliFatalClass(Form("Id=%d is >= max.allowed %d",segmId,kMaxSegmPerChipType));
900 return segmId + kChipTypePix*kMaxSegmPerChipType;
903 //______________________________________________________________________
904 void AliITSUGeomTGeo::Print(Option_t *) const
907 printf("Geometry version %d, NLayers:%d NChips:%d\n",fVersion,fNLayers,fNChips);
908 if (fVersion==kITSVNA) return;
909 for (int i=0;i<fNLayers;i++) {
910 printf("Lr%2d\tNStav:%2d\tNChips:%2d\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChipType:%3d\tChip#:%4d:%4d\tWrapVol:%d\n",
911 i,fNStaves[i],fNChipsPerModule[i],fNModules[i],fNSubStaves[i],fNStaves[i],
912 fLrChipType[i],GetFirstChipIndex(i),GetLastChipIndex(i),fLr2Wrapper[i]);
916 //______________________________________________________________________
917 void AliITSUGeomTGeo::FetchMatrices()
919 // store pointer on often used matrices for faster access
920 if (!gGeoManager) AliFatal("Geometry is not loaded");
921 fMatSens = new TObjArray(fNChips);
922 fMatSens->SetOwner(kTRUE);
923 for (int i=0;i<fNChips;i++) fMatSens->AddAt(new TGeoHMatrix(*ExtractMatrixSens(i)),i);
927 //______________________________________________________________________
928 void AliITSUGeomTGeo::CreateT2LMatrices()
930 // create tracking to local (Sensor!) matrices
931 fMatT2L = new TObjArray(fNChips);
932 fMatT2L->SetOwner(kTRUE);
934 double loc[3]={0,0,0},glo[3];
936 for (int isn=0;isn<fNChips;isn++) {
937 const TGeoHMatrix* matSens = GetMatrixSens(isn);
938 if (!matSens) {AliFatal(Form("Failed to get matrix for sensor %d",isn)); return;}
939 matSens->LocalToMaster(loc,glo);
940 rotm = matSens->GetRotationMatrix();
941 Double_t al = -ATan2(rotm[1],rotm[0]);
942 double sn=Sin(al), cs=Cos(al), r=glo[0]*sn-glo[1]*cs, x=r*sn, y=-r*cs; // sensor plane PCA to origin
943 TGeoHMatrix* t2l = new TGeoHMatrix();
944 t2l->RotateZ(ATan2(y,x)*RadToDeg()); // rotate in direction of normal to the sensor plane
947 t2l->MultiplyLeft(&matSens->Inverse());
948 fMatT2L->AddAt(t2l,isn);
950 const double *gtrans = matSens->GetTranslation();
951 memcpy(&rotMatrix[0], matSens->GetRotationMatrix(), 9*sizeof(Double_t));
952 Double_t al = -ATan2(rotMatrix[1],rotMatrix[0]);
953 Double_t rSens = Sqrt(gtrans[0]*gtrans[0] + gtrans[1]*gtrans[1]);
954 Double_t tanAl = ATan2(gtrans[1],gtrans[0]) - Pi()/2; //angle of tangent
955 Double_t alTr = tanAl - al;
957 // The X axis of tracking frame must always look outward
959 matSens->LocalToMaster(loc,glo);
960 double rPos = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]);
961 Bool_t rotOutward = rPos>rSens ? kFALSE : kTRUE;
963 // Transformation matrix
965 matLtoT.SetDx(-rSens*Sin(alTr)); // translation
967 matLtoT.SetDz(gtrans[2]);
969 rotMatrix[0]= 0; rotMatrix[1]= 1; rotMatrix[2]= 0; // + rotation
970 rotMatrix[3]=-1; rotMatrix[4]= 0; rotMatrix[5]= 0;
971 rotMatrix[6]= 0; rotMatrix[7]= 0; rotMatrix[8]= 1;
974 rot.SetMatrix(rotMatrix);
975 matLtoT.MultiplyLeft(&rot);
976 if (rotOutward) matLtoT.RotateZ(180.);
977 // Inverse transformation Matrix
978 fMatT2L->AddAt(new TGeoHMatrix(matLtoT.Inverse()),isn);