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