Handle deletion of AliFMDAltroMapping object. If we make the object
[u/mrichter/AliRoot.git] / FMD / AliFMDDetector.cxx
CommitLineData
1a1fdef7 1/**************************************************************************
2 * Copyright(c) 2004, 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 **************************************************************************/
1a1fdef7 15/* $Id$ */
c2fc1258 16/** @file AliFMDDetector.cxx
17 @author Christian Holm Christensen <cholm@nbi.dk>
18 @date Mon Mar 27 12:36:27 2006
19 @brief Sub-detector base class implementation
02a27b50 20 @ingroup FMD_base
c2fc1258 21*/
1a1fdef7 22
23//____________________________________________________________________
24//
6169f936 25// AliFMDDetector.
26//
27// Base class for concrete FMD detectors, like AliFMD1, AliFMD2,
28// AliFMD3.
1a1fdef7 29// Utility class to help implement the FMD geometry. This provides
30// the interface for the concrete geometry implementations of the FMD
31// sub-detectors.
32//
33// The AliFMDGeometry object owns the AliFMDDetector objects
34//
35// Latest changes by Christian Holm Christensen
36//
090026bf 37
38#include <TGeoManager.h> // ROOT_TGeoManager
4445cb1c 39#include <TGeoPhysicalNode.h> // ROOT_TGeoPhysicalNode
090026bf 40#include <TGeoMatrix.h> // ROOT_TGeoMatrix
41#include <TMath.h> // ROOT_TMath
42
1a1fdef7 43#include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
44#include "AliFMDRing.h" // ALIFMDRING_H
f95a63c4 45#include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H
1a1fdef7 46
47//====================================================================
48ClassImp(AliFMDDetector)
49#if 0
50 ; // This is here to keep Emacs for indenting the next line
51#endif
52
53//____________________________________________________________________
54AliFMDDetector::AliFMDDetector(Int_t id, AliFMDRing* inner, AliFMDRing* outer)
55 : TNamed(Form("FMD%d", id), "Forward multiplicity ring"),
56 fId(id),
b5ee4425 57 fInnerZ(0.),
58 fOuterZ(0.),
b5ee4425 59 fInnerHoneyLowR(0.),
60 fInnerHoneyHighR(0.),
61 fOuterHoneyLowR(0.),
62 fOuterHoneyHighR(0.),
1a1fdef7 63 fInner(inner),
bf000c32 64 fOuter(outer),
65 fInnerTransforms(0),
66 fOuterTransforms(0)
1a1fdef7 67{
088f8e79 68 // Constructor
69 //
70 // ID Id of detector (1,2, or 3)
71 // INNER Inner ring geometry
72 // OUTER Outer ring geometry (if any)
73 //
1a1fdef7 74 SetInnerHoneyLowR(0);
75 SetInnerHoneyHighR(0);
76 SetInnerZ(0);
77 SetOuterZ(0);
78 SetOuterHoneyLowR(0);
79 SetOuterHoneyHighR(0);
80}
81
82//____________________________________________________________________
088f8e79 83AliFMDDetector::AliFMDDetector(const AliFMDDetector& other)
84 : TNamed(other),
85 fId(other.fId),
b5ee4425 86 fInnerZ(0.),
87 fOuterZ(0.),
b5ee4425 88 fInnerHoneyLowR(0.),
89 fInnerHoneyHighR(0.),
90 fOuterHoneyLowR(0.),
91 fOuterHoneyHighR(0.),
088f8e79 92 fInner(other.fInner),
bf000c32 93 fOuter(other.fOuter),
94 fInnerTransforms(other.fInnerTransforms),
95 fOuterTransforms(other.fOuterTransforms)
088f8e79 96{
97 // Copy constructor
088f8e79 98 SetInnerHoneyLowR(other.GetInnerHoneyLowR());
99 SetInnerHoneyHighR(other.GetInnerHoneyHighR());
100 SetInnerZ(other.GetInnerZ());
101 SetOuterZ(other.GetOuterZ());
102 SetOuterHoneyLowR(other.GetOuterHoneyLowR());
103 SetOuterHoneyHighR(other.GetOuterHoneyHighR());
104}
105
106//____________________________________________________________________
107AliFMDDetector&
108AliFMDDetector::operator=(const AliFMDDetector& other)
109{
110 // Assignment operator
d015ecfe 111 if (&other == this) return *this;
088f8e79 112 SetName(other.GetName());
113 SetTitle(other.GetTitle());
bf000c32 114 fId = other.fId;
115 fInner = other.fInner;
116 fOuter = other.fOuter;
117 fInnerTransforms = other.fInnerTransforms;
118 fOuterTransforms = other.fOuterTransforms;
088f8e79 119 SetInnerHoneyLowR(other.GetInnerHoneyLowR());
120 SetInnerHoneyHighR(other.GetInnerHoneyHighR());
121 SetInnerZ(other.GetInnerZ());
122 SetOuterZ(other.GetOuterZ());
123 SetOuterHoneyLowR(other.GetOuterHoneyLowR());
124 SetOuterHoneyHighR(other.GetOuterHoneyHighR());
125 return *this;
126}
127
128//____________________________________________________________________
1a1fdef7 129void
130AliFMDDetector::Init()
131{
088f8e79 132 // Initialize.
1a1fdef7 133 if (fInner) {
134 SetInnerHoneyLowR(fInner->GetLowR() + 1.);
135 SetInnerHoneyHighR(fInner->GetHighR() + 1.);
136 }
137 if (fOuter) {
138 SetOuterHoneyLowR(fOuter->GetLowR() + 1.);
139 SetOuterHoneyHighR(fOuter->GetHighR() + 1.);
bf000c32 140 }
141}
142
143//____________________________________________________________________
144Bool_t
145AliFMDDetector::HasAllTransforms(Char_t ring) const
146{
02a27b50 147 // Check if we got all transformations for a given ring. Return
148 // true in that case.
bf000c32 149 AliFMDRing* r = GetRing(ring);
150 if (!r) return kTRUE;
151 TObjArray* matricies = (r == fInner ? fInnerTransforms : fOuterTransforms);
152 if (!matricies) return kTRUE;
153 if (matricies->GetEntries() == r->GetNModules()) return kTRUE;
154 return kFALSE;
155}
156
157#define IS_NODE_THIS(name) \
158 (name[0] == 'F' && name[2] == 'M' && name[1] == Char_t(48+fId) && \
159 (name[3] == 'T' || name[3] == 'B'))
d98fbfa5 160#define IS_NODE_SENSOR(name) \
161 (name[0] == 'F' && (name[2] == 'B' || name[2] == 'F') && name[3] == 'H')
458e52e8 162//#define IS_NODE_SENSOR(name)
d98fbfa5 163// (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
9de78b35 164#define IS_NODE_HALF(name) \
165 (name[0] == 'F' && name[2] == 'M' && (name[3] == 'B' || name[3] == 'T'))
4445cb1c 166#define HALF_FORMAT "FMD/FMD%d_%c"
167#define SENSOR_FORMAT "FMD/FMD%d_%c/FMD%c_%02d"
bf000c32 168
169//____________________________________________________________________
170void
171AliFMDDetector::InitTransformations()
172{
02a27b50 173 // Find all local<->global transformations for this detector.
bf000c32 174 if ((!fInner || (fInner && fInnerTransforms)) &&
175 (!fOuter || (fOuter && fOuterTransforms))) {
f95a63c4 176 AliFMDDebug(5, ("Transforms for FMD%d already registered", fId));
bf000c32 177 return;
178 }
f95a63c4 179 AliFMDDebug(5, ("Initializing transforms for FMD%d", fId));
bf000c32 180 if (!gGeoManager) {
181 AliFatal("No TGeoManager defined");
182 return;
183 }
4445cb1c 184
185 // Implementation using alignable volume names.
bf000c32 186 // Make container of transforms
187 if (fInner && !fInnerTransforms)
188 fInnerTransforms = new TObjArray(fInner->GetNModules());
189 if (fOuter && !fOuterTransforms)
190 fOuterTransforms = new TObjArray(fOuter->GetNModules());
191
b2e6f0b0 192 // Loop over bottom/top
193 for (size_t ihalf = 0; ihalf < 2; ihalf++) {
194 char half = (ihalf == 0 ? 'T' : 'B');
195 TString path(Form(HALF_FORMAT, fId, half));
196 TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
197 if (!entry) {
198 AliError(Form("Alignable entry for half-detector \"%s\" not found!",
199 path.Data()));
200 continue;
201 }
202 TGeoPhysicalNode* pn = entry->GetPhysicalNode();
203 if (!pn) {
204 AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
205 pn = gGeoManager->MakeAlignablePN(entry);
206 if (!pn) {
207 AliError(Form("No physical node for \"%s\"", path.Data()));
208 continue;
209 }
210 }
211 }
212
4445cb1c 213 // Loop over rings
214 for (size_t iring = 0; iring < 2; iring++) {
215 char ring = (iring == 0 ? 'I' : 'O');
216 TObjArray* trans = 0;
217 AliFMDRing* r = 0;
218 switch (ring) {
219 case 'I': r = fInner; trans = fInnerTransforms; break;
220 case 'O': r = fOuter; trans = fOuterTransforms; break;
221 }
222 if (!r || !trans) continue;
223
224 Int_t nModules = r->GetNModules();
225 if (nModules <= 0) continue;
226
227 // Loop over bottom/top
228 for (size_t ihalf = 0; ihalf < 2; ihalf++) {
229 char half = (ihalf == 0 ? 'T' : 'B');
230 Int_t base = (half == 'T' ? 0 : nModules / 2);
231
232 // Loop over modules in this half ring
233 for (Int_t imod = 0; imod < nModules / 2; imod++) {
234 // Find physical node entry
235 TString path(Form(SENSOR_FORMAT, fId, half, ring, base+imod));
236 TGeoPNEntry* entry = gGeoManager->GetAlignableEntry(path.Data());
237 if (!entry) {
238 AliError(Form("Alignable entry for sensor \"%s\" not found!",
239 path.Data()));
240 continue;
241 }
242 TGeoPhysicalNode* pn = entry->GetPhysicalNode();
243 if (!pn) {
244 AliWarning(Form("Making physical volume for \"%s\"", path.Data()));
245 pn = gGeoManager->MakeAlignablePN(entry);
246 if (!pn) {
247 AliError(Form("No physical node for \"%s\"", path.Data()));
248 continue;
249 }
250 }
251
252 const TGeoMatrix* pm = pn->GetMatrix();
253 if (!pm) {
254 AliError(Form("No matrix for path \"%s\"", path.Data()));
255 continue;
256 }
257 // Get transformation matrix for this node, and store it.
258 TGeoMatrix* t = new TGeoHMatrix(*pm);
259 trans->AddAt(t, base+imod);
42f1b2f5 260 AliFMDDebug(5, ("Found matrix for path \"%s\": %p",path.Data(),pm));
4445cb1c 261 }
262 }
263 }
264 if (HasAllTransforms('I') && HasAllTransforms('O')) return;
265
266 // Alternative implementation using TGeoIter.
267 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
268 if (!topVolume) {
269 AliFatal("No top-level volume defined");
270 return;
271 }
bf000c32 272 // Make an iterator
273 TGeoIterator next(topVolume);
274 TGeoNode* node = 0;
275
276 // Find the node corresponding to this detector, and then find the
277 // sensor volumes
278 Bool_t thisNodeFound = kFALSE;
279 Bool_t allInners = HasAllTransforms('I');
280 Bool_t allOuters = HasAllTransforms('O');
281
282 while ((node = static_cast<TGeoNode*>(next()))
283 && !(allInners && allOuters)) {
284 // Get nodes names
285 const Char_t* name = node->GetName();
286 if (!name) continue;
f95a63c4 287 AliFMDDebug(50, ("Got volume %s", name));
bf000c32 288 // Check if this node is this detector
289 // The base offset for numbers in the ASCII table is 48
290 if (IS_NODE_THIS(name)) {
f95a63c4 291 AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
bf000c32 292 thisNodeFound = kTRUE;
293 }
294 // if the detector was found, then we're on that branch, and we
295 // check if this node represents a module in that branch.
296 if (thisNodeFound && IS_NODE_SENSOR(name)) {
f95a63c4 297 AliFMDDebug(20, ("Found sensor node '%s' for FMD%d", name, fId));
bf000c32 298 // Get the ring Id.
299 Char_t ringid = name[1];
300
301 // Get the approprate ring
302 AliFMDRing* ring = GetRing(ringid);
303 if (!ring) continue;
304
305 // Check whether we have all the modules we need for this ring,
306 // and if so, go on to the next node.
307 Bool_t& done = (ring == fInner ? allInners : allOuters);
308 if ((done = HasAllTransforms(ringid))) {
f95a63c4 309 AliFMDDebug(20, ("Already has all module transforms for ring %c",
bf000c32 310 ringid));
311 continue;
312 }
313
314 // Get the approprate container
315 TObjArray* matricies = (ringid == 'i' || ringid == 'I'
316 ? fInnerTransforms : fOuterTransforms);
317
318 // Get the copy (module) number, and check that it hasn't
319 // already been added to the container.
320 Int_t copy = node->GetNumber();
321 if (matricies->At(copy)) {
322 AliWarning(Form("Have a transformation for module %d in ring %c",
323 copy, ringid));
324 continue;
325 }
326
327 // Get the global transformation matrix, and store it.
328 TGeoMatrix* trans = new TGeoHMatrix(*(next.GetCurrentMatrix()));
329 matricies->AddAt(trans, copy);
330
331 }
1a1fdef7 332 }
1a1fdef7 333}
334
335//____________________________________________________________________
9de78b35 336void
337AliFMDDetector::SetAlignableVolumes() const
338{
97e94238 339 // Set alignable volumes.
340 // This will define the alignable volumes.
341 // That is currently, the modules and the half-rings.
342
f95a63c4 343 AliFMDDebug(10, ("Making alignable volumes for FMD%d", fId));
9de78b35 344 if (!gGeoManager) {
345 AliFatal("No TGeoManager defined");
346 return;
347 }
348 TGeoVolume* topVolume = gGeoManager->GetTopVolume();
349 if (!topVolume) {
350 AliFatal("No top-level volume defined");
351 return;
352 }
353
354 // Make an iterator
355 TGeoIterator next(topVolume);
356 next.Reset(topVolume);
357 next.SetTopName(Form("/%s_1", topVolume->GetName()));
358 TGeoNode* node = 0;
359
360 Int_t nInnerSensor = (fInner ? fInner->GetNModules() : 0);
361 Int_t nOuterSensor = (fOuter ? fOuter->GetNModules() : 0);
362 // Find the node corresponding to this detector, and then find the
363 // sensor volumes
364 Bool_t thisNodeFound = kFALSE;
365 Char_t thisHalf = '\0';
366 Int_t iInnerSensor = 0;
367 Int_t iOuterSensor = 0;
368 Bool_t hasTop = false;
369 Bool_t hasBottom = false;
370
371 TString path, align;
372 while ((node = static_cast<TGeoNode*>(next()))
373 && (iInnerSensor < nInnerSensor || iOuterSensor < nOuterSensor
374 || !hasBottom || !hasTop)) {
375 // Get nodes names
376 const Char_t* name = node->GetName();
377 if (!name) continue;
f95a63c4 378 AliFMDDebug((name[0] == 'F' ? 40 : 50), ("Got volume %s", name));
9de78b35 379 // Check if this node is this detector
380 // The base offset for numbers in the ASCII table is 48
381 if (IS_NODE_THIS(name)) {
f95a63c4 382 AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
9de78b35 383 thisNodeFound = kTRUE;
384 }
385
386 // if a half ring is found, then we're on that branch, and we
387 // check if this node represents a half ring on that branch
388 if (thisNodeFound && IS_NODE_HALF(name)) {
f95a63c4 389 AliFMDDebug(30, ("Found half node '%s' for FMD%d", name, fId));
9de78b35 390 // Get the half Id.
391 thisHalf = name[3];
392
393 // Check if we're done
394 Bool_t done = (thisHalf == 'T' ? hasTop : hasBottom);
395 if (done) {
f95a63c4 396 AliFMDDebug(20, ("Already has all halves for detector %c",name[1]));
9de78b35 397 continue;
398 }
399
400 switch (thisHalf) {
401 case 'T': hasTop = true; break;
402 case 'B': hasBottom = true; break;
403 default:
a3b4090c 404 AliWarning(Form("Unknown part '%c' of FMD%d", thisHalf, fId));
9de78b35 405 continue; // because the node is unknown.
406 }
407
408 // Get the node path
409 next.GetPath(path);
4445cb1c 410 align = Form(HALF_FORMAT, fId, thisHalf);
9de78b35 411 }
412
413 // if the detector was found, then we're on that branch, and we
414 // check if this node represents a module in that branch.
415 if (thisNodeFound && thisHalf && IS_NODE_SENSOR(name)) {
f95a63c4 416 AliFMDDebug(30, ("Found sensor node '%s' for FMD%d", name, fId));
9de78b35 417 // Get the ring Id.
418 Char_t ringid = name[1];
419
420 // check that the ring is valid
421 if (!GetRing(ringid)) {
422 AliWarning(Form("Invalid ring %c for FMD%d", ringid, fId));
423 continue;
424 }
425
426 // Check if we're done
427 Bool_t done = false;
428 switch (ringid) {
429 case 'I': done = iInnerSensor >= nInnerSensor; break;
430 case 'O': done = iOuterSensor >= nOuterSensor; break;
431 default: continue;
432 }
433 if (done) {
f95a63c4 434 AliFMDDebug(20, ("Already has all sensor volumes for ring %c",ringid));
9de78b35 435 continue;
436 }
437 // Get the copy (module) number, and check that it hasn't
438 // already been added to the container.
439 Int_t copy = node->GetNumber();
440 next.GetPath(path);
441 // path.Replace("ALIC", "/ALIC_1");
4445cb1c 442 align = Form(SENSOR_FORMAT, fId, thisHalf, ringid, copy);
9de78b35 443
444 switch (ringid) {
445 case 'I': iInnerSensor++; break;
446 case 'O': iOuterSensor++; break;
447 }
448 }
449 if (!align.IsNull() && !path.IsNull()) {
f95a63c4 450 AliFMDDebug(20, ("Got %s -> %s", path.Data(), align.Data()));
9de78b35 451 TGeoPNEntry* entry =
452 gGeoManager->SetAlignableEntry(align.Data(),path.Data());
453 if(!entry)
454 AliFatal(Form("Alignable entry %s not created. "
455 "Volume path %s not valid",
456 align.Data(),path.Data()));
457#ifdef MAKE_ALIGNABLE_PHYSICAL
458 TGeoPhysicalNode* phys = gGeoManager->MakeAlignablePN(entry);
459 if (!phys)
460 AliWarning(Form("Physical node entry %s not created. "
461 "Volume path %s not valid",
462 align.Data(),path.Data()));
463#endif
464 align = "";
465 }
f95a63c4 466 AliFMDDebug(20, ("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d",
9de78b35 467 fId, hasTop, hasBottom, iInnerSensor, nInnerSensor,
468 iOuterSensor, nOuterSensor));
469 }
470}
471
472
473
474//____________________________________________________________________
1a1fdef7 475AliFMDRing*
476AliFMDDetector::GetRing(Char_t id) const
477{
088f8e79 478 // Get the specified ring
479 //
480 // ID Id of ring ('I' or 'O')
481 //
1a1fdef7 482 switch (id) {
483 case 'i':
484 case 'I': return GetInner();
485 case 'o':
486 case 'O': return GetOuter();
487 }
488 return 0;
489}
490
491//____________________________________________________________________
492Double_t
493AliFMDDetector::GetRingZ(Char_t id) const
494{
088f8e79 495 // Get the z-coordinate specified ring
496 //
497 // ID Id of ring ('I' or 'O')
498 //
1a1fdef7 499 switch (id) {
500 case 'i':
501 case 'I': return GetInnerZ();
502 case 'o':
503 case 'O': return GetOuterZ();
504 }
505 return 0;
506}
bf000c32 507
508//____________________________________________________________________
509TGeoMatrix*
510AliFMDDetector::FindTransform(Char_t ring, UShort_t sector) const
511{
512 // Find the transformation that corresponds to sector sector in ring
513 // ring.
514 TObjArray* matricies = 0;
515 switch (ring) {
516 case 'i': case 'I': matricies = fInnerTransforms; break;
517 case 'o': case 'O': matricies = fOuterTransforms; break;
518 }
519 if (!matricies) {
520 AliWarning(Form("Unknown ring %c of FMD%d", ring, fId));
521 return 0;
522 }
523 UInt_t module = sector / 2;
524 TGeoMatrix* m = static_cast<TGeoMatrix*>(matricies->At(module));
525 if (!m) {
526 AliWarning(Form("No matrix found for sector %d in FMD%d%c",
527 sector, fId, ring));
528 return 0;
529 }
530 return m;
531}
532
533
1a1fdef7 534//____________________________________________________________________
535void
bf000c32 536AliFMDDetector::Detector2XYZ(Char_t ring,
1a1fdef7 537 UShort_t sector,
538 UShort_t strip,
539 Double_t& x,
540 Double_t& y,
541 Double_t& z) const
542{
088f8e79 543 // Translate detector coordinates (this,ring,sector,strip) into
544 // (x,y,z) coordinates (in global reference frame)
1a1fdef7 545 AliFMDRing* r = GetRing(ring);
f38b1653 546 if (!r) {
547 AliWarning(Form("No such ring FMD%d%c ", fId, ring));
548 return;
549 }
bf000c32 550 TGeoMatrix* m = FindTransform(ring, sector);
f38b1653 551 if (!m) {
552 AliWarning(Form("No transfrmation found for FMD%d%c[%02d]",
553 fId, ring, sector));
554 return;
555 }
bf000c32 556 Double_t rho = r->GetStripRadius(strip);
557 Double_t phi = ((sector % 2) - .5) * r->GetTheta();
558 Double_t siThick = r->GetSiThickness();
458e52e8 559#if 0
bf000c32 560 Double_t modThick = (siThick
561 + r->GetPrintboardThickness()
562 + r->GetCopperThickness()
563 + r->GetChipThickness()
564 + r->GetSpacing());
458e52e8 565#endif
f95a63c4 566 AliFMDDebug(30, ("Rho %7.3f, angle %7.3f", rho, phi));
458e52e8 567 Double_t local[] = { rho * TMath::Cos(phi * TMath::DegToRad()),
568 rho * TMath::Sin(phi * TMath::DegToRad()),
d98fbfa5 569 /* -modThick + */ siThick / 2 };
bf000c32 570 Double_t master[3];
f95a63c4 571 AliFMDDebug(30, ("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
bf000c32 572 m->LocalToMaster(local, master);
f95a63c4 573 AliFMDDebug(30, ("Master (%7.3f,%7.3f,%7.3f)",
bf000c32 574 master[0],master[1],master[2]));
575 x = master[0];
576 y = master[1];
577 z = master[2];
1a1fdef7 578}
579
580//____________________________________________________________________
54e415a8 581Bool_t
582AliFMDDetector::XYZ2Detector(Double_t x,
583 Double_t y,
584 Double_t z,
585 Char_t& ring,
586 UShort_t& sector,
587 UShort_t& strip) const
588{
088f8e79 589 // Translate (x,y,z) coordinates (in global reference frame) into
590 // detector coordinates (this,ring,sector,strip).
54e415a8 591 AliFMDRing* rng = 0;
592 ring = -1;
593 for (int j = 0; j < 2; j++) {
594 rng = GetRing(j == 0 ? 'I' : 'O');
595 if (!rng) continue;
596 Double_t ringZ = GetRingZ(j == 0 ? 'I' : 'O');
597 Double_t modSpace = TMath::Sign(rng->GetModuleSpacing(), ringZ);
598 if (TMath::Abs(z - ringZ) < 0.01 ||
599 TMath::Abs(z - ringZ + modSpace) < 0.01) break;
600 rng = 0;
601 }
602 if (rng && rng->XYZ2Detector(x, y, z - GetRingZ(rng->GetId()),
603 sector, strip)) {
604 ring = rng->GetId();
605 return kTRUE;
606 }
607 return kFALSE;
608}
609
610
611
612//____________________________________________________________________
1a1fdef7 613//
614// EOF
615//