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