Belle II Software  release-08-01-10
ARICHGeometryPar.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <arich/geometry/ARICHGeometryPar.h>
10 
11 #include <framework/logging/Logger.h>
12 #include <framework/gearbox/GearDir.h>
13 #include <framework/gearbox/Unit.h>
14 
15 #include <Math/VectorUtil.h>
16 
17 #include <cmath>
18 #include <boost/format.hpp>
19 #include <boost/foreach.hpp>
20 
21 using namespace std;
22 using namespace boost;
23 
24 namespace Belle2 {
30  ARICHGeometryPar* ARICHGeometryPar::p_B4ARICHGeometryParDB = 0;
31 
32  ARICHGeometryPar* ARICHGeometryPar::Instance()
33  {
34  if (!p_B4ARICHGeometryParDB) {
35  p_B4ARICHGeometryParDB = new ARICHGeometryPar();
36  }
37  return p_B4ARICHGeometryParDB;
38  }
39 
40  ARICHGeometryPar::ARICHGeometryPar()
41  {
42  clear();
43  }
44 
45  ARICHGeometryPar::~ARICHGeometryPar()
46  {
47  }
48 
49  void ARICHGeometryPar::Initialize(const GearDir& content, const GearDir& mirrorcontent)
50  {
51 
52  read(content);
53  string Type = content.getString("@type", "");
54  if (Type == "beamtest") {
55  m_simple = true;
56  modulesPositionSimple(content);
57  mirrorPositionSimple(mirrorcontent);
58  } else {
59  modulesPosition(content);
60  mirrorPositions(content);
61  frontEndMapping(content);
62  }
63  chipLocPosition();
64  padPositions();
65  initDetectorMask(m_fR.size());
66  readModuleInfo(content);
67  m_init = true;
68  }
69 
70  void ARICHGeometryPar::Initialize(const GearDir& content)
71  {
72  Initialize(content, content);
73  }
74 
75  void ARICHGeometryPar::clear(void)
76  {
77  m_chipGap = 0.0;
78  m_detZpos = 0.0;
79  m_modXSize = 0.0;
80  m_modZSize = 0.0;
81  m_winThick = 0.0;
82  m_winRefInd = 0.0;
83  m_mirrorOuterRad = 0.0;
84  m_mirrorThickness = 0.0;
85  m_mirrorStartAng = 0.0;
86  m_nMirrors = 0;
87  m_mirrorZPos = 0.0;
88  m_nPadX = 0;
89  m_padSize = 0.0;
90  m_detInnerRadius = 0.0;
91  m_detOuterRadius = 0.0;
92  m_nrow = 0;
93  m_nRad = 0;
94  m_init = false;
95  m_simple = false;
96  m_ncol.clear(); m_fDFi.clear(); m_fDR.clear(); m_fR.clear();
97  m_fFi.clear(); m_fFiMod.clear(); m_chipLocPos.clear(); m_padWorldPositions.clear(); m_mirrornorm.clear(); m_mirrorpoint.clear();
98  m_ChannelQE.clear();
99  for (int i = 0; i < MAX_N_ALAYERS; i++) {
100  m_aeroTrLength[i] = 0; m_aeroRefIndex[i] = 0;
101  m_aeroZPosition[i] = 0; m_aeroThickness[i] = 0;
102  }
103  m_nPads = 0;
104  m_ColEffi = 0.;
105  m_LambdaFirst = 0.;
106  m_LambdaStep = 0.;
107  m_NpointsQE = 0;
108  m_qeScale = 0.;
109  m_windowAbsorbtion = 0.;
110  m_chipNegativeCrosstalk = 0;
111  for (int i = 0; i < MAXPTS_QE; i++) {m_QE[i] = 0.;}
112 
113  m_tileNr = 0;
114  m_tileGap = 0.;
115  m_aeroRin = 0.;
116  m_aeroRout = 0.;
117  for (int i = 0; i < 5; i++) m_tileNphi[i] = 0;
118 
119  }
120 
121  void ARICHGeometryPar::read(const GearDir& content)
122  {
123 
124  //------------------------------
125  // Get ARICH geometry parameters
126  //------------------------------
127  GearDir detParams(content, "Detector");
128  m_modXSize = detParams.getLength("Module/moduleXSize");
129  m_modZSize = detParams.getLength("Module/moduleZSize");
130  m_winThick = detParams.getLength("Module/windowThickness");
131  m_nPadX = detParams.getInt("Module/padXNum");
132  m_nPads = m_nPadX * m_nPadX;
133  m_padSize = detParams.getLength("Module/padSize");
134  m_chipGap = detParams.getLength("Module/chipGap");
135  m_detZpos = detParams.getLength("Plane/zPosition");
136  m_qeScale = detParams.getDouble("Module/qeScale");
137  m_windowAbsorbtion = detParams.getDouble("Module/windowAbsorbtion");
138  m_chipNegativeCrosstalk = detParams.getDouble("Module/chipNegativeCrosstalk");
139  string Type = content.getString("@type", "");
140  if (Type == "beamtest") return;
141  m_detInnerRadius = detParams.getLength("Plane/tubeInnerRadius");
142  m_detOuterRadius = detParams.getLength("Plane/tubeOuterRadius");
143 
144  GearDir mirrParams(content, "Mirrors");
145  if (mirrParams) {
146  m_nMirrors = mirrParams.getInt("nMirrors");
147  m_mirrorThickness = mirrParams.getLength("mirrorThickness");
148  m_mirrorOuterRad = mirrParams.getLength("outerRadius");
149  m_mirrorStartAng = mirrParams.getAngle("startAngle");
150  m_mirrorZPos = mirrParams.getLength("Zposition");
151  }
152 
153  GearDir qeParams(content, "QE");
154  m_ColEffi = qeParams.getDouble("ColEffi");
155  m_LambdaFirst = qeParams.getLength("LambdaFirst") / Unit::nm;
156  m_LambdaStep = qeParams.getLength("LambdaStep") / Unit::nm;
157  m_NpointsQE = 0;
158  for (int i = 0; i < MAXPTS_QE; i++) {
159  int ii = i + 1;
160  stringstream ss; string cc;
161  ss << ii; ss >> cc;
162  string path = "Qeffi[@component='point-" + cc + "']/";
163  GearDir qe(qeParams, path);
164  if (!qe) break;
165  m_NpointsQE++;
166  m_QE[i] = qe.getDouble("qe");
167  }
168 
169  GearDir aerogel(content, "Aerogel");
170  m_tileNr = aerogel.getInt("tileNr");
171  m_tileGap = aerogel.getLength("tileGap") / Unit::cm;
172  m_aeroRin = aerogel.getLength("tubeInnerRadius") / Unit::cm;
173  m_aeroRout = aerogel.getLength("tubeOuterRadius") / Unit::cm;
174 
175  int i = 0;
176  for (const GearDir& ring : aerogel.getNodes("tileNphi/Ring")) {
177  m_tileNphi[i] = ring.getInt();
178  i++;
179  }
180 
181  }
182 
183  void ARICHGeometryPar::frontEndMapping(const GearDir& content)
184  {
185 
186  GearDir mapping(content, "FrontEndMapping");
187 
188  for (const GearDir& merger : mapping.getNodes("Merger")) {
189  unsigned mergerID = (unsigned) merger.getInt("@id");
190 
191  auto testMer = m_mergerIDs.find(mergerID);
192  if (testMer != m_mergerIDs.end()) {
193  B2ERROR(mapping.getPath() << "/MergerID " << mergerID <<
194  " ***input already used");
195  }
196 
197  m_mergerIDs.insert(mergerID);
198 
199  std::vector<unsigned> boardIDs;
200  for (const GearDir& board : merger.getNodes("FEboards/FEboard")) {
201  unsigned boardID = board.getInt();
202  auto testBor = m_boardIDs.find(boardID);
203  if (testBor != m_boardIDs.end()) {
204  B2ERROR(mapping.getPath() << "/FEboardID " << boardID <<
205  " ***input already used");
206  }
207  boardIDs.push_back(boardID);
208  m_boardIDs.insert(boardID);
209  }
210  m_merger2feb.insert(std::pair<int, std::vector<unsigned>>(mergerID, boardIDs));
211  unsigned copperID = (unsigned) merger.getInt("COPPERid");
212  string finesseSlot = merger.getString("FinesseSlot");
213  int finesse = 0;
214  if (finesseSlot == "A") {finesse = 0;}
215  else if (finesseSlot == "B") {finesse = 1;}
216  else if (finesseSlot == "C") {finesse = 2;}
217  else if (finesseSlot == "D") {finesse = 3;}
218  else {
219  B2ERROR(merger.getPath() << "/FinesseSlot " << finesseSlot <<
220  " ***invalid slot (valid are A, B, C, D)");
221  continue;
222  }
223 
224  m_copperIDs.insert(copperID);
225 
226  std::pair<unsigned, int> copfin(copperID, finesse);
227  m_copper2merger.insert(std::pair<std::pair<unsigned, int>, unsigned>(copfin, mergerID));
228 
229  }
230 
231  }
232 
233  int ARICHGeometryPar::getMergerFromCooper(int copperID, int finesse)
234  {
235  auto merger = m_copper2merger.find(std::pair<unsigned, int>(copperID, finesse));
236  if (merger == m_copper2merger.end()) {
237  // B2INFO("getMergerFromCooper: " << " copper " << copperID << ", finesse "
238  // << finesse << " is not assigned to any merger board");
239  return 0;
240  }
241 
242  return merger->second;
243  }
244 
245  int ARICHGeometryPar::getBoardFromMerger(int mergerID, int slot)
246  {
247  auto boards = m_merger2feb.find(mergerID);
248  if (boards == m_merger2feb.end()) {
249  B2ERROR("getBoardFromMerger: " << " merger " << mergerID << " is not mapped");
250  return -1;
251  }
252  if ((boards->second).size() <= unsigned(slot)) {
253  B2ERROR("getBoardFromMerger: " << " merger " << mergerID << " slot " << slot << " is not assigned to FE board.");
254  return -1;
255  }
256  return (boards->second).at(slot);
257  }
258 
259  int ARICHGeometryPar::getNBoardsOnMerger(int mergerID)
260  {
261  auto boards = m_merger2feb.find(mergerID);
262  if (boards == m_merger2feb.end()) {
263  B2ERROR("getNBoardsOnMerger: " << " merger " << mergerID << " is not mapped");
264  }
265  return (boards->second).size();
266  }
267 
268  void ARICHGeometryPar::readModuleInfo(const GearDir& content)
269  {
270  istringstream chstream;
271  int ch; double qq;
272  GearDir modParams(content, "ModuleInfo");
273  uint8_t defqe = uint8_t(modParams.getDouble("DefaultQE") * 100);
274  m_ChannelQE.assign(m_nPads * m_fR.size(), defqe);
275  BOOST_FOREACH(const GearDir & module, modParams.getNodes("Module")) {
276  int modid = atoi(module.getString("@id", "").c_str());
277  chstream.str(module.getString("ChannelsQE"));
278  while (chstream >> ch >> qq) {
279  int chid = (modid - 1) * m_nPads + ch;
280  m_ChannelQE[chid] = uint8_t(qq * 100);
281  }
282  chstream.clear();
283  chstream.str(module.getString("DeadChannels"));
284  while (chstream >> ch) {
285  setActive(modid, ch, false);
286  }
287  chstream.clear();
288  }
289  }
290 
291  double ARICHGeometryPar::QE(double e) const
292  {
293  if (e < 0.001) return 0;
294  double dlam = 1240 / e - m_LambdaFirst;
295  if (dlam < 0) return 0;
296  int i = int(dlam / m_LambdaStep);
297  if (i > m_NpointsQE - 2) return 0;
298  return m_QE[i] + (m_QE[i + 1] - m_QE[i]) / m_LambdaStep * (dlam - i * m_LambdaStep);
299  }
300 
301 
302  void ARICHGeometryPar::Print(void) const
303  {
304  }
305 
306  double ARICHGeometryPar::getChannelQE(int moduleID, int channelID)
307  {
308  int id = (moduleID - 1) * m_nPads + channelID;
309  return m_ChannelQE.at(id) / 100.0;
310  }
311 
312  int ARICHGeometryPar::getChannelID(TVector2 position)
313  {
314  int ChipID = getChipID(position);
315  int Npad = int(m_nPadX / 2);
316  TVector2 chipPos = getChipLocPos(ChipID);
317  TVector2 locloc = position - chipPos;
318  int ix = int(locloc.X() / m_padSize);
319  int iy = int(locloc.Y() / m_padSize);
320  if (locloc.X() < 0 || locloc.Y() < 0) return -1;
321  if (ix > Npad - 1 || iy > Npad - 1) return -1;
322  int chID = ChipID * Npad * Npad + iy + ix * Npad;
323  return chID;
324  }
325 
326  void ARICHGeometryPar::modulesPosition(const GearDir& content)
327  {
328 
329  GearDir detParams(content, "Detector/Plane/Rings");
330 
331  double r = m_detInnerRadius;
332 
333  BOOST_FOREACH(const GearDir & ring, detParams.getNodes("Ring")) {
334  double dR = ring.getLength("dR");
335  r += dR;
336  double rcenter = r + m_modXSize / 2.;
337  if (rcenter + m_modXSize * sqrt(2) / 2. > m_detOuterRadius) {
338  B2WARNING(m_ncol.size() + 1 << "th ring of ARICH photon detectors will not be placed (out of detector tube).");
339  break;
340  }
341  m_nrow++;
342  int nSeg = ring.getInt("nSegments") ;
343  double dFi = ring.getLength("dFi");
344  m_fDR.push_back(dR);
345  double f = 2.*atan2((m_modXSize + dFi) / 2., r);
346  int blaa = int(2.*M_PI / f / nSeg) * nSeg;
347  m_ncol.push_back(blaa);
348  f = 2.*M_PI / double(blaa);
349  m_fDFi.push_back(f);
350  B2INFO(blaa << " modules of " << m_ncol.size() << "th ring of ARICH photon detectors will be placed at r = " << rcenter << "cm. ");
351  for (int nv = 0; nv < blaa; ++nv) {
352  m_fR.push_back(rcenter);
353  double fi = f * (nv + 0.5);
354  m_fFi.push_back(fi);
355  m_fFiMod.push_back(fi);
356  }
357  r += (m_modXSize + r * (1 - cos(f / 2.)));
358  }
359  B2INFO("Altogether " << m_fR.size() << " ARICH photon detector modules will be placed.");
360  }
361 
362  void ARICHGeometryPar::modulesPositionSimple(const GearDir& content)
363  {
364  BOOST_FOREACH(const GearDir & module, content.getNodes("Detector/Plane/Modules/Module")) {
365  TVector2 position(module.getLength("xPos"), module.getLength("yPos"));
366  double angle = module.getAngle("angle") / Unit::rad;
367  m_fFi.push_back(position.Phi());
368  m_fR.push_back(position.Mod());
369  m_fFiMod.push_back(angle);
370  }
371  B2INFO("Altogether " << m_fR.size() << " ARICH photon detector modules will be placed.");
372  }
373 
374  int ARICHGeometryPar::getCopyNo(TVector3 hit)
375  {
376  double x = hit.X();
377  double y = hit.Y();
378  double r = sqrt(x * x + y * y);
379  double fi = atan2(y, x);
380  if (fi < 0) fi += 2 * M_PI;
381  int ntot = 0;
382  for (int i = 0; i < m_nrow; i++) {
383  int nfi = int(fi / m_fDFi[i]);
384  int copyno = ntot + nfi;
385  if (fabs(r - m_fR[copyno]) < m_modXSize / 2.) return copyno + 1;
386  ntot += m_ncol[i];
387  }
388  return -1;
389  }
390 
391  int ARICHGeometryPar::getCopyNo(const ROOT::Math::XYZVector& hit)
392  {
393  TVector3 hitVector(hit.X(), hit.Y(), hit.Z());
394  return getCopyNo(hitVector);
395  }
396 
397  TVector3 ARICHGeometryPar::getOrigin(int copyNo)
398  {
399  TVector2 origin;
400  origin.SetMagPhi(m_fR[copyNo - 1], m_fFi[copyNo - 1]);
401  return TVector3(origin.X(), origin.Y(), m_detZpos + m_modZSize / 2.);
402  }
403 
404  G4ThreeVector ARICHGeometryPar::getOriginG4(int copyNo)
405  {
406  TVector3 origin = getOrigin(copyNo);
407  return G4ThreeVector(origin.X() / Unit::mm, origin.Y() / Unit::mm, origin.Z() / Unit::mm);
408  }
409 
410  double ARICHGeometryPar::getModAngle(int copyno)
411  {
412  return m_fFiMod[copyno - 1];
413  }
414 
415  void ARICHGeometryPar::chipLocPosition()
416  {
417  double xycenter = m_padSize * m_nPadX / 4. + m_chipGap / 2.;
418  m_chipLocPos.push_back(TVector2(xycenter - m_padSize * m_nPadX / 4., xycenter - m_padSize * m_nPadX / 4.));
419  m_chipLocPos.push_back(TVector2(xycenter - m_padSize * m_nPadX / 4., -xycenter - m_padSize * m_nPadX / 4.));
420  m_chipLocPos.push_back(TVector2(-xycenter - m_padSize * m_nPadX / 4., xycenter - m_padSize * m_nPadX / 4.));
421  m_chipLocPos.push_back(TVector2(-xycenter - m_padSize * m_nPadX / 4., -xycenter - m_padSize * m_nPadX / 4.));
422  }
423 
424 
425  int ARICHGeometryPar::getChipID(TVector2 locpos)
426  {
427  if (locpos.X() > 0) {
428  if (locpos.Y() > 0) return 0;
429  return 1;
430  }
431  if (locpos.Y() > 0) return 2;
432  return 3;
433  }
434 
435 
436  TVector3 ARICHGeometryPar::getChannelCenterGlob(int modID, int chanID)
437  {
438  int id = (modID - 1) * m_nPads + chanID;
439  return TVector3(m_padWorldPositions.at(id).X(), m_padWorldPositions.at(id).Y(), m_detZpos + m_winThick);
440  }
441 
442  TVector2 ARICHGeometryPar::getChannelCenterLoc(int chID)
443  {
444  return m_padLocPositions[chID];
445  }
446 
447 
448  void ARICHGeometryPar::padPositions()
449  {
450  int Npad = int(m_nPadX / 2.);
451  TVector2 xstart(m_padSize / 2., m_padSize / 2.);
452  for (int chipID = 0; chipID < 4; chipID++) {
453  TVector2 chipPos = getChipLocPos(chipID);
454  for (int ix = 0; ix < Npad; ix++) {
455  for (int iy = 0; iy < Npad; iy++) {
456  int chanID = chipID * Npad * Npad + ix * Npad + iy;
457  TVector2 center(m_padSize / 2. + ix * m_padSize, m_padSize / 2. + iy * m_padSize);
458  center = center + chipPos;
459  m_padLocPositions[chanID] = center;
460  }
461  }
462  }
463  for (int iMod = 0; iMod < getNMCopies(); iMod++) {
464  for (unsigned int iChan = 0; iChan < m_padLocPositions.size(); iChan++) {
465  TVector2 iModCenter;
466  iModCenter.SetMagPhi(m_fR[iMod], m_fFi[iMod]);
467  TVector2 iChanCenter = m_padLocPositions[iChan];
468  iChanCenter = iChanCenter.Rotate(m_fFiMod[iMod]);
469  TVector2 iWorld((iModCenter + iChanCenter).X(), (iModCenter + iChanCenter).Y());
470  m_padWorldPositions.push_back(iWorld);
471  }
472  }
473  }
474 
475  void ARICHGeometryPar::mirrorPositions(const GearDir& content)
476  {
477  double rmir = m_mirrorOuterRad * cos(M_PI / m_nMirrors) - m_mirrorThickness;
478  for (int i = 0; i < m_nMirrors; i++) {
479  TVector3 norm(cos(2.*M_PI / double(m_nMirrors) * (i + 0.5) + m_mirrorStartAng),
480  sin(2.*M_PI / double(m_nMirrors) * (i + 0.5) + m_mirrorStartAng), 0);
481  m_mirrornorm.push_back(norm);
482  m_mirrorpoint.push_back(rmir * norm);
483  }
484  readMirrorAlignment(content);
485  }
486 
487  void ARICHGeometryPar::mirrorPositionSimple(const GearDir& content)
488  {
489  double thick = content.getLength("Mirrors/thickness");
490  BOOST_FOREACH(const GearDir & mirror, content.getNodes("Mirrors/Mirror")) {
491  double angle = mirror.getAngle("angle");
492  TVector3 point(mirror.getLength("xPos") - cos(angle)*thick / 2., mirror.getLength("yPos") - sin(angle)*thick / 2., 0);
493  TVector3 norm(cos(angle), sin(angle), 0);
494  m_mirrorpoint.push_back(point);
495  m_mirrornorm.push_back(norm);
496  m_mirrorZPos = mirror.getLength("zPos");
497  m_nMirrors++;
498  }
499  }
500 
501  TVector3 ARICHGeometryPar::getMirrorNormal(int mirID)
502  {
503  return m_mirrornorm[mirID];
504  }
505 
506  TVector3 ARICHGeometryPar::getMirrorPoint(int mirID)
507  {
508  return m_mirrorpoint[mirID];
509  }
510 
511  void ARICHGeometryPar::setAeroTransLength(int layer, double trlength)
512  {
513  m_aeroTrLength[layer] = trlength;
514  }
515 
516  void ARICHGeometryPar::setAeroRefIndex(int layer, double n)
517  {
518  if (n) m_aeroRefIndex[layer] = n;
519  }
520 
521  void ARICHGeometryPar::setAerogelThickness(int layer, double thick)
522  {
523  m_nRad++;
524  m_aeroThickness[layer] = thick;
525  }
526 
527  void ARICHGeometryPar::setAerogelZPosition(int layer, double zPos)
528  {
529  m_aeroZPosition[layer] = zPos;
530  }
531 
532  void ARICHGeometryPar::setWindowRefIndex(double refInd)
533  {
534  m_winRefInd = refInd;
535  }
536 
537  void ARICHGeometryPar::initDetectorMask(int nmodules)
538  {
539  int m_DetectorMaskSize = m_nPads * nmodules / 32 + 1;
540  for (int i = 0; i < m_DetectorMaskSize; i++) {
541  m_DetectorMask.push_back(0xFFFFFFFF);
542  }
543  B2INFO("DetectorMask initialized size=" << m_nPads << " * " << nmodules << " +1 =" << m_DetectorMaskSize);
544 
545  }
546 
547  void ARICHGeometryPar::setActive(int module, int channel, bool active)
548  {
549  int ch = (module - 1) * m_nPads + channel;
550  int bit = ch % 32;
551  unsigned int idx = ch / 32;
552  if (idx >= m_DetectorMask.size()) {
553  B2WARNING(idx << " Wrong detector mask size >= " << m_DetectorMask.size());
554  }
555  if (active) m_DetectorMask[idx] |= (1 << bit);
556  else m_DetectorMask[idx] &= ~(1 << bit);
557  }
558 
559  bool ARICHGeometryPar::isActive(int module, int channel)
560  {
561  int ch = (module - 1) * m_nPads + channel;
562  int bit = ch % 32;
563  int idx = ch / 32;
564  return m_DetectorMask[idx] & (1 << bit);
565  }
566 
567  void ARICHGeometryPar::readMirrorAlignment(const GearDir& content)
568  {
569  GearDir modParams(content, "Mirrors/Alignment");
570 
571  BOOST_FOREACH(const GearDir & plate, modParams.getNodes("Plate")) {
572  int id = atoi(plate.getString("@id").c_str());
573  double dr = plate.getLength("dr");
574  double dphi = plate.getAngle("dphi");
575  double dtheta = plate.getAngle("dtheta");
576  m_mirrorpoint[id - 1].SetMag(m_mirrorpoint[id - 1].Mag() + dr);
577  m_mirrornorm[id - 1].SetTheta(m_mirrornorm[id - 1].Theta() + dtheta);
578  m_mirrornorm[id - 1].SetPhi(m_mirrornorm[id - 1].Phi() + dphi);
579  }
580  }
581 
582 
583  int ARICHGeometryPar::getAerogelTileID(TVector2 locpos)
584  {
585 
586  double size = (m_aeroRout - m_aeroRin) / double(m_tileNr);
587  double r = locpos.Mod();
588  double phi = ROOT::Math::VectorUtil::Phi_0_2pi(locpos.Phi());
589  int nr = int((r - m_aeroRin) / size);
590 
591  if (r < m_aeroRin + nr * size + m_tileGap / 2. || r > m_aeroRin + (nr + 1)*size - m_tileGap / 2.) return 0;
592 
593  double dphi = 2.*M_PI / double(m_tileNphi[nr]);
594  double gapPhi = m_tileGap / (m_aeroRin + (nr + 1) * size - m_tileGap / 2.);
595 
596  int nphi = int(phi / dphi);
597  if (phi < nphi * dphi + gapPhi / 2. || phi > (nphi + 1)*dphi - gapPhi / 2.) return 0;
598 
599  int tileID = nphi;
600  for (int i = 0; i < nr; i++) tileID += m_tileNphi[i];
601 
602  return tileID + 1;
603 
604  }
605 
606 
608 } // namespace Belle2
The Class for ARICH Geometry Parameters.
GearDir is the basic class used for accessing the parameter store.
Definition: GearDir.h:31
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition: GearDir.h:69
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
Definition: Interface.h:299
double getDouble(const std::string &path="") const noexcept(false)
Get the parameter path as a double.
Definition: Interface.cc:41
std::string getPath() const
Return path of the current interface.
Definition: Interface.h:70
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
Definition: Interface.h:259
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
Definition: Interface.cc:21
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
Definition: Interface.cc:60
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.