Belle II Software development
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#include <framework/geometry/VectorUtil.h>
15
16#include <Math/VectorUtil.h>
17
18#include <cmath>
19#include <boost/format.hpp>
20#include <boost/foreach.hpp>
21
22using namespace std;
23using namespace boost;
24
25namespace Belle2 {
31 ARICHGeometryPar* ARICHGeometryPar::p_B4ARICHGeometryParDB = 0;
32
34 {
37 }
39 }
40
42 {
43 clear();
44 }
45
47 {
48 }
49
50 void ARICHGeometryPar::Initialize(const GearDir& content, const GearDir& mirrorcontent)
51 {
52
53 read(content);
54 string Type = content.getString("@type", "");
55 if (Type == "beamtest") {
56 m_simple = true;
57 modulesPositionSimple(content);
58 mirrorPositionSimple(mirrorcontent);
59 } else {
60 modulesPosition(content);
61 mirrorPositions(content);
62 frontEndMapping(content);
63 }
66 initDetectorMask(m_fR.size());
67 readModuleInfo(content);
68 m_init = true;
69 }
70
72 {
73 Initialize(content, content);
74 }
75
77 {
78 m_chipGap = 0.0;
79 m_detZpos = 0.0;
80 m_modXSize = 0.0;
81 m_modZSize = 0.0;
82 m_winThick = 0.0;
83 m_winRefInd = 0.0;
84 m_mirrorOuterRad = 0.0;
86 m_mirrorStartAng = 0.0;
87 m_nMirrors = 0;
88 m_mirrorZPos = 0.0;
89 m_nPadX = 0;
90 m_padSize = 0.0;
91 m_detInnerRadius = 0.0;
92 m_detOuterRadius = 0.0;
93 m_nrow = 0;
94 m_nRad = 0;
95 m_init = false;
96 m_simple = false;
97 m_ncol.clear(); m_fDFi.clear(); m_fDR.clear(); m_fR.clear();
98 m_fFi.clear(); m_fFiMod.clear(); m_chipLocPos.clear(); m_padWorldPositions.clear(); m_mirrornorm.clear(); m_mirrorpoint.clear();
99 m_ChannelQE.clear();
100 for (int i = 0; i < MAX_N_ALAYERS; i++) {
101 m_aeroTrLength[i] = 0; m_aeroRefIndex[i] = 0;
102 m_aeroZPosition[i] = 0; m_aeroThickness[i] = 0;
103 }
104 m_nPads = 0;
105 m_ColEffi = 0.;
106 m_LambdaFirst = 0.;
107 m_LambdaStep = 0.;
108 m_NpointsQE = 0;
109 m_qeScale = 0.;
112 for (int i = 0; i < MAXPTS_QE; i++) {m_QE[i] = 0.;}
113
114 m_tileNr = 0;
115 m_tileGap = 0.;
116 m_aeroRin = 0.;
117 m_aeroRout = 0.;
118 for (int i = 0; i < 5; i++) m_tileNphi[i] = 0;
119
120 }
121
122 void ARICHGeometryPar::read(const GearDir& content)
123 {
124
125 //------------------------------
126 // Get ARICH geometry parameters
127 //------------------------------
128 GearDir detParams(content, "Detector");
129 m_modXSize = detParams.getLength("Module/moduleXSize");
130 m_modZSize = detParams.getLength("Module/moduleZSize");
131 m_winThick = detParams.getLength("Module/windowThickness");
132 m_nPadX = detParams.getInt("Module/padXNum");
134 m_padSize = detParams.getLength("Module/padSize");
135 m_chipGap = detParams.getLength("Module/chipGap");
136 m_detZpos = detParams.getLength("Plane/zPosition");
137 m_qeScale = detParams.getDouble("Module/qeScale");
138 m_windowAbsorbtion = detParams.getDouble("Module/windowAbsorbtion");
139 m_chipNegativeCrosstalk = detParams.getDouble("Module/chipNegativeCrosstalk");
140 string Type = content.getString("@type", "");
141 if (Type == "beamtest") return;
142 m_detInnerRadius = detParams.getLength("Plane/tubeInnerRadius");
143 m_detOuterRadius = detParams.getLength("Plane/tubeOuterRadius");
144
145 GearDir mirrParams(content, "Mirrors");
146 if (mirrParams) {
147 m_nMirrors = mirrParams.getInt("nMirrors");
148 m_mirrorThickness = mirrParams.getLength("mirrorThickness");
149 m_mirrorOuterRad = mirrParams.getLength("outerRadius");
150 m_mirrorStartAng = mirrParams.getAngle("startAngle");
151 m_mirrorZPos = mirrParams.getLength("Zposition");
152 }
153
154 GearDir qeParams(content, "QE");
155 m_ColEffi = qeParams.getDouble("ColEffi");
156 m_LambdaFirst = qeParams.getLength("LambdaFirst") / Unit::nm;
157 m_LambdaStep = qeParams.getLength("LambdaStep") / Unit::nm;
158 m_NpointsQE = 0;
159 for (int i = 0; i < MAXPTS_QE; i++) {
160 int ii = i + 1;
161 stringstream ss; string cc;
162 ss << ii; ss >> cc;
163 string path = "Qeffi[@component='point-" + cc + "']/";
164 GearDir qe(qeParams, path);
165 if (!qe) break;
166 m_NpointsQE++;
167 m_QE[i] = qe.getDouble("qe");
168 }
169
170 GearDir aerogel(content, "Aerogel");
171 m_tileNr = aerogel.getInt("tileNr");
172 m_tileGap = aerogel.getLength("tileGap") / Unit::cm;
173 m_aeroRin = aerogel.getLength("tubeInnerRadius") / Unit::cm;
174 m_aeroRout = aerogel.getLength("tubeOuterRadius") / Unit::cm;
175
176 int i = 0;
177 for (const GearDir& ring : aerogel.getNodes("tileNphi/Ring")) {
178 m_tileNphi[i] = ring.getInt();
179 i++;
180 }
181
182 }
183
185 {
186
187 GearDir mapping(content, "FrontEndMapping");
188
189 for (const GearDir& merger : mapping.getNodes("Merger")) {
190 unsigned mergerID = (unsigned) merger.getInt("@id");
191
192 auto testMer = m_mergerIDs.find(mergerID);
193 if (testMer != m_mergerIDs.end()) {
194 B2ERROR(mapping.getPath() << "/MergerID " << mergerID <<
195 " ***input already used");
196 }
197
198 m_mergerIDs.insert(mergerID);
199
200 std::vector<unsigned> boardIDs;
201 for (const GearDir& board : merger.getNodes("FEboards/FEboard")) {
202 unsigned boardID = board.getInt();
203 auto testBor = m_boardIDs.find(boardID);
204 if (testBor != m_boardIDs.end()) {
205 B2ERROR(mapping.getPath() << "/FEboardID " << boardID <<
206 " ***input already used");
207 }
208 boardIDs.push_back(boardID);
209 m_boardIDs.insert(boardID);
210 }
211 m_merger2feb.insert(std::pair<int, std::vector<unsigned>>(mergerID, boardIDs));
212 unsigned copperID = (unsigned) merger.getInt("COPPERid");
213 string finesseSlot = merger.getString("FinesseSlot");
214 int finesse = 0;
215 if (finesseSlot == "A") {finesse = 0;}
216 else if (finesseSlot == "B") {finesse = 1;}
217 else if (finesseSlot == "C") {finesse = 2;}
218 else if (finesseSlot == "D") {finesse = 3;}
219 else {
220 B2ERROR(merger.getPath() << "/FinesseSlot " << finesseSlot <<
221 " ***invalid slot (valid are A, B, C, D)");
222 continue;
223 }
224
225 m_copperIDs.insert(copperID);
226
227 std::pair<unsigned, int> copfin(copperID, finesse);
228 m_copper2merger.insert(std::pair<std::pair<unsigned, int>, unsigned>(copfin, mergerID));
229
230 }
231
232 }
233
234 int ARICHGeometryPar::getMergerFromCooper(int copperID, int finesse)
235 {
236 auto merger = m_copper2merger.find(std::pair<unsigned, int>(copperID, finesse));
237 if (merger == m_copper2merger.end()) {
238 // B2INFO("getMergerFromCooper: " << " copper " << copperID << ", finesse "
239 // << finesse << " is not assigned to any merger board");
240 return 0;
241 }
242
243 return merger->second;
244 }
245
246 int ARICHGeometryPar::getBoardFromMerger(int mergerID, int slot)
247 {
248 auto boards = m_merger2feb.find(mergerID);
249 if (boards == m_merger2feb.end()) {
250 B2ERROR("getBoardFromMerger: " << " merger " << mergerID << " is not mapped");
251 return -1;
252 }
253 if ((boards->second).size() <= unsigned(slot)) {
254 B2ERROR("getBoardFromMerger: " << " merger " << mergerID << " slot " << slot << " is not assigned to FE board.");
255 return -1;
256 }
257 return (boards->second).at(slot);
258 }
259
261 {
262 auto boards = m_merger2feb.find(mergerID);
263 if (boards == m_merger2feb.end()) {
264 B2ERROR("getNBoardsOnMerger: " << " merger " << mergerID << " is not mapped");
265 }
266 return (boards->second).size();
267 }
268
270 {
271 istringstream chstream;
272 int ch; double qq;
273 GearDir modParams(content, "ModuleInfo");
274 uint8_t defqe = uint8_t(modParams.getDouble("DefaultQE") * 100);
275 m_ChannelQE.assign(m_nPads * m_fR.size(), defqe);
276 BOOST_FOREACH(const GearDir & module, modParams.getNodes("Module")) {
277 int modid = atoi(module.getString("@id", "").c_str());
278 chstream.str(module.getString("ChannelsQE"));
279 while (chstream >> ch >> qq) {
280 int chid = (modid - 1) * m_nPads + ch;
281 m_ChannelQE[chid] = uint8_t(qq * 100);
282 }
283 chstream.clear();
284 chstream.str(module.getString("DeadChannels"));
285 while (chstream >> ch) {
286 setActive(modid, ch, false);
287 }
288 chstream.clear();
289 }
290 }
291
292 double ARICHGeometryPar::QE(double e) const
293 {
294 if (e < 0.001) return 0;
295 double dlam = 1240 / e - m_LambdaFirst;
296 if (dlam < 0) return 0;
297 int i = int(dlam / m_LambdaStep);
298 if (i > m_NpointsQE - 2) return 0;
299 return m_QE[i] + (m_QE[i + 1] - m_QE[i]) / m_LambdaStep * (dlam - i * m_LambdaStep);
300 }
301
302
303 void ARICHGeometryPar::Print(void) const
304 {
305 }
306
307 double ARICHGeometryPar::getChannelQE(int moduleID, int channelID)
308 {
309 int id = (moduleID - 1) * m_nPads + channelID;
310 return m_ChannelQE.at(id) / 100.0;
311 }
312
313 int ARICHGeometryPar::getChannelID(ROOT::Math::XYVector position)
314 {
315 int ChipID = getChipID(position);
316 int Npad = int(m_nPadX / 2);
317 ROOT::Math::XYVector chipPos = getChipLocPos(ChipID);
318 ROOT::Math::XYVector locloc = position - chipPos;
319 int ix = int(locloc.X() / m_padSize);
320 int iy = int(locloc.Y() / m_padSize);
321 if (locloc.X() < 0 || locloc.Y() < 0) return -1;
322 if (ix > Npad - 1 || iy > Npad - 1) return -1;
323 int chID = ChipID * Npad * Npad + iy + ix * Npad;
324 return chID;
325 }
326
328 {
329
330 GearDir detParams(content, "Detector/Plane/Rings");
331
332 double r = m_detInnerRadius;
333
334 BOOST_FOREACH(const GearDir & ring, detParams.getNodes("Ring")) {
335 double dR = ring.getLength("dR");
336 r += dR;
337 double rcenter = r + m_modXSize / 2.;
338 if (rcenter + m_modXSize * sqrt(2) / 2. > m_detOuterRadius) {
339 B2WARNING(m_ncol.size() + 1 << "th ring of ARICH photon detectors will not be placed (out of detector tube).");
340 break;
341 }
342 m_nrow++;
343 int nSeg = ring.getInt("nSegments") ;
344 double dFi = ring.getLength("dFi");
345 m_fDR.push_back(dR);
346 double f = 2.*atan2((m_modXSize + dFi) / 2., r);
347 int blaa = int(2.*M_PI / f / nSeg) * nSeg;
348 m_ncol.push_back(blaa);
349 f = 2.*M_PI / double(blaa);
350 m_fDFi.push_back(f);
351 B2INFO(blaa << " modules of " << m_ncol.size() << "th ring of ARICH photon detectors will be placed at r = " << rcenter << "cm. ");
352 for (int nv = 0; nv < blaa; ++nv) {
353 m_fR.push_back(rcenter);
354 double fi = f * (nv + 0.5);
355 m_fFi.push_back(fi);
356 m_fFiMod.push_back(fi);
357 }
358 r += (m_modXSize + r * (1 - cos(f / 2.)));
359 }
360 B2INFO("Altogether " << m_fR.size() << " ARICH photon detector modules will be placed.");
361 }
362
364 {
365 BOOST_FOREACH(const GearDir & module, content.getNodes("Detector/Plane/Modules/Module")) {
366 ROOT::Math::XYVector position(module.getLength("xPos"), module.getLength("yPos"));
367 double angle = module.getAngle("angle") / Unit::rad;
368 m_fFi.push_back(position.Phi());
369 m_fR.push_back(position.R());
370 m_fFiMod.push_back(angle);
371 }
372 B2INFO("Altogether " << m_fR.size() << " ARICH photon detector modules will be placed.");
373 }
374
375 int ARICHGeometryPar::getCopyNo(const ROOT::Math::XYZVector& hit)
376 {
377 double x = hit.X();
378 double y = hit.Y();
379 double r = sqrt(x * x + y * y);
380 double fi = atan2(y, x);
381 if (fi < 0) fi += 2 * M_PI;
382 int ntot = 0;
383 for (int i = 0; i < m_nrow; i++) {
384 int nfi = int(fi / m_fDFi[i]);
385 int copyno = ntot + nfi;
386 if (fabs(r - m_fR[copyno]) < m_modXSize / 2.) return copyno + 1;
387 ntot += m_ncol[i];
388 }
389 return -1;
390 }
391
392 ROOT::Math::XYZVector ARICHGeometryPar::getOrigin(int copyNo)
393 {
394 const double amag = std::abs(m_fR[copyNo - 1]);
395 const double phi = m_fFi[copyNo - 1];
396 return ROOT::Math::XYZVector(amag * std::cos(phi), amag * std::sin(phi), m_detZpos + m_modZSize / 2.);
397 }
398
399 G4ThreeVector ARICHGeometryPar::getOriginG4(int copyNo)
400 {
401 ROOT::Math::XYZVector origin = getOrigin(copyNo);
402 return G4ThreeVector(origin.X() / Unit::mm, origin.Y() / Unit::mm, origin.Z() / Unit::mm);
403 }
404
406 {
407 return m_fFiMod[copyno - 1];
408 }
409
411 {
412 double xycenter = m_padSize * m_nPadX / 4. + m_chipGap / 2.;
413 m_chipLocPos.push_back(ROOT::Math::XYVector(xycenter - m_padSize * m_nPadX / 4., xycenter - m_padSize * m_nPadX / 4.));
414 m_chipLocPos.push_back(ROOT::Math::XYVector(xycenter - m_padSize * m_nPadX / 4., -xycenter - m_padSize * m_nPadX / 4.));
415 m_chipLocPos.push_back(ROOT::Math::XYVector(-xycenter - m_padSize * m_nPadX / 4., xycenter - m_padSize * m_nPadX / 4.));
416 m_chipLocPos.push_back(ROOT::Math::XYVector(-xycenter - m_padSize * m_nPadX / 4., -xycenter - m_padSize * m_nPadX / 4.));
417 }
418
419
420 int ARICHGeometryPar::getChipID(ROOT::Math::XYVector locpos)
421 {
422 if (locpos.X() > 0) {
423 if (locpos.Y() > 0) return 0;
424 return 1;
425 }
426 if (locpos.Y() > 0) return 2;
427 return 3;
428 }
429
430
431 ROOT::Math::XYZVector ARICHGeometryPar::getChannelCenterGlob(int modID, int chanID)
432 {
433 int id = (modID - 1) * m_nPads + chanID;
434 return ROOT::Math::XYZVector(m_padWorldPositions.at(id).X(), m_padWorldPositions.at(id).Y(), m_detZpos + m_winThick);
435 }
436
437 ROOT::Math::XYVector ARICHGeometryPar::getChannelCenterLoc(int chID)
438 {
439 return m_padLocPositions[chID];
440 }
441
442
444 {
445 int Npad = int(m_nPadX / 2.);
446 ROOT::Math::XYVector xstart(m_padSize / 2., m_padSize / 2.);
447 for (int chipID = 0; chipID < 4; chipID++) {
448 ROOT::Math::XYVector chipPos = getChipLocPos(chipID);
449 for (int ix = 0; ix < Npad; ix++) {
450 for (int iy = 0; iy < Npad; iy++) {
451 int chanID = chipID * Npad * Npad + ix * Npad + iy;
452 ROOT::Math::XYVector center(m_padSize / 2. + ix * m_padSize, m_padSize / 2. + iy * m_padSize);
453 center = center + chipPos;
454 m_padLocPositions[chanID] = center;
455 }
456 }
457 }
458 for (int iMod = 0; iMod < getNMCopies(); iMod++) {
459 const double magnitude = std::abs(m_fR[iMod]);
460 const double phi = m_fFi[iMod];
461 const double phiMod = m_fFiMod[iMod];
462 const double iModCenterX = magnitude * std::cos(phi);
463 const double iModCenterY = magnitude * std::sin(phi);
464
465 for (unsigned int iChan = 0; iChan < m_padLocPositions.size(); iChan++) {
466 const ROOT::Math::XYVector& iChanCenter = m_padLocPositions[iChan];
467 const double cosPhiMod = std::cos(phiMod);
468 const double sinPhiMod = std::sin(phiMod);
469 const double iChanCenterRotatedX = iChanCenter.X() * cosPhiMod - iChanCenter.Y() * sinPhiMod;
470 const double iChanCenterRotatedY = iChanCenter.X() * sinPhiMod + iChanCenter.Y() * cosPhiMod;
471 ROOT::Math::XYVector iWorld(iModCenterX + iChanCenterRotatedX, iModCenterY + iChanCenterRotatedY);
472 m_padWorldPositions.push_back(iWorld);
473 }
474 }
475 }
476
478 {
479 double rmir = m_mirrorOuterRad * cos(M_PI / m_nMirrors) - m_mirrorThickness;
480 for (int i = 0; i < m_nMirrors; i++) {
481 ROOT::Math::XYZVector norm(cos(2.*M_PI / double(m_nMirrors) * (i + 0.5) + m_mirrorStartAng),
482 sin(2.*M_PI / double(m_nMirrors) * (i + 0.5) + m_mirrorStartAng), 0);
483 m_mirrornorm.push_back(norm);
484 m_mirrorpoint.push_back(rmir * norm);
485 }
486 readMirrorAlignment(content);
487 }
488
490 {
491 double thick = content.getLength("Mirrors/thickness");
492 BOOST_FOREACH(const GearDir & mirror, content.getNodes("Mirrors/Mirror")) {
493 double angle = mirror.getAngle("angle");
494 ROOT::Math::XYZVector point(mirror.getLength("xPos") - cos(angle)*thick / 2., mirror.getLength("yPos") - sin(angle)*thick / 2., 0);
495 ROOT::Math::XYZVector norm(cos(angle), sin(angle), 0);
496 m_mirrorpoint.push_back(point);
497 m_mirrornorm.push_back(norm);
498 m_mirrorZPos = mirror.getLength("zPos");
499 m_nMirrors++;
500 }
501 }
502
503 ROOT::Math::XYZVector ARICHGeometryPar::getMirrorNormal(int mirID)
504 {
505 return m_mirrornorm[mirID];
506 }
507
508 ROOT::Math::XYZVector ARICHGeometryPar::getMirrorPoint(int mirID)
509 {
510 return m_mirrorpoint[mirID];
511 }
512
513 void ARICHGeometryPar::setAeroTransLength(int layer, double trlength)
514 {
515 m_aeroTrLength[layer] = trlength;
516 }
517
518 void ARICHGeometryPar::setAeroRefIndex(int layer, double n)
519 {
520 if (n) m_aeroRefIndex[layer] = n;
521 }
522
523 void ARICHGeometryPar::setAerogelThickness(int layer, double thick)
524 {
525 m_nRad++;
526 m_aeroThickness[layer] = thick;
527 }
528
529 void ARICHGeometryPar::setAerogelZPosition(int layer, double zPos)
530 {
531 m_aeroZPosition[layer] = zPos;
532 }
533
535 {
536 m_winRefInd = refInd;
537 }
538
540 {
541 int m_DetectorMaskSize = m_nPads * nmodules / 32 + 1;
542 for (int i = 0; i < m_DetectorMaskSize; i++) {
543 m_DetectorMask.push_back(0xFFFFFFFF);
544 }
545 B2INFO("DetectorMask initialized size=" << m_nPads << " * " << nmodules << " +1 =" << m_DetectorMaskSize);
546
547 }
548
549 void ARICHGeometryPar::setActive(int module, int channel, bool active)
550 {
551 int ch = (module - 1) * m_nPads + channel;
552 int bit = ch % 32;
553 unsigned int idx = ch / 32;
554 if (idx >= m_DetectorMask.size()) {
555 B2WARNING(idx << " Wrong detector mask size >= " << m_DetectorMask.size());
556 }
557 if (active) m_DetectorMask[idx] |= (1 << bit);
558 else m_DetectorMask[idx] &= ~(1 << bit);
559 }
560
561 bool ARICHGeometryPar::isActive(int module, int channel)
562 {
563 int ch = (module - 1) * m_nPads + channel;
564 int bit = ch % 32;
565 int idx = ch / 32;
566 return m_DetectorMask[idx] & (1 << bit);
567 }
568
570 {
571 GearDir modParams(content, "Mirrors/Alignment");
572
573 BOOST_FOREACH(const GearDir & plate, modParams.getNodes("Plate")) {
574 int id = atoi(plate.getString("@id").c_str());
575 double dr = plate.getLength("dr");
576 double dphi = plate.getAngle("dphi");
577 double dtheta = plate.getAngle("dtheta");
578 VectorUtil::setMag(m_mirrorpoint[id - 1], m_mirrorpoint[id - 1].R() + dr);
579 VectorUtil::setTheta(m_mirrornorm[id - 1], m_mirrornorm[id - 1].Theta() + dtheta);
580 VectorUtil::setPhi(m_mirrornorm[id - 1], m_mirrornorm[id - 1].Phi() + dphi);
581 }
582 }
583
584
585 int ARICHGeometryPar::getAerogelTileID(ROOT::Math::XYVector locpos)
586 {
587
588 double size = (m_aeroRout - m_aeroRin) / double(m_tileNr);
589 double r = locpos.R();
590 double phi = ROOT::Math::VectorUtil::Phi_0_2pi(locpos.Phi());
591 int nr = int((r - m_aeroRin) / size);
592
593 if (r < m_aeroRin + nr * size + m_tileGap / 2. || r > m_aeroRin + (nr + 1)*size - m_tileGap / 2.) return 0;
594
595 double dphi = 2.*M_PI / double(m_tileNphi[nr]);
596 double gapPhi = m_tileGap / (m_aeroRin + (nr + 1) * size - m_tileGap / 2.);
597
598 int nphi = int(phi / dphi);
599 if (phi < nphi * dphi + gapPhi / 2. || phi > (nphi + 1)*dphi - gapPhi / 2.) return 0;
600
601 int tileID = nphi;
602 for (int i = 0; i < nr; i++) tileID += m_tileNphi[i];
603
604 return tileID + 1;
605
606 }
607
608
610} // namespace Belle2
double R
typedef autogenerated by FFTW
The Class for ARICH Geometry Parameters.
double m_modXSize
Detector module length.
double m_tileGap
Gap size between two aerogel tiles.
double m_winThick
Thickness of detector module window.
double m_padSize
Detector pad size.
double m_chipGap
Gap between chips in detector module.
double m_LambdaFirst
wavelength [nm]: first QE data point
std::vector< ROOT::Math::XYZVector > m_mirrornorm
vector holding normal vectors of mirror plates
std::vector< ROOT::Math::XYVector > m_chipLocPos
vector holding chip positions (in detector module local coordinates)
double m_aeroRout
Outer radius of aerogel tube.
double m_detZpos
Z position of detector plane.
double m_detInnerRadius
Inner radius of detector tube.
double m_aeroRin
Inner radius of aerogel tube.
double m_mirrorOuterRad
Radius of circle outscribed to mirrors polygon.
double m_aeroZPosition[MAX_N_ALAYERS]
Array of aerogel Z positions.
double m_qeScale
QE scale factor for photons internally reflected in HAPD window.
double m_detOuterRadius
Outer radius of detector tube.
std::vector< double > m_fDR
minimal distance between detector modules in radial direction
int m_nrow
number of detector rings
double m_modZSize
Detector module height.
double m_aeroTrLength[MAX_N_ALAYERS]
Array of aerogel transmission lenths.
int m_NpointsQE
number of QE data points
std::unordered_set< unsigned int > m_boardIDs
FEB ID's.
std::unordered_set< unsigned int > m_mergerIDs
Merger ID's.
std::vector< double > m_fR
radial coordinate of detector modules
double m_LambdaStep
wavelength [nm]: step
int m_tileNphi[5]
Number of aerogel tiles in phi direction of each "radial" ring.
double m_winRefInd
Detector window refractive index.
std::vector< uint32_t > m_DetectorMask
Detector Mask of inactive channels.
double m_ColEffi
collection efficiency
bool m_simple
True if parametrization initialized with simple geometry (beamtest)
int m_nRad
Number of aerogel layers.
double m_mirrorZPos
Z position of mirror plates (starting z)
std::vector< double > m_fDFi
angle covered by one detector module in ring
double m_chipNegativeCrosstalk
to simulate opposite polarity crosstalk among channels on chip
double m_QE[MAXPTS_QE]
quantum efficiency curve
std::unordered_set< unsigned int > m_copperIDs
COPPER ID's.
double m_aeroRefIndex[MAX_N_ALAYERS]
Array of aerogel refracive indices.
std::vector< double > m_fFi
angular coordinate of detector modules
std::map< int, ROOT::Math::XYVector > m_padLocPositions
map holding channel local positions (in detector module local coordinates)
double m_windowAbsorbtion
absorbtion probability for photons internally reflected in HAPD window
std::map< std::pair< unsigned, int >, unsigned > m_copper2merger
mapping of merger boards to cooper boards
bool m_init
True if parametrization is already initialized.
int m_nPadX
Number of detector module pads in one direction.
int m_nPads
total number of pads in a sensor
std::vector< ROOT::Math::XYZVector > m_mirrorpoint
vector holding one point of each mirror plate
std::vector< ROOT::Math::XYVector > m_padWorldPositions
map holding channel global positions
std::vector< uint8_t > m_ChannelQE
Channel QE at 400nm.
std::vector< double > m_fFiMod
angle of detector module
double m_mirrorStartAng
The angle of first corner of mirror plates polygon.
double m_aeroThickness[MAX_N_ALAYERS]
Array of aerogel thickness.
int m_nMirrors
Number of mirrors segments.
std::map< int, std::vector< unsigned > > m_merger2feb
mapping of front-end boards to mergers
std::vector< int > m_ncol
m_ncol[i] gives number of detector modules in i-th detector ring (first one is the outer most)
int m_tileNr
Number of aerogel tiles in radial direction.
double m_mirrorThickness
Thickness of mirror plates.
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
static const double mm
[millimeters]
Definition: Unit.h:70
static const double rad
Standard of [angle].
Definition: Unit.h:50
static const double nm
[nanometers]
Definition: Unit.h:72
static const double cm
Standard units with the value = 1.
Definition: Unit.h:47
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
ROOT::Math::XYVector getChipLocPos(int chipID)
get center position of chipID-th chip of detector module (in detector module local coordinates)
int getMergerFromCooper(int cooperID, int finesse)
returns merger board ID from cooperID and finesse
void setAeroTransLength(int ilayer, double trlen)
set transmission length of "ilayer" aerogel layer
int getBoardFromMerger(int mergerID, int slot)
returns front-end board ID from merger ID and slot
ROOT::Math::XYZVector getOrigin(int copyno)
get the position of copyno-th HAPD module origin
void mirrorPositions(const GearDir &content)
calculates parameters of all mirror planes (normal vector and point on plane)
int getChannelID(ROOT::Math::XYVector hit)
get ID number of channel containing point "hit" (hit is in detector module local coordinates)
void setAerogelThickness(int ilayer, double thick)
set thickness of "ilayer" aerogel layer
void modulesPositionSimple(const GearDir &content)
gets modules positions directly from xml file (for simple "beamtest" geometry).
void frontEndMapping(const GearDir &content)
reads front-end board to merger to cooper mapping from an xml file
void padPositions()
calculates the centers of channels in local (detector module) and global coordinates
int getNBoardsOnMerger(int mergerID)
returns number of front-end boards connected to the merger
void Initialize(const GearDir &content)
calculates detector parameters needed for geometry build and reconstruction.
void setAerogelZPosition(int ilayer, double zPos)
set z position of "ilayer" aerogel layer
void read(const GearDir &content)
gets geometry parameters from gearbox.
void Print(void) const
Print some debug information.
void mirrorPositionSimple(const GearDir &content)
Gets mirrors positions directly from xml file (in case of simple "beamtest" geometry).
static ARICHGeometryPar * Instance()
Static method to get a reference to the ARICHGeometryPar instance.
void setAeroRefIndex(int ilayer, double n)
set refractive index of "ilayer" aerogel layer
virtual ~ARICHGeometryPar()
Destructor.
double getModAngle(int copyno)
get the angle of copyno-th HAPD rotation
static ARICHGeometryPar * p_B4ARICHGeometryParDB
Pointer that saves the instance of this class.
G4ThreeVector getOriginG4(int copyNo)
get the position of copyNo-th HAPD module origin (returns G4ThreeVector)
void readMirrorAlignment(const GearDir &content)
Reads mirror plates alignment parameters.
int getNMCopies() const
get the total number of HAPD modules
ROOT::Math::XYZVector getMirrorNormal(int mirID)
get normal vector of mirID-th mirror plate
void setActive(int module, int channel, bool val)
set the channel on/off
void initDetectorMask(int nmodules)
initialize detector mask
int getChipID(ROOT::Math::XYVector locpos)
get ID number of chip containing point "locpos"
void setWindowRefIndex(double refInd)
set detector module window refractive index
void chipLocPosition()
calculates the centers of chips in detector module local coordinates
void readModuleInfo(const GearDir &content)
read parameters of each module from gearbox.
bool isActive(int module, int channel)
check the activity of the channel
double getChannelQE(int moduleID, int channelID)
get channel quantum efficiency
double QE(double e) const
get photocathode quantum efficiency at energy e.
int getAerogelTileID(ROOT::Math::XYVector locpos)
returns ID number of aerogel tile containing locpos (x-y) point.
int getCopyNo(const ROOT::Math::XYZVector &hit)
get the copy number of HAPD module containing point "hit"
ROOT::Math::XYZVector getChannelCenterGlob(int modID, int chanID)
get center of chanID channel of modID detector module (in global coordinates)
void modulesPosition(const GearDir &content)
calculates the positions of HAPD modules, with the parameters from xml.
ROOT::Math::XYVector getChannelCenterLoc(int chID)
get center position of chID channel (in detector module local coordinates)
ROOT::Math::XYZVector getMirrorPoint(int mirID)
get one point lying on mirID-th mirror plate
double sqrt(double a)
sqrt for double
Definition: beamHelpers.h:28
Abstract base class for different kinds of events.
STL namespace.