Line data Source code
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 12 : 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 897804 : if (!fgInstance) fgInstance = new AliFMDGeometry("FMD");
104 448899 : return fgInstance;
105 0 : }
106 :
107 : //____________________________________________________________________
108 : AliFMDGeometry::AliFMDGeometry()
109 0 : : AliGeometry(),
110 0 : fIsInitialized(kFALSE),
111 0 : fInner(0),
112 0 : fOuter(0),
113 0 : fFMD1(0),
114 0 : fFMD2(0),
115 0 : fFMD3(0),
116 0 : fUseFMD1(kTRUE),
117 0 : fUseFMD2(kTRUE),
118 0 : fUseFMD3(kTRUE),
119 0 : fIsInitTrans(kFALSE),
120 0 : fBuilder(0),
121 0 : fDetectorOff(0),
122 0 : fModuleOff(0),
123 0 : fRingOff(0),
124 0 : fSectorOff(0),
125 0 : fActive(2),
126 0 : fDetailed(kTRUE),
127 0 : fUseAssembly(kTRUE)
128 0 : {
129 : // PROTECTED
130 : //
131 : // CTOR
132 : //
133 0 : }
134 :
135 : //____________________________________________________________________
136 : AliFMDGeometry::AliFMDGeometry(const char* )
137 3 : : AliGeometry("FMD", "Forward multiplicity"),
138 3 : fIsInitialized(kFALSE),
139 3 : fInner(0),
140 3 : fOuter(0),
141 3 : fFMD1(0),
142 3 : fFMD2(0),
143 3 : fFMD3(0),
144 3 : fUseFMD1(kTRUE),
145 3 : fUseFMD2(kTRUE),
146 3 : fUseFMD3(kTRUE),
147 3 : fIsInitTrans(kFALSE),
148 3 : fBuilder(0),
149 3 : fDetectorOff(0),
150 3 : fModuleOff(0),
151 3 : fRingOff(0),
152 3 : fSectorOff(0),
153 3 : fActive(2),
154 3 : fDetailed(kTRUE),
155 3 : fUseAssembly(kTRUE)
156 15 : {
157 : // PROTECTED
158 : //
159 : // CTOR
160 : //
161 : // Parameters:
162 : // name Not used
163 : //
164 9 : fInner = new AliFMDRing('I');
165 9 : fOuter = new AliFMDRing('O');
166 9 : fFMD1 = new AliFMD1(fInner);
167 9 : fFMD2 = new AliFMD2(fInner, fOuter);
168 9 : fFMD3 = new AliFMD3(fInner, fOuter);
169 3 : fIsInitialized = kFALSE;
170 3 : fActive.Reset(-1);
171 6 : }
172 :
173 : //____________________________________________________________________
174 : AliFMDGeometry::AliFMDGeometry(const AliFMDGeometry& other)
175 0 : : AliGeometry(other),
176 0 : fIsInitialized(other.fIsInitialized),
177 0 : fInner(other.fInner),
178 0 : fOuter(other.fOuter),
179 0 : fFMD1(other.fFMD1),
180 0 : fFMD2(other.fFMD2),
181 0 : fFMD3(other.fFMD3),
182 0 : fUseFMD1(other.fUseFMD1),
183 0 : fUseFMD2(other.fUseFMD2),
184 0 : fUseFMD3(other.fUseFMD3),
185 0 : fIsInitTrans(other.fIsInitTrans),
186 0 : fBuilder(other.fBuilder),
187 0 : fDetectorOff(other.fDetectorOff),
188 0 : fModuleOff(other.fModuleOff),
189 0 : fRingOff(other.fRingOff),
190 0 : fSectorOff(other.fSectorOff),
191 0 : fActive(other.fActive),
192 0 : fDetailed(other.fDetailed),
193 0 : fUseAssembly(other.fUseAssembly)
194 0 : {
195 : // PROTECTED
196 : //
197 : // Copy CTOR
198 : //
199 : // Parameters:
200 : // other To copy from
201 : //
202 0 : }
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 0 : if (&other == this) return *this;
220 0 : fUseFMD1 = other.fUseFMD1;
221 0 : fUseFMD2 = other.fUseFMD2;
222 0 : fUseFMD3 = other.fUseFMD3;
223 0 : fFMD1 = other.fFMD1;
224 0 : fFMD2 = other.fFMD2;
225 0 : fFMD3 = other.fFMD3;
226 0 : fInner = other.fInner;
227 0 : fOuter = other.fOuter;
228 0 : fIsInitialized = other.fIsInitialized;
229 0 : return *this;
230 0 : }
231 :
232 : //____________________________________________________________________
233 : void
234 : AliFMDGeometry::Init()
235 : {
236 : //
237 : // Initialize the the singleton if not done so already
238 : //
239 22 : if (fIsInitialized) return;
240 11 : fInner->Init();
241 11 : fOuter->Init();
242 11 : fFMD1->Init();
243 11 : fFMD2->Init();
244 11 : fFMD3->Init();
245 22 : }
246 :
247 : //____________________________________________________________________
248 : void
249 : AliFMDGeometry::InitTransformations(Bool_t force)
250 : {
251 : //
252 : // Find all local <-> global transforms
253 : //
254 10 : if (force) fIsInitTrans = kFALSE;
255 10 : if (fIsInitTrans) return;
256 2 : if (!gGeoManager) {
257 0 : AliError("No TGeoManager defined");
258 0 : return;
259 : }
260 4 : AliFMDDebug(1, ("Initialising transforms for FMD geometry"));
261 4 : if (fFMD1) fFMD1->InitTransformations();
262 4 : if (fFMD2) fFMD2->InitTransformations();
263 4 : if (fFMD3) fFMD3->InitTransformations();
264 2 : fIsInitTrans = kTRUE;
265 12 : }
266 :
267 : //____________________________________________________________________
268 : void
269 : AliFMDGeometry::Build()
270 : {
271 : //
272 : // Make the geometry. This delegates to AliFMDGeometryBuilder
273 : //
274 4 : if (!fBuilder) fBuilder = new AliFMDGeometryBuilder(fDetailed);
275 1 : fBuilder->SetDetailed(fDetailed);
276 1 : fBuilder->UseAssembly(fUseAssembly);
277 1 : fBuilder->Exec();
278 1 : }
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 4 : fActive.Set(n);
292 12 : for (Int_t i = 0; i < n; i++) {
293 8 : AliFMDDebug(1, ("Active vol id # %d: %d", i, active[i]));
294 4 : fActive[i] = active[i];
295 : }
296 2 : }
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 0 : Int_t n = fActive.fN;
310 0 : fActive.Set(n+1);
311 0 : fActive[n] = active;
312 0 : }
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 47772 : for (Int_t i = 0; i < fActive.fN; i++)
327 12397 : if (fActive[i] == vol) return kTRUE;
328 5829 : return kFALSE;
329 6167 : }
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 885472 : switch (i) {
344 270732 : case 1: return fUseFMD1 ? static_cast<AliFMDDetector*>(fFMD1) : 0;
345 528846 : case 2: return fUseFMD2 ? static_cast<AliFMDDetector*>(fFMD2) : 0;
346 528630 : case 3: return fUseFMD3 ? static_cast<AliFMDDetector*>(fFMD3) : 0;
347 : }
348 0 : return 0;
349 442736 : }
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 6 : switch (i) {
366 : case 'I':
367 3 : case 'i': return fInner;
368 : case 'O':
369 0 : case 'o': return fOuter;
370 : }
371 0 : return 0;
372 3 : }
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 0 : switch (i) {
385 0 : case 1: fUseFMD1 = kTRUE; break;
386 0 : case 2: fUseFMD2 = kTRUE; break;
387 0 : case 3: fUseFMD3 = kTRUE; break;
388 : }
389 0 : }
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 0 : switch (i) {
402 0 : case 1: fUseFMD1 = kFALSE; break;
403 0 : case 2: fUseFMD2 = kFALSE; break;
404 0 : case 3: fUseFMD3 = kFALSE; break;
405 : }
406 0 : }
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 884736 : AliFMDDetector* det = GetDetector(detector);
434 442368 : if (!det) {
435 0 : AliWarning(Form("Unknown detector %d", detector));
436 0 : return;
437 : }
438 442368 : det->Detector2XYZ(ring, sector, strip, x, y, z);
439 884736 : }
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 0 : detector = 0;
476 0 : for (int i = 1; i <= 3; i++) {
477 0 : det = GetDetector(i);
478 0 : if (!det) continue;
479 0 : if (det->XYZ2Detector(x, y, z, ring, sector, strip)) {
480 0 : detector = det->GetId();
481 0 : return kTRUE;
482 : }
483 : }
484 0 : return kFALSE;
485 0 : }
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 884736 : if (x == 0 && y == 0 && z == 0) return kFALSE;
514 :
515 : // Correct for vertex offset.
516 442368 : phi = TMath::ATan2(y, x);
517 442368 : r = TMath::Sqrt(y * y + x * x);
518 442368 : theta = TMath::ATan2(r, z);
519 442368 : eta = -TMath::Log(TMath::Tan(theta / 2));
520 :
521 442368 : return kTRUE;
522 442368 : }
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 0 : GetGlobal(p, pos);
540 0 : }
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 0 : Double_t x, y, z;
555 0 : TVector3 local;
556 0 : p->GetLocalPosition(local);
557 0 : UShort_t detector = UShort_t(local.X());
558 0 : UShort_t sector = UShort_t(local.Y());
559 0 : UShort_t strip = UShort_t(local.Z());
560 0 : Detector2XYZ(detector, 'I', sector, strip, x, y, z);
561 0 : pos.SetXYZ(x, y, z);
562 0 : }
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 0 : return kFALSE;
579 : }
580 :
581 : //____________________________________________________________________
582 : void
583 : AliFMDGeometry::SetAlignableVolumes() const
584 : {
585 : //
586 : // Declare alignable volumes
587 : //
588 9 : for (Int_t d = 1; d <= 3; d++)
589 6 : if (GetDetector(d)) GetDetector(d)->SetAlignableVolumes();
590 1 : }
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 0 : Int_t detectorDepth = FindNodeDepth("F1MT_1", "ALIC");
607 0 : Int_t ringDepth = FindNodeDepth(Form("FITV_%d", int('I')), "ALIC");
608 0 : Int_t moduleDepth = FindNodeDepth("FIBH_0", "ALIC");
609 0 : Int_t sectorDepth = FindNodeDepth("FISC_1", "ALIC");
610 0 : fActive.Set(0);
611 0 : fActive.Reset(-1);
612 0 : 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 0 : if (sectorDepth < 0 && moduleDepth < 0) {
619 0 : fDetailed = kFALSE;
620 0 : fSectorOff = -1;
621 0 : fModuleOff = -1;
622 0 : fRingOff = 0;
623 0 : fDetectorOff = (ringDepth - detectorDepth);
624 0 : TGeoVolume* actiVol = gGeoManager->GetVolume("FIAC");
625 0 : TGeoVolume* actoVol = gGeoManager->GetVolume("FOAC");
626 0 : if (actiVol) AddActive(actiVol->GetNumber());
627 0 : if (actoVol) AddActive(actoVol->GetNumber());
628 0 : }
629 0 : else if (sectorDepth < 0) {
630 0 : fDetailed = kFALSE;
631 0 : fSectorOff = -1;
632 0 : fModuleOff = 1;
633 0 : fRingOff = (moduleDepth - ringDepth) + 1;
634 0 : fDetectorOff = (moduleDepth - detectorDepth) + 1;
635 0 : TGeoVolume* modiVol = gGeoManager->GetVolume("FIMO");
636 0 : TGeoVolume* modoVol = gGeoManager->GetVolume("FOMO");
637 0 : if (modiVol) AddActive(modiVol->GetNumber());
638 0 : if (modoVol) AddActive(modoVol->GetNumber());
639 0 : }
640 : else {
641 0 : Int_t stripDepth = FindNodeDepth("FIST_1", "ALIC");
642 0 : fDetailed = kTRUE;
643 0 : fSectorOff = (stripDepth - sectorDepth);
644 0 : fModuleOff = (moduleDepth >= 0 ? (stripDepth - moduleDepth) : -1);
645 0 : fRingOff = (stripDepth - ringDepth);
646 0 : fDetectorOff = (stripDepth - detectorDepth );
647 0 : TGeoVolume* striVol = gGeoManager->GetVolume("FIST");
648 0 : TGeoVolume* stroVol = gGeoManager->GetVolume("FOST");
649 0 : if (striVol) AddActive(striVol->GetNumber());
650 0 : if (stroVol) AddActive(stroVol->GetNumber());
651 : }
652 0 : 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 0 : }
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 0 : TGeoVolume* vol = gGeoManager->GetVolume(volname);
698 0 : if (!vol) {
699 0 : std::cerr << "No top volume defined" << std::endl;
700 0 : return -1;
701 : }
702 :
703 0 : TGeoIterator next(vol);
704 : TGeoNode* node = 0;
705 0 : TString sName(name);
706 0 : while ((node = next())) {
707 0 : if (sName == node->GetName()) {
708 : //std::cout << "Found node " << node->GetName() << " at level "
709 : // << next.GetLevel() << std::endl;
710 0 : return next.GetLevel();
711 : }
712 : }
713 0 : 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 0 : }
728 :
729 : //____________________________________________________________________
730 : //
731 : // EOF
732 : //
|