AliRoot Core  edcc906 (edcc906)
AliFMDDetector.cxx
Go to the documentation of this file.
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  **************************************************************************/
15 /* $Id$ */
23 //____________________________________________________________________
24 //
25 // AliFMDDetector.
26 //
27 // Base class for concrete FMD detectors, like AliFMD1, AliFMD2,
28 // AliFMD3.
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 //
37 
38 #include <TGeoManager.h> // ROOT_TGeoManager
39 #include <TGeoPhysicalNode.h> // ROOT_TGeoPhysicalNode
40 #include <TGeoMatrix.h> // ROOT_TGeoMatrix
41 #include <TMath.h> // ROOT_TMath
42 
43 #include "AliFMDDetector.h" // ALIFMDSUBDETECTOR_H
44 #include "AliFMDRing.h" // ALIFMDRING_H
45 #include "AliFMDDebug.h" // ALIFMDDEBUG_H ALILOG_H
46 
47 //====================================================================
48 ClassImp(AliFMDDetector)
49 #if 0
50  ; // This is here to keep Emacs for indenting the next line
51 #endif
52 
53 //____________________________________________________________________
55  : TNamed(Form("FMD%d", id), "Forward multiplicity ring"),
56  fId(id),
57  fInnerZ(0.),
58  fOuterZ(0.),
59  fInnerHoneyLowR(0.),
60  fInnerHoneyHighR(0.),
61  fOuterHoneyLowR(0.),
62  fOuterHoneyHighR(0.),
63  fInner(inner),
64  fOuter(outer),
65  fInnerTransforms(0),
66  fOuterTransforms(0)
67 {
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  //
76  SetInnerZ(0);
77  SetOuterZ(0);
80 }
81 
82 //____________________________________________________________________
84  : TNamed(other),
85  fId(other.fId),
86  fInnerZ(0.),
87  fOuterZ(0.),
88  fInnerHoneyLowR(0.),
89  fInnerHoneyHighR(0.),
90  fOuterHoneyLowR(0.),
91  fOuterHoneyHighR(0.),
92  fInner(other.fInner),
93  fOuter(other.fOuter),
96 {
97  // Copy constructor
100  SetInnerZ(other.GetInnerZ());
101  SetOuterZ(other.GetOuterZ());
104 }
105 
106 //____________________________________________________________________
109 {
110  // Assignment operator
111  if (&other == this) return *this;
112  SetName(other.GetName());
113  SetTitle(other.GetTitle());
114  fId = other.fId;
115  fInner = other.fInner;
116  fOuter = other.fOuter;
121  SetInnerZ(other.GetInnerZ());
122  SetOuterZ(other.GetOuterZ());
125  return *this;
126 }
127 
128 //____________________________________________________________________
129 void
131 {
132  // Initialize.
133  if (fInner) {
136  }
137  if (fOuter) {
140  }
141 }
142 
143 //____________________________________________________________________
144 Bool_t
146 {
147  // Check if we got all transformations for a given ring. Return
148  // true in that case.
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'))
160 #define IS_NODE_SENSOR(name) \
161  (name[0] == 'F' && (name[2] == 'B' || name[2] == 'F') && name[3] == 'H')
162 //#define IS_NODE_SENSOR(name)
163 // (name[0] == 'F' && name[2] == 'S' && name[3] == 'E')
164 #define IS_NODE_HALF(name) \
165  (name[0] == 'F' && name[2] == 'M' && (name[3] == 'B' || name[3] == 'T'))
166 #define HALF_FORMAT "FMD/FMD%d_%c"
167 #define SENSOR_FORMAT "FMD/FMD%d_%c/FMD%c_%02d"
168 
169 //____________________________________________________________________
170 void
172 {
173  // Find all local<->global transformations for this detector.
174  if ((!fInner || (fInner && fInnerTransforms)) &&
175  (!fOuter || (fOuter && fOuterTransforms))) {
176  AliFMDDebug(5, ("Transforms for FMD%d already registered", fId));
177  return;
178  }
179  AliFMDDebug(5, ("Initializing transforms for FMD%d", fId));
180  if (!gGeoManager) {
181  AliFatal("No TGeoManager defined");
182  return;
183  }
184 
185  // Implementation using alignable volume names.
186  // Make container of transforms
187  if (fInner && !fInnerTransforms)
189  if (fOuter && !fOuterTransforms)
191 
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 
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);
260  AliFMDDebug(5, ("Found matrix for path \"%s\": %p",path.Data(),pm));
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  }
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;
287  AliFMDDebug(50, ("Got volume %s", name));
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)) {
291  AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
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)) {
297  AliFMDDebug(20, ("Found sensor node '%s' for FMD%d", name, fId));
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))) {
309  AliFMDDebug(20, ("Already has all module transforms for ring %c",
310  ringid));
311  continue;
312  }
313 
314  // Get the approprate container
315  TObjArray* matricies = (ringid == 'i' || ringid == 'I'
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  }
332  }
333 }
334 
335 //____________________________________________________________________
336 void
338 {
339  // Set alignable volumes.
340  // This will define the alignable volumes.
341  // That is currently, the modules and the half-rings.
342 
343  AliFMDDebug(10, ("Making alignable volumes for FMD%d", fId));
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;
378  AliFMDDebug((name[0] == 'F' ? 40 : 50), ("Got volume %s", name));
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)) {
382  AliFMDDebug(20, ("Found detector node '%s' for FMD%d", name, fId));
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)) {
389  AliFMDDebug(30, ("Found half node '%s' for FMD%d", name, fId));
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) {
396  AliFMDDebug(20, ("Already has all halves for detector %c",name[1]));
397  continue;
398  }
399 
400  switch (thisHalf) {
401  case 'T': hasTop = true; break;
402  case 'B': hasBottom = true; break;
403  default:
404  AliWarning(Form("Unknown part '%c' of FMD%d", thisHalf, fId));
405  continue; // because the node is unknown.
406  }
407 
408  // Get the node path
409  next.GetPath(path);
410  align = Form(HALF_FORMAT, fId, thisHalf);
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)) {
416  AliFMDDebug(30, ("Found sensor node '%s' for FMD%d", name, fId));
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) {
434  AliFMDDebug(20, ("Already has all sensor volumes for ring %c",ringid));
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");
442  align = Form(SENSOR_FORMAT, fId, thisHalf, ringid, copy);
443 
444  switch (ringid) {
445  case 'I': iInnerSensor++; break;
446  case 'O': iOuterSensor++; break;
447  }
448  }
449  if (!align.IsNull() && !path.IsNull()) {
450  AliFMDDebug(20, ("Got %s -> %s", path.Data(), align.Data()));
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  }
466  AliFMDDebug(20, ("FMD%d: top: %d bottom: %d Inner: %d/%d Outer %d/%d",
467  fId, hasTop, hasBottom, iInnerSensor, nInnerSensor,
468  iOuterSensor, nOuterSensor));
469  }
470 }
471 
472 
473 
474 //____________________________________________________________________
475 AliFMDRing*
476 AliFMDDetector::GetRing(Char_t id) const
477 {
478  // Get the specified ring
479  //
480  // ID Id of ring ('I' or 'O')
481  //
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 //____________________________________________________________________
492 Double_t
493 AliFMDDetector::GetRingZ(Char_t id) const
494 {
495  // Get the z-coordinate specified ring
496  //
497  // ID Id of ring ('I' or 'O')
498  //
499  switch (id) {
500  case 'i':
501  case 'I': return GetInnerZ();
502  case 'o':
503  case 'O': return GetOuterZ();
504  }
505  return 0;
506 }
507 
508 //____________________________________________________________________
509 TGeoMatrix*
510 AliFMDDetector::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 
534 //____________________________________________________________________
535 void
537  UShort_t sector,
538  UShort_t strip,
539  Double_t& x,
540  Double_t& y,
541  Double_t& z) const
542 {
543  // Translate detector coordinates (this,ring,sector,strip) into
544  // (x,y,z) coordinates (in global reference frame)
545  AliFMDRing* r = GetRing(ring);
546  if (!r) {
547  AliWarning(Form("No such ring FMD%d%c ", fId, ring));
548  return;
549  }
550  TGeoMatrix* m = FindTransform(ring, sector);
551  if (!m) {
552  AliWarning(Form("No transfrmation found for FMD%d%c[%02d]",
553  fId, ring, sector));
554  return;
555  }
556  Double_t rho = r->GetStripRadius(strip);
557  Double_t phi = ((sector % 2) - .5) * r->GetTheta();
558  Double_t siThick = r->GetSiThickness();
559 #if 0
560  Double_t modThick = (siThick
562  + r->GetCopperThickness()
563  + r->GetChipThickness()
564  + r->GetSpacing());
565 #endif
566  AliFMDDebug(30, ("Rho %7.3f, angle %7.3f", rho, phi));
567  Double_t local[] = { rho * TMath::Cos(phi * TMath::DegToRad()),
568  rho * TMath::Sin(phi * TMath::DegToRad()),
569  /* -modThick + */ siThick / 2 };
570  Double_t master[3];
571  AliFMDDebug(30, ("Local (%7.3f,%7.3f,%7.3f)",local[0], local[1], local[2]));
572  m->LocalToMaster(local, master);
573  AliFMDDebug(30, ("Master (%7.3f,%7.3f,%7.3f)",
574  master[0],master[1],master[2]));
575  x = master[0];
576  y = master[1];
577  z = master[2];
578 }
579 
580 //____________________________________________________________________
581 Bool_t
583  Double_t y,
584  Double_t z,
585  Char_t& ring,
586  UShort_t& sector,
587  UShort_t& strip) const
588 {
589  // Translate (x,y,z) coordinates (in global reference frame) into
590  // detector coordinates (this,ring,sector,strip).
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 //____________________________________________________________________
613 //
614 // EOF
615 //
Double_t GetOuterZ() const
#define IS_NODE_THIS(name)
Bool_t HasAllTransforms(Char_t ring) const
AliFMDRing * GetInner() const
AliFMDDetector(Int_t id, AliFMDRing *inner, AliFMDRing *outer)
Double_t GetInnerHoneyHighR() const
AliFMDRing * fOuter
AliFMDRing * GetOuter() const
Double_t GetHighR() const
Definition: AliFMDRing.h:194
Double_t GetInnerZ() const
#define TObjArray
AliTPCcalibAlign align
Definition: CalibAlign.C:43
Double_t GetChipThickness() const
Definition: AliFMDRing.h:254
const char * path
FMD ring geometry parameters.
Double_t GetCopperThickness() const
Definition: AliFMDRing.h:249
void Detector2XYZ(Char_t ring, UShort_t sector, UShort_t strip, Double_t &x, Double_t &y, Double_t &z) const
#define SENSOR_FORMAT
AliFMDRing * GetRing(Char_t id) const
Char_t GetId() const
Definition: AliFMDRing.h:159
Double_t fInnerHoneyLowR
Double_t GetSpacing() const
Definition: AliFMDRing.h:259
Base class for the geometry description and parameters of the FMD sub detectors FMD1, FMD2, and FMD3.
Double_t GetStripRadius(UShort_t strip) const
Definition: AliFMDRing.cxx:248
TObjArray * fInnerTransforms
#define AliWarning(message)
Definition: AliLog.h:541
Double_t GetSiThickness() const
Definition: AliFMDRing.h:174
TGeoMatrix * FindTransform(Char_t ring, UShort_t sector) const
Double_t fInnerHoneyHighR
Double_t fOuterHoneyHighR
bool trans(const AliFMDIndex &x, const AliFMDIndex &y, const AliFMDIndex &z)
Definition: TestIndex.C:94
Double_t GetRingZ(Char_t id) const
AliFMDRing * fInner
Double_t fOuterHoneyLowR
void SetOuterHoneyHighR(Double_t x)
Double_t GetLowR() const
Definition: AliFMDRing.h:189
Int_t GetNModules() const
Definition: AliFMDRing.h:214
TGeoManager * gGeoManager
virtual void Init()
#define IS_NODE_HALF(name)
#define AliFMDDebug(N, A)
Definition: AliFMDDebug.h:39
void SetOuterZ(Double_t x)
void SetInnerHoneyLowR(Double_t x)
Double_t GetPrintboardThickness() const
Definition: AliFMDRing.h:244
#define AliFatal(message)
Definition: AliLog.h:640
AliFMDDetector & operator=(const AliFMDDetector &other)
TObjArray * fOuterTransforms
void SetOuterHoneyLowR(Double_t x)
#define IS_NODE_SENSOR(name)
void SetInnerHoneyHighR(Double_t x)
Double_t GetOuterHoneyHighR() const
Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z, Char_t &ring, UShort_t &sector, UShort_t &strip) const
virtual void SetAlignableVolumes() const
Double_t GetTheta() const
Definition: AliFMDRing.h:199
Geometry description and parameters of a ring in the FMD detector.
Definition: AliFMDRing.h:41
Bool_t XYZ2Detector(Double_t x, Double_t y, Double_t z, UShort_t &sector, UShort_t &strip) const
Definition: AliFMDRing.cxx:338
Double_t GetOuterHoneyLowR() const
#define AliError(message)
Definition: AliLog.h:591
#define HALF_FORMAT
Double_t GetModuleSpacing() const
Definition: AliFMDRing.h:239
virtual void InitTransformations()
Sub-detector base class declaration.
void SetInnerZ(Double_t x)
Double_t GetInnerHoneyLowR() const