Create a parameter object from gearbox.
438 {
439 TOPGeometry* geo = new TOPGeometry("TOPGeometry");
440
441
442
443 GearDir pmtParams(content, "PMTs/PMT");
444 TOPGeoPMT pmt(pmtParams.getLength("ModuleXSize"),
445 pmtParams.getLength("ModuleYSize"),
446 pmtParams.getLength("ModuleZSize") +
447 pmtParams.getLength("WindowThickness") +
448 pmtParams.getLength("BottomThickness"));
449 pmt.setWallThickness(pmtParams.getLength("ModuleWall"));
450 pmt.setWallMaterial(pmtParams.getString("wallMaterial"));
451 pmt.setFillMaterial(pmtParams.getString("fillMaterial"));
452 pmt.setSensVolume(pmtParams.getLength("SensXSize"),
453 pmtParams.getLength("SensYSize"),
454 pmtParams.getLength("SensThickness"),
455 pmtParams.getString("sensMaterial"));
456 pmt.setNumPixels(pmtParams.getInt("PadXNum"),
457 pmtParams.getInt("PadYNum"));
458 pmt.setWindow(pmtParams.getLength("WindowThickness"),
459 pmtParams.getString("winMaterial"));
460 pmt.setBottom(pmtParams.getLength("BottomThickness"),
461 pmtParams.getString("botMaterial"));
462
464 GearDir reflEdgeSurfParams(pmtParams, "reflectiveEdge/Surface");
465 pmt.setReflEdge(pmtParams.getLength("reflectiveEdge/width"),
466 pmtParams.getLength("reflectiveEdge/thickness"),
467 materials.createOpticalSurfaceConfig(reflEdgeSurfParams));
468
469 GearDir arrayParams(content, "PMTs");
470 TOPGeoPMTArray pmtArray(arrayParams.getInt("nPMTx"),
471 arrayParams.getInt("nPMTy"),
472 arrayParams.getLength("Xgap"),
473 arrayParams.getLength("Ygap"),
474 arrayParams.getString("stackMaterial"),
475 pmt);
476 pmtArray.setSiliconeCookie(arrayParams.getLength("siliconeCookie/thickness"),
477 arrayParams.getString("siliconeCookie/material"));
478 pmtArray.setWavelengthFilter(arrayParams.getLength("wavelengthFilter/thickness"),
479 arrayParams.getString("wavelengthFilter/material"));
480 pmtArray.setAirGap(arrayParams.getLength("airGap", 0));
481 double decoupledFraction = arrayParams.getDouble("decoupledFraction", 0);
482
483
484
485 GearDir moduleParams(content, "Modules");
486 GearDir glueParams(moduleParams, "Glue");
487 int numModules = moduleParams.getNumberNodes("Module");
488 for (int slotID = 1; slotID <= numModules; slotID++) {
489 std::string gearName = "Module[@slotID='" + std::to_string(slotID) + "']";
490 GearDir slotParams(moduleParams, gearName);
491 TOPGeoModule module(slotID,
492 slotParams.getLength("Radius"),
493 slotParams.getAngle("Phi"),
494 slotParams.getLength("BackwardZ"));
495 int cNumber = slotParams.getInt("ConstructionNumber");
496 module.setModuleCNumber(cNumber);
497 module.setName(
addNumber(module.getName(), cNumber));
498
499 auto prism =
createPrism(content, slotParams.getString(
"Prism"));
500 prism.setName(
addNumber(prism.getName(), cNumber));
501 module.setPrism(prism);
502
503 auto barSegment2 =
createBarSegment(content, slotParams.getString(
"BarSegment2"));
504 barSegment2.setName(
addNumber(barSegment2.getName() +
"2-", cNumber));
505 barSegment2.setGlue(glueParams.getLength("Thicknes1"),
506 glueParams.getString("GlueMaterial"));
507 module.setBarSegment2(barSegment2);
508
509 auto barSegment1 =
createBarSegment(content, slotParams.getString(
"BarSegment1"));
510 barSegment1.setName(
addNumber(barSegment1.getName() +
"1-", cNumber));
511 barSegment1.setGlue(glueParams.getLength("Thicknes2"),
512 glueParams.getString("GlueMaterial"));
513 module.setBarSegment1(barSegment1);
514
516 mirror.setName(
addNumber(mirror.getName(), cNumber));
517 mirror.setGlue(glueParams.getLength("Thicknes3"),
518 glueParams.getString("GlueMaterial"));
519 module.setMirrorSegment(mirror);
520
521 module.setPMTArray(pmtArray);
522 if (decoupledFraction > 0) module.generateDecoupledPMTs(decoupledFraction);
523
524 geo->appendModule(module);
525 }
526
527
528
529 GearDir displacedGeometry(content, "DisplacedGeometry");
530 if (displacedGeometry) {
531 if (displacedGeometry.getInt("SwitchON") != 0) {
532 B2WARNING("TOP: displaced geometry is activated");
533 for (const GearDir& slot : displacedGeometry.getNodes("Slot")) {
534 int moduleID = slot.getInt("@ID");
535 if (!geo->isModuleIDValid(moduleID)) {
536 B2WARNING("TOPGeometryPar: DisplacedGeometry.xml: invalid moduleID."
537 <<
LogVar(
"moduleID", moduleID));
538 continue;
539 }
540 TOPGeoModuleDisplacement moduleDispl(slot.getLength("x"),
541 slot.getLength("y"),
542 slot.getLength("z"),
543 slot.getAngle("alpha"),
544 slot.getAngle("beta"),
545 slot.getAngle("gamma"));
546 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
547 module.setModuleDisplacement(moduleDispl);
548 }
549 }
550 }
551
552
553
554 GearDir displacedPMTArrays(content, "DisplacedPMTArrays");
555 if (displacedPMTArrays) {
556 if (displacedPMTArrays.getInt("SwitchON") != 0) {
557 B2WARNING("TOP: displaced PMT arrays are activated");
558 for (const GearDir& slot : displacedPMTArrays.getNodes("Slot")) {
559 int moduleID = slot.getInt("@ID");
560 if (!geo->isModuleIDValid(moduleID)) {
561 B2WARNING("TOPGeometryPar: DisplacedPMTArrays.xml: invalid moduleID."
562 <<
LogVar(
"moduleID", moduleID));
563 continue;
564 }
565 TOPGeoPMTArrayDisplacement arrayDispl(slot.getLength("x"),
566 slot.getLength("y"),
567 slot.getAngle("alpha"));
568 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
569 module.setPMTArrayDisplacement(arrayDispl);
570 }
571 }
572 }
573
574
575
576 GearDir brokenGlues(content, "BrokenGlues");
577 if (brokenGlues) {
578 if (brokenGlues.getInt("SwitchON") != 0) {
579 auto material = brokenGlues.getString("material");
580 for (const GearDir& slot : brokenGlues.getNodes("Slot")) {
581 int moduleID = slot.getInt("@ID");
582 if (!geo->isModuleIDValid(moduleID)) {
583 B2WARNING("TOPGeometryPar: BrokenGlues.xml: invalid moduleID."
584 <<
LogVar(
"moduleID", moduleID));
585 continue;
586 }
587 auto& module = const_cast<TOPGeoModule&>(geo->getModule(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);
594 }
595 }
596 }
597 }
598
599
600
601 GearDir peelOff(content, "PeelOffCookies");
602 if (peelOff) {
603 if (peelOff.getInt("SwitchON") != 0) {
604 auto material = peelOff.getString("material");
605 double thickness = peelOff.getLength("thickness");
606 for (const GearDir& slot : peelOff.getNodes("Slot")) {
607 int moduleID = slot.getInt("@ID");
608 if (!geo->isModuleIDValid(moduleID)) {
609 B2WARNING("TOPGeometryPar: PeelOffCookiess.xml: invalid moduleID."
610 <<
LogVar(
"moduleID", moduleID));
611 continue;
612 }
613 auto& module = const_cast<TOPGeoModule&>(geo->getModule(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);
621 }
622 }
623 }
624 }
625
626
627
628 GearDir feParams(content, "FrontEndGeo");
629 GearDir fbParams(feParams, "FrontBoard");
630 TOPGeoFrontEnd frontEnd;
631 frontEnd.setFrontBoard(fbParams.getLength("width"),
632 fbParams.getLength("height"),
633 fbParams.getLength("thickness"),
634 fbParams.getLength("gap"),
635 fbParams.getLength("y"),
636 fbParams.getString("material"));
637 GearDir hvParams(feParams, "HVBoard");
638 frontEnd.setHVBoard(hvParams.getLength("width"),
639 hvParams.getLength("length"),
640 hvParams.getLength("thickness"),
641 hvParams.getLength("gap"),
642 hvParams.getLength("y"),
643 hvParams.getString("material"));
644 GearDir bsParams(feParams, "BoardStack");
645 frontEnd.setBoardStack(bsParams.getLength("width"),
646 bsParams.getLength("height"),
647 bsParams.getLength("length"),
648 bsParams.getLength("gap"),
649 bsParams.getLength("y"),
650 bsParams.getString("material"),
651 bsParams.getLength("spacerWidth"),
652 bsParams.getString("spacerMaterial"));
653 geo->setFrontEnd(frontEnd, feParams.getInt("numBoardStacks"));
654
655
656
657 GearDir qbbParams(content, "QBB");
658 TOPGeoQBB qbb(qbbParams.getLength("width"),
659 qbbParams.getLength("length"),
660 qbbParams.getLength("prismPosition"),
661 qbbParams.getString("material"));
662
663 GearDir outerPanelParams(qbbParams, "outerPanel");
664 TOPGeoHoneycombPanel outerPanel(outerPanelParams.getLength("width"),
665 outerPanelParams.getLength("length"),
666 outerPanelParams.getLength("minThickness"),
667 outerPanelParams.getLength("maxThickness"),
668 outerPanelParams.getLength("radius"),
669 outerPanelParams.getLength("edgeWidth"),
670 outerPanelParams.getLength("y"),
671 outerPanelParams.getInt("N"),
672 outerPanelParams.getString("material"),
673 outerPanelParams.getString("edgeMaterial"),
674 "TOPOuterHoneycombPanel");
675 qbb.setOuterPanel(outerPanel);
676
677 GearDir innerPanelParams(qbbParams, "innerPanel");
678 TOPGeoHoneycombPanel innerPanel(innerPanelParams.getLength("width"),
679 innerPanelParams.getLength("length"),
680 innerPanelParams.getLength("minThickness"),
681 innerPanelParams.getLength("maxThickness"),
682 innerPanelParams.getLength("radius"),
683 innerPanelParams.getLength("edgeWidth"),
684 innerPanelParams.getLength("y"),
685 innerPanelParams.getInt("N"),
686 innerPanelParams.getString("material"),
687 innerPanelParams.getString("edgeMaterial"),
688 "TOPInnerHoneycombPanel");
689 qbb.setInnerPanel(innerPanel);
690
691 GearDir sideRailsParams(qbbParams, "sideRails");
692 TOPGeoSideRails sideRails(sideRailsParams.getLength("thickness"),
693 sideRailsParams.getLength("reducedThickness"),
694 sideRailsParams.getLength("height"),
695 sideRailsParams.getString("material"));
696 qbb.setSideRails(sideRails);
697
698 GearDir prismEnclParams(qbbParams, "prismEnclosure");
699 TOPGeoPrismEnclosure prismEncl(prismEnclParams.getLength("length"),
700 prismEnclParams.getLength("height"),
701 prismEnclParams.getAngle("angle"),
702 prismEnclParams.getLength("bottomThickness"),
703 prismEnclParams.getLength("sideThickness"),
704 prismEnclParams.getLength("backThickness"),
705 prismEnclParams.getLength("frontThickness"),
706 prismEnclParams.getLength("extensionThickness"),
707 prismEnclParams.getString("material"));
708 qbb.setPrismEnclosure(prismEncl);
709
710 GearDir endPlateParams(qbbParams, "forwardEndPlate");
711 TOPGeoEndPlate endPlate(endPlateParams.getLength("thickness"),
712 endPlateParams.getLength("height"),
713 endPlateParams.getString("material"),
714 "TOPForwardEndPlate");
715 qbb.setEndPlate(endPlate);
716
717 GearDir coldPlateParams(qbbParams, "coldPlate");
718 TOPGeoColdPlate coldPlate(coldPlateParams.getLength("baseThickness"),
719 coldPlateParams.getString("baseMaterial"),
720 coldPlateParams.getLength("coolThickness"),
721 coldPlateParams.getLength("coolWidth"),
722 coldPlateParams.getString("coolMaterial"));
723 qbb.setColdPlate(coldPlate);
724
725 geo->setQBB(qbb);
726
727
728
729 GearDir qeParams(content, "QE");
730 std::vector<float> qeData;
731 for (const GearDir& Qeffi : qeParams.getNodes("Qeffi")) {
732 qeData.push_back(Qeffi.getDouble(""));
733 }
734 TOPNominalQE nominalQE(qeParams.getLength(
"LambdaFirst") /
Unit::nm,
735 qeParams.getLength(
"LambdaStep") /
Unit::nm,
736 qeParams.getDouble("ColEffi"),
737 qeData);
738 geo->setNominalQE(nominalQE);
739
740
741
742 GearDir ttsParams(content, "PMTs/TTS");
743 TOPNominalTTS nominalTTS("TOPNominalTTS");
744 for (const GearDir& Gauss : ttsParams.getNodes("Gauss")) {
745 nominalTTS.appendGaussian(Gauss.getDouble("fraction"),
746 Gauss.getTime("mean"),
747 Gauss.getTime("sigma"));
748 }
749 nominalTTS.normalize();
750 geo->setNominalTTS(nominalTTS);
751
752
753
754 GearDir pmtTTSParams(content, "TTSofPMTs");
755 for (const GearDir& ttsPar : pmtTTSParams.getNodes("TTSpar")) {
756 int type = ttsPar.getInt("type");
757 double tuneFactor = ttsPar.getDouble("PDEtuneFactor");
758 TOPNominalTTS tts("TTS of " + ttsPar.getString("@name") + " PMT");
759 tts.setPMTType(type);
760 for (const GearDir& Gauss : ttsPar.getNodes("Gauss")) {
761 tts.appendGaussian(Gauss.getDouble("fraction"),
762 Gauss.getTime("mean"),
763 Gauss.getTime("sigma"));
764 }
765 tts.normalize();
766 geo->appendTTS(tts);
767 geo->appendPDETuningFactor(type, tuneFactor);
768 }
769
770
771
772 GearDir tdcParams(content, "TDC");
773 if (tdcParams) {
774 TOPNominalTDC nominalTDC(tdcParams.getInt("numWindows"),
775 tdcParams.getInt("subBits"),
776 tdcParams.getTime("syncTimeBase"),
777 tdcParams.getInt("numofBunches"),
778 tdcParams.getTime("offset"),
779 tdcParams.getTime("pileupTime"),
780 tdcParams.getTime("doubleHitResolution"),
781 tdcParams.getTime("timeJitter"),
782 tdcParams.getDouble("efficiency"));
783 nominalTDC.setADCBits(tdcParams.getInt("adcBits"));
784 nominalTDC.setAveragePedestal(tdcParams.getInt("averagePedestal"));
785 geo->setNominalTDC(nominalTDC);
786 } else {
787 TOPNominalTDC nominalTDC(pmtParams.getInt("TDCbits"),
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));
794 geo->setNominalTDC(nominalTDC);
795 }
796
797
798
799 GearDir shapeParams(content, "SignalShape");
800 if (shapeParams) {
801 GearDir noiseBandwidth(shapeParams, "noiseBandwidth");
802 TOPSignalShape signalShape(shapeParams.getArray("sampleValues"),
803 geo->getNominalTDC().getSampleWidth(),
804 shapeParams.getTime("tailTimeConstant"),
805 noiseBandwidth.getDouble("pole1") / 1000,
806 noiseBandwidth.getDouble("pole2") / 1000);
807 geo->setSignalShape(signalShape);
808 }
809
810
811
812 GearDir calpulseParams(content, "CalPulseShape");
813 if (calpulseParams) {
814 GearDir noiseBandwidth(calpulseParams, "noiseBandwidth");
815 TOPSignalShape shape(calpulseParams.getArray("sampleValues"),
816 geo->getNominalTDC().getSampleWidth(),
817 calpulseParams.getTime("tailTimeConstant"),
818 noiseBandwidth.getDouble("pole1") / 1000,
819 noiseBandwidth.getDouble("pole2") / 1000);
820 geo->setCalPulseShape(shape);
821 }
822
823
824
825 std::string materialNode = "Materials/Material[@name='TOPWavelengthFilterIHU340']";
826 GearDir filterMaterial(content, materialNode);
827 if (!filterMaterial) {
828 B2FATAL("TOPGeometry: " << materialNode << " not found");
829 }
830 GearDir property(filterMaterial, "Property[@name='ABSLENGTH']");
831 if (!property) {
832 B2FATAL("TOPGeometry: " << materialNode << ", Property ABSLENGTH not found");
833 }
834 int numNodes = property.getNumberNodes("value");
835 if (numNodes > 1) {
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);
843 }
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));
856 }
857 TOPWavelengthFilter
filter(lambdaFirst, lambdaStep, bulkTransmittances);
858 geo->setWavelengthFilter(
filter);
859 } else {
860 B2FATAL("TOPGeometry: " << materialNode
861 << ", Property ABSLENGTH has less than 2 nodes");
862 }
863
864 return geo;
865 }
TOPGeoPrism createPrism(const GearDir &content, const std::string &serialNumber)
Create a parameter object from gearbox for prism.
TOPGeoMirrorSegment createMirrorSegment(const GearDir &content, const std::string &serialNumber)
Create a parameter object from gearbox for mirror segment.
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].
TOPGeoBarSegment createBarSegment(const GearDir &content, const std::string &serialNumber)
Create a parameter object from gearbox for bar segment.
static const double mm
[millimeters]
static const double nm
[nanometers]
static const double eV
[electronvolt]
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.
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