Belle II Software development
TOPGeometryPar.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 <top/geometry/TOPGeometryPar.h>
10
11#include <framework/gearbox/GearDir.h>
12#include <framework/logging/Logger.h>
13#include <framework/logging/LogSystem.h>
14#include <framework/geometry/BFieldManager.h>
15#include <geometry/Materials.h>
16#include <iostream>
17#include <TSpline.h>
18#include <algorithm>
19#include <set>
20#include <cmath>
21
22using namespace std;
23
24namespace Belle2 {
29
30 namespace TOP {
31
33 const double TOPGeometryPar::c_hc = 1239.84193; // [eV*nm]
34
36 {
37 if (m_geo) delete m_geo;
38 if (m_geoDB) delete m_geoDB;
39 s_instance = 0;
40 }
41
42
44 {
45 if (!s_instance) {
47 }
48 return s_instance;
49 }
50
51
53 {
54
55 m_fromDB = false;
56 m_valid = false;
57
58 if (m_geo) delete m_geo;
59 m_geo = createConfiguration(content);
60 if (!m_geo->isConsistent()) {
61 B2ERROR("TOPGeometryPar::createConfiguration: geometry not consistently defined");
62 return;
63 }
64
65 GearDir frontEndMapping(content, "FrontEndMapping");
66 m_frontEndMapper.initialize(frontEndMapping);
67 if (!m_frontEndMapper.isValid()) {
68 return;
69 }
70
71 GearDir channelMapping0(content, "ChannelMapping[@type='IRS3B']");
72 m_channelMapperIRS3B.initialize(channelMapping0);
73 if (!m_channelMapperIRS3B.isValid()) {
74 return;
75 }
76
77 GearDir channelMapping1(content, "ChannelMapping[@type='IRSX']");
78 m_channelMapperIRSX.initialize(channelMapping1);
79 if (!m_channelMapperIRSX.isValid()) {
80 return;
81 }
82 m_valid = true;
83
85
86 }
87
88
90 {
91 m_fromDB = true;
92 m_valid = false;
93
94 if (m_geoDB) delete m_geoDB;
96
97 if (!m_geoDB->isValid()) {
98 B2ERROR("TOPGeometry: no payload found in database");
99 return;
100 }
101 if ((*m_geoDB)->getWavelengthFilter().getName().empty()) {
102 m_oldPayload = true;
103 B2WARNING("TOPGeometry: obsolete payload revision (pixel independent PDE) - please, check global tags");
104 }
105 if ((*m_geoDB)->getTTSes().empty()) {
106 B2WARNING("TOPGeometry: obsolete payload revision (nominal TTS only) - please, check global tags");
107 }
108 if ((*m_geoDB)->arePDETuningFactorsEmpty()) {
109 B2WARNING("TOPGeometry: obsolete payload revision (before bugfix and update of optical properties) - please, check global tags");
110 }
111
112 // Make sure that we abort as soon as the geometry changes
113 m_geoDB->addCallback([]() {
114 B2FATAL("Geometry cannot change during processing, "
115 "aborting (component TOP)");
116 });
117
118 m_frontEndMapper.initialize();
119 if (!m_frontEndMapper.isValid()) {
120 B2ERROR("TOPFrontEndMaps: no payload found in database");
121 return;
122 }
123
124 m_channelMapperIRSX.initialize();
125 if (!m_channelMapperIRSX.isValid()) {
126 B2ERROR("TOPChannelMaps: no payload found in database");
127 return;
128 }
129 m_valid = true;
130
132
133 }
134
136 {
137 // set B field flag
138 m_BfieldOn = (BFieldManager::getField(0, 0, 0).R() / Unit::T) > 0.1;
139
140 // add call backs for PMT data
141 m_pmtInstalled.addCallback(this, &TOPGeometryPar::clearCache);
142 m_pmtQEData.addCallback(this, &TOPGeometryPar::clearCache);
143 m_pulseHeights.addCallback(this, &TOPGeometryPar::clearCache);
144
145 // print geometry if the debug level for 'top' is set 10000
146 const auto& logSystem = LogSystem::Instance();
147 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 10000, "top")) {
148 getGeometry()->print();
149 if (m_oldPayload) {
150 cout << "Envelope QE same as nominal quantum efficiency" << endl << endl;
151 return;
152 }
153 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
154 m_envelopeQE.print("Envelope QE");
155 }
156 }
157
159 {
160 m_envelopeQE.clear();
161 m_pmts.clear();
162 m_relEfficiencies.clear();
163 m_relPDEonMC.clear();
164 m_pmtTypes.clear();
165 }
166
168 {
169 if (!m_valid) B2FATAL("No geometry available for TOP");
170
172 if (m_fromDB) {
173 return &(**m_geoDB);
174 } else {
175 return m_geo;
176 }
177 }
178
180 {
181 double lambda = c_hc / energy;
182
183 if (m_oldPayload) { // filter transmittance is included in nominal QE, return it!
184 return getGeometry()->getNominalQE().getEfficiency(lambda);
185 }
186
187 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
188 return m_envelopeQE.getEfficiency(lambda);
189 }
190
192 int moduleID, int pmtID,
193 double x, double y) const
194 {
195 const auto* geo = getGeometry();
196 if (!geo->isModuleIDValid(moduleID)) return 0;
197
198 double lambda = c_hc / energy;
199
200 if (m_oldPayload) { // filter transmittance is included in nominal QE, return it!
201 return geo->getNominalQE().getEfficiency(lambda);
202 }
203
204 if (m_pmts.empty()) mapPmtQEToPositions();
205
206 int id = getUniquePmtID(moduleID, pmtID);
207 const auto* pmtQE = m_pmts[id];
208 if (!pmtQE) return 0;
209
210 const auto& pmtArray = geo->getModule(moduleID).getPMTArray();
211 auto pmtPixel = pmtArray.getPMT().getPixelID(x, y);
212 if (pmtPixel == 0) return 0;
213
214 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
215 auto channel = getChannelMapper().getChannel(pixelID);
216
217 double RQE = geo->getPDETuningFactor(getPMTType(moduleID, pmtID));
218 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
219
220 return pmtQE->getEfficiency(pmtPixel, lambda, m_BfieldOn) * RQE;
221
222 }
223
224
225 double TOPGeometryPar::getRelativePixelEfficiency(int moduleID, int pixelID) const
226 {
227
228 auto channel = getChannelMapper().getChannel(pixelID);
229 auto pmtID = getChannelMapper().getPmtID(pixelID);
230
231 double RQE = getGeometry()->getPDETuningFactor(getPMTType(moduleID, pmtID));
232 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
233
234 double thrEffi = 1.0;
235 if (m_thresholdEff.isValid()) thrEffi = m_thresholdEff->getThrEff(moduleID, channel);
236
237 if (m_oldPayload) { // nominal QE is used
238 return RQE * thrEffi;
239 }
240
242
243 int id = getUniquePixelID(moduleID, pixelID);
244 return m_relEfficiencies[id] * RQE * thrEffi;
245 }
246
247
248 double TOPGeometryPar::getRelativePDEonMC(int moduleID, int pixelID) const
249 {
250 if (m_oldPayload) {
251 B2ERROR("TOPGeometryPar::getRelativePDEonMC: called using obsolete TOPGeometry payload revision - please, check global tags");
252 return 0; // to prevent wrong RQE calibration - see TOPPhotonYieldsAlgorithm.cc
253 }
254
255 if (m_relPDEonMC.empty()) prepareRelPDEonMC();
256
257 int id = getUniquePixelID(moduleID, pixelID);
258 return m_relPDEonMC[id];
259 }
260
261
262 unsigned TOPGeometryPar::getPMTType(int moduleID, int pmtID) const
263 {
264 if (m_pmtTypes.empty()) mapPmtTypeToPositions();
265
266 int id = getUniquePmtID(moduleID, pmtID);
267 return m_pmtTypes[id];
268 }
269
270
271 const TOPNominalTTS& TOPGeometryPar::getTTS(int moduleID, int pmtID) const
272 {
273 auto pmtType = getPMTType(moduleID, pmtID);
274 return getGeometry()->getTTS(pmtType);
275 }
276
277
279 {
280 if (m_pmtQEData.getEntries() == 0) {
281 B2ERROR("DBArray TOPPmtQEs is empty");
282 return;
283 }
284
285 double lambdaFirst = 0;
286 for (const auto& pmt : m_pmtQEData) {
287 if (pmt.getLambdaFirst() > 0) {
288 lambdaFirst = pmt.getLambdaFirst();
289 break;
290 }
291 }
292 if (lambdaFirst == 0) {
293 B2ERROR("DBArray TOPPmtQEs: lambdaFirst of all PMT found to be less or equal 0");
294 return;
295 }
296 for (const auto& pmt : m_pmtQEData) {
297 if (pmt.getLambdaFirst() > 0) {
298 lambdaFirst = std::min(lambdaFirst, pmt.getLambdaFirst());
299 }
300 }
301
302 double lambdaStep = 0;
303 for (const auto& pmt : m_pmtQEData) {
304 if (pmt.getLambdaStep() > 0) {
305 lambdaStep = pmt.getLambdaStep();
306 break;
307 }
308 }
309 if (lambdaStep == 0) {
310 B2ERROR("DBArray TOPPmtQEs: lambdaStep of all PMT found to be less or equal 0");
311 return;
312 }
313 for (const auto& pmt : m_pmtQEData) {
314 if (pmt.getLambdaStep() > 0) {
315 lambdaStep = std::min(lambdaStep, pmt.getLambdaStep());
316 }
317 }
318
319 std::map<std::string, const TOPPmtInstallation*> map;
320 for (const auto& pmt : m_pmtInstalled) {
321 map[pmt.getSerialNumber()] = &pmt;
322 }
323 const auto* geo = getGeometry();
324
325 std::vector<float> envelopeQE;
326 for (const auto& pmt : m_pmtQEData) {
327 float ce = pmt.getCE(m_BfieldOn);
328 auto pmtInstalled = map[pmt.getSerialNumber()];
329 if (pmtInstalled) ce *= geo->getPDETuningFactor(pmtInstalled->getType());
330 if (pmt.getLambdaFirst() == lambdaFirst and pmt.getLambdaStep() == lambdaStep) {
331 const auto& envelope = pmt.getEnvelopeQE();
332 if (envelopeQE.size() < envelope.size()) {
333 envelopeQE.resize(envelope.size() - envelopeQE.size(), 0);
334 }
335 for (size_t i = 0; i < std::min(envelopeQE.size(), envelope.size()); i++) {
336 envelopeQE[i] = std::max(envelopeQE[i], envelope[i] * ce);
337 }
338 } else {
339 double lambdaLast = pmt.getLambdaLast();
340 int nExtra = (lambdaLast - lambdaFirst) / lambdaStep + 1 - envelopeQE.size();
341 if (nExtra > 0) envelopeQE.resize(nExtra, 0);
342 for (size_t i = 0; i < envelopeQE.size(); i++) {
343 float qe = pmt.getEnvelopeQE(lambdaFirst + lambdaStep * i);
344 envelopeQE[i] = std::max(envelopeQE[i], qe * ce);
345 }
346 }
347 }
348
349 m_envelopeQE.set(lambdaFirst, lambdaStep, 1.0, envelopeQE, "EnvelopeQE");
350
351 B2INFO("TOPGeometryPar: envelope of PMT dependent QE has been set");
352
353 }
354
355
357 {
358 m_pmts.clear();
359
360 std::map<std::string, const TOPPmtQE*> map;
361 for (const auto& pmt : m_pmtQEData) {
362 map[pmt.getSerialNumber()] = &pmt;
363 }
364 for (const auto& pmt : m_pmtInstalled) {
365 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
366 m_pmts[id] = map[pmt.getSerialNumber()];
367 }
368
369 B2INFO("TOPGeometryPar: QE of PMT's mapped to positions, size = " << m_pmts.size());
370 }
371
372
374 {
375 for (const auto& pmt : m_pmtInstalled) {
376 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
377 m_pmtTypes[id] = pmt.getType();
378 }
379
380 B2INFO("TOPGeometryPar: PMT types mapped to positions, size = "
381 << m_pmtTypes.size());
382
383
384 std::set<unsigned> types;
385 for (const auto& pmt : m_pmtInstalled) {
386 types.insert(pmt.getType());
387 }
388 const auto* geo = getGeometry();
389 for (const auto& type : types) {
390 if (geo->getTTS(type).getPMTType() != type) {
391 B2WARNING("No TTS found for an installed PMT type. Nominal one will be used."
392 << LogVar("PMT type", type));
393 }
394 }
395
396 }
397
398
400 {
401 m_relEfficiencies.clear();
402 if (m_pmts.empty()) mapPmtQEToPositions();
403
404 const auto* geo = getGeometry();
405
406 const auto& nominalQE = geo->getNominalQE();
407 double s0 = integralOfQE(nominalQE.getQE(), nominalQE.getCE(),
408 nominalQE.getLambdaFirst(), nominalQE.getLambdaStep());
409
410 for (const auto& module : geo->getModules()) {
411 auto moduleID = module.getModuleID();
412 const auto& pmtArray = module.getPMTArray();
413 int numPMTs = pmtArray.getSize();
414 int numPMTPixels = pmtArray.getPMT().getNumPixels();
415 for (int pmtID = 1; pmtID <= numPMTs; pmtID++) {
416 const auto* pmtQE = m_pmts[getUniquePmtID(moduleID, pmtID)];
417 for (int pmtPixel = 1; pmtPixel <= numPMTPixels; pmtPixel++) {
418 double s = 0;
419 if (pmtQE) {
420 s = integralOfQE(pmtQE->getQE(pmtPixel), pmtQE->getCE(m_BfieldOn),
421 pmtQE->getLambdaFirst(), pmtQE->getLambdaStep());
422 }
423 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
424 auto id = getUniquePixelID(moduleID, pixelID);
425 m_relEfficiencies[id] = s / s0;
426 }
427 }
428 }
429
430 B2INFO("TOPGeometryPar: pixel relative quantum efficiencies have been set, size = "
431 << m_relEfficiencies.size());
432 }
433
435 {
436 m_relPDEonMC.clear();
438
439 const auto* geo = getGeometry();
440
441 for (const auto& module : geo->getModules()) {
442 auto moduleID = module.getModuleID();
443 const auto& pmtArray = module.getPMTArray();
444 int numPMTs = pmtArray.getSize();
445 int numPMTPixels = pmtArray.getPMT().getNumPixels();
446 for (int pmtID = 1; pmtID <= numPMTs; pmtID++) {
447 double tuneFactor = getGeometry()->getPDETuningFactor(getPMTType(moduleID, pmtID));
448 for (int pmtPixel = 1; pmtPixel <= numPMTPixels; pmtPixel++) {
449 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
450 auto channel = getChannelMapper().getChannel(pixelID);
451 double thrEffi = 0.973; //TODO(rel-10) get rid of hard coding
452 if (m_pulseHeights->isCalibrated(moduleID, channel)) {
453 thrEffi = m_pulseHeights->getParameters(moduleID, channel).getThresholdEffi(40, 9.7); //TODO(rel-10) get rid of hard coding
454 }
455 int id = getUniquePixelID(moduleID, pixelID);
456 m_relPDEonMC[id] = m_relEfficiencies[id] * tuneFactor * thrEffi;
457 }
458 }
459 }
460
461 B2INFO("TOPGeometryPar: pixel relative PDE on MC have been set, size = " << m_relPDEonMC.size());
462 }
463
464 double TOPGeometryPar::integralOfQE(const std::vector<float>& qe, double ce,
465 double lambdaFirst, double lambdaStep) const
466 {
467 if (qe.empty()) return 0;
468
469 const auto* geo = getGeometry();
470 const auto& filter = geo->getWavelengthFilter();
471
472 double s = 0;
473 double lambda = lambdaFirst;
474 double f1 = qe[0] * filter.getBulkTransmittance(lambda) / (lambda * lambda);
475 for (size_t i = 1; i < qe.size(); i++) {
476 lambda += lambdaStep;
477 double f2 = qe[i] * filter.getBulkTransmittance(lambda) / (lambda * lambda);
478 s += (f1 + f2) / 2;
479 f1 = f2;
480 }
481 return s * c_hc * lambdaStep * ce;
482 }
483
484
486 {
487 TOPGeometry* geo = new TOPGeometry("TOPGeometry");
488
489 // PMT array
490
491 GearDir pmtParams(content, "PMTs/PMT");
492 TOPGeoPMT pmt(pmtParams.getLength("ModuleXSize"),
493 pmtParams.getLength("ModuleYSize"),
494 pmtParams.getLength("ModuleZSize") +
495 pmtParams.getLength("WindowThickness") +
496 pmtParams.getLength("BottomThickness"));
497 pmt.setWallThickness(pmtParams.getLength("ModuleWall"));
498 pmt.setWallMaterial(pmtParams.getString("wallMaterial"));
499 pmt.setFillMaterial(pmtParams.getString("fillMaterial"));
500 pmt.setSensVolume(pmtParams.getLength("SensXSize"),
501 pmtParams.getLength("SensYSize"),
502 pmtParams.getLength("SensThickness"),
503 pmtParams.getString("sensMaterial"));
504 pmt.setNumPixels(pmtParams.getInt("PadXNum"),
505 pmtParams.getInt("PadYNum"));
506 pmt.setWindow(pmtParams.getLength("WindowThickness"),
507 pmtParams.getString("winMaterial"));
508 pmt.setBottom(pmtParams.getLength("BottomThickness"),
509 pmtParams.getString("botMaterial"));
510
511 auto& materials = geometry::Materials::getInstance();
512 GearDir reflEdgeSurfParams(pmtParams, "reflectiveEdge/Surface");
513 pmt.setReflEdge(pmtParams.getLength("reflectiveEdge/width"),
514 pmtParams.getLength("reflectiveEdge/thickness"),
515 materials.createOpticalSurfaceConfig(reflEdgeSurfParams));
516
517 GearDir arrayParams(content, "PMTs");
518 TOPGeoPMTArray pmtArray(arrayParams.getInt("nPMTx"),
519 arrayParams.getInt("nPMTy"),
520 arrayParams.getLength("Xgap"),
521 arrayParams.getLength("Ygap"),
522 arrayParams.getString("stackMaterial"),
523 pmt);
524 pmtArray.setSiliconeCookie(arrayParams.getLength("siliconeCookie/thickness"),
525 arrayParams.getString("siliconeCookie/material"));
526 pmtArray.setWavelengthFilter(arrayParams.getLength("wavelengthFilter/thickness"),
527 arrayParams.getString("wavelengthFilter/material"));
528 pmtArray.setAirGap(arrayParams.getLength("airGap", 0));
529 double decoupledFraction = arrayParams.getDouble("decoupledFraction", 0);
530
531 // modules
532
533 GearDir moduleParams(content, "Modules");
534 GearDir glueParams(moduleParams, "Glue");
535 int numModules = moduleParams.getNumberNodes("Module");
536 for (int slotID = 1; slotID <= numModules; slotID++) {
537 std::string gearName = "Module[@slotID='" + std::to_string(slotID) + "']";
538 GearDir slotParams(moduleParams, gearName);
539 TOPGeoModule module(slotID,
540 slotParams.getLength("Radius"),
541 slotParams.getAngle("Phi"),
542 slotParams.getLength("BackwardZ"));
543 int cNumber = slotParams.getInt("ConstructionNumber");
544 module.setModuleCNumber(cNumber);
545 module.setName(addNumber(module.getName(), cNumber));
546
547 auto prism = createPrism(content, slotParams.getString("Prism"));
548 prism.setName(addNumber(prism.getName(), cNumber));
549 module.setPrism(prism);
550
551 auto barSegment2 = createBarSegment(content, slotParams.getString("BarSegment2"));
552 barSegment2.setName(addNumber(barSegment2.getName() + "2-", cNumber));
553 barSegment2.setGlue(glueParams.getLength("Thicknes1"),
554 glueParams.getString("GlueMaterial"));
555 module.setBarSegment2(barSegment2);
556
557 auto barSegment1 = createBarSegment(content, slotParams.getString("BarSegment1"));
558 barSegment1.setName(addNumber(barSegment1.getName() + "1-", cNumber));
559 barSegment1.setGlue(glueParams.getLength("Thicknes2"),
560 glueParams.getString("GlueMaterial"));
561 module.setBarSegment1(barSegment1);
562
563 auto mirror = createMirrorSegment(content, slotParams.getString("Mirror"));
564 mirror.setName(addNumber(mirror.getName(), cNumber));
565 mirror.setGlue(glueParams.getLength("Thicknes3"),
566 glueParams.getString("GlueMaterial"));
567 module.setMirrorSegment(mirror);
568
569 module.setPMTArray(pmtArray);
570 if (decoupledFraction > 0) module.generateDecoupledPMTs(decoupledFraction);
571
572 geo->appendModule(module);
573 }
574
575 // displaced geometry (if defined)
576
577 GearDir displacedGeometry(content, "DisplacedGeometry");
578 if (displacedGeometry) {
579 if (displacedGeometry.getInt("SwitchON") != 0) {
580 B2WARNING("TOP: displaced geometry is activated");
581 for (const GearDir& slot : displacedGeometry.getNodes("Slot")) {
582 int moduleID = slot.getInt("@ID");
583 if (!geo->isModuleIDValid(moduleID)) {
584 B2WARNING("TOPGeometryPar: DisplacedGeometry.xml: invalid moduleID."
585 << LogVar("moduleID", moduleID));
586 continue;
587 }
588 TOPGeoModuleDisplacement moduleDispl(slot.getLength("x"),
589 slot.getLength("y"),
590 slot.getLength("z"),
591 slot.getAngle("alpha"),
592 slot.getAngle("beta"),
593 slot.getAngle("gamma"));
594 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
595 module.setModuleDisplacement(moduleDispl);
596 }
597 }
598 }
599
600 // displaced PMT arrays (if defined)
601
602 GearDir displacedPMTArrays(content, "DisplacedPMTArrays");
603 if (displacedPMTArrays) {
604 if (displacedPMTArrays.getInt("SwitchON") != 0) {
605 B2WARNING("TOP: displaced PMT arrays are activated");
606 for (const GearDir& slot : displacedPMTArrays.getNodes("Slot")) {
607 int moduleID = slot.getInt("@ID");
608 if (!geo->isModuleIDValid(moduleID)) {
609 B2WARNING("TOPGeometryPar: DisplacedPMTArrays.xml: invalid moduleID."
610 << LogVar("moduleID", moduleID));
611 continue;
612 }
613 TOPGeoPMTArrayDisplacement arrayDispl(slot.getLength("x"),
614 slot.getLength("y"),
615 slot.getAngle("alpha"));
616 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
617 module.setPMTArrayDisplacement(arrayDispl);
618 }
619 }
620 }
621
622 // broken glues (if any)
623
624 GearDir brokenGlues(content, "BrokenGlues");
625 if (brokenGlues) {
626 if (brokenGlues.getInt("SwitchON") != 0) {
627 auto material = brokenGlues.getString("material");
628 for (const GearDir& slot : brokenGlues.getNodes("Slot")) {
629 int moduleID = slot.getInt("@ID");
630 if (!geo->isModuleIDValid(moduleID)) {
631 B2WARNING("TOPGeometryPar: BrokenGlues.xml: invalid moduleID."
632 << LogVar("moduleID", moduleID));
633 continue;
634 }
635 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
636 for (const GearDir& glue : slot.getNodes("Glue")) {
637 int glueID = glue.getInt("@ID");
638 double fraction = glue.getDouble("fraction");
639 if (fraction <= 0) continue;
640 double angle = glue.getAngle("angle");
641 module.setBrokenGlue(glueID, fraction, angle, material);
642 }
643 }
644 }
645 }
646
647 // peel-off cookies (if any)
648
649 GearDir peelOff(content, "PeelOffCookies");
650 if (peelOff) {
651 if (peelOff.getInt("SwitchON") != 0) {
652 auto material = peelOff.getString("material");
653 double thickness = peelOff.getLength("thickness");
654 for (const GearDir& slot : peelOff.getNodes("Slot")) {
655 int moduleID = slot.getInt("@ID");
656 if (!geo->isModuleIDValid(moduleID)) {
657 B2WARNING("TOPGeometryPar: PeelOffCookiess.xml: invalid moduleID."
658 << LogVar("moduleID", moduleID));
659 continue;
660 }
661 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
662 module.setPeelOffRegions(thickness, material);
663 for (const GearDir& region : slot.getNodes("Region")) {
664 int regionID = region.getInt("@ID");
665 double fraction = region.getDouble("fraction");
666 if (fraction <= 0) continue;
667 double angle = region.getAngle("angle");
668 module.appendPeelOffRegion(regionID, fraction, angle);
669 }
670 }
671 }
672 }
673
674 // front-end electronics geometry
675
676 GearDir feParams(content, "FrontEndGeo");
677 GearDir fbParams(feParams, "FrontBoard");
678 TOPGeoFrontEnd frontEnd;
679 frontEnd.setFrontBoard(fbParams.getLength("width"),
680 fbParams.getLength("height"),
681 fbParams.getLength("thickness"),
682 fbParams.getLength("gap"),
683 fbParams.getLength("y"),
684 fbParams.getString("material"));
685 GearDir hvParams(feParams, "HVBoard");
686 frontEnd.setHVBoard(hvParams.getLength("width"),
687 hvParams.getLength("length"),
688 hvParams.getLength("thickness"),
689 hvParams.getLength("gap"),
690 hvParams.getLength("y"),
691 hvParams.getString("material"));
692 GearDir bsParams(feParams, "BoardStack");
693 frontEnd.setBoardStack(bsParams.getLength("width"),
694 bsParams.getLength("height"),
695 bsParams.getLength("length"),
696 bsParams.getLength("gap"),
697 bsParams.getLength("y"),
698 bsParams.getString("material"),
699 bsParams.getLength("spacerWidth"),
700 bsParams.getString("spacerMaterial"));
701 geo->setFrontEnd(frontEnd, feParams.getInt("numBoardStacks"));
702
703 // QBB
704
705 GearDir qbbParams(content, "QBB");
706 TOPGeoQBB qbb(qbbParams.getLength("width"),
707 qbbParams.getLength("length"),
708 qbbParams.getLength("prismPosition"),
709 qbbParams.getString("material"));
710
711 GearDir outerPanelParams(qbbParams, "outerPanel");
712 TOPGeoHoneycombPanel outerPanel(outerPanelParams.getLength("width"),
713 outerPanelParams.getLength("length"),
714 outerPanelParams.getLength("minThickness"),
715 outerPanelParams.getLength("maxThickness"),
716 outerPanelParams.getLength("radius"),
717 outerPanelParams.getLength("edgeWidth"),
718 outerPanelParams.getLength("y"),
719 outerPanelParams.getInt("N"),
720 outerPanelParams.getString("material"),
721 outerPanelParams.getString("edgeMaterial"),
722 "TOPOuterHoneycombPanel");
723 qbb.setOuterPanel(outerPanel);
724
725 GearDir innerPanelParams(qbbParams, "innerPanel");
726 TOPGeoHoneycombPanel innerPanel(innerPanelParams.getLength("width"),
727 innerPanelParams.getLength("length"),
728 innerPanelParams.getLength("minThickness"),
729 innerPanelParams.getLength("maxThickness"),
730 innerPanelParams.getLength("radius"),
731 innerPanelParams.getLength("edgeWidth"),
732 innerPanelParams.getLength("y"),
733 innerPanelParams.getInt("N"),
734 innerPanelParams.getString("material"),
735 innerPanelParams.getString("edgeMaterial"),
736 "TOPInnerHoneycombPanel");
737 qbb.setInnerPanel(innerPanel);
738
739 GearDir sideRailsParams(qbbParams, "sideRails");
740 TOPGeoSideRails sideRails(sideRailsParams.getLength("thickness"),
741 sideRailsParams.getLength("reducedThickness"),
742 sideRailsParams.getLength("height"),
743 sideRailsParams.getString("material"));
744 qbb.setSideRails(sideRails);
745
746 GearDir prismEnclParams(qbbParams, "prismEnclosure");
747 TOPGeoPrismEnclosure prismEncl(prismEnclParams.getLength("length"),
748 prismEnclParams.getLength("height"),
749 prismEnclParams.getAngle("angle"),
750 prismEnclParams.getLength("bottomThickness"),
751 prismEnclParams.getLength("sideThickness"),
752 prismEnclParams.getLength("backThickness"),
753 prismEnclParams.getLength("frontThickness"),
754 prismEnclParams.getLength("extensionThickness"),
755 prismEnclParams.getString("material"));
756 qbb.setPrismEnclosure(prismEncl);
757
758 GearDir endPlateParams(qbbParams, "forwardEndPlate");
759 TOPGeoEndPlate endPlate(endPlateParams.getLength("thickness"),
760 endPlateParams.getLength("height"),
761 endPlateParams.getString("material"),
762 "TOPForwardEndPlate");
763 qbb.setEndPlate(endPlate);
764
765 GearDir coldPlateParams(qbbParams, "coldPlate");
766 TOPGeoColdPlate coldPlate(coldPlateParams.getLength("baseThickness"),
767 coldPlateParams.getString("baseMaterial"),
768 coldPlateParams.getLength("coolThickness"),
769 coldPlateParams.getLength("coolWidth"),
770 coldPlateParams.getString("coolMaterial"));
771 qbb.setColdPlate(coldPlate);
772
773 geo->setQBB(qbb);
774
775 // nominal QE
776
777 GearDir qeParams(content, "QE");
778 std::vector<float> qeData;
779 for (const GearDir& Qeffi : qeParams.getNodes("Qeffi")) {
780 qeData.push_back(Qeffi.getDouble(""));
781 }
782 TOPNominalQE nominalQE(qeParams.getLength("LambdaFirst") / Unit::nm,
783 qeParams.getLength("LambdaStep") / Unit::nm,
784 qeParams.getDouble("ColEffi"),
785 qeData);
786 geo->setNominalQE(nominalQE);
787
788 // nominal TTS
789
790 GearDir ttsParams(content, "PMTs/TTS");
791 TOPNominalTTS nominalTTS("TOPNominalTTS");
792 for (const GearDir& Gauss : ttsParams.getNodes("Gauss")) {
793 nominalTTS.appendGaussian(Gauss.getDouble("fraction"),
794 Gauss.getTime("mean"),
795 Gauss.getTime("sigma"));
796 }
797 nominalTTS.normalize();
798 geo->setNominalTTS(nominalTTS);
799
800 // PMT type dependent TTS
801
802 GearDir pmtTTSParams(content, "TTSofPMTs");
803 for (const GearDir& ttsPar : pmtTTSParams.getNodes("TTSpar")) {
804 int type = ttsPar.getInt("type");
805 double tuneFactor = ttsPar.getDouble("PDEtuneFactor");
806 TOPNominalTTS tts("TTS of " + ttsPar.getString("@name") + " PMT");
807 tts.setPMTType(type);
808 for (const GearDir& Gauss : ttsPar.getNodes("Gauss")) {
809 tts.appendGaussian(Gauss.getDouble("fraction"),
810 Gauss.getTime("mean"),
811 Gauss.getTime("sigma"));
812 }
813 tts.normalize();
814 geo->appendTTS(tts);
815 geo->appendPDETuningFactor(type, tuneFactor);
816 }
817
818 // nominal TDC
819
820 GearDir tdcParams(content, "TDC");
821 if (tdcParams) {
822 TOPNominalTDC nominalTDC(tdcParams.getInt("numWindows"),
823 tdcParams.getInt("subBits"),
824 tdcParams.getTime("syncTimeBase"),
825 tdcParams.getInt("numofBunches"),
826 tdcParams.getTime("offset"),
827 tdcParams.getTime("pileupTime"),
828 tdcParams.getTime("doubleHitResolution"),
829 tdcParams.getTime("timeJitter"),
830 tdcParams.getDouble("efficiency"));
831 nominalTDC.setADCBits(tdcParams.getInt("adcBits"));
832 nominalTDC.setAveragePedestal(tdcParams.getInt("averagePedestal"));
833 geo->setNominalTDC(nominalTDC);
834 } else {
835 TOPNominalTDC nominalTDC(pmtParams.getInt("TDCbits"),
836 pmtParams.getTime("TDCbitwidth"),
837 pmtParams.getTime("TDCoffset", 0),
838 pmtParams.getTime("TDCpileupTime", 0),
839 pmtParams.getTime("TDCdoubleHitResolution", 0),
840 pmtParams.getTime("TDCtimeJitter", 50e-3),
841 pmtParams.getDouble("TDCefficiency", 1));
842 geo->setNominalTDC(nominalTDC);
843 }
844
845 // single photon signal shape
846
847 GearDir shapeParams(content, "SignalShape");
848 if (shapeParams) {
849 GearDir noiseBandwidth(shapeParams, "noiseBandwidth");
850 TOPSignalShape signalShape(shapeParams.getArray("sampleValues"),
852 shapeParams.getTime("tailTimeConstant"),
853 noiseBandwidth.getDouble("pole1") / 1000,
854 noiseBandwidth.getDouble("pole2") / 1000);
855 geo->setSignalShape(signalShape);
856 }
857
858 // calibration pulse shape
859
860 GearDir calpulseParams(content, "CalPulseShape");
861 if (calpulseParams) {
862 GearDir noiseBandwidth(calpulseParams, "noiseBandwidth");
863 TOPSignalShape shape(calpulseParams.getArray("sampleValues"),
865 calpulseParams.getTime("tailTimeConstant"),
866 noiseBandwidth.getDouble("pole1") / 1000,
867 noiseBandwidth.getDouble("pole2") / 1000);
868 geo->setCalPulseShape(shape);
869 }
870
871 // wavelength filter bulk transmittance
872
873 std::string materialNode = "Materials/Material[@name='TOPWavelengthFilterIHU340']";
874 GearDir filterMaterial(content, materialNode);
875 if (!filterMaterial) {
876 B2FATAL("TOPGeometry: " << materialNode << " not found");
877 }
878 GearDir property(filterMaterial, "Property[@name='ABSLENGTH']");
879 if (!property) {
880 B2FATAL("TOPGeometry: " << materialNode << ", Property ABSLENGTH not found");
881 }
882 int numNodes = property.getNumberNodes("value");
883 if (numNodes > 1) {
884 double conversion = Unit::convertValue(1, property.getString("@unit", "GeV"));
885 std::vector<double> energies;
886 std::vector<double> absLengths;
887 for (int i = 0; i < numNodes; i++) {
888 GearDir value(property, "value", i + 1);
889 energies.push_back(value.getDouble("@energy") * conversion / Unit::eV);// [eV]
890 absLengths.push_back(value.getDouble() * Unit::mm); // [cm]
891 }
892 TSpline3 spline("absLen", energies.data(), absLengths.data(), energies.size());
893 double lambdaFirst = c_hc / energies.back();
894 double lambdaLast = c_hc / energies[0];
895 double lambdaStep = 5; // [nm]
896 int numSteps = (lambdaLast - lambdaFirst) / lambdaStep + 1;
897 const double filterThickness = arrayParams.getLength("wavelengthFilter/thickness");
898 std::vector<float> bulkTransmittances;
899 for (int i = 0; i < numSteps; i++) {
900 double wavelength = lambdaFirst + lambdaStep * i;
901 double energy = c_hc / wavelength;
902 double absLen = spline.Eval(energy);
903 bulkTransmittances.push_back(exp(-filterThickness / absLen));
904 }
905 TOPWavelengthFilter filter(lambdaFirst, lambdaStep, bulkTransmittances);
907 } else {
908 B2FATAL("TOPGeometry: " << materialNode
909 << ", Property ABSLENGTH has less than 2 nodes");
910 }
911
912 return geo;
913 }
914
915
917 const std::string& SN)
918 {
919 // dimensions and material
920 GearDir params(content, "QuartzBars/QuartzBar[@SerialNumber='" + SN + "']");
921 TOPGeoBarSegment bar(params.getLength("Width"),
922 params.getLength("Thickness"),
923 params.getLength("Length"),
924 params.getString("Material"));
925 bar.setVendorData(params.getString("Vendor"), SN);
926
927 // optical surface
928 std::string surfaceName = params.getString("OpticalSurface");
929 double sigmaAlpha = params.getDouble("SigmaAlpha");
930 GearDir surfaceParams(content, "Modules/Surface[@name='" + surfaceName + "']");
931 auto& materials = geometry::Materials::getInstance();
932 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
933 bar.setSurface(quartzSurface, sigmaAlpha);
934
935 return bar;
936 }
937
938
940 const std::string& SN)
941 {
942 // dimensions and material
943 GearDir params(content, "Mirrors/Mirror[@SerialNumber='" + SN + "']");
944 TOPGeoMirrorSegment mirror(params.getLength("Width"),
945 params.getLength("Thickness"),
946 params.getLength("Length"),
947 params.getString("Material"));
948 mirror.setVendorData(params.getString("Vendor"), SN);
949 mirror.setRadius(params.getLength("Radius"));
950 mirror.setCenterOfCurvature(params.getLength("Xpos"), params.getLength("Ypos"));
951
952 // mirror reflective coating
953 auto& materials = geometry::Materials::getInstance();
954 GearDir coatingParams(params, "Surface");
955 mirror.setCoating(params.getLength("mirrorThickness"), "Al",
956 materials.createOpticalSurfaceConfig(coatingParams));
957
958 // optical surface
959 std::string surfaceName = params.getString("OpticalSurface");
960 double sigmaAlpha = params.getDouble("SigmaAlpha");
961 GearDir surfaceParams(content, "Modules/Surface[@name='" + surfaceName + "']");
962 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
963 mirror.setSurface(quartzSurface, sigmaAlpha);
964
965 return mirror;
966 }
967
968
970 const std::string& SN)
971 {
972 // dimensions and material
973 GearDir params(content, "Prisms/Prism[@SerialNumber='" + SN + "']");
974 TOPGeoPrism prism(params.getLength("Width"),
975 params.getLength("Thickness"),
976 params.getLength("Length"),
977 params.getLength("ExitThickness"),
978 0.,
979 params.getString("Material"));
980 prism.setAngle(params.getAngle("Angle"));
981 prism.setVendorData(params.getString("Vendor"), SN);
982
983 // optical surface
984 std::string surfaceName = params.getString("OpticalSurface");
985 double sigmaAlpha = params.getDouble("SigmaAlpha");
986 GearDir surfaceParams(content, "Modules/Surface[@name='" + surfaceName + "']");
987 auto& materials = geometry::Materials::getInstance();
988 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
989 prism.setSurface(quartzSurface, sigmaAlpha);
990
991 return prism;
992 }
993
994 std::string TOPGeometryPar::addNumber(const std::string& str, unsigned number)
995 {
996 stringstream ss;
997 if (number < 10) {
998 ss << str << "0" << number;
999 } else {
1000 ss << str << number;
1001 }
1002 string out;
1003 ss >> out;
1004 return out;
1005 }
1006
1007 double TOPGeometryPar::refractiveIndex(double lambda) const
1008 {
1009 // parameters of SellMeier equation (Matsuoka-san, 24.11.2018)
1010 // from the specs of Corning HPFS 7980
1011 // https://www.corning.com/media/worldwide/csm/documents/5bf092438c5546dfa9b08e423348317b.pdf
1012 const double b[] = {0.683740494, 0.420323613, 0.585027480};
1013 const double c[] = {0.00460352869, 0.0133968856, 64.4932732};
1014
1015 double x = pow(lambda * 0.001, 2);
1016 double y = 1;
1017 for (int i = 0; i < 3; i++) {
1018 y += b[i] * x / (x - c[i]);
1019 }
1020 return sqrt(y);
1021 }
1022
1023 double TOPGeometryPar::getPhaseIndex(double energy) const
1024 {
1025 double lambda = c_hc / energy;
1026 return refractiveIndex(lambda);
1027 }
1028
1029 double TOPGeometryPar::getGroupIndex(double energy) const
1030 {
1031 double lambda = c_hc / energy;
1032 double dl = 1.0; // [nm]
1033 double n = refractiveIndex(lambda);
1034 double dndl = (refractiveIndex(lambda + dl / 2) - refractiveIndex(lambda - dl / 2)) / dl;
1035 return n / (1 + lambda / n * dndl);
1036 }
1037
1038 } // End namespace TOP
1040} // End namespace Belle2
Class for accessing objects in the database.
Definition DBObjPtr.h:21
GearDir is the basic class used for accessing the parameter store.
Definition GearDir.h:31
virtual int getNumberNodes(const std::string &path="") const override
Return the number of nodes a given path will expand to.
Definition GearDir.h:58
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
Definition GearDir.h:69
@ c_Debug
Debug: for code development.
Definition LogConfig.h:26
static LogSystem & Instance()
Static method to get a reference to the LogSystem instance.
Definition LogSystem.cc:28
Geometry parameters of a quartz bar segment.
void setVendorData(const std::string &vendor, const std::string &serialNumber)
Sets vendor's name and serial number.
void setSurface(const GeoOpticalSurface &surface, double sigmaAlpha)
Sets optical surface.
Geometry parameters of cold plate (simplified)
Geometry parameters of forward end plate (simplified)
Geometry parameters of board stack (front-end electronic module)
void setBoardStack(double width, double height, double length, double gap, double y, const std::string &material, double spacerWidth, const std::string &spacerMaterial)
Sets board stack data.
void setHVBoard(double width, double length, double thickness, double gap, double y, const std::string &material)
Sets HV board data.
void setFrontBoard(double width, double height, double thickness, double gap, double y, const std::string &material)
Sets front board data.
Geometry parameters of honeycomb panel.
Geometry parameters of a mirror segment.
void setRadius(double radius)
Sets spherical mirror radius of curvature.
void setCenterOfCurvature(double xc, double yc)
Sets spherical mirror center of curvature.
void setCoating(double thickness, const std::string &material, const GeoOpticalSurface &surface)
Sets parameters of reflective coating.
Displacement parameters of a TOP module.
Geometry parameters of a module (optical components + positioning)
Displacement parameters of MCP-PMT array.
Geometry parameters of MCP-PMT array.
void setSiliconeCookie(double thickness, const std::string &material)
Sets silicone cookie.
void setWavelengthFilter(double thickness, const std::string &material)
Sets wavelength filter.
void setAirGap(double gap)
Sets air gap for optically decoupled PMT's.
Geometry parameters of MCP-PMT.
Definition TOPGeoPMT.h:24
void setBottom(double thickness, const std::string &material)
Sets bottom.
Definition TOPGeoPMT.h:106
void setWindow(double thickness, const std::string &material)
Sets entrance window.
Definition TOPGeoPMT.h:95
void setSensVolume(double sizeX, double sizeY, double thickness, const std::string &material)
Sets sensitive volume (photo-cathode)
Definition TOPGeoPMT.h:70
void setWallThickness(double thickness)
Sets wall thickness.
Definition TOPGeoPMT.h:49
void setWallMaterial(const std::string &material)
Sets casing material.
Definition TOPGeoPMT.h:55
void setNumPixels(unsigned numColumns, unsigned numRows)
Sets number of pixel rows and columns.
Definition TOPGeoPMT.h:84
void setFillMaterial(const std::string &material)
Sets inside material.
Definition TOPGeoPMT.h:61
void setReflEdge(double width, double thickness, const GeoOpticalSurface &surf)
Sets reflective edge.
Definition TOPGeoPMT.h:118
Geometry parameters of prism enclosure (simplified)
Geometry parameters of prism.
Definition TOPGeoPrism.h:27
void setAngle(double angle)
Recalculates flatLength according to given prism angle.
Definition TOPGeoPrism.h:93
Geometry parameters of Quartz Bar Box (mother class)
Definition TOPGeoQBB.h:30
void setOuterPanel(const TOPGeoHoneycombPanel &outerPanel)
Sets outer honeycomb panel.
Definition TOPGeoQBB.h:66
void setColdPlate(const TOPGeoColdPlate &coldPlate)
Sets forward cold plate.
Definition TOPGeoQBB.h:96
void setPrismEnclosure(const TOPGeoPrismEnclosure &prismEnclosure)
Sets prism enclosure.
Definition TOPGeoQBB.h:81
void setSideRails(const TOPGeoSideRails &sideRails)
Sets side rails.
Definition TOPGeoQBB.h:75
void setInnerPanel(const TOPGeoHoneycombPanel &innerPanel)
Sets inner honeycomb panel.
Definition TOPGeoQBB.h:57
void setEndPlate(const TOPGeoEndPlate &endPlate)
Sets forward end plate.
Definition TOPGeoQBB.h:90
Geometry parameters of side rails (simplified)
Geometry parameters of TOP.
Definition TOPGeometry.h:34
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
void setCalPulseShape(const TOPSignalShape &shape)
Sets calibration pulse shape.
void appendTTS(const TOPNominalTTS &tts)
Appends time transition spread of a particular PMT type.
Definition TOPGeometry.h:99
void setWavelengthFilter(const TOPWavelengthFilter &filter)
Sets wavelength filter transmittance.
void setNominalTDC(const TOPNominalTDC &nominalTDC)
Sets nominal time-to-digit conversion parameters.
void setQBB(const TOPGeoQBB &QBB)
Sets quartz bar box.
Definition TOPGeometry.h:81
void setFrontEnd(const TOPGeoFrontEnd &frontEnd, unsigned num=4)
Sets front-end.
Definition TOPGeometry.h:71
static void useBasf2Units()
Use basf2 units when returning geometry parameters.
Definition TOPGeometry.h:53
void setNominalQE(const TOPNominalQE &nominalQE)
Sets nominal quantum efficiency of PMT.
Definition TOPGeometry.h:87
void appendPDETuningFactor(unsigned type, double factor)
Appends photon detection efficiency tuning factor of a particular PMT type.
const TOPNominalQE & getNominalQE() const
Returns nominal quantum efficiency of PMT.
void setSignalShape(const TOPSignalShape &signalShape)
Sets single photon signal shape.
void setNominalTTS(const TOPNominalTTS &nominalTTS)
Sets nominal time transition spread of PMT.
Definition TOPGeometry.h:93
Nominal quantum efficiency of PMT.
double getEfficiency(double lambda) const
Returns quantum times collection efficiency at given photon wavelength using linear interpolation.
Nominal time-to-digit conversion parameters (simplified model)
double getSampleWidth() const
Returns time difference between two samples.
void setADCBits(unsigned adcBits)
Sets the number of ADC bits.
void setAveragePedestal(int averagePedestal)
Sets average of pedestals.
Nominal time transition spread of PMT.
void setPMTType(unsigned type)
Set type of PMT (see TOPPmtObsoleteData::EType for the defined types)
Normalized shape of single photon pulse (waveform) Pulse must be positive.
Bulk transmittance of wavelength filter.
int getPmtID(int pixel) const
Returns PMT ID (1-based)
unsigned getChannel(int pixel) const
Converts pixel to hardware channel number (0-based)
Singleton class for TOP Geometry Parameters.
double integralOfQE(const std::vector< float > &qe, double ce, double lambdaFirst, double lambdaStep) const
Returns integral of quantum efficiency over photon energies.
TOPGeoPrism createPrism(const GearDir &content, const std::string &serialNumber)
Create a parameter object from gearbox for prism.
virtual ~TOPGeometryPar()
Destructor.
OptionalDBArray< TOPPmtQE > m_pmtQEData
quantum efficiencies
double getRelativePixelEfficiency(int moduleID, int pixelID) const
Returns relative pixel efficiency (including CE, RQE and threshold efficiency)
bool m_BfieldOn
true if B field is on
double getPMTEfficiencyEnvelope(double energy) const
Returns PMT efficiency envelope, e.g.
bool m_fromDB
parameters from database or Gearbox
const TOPGeometry * getGeometry() const
Returns pointer to geometry object using basf2 units.
TOPGeoMirrorSegment createMirrorSegment(const GearDir &content, const std::string &serialNumber)
Create a parameter object from gearbox for mirror segment.
DBObjPtr< TOPGeometry > * m_geoDB
geometry parameters from database
unsigned getPMTType(int moduleID, int pmtID) const
Returns PMT type at a given position.
void finalizeInitialization()
finalize initialization
int getUniquePixelID(int moduleID, int pixelID) const
Returns unique pixel ID within the detector.
const ChannelMapper & getChannelMapper() const
Returns default channel mapper (mapping of channels to pixels)
void prepareRelEfficiencies() const
Prepares a map of relative pixel quantum times collection efficiencies (relative to nominal one)
double getPMTEfficiency(double energy, int moduleID, int pmtID, double x, double y) const
Returns PMT pixel efficiency, a product of quantum and collection efficiency.
TOPGeometry * createConfiguration(const GearDir &content)
Create a parameter object from gearbox.
DBObjPtr< TOPCalChannelThresholdEff > m_thresholdEff
channel threshold effi.
static TOPGeometryPar * Instance()
Static method to obtain the pointer to its instance.
TOPNominalQE m_envelopeQE
envelope quantum efficiency
std::map< int, unsigned > m_pmtTypes
PMT types mapped to positions.
DBObjPtr< TOPCalChannelRQE > m_channelRQE
channel relative quantum effi.
ChannelMapper m_channelMapperIRS3B
channel-pixel mapper
FrontEndMapper m_frontEndMapper
front end electronics mapper
std::string addNumber(const std::string &str, unsigned number)
Adds number to string.
static const double c_hc
Planck constant times speed of light in [eV*nm].
const TOPNominalTTS & getTTS(int moduleID, int pmtID) const
Returns TTS of a PMT at given position.
void prepareRelPDEonMC() const
Prepares a map of relative pixel photon detection efficiencies on MC.
std::map< int, const TOPPmtQE * > m_pmts
QE data mapped to positions.
bool m_valid
true if geometry is available
void clearCache()
Clears cache for PMT dependent QE data - function is used in call backs.
ChannelMapper m_channelMapperIRSX
channel-pixel mapper
void Initialize()
Initialize from database.
TOPGeoBarSegment createBarSegment(const GearDir &content, const std::string &serialNumber)
Create a parameter object from gearbox for bar segment.
double getRelativePDEonMC(int moduleID, int pixelID) const
Returns relative PDE on MC (including CE, tuning factor and threshold efficiency)
double getPhaseIndex(double energy) const
Returns phase refractive index of quartz at given photon energy.
double refractiveIndex(double lambda) const
Quartz refractive index (SellMeier equation)
bool m_oldPayload
true if old payload found in DB
std::map< int, double > m_relPDEonMC
pixel relative photon detection efficiencies on MC
void mapPmtQEToPositions() const
Maps PMT QE data to positions within the detector.
double getGroupIndex(double energy) const
Returns group refractive index of quartz at given photon energy.
TOPGeometry * m_geo
geometry parameters from Gearbox
TOPGeometryPar()
Hidden constructor since it is a singleton class.
void setEnvelopeQE() const
Constructs envelope of quantum efficiency from PMT data.
void mapPmtTypeToPositions() const
Maps PMT type to positions within the detector.
DBObjPtr< TOPCalChannelPulseHeight > m_pulseHeights
channel pulse height parametrizations
int getUniquePmtID(int moduleID, int pmtID) const
Returns unique PMT ID within the detector.
static TOPGeometryPar * s_instance
Pointer to the class instance.
OptionalDBArray< TOPPmtInstallation > m_pmtInstalled
PMT installation data.
std::map< int, double > m_relEfficiencies
pixel relative QE
static const double mm
[millimeters]
Definition Unit.h:70
static const double nm
[nanometers]
Definition Unit.h:72
static const double eV
[electronvolt]
Definition Unit.h:112
static const double T
[tesla]
Definition Unit.h:120
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
std::vector< double > getArray(const std::string &path) const noexcept(false)
Get the parameter path as a list of double values converted to the standard unit.
Definition Interface.cc:123
double getTime(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard time unit.
Definition Interface.h:419
double getDouble(const std::string &path="") const noexcept(false)
Get the parameter path as a double.
Definition Interface.cc:41
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
static Materials & getInstance()
Get a reference to the singleton instance.
Definition Materials.cc:85
Class to store variables with their name which were sent to the logging service.
static double convertValue(double value, const std::string &unitString)
Converts a floating point value to the standard framework unit.
Definition UnitConst.cc:128
static void getField(const double *pos, double *field)
return the magnetic field at a given position.
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28
std::map< ExpRun, std::pair< double, double > > filter(const std::map< ExpRun, std::pair< double, double > > &runs, double cut, std::map< ExpRun, std::pair< double, double > > &runsRemoved)
filter events to remove runs shorter than cut, it stores removed runs in runsRemoved
Definition Splitter.cc:38
double normalize()
Normalize the distribution (fractions)
void appendModule(const TOPGeoModule &module)
Appends module (if its ID differs from already appended modules)
void print(const std::string &title="TOP geometry parameters") const override
Print the content of the class.
bool isModuleIDValid(int moduleID) const
Checks if module exists in m_modules.
const TOPNominalTTS & getTTS(unsigned type) const
Returns time transition spread of a given PMT type.
void appendGaussian(double norm, double mean, double sigma)
Append Gaussian.
double getPDETuningFactor(unsigned type) const
Returns photon detection efficiency tuning factor of a given PMT type.
Abstract base class for different kinds of events.
STL namespace.