Mario's change of SubStave -> HalfStave, to be reverted
[u/mrichter/AliRoot.git] / ITS / UPGRADE / AliITSUGeomTGeo.cxx
CommitLineData
ce886e8e 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///////////////////////////////////////////////////////////////////////////
451f5018 17// AliITSUGeomTGeo is a simple interface class to TGeoManager //
ce886e8e 18// It is used in the simulation and reconstruction in order to //
19// query the TGeo ITS geometry //
20// //
21// author - cvetan.cheshkov@cern.ch //
22// 15/02/2007 //
23// adapted to ITSupg 18/07/2012 - ruben.shahoyan@cern.ch //
24// //
451f5018 25// ATTENTION: In opposite to ols AliITSgeomTGeo, all indices start //
26// from 0, not from 1!!! //
27// //
ce886e8e 28///////////////////////////////////////////////////////////////////////////
29
30#include <TClass.h>
31#include <TString.h>
32#include <TGeoManager.h>
33#include <TGeoPhysicalNode.h>
34#include <TDatime.h>
af4b47c9 35#include <TMath.h>
546d00d8 36#include <TSystem.h>
ce886e8e 37
451f5018 38#include "AliITSUGeomTGeo.h"
ce886e8e 39#include "AliLog.h"
40#include "AliAlignObj.h"
546d00d8 41#include "AliITSsegmentation.h"
42#include "AliITSUSegmentationPix.h"
af4b47c9 43using namespace TMath;
ce886e8e 44
451f5018 45ClassImp(AliITSUGeomTGeo)
46
e1f00b9d 47UInt_t AliITSUGeomTGeo::fgUIDShift = 16; // bit shift to go from mod.id to modUUID for TGeo
852af72e 48TString AliITSUGeomTGeo::fgITSVolName = "ITSV";
49TString AliITSUGeomTGeo::fgITSLrName = "ITSULayer";
50TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave";
44730824 51TString AliITSUGeomTGeo::fgITSHalfStaveName = "ITSUHalfStave";
52TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModule";
852af72e 53TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip";
54TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor";
55TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol";
56TString AliITSUGeomTGeo::fgITSChipTypeName[AliITSUGeomTGeo::kNChipTypes] = {"Pix"};
451f5018 57//
852af72e 58TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root";
ce886e8e 59
451f5018 60//______________________________________________________________________
546d00d8 61AliITSUGeomTGeo::AliITSUGeomTGeo(Bool_t build, Bool_t loadSegm)
cf457606 62 :fVersion(kITSVNA)
451f5018 63 ,fNLayers(0)
852af72e 64 ,fNChips(0)
65 ,fNStaves(0)
44730824 66 ,fNHalfStaves(0)
451f5018 67 ,fNModules(0)
852af72e 68 ,fNChipsPerModule(0)
44730824 69 ,fNChipsPerHalfStave(0)
852af72e 70 ,fNChipsPerStave(0)
71 ,fNChipsPerLayer(0)
72 ,fLrChipType(0)
73 ,fLastChipIndex(0)
cf457606 74 ,fMatSens(0)
75 ,fMatT2L(0)
546d00d8 76 ,fSegm(0)
451f5018 77{
78 // default c-tor
43361342 79 for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = -1;
546d00d8 80 if (build) BuildITS(loadSegm);
451f5018 81}
ce886e8e 82
451f5018 83//______________________________________________________________________
84AliITSUGeomTGeo::AliITSUGeomTGeo(const AliITSUGeomTGeo &src)
85 :TObject(src)
86 ,fVersion(src.fVersion)
87 ,fNLayers(src.fNLayers)
852af72e 88 ,fNChips(src.fNChips)
89 ,fNStaves(0)
44730824 90 ,fNHalfStaves(0)
852af72e 91 ,fNModules(0)
92 ,fNChipsPerModule(0)
44730824 93 ,fNChipsPerHalfStave(0)
852af72e 94 ,fNChipsPerStave(0)
95 ,fNChipsPerLayer(0)
96 ,fLrChipType(0)
97 ,fLastChipIndex(0)
cf457606 98 ,fMatSens(0)
99 ,fMatT2L(0)
546d00d8 100 ,fSegm(0)
451f5018 101{
102 // copy c-tor
103 if (fNLayers) {
852af72e 104 fNStaves = new Int_t[fNLayers];
105 fNChipsPerModule = new Int_t[fNLayers];
106 fLrChipType = new Int_t[fNLayers];
107 fLastChipIndex = new Int_t[fNLayers];
44730824 108 fNChipsPerHalfStave = new Int_t[fNLayers];
852af72e 109 fNChipsPerStave = new Int_t[fNLayers];
110 fNChipsPerLayer = new Int_t[fNLayers];
111 //
451f5018 112 for (int i=fNLayers;i--;) {
852af72e 113 fNStaves[i] = src.fNStaves[i];
44730824 114 fNHalfStaves[i] = src.fNHalfStaves[i];
852af72e 115 fNModules[i] = src.fNModules[i];
116 fNChipsPerModule[i] = src.fNChipsPerModule[i];
44730824 117 fNChipsPerHalfStave[i] = src.fNChipsPerHalfStave[i];
852af72e 118 fNChipsPerStave[i] = src.fNChipsPerStave[i];
119 fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
120 fLrChipType[i] = src.fLrChipType[i];
121 fLastChipIndex[i] = src.fLastChipIndex[i];
451f5018 122 }
cf457606 123 if (src.fMatSens) {
852af72e 124 fMatSens = new TObjArray(fNChips);
cf457606 125 fMatSens->SetOwner(kTRUE);
852af72e 126 for (int i=0;i<fNChips;i++) {
cf457606 127 const TGeoHMatrix* mat = (TGeoHMatrix*)src.fMatSens->At(i);
128 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
129 }
130 }
131 if (src.fMatT2L) {
852af72e 132 fMatT2L = new TObjArray(fNChips);
cf457606 133 fMatT2L->SetOwner(kTRUE);
852af72e 134 for (int i=0;i<fNChips;i++) {
cf457606 135 const TGeoHMatrix* mat =(TGeoHMatrix*) src.fMatT2L->At(i);
546d00d8 136 fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
137 }
138 }
139 if (src.fSegm) {
140 int sz = src.fSegm->GetEntriesFast();
141 fSegm = new TObjArray(sz);
142 fSegm->SetOwner(kTRUE);
143 for (int i=0;i<sz;i++) {
144 AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
145 if (!sg) continue;
146 fSegm->AddAt(sg->Clone(),i);
cf457606 147 }
148 }
451f5018 149 }
43361342 150 for (int i=AliITSUAux::kMaxLayers;i--;) fLr2Wrapper[i] = src.fLr2Wrapper[i];
451f5018 151}
ce886e8e 152
451f5018 153//______________________________________________________________________
154AliITSUGeomTGeo::~AliITSUGeomTGeo()
155{
156 //d-tor
852af72e 157 delete[] fNStaves;
44730824 158 delete[] fNHalfStaves;
852af72e 159 delete[] fNModules;
160 delete[] fLrChipType;
161 delete[] fNChipsPerModule;
44730824 162 delete[] fNChipsPerHalfStave;
852af72e 163 delete[] fNChipsPerStave;
164 delete[] fNChipsPerLayer;
165 delete[] fLastChipIndex;
cf457606 166 delete fMatT2L;
167 delete fMatSens;
546d00d8 168 delete fSegm;
451f5018 169}
ce886e8e 170
171
172//______________________________________________________________________
451f5018 173AliITSUGeomTGeo& AliITSUGeomTGeo::operator=(const AliITSUGeomTGeo &src)
174{
175 // cp op.
176 if (this!=&src) {
852af72e 177 delete[] fNStaves;
44730824 178 delete[] fNHalfStaves;
852af72e 179 delete[] fNModules;
180 delete[] fLrChipType;
181 delete[] fNChipsPerModule;
44730824 182 delete[] fNChipsPerHalfStave;
852af72e 183 delete[] fNChipsPerStave;
184 delete[] fNChipsPerLayer;
185 delete[] fLastChipIndex;
44730824 186 fNStaves = fNHalfStaves = fNModules = fLrChipType = fNChipsPerModule = fLastChipIndex = 0;
451f5018 187 fVersion = src.fVersion;
188 fNLayers = src.fNLayers;
852af72e 189 fNChips = src.fNChips;
cf457606 190 if (src.fMatSens) {
191 delete fMatSens;
852af72e 192 fMatSens = new TObjArray(fNChips);
cf457606 193 fMatSens->SetOwner(kTRUE);
852af72e 194 for (int i=0;i<fNChips;i++) {
cf457606 195 const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatSens->At(i);
196 fMatSens->AddAt(new TGeoHMatrix(*mat),i);
197 }
198 }
199 if (src.fMatT2L) {
200 delete fMatT2L;
852af72e 201 fMatT2L = new TObjArray(fNChips);
cf457606 202 fMatT2L->SetOwner(kTRUE);
852af72e 203 for (int i=0;i<fNChips;i++) {
cf457606 204 const TGeoHMatrix* mat = (TGeoHMatrix*) src.fMatT2L->At(i);
205 fMatT2L->AddAt(new TGeoHMatrix(*mat),i);
206 }
207 }
546d00d8 208 if (src.fSegm) {
209 int sz = src.fSegm->GetEntriesFast();
210 fSegm = new TObjArray(sz);
211 fSegm->SetOwner(kTRUE);
212 for (int i=0;i<sz;i++) {
213 AliITSsegmentation* sg = (AliITSsegmentation*)src.fSegm->UncheckedAt(i);
214 if (!sg) continue;
215 fSegm->AddAt(sg->Clone(),i);
216 }
217 }
cf457606 218 //
451f5018 219 if (fNLayers) {
852af72e 220 fNStaves = new Int_t[fNLayers];
44730824 221 fNHalfStaves = new Int_t[fNLayers];
852af72e 222 fNModules = new Int_t[fNLayers];
223 fNChipsPerModule = new Int_t[fNLayers];
44730824 224 fNChipsPerHalfStave = new Int_t[fNLayers];
852af72e 225 fNChipsPerStave = new Int_t[fNLayers];
226 fNChipsPerLayer = new Int_t[fNLayers];
227 fLrChipType = new Int_t[fNLayers];
228 fLastChipIndex = new Int_t[fNLayers];
451f5018 229 for (int i=fNLayers;i--;) {
852af72e 230 fNStaves[i] = src.fNStaves[i];
44730824 231 fNHalfStaves[i] = src.fNHalfStaves[i];
852af72e 232 fNModules[i] = src.fNModules[i];
233 fNChipsPerModule[i] = src.fNChipsPerModule[i];
44730824 234 fNChipsPerHalfStave[i] = src.fNChipsPerHalfStave[i];
852af72e 235 fNChipsPerStave[i] = src.fNChipsPerStave[i];
236 fNChipsPerLayer[i] = src.fNChipsPerLayer[i];
237 fLrChipType[i] = src.fLrChipType[i];
238 fLastChipIndex[i] = src.fLastChipIndex[i];
451f5018 239 }
240 }
241 }
242 return *this;
243}
244
245//______________________________________________________________________
852af72e 246Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta,Int_t chipInStave) const
247{
248 // This routine computes the chip index number from the layer,
249 // stave, and chip number in stave.
250 // Inputs:
251 // Int_t lay The layer number. Starting from 0.
252 // Int_t sta The stave number. Starting from 0
253 // Int_t chipInStave The chip number in the stave. Starting from 0
254 //
255 return GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInStave;
256}
257
258//______________________________________________________________________
259Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t chipInSStave) const
260{
261 // This routine computes the chip index number from the layer,
262 // stave, substave and chip number in substave.
263 // Inputs:
264 // Int_t lay The layer number. Starting from 0.
265 // Int_t sta The stave number. Starting from 0
266 // Int_t substa The substave number. Starting from 0
267 // Int_t chipInSStave The chip number in the sub stave. Starting from 0
268 //
269 int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInSStave;
44730824 270 if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa;
852af72e 271 return n;
272}
273
274//______________________________________________________________________
275Int_t AliITSUGeomTGeo::GetChipIndex(Int_t lay,Int_t sta, Int_t substa, Int_t md, Int_t chipInMod) const
ce886e8e 276{
852af72e 277 // This routine computes the chip index number from the layer,
278 // stave, substave module and chip number in module.
ce886e8e 279 // Inputs:
451f5018 280 // Int_t lay The layer number. Starting from 0.
852af72e 281 // Int_t sta The stave number. Starting from 0
282 // Int_t substa The substave number. Starting from 0
283 // Int_t module The module number ...
284 // Int_t chipInSStave The chip number in the module. Starting from 0
ce886e8e 285 //
852af72e 286 int n = GetFirstChipIndex(lay) + fNChipsPerStave[lay]*sta + chipInMod;
44730824 287 if (fNHalfStaves[lay] && substa>0) n += fNChipsPerHalfStave[lay]*substa;
852af72e 288 if (fNModules[lay] && md>0) n += fNChipsPerModule[lay]*md;
289 return n;
ce886e8e 290}
291
292//______________________________________________________________________
852af72e 293Bool_t AliITSUGeomTGeo::GetLayer(Int_t index,Int_t &lay,Int_t &indexInLr) const
ce886e8e 294{
852af72e 295 // This routine computes the layer number a
296 // given the chip index. The
ce886e8e 297 // Inputs:
852af72e 298 // Int_t index The chip index number, starting from zero.
ce886e8e 299 // Outputs:
852af72e 300 // Int_t indexInLr The chip index inside a layer, starting from zero.
451f5018 301 // Int_t lay The layer number. Starting from 0.
302 //
303 lay = GetLayer(index);
852af72e 304 indexInLr = index - GetFirstChipIndex(lay);
451f5018 305 return kTRUE;
306 //
307}
ce886e8e 308
451f5018 309//______________________________________________________________________
310Int_t AliITSUGeomTGeo::GetLayer(Int_t index) const
311{
852af72e 312 // Get chip layer, from 0
451f5018 313 //
314 int lay = 0;
852af72e 315 while(index>fLastChipIndex[lay]) lay++;
02d6eccc 316 return lay;
451f5018 317}
ce886e8e 318
451f5018 319//______________________________________________________________________
852af72e 320Int_t AliITSUGeomTGeo::GetStave(Int_t index) const
321{
322 // Get chip stave, from 0
323 //
324 int lay = 0;
325 while(index>fLastChipIndex[lay]) lay++;
326 index -= GetFirstChipIndex(lay);
327 return index/fNChipsPerStave[lay];
328}
329
330//______________________________________________________________________
44730824 331Int_t AliITSUGeomTGeo::GetHalfStave(Int_t index) const
451f5018 332{
852af72e 333 // Get chip substave id in stave, from 0
451f5018 334 //
335 int lay = 0;
852af72e 336 while(index>fLastChipIndex[lay]) lay++;
44730824 337 if (fNHalfStaves[lay]<0) return -1;
852af72e 338 index -= GetFirstChipIndex(lay);
339 index %= fNChipsPerStave[lay];
44730824 340 return index/fNChipsPerHalfStave[lay];
ce886e8e 341}
342
343//______________________________________________________________________
852af72e 344Int_t AliITSUGeomTGeo::GetModule(Int_t index) const
451f5018 345{
852af72e 346 // Get chip module id in substave, from 0
451f5018 347 //
348 int lay = 0;
852af72e 349 while(index>fLastChipIndex[lay]) lay++;
350 if (fNModules[lay]<0) return 0;
351 index -= GetFirstChipIndex(lay);
352 index %= fNChipsPerStave[lay];
44730824 353 if (fNHalfStaves[lay]) index %= fNChipsPerHalfStave[lay];
852af72e 354 return index/fNChipsPerModule[lay];
355}
356
357//______________________________________________________________________
358Int_t AliITSUGeomTGeo::GetChipIdInLayer(Int_t index) const
359{
360 // Get chip number within layer, from 0
361 //
362 int lay = 0;
363 while(index>fLastChipIndex[lay]) lay++;
364 index -= GetFirstChipIndex(lay);
451f5018 365 return index;
366}
367
368//______________________________________________________________________
852af72e 369Int_t AliITSUGeomTGeo::GetChipIdInStave(Int_t index) const
451f5018 370{
852af72e 371 // Get chip number within stave, from 0
451f5018 372 //
373 int lay = 0;
852af72e 374 while(index>fLastChipIndex[lay]) lay++;
375 index -= GetFirstChipIndex(lay);
376 return index%fNChipsPerStave[lay];
451f5018 377}
378
379//______________________________________________________________________
44730824 380Int_t AliITSUGeomTGeo::GetChipIdInHalfStave(Int_t index) const
ce886e8e 381{
852af72e 382 // Get chip number within stave, from 0
ce886e8e 383 //
852af72e 384 int lay = 0;
385 while(index>fLastChipIndex[lay]) lay++;
386 index -= GetFirstChipIndex(lay);
44730824 387 return index%fNChipsPerHalfStave[lay];
852af72e 388}
389
390//______________________________________________________________________
391Int_t AliITSUGeomTGeo::GetChipIdInModule(Int_t index) const
392{
393 // Get chip number within module, from 0
394 //
395 int lay = 0;
396 while(index>fLastChipIndex[lay]) lay++;
397 index -= GetFirstChipIndex(lay);
398 return index%fNChipsPerModule[lay];
399}
400
401//______________________________________________________________________
44730824 402Bool_t AliITSUGeomTGeo::GetChipId(Int_t index,Int_t &lay,Int_t &sta,Int_t &hsta, Int_t &mod, Int_t &chip) const
852af72e 403{
404 //
405 // This routine computes the layer, stave, substave, module and chip number
406 // given the chip index number.
ce886e8e 407 // Inputs:
852af72e 408 // Int_t index The chip index number, starting from zero.
ce886e8e 409 // Outputs:
451f5018 410 // Int_t lay The layer number. Starting from 0
852af72e 411 // Int_t sta The stave number. Starting from 0
44730824 412 // Int_t ssta The halfstave number. Starting from 0
852af72e 413 // Int_t mod The module number. Starting from 0
414 // Int_t chip The detector number. Starting from 0
451f5018 415 //
416 lay = GetLayer(index);
852af72e 417 index -= GetFirstChipIndex(lay);
418 sta = index/fNChipsPerStave[lay];
419 index %= fNChipsPerStave[lay];
44730824 420 hsta = fNHalfStaves[lay]>0 ? index/fNChipsPerHalfStave[lay] : -1;
421 index %= fNChipsPerHalfStave[lay];
852af72e 422 mod = fNModules[lay]>0 ? index/fNChipsPerModule[lay] : -1;
423 chip = index%fNChipsPerModule[lay];
424 //
ce886e8e 425 return kTRUE;
426}
427
428//______________________________________________________________________
451f5018 429const char* AliITSUGeomTGeo::GetSymName(Int_t index) const
ce886e8e 430{
431 // Get the TGeoPNEntry symbolic name
852af72e 432 // for a given chip identified by 'index'
ce886e8e 433 //
ce886e8e 434 Int_t lay, index2;
435 if (!GetLayer(index,lay,index2)) return NULL;
451f5018 436 // return AliGeomManager::SymName((AliGeomManager::ELayerID)((lay-1)+AliGeomManager::kSPD1),index2);
437 // RS: this is not optimal, but we cannod access directly AliGeomManager, since the latter has hardwired layers
02d6eccc 438 // TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( AliGeomManager::LayerToVolUID(lay+1,index2) );
852af72e 439 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
451f5018 440 if (!pne) {
852af72e 441 AliError(Form("Failed to find alignable entry with index %d: (Lr%d Chip:%d) !",index,lay,index2));
451f5018 442 return NULL;
ce886e8e 443 }
451f5018 444 return pne->GetName();
ce886e8e 445}
446
447//______________________________________________________________________
392efe73 448const char* AliITSUGeomTGeo::ComposeSymNameITS()
449{
450 // sym name of the layer
451 return "ITS";
452}
453
454//______________________________________________________________________
455const char* AliITSUGeomTGeo::ComposeSymNameLayer(Int_t lr)
456{
457 // sym name of the layer
458 return Form("%s/%s%d",ComposeSymNameITS(),GetITSLayerPattern(),lr);
459}
460
461//______________________________________________________________________
852af72e 462const char* AliITSUGeomTGeo::ComposeSymNameStave(Int_t lr, Int_t stave)
463{
464 // sym name of the stave at given layer
465 return Form("%s/%s%d",ComposeSymNameLayer(lr),GetITSStavePattern(),stave);
466}
467
468//______________________________________________________________________
44730824 469const char* AliITSUGeomTGeo::ComposeSymNameHalfStave(Int_t lr, Int_t stave, Int_t substave)
852af72e 470{
471 // sym name of the stave at given layer
472 return substave>=0 ?
44730824 473 Form("%s/%s%d",ComposeSymNameStave(lr,stave),GetITSHalfStavePattern(),substave) :
852af72e 474 ComposeSymNameStave(lr,stave);
475}
476
477//______________________________________________________________________
478const char* AliITSUGeomTGeo::ComposeSymNameModule(Int_t lr, Int_t stave, Int_t substave, Int_t mod)
392efe73 479{
852af72e 480 // sym name of the substave at given layer/stave
481 return mod>=0 ?
44730824 482 Form("%s/%s%d",ComposeSymNameHalfStave(lr,stave,substave),GetITSModulePattern(),mod) :
483 ComposeSymNameHalfStave(lr,stave,substave);
392efe73 484}
485
486//______________________________________________________________________
852af72e 487const char* AliITSUGeomTGeo::ComposeSymNameChip(Int_t lr, Int_t sta, Int_t substave, Int_t mod, Int_t chip)
392efe73 488{
852af72e 489 // sym name of the chip in the given layer/stave/substave/module
490 return Form("%s/%s%d",ComposeSymNameModule(lr,sta,substave,mod),GetITSChipPattern(),chip);
392efe73 491}
492
493//______________________________________________________________________
451f5018 494TGeoHMatrix* AliITSUGeomTGeo::GetMatrix(Int_t index) const
ce886e8e 495{
852af72e 496 // Get the transformation matrix for a given chip 'index'
ce886e8e 497 // by quering the TGeoManager
dde91d5d 498 static TGeoHMatrix matTmp;
ce886e8e 499 TGeoPNEntry *pne = GetPNEntry(index);
500 if (!pne) return NULL;
501
502 TGeoPhysicalNode *pnode = pne->GetPhysicalNode();
503 if (pnode) return pnode->GetMatrix();
504
505 const char* path = pne->GetTitle();
451f5018 506 gGeoManager->PushPath(); // Preserve the modeler state.
ce886e8e 507 if (!gGeoManager->cd(path)) {
451f5018 508 gGeoManager->PopPath();
509 AliError(Form("Volume path %s not valid!",path));
ce886e8e 510 return NULL;
511 }
dde91d5d 512 matTmp = *gGeoManager->GetCurrentMatrix();
451f5018 513 gGeoManager->PopPath();
dde91d5d 514 return &matTmp;
ce886e8e 515}
516
517//______________________________________________________________________
451f5018 518Bool_t AliITSUGeomTGeo::GetTranslation(Int_t index, Double_t t[3]) const
ce886e8e 519{
852af72e 520 // Get the translation vector for a given chip 'index'
ce886e8e 521 // by quering the TGeoManager
ce886e8e 522 TGeoHMatrix *m = GetMatrix(index);
523 if (!m) return kFALSE;
524
525 Double_t *trans = m->GetTranslation();
526 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
527
528 return kTRUE;
529}
530
531//______________________________________________________________________
451f5018 532Bool_t AliITSUGeomTGeo::GetRotation(Int_t index, Double_t r[9]) const
ce886e8e 533{
852af72e 534 // Get the rotation matrix for a given chip 'index'
ce886e8e 535 // by quering the TGeoManager
ce886e8e 536 TGeoHMatrix *m = GetMatrix(index);
537 if (!m) return kFALSE;
538
539 Double_t *rot = m->GetRotationMatrix();
540 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
541
542 return kTRUE;
543}
544
545//______________________________________________________________________
451f5018 546Bool_t AliITSUGeomTGeo::GetOrigMatrix(Int_t index, TGeoHMatrix &m) const
ce886e8e 547{
548 // Get the original (ideal geometry) TGeo matrix for
852af72e 549 // a given chip identified by 'index'.
ce886e8e 550 // The method is slow, so it should be used
551 // with great care.
ce886e8e 552 m.Clear();
553
554 const char *symname = GetSymName(index);
555 if (!symname) return kFALSE;
556
557 return AliGeomManager::GetOrigGlobalMatrix(symname,m);
558}
559
560//______________________________________________________________________
451f5018 561Bool_t AliITSUGeomTGeo::GetOrigTranslation(Int_t index, Double_t t[3]) const
ce886e8e 562{
563 // Get the original translation vector (ideal geometry)
852af72e 564 // for a given chip 'index' by quering the TGeoManager
ce886e8e 565 TGeoHMatrix m;
566 if (!GetOrigMatrix(index,m)) return kFALSE;
567
568 Double_t *trans = m.GetTranslation();
569 for (Int_t i = 0; i < 3; i++) t[i] = trans[i];
570
571 return kTRUE;
572}
573
574//______________________________________________________________________
451f5018 575Bool_t AliITSUGeomTGeo::GetOrigRotation(Int_t index, Double_t r[9]) const
ce886e8e 576{
577 // Get the original rotation matrix (ideal geometry)
852af72e 578 // for a given chip 'index' by quering the TGeoManager
ce886e8e 579 TGeoHMatrix m;
580 if (!GetOrigMatrix(index,m)) return kFALSE;
581
582 Double_t *rot = m.GetRotationMatrix();
583 for (Int_t i = 0; i < 9; i++) r[i] = rot[i];
584
585 return kTRUE;
586}
587
588//______________________________________________________________________
cf457606 589TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixT2L(Int_t index) const
ce886e8e 590{
591 // Get the matrix which transforms from the tracking to local r.s.
592 // The method queries directly the TGeoPNEntry
ce886e8e 593 TGeoPNEntry *pne = GetPNEntry(index);
594 if (!pne) return NULL;
595
cf457606 596 TGeoHMatrix *m = (TGeoHMatrix*) pne->GetMatrix();
597 if (!m) AliError(Form("TGeoPNEntry (%s) contains no matrix !",pne->GetName()));
ce886e8e 598
599 return m;
600}
601
602//______________________________________________________________________
cf457606 603Bool_t AliITSUGeomTGeo::GetTrackingMatrix(Int_t index, TGeoHMatrix &m)
ce886e8e 604{
605 // Get the matrix which transforms from the tracking r.s. to
606 // the global one.
607 // Returns kFALSE in case of error.
ce886e8e 608 m.Clear();
609
610 TGeoHMatrix *m1 = GetMatrix(index);
611 if (!m1) return kFALSE;
612
cf457606 613 const TGeoHMatrix *m2 = GetMatrixT2L(index);
ce886e8e 614 if (!m2) return kFALSE;
615
616 m = *m1;
617 m.Multiply(m2);
618
619 return kTRUE;
620}
621
622//______________________________________________________________________
cf457606 623TGeoHMatrix* AliITSUGeomTGeo::ExtractMatrixSens(Int_t index) const
451f5018 624{
852af72e 625 // Get the transformation matrix of the SENSOR (not ncessary the same as the chip)
626 // for a given chip 'index' by quering the TGeoManager
627 Int_t lay,stav,sstav,mod,chipInMod;
628 GetChipId(index,lay,stav,sstav,mod,chipInMod);
43361342 629 int wrID = fLr2Wrapper[lay];
852af72e 630 TString path = Form("/ALIC_1/%s_2/",AliITSUGeomTGeo::GetITSVolPattern());
631 if (wrID>=0) path += Form("%s%d_1/",GetITSWrapVolPattern(),wrID);
632 path += Form("%s%d_1/%s%d_%d/",AliITSUGeomTGeo::GetITSLayerPattern(),lay,AliITSUGeomTGeo::GetITSStavePattern(),lay,stav);
44730824 633 if (fNHalfStaves[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSHalfStavePattern(),lay,sstav);
852af72e 634 if (fNModules[lay]>0) path += Form("%s%d_%d/",AliITSUGeomTGeo::GetITSModulePattern(),lay,mod);
635 path += Form("%s%d_%d/%s%d_1",AliITSUGeomTGeo::GetITSChipPattern(),lay,chipInMod,AliITSUGeomTGeo::GetITSSensorPattern(),lay);
636 static TGeoHMatrix matTmp;
451f5018 637 gGeoManager->PushPath();
638 if (!gGeoManager->cd(path.Data())) {
639 gGeoManager->PopPath();
640 AliError(Form("Error in cd-ing to %s",path.Data()));
641 return 0;
642 } // end if !gGeoManager
616016f9 643 matTmp = *gGeoManager->GetCurrentMatrix(); // matrix may change after cd
4fa9d550 644 //RSS
852af72e 645 // printf("%d/%d/%d %s\n",lay,stav,detInSta,path.Data());
4fa9d550 646 // mat->Print();
451f5018 647 // Retstore the modeler state.
648 gGeoManager->PopPath();
616016f9 649 return &matTmp;
451f5018 650}
651
652
653//______________________________________________________________________
654TGeoPNEntry* AliITSUGeomTGeo::GetPNEntry(Int_t index) const
ce886e8e 655{
852af72e 656 // Get a pointer to the TGeoPNEntry of a chip
ce886e8e 657 // identified by 'index'
658 // Returns NULL in case of invalid index,
659 // missing TGeoManager or invalid symbolic name
ce886e8e 660 //
852af72e 661 if (index >= fNChips) {
662 AliError(Form("Invalid ITS chip index: %d (0 -> %d) !",index,fNChips));
ce886e8e 663 return NULL;
664 }
665
666 if (!gGeoManager || !gGeoManager->IsClosed()) {
451f5018 667 AliError("Can't get the matrix! gGeoManager doesn't exist or it is still opened!");
ce886e8e 668 return NULL;
669 }
852af72e 670 TGeoPNEntry* pne = gGeoManager->GetAlignableEntryByUID( ChipVolUID(index) );
e1f00b9d
RS
671 // TGeoPNEntry* pne = gGeoManager->GetAlignableEntry(GetSymName(index));
672 if (!pne) AliError(Form("The index %d does not correspond to a physical entry!",index));
451f5018 673 //
ce886e8e 674 return pne;
675}
676
677//______________________________________________________________________
546d00d8 678void AliITSUGeomTGeo::BuildITS(Bool_t loadSegm)
ce886e8e 679{
680 // exract upg ITS parameters from TGeo
451f5018 681 if (fVersion!=kITSVNA) {AliWarning("Already built"); return; // already initialized}
682 if (!gGeoManager) AliFatal("Geometry is not loaded");
ce886e8e 683 }
451f5018 684 fNLayers = ExtractNumberOfLayers();
685 if (!fNLayers) return;
686 //
852af72e 687 fNStaves = new Int_t[fNLayers];
44730824 688 fNHalfStaves = new Int_t[fNLayers];
852af72e 689 fNModules = new Int_t[fNLayers];
690 fNChipsPerModule = new Int_t[fNLayers];
44730824 691 fNChipsPerHalfStave = new Int_t[fNLayers];
852af72e 692 fNChipsPerStave = new Int_t[fNLayers];
693 fNChipsPerLayer = new Int_t[fNLayers];
694 fLrChipType = new Int_t[fNLayers];
695 fLastChipIndex = new Int_t[fNLayers];
696 fNChips = 0;
451f5018 697 for (int i=0;i<fNLayers;i++) {
852af72e 698 fLrChipType[i] = ExtractLayerChipType(i);
699 fNStaves[i] = ExtractNumberOfStaves(i);
44730824 700 fNHalfStaves[i] = ExtractNumberOfHalfStaves(i);
852af72e 701 fNModules[i] = ExtractNumberOfModules(i);
702 fNChipsPerModule[i] = ExtractNChipsPerModule(i);
44730824 703 fNChipsPerHalfStave[i]= fNChipsPerModule[i]*Max(1,fNModules[i]);
704 fNChipsPerStave[i] = fNChipsPerHalfStave[i]*Max(1,fNHalfStaves[i]);
852af72e 705 fNChipsPerLayer[i] = fNChipsPerStave[i]*fNStaves[i];
706 fNChips += fNChipsPerLayer[i];
707 fLastChipIndex[i] = fNChips-1;
451f5018 708 }
709 //
cf457606 710 FetchMatrices();
451f5018 711 fVersion = kITSVUpg;
ce886e8e 712 //
546d00d8 713 if (loadSegm) { // fetch segmentations
714 fSegm = new TObjArray();
715 AliITSUSegmentationPix::LoadSegmentations(fSegm,GetITSsegmentationFileName());
716 }
717 //
ce886e8e 718}
719
720//______________________________________________________________________
43361342 721Int_t AliITSUGeomTGeo::ExtractNumberOfLayers()
ce886e8e 722{
723 // Determines the number of layers in the Upgrade Geometry
724 //
ce886e8e 725 Int_t numberOfLayers = 0;
726 //
852af72e 727 TGeoVolume *itsV = gGeoManager->GetVolume(GetITSVolPattern());
728 if (!itsV) AliFatal(Form("ITS volume %s is not in the geometry",GetITSVolPattern()));
e1f00b9d 729 SetUIDShift(itsV->GetUniqueID());
ce886e8e 730 //
731 // Loop on all ITSV nodes, count Layer volumes by checking names
43361342 732 // Build on the fly layer - wrapper correspondence
733 TObjArray* nodes = itsV->GetNodes();
734 Int_t nNodes = nodes->GetEntriesFast();
735 //
736 int nWrp = 0;
737 for (Int_t j=0; j<nNodes; j++) {
738 TGeoNode* nd = (TGeoNode*)nodes->At(j);
739 const char* name = nd->GetName();
852af72e 740 if (strstr(name,GetITSLayerPattern())) numberOfLayers++;
741 else if (strstr(name,GetITSWrapVolPattern())) { // this is a wrapper volume, may cointain layers
43361342 742 TObjArray* nodesW = nd->GetNodes();
743 int nNodesW = nodesW->GetEntriesFast();
744 for (Int_t jw=0; jw<nNodesW; jw++) {
745 TGeoNode* ndW = (TGeoNode*)nodesW->At(jw);
852af72e 746 if (strstr(ndW->GetName(),GetITSLayerPattern())) fLr2Wrapper[numberOfLayers++] = nWrp;
43361342 747 }
748 nWrp++;
749 }
750 }
ce886e8e 751 //
752 return numberOfLayers;
753}
754
755//______________________________________________________________________
852af72e 756Int_t AliITSUGeomTGeo::ExtractNumberOfStaves(Int_t lay) const
ce886e8e 757{
758 // Determines the number of layers in the Upgrade Geometry
759 //
760 // Inputs:
451f5018 761 // lay: layer number, starting from 0
762 //
ce886e8e 763 // MS
852af72e 764 Int_t numberOfStaves = 0;
ce886e8e 765 char laynam[30];
852af72e 766 snprintf(laynam, 30, "%s%d",GetITSLayerPattern(),lay);
ce886e8e 767 TGeoVolume* volLr = gGeoManager->GetVolume(laynam);
451f5018 768 if (!volLr) AliFatal(Form("can't find %s volume",laynam));
ce886e8e 769 //
852af72e 770 // Loop on all layer nodes, count Stave volumes by checking names
ce886e8e 771 Int_t nNodes = volLr->GetNodes()->GetEntries();
852af72e 772 for (Int_t j=0; j<nNodes; j++) {
773 // AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern(),numberOfStaves));
774 if (strstr(volLr->GetNodes()->At(j)->GetName(),GetITSStavePattern())) numberOfStaves++;
775 }
ce886e8e 776 //
852af72e 777 return numberOfStaves;
ce886e8e 778 //
779}
780
781//______________________________________________________________________
44730824 782Int_t AliITSUGeomTGeo::ExtractNumberOfHalfStaves(Int_t lay) const
ce886e8e 783{
852af72e 784 // Determines the number of substaves in the stave of the layer
785 //
786 // Inputs:
787 // lay: layer number, starting from 0
788 //
789 // MS
44730824 790 if (fgITSHalfStaveName.IsNull()) return 0; // for the setup w/o substave defined the stave and the substave is the same thing
852af72e 791 Int_t nSS = 0;
792 char stavnam[30];
793 snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
794 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
795 if (!volLd) AliFatal(Form("can't find %s volume",stavnam));
796 //
797 // Loop on all stave nodes, count Chip volumes by checking names
798 Int_t nNodes = volLd->GetNodes()->GetEntries();
44730824 799 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSHalfStavePattern())) nSS++;
852af72e 800 //
801 return nSS;
802 //
803}
804
805//______________________________________________________________________
806Int_t AliITSUGeomTGeo::ExtractNumberOfModules(Int_t lay) const
807{
808 // Determines the number of modules in substave in the stave of the layer
809 //
810 // Inputs:
811 // lay: layer number, starting from 0
812 //
813 // for the setup w/o modules defined the module and the stave or the substave is the same thing
814 if (fgITSModuleName.IsNull()) return 0;
815 char stavnam[30];
816 TGeoVolume* volLd = 0;
44730824 817 if (!fgITSHalfStaveName.IsNull()) {
818 snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay);
852af72e 819 volLd = gGeoManager->GetVolume(stavnam);
820 }
821 if (!volLd) { // no substaves, check staves
822 snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
823 volLd = gGeoManager->GetVolume(stavnam);
824 }
825 if (!volLd) return 0;
826 Int_t nMod = 0;
827 //
828 // Loop on all substave nodes, count module volumes by checking names
829 Int_t nNodes = volLd->GetNodes()->GetEntries();
830 for (Int_t j=0; j<nNodes; j++) if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSModulePattern())) nMod++;
831 //
832 return nMod;
833 //
834}
835
836//______________________________________________________________________
837Int_t AliITSUGeomTGeo::ExtractNChipsPerModule(Int_t lay) const
838{
839 // Determines the number of chips per module on the (sub)stave in the Upgrade Geometry
ce886e8e 840 //
841 // Inputs:
451f5018 842 // lay: layer number from 0
ce886e8e 843 // MS
852af72e 844 Int_t numberOfChips = 0;
845 char stavnam[30];
846 TGeoVolume* volLd = 0;
847 if (!fgITSModuleName.IsNull()) {
848 snprintf(stavnam, 30, "%s%d", GetITSModulePattern(),lay);
849 volLd = gGeoManager->GetVolume(stavnam);
850 }
851 if (!volLd) { // no modules on this layer, check substaves
44730824 852 if (!fgITSHalfStaveName.IsNull()) {
853 snprintf(stavnam, 30, "%s%d", GetITSHalfStavePattern(),lay);
852af72e 854 volLd = gGeoManager->GetVolume(stavnam);
855 }
856 }
857 if (!volLd) { // no substaves on this layer, check staves
858 snprintf(stavnam, 30, "%s%d", GetITSStavePattern(),lay);
859 volLd = gGeoManager->GetVolume(stavnam);
860 }
861 if (!volLd) AliFatal(Form("can't find volume containing chips on layer %d",lay));
ce886e8e 862 //
852af72e 863 // Loop on all stave nodes, count Chip volumes by checking names
ce886e8e 864 Int_t nNodes = volLd->GetNodes()->GetEntries();
852af72e 865 for (Int_t j=0; j<nNodes; j++) {
866 // AliInfo(Form("L%d %d of %d %s %s -> %d",lay,j,nNodes,volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern(),numberOfChips));
867 if (strstr(volLd->GetNodes()->At(j)->GetName(),GetITSChipPattern())) numberOfChips++;
868 }
ce886e8e 869 //
852af72e 870 return numberOfChips;
ce886e8e 871 //
872}
535d15f5 873
874//______________________________________________________________________
852af72e 875Int_t AliITSUGeomTGeo::ExtractLayerChipType(Int_t lay) const
535d15f5 876{
877 // Determines the layer detector type the Upgrade Geometry
878 //
879 // Inputs:
75875328 880 // lay: layer number from 0
535d15f5 881 // Outputs:
882 // none
883 // Return:
884 // detector type id for the layer
885 // MS
852af72e 886 char stavnam[30];
887 snprintf(stavnam, 30, "%s%d", GetITSLayerPattern(),lay);
888 TGeoVolume* volLd = gGeoManager->GetVolume(stavnam);
889 if (!volLd) {AliFatal(Form("can't find %s volume",stavnam)); return -1;}
535d15f5 890 //
891 return volLd->GetUniqueID();
892 //
893}
451f5018 894
895//______________________________________________________________________
852af72e 896UInt_t AliITSUGeomTGeo::ComposeChipTypeID(UInt_t segmId)
451f5018 897{
852af72e 898 if (segmId>=kMaxSegmPerChipType) AliFatalClass(Form("Id=%d is >= max.allowed %d",segmId,kMaxSegmPerChipType));
899 return segmId + kChipTypePix*kMaxSegmPerChipType;
02d6eccc 900}
901
902//______________________________________________________________________
903void AliITSUGeomTGeo::Print(Option_t *) const
904{
905 // print
852af72e 906 printf("Geometry version %d, NLayers:%d NChips:%d\n",fVersion,fNLayers,fNChips);
02d6eccc 907 if (fVersion==kITSVNA) return;
908 for (int i=0;i<fNLayers;i++) {
852af72e 909 printf("Lr%2d\tNStav:%2d\tNChips:%2d\tNMod:%d\tNSubSt:%d\tNSt:%3d\tChipType:%3d\tChip#:%4d:%4d\tWrapVol:%d\n",
44730824 910 i,fNStaves[i],fNChipsPerModule[i],fNModules[i],fNHalfStaves[i],fNStaves[i],
852af72e 911 fLrChipType[i],GetFirstChipIndex(i),GetLastChipIndex(i),fLr2Wrapper[i]);
02d6eccc 912 }
451f5018 913}
cf457606 914
915//______________________________________________________________________
916void AliITSUGeomTGeo::FetchMatrices()
917{
918 // store pointer on often used matrices for faster access
919 if (!gGeoManager) AliFatal("Geometry is not loaded");
852af72e 920 fMatSens = new TObjArray(fNChips);
cf457606 921 fMatSens->SetOwner(kTRUE);
852af72e 922 for (int i=0;i<fNChips;i++) fMatSens->AddAt(new TGeoHMatrix(*ExtractMatrixSens(i)),i);
af4b47c9 923 CreateT2LMatrices();
924}
925
926//______________________________________________________________________
927void AliITSUGeomTGeo::CreateT2LMatrices()
928{
929 // create tracking to local (Sensor!) matrices
852af72e 930 fMatT2L = new TObjArray(fNChips);
cf457606 931 fMatT2L->SetOwner(kTRUE);
af4b47c9 932 TGeoHMatrix matLtoT;
933 double loc[3]={0,0,0},glo[3];
934 const double *rotm;
852af72e 935 for (int isn=0;isn<fNChips;isn++) {
af4b47c9 936 const TGeoHMatrix* matSens = GetMatrixSens(isn);
937 if (!matSens) {AliFatal(Form("Failed to get matrix for sensor %d",isn)); return;}
938 matSens->LocalToMaster(loc,glo);
939 rotm = matSens->GetRotationMatrix();
940 Double_t al = -ATan2(rotm[1],rotm[0]);
3b9474b3 941 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
af4b47c9 942 TGeoHMatrix* t2l = new TGeoHMatrix();
943 t2l->RotateZ(ATan2(y,x)*RadToDeg()); // rotate in direction of normal to the sensor plane
944 t2l->SetDx(x);
945 t2l->SetDy(y);
946 t2l->MultiplyLeft(&matSens->Inverse());
947 fMatT2L->AddAt(t2l,isn);
948 /*
949 const double *gtrans = matSens->GetTranslation();
950 memcpy(&rotMatrix[0], matSens->GetRotationMatrix(), 9*sizeof(Double_t));
951 Double_t al = -ATan2(rotMatrix[1],rotMatrix[0]);
952 Double_t rSens = Sqrt(gtrans[0]*gtrans[0] + gtrans[1]*gtrans[1]);
953 Double_t tanAl = ATan2(gtrans[1],gtrans[0]) - Pi()/2; //angle of tangent
954 Double_t alTr = tanAl - al;
955 //
956 // The X axis of tracking frame must always look outward
957 loc[1] = rSens/2;
958 matSens->LocalToMaster(loc,glo);
959 double rPos = Sqrt(glo[0]*glo[0] + glo[1]*glo[1]);
960 Bool_t rotOutward = rPos>rSens ? kFALSE : kTRUE;
961 //
962 // Transformation matrix
963 matLtoT.Clear();
964 matLtoT.SetDx(-rSens*Sin(alTr)); // translation
965 matLtoT.SetDy(0.);
966 matLtoT.SetDz(gtrans[2]);
967 // Rotation matrix
968 rotMatrix[0]= 0; rotMatrix[1]= 1; rotMatrix[2]= 0; // + rotation
969 rotMatrix[3]=-1; rotMatrix[4]= 0; rotMatrix[5]= 0;
970 rotMatrix[6]= 0; rotMatrix[7]= 0; rotMatrix[8]= 1;
971 //
972 TGeoRotation rot;
973 rot.SetMatrix(rotMatrix);
974 matLtoT.MultiplyLeft(&rot);
975 if (rotOutward) matLtoT.RotateZ(180.);
976 // Inverse transformation Matrix
977 fMatT2L->AddAt(new TGeoHMatrix(matLtoT.Inverse()),isn);
978 */
cf457606 979 }
af4b47c9 980 //
cf457606 981}
af4b47c9 982