]>
Commit | Line | Data |
---|---|---|
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 | /* $Id$ */ | |
16 | /** | |
17 | * @file AliFMDGeometry.cxx | |
18 | * @author Christian Holm Christensen <cholm@nbi.dk> | |
19 | * @date Mon Mar 27 12:40:37 2006 | |
20 | * @brief Geometry mananger for the FMD | |
21 | */ | |
22 | //____________________________________________________________________ | |
23 | // | |
24 | // Forward Multiplicity Detector based on Silicon wafers. | |
25 | // | |
26 | // This class is a singleton that handles the geometry parameters of | |
27 | // the FMD detectors. | |
28 | // | |
29 | // The actual code is done by various separate classes. Below is | |
30 | // diagram showing the relationship between the various FMD classes | |
31 | // that handles the geometry | |
32 | // | |
33 | // +------------+ | |
34 | // +- | AliFMDRing | | |
35 | // 2 | +------------+ | |
36 | // +----------------+<>--+ | | |
37 | // | AliFMDGeometry | ^ | |
38 | // +----------------+<>--+ V 1..2 | |
39 | // 3 | +----------------+ | |
40 | // +-| AliFMDDetector | | |
41 | // +----------------+ | |
42 | // ^ | |
43 | // | | |
44 | // +-------------+-------------+ | |
45 | // | | | | |
46 | // +---------+ +---------+ +---------+ | |
47 | // | AliFMD1 | | AliFMD2 | | AliFMD3 | | |
48 | // +---------+ +---------+ +---------+ | |
49 | // | |
50 | // | |
51 | // * AliFMDRing | |
52 | // This class contains all stuff needed to do with a ring. It's | |
53 | // used by the AliFMDDetector objects to instantise inner and | |
54 | // outer rings. The AliFMDRing objects are shared by the | |
55 | // AliFMDDetector objects, and owned by the AliFMDv1 object. | |
56 | // | |
57 | // * AliFMD1, AliFMD2, and AliFMD3 | |
58 | // These are specialisation of AliFMDDetector, that contains the | |
59 | // particularities of each of the sub-detector system. It is | |
60 | // envisioned that the classes should also define the support | |
61 | // volumes and material for each of the detectors. | |
62 | // | |
63 | // | |
64 | #include "AliFMDGeometry.h" // ALIFMDGEOMETRY_H | |
65 | #include "AliFMDRing.h" // ALIFMDRING_H | |
66 | #include "AliFMD1.h" // ALIFMD1_H | |
67 | #include "AliFMD2.h" // ALIFMD2_H | |
68 | #include "AliFMD3.h" // ALIFMD2_H | |
69 | #include "AliRecPoint.h" // ALIRECPOINT_H | |
70 | #include "AliFMDDebug.h" // ALILOG_H | |
71 | #include <TVector3.h> // ROOT_TVector3 | |
72 | // #include <TMatrix.h> // ROOT_TMatrix | |
73 | // #include <TParticle.h> // ROOT_TParticle | |
74 | #include <Riostream.h> | |
75 | #include "AliFMDGeometryBuilder.h" | |
76 | // #include <TArrayI.h> | |
77 | #include <TGeoManager.h> | |
78 | #include <TGeoVolume.h> | |
79 | #include <TGeoNode.h> | |
80 | #include <TMath.h> | |
81 | static Int_t FindNodeDepth(const char* name, const char* volname); | |
82 | ||
83 | ||
84 | //==================================================================== | |
85 | ClassImp(AliFMDGeometry) | |
86 | #if 0 | |
87 | ; // This is here to keep Emacs for indenting the next line | |
88 | #endif | |
89 | ||
90 | //____________________________________________________________________ | |
91 | AliFMDGeometry* AliFMDGeometry::fgInstance = 0; | |
92 | ||
93 | //____________________________________________________________________ | |
94 | AliFMDGeometry* | |
95 | AliFMDGeometry::Instance() | |
96 | { | |
97 | // | |
98 | // singleton access | |
99 | // | |
100 | // Return: | |
101 | // Singleton | |
102 | // | |
103 | if (!fgInstance) fgInstance = new AliFMDGeometry("FMD"); | |
104 | return fgInstance; | |
105 | } | |
106 | ||
107 | //____________________________________________________________________ | |
108 | AliFMDGeometry::AliFMDGeometry() | |
109 | : AliGeometry(), | |
110 | fIsInitialized(kFALSE), | |
111 | fInner(0), | |
112 | fOuter(0), | |
113 | fFMD1(0), | |
114 | fFMD2(0), | |
115 | fFMD3(0), | |
116 | fUseFMD1(kTRUE), | |
117 | fUseFMD2(kTRUE), | |
118 | fUseFMD3(kTRUE), | |
119 | fIsInitTrans(kFALSE), | |
120 | fBuilder(0), | |
121 | fDetectorOff(0), | |
122 | fModuleOff(0), | |
123 | fRingOff(0), | |
124 | fSectorOff(0), | |
125 | fActive(2), | |
126 | fDetailed(kTRUE), | |
127 | fUseAssembly(kTRUE) | |
128 | { | |
129 | // PROTECTED | |
130 | // | |
131 | // CTOR | |
132 | // | |
133 | } | |
134 | ||
135 | //____________________________________________________________________ | |
136 | AliFMDGeometry::AliFMDGeometry(const char* ) | |
137 | : AliGeometry("FMD", "Forward multiplicity"), | |
138 | fIsInitialized(kFALSE), | |
139 | fInner(0), | |
140 | fOuter(0), | |
141 | fFMD1(0), | |
142 | fFMD2(0), | |
143 | fFMD3(0), | |
144 | fUseFMD1(kTRUE), | |
145 | fUseFMD2(kTRUE), | |
146 | fUseFMD3(kTRUE), | |
147 | fIsInitTrans(kFALSE), | |
148 | fBuilder(0), | |
149 | fDetectorOff(0), | |
150 | fModuleOff(0), | |
151 | fRingOff(0), | |
152 | fSectorOff(0), | |
153 | fActive(2), | |
154 | fDetailed(kTRUE), | |
155 | fUseAssembly(kTRUE) | |
156 | { | |
157 | // PROTECTED | |
158 | // | |
159 | // CTOR | |
160 | // | |
161 | // Parameters: | |
162 | // name Not used | |
163 | // | |
164 | fInner = new AliFMDRing('I'); | |
165 | fOuter = new AliFMDRing('O'); | |
166 | fFMD1 = new AliFMD1(fInner); | |
167 | fFMD2 = new AliFMD2(fInner, fOuter); | |
168 | fFMD3 = new AliFMD3(fInner, fOuter); | |
169 | fIsInitialized = kFALSE; | |
170 | fActive.Reset(-1); | |
171 | } | |
172 | ||
173 | //____________________________________________________________________ | |
174 | AliFMDGeometry::AliFMDGeometry(const AliFMDGeometry& other) | |
175 | : AliGeometry(other), | |
176 | fIsInitialized(other.fIsInitialized), | |
177 | fInner(other.fInner), | |
178 | fOuter(other.fOuter), | |
179 | fFMD1(other.fFMD1), | |
180 | fFMD2(other.fFMD2), | |
181 | fFMD3(other.fFMD3), | |
182 | fUseFMD1(other.fUseFMD1), | |
183 | fUseFMD2(other.fUseFMD2), | |
184 | fUseFMD3(other.fUseFMD3), | |
185 | fIsInitTrans(other.fIsInitTrans), | |
186 | fBuilder(other.fBuilder), | |
187 | fDetectorOff(other.fDetectorOff), | |
188 | fModuleOff(other.fModuleOff), | |
189 | fRingOff(other.fRingOff), | |
190 | fSectorOff(other.fSectorOff), | |
191 | fActive(other.fActive), | |
192 | fDetailed(other.fDetailed), | |
193 | fUseAssembly(other.fUseAssembly) | |
194 | { | |
195 | // PROTECTED | |
196 | // | |
197 | // Copy CTOR | |
198 | // | |
199 | // Parameters: | |
200 | // other To copy from | |
201 | // | |
202 | } | |
203 | ||
204 | ||
205 | ||
206 | //____________________________________________________________________ | |
207 | AliFMDGeometry& | |
208 | AliFMDGeometry::operator=(const AliFMDGeometry& other) | |
209 | { | |
210 | // PROTECTED | |
211 | // | |
212 | // Assignment operator | |
213 | // | |
214 | // Parameters: | |
215 | // other To assig from | |
216 | // Return: | |
217 | // reference to this. | |
218 | // | |
219 | if (&other == this) return *this; | |
220 | fUseFMD1 = other.fUseFMD1; | |
221 | fUseFMD2 = other.fUseFMD2; | |
222 | fUseFMD3 = other.fUseFMD3; | |
223 | fFMD1 = other.fFMD1; | |
224 | fFMD2 = other.fFMD2; | |
225 | fFMD3 = other.fFMD3; | |
226 | fInner = other.fInner; | |
227 | fOuter = other.fOuter; | |
228 | fIsInitialized = other.fIsInitialized; | |
229 | return *this; | |
230 | } | |
231 | ||
232 | //____________________________________________________________________ | |
233 | void | |
234 | AliFMDGeometry::Init() | |
235 | { | |
236 | // | |
237 | // Initialize the the singleton if not done so already | |
238 | // | |
239 | if (fIsInitialized) return; | |
240 | fInner->Init(); | |
241 | fOuter->Init(); | |
242 | fFMD1->Init(); | |
243 | fFMD2->Init(); | |
244 | fFMD3->Init(); | |
245 | } | |
246 | ||
247 | //____________________________________________________________________ | |
248 | void | |
249 | AliFMDGeometry::InitTransformations(Bool_t force) | |
250 | { | |
251 | // | |
252 | // Find all local <-> global transforms | |
253 | // | |
254 | if (force) fIsInitTrans = kFALSE; | |
255 | if (fIsInitTrans) return; | |
256 | if (!gGeoManager) { | |
257 | AliError("No TGeoManager defined"); | |
258 | return; | |
259 | } | |
260 | AliFMDDebug(1, ("Initialising transforms for FMD geometry")); | |
261 | if (fFMD1) fFMD1->InitTransformations(); | |
262 | if (fFMD2) fFMD2->InitTransformations(); | |
263 | if (fFMD3) fFMD3->InitTransformations(); | |
264 | fIsInitTrans = kTRUE; | |
265 | } | |
266 | ||
267 | //____________________________________________________________________ | |
268 | void | |
269 | AliFMDGeometry::Build() | |
270 | { | |
271 | // | |
272 | // Make the geometry. This delegates to AliFMDGeometryBuilder | |
273 | // | |
274 | if (!fBuilder) fBuilder = new AliFMDGeometryBuilder(fDetailed); | |
275 | fBuilder->SetDetailed(fDetailed); | |
276 | fBuilder->UseAssembly(fUseAssembly); | |
277 | fBuilder->Exec(); | |
278 | } | |
279 | ||
280 | //____________________________________________________________________ | |
281 | void | |
282 | AliFMDGeometry::SetActive(Int_t* active, Int_t n) | |
283 | { | |
284 | // | |
285 | // Set active volumes | |
286 | // | |
287 | // Parameters: | |
288 | // active Active volume id array | |
289 | // n elements of @a active | |
290 | // | |
291 | fActive.Set(n); | |
292 | for (Int_t i = 0; i < n; i++) { | |
293 | AliFMDDebug(1, ("Active vol id # %d: %d", i, active[i])); | |
294 | fActive[i] = active[i]; | |
295 | } | |
296 | } | |
297 | ||
298 | //____________________________________________________________________ | |
299 | void | |
300 | AliFMDGeometry::AddActive(Int_t active) | |
301 | { | |
302 | // | |
303 | // Add an active volume | |
304 | // | |
305 | // Parameters: | |
306 | // id Register volume @a id to be active | |
307 | // | |
308 | // | |
309 | Int_t n = fActive.fN; | |
310 | fActive.Set(n+1); | |
311 | fActive[n] = active; | |
312 | } | |
313 | ||
314 | //____________________________________________________________________ | |
315 | Bool_t | |
316 | AliFMDGeometry::IsActive(Int_t vol) const | |
317 | { | |
318 | // | |
319 | // Check if volume @a vol is marked as active | |
320 | // | |
321 | // Parameters: | |
322 | // vol Volume ID | |
323 | // Return: | |
324 | // @c true if @a vol is declared active | |
325 | // | |
326 | for (Int_t i = 0; i < fActive.fN; i++) | |
327 | if (fActive[i] == vol) return kTRUE; | |
328 | return kFALSE; | |
329 | } | |
330 | ||
331 | //____________________________________________________________________ | |
332 | AliFMDDetector* | |
333 | AliFMDGeometry::GetDetector(Int_t i) const | |
334 | { | |
335 | // | |
336 | // Get description of a sub-detector | |
337 | // | |
338 | // Parameters: | |
339 | // i Sub-detector # | |
340 | // Return: | |
341 | // Description of sub-detector, or 0 | |
342 | // | |
343 | switch (i) { | |
344 | case 1: return fUseFMD1 ? static_cast<AliFMDDetector*>(fFMD1) : 0; | |
345 | case 2: return fUseFMD2 ? static_cast<AliFMDDetector*>(fFMD2) : 0; | |
346 | case 3: return fUseFMD3 ? static_cast<AliFMDDetector*>(fFMD3) : 0; | |
347 | } | |
348 | return 0; | |
349 | } | |
350 | ||
351 | //____________________________________________________________________ | |
352 | AliFMDRing* | |
353 | AliFMDGeometry::GetRing(Char_t i) const | |
354 | { | |
355 | // | |
356 | // Get description of a ring, i should be one of 'I' or 'O' (case | |
357 | // insensitive). If an invalid parameter is passed, 0 (NULL) is | |
358 | // returned. | |
359 | // | |
360 | // Parameters: | |
361 | // i Ring id | |
362 | // Return: | |
363 | // Description of ring, or 0 | |
364 | // | |
365 | switch (i) { | |
366 | case 'I': | |
367 | case 'i': return fInner; | |
368 | case 'O': | |
369 | case 'o': return fOuter; | |
370 | } | |
371 | return 0; | |
372 | } | |
373 | ||
374 | //____________________________________________________________________ | |
375 | void | |
376 | AliFMDGeometry::Enable(Int_t i) | |
377 | { | |
378 | // | |
379 | // Enable the ith detector | |
380 | // | |
381 | // Parameters: | |
382 | // i IF true, enable sub-detector @a i | |
383 | // | |
384 | switch (i) { | |
385 | case 1: fUseFMD1 = kTRUE; break; | |
386 | case 2: fUseFMD2 = kTRUE; break; | |
387 | case 3: fUseFMD3 = kTRUE; break; | |
388 | } | |
389 | } | |
390 | ||
391 | //____________________________________________________________________ | |
392 | void | |
393 | AliFMDGeometry::Disable(Int_t i) | |
394 | { | |
395 | // | |
396 | // Disable the ith detector | |
397 | // | |
398 | // Parameters: | |
399 | // i IF true, disable sub-detector @a i | |
400 | // | |
401 | switch (i) { | |
402 | case 1: fUseFMD1 = kFALSE; break; | |
403 | case 2: fUseFMD2 = kFALSE; break; | |
404 | case 3: fUseFMD3 = kFALSE; break; | |
405 | } | |
406 | } | |
407 | ||
408 | //____________________________________________________________________ | |
409 | void | |
410 | AliFMDGeometry::Detector2XYZ(UShort_t detector, | |
411 | Char_t ring, | |
412 | UShort_t sector, | |
413 | UShort_t strip, | |
414 | Double_t& x, | |
415 | Double_t& y, | |
416 | Double_t& z) const | |
417 | { | |
418 | // | |
419 | // Translate detector coordinates (detector, ring, sector, strip) | |
420 | // to spatial coordinates (x, y, z) in the master reference frame | |
421 | // of ALICE. The member function uses the transformations | |
422 | // previously obtained from the TGeoManager. | |
423 | // | |
424 | // Parameters: | |
425 | // detector Detector number | |
426 | // ring Ring id | |
427 | // sector Sector number | |
428 | // strip Strip number | |
429 | // x On return, X coordinate | |
430 | // y On return, Y coordinate | |
431 | // z On return, Z coordinate | |
432 | // | |
433 | AliFMDDetector* det = GetDetector(detector); | |
434 | if (!det) { | |
435 | AliWarning(Form("Unknown detector %d", detector)); | |
436 | return; | |
437 | } | |
438 | det->Detector2XYZ(ring, sector, strip, x, y, z); | |
439 | } | |
440 | ||
441 | //____________________________________________________________________ | |
442 | Bool_t | |
443 | AliFMDGeometry::XYZ2Detector(Double_t x, | |
444 | Double_t y, | |
445 | Double_t z, | |
446 | UShort_t& detector, | |
447 | Char_t& ring, | |
448 | UShort_t& sector, | |
449 | UShort_t& strip) const | |
450 | { | |
451 | // | |
452 | // Translate spatial coordinates (x,y,z) in the master reference | |
453 | // frame of ALICE to the detector coordinates (detector, ring, | |
454 | // sector, strip). Note, that if this method is to be used in | |
455 | // reconstruction or the like, then the input z-coordinate should | |
456 | // be corrected for the events interactions points z-coordinate, | |
457 | // like | |
458 | // @code | |
459 | // geom->XYZ2Detector(x,y,z-ipz,d,r,s,t); | |
460 | // @endcode | |
461 | // | |
462 | // Parameters: | |
463 | // x X coordinate | |
464 | // y Y coordinate | |
465 | // z Z coordinate | |
466 | // detector On return, Detector number | |
467 | // ring On return, Ring id | |
468 | // sector On return, Sector number | |
469 | // strip On return, Strip number | |
470 | // Return: | |
471 | // @c false of (@a x, @a y, @a z) is not within this | |
472 | // detector. | |
473 | // | |
474 | AliFMDDetector* det = 0; | |
475 | detector = 0; | |
476 | for (int i = 1; i <= 3; i++) { | |
477 | det = GetDetector(i); | |
478 | if (!det) continue; | |
479 | if (det->XYZ2Detector(x, y, z, ring, sector, strip)) { | |
480 | detector = det->GetId(); | |
481 | return kTRUE; | |
482 | } | |
483 | } | |
484 | return kFALSE; | |
485 | } | |
486 | ||
487 | //____________________________________________________________________ | |
488 | Bool_t | |
489 | AliFMDGeometry::XYZ2REtaPhiTheta(Double_t x, Double_t y, | |
490 | Double_t z, | |
491 | Double_t& r, Double_t& eta, | |
492 | Double_t& phi, Double_t& theta) | |
493 | { | |
494 | ||
495 | // | |
496 | // Service function to convert Cartisean XYZ to r, eta, phi, and theta. | |
497 | // | |
498 | // Note, that the z input should be corrected for the vertex location | |
499 | // if needed. | |
500 | // | |
501 | // Parameters: | |
502 | // x Cartisean X coordinate | |
503 | // y Cartisean Y coordinate | |
504 | // z Cartisean Z coordinate | |
505 | // r On return, the radius | |
506 | // eta On return, the pseudo-rapidity | |
507 | // phi On return, the azimuthal angle | |
508 | // theta On return, the polar angle; | |
509 | // | |
510 | // Return: | |
511 | // kTRUE on success, kFALSE in case of problems | |
512 | // | |
513 | if (x == 0 && y == 0 && z == 0) return kFALSE; | |
514 | ||
515 | // Correct for vertex offset. | |
516 | phi = TMath::ATan2(y, x); | |
517 | r = TMath::Sqrt(y * y + x * x); | |
518 | theta = TMath::ATan2(r, z); | |
519 | eta = -TMath::Log(TMath::Tan(theta / 2)); | |
520 | ||
521 | return kTRUE; | |
522 | } | |
523 | ||
524 | ||
525 | //____________________________________________________________________ | |
526 | void | |
527 | AliFMDGeometry::GetGlobal(const AliRecPoint* p, | |
528 | TVector3& pos, | |
529 | TMatrixF& /* mat */) const | |
530 | { | |
531 | // | |
532 | // Get global coordinates cooresponding to a rec point. | |
533 | // | |
534 | // Parameters: | |
535 | // p Reconstructed point. | |
536 | // pos On return, the position | |
537 | // mat On return, the material at @a post | |
538 | // | |
539 | GetGlobal(p, pos); | |
540 | } | |
541 | ||
542 | //____________________________________________________________________ | |
543 | void | |
544 | AliFMDGeometry::GetGlobal(const AliRecPoint* p, TVector3& pos) const | |
545 | { | |
546 | // | |
547 | // Get global coordinates cooresponding to a rec point. | |
548 | // | |
549 | // Parameters: | |
550 | // p Reconstructed point. | |
551 | // pos On return, the position | |
552 | // | |
553 | // FIXME: Implement this function to work with outer rings too. | |
554 | Double_t x, y, z; | |
555 | TVector3 local; | |
556 | p->GetLocalPosition(local); | |
557 | UShort_t detector = UShort_t(local.X()); | |
558 | UShort_t sector = UShort_t(local.Y()); | |
559 | UShort_t strip = UShort_t(local.Z()); | |
560 | Detector2XYZ(detector, 'I', sector, strip, x, y, z); | |
561 | pos.SetXYZ(x, y, z); | |
562 | } | |
563 | ||
564 | //____________________________________________________________________ | |
565 | Bool_t | |
566 | AliFMDGeometry::Impact(const TParticle* /* particle */) const | |
567 | { | |
568 | // | |
569 | // Check if particle will hit an active detector element. | |
570 | // | |
571 | // @todo implement this function | |
572 | // | |
573 | // Parameters: | |
574 | // particle Track | |
575 | // Return: | |
576 | // @c true if @a particle will hit this detector | |
577 | // | |
578 | return kFALSE; | |
579 | } | |
580 | ||
581 | //____________________________________________________________________ | |
582 | void | |
583 | AliFMDGeometry::SetAlignableVolumes() const | |
584 | { | |
585 | // | |
586 | // Declare alignable volumes | |
587 | // | |
588 | for (Int_t d = 1; d <= 3; d++) | |
589 | if (GetDetector(d)) GetDetector(d)->SetAlignableVolumes(); | |
590 | } | |
591 | ||
592 | ||
593 | //____________________________________________________________________ | |
594 | void | |
595 | AliFMDGeometry::ExtractGeomInfo() | |
596 | { | |
597 | // Check the volume depth of some nodes, get the active volume | |
598 | // numbers, and so forth. | |
599 | // | |
600 | // TODO: Here, we should actually also get the parameters of the | |
601 | // shapes, like the verticies of the polygon shape that makes up the | |
602 | // silicon sensor, the strip pitch, the ring radii, the z-positions, | |
603 | // and so on - that is, all the geometric information we need for | |
604 | // futher processing, such as simulation, digitization, | |
605 | // reconstruction, etc. | |
606 | Int_t detectorDepth = FindNodeDepth("F1MT_1", "ALIC"); | |
607 | Int_t ringDepth = FindNodeDepth(Form("FITV_%d", int('I')), "ALIC"); | |
608 | Int_t moduleDepth = FindNodeDepth("FIBH_0", "ALIC"); | |
609 | Int_t sectorDepth = FindNodeDepth("FISC_1", "ALIC"); | |
610 | fActive.Set(0); | |
611 | fActive.Reset(-1); | |
612 | AliFMDDebug(1, ("Geometry depths:\n" | |
613 | " Sector: %d\n" | |
614 | " Module: %d\n" | |
615 | " Ring: %d\n" | |
616 | " Detector: %d", | |
617 | sectorDepth, moduleDepth, ringDepth, detectorDepth)); | |
618 | if (sectorDepth < 0 && moduleDepth < 0) { | |
619 | fDetailed = kFALSE; | |
620 | fSectorOff = -1; | |
621 | fModuleOff = -1; | |
622 | fRingOff = 0; | |
623 | fDetectorOff = (ringDepth - detectorDepth); | |
624 | TGeoVolume* actiVol = gGeoManager->GetVolume("FIAC"); | |
625 | TGeoVolume* actoVol = gGeoManager->GetVolume("FOAC"); | |
626 | if (actiVol) AddActive(actiVol->GetNumber()); | |
627 | if (actiVol) AddActive(actoVol->GetNumber()); | |
628 | } | |
629 | else if (sectorDepth < 0) { | |
630 | fDetailed = kFALSE; | |
631 | fSectorOff = -1; | |
632 | fModuleOff = 1; | |
633 | fRingOff = (moduleDepth - ringDepth) + 1; | |
634 | fDetectorOff = (moduleDepth - detectorDepth) + 1; | |
635 | TGeoVolume* modiVol = gGeoManager->GetVolume("FIMO"); | |
636 | TGeoVolume* modoVol = gGeoManager->GetVolume("FOMO"); | |
637 | if (modiVol) AddActive(modiVol->GetNumber()); | |
638 | if (modoVol) AddActive(modoVol->GetNumber()); | |
639 | } | |
640 | else { | |
641 | Int_t stripDepth = FindNodeDepth("FIST_1", "ALIC"); | |
642 | fDetailed = kTRUE; | |
643 | fSectorOff = (stripDepth - sectorDepth); | |
644 | fModuleOff = (moduleDepth >= 0 ? (stripDepth - moduleDepth) : -1); | |
645 | fRingOff = (stripDepth - ringDepth); | |
646 | fDetectorOff = (stripDepth - detectorDepth ); | |
647 | TGeoVolume* striVol = gGeoManager->GetVolume("FIST"); | |
648 | TGeoVolume* stroVol = gGeoManager->GetVolume("FOST"); | |
649 | if (striVol) AddActive(striVol->GetNumber()); | |
650 | if (stroVol) AddActive(stroVol->GetNumber()); | |
651 | } | |
652 | AliFMDDebug(1, ("Geometry offsets:\n" | |
653 | " Sector: %d\n" | |
654 | " Module: %d\n" | |
655 | " Ring: %d\n" | |
656 | " Detector: %d", | |
657 | fSectorOff, fModuleOff, fRingOff, fDetectorOff)); | |
658 | } | |
659 | ||
660 | #if 0 | |
661 | //____________________________________________________________________ | |
662 | static Int_t | |
663 | CheckNodes(TGeoNode* node, const char* name, Int_t& lvl) | |
664 | { | |
665 | // If there's no node here. | |
666 | if (!node) return -1; | |
667 | // Check if it this one | |
668 | TString sname(name); | |
669 | if (sname == node->GetName()) return lvl; | |
670 | ||
671 | // Check if the node is an immediate daugther | |
672 | TObjArray* nodes = node->GetNodes(); | |
673 | if (!nodes) return -1; | |
674 | // Increase the level, and search immediate sub nodes. | |
675 | lvl++; | |
676 | TGeoNode* found = static_cast<TGeoNode*>(nodes->FindObject(name)); | |
677 | if (found) return lvl; | |
678 | ||
679 | // Check the sub node, if any of their sub-nodes match. | |
680 | for (Int_t i = 0; i < nodes->GetEntries(); i++) { | |
681 | TGeoNode* sub = static_cast<TGeoNode*>(nodes->At(i)); | |
682 | if (!sub) continue; | |
683 | // Recurive check | |
684 | if (CheckNodes(sub, name, lvl) >= 0) return lvl; | |
685 | } | |
686 | // If not found, decrease the level | |
687 | lvl--; | |
688 | return -1; | |
689 | } | |
690 | #endif | |
691 | ||
692 | //____________________________________________________________________ | |
693 | Int_t | |
694 | FindNodeDepth(const char* name, const char* volname) | |
695 | { | |
696 | // Find the depth of a node | |
697 | TGeoVolume* vol = gGeoManager->GetVolume(volname); | |
698 | if (!vol) { | |
699 | std::cerr << "No top volume defined" << std::endl; | |
700 | return -1; | |
701 | } | |
702 | ||
703 | TGeoIterator next(vol); | |
704 | TGeoNode* node = 0; | |
705 | TString sName(name); | |
706 | while ((node = next())) { | |
707 | if (sName == node->GetName()) { | |
708 | //std::cout << "Found node " << node->GetName() << " at level " | |
709 | // << next.GetLevel() << std::endl; | |
710 | return next.GetLevel(); | |
711 | } | |
712 | } | |
713 | return -1; | |
714 | #if 0 | |
715 | TObjArray* nodes = vol->GetNodes(); | |
716 | if (!nodes) { | |
717 | std::cerr << "No nodes in top volume" << std::endl; | |
718 | return -1; | |
719 | } | |
720 | TIter next(nodes); | |
721 | TGeoNode* node = 0; | |
722 | Int_t lvl = 0; | |
723 | while ((node = static_cast<TGeoNode*>(next()))) | |
724 | if (CheckNodes(node, name, lvl) >= 0) return lvl; | |
725 | return -1; | |
726 | #endif | |
727 | } | |
728 | ||
729 | //____________________________________________________________________ | |
730 | // | |
731 | // EOF | |
732 | // |