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