9 #include <top/geometry/TOPGeometryPar.h>
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>
32 TOPGeometryPar* TOPGeometryPar::s_instance = 0;
33 const double TOPGeometryPar::c_hc = 1239.84193;
35 TOPGeometryPar::~TOPGeometryPar()
37 if (m_geo)
delete m_geo;
38 if (m_geoDB)
delete m_geoDB;
52 void TOPGeometryPar::Initialize(
const GearDir& content)
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");
65 GearDir frontEndMapping(content,
"FrontEndMapping");
66 m_frontEndMapper.initialize(frontEndMapping);
67 if (!m_frontEndMapper.isValid()) {
71 GearDir channelMapping0(content,
"ChannelMapping[@type='IRS3B']");
72 m_channelMapperIRS3B.initialize(channelMapping0);
73 if (!m_channelMapperIRS3B.isValid()) {
77 GearDir channelMapping1(content,
"ChannelMapping[@type='IRSX']");
78 m_channelMapperIRSX.initialize(channelMapping1);
79 if (!m_channelMapperIRSX.isValid()) {
84 finalizeInitialization();
89 void TOPGeometryPar::Initialize()
94 if (m_geoDB)
delete m_geoDB;
97 if (!m_geoDB->isValid()) {
98 B2ERROR(
"TOPGeometry: no payload found in database");
101 if ((*m_geoDB)->getWavelengthFilter().getName().empty()) {
103 B2WARNING(
"TOPGeometry: obsolete payload revision (pixel independent PDE) - please, check global tag");
105 if ((*m_geoDB)->getTTSes().empty()) {
106 B2WARNING(
"TOPGeometry: obsolete payload revision (nominal TTS only) - please, check global tag");
108 if ((*m_geoDB)->arePDETuningFactorsEmpty()) {
109 B2WARNING(
"TOPGeometry: old payload revision (before bugfix and update of optical properties)");
113 m_geoDB->addCallback([]() {
114 B2FATAL(
"Geometry cannot change during processing, "
115 "aborting (component TOP)");
118 m_frontEndMapper.initialize();
119 if (!m_frontEndMapper.isValid()) {
120 B2ERROR(
"TOPFrontEndMaps: no payload found in database");
124 m_channelMapperIRSX.initialize();
125 if (!m_channelMapperIRSX.isValid()) {
126 B2ERROR(
"TOPChannelMaps: no payload found in database");
131 finalizeInitialization();
135 void TOPGeometryPar::finalizeInitialization()
138 m_BfieldOn = (BFieldManager::getField(0, 0, 0).R() / Unit::T) > 0.1;
141 m_pmtInstalled.addCallback(
this, &TOPGeometryPar::clearCache);
142 m_pmtQEData.addCallback(
this, &TOPGeometryPar::clearCache);
145 const auto& logSystem = LogSystem::Instance();
146 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 10000,
"top")) {
147 getGeometry()->print();
149 cout <<
"Envelope QE same as nominal quantum efficiency" << endl << endl;
152 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
153 m_envelopeQE.print(
"Envelope QE");
157 void TOPGeometryPar::clearCache()
159 m_envelopeQE.clear();
161 m_relEfficiencies.clear();
167 if (!m_valid) B2FATAL(
"No geometry available for TOP");
169 TOPGeometry::useBasf2Units();
177 double TOPGeometryPar::getPMTEfficiencyEnvelope(
double energy)
const
179 double lambda = c_hc / energy;
182 return getGeometry()->getNominalQE().getEfficiency(lambda);
185 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
186 return m_envelopeQE.getEfficiency(lambda);
189 double TOPGeometryPar::getPMTEfficiency(
double energy,
190 int moduleID,
int pmtID,
191 double x,
double y)
const
193 const auto* geo = getGeometry();
194 if (!geo->isModuleIDValid(moduleID))
return 0;
196 double lambda = c_hc / energy;
199 return geo->getNominalQE().getEfficiency(lambda);
202 if (m_pmts.empty()) mapPmtQEToPositions();
204 int id = getUniquePmtID(moduleID, pmtID);
205 const auto* pmtQE = m_pmts[id];
206 if (!pmtQE)
return 0;
208 const auto& pmtArray = geo->getModule(moduleID).getPMTArray();
209 auto pmtPixel = pmtArray.getPMT().getPixelID(x, y);
210 if (pmtPixel == 0)
return 0;
212 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
213 auto channel = getChannelMapper().getChannel(pixelID);
215 double RQE = geo->getPDETuningFactor(getPMTType(moduleID, pmtID));
216 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
218 return pmtQE->getEfficiency(pmtPixel, lambda, m_BfieldOn) * RQE;
223 double TOPGeometryPar::getRelativePixelEfficiency(
int moduleID,
int pixelID)
const
226 auto channel = getChannelMapper().getChannel(pixelID);
227 auto pmtID = getChannelMapper().getPmtID(pixelID);
229 double RQE = getGeometry()->getPDETuningFactor(getPMTType(moduleID, pmtID));
230 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
232 double thrEffi = 1.0;
233 if (m_thresholdEff.isValid()) thrEffi = m_thresholdEff->getThrEff(moduleID, channel);
236 return RQE * thrEffi;
239 if (m_relEfficiencies.empty()) prepareRelEfficiencies();
241 int id = getUniquePixelID(moduleID, pixelID);
242 return m_relEfficiencies[id] * RQE * thrEffi;
246 unsigned TOPGeometryPar::getPMTType(
int moduleID,
int pmtID)
const
248 if (m_pmtTypes.empty()) mapPmtTypeToPositions();
250 int id = getUniquePmtID(moduleID, pmtID);
251 return m_pmtTypes[id];
257 auto pmtType = getPMTType(moduleID, pmtID);
258 return getGeometry()->getTTS(pmtType);
262 void TOPGeometryPar::setEnvelopeQE()
const
264 if (m_pmtQEData.getEntries() == 0) {
265 B2ERROR(
"DBArray TOPPmtQEs is empty");
269 double lambdaFirst = 0;
270 for (
const auto& pmt : m_pmtQEData) {
271 if (pmt.getLambdaFirst() > 0) {
272 lambdaFirst = pmt.getLambdaFirst();
276 if (lambdaFirst == 0) {
277 B2ERROR(
"DBArray TOPPmtQEs: lambdaFirst of all PMT found to be less or equal 0");
280 for (
const auto& pmt : m_pmtQEData) {
281 if (pmt.getLambdaFirst() > 0) {
282 lambdaFirst = std::min(lambdaFirst, pmt.getLambdaFirst());
286 double lambdaStep = 0;
287 for (
const auto& pmt : m_pmtQEData) {
288 if (pmt.getLambdaStep() > 0) {
289 lambdaStep = pmt.getLambdaStep();
293 if (lambdaStep == 0) {
294 B2ERROR(
"DBArray TOPPmtQEs: lambdaStep of all PMT found to be less or equal 0");
297 for (
const auto& pmt : m_pmtQEData) {
298 if (pmt.getLambdaStep() > 0) {
299 lambdaStep = std::min(lambdaStep, pmt.getLambdaStep());
303 std::map<std::string, const TOPPmtInstallation*> map;
304 for (
const auto& pmt : m_pmtInstalled) {
305 map[pmt.getSerialNumber()] = &pmt;
307 const auto* geo = getGeometry();
309 std::vector<float> envelopeQE;
310 for (
const auto& pmt : m_pmtQEData) {
311 float ce = pmt.getCE(m_BfieldOn);
312 auto pmtInstalled = map[pmt.getSerialNumber()];
313 if (pmtInstalled) ce *= geo->getPDETuningFactor(pmtInstalled->getType());
314 if (pmt.getLambdaFirst() == lambdaFirst and pmt.getLambdaStep() == lambdaStep) {
315 const auto& envelope = pmt.getEnvelopeQE();
316 if (envelopeQE.size() < envelope.size()) {
317 envelopeQE.resize(envelope.size() - envelopeQE.size(), 0);
319 for (
size_t i = 0; i < std::min(envelopeQE.size(), envelope.size()); i++) {
320 envelopeQE[i] = std::max(envelopeQE[i], envelope[i] * ce);
323 double lambdaLast = pmt.getLambdaLast();
324 int nExtra = (lambdaLast - lambdaFirst) / lambdaStep + 1 - envelopeQE.size();
325 if (nExtra > 0) envelopeQE.resize(nExtra, 0);
326 for (
size_t i = 0; i < envelopeQE.size(); i++) {
327 float qe = pmt.getEnvelopeQE(lambdaFirst + lambdaStep * i);
328 envelopeQE[i] = std::max(envelopeQE[i], qe * ce);
333 m_envelopeQE.set(lambdaFirst, lambdaStep, 1.0, envelopeQE,
"EnvelopeQE");
335 B2INFO(
"TOPGeometryPar: envelope of PMT dependent QE has been set");
340 void TOPGeometryPar::mapPmtQEToPositions()
const
344 std::map<std::string, const TOPPmtQE*> map;
345 for (
const auto& pmt : m_pmtQEData) {
346 map[pmt.getSerialNumber()] = &pmt;
348 for (
const auto& pmt : m_pmtInstalled) {
349 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
350 m_pmts[id] = map[pmt.getSerialNumber()];
353 B2INFO(
"TOPGeometryPar: QE of PMT's mapped to positions, size = " << m_pmts.size());
357 void TOPGeometryPar::mapPmtTypeToPositions()
const
359 for (
const auto& pmt : m_pmtInstalled) {
360 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
361 m_pmtTypes[id] = pmt.getType();
364 B2INFO(
"TOPGeometryPar: PMT types mapped to positions, size = "
365 << m_pmtTypes.size());
368 std::set<unsigned> types;
369 for (
const auto& pmt : m_pmtInstalled) {
370 types.insert(pmt.getType());
372 const auto* geo = getGeometry();
373 for (
const auto& type : types) {
374 if (geo->getTTS(type).getPMTType() != type) {
375 B2WARNING(
"No TTS found for an installed PMT type. Nominal one will be used."
376 <<
LogVar(
"PMT type", type));
383 void TOPGeometryPar::prepareRelEfficiencies()
const
385 m_relEfficiencies.clear();
386 if (m_pmts.empty()) mapPmtQEToPositions();
388 const auto* geo = getGeometry();
390 const auto& nominalQE = geo->getNominalQE();
391 double s0 = integralOfQE(nominalQE.getQE(), nominalQE.getCE(),
392 nominalQE.getLambdaFirst(), nominalQE.getLambdaStep());
394 for (
const auto& module : geo->getModules()) {
395 auto moduleID = module.getModuleID();
396 const auto& pmtArray = module.getPMTArray();
397 int numPMTs = pmtArray.getSize();
398 int numPMTPixels = pmtArray.getPMT().getNumPixels();
399 for (
int pmtID = 1; pmtID <= numPMTs; pmtID++) {
400 const auto* pmtQE = m_pmts[getUniquePmtID(moduleID, pmtID)];
401 for (
int pmtPixel = 1; pmtPixel <= numPMTPixels; pmtPixel++) {
404 s = integralOfQE(pmtQE->getQE(pmtPixel), pmtQE->getCE(m_BfieldOn),
405 pmtQE->getLambdaFirst(), pmtQE->getLambdaStep());
407 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
408 auto id = getUniquePixelID(moduleID, pixelID);
409 m_relEfficiencies[id] = s / s0;
414 B2INFO(
"TOPGeometryPar: pixel relative quantum efficiencies have been set, size = "
415 << m_relEfficiencies.size());
419 double TOPGeometryPar::integralOfQE(
const std::vector<float>& qe,
double ce,
420 double lambdaFirst,
double lambdaStep)
const
422 if (qe.empty())
return 0;
425 double lambda = lambdaFirst;
426 double f1 = qe[0] / (lambda * lambda);
427 for (
size_t i = 1; i < qe.size(); i++) {
428 lambda += lambdaStep;
429 double f2 = qe[i] / (lambda * lambda);
433 return s * c_hc * lambdaStep * ce;
443 GearDir pmtParams(content,
"PMTs/PMT");
457 pmtParams.
getInt(
"PadYNum"));
463 auto& materials = geometry::Materials::getInstance();
464 GearDir reflEdgeSurfParams(pmtParams,
"reflectiveEdge/Surface");
466 pmtParams.
getLength(
"reflectiveEdge/thickness"),
467 materials.createOpticalSurfaceConfig(reflEdgeSurfParams));
469 GearDir arrayParams(content,
"PMTs");
471 arrayParams.
getInt(
"nPMTy"),
477 arrayParams.
getString(
"siliconeCookie/material"));
479 arrayParams.
getString(
"wavelengthFilter/material"));
481 double decoupledFraction = arrayParams.
getDouble(
"decoupledFraction", 0);
485 GearDir moduleParams(content,
"Modules");
486 GearDir glueParams(moduleParams,
"Glue");
488 for (
int slotID = 1; slotID <= numModules; slotID++) {
489 std::string gearName =
"Module[@slotID='" + std::to_string(slotID) +
"']";
490 GearDir slotParams(moduleParams, gearName);
495 int cNumber = slotParams.
getInt(
"ConstructionNumber");
496 module.setModuleCNumber(cNumber);
497 module.setName(addNumber(module.getName(), cNumber));
499 auto prism = createPrism(content, slotParams.
getString(
"Prism"));
500 prism.setName(addNumber(prism.getName(), cNumber));
501 module.setPrism(prism);
503 auto barSegment2 = createBarSegment(content, slotParams.
getString(
"BarSegment2"));
504 barSegment2.setName(addNumber(barSegment2.getName() +
"2-", cNumber));
505 barSegment2.setGlue(glueParams.
getLength(
"Thicknes1"),
507 module.setBarSegment2(barSegment2);
509 auto barSegment1 = createBarSegment(content, slotParams.
getString(
"BarSegment1"));
510 barSegment1.setName(addNumber(barSegment1.getName() +
"1-", cNumber));
511 barSegment1.setGlue(glueParams.
getLength(
"Thicknes2"),
513 module.setBarSegment1(barSegment1);
515 auto mirror = createMirrorSegment(content, slotParams.
getString(
"Mirror"));
516 mirror.setName(addNumber(mirror.getName(), cNumber));
517 mirror.setGlue(glueParams.
getLength(
"Thicknes3"),
519 module.setMirrorSegment(mirror);
521 module.setPMTArray(pmtArray);
522 if (decoupledFraction > 0) module.generateDecoupledPMTs(decoupledFraction);
529 GearDir displacedGeometry(content,
"DisplacedGeometry");
530 if (displacedGeometry) {
531 if (displacedGeometry.
getInt(
"SwitchON") != 0) {
532 B2WARNING(
"TOP: displaced geometry is activated");
534 int moduleID = slot.getInt(
"@ID");
536 B2WARNING(
"TOPGeometryPar: DisplacedGeometry.xml: invalid moduleID."
537 <<
LogVar(
"moduleID", moduleID));
543 slot.getAngle(
"alpha"),
544 slot.getAngle(
"beta"),
545 slot.getAngle(
"gamma"));
547 module.setModuleDisplacement(moduleDispl);
554 GearDir displacedPMTArrays(content,
"DisplacedPMTArrays");
555 if (displacedPMTArrays) {
556 if (displacedPMTArrays.
getInt(
"SwitchON") != 0) {
557 B2WARNING(
"TOP: displaced PMT arrays are activated");
559 int moduleID = slot.getInt(
"@ID");
561 B2WARNING(
"TOPGeometryPar: DisplacedPMTArrays.xml: invalid moduleID."
562 <<
LogVar(
"moduleID", moduleID));
567 slot.getAngle(
"alpha"));
569 module.setPMTArrayDisplacement(arrayDispl);
576 GearDir brokenGlues(content,
"BrokenGlues");
578 if (brokenGlues.
getInt(
"SwitchON") != 0) {
579 auto material = brokenGlues.
getString(
"material");
581 int moduleID = slot.getInt(
"@ID");
583 B2WARNING(
"TOPGeometryPar: BrokenGlues.xml: invalid moduleID."
584 <<
LogVar(
"moduleID", moduleID));
588 for (
const GearDir& glue : slot.getNodes(
"Glue")) {
589 int glueID = glue.getInt(
"@ID");
590 double fraction = glue.getDouble(
"fraction");
591 if (fraction <= 0)
continue;
592 double angle = glue.getAngle(
"angle");
593 module.setBrokenGlue(glueID, fraction, angle, material);
601 GearDir peelOff(content,
"PeelOffCookies");
603 if (peelOff.
getInt(
"SwitchON") != 0) {
604 auto material = peelOff.
getString(
"material");
605 double thickness = peelOff.
getLength(
"thickness");
607 int moduleID = slot.getInt(
"@ID");
609 B2WARNING(
"TOPGeometryPar: PeelOffCookiess.xml: invalid moduleID."
610 <<
LogVar(
"moduleID", moduleID));
614 module.setPeelOffRegions(thickness, material);
615 for (
const GearDir& region : slot.getNodes(
"Region")) {
616 int regionID = region.getInt(
"@ID");
617 double fraction = region.getDouble(
"fraction");
618 if (fraction <= 0)
continue;
619 double angle = region.getAngle(
"angle");
620 module.appendPeelOffRegion(regionID, fraction, angle);
628 GearDir feParams(content,
"FrontEndGeo");
629 GearDir fbParams(feParams,
"FrontBoard");
637 GearDir hvParams(feParams,
"HVBoard");
644 GearDir bsParams(feParams,
"BoardStack");
657 GearDir qbbParams(content,
"QBB");
663 GearDir outerPanelParams(qbbParams,
"outerPanel");
666 outerPanelParams.
getLength(
"minThickness"),
667 outerPanelParams.
getLength(
"maxThickness"),
671 outerPanelParams.
getInt(
"N"),
673 outerPanelParams.
getString(
"edgeMaterial"),
674 "TOPOuterHoneycombPanel");
677 GearDir innerPanelParams(qbbParams,
"innerPanel");
680 innerPanelParams.
getLength(
"minThickness"),
681 innerPanelParams.
getLength(
"maxThickness"),
685 innerPanelParams.
getInt(
"N"),
687 innerPanelParams.
getString(
"edgeMaterial"),
688 "TOPInnerHoneycombPanel");
691 GearDir sideRailsParams(qbbParams,
"sideRails");
693 sideRailsParams.
getLength(
"reducedThickness"),
698 GearDir prismEnclParams(qbbParams,
"prismEnclosure");
702 prismEnclParams.
getLength(
"bottomThickness"),
703 prismEnclParams.
getLength(
"sideThickness"),
704 prismEnclParams.
getLength(
"backThickness"),
705 prismEnclParams.
getLength(
"frontThickness"),
706 prismEnclParams.
getLength(
"extensionThickness"),
710 GearDir endPlateParams(qbbParams,
"forwardEndPlate");
714 "TOPForwardEndPlate");
717 GearDir coldPlateParams(qbbParams,
"coldPlate");
719 coldPlateParams.
getString(
"baseMaterial"),
720 coldPlateParams.
getLength(
"coolThickness"),
722 coldPlateParams.
getString(
"coolMaterial"));
729 GearDir qeParams(content,
"QE");
730 std::vector<float> qeData;
732 qeData.push_back(Qeffi.getDouble(
""));
735 qeParams.
getLength(
"LambdaStep") / Unit::nm,
742 GearDir ttsParams(content,
"PMTs/TTS");
746 Gauss.getTime(
"mean"),
747 Gauss.getTime(
"sigma"));
754 GearDir pmtTTSParams(content,
"TTSofPMTs");
756 int type = ttsPar.getInt(
"type");
757 double tuneFactor = ttsPar.getDouble(
"PDEtuneFactor");
758 TOPNominalTTS tts(
"TTS of " + ttsPar.getString(
"@name") +
" PMT");
762 Gauss.getTime(
"mean"),
763 Gauss.getTime(
"sigma"));
772 GearDir tdcParams(content,
"TDC");
775 tdcParams.
getInt(
"subBits"),
776 tdcParams.
getTime(
"syncTimeBase"),
777 tdcParams.
getInt(
"numofBunches"),
779 tdcParams.
getTime(
"pileupTime"),
780 tdcParams.
getTime(
"doubleHitResolution"),
781 tdcParams.
getTime(
"timeJitter"),
788 pmtParams.
getTime(
"TDCbitwidth"),
789 pmtParams.
getTime(
"TDCoffset", 0),
790 pmtParams.
getTime(
"TDCpileupTime", 0),
791 pmtParams.
getTime(
"TDCdoubleHitResolution", 0),
792 pmtParams.
getTime(
"TDCtimeJitter", 50e-3),
793 pmtParams.
getDouble(
"TDCefficiency", 1));
799 GearDir shapeParams(content,
"SignalShape");
801 GearDir noiseBandwidth(shapeParams,
"noiseBandwidth");
804 shapeParams.
getTime(
"tailTimeConstant"),
805 noiseBandwidth.
getDouble(
"pole1") / 1000,
806 noiseBandwidth.
getDouble(
"pole2") / 1000);
812 GearDir calpulseParams(content,
"CalPulseShape");
813 if (calpulseParams) {
814 GearDir noiseBandwidth(calpulseParams,
"noiseBandwidth");
817 calpulseParams.
getTime(
"tailTimeConstant"),
818 noiseBandwidth.
getDouble(
"pole1") / 1000,
819 noiseBandwidth.
getDouble(
"pole2") / 1000);
825 std::string materialNode =
"Materials/Material[@name='TOPWavelengthFilterIHU340']";
826 GearDir filterMaterial(content, materialNode);
827 if (!filterMaterial) {
828 B2FATAL(
"TOPGeometry: " << materialNode <<
" not found");
830 GearDir property(filterMaterial,
"Property[@name='ABSLENGTH']");
832 B2FATAL(
"TOPGeometry: " << materialNode <<
", Property ABSLENGTH not found");
834 int numNodes =
property.getNumberNodes(
"value");
836 double conversion = Unit::convertValue(1, property.
getString(
"@unit",
"GeV"));
837 std::vector<double> energies;
838 std::vector<double> absLengths;
839 for (
int i = 0; i < numNodes; i++) {
840 GearDir value(property,
"value", i + 1);
841 energies.push_back(value.getDouble(
"@energy") * conversion / Unit::eV);
842 absLengths.push_back(value.getDouble() * Unit::mm);
844 TSpline3 spline(
"absLen", energies.data(), absLengths.data(), energies.size());
845 double lambdaFirst = c_hc / energies.back();
846 double lambdaLast = c_hc / energies[0];
847 double lambdaStep = 5;
848 int numSteps = (lambdaLast - lambdaFirst) / lambdaStep + 1;
849 const double filterThickness = arrayParams.
getLength(
"wavelengthFilter/thickness");
850 std::vector<float> bulkTransmittances;
851 for (
int i = 0; i < numSteps; i++) {
852 double wavelength = lambdaFirst + lambdaStep * i;
853 double energy = c_hc / wavelength;
854 double absLen = spline.Eval(energy);
855 bulkTransmittances.push_back(exp(-filterThickness / absLen));
860 B2FATAL(
"TOPGeometry: " << materialNode
861 <<
", Property ABSLENGTH has less than 2 nodes");
869 const std::string& SN)
872 GearDir params(content,
"QuartzBars/QuartzBar[@SerialNumber='" + SN +
"']");
874 params.getLength(
"Thickness"),
875 params.getLength(
"Length"),
876 params.getString(
"Material"));
880 std::string surfaceName = params.getString(
"OpticalSurface");
881 double sigmaAlpha = params.getDouble(
"SigmaAlpha");
882 GearDir surfaceParams(content,
"Modules/Surface[@name='" + surfaceName +
"']");
883 auto& materials = geometry::Materials::getInstance();
884 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
892 const std::string& SN)
895 GearDir params(content,
"Mirrors/Mirror[@SerialNumber='" + SN +
"']");
897 params.getLength(
"Thickness"),
898 params.getLength(
"Length"),
899 params.getString(
"Material"));
901 mirror.
setRadius(params.getLength(
"Radius"));
905 auto& materials = geometry::Materials::getInstance();
906 GearDir coatingParams(params,
"Surface");
907 mirror.
setCoating(params.getLength(
"mirrorThickness"),
"Al",
908 materials.createOpticalSurfaceConfig(coatingParams));
911 std::string surfaceName = params.getString(
"OpticalSurface");
912 double sigmaAlpha = params.getDouble(
"SigmaAlpha");
913 GearDir surfaceParams(content,
"Modules/Surface[@name='" + surfaceName +
"']");
914 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
922 const std::string& SN)
925 GearDir params(content,
"Prisms/Prism[@SerialNumber='" + SN +
"']");
927 params.getLength(
"Thickness"),
928 params.getLength(
"Length"),
929 params.getLength(
"ExitThickness"),
931 params.getString(
"Material"));
932 prism.
setAngle(params.getAngle(
"Angle"));
936 std::string surfaceName = params.getString(
"OpticalSurface");
937 double sigmaAlpha = params.getDouble(
"SigmaAlpha");
938 GearDir surfaceParams(content,
"Modules/Surface[@name='" + surfaceName +
"']");
939 auto& materials = geometry::Materials::getInstance();
940 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
946 std::string TOPGeometryPar::addNumber(
const std::string& str,
unsigned number)
950 ss << str <<
"0" << number;
959 double TOPGeometryPar::refractiveIndex(
double lambda)
const
964 const double b[] = {0.683740494, 0.420323613, 0.585027480};
965 const double c[] = {0.00460352869, 0.0133968856, 64.4932732};
967 double x = pow(lambda * 0.001, 2);
969 for (
int i = 0; i < 3; i++) {
970 y += b[i] * x / (x - c[i]);
975 double TOPGeometryPar::getPhaseIndex(
double energy)
const
977 double lambda = c_hc / energy;
978 return refractiveIndex(lambda);
981 double TOPGeometryPar::getGroupIndex(
double energy)
const
983 double lambda = c_hc / energy;
985 double n = refractiveIndex(lambda);
986 double dndl = (refractiveIndex(lambda + dl / 2) - refractiveIndex(lambda - dl / 2)) / dl;
987 return n / (1 + lambda / n * dndl);
Class for accessing objects in the database.
GearDir is the basic class used for accessing the parameter store.
virtual int getNumberNodes(const std::string &path="") const override
Return the number of nodes a given path will expand to.
virtual std::string getString(const std::string &path="") const noexcept(false) override
Get the parameter path as a string.
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.
void setBottom(double thickness, const std::string &material)
Sets bottom.
void setWindow(double thickness, const std::string &material)
Sets entrance window.
void setSensVolume(double sizeX, double sizeY, double thickness, const std::string &material)
Sets sensitive volume (photo-cathode)
void setWallThickness(double thickness)
Sets wall thickness.
void setWallMaterial(const std::string &material)
Sets casing material.
void setNumPixels(unsigned numColumns, unsigned numRows)
Sets number of pixel rows and columns.
void setFillMaterial(const std::string &material)
Sets inside material.
void setReflEdge(double width, double thickness, const GeoOpticalSurface &surf)
Sets reflective edge.
Geometry parameters of prism enclosure (simplified)
Geometry parameters of prism.
void setAngle(double angle)
Recalculates flatLength according to given prism angle.
Geometry parameters of Quartz Bar Box (mother class)
void setOuterPanel(const TOPGeoHoneycombPanel &outerPanel)
Sets outer honeycomb panel.
void setColdPlate(const TOPGeoColdPlate &coldPlate)
Sets forward cold plate.
void setPrismEnclosure(const TOPGeoPrismEnclosure &prismEnclosure)
Sets prism enclosure.
void setSideRails(const TOPGeoSideRails &sideRails)
Sets side rails.
void setInnerPanel(const TOPGeoHoneycombPanel &innerPanel)
Sets inner honeycomb panel.
void setEndPlate(const TOPGeoEndPlate &endPlate)
Sets forward end plate.
Geometry parameters of side rails (simplified)
Geometry parameters of TOP.
void setCalPulseShape(const TOPSignalShape &shape)
Sets calibration pulse shape.
void appendTTS(const TOPNominalTTS &tts)
Appends time transition spread of a particular PMT type.
void setWavelengthFilter(const TOPWavelengthFilter &filter)
Sets wavelength filter transmittance.
const TOPNominalTDC & getNominalTDC() const
Returns nominal time-to-digit conversion parameters.
void setNominalTDC(const TOPNominalTDC &nominalTDC)
Sets nominal time-to-digit conversion parameters.
void setQBB(const TOPGeoQBB &QBB)
Sets quartz bar box.
void setFrontEnd(const TOPGeoFrontEnd &frontEnd, unsigned num=4)
Sets front-end.
void setNominalQE(const TOPNominalQE &nominalQE)
Sets nominal quantum efficiency of PMT.
void appendPDETuningFactor(unsigned type, double factor)
Appends photon detection efficiency tuning factor of a particular PMT type.
void setSignalShape(const TOPSignalShape &signalShape)
Sets single photon signal shape.
void setNominalTTS(const TOPNominalTTS &nominalTTS)
Sets nominal time transition spread of PMT.
Nominal quantum efficiency of PMT.
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.
Singleton class for TOP Geometry Parameters.
double getAngle(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard angle unit.
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.
double getTime(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard time unit.
double getDouble(const std::string &path="") const noexcept(false)
Get the parameter path as a double.
double getLength(const std::string &path="") const noexcept(false)
Get the parameter path as a double converted to the standard length unit.
std::vector< GearDir > getNodes(const std::string &path="") const
Get vector of GearDirs which point to all the nodes the given path evaluates to.
int getInt(const std::string &path="") const noexcept(false)
Get the parameter path as a int.
Class to store variables with their name which were sent to the logging service.
double sqrt(double a)
sqrt for double
double normalize()
Normalize the distribution (fractions)
void appendModule(const TOPGeoModule &module)
Appends module (if its ID differs from already appended modules)
bool isModuleIDValid(int moduleID) const
Checks if module exists in m_modules.
const TOPGeoModule & getModule(int moduleID) const
Returns module.
void appendGaussian(double norm, double mean, double sigma)
Append Gaussian.
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
Abstract base class for different kinds of events.