]>
Commit | Line | Data |
---|---|---|
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 | 45 | using namespace TMath; |
ce886e8e | 46 | |
451f5018 | 47 | ClassImp(AliITSUGeomTGeo) |
48 | ||
e1f00b9d | 49 | UInt_t AliITSUGeomTGeo::fgUIDShift = 16; // bit shift to go from mod.id to modUUID for TGeo |
852af72e | 50 | TString AliITSUGeomTGeo::fgITSVolName = "ITSV"; |
51 | TString AliITSUGeomTGeo::fgITSLrName = "ITSULayer"; | |
52 | TString AliITSUGeomTGeo::fgITSStaveName = "ITSUStave"; | |
44730824 | 53 | TString AliITSUGeomTGeo::fgITSHalfStaveName = "ITSUHalfStave"; |
54 | TString AliITSUGeomTGeo::fgITSModuleName = "ITSUModule"; | |
852af72e | 55 | TString AliITSUGeomTGeo::fgITSChipName = "ITSUChip"; |
56 | TString AliITSUGeomTGeo::fgITSSensName = "ITSUSensor"; | |
57 | TString AliITSUGeomTGeo::fgITSWrapVolName = "ITSUWrapVol"; | |
58 | TString AliITSUGeomTGeo::fgITSChipTypeName[AliITSUGeomTGeo::kNChipTypes] = {"Pix"}; | |
451f5018 | 59 | // |
852af72e | 60 | TString AliITSUGeomTGeo::fgITSsegmFileName = "itsSegmentations.root"; |
ce886e8e | 61 | |
451f5018 | 62 | //______________________________________________________________________ |
546d00d8 | 63 | AliITSUGeomTGeo::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 | //______________________________________________________________________ |
87 | AliITSUGeomTGeo::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 | //______________________________________________________________________ |
160 | AliITSUGeomTGeo::~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 | 180 | AliITSUGeomTGeo& 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 | 256 | Int_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 | //______________________________________________________________________ | |
269 | Int_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 | //______________________________________________________________________ | |
285 | Int_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 | 303 | Bool_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 | //______________________________________________________________________ |
320 | Int_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 | 330 | Int_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 | 341 | Int_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 | 354 | Int_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 | //______________________________________________________________________ | |
368 | Int_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 | 379 | Int_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 | 390 | Int_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 | //______________________________________________________________________ | |
401 | Int_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 | 412 | Bool_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 | 439 | const 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 | //______________________________________________________________________ |
458 | const char* AliITSUGeomTGeo::ComposeSymNameITS() | |
459 | { | |
460 | // sym name of the layer | |
461 | return "ITS"; | |
462 | } | |
463 | ||
464 | //______________________________________________________________________ | |
465 | const 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 | 472 | const 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 | 479 | const 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 | //______________________________________________________________________ | |
488 | const 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 | 497 | const 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 | 504 | TGeoHMatrix* 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 | 528 | Bool_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 | 542 | Bool_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 | 556 | Bool_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 | 571 | Bool_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 | 585 | Bool_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 | 599 | TGeoHMatrix* 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 | 613 | Bool_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 | 633 | TGeoHMatrix* 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 | //______________________________________________________________________ | |
664 | TGeoPNEntry* 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 | 688 | void 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 | 733 | Int_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 | 768 | Int_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 | 794 | Int_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 | //______________________________________________________________________ | |
818 | Int_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 | 849 | Int_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 | 920 | Int_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 | 941 | UInt_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 | //______________________________________________________________________ | |
948 | void AliITSUGeomTGeo::Print(Option_t *) const | |
949 | { | |
950 | ||
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 | //______________________________________________________________________ | |
963 | void 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 | //______________________________________________________________________ | |
974 | void 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 |