12 #include <top/geometry/TOPGeometryPar.h>
14 #include <framework/gearbox/GearDir.h>
15 #include <framework/logging/Logger.h>
16 #include <framework/logging/LogSystem.h>
17 #include <framework/geometry/BFieldManager.h>
18 #include <geometry/Materials.h>
34 TOPGeometryPar* TOPGeometryPar::s_instance = 0;
35 const double TOPGeometryPar::c_hc = 1239.84193;
37 TOPGeometryPar::~TOPGeometryPar()
39 if (m_geo)
delete m_geo;
40 if (m_geoDB)
delete m_geoDB;
54 void TOPGeometryPar::Initialize(
const GearDir& content)
60 if (m_geo)
delete m_geo;
61 m_geo = createConfiguration(content);
62 if (!m_geo->isConsistent()) {
63 B2ERROR(
"TOPGeometryPar::createConfiguration: geometry not consistently defined");
67 GearDir frontEndMapping(content,
"FrontEndMapping");
68 m_frontEndMapper.initialize(frontEndMapping);
69 if (!m_frontEndMapper.isValid()) {
73 GearDir channelMapping0(content,
"ChannelMapping[@type='IRS3B']");
74 m_channelMapperIRS3B.initialize(channelMapping0);
75 if (!m_channelMapperIRS3B.isValid()) {
79 GearDir channelMapping1(content,
"ChannelMapping[@type='IRSX']");
80 m_channelMapperIRSX.initialize(channelMapping1);
81 if (!m_channelMapperIRSX.isValid()) {
86 finalizeInitialization();
91 void TOPGeometryPar::Initialize()
96 if (m_geoDB)
delete m_geoDB;
99 if (!m_geoDB->isValid()) {
100 B2ERROR(
"TOPGeometry: no payload found in database");
103 if ((*m_geoDB)->getWavelengthFilter().getName().empty()) {
105 B2WARNING(
"TOPGeometry: obsolete payload revision (pixel independent PDE) - please, check global tag");
107 if ((*m_geoDB)->getTTSes().empty()) {
108 B2WARNING(
"TOPGeometry: obsolete payload revision (nominal TTS only) - please, check global tag");
110 if ((*m_geoDB)->arePDETuningFactorsEmpty()) {
111 B2WARNING(
"TOPGeometry: old payload revision (before bugfix and update of optical properties)");
115 m_geoDB->addCallback([]() {
116 B2FATAL(
"Geometry cannot change during processing, "
117 "aborting (component TOP)");
120 m_frontEndMapper.initialize();
121 if (!m_frontEndMapper.isValid()) {
122 B2ERROR(
"TOPFrontEndMaps: no payload found in database");
126 m_channelMapperIRSX.initialize();
127 if (!m_channelMapperIRSX.isValid()) {
128 B2ERROR(
"TOPChannelMaps: no payload found in database");
133 finalizeInitialization();
137 void TOPGeometryPar::finalizeInitialization()
140 m_BfieldOn = (BFieldManager::getField(0, 0, 0).Mag() / Unit::T) > 0.1;
143 m_pmtInstalled.addCallback(
this, &TOPGeometryPar::clearCache);
144 m_pmtQEData.addCallback(
this, &TOPGeometryPar::clearCache);
147 const auto& logSystem = LogSystem::Instance();
148 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 10000,
"top")) {
149 getGeometry()->print();
151 cout <<
"Envelope QE same as nominal quantum efficiency" << endl << endl;
154 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
155 m_envelopeQE.print(
"Envelope QE");
159 void TOPGeometryPar::clearCache()
161 m_envelopeQE.clear();
163 m_relEfficiencies.clear();
169 if (!m_valid) B2FATAL(
"No geometry available for TOP");
171 TOPGeometry::useBasf2Units();
179 double TOPGeometryPar::getPMTEfficiencyEnvelope(
double energy)
const
181 double lambda = c_hc / energy;
184 return getGeometry()->getNominalQE().getEfficiency(lambda);
187 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
188 return m_envelopeQE.getEfficiency(lambda);
191 double TOPGeometryPar::getPMTEfficiency(
double energy,
192 int moduleID,
int pmtID,
193 double x,
double y)
const
195 const auto* geo = getGeometry();
196 if (!geo->isModuleIDValid(moduleID))
return 0;
198 double lambda = c_hc / energy;
201 return geo->getNominalQE().getEfficiency(lambda);
204 if (m_pmts.empty()) mapPmtQEToPositions();
206 int id = getUniquePmtID(moduleID, pmtID);
207 const auto* pmtQE = m_pmts[id];
208 if (!pmtQE)
return 0;
210 const auto& pmtArray = geo->getModule(moduleID).getPMTArray();
211 auto pmtPixel = pmtArray.getPMT().getPixelID(x, y);
212 if (pmtPixel == 0)
return 0;
214 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
215 auto channel = getChannelMapper().getChannel(pixelID);
217 double RQE = geo->getPDETuningFactor(getPMTType(moduleID, pmtID));
218 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
220 return pmtQE->getEfficiency(pmtPixel, lambda, m_BfieldOn) * RQE;
225 double TOPGeometryPar::getRelativePixelEfficiency(
int moduleID,
int pixelID)
const
228 auto channel = getChannelMapper().getChannel(pixelID);
229 auto pmtID = getChannelMapper().getPmtID(pixelID);
231 double RQE = getGeometry()->getPDETuningFactor(getPMTType(moduleID, pmtID));
232 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
234 double thrEffi = 1.0;
235 if (m_thresholdEff.isValid()) thrEffi = m_thresholdEff->getThrEff(moduleID, channel);
238 return RQE * thrEffi;
241 if (m_relEfficiencies.empty()) prepareRelEfficiencies();
243 int id = getUniquePixelID(moduleID, pixelID);
244 return m_relEfficiencies[id] * RQE * thrEffi;
248 unsigned TOPGeometryPar::getPMTType(
int moduleID,
int pmtID)
const
250 if (m_pmtTypes.empty()) mapPmtTypeToPositions();
252 int id = getUniquePmtID(moduleID, pmtID);
253 return m_pmtTypes[id];
259 auto pmtType = getPMTType(moduleID, pmtID);
260 return getGeometry()->getTTS(pmtType);
264 void TOPGeometryPar::setEnvelopeQE()
const
266 if (m_pmtQEData.getEntries() == 0) {
267 B2ERROR(
"DBArray TOPPmtQEs is empty");
271 double lambdaFirst = 0;
272 for (
const auto& pmt : m_pmtQEData) {
273 if (pmt.getLambdaFirst() > 0) {
274 lambdaFirst = pmt.getLambdaFirst();
278 if (lambdaFirst == 0) {
279 B2ERROR(
"DBArray TOPPmtQEs: lambdaFirst of all PMT found to be less or equal 0");
282 for (
const auto& pmt : m_pmtQEData) {
283 if (pmt.getLambdaFirst() > 0) {
284 lambdaFirst = std::min(lambdaFirst, pmt.getLambdaFirst());
288 double lambdaStep = 0;
289 for (
const auto& pmt : m_pmtQEData) {
290 if (pmt.getLambdaStep() > 0) {
291 lambdaStep = pmt.getLambdaStep();
295 if (lambdaStep == 0) {
296 B2ERROR(
"DBArray TOPPmtQEs: lambdaStep of all PMT found to be less or equal 0");
299 for (
const auto& pmt : m_pmtQEData) {
300 if (pmt.getLambdaStep() > 0) {
301 lambdaStep = std::min(lambdaStep, pmt.getLambdaStep());
305 std::map<std::string, const TOPPmtInstallation*> map;
306 for (
const auto& pmt : m_pmtInstalled) {
307 map[pmt.getSerialNumber()] = &pmt;
309 const auto* geo = getGeometry();
311 std::vector<float> envelopeQE;
312 for (
const auto& pmt : m_pmtQEData) {
313 float ce = pmt.getCE(m_BfieldOn);
314 auto pmtInstalled = map[pmt.getSerialNumber()];
315 if (pmtInstalled) ce *= geo->getPDETuningFactor(pmtInstalled->getType());
316 if (pmt.getLambdaFirst() == lambdaFirst and pmt.getLambdaStep() == lambdaStep) {
317 const auto& envelope = pmt.getEnvelopeQE();
318 if (envelopeQE.size() < envelope.size()) {
319 envelopeQE.resize(envelope.size() - envelopeQE.size(), 0);
321 for (
size_t i = 0; i < std::min(envelopeQE.size(), envelope.size()); i++) {
322 envelopeQE[i] = std::max(envelopeQE[i], envelope[i] * ce);
325 double lambdaLast = pmt.getLambdaLast();
326 int nExtra = (lambdaLast - lambdaFirst) / lambdaStep + 1 - envelopeQE.size();
327 if (nExtra > 0) envelopeQE.resize(nExtra, 0);
328 for (
size_t i = 0; i < envelopeQE.size(); i++) {
329 float qe = pmt.getEnvelopeQE(lambdaFirst + lambdaStep * i);
330 envelopeQE[i] = std::max(envelopeQE[i], qe * ce);
335 m_envelopeQE.set(lambdaFirst, lambdaStep, 1.0, envelopeQE,
"EnvelopeQE");
337 B2INFO(
"TOPGeometryPar: envelope of PMT dependent QE has been set");
342 void TOPGeometryPar::mapPmtQEToPositions()
const
346 std::map<std::string, const TOPPmtQE*> map;
347 for (
const auto& pmt : m_pmtQEData) {
348 map[pmt.getSerialNumber()] = &pmt;
350 for (
const auto& pmt : m_pmtInstalled) {
351 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
352 m_pmts[id] = map[pmt.getSerialNumber()];
355 B2INFO(
"TOPGeometryPar: QE of PMT's mapped to positions, size = " << m_pmts.size());
359 void TOPGeometryPar::mapPmtTypeToPositions()
const
361 for (
const auto& pmt : m_pmtInstalled) {
362 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
363 m_pmtTypes[id] = pmt.getType();
366 B2INFO(
"TOPGeometryPar: PMT types mapped to positions, size = "
367 << m_pmtTypes.size());
370 std::set<unsigned> types;
371 for (
const auto& pmt : m_pmtInstalled) {
372 types.insert(pmt.getType());
374 const auto* geo = getGeometry();
375 for (
const auto& type : types) {
376 if (geo->getTTS(type).getPMTType() != type) {
377 B2WARNING(
"No TTS found for an installed PMT type. Nominal one will be used."
378 <<
LogVar(
"PMT type", type));
385 void TOPGeometryPar::prepareRelEfficiencies()
const
387 m_relEfficiencies.clear();
388 if (m_pmts.empty()) mapPmtQEToPositions();
390 const auto* geo = getGeometry();
392 const auto& nominalQE = geo->getNominalQE();
393 double s0 = integralOfQE(nominalQE.getQE(), nominalQE.getCE(),
394 nominalQE.getLambdaFirst(), nominalQE.getLambdaStep());
396 for (
const auto& module : geo->getModules()) {
397 auto moduleID = module.getModuleID();
398 const auto& pmtArray = module.getPMTArray();
399 int numPMTs = pmtArray.getSize();
400 int numPMTPixels = pmtArray.getPMT().getNumPixels();
401 for (
int pmtID = 1; pmtID <= numPMTs; pmtID++) {
402 const auto* pmtQE = m_pmts[getUniquePmtID(moduleID, pmtID)];
403 for (
int pmtPixel = 1; pmtPixel <= numPMTPixels; pmtPixel++) {
406 s = integralOfQE(pmtQE->getQE(pmtPixel), pmtQE->getCE(m_BfieldOn),
407 pmtQE->getLambdaFirst(), pmtQE->getLambdaStep());
409 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
410 auto id = getUniquePixelID(moduleID, pixelID);
411 m_relEfficiencies[id] = s / s0;
416 B2INFO(
"TOPGeometryPar: pixel relative quantum efficiencies have been set, size = "
417 << m_relEfficiencies.size());
421 double TOPGeometryPar::integralOfQE(
const std::vector<float>& qe,
double ce,
422 double lambdaFirst,
double lambdaStep)
const
424 if (qe.empty())
return 0;
427 double lambda = lambdaFirst;
428 double f1 = qe[0] / (lambda * lambda);
429 for (
size_t i = 1; i < qe.size(); i++) {
430 lambda += lambdaStep;
431 double f2 = qe[i] / (lambda * lambda);
435 return s * c_hc * lambdaStep * ce;
445 GearDir pmtParams(content,
"PMTs/PMT");
459 pmtParams.
getInt(
"PadYNum"));
465 auto& materials = geometry::Materials::getInstance();
466 GearDir reflEdgeSurfParams(pmtParams,
"reflectiveEdge/Surface");
468 pmtParams.
getLength(
"reflectiveEdge/thickness"),
469 materials.createOpticalSurfaceConfig(reflEdgeSurfParams));
471 GearDir arrayParams(content,
"PMTs");
473 arrayParams.
getInt(
"nPMTy"),
479 arrayParams.
getString(
"siliconeCookie/material"));
481 arrayParams.
getString(
"wavelengthFilter/material"));
483 double decoupledFraction = arrayParams.
getDouble(
"decoupledFraction", 0);
487 GearDir moduleParams(content,
"Modules");
488 GearDir glueParams(moduleParams,
"Glue");
490 for (
int slotID = 1; slotID <= numModules; slotID++) {
491 std::string gearName =
"Module[@slotID='" + std::to_string(slotID) +
"']";
492 GearDir slotParams(moduleParams, gearName);
497 int cNumber = slotParams.
getInt(
"ConstructionNumber");
498 module.setModuleCNumber(cNumber);
499 module.setName(addNumber(module.getName(), cNumber));
501 auto prism = createPrism(content, slotParams.
getString(
"Prism"));
502 prism.setName(addNumber(prism.getName(), cNumber));
503 module.setPrism(prism);
505 auto barSegment2 = createBarSegment(content, slotParams.
getString(
"BarSegment2"));
506 barSegment2.setName(addNumber(barSegment2.getName() +
"2-", cNumber));
507 barSegment2.setGlue(glueParams.
getLength(
"Thicknes1"),
509 module.setBarSegment2(barSegment2);
511 auto barSegment1 = createBarSegment(content, slotParams.
getString(
"BarSegment1"));
512 barSegment1.setName(addNumber(barSegment1.getName() +
"1-", cNumber));
513 barSegment1.setGlue(glueParams.
getLength(
"Thicknes2"),
515 module.setBarSegment1(barSegment1);
517 auto mirror = createMirrorSegment(content, slotParams.
getString(
"Mirror"));
518 mirror.setName(addNumber(mirror.getName(), cNumber));
519 mirror.setGlue(glueParams.
getLength(
"Thicknes3"),
521 module.setMirrorSegment(mirror);
523 module.setPMTArray(pmtArray);
524 if (decoupledFraction > 0) module.generateDecoupledPMTs(decoupledFraction);
531 GearDir displacedGeometry(content,
"DisplacedGeometry");
532 if (displacedGeometry) {
533 if (displacedGeometry.
getInt(
"SwitchON") != 0) {
534 B2WARNING(
"TOP: displaced geometry is activated");
536 int moduleID = slot.getInt(
"@ID");
538 B2WARNING(
"TOPGeometryPar: DisplacedGeometry.xml: invalid moduleID."
539 <<
LogVar(
"moduleID", moduleID));
545 slot.getAngle(
"alpha"),
546 slot.getAngle(
"beta"),
547 slot.getAngle(
"gamma"));
549 module.setModuleDisplacement(moduleDispl);
556 GearDir displacedPMTArrays(content,
"DisplacedPMTArrays");
557 if (displacedPMTArrays) {
558 if (displacedPMTArrays.
getInt(
"SwitchON") != 0) {
559 B2WARNING(
"TOP: displaced PMT arrays are activated");
561 int moduleID = slot.getInt(
"@ID");
563 B2WARNING(
"TOPGeometryPar: DisplacedPMTArrays.xml: invalid moduleID."
564 <<
LogVar(
"moduleID", moduleID));
569 slot.getAngle(
"alpha"));
571 module.setPMTArrayDisplacement(arrayDispl);
578 GearDir brokenGlues(content,
"BrokenGlues");
580 if (brokenGlues.
getInt(
"SwitchON") != 0) {
581 auto material = brokenGlues.
getString(
"material");
583 int moduleID = slot.getInt(
"@ID");
585 B2WARNING(
"TOPGeometryPar: BrokenGlues.xml: invalid moduleID."
586 <<
LogVar(
"moduleID", moduleID));
590 for (
const GearDir& glue : slot.getNodes(
"Glue")) {
591 int glueID = glue.getInt(
"@ID");
592 double fraction = glue.getDouble(
"fraction");
593 if (fraction <= 0)
continue;
594 double angle = glue.getAngle(
"angle");
595 module.setBrokenGlue(glueID, fraction, angle, material);
603 GearDir peelOff(content,
"PeelOffCookies");
605 if (peelOff.
getInt(
"SwitchON") != 0) {
606 auto material = peelOff.
getString(
"material");
607 double thickness = peelOff.
getLength(
"thickness");
609 int moduleID = slot.getInt(
"@ID");
611 B2WARNING(
"TOPGeometryPar: PeelOffCookiess.xml: invalid moduleID."
612 <<
LogVar(
"moduleID", moduleID));
616 module.setPeelOffRegions(thickness, material);
617 for (
const GearDir& region : slot.getNodes(
"Region")) {
618 int regionID = region.getInt(
"@ID");
619 double fraction = region.getDouble(
"fraction");
620 if (fraction <= 0)
continue;
621 double angle = region.getAngle(
"angle");
622 module.appendPeelOffRegion(regionID, fraction, angle);
630 GearDir feParams(content,
"FrontEndGeo");
631 GearDir fbParams(feParams,
"FrontBoard");
639 GearDir hvParams(feParams,
"HVBoard");
646 GearDir bsParams(feParams,
"BoardStack");
659 GearDir qbbParams(content,
"QBB");
665 GearDir outerPanelParams(qbbParams,
"outerPanel");
668 outerPanelParams.
getLength(
"minThickness"),
669 outerPanelParams.
getLength(
"maxThickness"),
673 outerPanelParams.
getInt(
"N"),
675 outerPanelParams.
getString(
"edgeMaterial"),
676 "TOPOuterHoneycombPanel");
679 GearDir innerPanelParams(qbbParams,
"innerPanel");
682 innerPanelParams.
getLength(
"minThickness"),
683 innerPanelParams.
getLength(
"maxThickness"),
687 innerPanelParams.
getInt(
"N"),
689 innerPanelParams.
getString(
"edgeMaterial"),
690 "TOPInnerHoneycombPanel");
693 GearDir sideRailsParams(qbbParams,
"sideRails");
695 sideRailsParams.
getLength(
"reducedThickness"),
700 GearDir prismEnclParams(qbbParams,
"prismEnclosure");
704 prismEnclParams.
getLength(
"bottomThickness"),
705 prismEnclParams.
getLength(
"sideThickness"),
706 prismEnclParams.
getLength(
"backThickness"),
707 prismEnclParams.
getLength(
"frontThickness"),
708 prismEnclParams.
getLength(
"extensionThickness"),
712 GearDir endPlateParams(qbbParams,
"forwardEndPlate");
716 "TOPForwardEndPlate");
719 GearDir coldPlateParams(qbbParams,
"coldPlate");
721 coldPlateParams.
getString(
"baseMaterial"),
722 coldPlateParams.
getLength(
"coolThickness"),
724 coldPlateParams.
getString(
"coolMaterial"));
731 GearDir qeParams(content,
"QE");
732 std::vector<float> qeData;
734 qeData.push_back(Qeffi.getDouble(
""));
737 qeParams.
getLength(
"LambdaStep") / Unit::nm,
744 GearDir ttsParams(content,
"PMTs/TTS");
748 Gauss.getTime(
"mean"),
749 Gauss.getTime(
"sigma"));
756 GearDir pmtTTSParams(content,
"TTSofPMTs");
758 int type = ttsPar.getInt(
"type");
759 double tuneFactor = ttsPar.getDouble(
"PDEtuneFactor");
760 TOPNominalTTS tts(
"TTS of " + ttsPar.getString(
"@name") +
" PMT");
764 Gauss.getTime(
"mean"),
765 Gauss.getTime(
"sigma"));
774 GearDir tdcParams(content,
"TDC");
777 tdcParams.
getInt(
"subBits"),
778 tdcParams.
getTime(
"syncTimeBase"),
779 tdcParams.
getInt(
"numofBunches"),
781 tdcParams.
getTime(
"pileupTime"),
782 tdcParams.
getTime(
"doubleHitResolution"),
783 tdcParams.
getTime(
"timeJitter"),
790 pmtParams.
getTime(
"TDCbitwidth"),
791 pmtParams.
getTime(
"TDCoffset", 0),
792 pmtParams.
getTime(
"TDCpileupTime", 0),
793 pmtParams.
getTime(
"TDCdoubleHitResolution", 0),
794 pmtParams.
getTime(
"TDCtimeJitter", 50e-3),
795 pmtParams.
getDouble(
"TDCefficiency", 1));
801 GearDir shapeParams(content,
"SignalShape");
803 GearDir noiseBandwidth(shapeParams,
"noiseBandwidth");
806 shapeParams.
getTime(
"tailTimeConstant"),
807 noiseBandwidth.
getDouble(
"pole1") / 1000,
808 noiseBandwidth.
getDouble(
"pole2") / 1000);
814 GearDir calpulseParams(content,
"CalPulseShape");
815 if (calpulseParams) {
816 GearDir noiseBandwidth(calpulseParams,
"noiseBandwidth");
819 calpulseParams.
getTime(
"tailTimeConstant"),
820 noiseBandwidth.
getDouble(
"pole1") / 1000,
821 noiseBandwidth.
getDouble(
"pole2") / 1000);
827 std::string materialNode =
"Materials/Material[@name='TOPWavelengthFilterIHU340']";
828 GearDir filterMaterial(content, materialNode);
829 if (!filterMaterial) {
830 B2FATAL(
"TOPGeometry: " << materialNode <<
" not found");
832 GearDir property(filterMaterial,
"Property[@name='ABSLENGTH']");
834 B2FATAL(
"TOPGeometry: " << materialNode <<
", Property ABSLENGTH not found");
836 int numNodes =
property.getNumberNodes(
"value");
838 double conversion = Unit::convertValue(1, property.
getString(
"@unit",
"GeV"));
839 std::vector<double> energies;
840 std::vector<double> absLengths;
841 for (
int i = 0; i < numNodes; i++) {
842 GearDir value(property,
"value", i + 1);
843 energies.push_back(value.getDouble(
"@energy") * conversion / Unit::eV);
844 absLengths.push_back(value.getDouble() * Unit::mm);
846 TSpline3 spline(
"absLen", energies.data(), absLengths.data(), energies.size());
847 double lambdaFirst = c_hc / energies.back();
848 double lambdaLast = c_hc / energies[0];
849 double lambdaStep = 5;
850 int numSteps = (lambdaLast - lambdaFirst) / lambdaStep + 1;
851 const double filterThickness = arrayParams.
getLength(
"wavelengthFilter/thickness");
852 std::vector<float> bulkTransmittances;
853 for (
int i = 0; i < numSteps; i++) {
854 double wavelength = lambdaFirst + lambdaStep * i;
855 double energy = c_hc / wavelength;
856 double absLen = spline.Eval(energy);
857 bulkTransmittances.push_back(exp(-filterThickness / absLen));
862 B2FATAL(
"TOPGeometry: " << materialNode
863 <<
", Property ABSLENGTH has less than 2 nodes");
871 const std::string& SN)
874 GearDir params(content,
"QuartzBars/QuartzBar[@SerialNumber='" + SN +
"']");
876 params.getLength(
"Thickness"),
877 params.getLength(
"Length"),
878 params.getString(
"Material"));
882 std::string surfaceName = params.getString(
"OpticalSurface");
883 double sigmaAlpha = params.getDouble(
"SigmaAlpha");
884 GearDir surfaceParams(content,
"Modules/Surface[@name='" + surfaceName +
"']");
885 auto& materials = geometry::Materials::getInstance();
886 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
894 const std::string& SN)
897 GearDir params(content,
"Mirrors/Mirror[@SerialNumber='" + SN +
"']");
899 params.getLength(
"Thickness"),
900 params.getLength(
"Length"),
901 params.getString(
"Material"));
903 mirror.
setRadius(params.getLength(
"Radius"));
907 auto& materials = geometry::Materials::getInstance();
908 GearDir coatingParams(params,
"Surface");
909 mirror.
setCoating(params.getLength(
"mirrorThickness"),
"Al",
910 materials.createOpticalSurfaceConfig(coatingParams));
913 std::string surfaceName = params.getString(
"OpticalSurface");
914 double sigmaAlpha = params.getDouble(
"SigmaAlpha");
915 GearDir surfaceParams(content,
"Modules/Surface[@name='" + surfaceName +
"']");
916 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
924 const std::string& SN)
927 GearDir params(content,
"Prisms/Prism[@SerialNumber='" + SN +
"']");
929 params.getLength(
"Thickness"),
930 params.getLength(
"Length"),
931 params.getLength(
"ExitThickness"),
933 params.getString(
"Material"));
934 prism.
setAngle(params.getAngle(
"Angle"));
938 std::string surfaceName = params.getString(
"OpticalSurface");
939 double sigmaAlpha = params.getDouble(
"SigmaAlpha");
940 GearDir surfaceParams(content,
"Modules/Surface[@name='" + surfaceName +
"']");
941 auto& materials = geometry::Materials::getInstance();
942 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
948 std::string TOPGeometryPar::addNumber(
const std::string& str,
unsigned number)
952 ss << str <<
"0" << number;