Belle II Software development
TOPGeometryPar Class Reference

Singleton class for TOP Geometry Parameters. More...

#include <TOPGeometryPar.h>

Public Member Functions

virtual ~TOPGeometryPar ()
 Destructor.
 
void Initialize (const GearDir &content)
 Initialize from Gearbox (XML)
 
void Initialize ()
 Initialize from database.
 
bool isValid () const
 check if the geometry is available
 
const TOPGeometrygetGeometry () const
 Returns pointer to geometry object using basf2 units.
 
const FrontEndMappergetFrontEndMapper () const
 Returns front-end mapper (mapping of SCROD's to positions within TOP modules)
 
const ChannelMappergetChannelMapper () const
 Returns default channel mapper (mapping of channels to pixels)
 
const ChannelMappergetChannelMapper (ChannelMapper::EType type) const
 Returns channel mapper (mapping of channels to pixels) - Gearbox only.
 
double getPMTEfficiencyEnvelope (double energy) const
 Returns PMT efficiency envelope, e.g.
 
double getPMTEfficiency (double energy, int moduleID, int pmtID, double x, double y) const
 Returns PMT pixel efficiency, a product of quantum and collection efficiency.
 
double getRelativePixelEfficiency (int moduleID, int pixelID) const
 Returns relative pixel efficiency (including CE, RQE and threshold efficiency)
 
double getRelativePDEonMC (int moduleID, int pixelID) const
 Returns relative PDE on MC (including CE, tuning factor and threshold efficiency)
 
unsigned getPMTType (int moduleID, int pmtID) const
 Returns PMT type at a given position.
 
const TOPNominalTTSgetTTS (int moduleID, int pmtID) const
 Returns TTS of a PMT at given position.
 
double getPhaseIndex (double energy) const
 Returns phase refractive index of quartz at given photon energy.
 
double getGroupIndex (double energy) const
 Returns group refractive index of quartz at given photon energy.
 
double getPhaseIndexDerivative (double energy) const
 Returns the derivative (dn/dE) of phase refractive index of quartz at given photon energy.
 
double getGroupIndexDerivative (double energy) const
 Returns the derivative (dn_g/dE) of group refractive index of quartz at given photon energy.
 
double getAbsorptionLength (double energy) const
 Returns bulk absorption lenght of quartz at given photon energy.
 

Static Public Member Functions

static TOPGeometryParInstance ()
 Static method to obtain the pointer to its instance.
 

Static Public Attributes

static const double c_hc = 1239.84193
 Planck constant times speed of light in [eV*nm].
 

Private Member Functions

 TOPGeometryPar ()
 Hidden constructor since it is a singleton class.
 
void finalizeInitialization ()
 finalize initialization
 
TOPGeometrycreateConfiguration (const GearDir &content)
 Create a parameter object from gearbox.
 
TOPGeoBarSegment createBarSegment (const GearDir &content, const std::string &serialNumber)
 Create a parameter object from gearbox for bar segment.
 
TOPGeoMirrorSegment createMirrorSegment (const GearDir &content, const std::string &serialNumber)
 Create a parameter object from gearbox for mirror segment.
 
TOPGeoPrism createPrism (const GearDir &content, const std::string &serialNumber)
 Create a parameter object from gearbox for prism.
 
std::string addNumber (const std::string &str, unsigned number)
 Adds number to string.
 
void clearCache ()
 Clears cache for PMT dependent QE data - function is used in call backs.
 
void setEnvelopeQE () const
 Constructs envelope of quantum efficiency from PMT data.
 
void mapPmtQEToPositions () const
 Maps PMT QE data to positions within the detector.
 
void mapPmtTypeToPositions () const
 Maps PMT type to positions within the detector.
 
void prepareRelEfficiencies () const
 Prepares a map of relative pixel quantum times collection efficiencies (relative to nominal one)
 
void prepareRelPDEonMC () const
 Prepares a map of relative pixel photon detection efficiencies on MC.
 
int getUniquePmtID (int moduleID, int pmtID) const
 Returns unique PMT ID within the detector.
 
int getUniquePixelID (int moduleID, int pixelID) const
 Returns unique pixel ID within the detector.
 
double integralOfQE (const std::vector< float > &qe, double ce, double lambdaFirst, double lambdaStep) const
 Returns integral of quantum efficiency over photon energies.
 
double refractiveIndex (double lambda) const
 Quartz refractive index (SellMeier equation)
 

Private Attributes

TOPGeometrym_geo = 0
 geometry parameters from Gearbox
 
DBObjPtr< TOPGeometry > * m_geoDB = 0
 geometry parameters from database
 
bool m_fromDB = false
 parameters from database or Gearbox
 
bool m_valid = false
 true if geometry is available
 
bool m_oldPayload = false
 true if old payload found in DB
 
bool m_BfieldOn = true
 true if B field is on
 
FrontEndMapper m_frontEndMapper
 front end electronics mapper
 
ChannelMapper m_channelMapperIRS3B
 channel-pixel mapper
 
ChannelMapper m_channelMapperIRSX
 channel-pixel mapper
 
OptionalDBArray< TOPPmtInstallationm_pmtInstalled
 PMT installation data.
 
OptionalDBArray< TOPPmtQEm_pmtQEData
 quantum efficiencies
 
DBObjPtr< TOPCalChannelRQEm_channelRQE
 channel relative quantum effi.
 
DBObjPtr< TOPCalChannelThresholdEffm_thresholdEff
 channel threshold effi.
 
DBObjPtr< TOPCalChannelPulseHeightm_pulseHeights
 channel pulse height parametrizations
 
TOPNominalQE m_envelopeQE
 envelope quantum efficiency
 
std::map< int, const TOPPmtQE * > m_pmts
 QE data mapped to positions.
 
std::map< int, double > m_relEfficiencies
 pixel relative QE
 
std::map< int, double > m_relPDEonMC
 pixel relative photon detection efficiencies on MC
 
std::map< int, unsigned > m_pmtTypes
 PMT types mapped to positions.
 

Static Private Attributes

static TOPGeometryPars_instance = 0
 Pointer to the class instance.
 

Detailed Description

Singleton class for TOP Geometry Parameters.

Definition at line 36 of file TOPGeometryPar.h.

Constructor & Destructor Documentation

◆ ~TOPGeometryPar()

~TOPGeometryPar ( )
virtual

Destructor.

Definition at line 35 of file TOPGeometryPar.cc.

36 {
37 if (m_geo) delete m_geo;
38 if (m_geoDB) delete m_geoDB;
39 s_instance = 0;
40 }

◆ TOPGeometryPar()

TOPGeometryPar ( )
inlineprivate

Hidden constructor since it is a singleton class.

Definition at line 189 of file TOPGeometryPar.h.

190 {}

Member Function Documentation

◆ addNumber()

std::string addNumber ( const std::string & str,
unsigned number )
private

Adds number to string.

Parameters
strstring
numbernumber to be added
Returns
string with a number

Definition at line 994 of file TOPGeometryPar.cc.

995 {
996 stringstream ss;
997 if (number < 10) {
998 ss << str << "0" << number;
999 } else {
1000 ss << str << number;
1001 }
1002 string out;
1003 ss >> out;
1004 return out;
1005 }

◆ clearCache()

void clearCache ( )
private

Clears cache for PMT dependent QE data - function is used in call backs.

Definition at line 158 of file TOPGeometryPar.cc.

159 {
160 m_envelopeQE.clear();
161 m_pmts.clear();
162 m_relEfficiencies.clear();
163 m_relPDEonMC.clear();
164 m_pmtTypes.clear();
165 }

◆ createBarSegment()

TOPGeoBarSegment createBarSegment ( const GearDir & content,
const std::string & serialNumber )
private

Create a parameter object from gearbox for bar segment.

Parameters
contentXML data directory
serialNumberbar segment serial number

Definition at line 916 of file TOPGeometryPar.cc.

918 {
919 // dimensions and material
920 GearDir params(content, "QuartzBars/QuartzBar[@SerialNumber='" + SN + "']");
921 TOPGeoBarSegment bar(params.getLength("Width"),
922 params.getLength("Thickness"),
923 params.getLength("Length"),
924 params.getString("Material"));
925 bar.setVendorData(params.getString("Vendor"), SN);
926
927 // optical surface
928 std::string surfaceName = params.getString("OpticalSurface");
929 double sigmaAlpha = params.getDouble("SigmaAlpha");
930 GearDir surfaceParams(content, "Modules/Surface[@name='" + surfaceName + "']");
931 auto& materials = geometry::Materials::getInstance();
932 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
933 bar.setSurface(quartzSurface, sigmaAlpha);
934
935 return bar;
936 }

◆ createConfiguration()

TOPGeometry * createConfiguration ( const GearDir & content)
private

Create a parameter object from gearbox.

Parameters
contentXML data directory

Definition at line 485 of file TOPGeometryPar.cc.

486 {
487 TOPGeometry* geo = new TOPGeometry("TOPGeometry");
488
489 // PMT array
490
491 GearDir pmtParams(content, "PMTs/PMT");
492 TOPGeoPMT pmt(pmtParams.getLength("ModuleXSize"),
493 pmtParams.getLength("ModuleYSize"),
494 pmtParams.getLength("ModuleZSize") +
495 pmtParams.getLength("WindowThickness") +
496 pmtParams.getLength("BottomThickness"));
497 pmt.setWallThickness(pmtParams.getLength("ModuleWall"));
498 pmt.setWallMaterial(pmtParams.getString("wallMaterial"));
499 pmt.setFillMaterial(pmtParams.getString("fillMaterial"));
500 pmt.setSensVolume(pmtParams.getLength("SensXSize"),
501 pmtParams.getLength("SensYSize"),
502 pmtParams.getLength("SensThickness"),
503 pmtParams.getString("sensMaterial"));
504 pmt.setNumPixels(pmtParams.getInt("PadXNum"),
505 pmtParams.getInt("PadYNum"));
506 pmt.setWindow(pmtParams.getLength("WindowThickness"),
507 pmtParams.getString("winMaterial"));
508 pmt.setBottom(pmtParams.getLength("BottomThickness"),
509 pmtParams.getString("botMaterial"));
510
511 auto& materials = geometry::Materials::getInstance();
512 GearDir reflEdgeSurfParams(pmtParams, "reflectiveEdge/Surface");
513 pmt.setReflEdge(pmtParams.getLength("reflectiveEdge/width"),
514 pmtParams.getLength("reflectiveEdge/thickness"),
515 materials.createOpticalSurfaceConfig(reflEdgeSurfParams));
516
517 GearDir arrayParams(content, "PMTs");
518 TOPGeoPMTArray pmtArray(arrayParams.getInt("nPMTx"),
519 arrayParams.getInt("nPMTy"),
520 arrayParams.getLength("Xgap"),
521 arrayParams.getLength("Ygap"),
522 arrayParams.getString("stackMaterial"),
523 pmt);
524 pmtArray.setSiliconeCookie(arrayParams.getLength("siliconeCookie/thickness"),
525 arrayParams.getString("siliconeCookie/material"));
526 pmtArray.setWavelengthFilter(arrayParams.getLength("wavelengthFilter/thickness"),
527 arrayParams.getString("wavelengthFilter/material"));
528 pmtArray.setAirGap(arrayParams.getLength("airGap", 0));
529 double decoupledFraction = arrayParams.getDouble("decoupledFraction", 0);
530
531 // modules
532
533 GearDir moduleParams(content, "Modules");
534 GearDir glueParams(moduleParams, "Glue");
535 int numModules = moduleParams.getNumberNodes("Module");
536 for (int slotID = 1; slotID <= numModules; slotID++) {
537 std::string gearName = "Module[@slotID='" + std::to_string(slotID) + "']";
538 GearDir slotParams(moduleParams, gearName);
539 TOPGeoModule module(slotID,
540 slotParams.getLength("Radius"),
541 slotParams.getAngle("Phi"),
542 slotParams.getLength("BackwardZ"));
543 int cNumber = slotParams.getInt("ConstructionNumber");
544 module.setModuleCNumber(cNumber);
545 module.setName(addNumber(module.getName(), cNumber));
546
547 auto prism = createPrism(content, slotParams.getString("Prism"));
548 prism.setName(addNumber(prism.getName(), cNumber));
549 module.setPrism(prism);
550
551 auto barSegment2 = createBarSegment(content, slotParams.getString("BarSegment2"));
552 barSegment2.setName(addNumber(barSegment2.getName() + "2-", cNumber));
553 barSegment2.setGlue(glueParams.getLength("Thicknes1"),
554 glueParams.getString("GlueMaterial"));
555 module.setBarSegment2(barSegment2);
556
557 auto barSegment1 = createBarSegment(content, slotParams.getString("BarSegment1"));
558 barSegment1.setName(addNumber(barSegment1.getName() + "1-", cNumber));
559 barSegment1.setGlue(glueParams.getLength("Thicknes2"),
560 glueParams.getString("GlueMaterial"));
561 module.setBarSegment1(barSegment1);
562
563 auto mirror = createMirrorSegment(content, slotParams.getString("Mirror"));
564 mirror.setName(addNumber(mirror.getName(), cNumber));
565 mirror.setGlue(glueParams.getLength("Thicknes3"),
566 glueParams.getString("GlueMaterial"));
567 module.setMirrorSegment(mirror);
568
569 module.setPMTArray(pmtArray);
570 if (decoupledFraction > 0) module.generateDecoupledPMTs(decoupledFraction);
571
572 geo->appendModule(module);
573 }
574
575 // displaced geometry (if defined)
576
577 GearDir displacedGeometry(content, "DisplacedGeometry");
578 if (displacedGeometry) {
579 if (displacedGeometry.getInt("SwitchON") != 0) {
580 B2WARNING("TOP: displaced geometry is activated");
581 for (const GearDir& slot : displacedGeometry.getNodes("Slot")) {
582 int moduleID = slot.getInt("@ID");
583 if (!geo->isModuleIDValid(moduleID)) {
584 B2WARNING("TOPGeometryPar: DisplacedGeometry.xml: invalid moduleID."
585 << LogVar("moduleID", moduleID));
586 continue;
587 }
588 TOPGeoModuleDisplacement moduleDispl(slot.getLength("x"),
589 slot.getLength("y"),
590 slot.getLength("z"),
591 slot.getAngle("alpha"),
592 slot.getAngle("beta"),
593 slot.getAngle("gamma"));
594 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
595 module.setModuleDisplacement(moduleDispl);
596 }
597 }
598 }
599
600 // displaced PMT arrays (if defined)
601
602 GearDir displacedPMTArrays(content, "DisplacedPMTArrays");
603 if (displacedPMTArrays) {
604 if (displacedPMTArrays.getInt("SwitchON") != 0) {
605 B2WARNING("TOP: displaced PMT arrays are activated");
606 for (const GearDir& slot : displacedPMTArrays.getNodes("Slot")) {
607 int moduleID = slot.getInt("@ID");
608 if (!geo->isModuleIDValid(moduleID)) {
609 B2WARNING("TOPGeometryPar: DisplacedPMTArrays.xml: invalid moduleID."
610 << LogVar("moduleID", moduleID));
611 continue;
612 }
613 TOPGeoPMTArrayDisplacement arrayDispl(slot.getLength("x"),
614 slot.getLength("y"),
615 slot.getAngle("alpha"));
616 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
617 module.setPMTArrayDisplacement(arrayDispl);
618 }
619 }
620 }
621
622 // broken glues (if any)
623
624 GearDir brokenGlues(content, "BrokenGlues");
625 if (brokenGlues) {
626 if (brokenGlues.getInt("SwitchON") != 0) {
627 auto material = brokenGlues.getString("material");
628 for (const GearDir& slot : brokenGlues.getNodes("Slot")) {
629 int moduleID = slot.getInt("@ID");
630 if (!geo->isModuleIDValid(moduleID)) {
631 B2WARNING("TOPGeometryPar: BrokenGlues.xml: invalid moduleID."
632 << LogVar("moduleID", moduleID));
633 continue;
634 }
635 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
636 for (const GearDir& glue : slot.getNodes("Glue")) {
637 int glueID = glue.getInt("@ID");
638 double fraction = glue.getDouble("fraction");
639 if (fraction <= 0) continue;
640 double angle = glue.getAngle("angle");
641 module.setBrokenGlue(glueID, fraction, angle, material);
642 }
643 }
644 }
645 }
646
647 // peel-off cookies (if any)
648
649 GearDir peelOff(content, "PeelOffCookies");
650 if (peelOff) {
651 if (peelOff.getInt("SwitchON") != 0) {
652 auto material = peelOff.getString("material");
653 double thickness = peelOff.getLength("thickness");
654 for (const GearDir& slot : peelOff.getNodes("Slot")) {
655 int moduleID = slot.getInt("@ID");
656 if (!geo->isModuleIDValid(moduleID)) {
657 B2WARNING("TOPGeometryPar: PeelOffCookiess.xml: invalid moduleID."
658 << LogVar("moduleID", moduleID));
659 continue;
660 }
661 auto& module = const_cast<TOPGeoModule&>(geo->getModule(moduleID));
662 module.setPeelOffRegions(thickness, material);
663 for (const GearDir& region : slot.getNodes("Region")) {
664 int regionID = region.getInt("@ID");
665 double fraction = region.getDouble("fraction");
666 if (fraction <= 0) continue;
667 double angle = region.getAngle("angle");
668 module.appendPeelOffRegion(regionID, fraction, angle);
669 }
670 }
671 }
672 }
673
674 // front-end electronics geometry
675
676 GearDir feParams(content, "FrontEndGeo");
677 GearDir fbParams(feParams, "FrontBoard");
678 TOPGeoFrontEnd frontEnd;
679 frontEnd.setFrontBoard(fbParams.getLength("width"),
680 fbParams.getLength("height"),
681 fbParams.getLength("thickness"),
682 fbParams.getLength("gap"),
683 fbParams.getLength("y"),
684 fbParams.getString("material"));
685 GearDir hvParams(feParams, "HVBoard");
686 frontEnd.setHVBoard(hvParams.getLength("width"),
687 hvParams.getLength("length"),
688 hvParams.getLength("thickness"),
689 hvParams.getLength("gap"),
690 hvParams.getLength("y"),
691 hvParams.getString("material"));
692 GearDir bsParams(feParams, "BoardStack");
693 frontEnd.setBoardStack(bsParams.getLength("width"),
694 bsParams.getLength("height"),
695 bsParams.getLength("length"),
696 bsParams.getLength("gap"),
697 bsParams.getLength("y"),
698 bsParams.getString("material"),
699 bsParams.getLength("spacerWidth"),
700 bsParams.getString("spacerMaterial"));
701 geo->setFrontEnd(frontEnd, feParams.getInt("numBoardStacks"));
702
703 // QBB
704
705 GearDir qbbParams(content, "QBB");
706 TOPGeoQBB qbb(qbbParams.getLength("width"),
707 qbbParams.getLength("length"),
708 qbbParams.getLength("prismPosition"),
709 qbbParams.getString("material"));
710
711 GearDir outerPanelParams(qbbParams, "outerPanel");
712 TOPGeoHoneycombPanel outerPanel(outerPanelParams.getLength("width"),
713 outerPanelParams.getLength("length"),
714 outerPanelParams.getLength("minThickness"),
715 outerPanelParams.getLength("maxThickness"),
716 outerPanelParams.getLength("radius"),
717 outerPanelParams.getLength("edgeWidth"),
718 outerPanelParams.getLength("y"),
719 outerPanelParams.getInt("N"),
720 outerPanelParams.getString("material"),
721 outerPanelParams.getString("edgeMaterial"),
722 "TOPOuterHoneycombPanel");
723 qbb.setOuterPanel(outerPanel);
724
725 GearDir innerPanelParams(qbbParams, "innerPanel");
726 TOPGeoHoneycombPanel innerPanel(innerPanelParams.getLength("width"),
727 innerPanelParams.getLength("length"),
728 innerPanelParams.getLength("minThickness"),
729 innerPanelParams.getLength("maxThickness"),
730 innerPanelParams.getLength("radius"),
731 innerPanelParams.getLength("edgeWidth"),
732 innerPanelParams.getLength("y"),
733 innerPanelParams.getInt("N"),
734 innerPanelParams.getString("material"),
735 innerPanelParams.getString("edgeMaterial"),
736 "TOPInnerHoneycombPanel");
737 qbb.setInnerPanel(innerPanel);
738
739 GearDir sideRailsParams(qbbParams, "sideRails");
740 TOPGeoSideRails sideRails(sideRailsParams.getLength("thickness"),
741 sideRailsParams.getLength("reducedThickness"),
742 sideRailsParams.getLength("height"),
743 sideRailsParams.getString("material"));
744 qbb.setSideRails(sideRails);
745
746 GearDir prismEnclParams(qbbParams, "prismEnclosure");
747 TOPGeoPrismEnclosure prismEncl(prismEnclParams.getLength("length"),
748 prismEnclParams.getLength("height"),
749 prismEnclParams.getAngle("angle"),
750 prismEnclParams.getLength("bottomThickness"),
751 prismEnclParams.getLength("sideThickness"),
752 prismEnclParams.getLength("backThickness"),
753 prismEnclParams.getLength("frontThickness"),
754 prismEnclParams.getLength("extensionThickness"),
755 prismEnclParams.getString("material"));
756 qbb.setPrismEnclosure(prismEncl);
757
758 GearDir endPlateParams(qbbParams, "forwardEndPlate");
759 TOPGeoEndPlate endPlate(endPlateParams.getLength("thickness"),
760 endPlateParams.getLength("height"),
761 endPlateParams.getString("material"),
762 "TOPForwardEndPlate");
763 qbb.setEndPlate(endPlate);
764
765 GearDir coldPlateParams(qbbParams, "coldPlate");
766 TOPGeoColdPlate coldPlate(coldPlateParams.getLength("baseThickness"),
767 coldPlateParams.getString("baseMaterial"),
768 coldPlateParams.getLength("coolThickness"),
769 coldPlateParams.getLength("coolWidth"),
770 coldPlateParams.getString("coolMaterial"));
771 qbb.setColdPlate(coldPlate);
772
773 geo->setQBB(qbb);
774
775 // nominal QE
776
777 GearDir qeParams(content, "QE");
778 std::vector<float> qeData;
779 for (const GearDir& Qeffi : qeParams.getNodes("Qeffi")) {
780 qeData.push_back(Qeffi.getDouble(""));
781 }
782 TOPNominalQE nominalQE(qeParams.getLength("LambdaFirst") / Unit::nm,
783 qeParams.getLength("LambdaStep") / Unit::nm,
784 qeParams.getDouble("ColEffi"),
785 qeData);
786 geo->setNominalQE(nominalQE);
787
788 // nominal TTS
789
790 GearDir ttsParams(content, "PMTs/TTS");
791 TOPNominalTTS nominalTTS("TOPNominalTTS");
792 for (const GearDir& Gauss : ttsParams.getNodes("Gauss")) {
793 nominalTTS.appendGaussian(Gauss.getDouble("fraction"),
794 Gauss.getTime("mean"),
795 Gauss.getTime("sigma"));
796 }
797 nominalTTS.normalize();
798 geo->setNominalTTS(nominalTTS);
799
800 // PMT type dependent TTS
801
802 GearDir pmtTTSParams(content, "TTSofPMTs");
803 for (const GearDir& ttsPar : pmtTTSParams.getNodes("TTSpar")) {
804 int type = ttsPar.getInt("type");
805 double tuneFactor = ttsPar.getDouble("PDEtuneFactor");
806 TOPNominalTTS tts("TTS of " + ttsPar.getString("@name") + " PMT");
807 tts.setPMTType(type);
808 for (const GearDir& Gauss : ttsPar.getNodes("Gauss")) {
809 tts.appendGaussian(Gauss.getDouble("fraction"),
810 Gauss.getTime("mean"),
811 Gauss.getTime("sigma"));
812 }
813 tts.normalize();
814 geo->appendTTS(tts);
815 geo->appendPDETuningFactor(type, tuneFactor);
816 }
817
818 // nominal TDC
819
820 GearDir tdcParams(content, "TDC");
821 if (tdcParams) {
822 TOPNominalTDC nominalTDC(tdcParams.getInt("numWindows"),
823 tdcParams.getInt("subBits"),
824 tdcParams.getTime("syncTimeBase"),
825 tdcParams.getInt("numofBunches"),
826 tdcParams.getTime("offset"),
827 tdcParams.getTime("pileupTime"),
828 tdcParams.getTime("doubleHitResolution"),
829 tdcParams.getTime("timeJitter"),
830 tdcParams.getDouble("efficiency"));
831 nominalTDC.setADCBits(tdcParams.getInt("adcBits"));
832 nominalTDC.setAveragePedestal(tdcParams.getInt("averagePedestal"));
833 geo->setNominalTDC(nominalTDC);
834 } else {
835 TOPNominalTDC nominalTDC(pmtParams.getInt("TDCbits"),
836 pmtParams.getTime("TDCbitwidth"),
837 pmtParams.getTime("TDCoffset", 0),
838 pmtParams.getTime("TDCpileupTime", 0),
839 pmtParams.getTime("TDCdoubleHitResolution", 0),
840 pmtParams.getTime("TDCtimeJitter", 50e-3),
841 pmtParams.getDouble("TDCefficiency", 1));
842 geo->setNominalTDC(nominalTDC);
843 }
844
845 // single photon signal shape
846
847 GearDir shapeParams(content, "SignalShape");
848 if (shapeParams) {
849 GearDir noiseBandwidth(shapeParams, "noiseBandwidth");
850 TOPSignalShape signalShape(shapeParams.getArray("sampleValues"),
851 geo->getNominalTDC().getSampleWidth(),
852 shapeParams.getTime("tailTimeConstant"),
853 noiseBandwidth.getDouble("pole1") / 1000,
854 noiseBandwidth.getDouble("pole2") / 1000);
855 geo->setSignalShape(signalShape);
856 }
857
858 // calibration pulse shape
859
860 GearDir calpulseParams(content, "CalPulseShape");
861 if (calpulseParams) {
862 GearDir noiseBandwidth(calpulseParams, "noiseBandwidth");
863 TOPSignalShape shape(calpulseParams.getArray("sampleValues"),
864 geo->getNominalTDC().getSampleWidth(),
865 calpulseParams.getTime("tailTimeConstant"),
866 noiseBandwidth.getDouble("pole1") / 1000,
867 noiseBandwidth.getDouble("pole2") / 1000);
868 geo->setCalPulseShape(shape);
869 }
870
871 // wavelength filter bulk transmittance
872
873 std::string materialNode = "Materials/Material[@name='TOPWavelengthFilterIHU340']";
874 GearDir filterMaterial(content, materialNode);
875 if (!filterMaterial) {
876 B2FATAL("TOPGeometry: " << materialNode << " not found");
877 }
878 GearDir property(filterMaterial, "Property[@name='ABSLENGTH']");
879 if (!property) {
880 B2FATAL("TOPGeometry: " << materialNode << ", Property ABSLENGTH not found");
881 }
882 int numNodes = property.getNumberNodes("value");
883 if (numNodes > 1) {
884 double conversion = Unit::convertValue(1, property.getString("@unit", "GeV"));
885 std::vector<double> energies;
886 std::vector<double> absLengths;
887 for (int i = 0; i < numNodes; i++) {
888 GearDir value(property, "value", i + 1);
889 energies.push_back(value.getDouble("@energy") * conversion / Unit::eV);// [eV]
890 absLengths.push_back(value.getDouble() * Unit::mm); // [cm]
891 }
892 TSpline3 spline("absLen", energies.data(), absLengths.data(), energies.size());
893 double lambdaFirst = c_hc / energies.back();
894 double lambdaLast = c_hc / energies[0];
895 double lambdaStep = 5; // [nm]
896 int numSteps = (lambdaLast - lambdaFirst) / lambdaStep + 1;
897 const double filterThickness = arrayParams.getLength("wavelengthFilter/thickness");
898 std::vector<float> bulkTransmittances;
899 for (int i = 0; i < numSteps; i++) {
900 double wavelength = lambdaFirst + lambdaStep * i;
901 double energy = c_hc / wavelength;
902 double absLen = spline.Eval(energy);
903 bulkTransmittances.push_back(exp(-filterThickness / absLen));
904 }
905 TOPWavelengthFilter filter(lambdaFirst, lambdaStep, bulkTransmittances);
906 geo->setWavelengthFilter(filter);
907 } else {
908 B2FATAL("TOPGeometry: " << materialNode
909 << ", Property ABSLENGTH has less than 2 nodes");
910 }
911
912 return geo;
913 }

◆ createMirrorSegment()

TOPGeoMirrorSegment createMirrorSegment ( const GearDir & content,
const std::string & serialNumber )
private

Create a parameter object from gearbox for mirror segment.

Parameters
contentXML data directory
serialNumbermirror segment serial number

Definition at line 939 of file TOPGeometryPar.cc.

941 {
942 // dimensions and material
943 GearDir params(content, "Mirrors/Mirror[@SerialNumber='" + SN + "']");
944 TOPGeoMirrorSegment mirror(params.getLength("Width"),
945 params.getLength("Thickness"),
946 params.getLength("Length"),
947 params.getString("Material"));
948 mirror.setVendorData(params.getString("Vendor"), SN);
949 mirror.setRadius(params.getLength("Radius"));
950 mirror.setCenterOfCurvature(params.getLength("Xpos"), params.getLength("Ypos"));
951
952 // mirror reflective coating
953 auto& materials = geometry::Materials::getInstance();
954 GearDir coatingParams(params, "Surface");
955 mirror.setCoating(params.getLength("mirrorThickness"), "Al",
956 materials.createOpticalSurfaceConfig(coatingParams));
957
958 // optical surface
959 std::string surfaceName = params.getString("OpticalSurface");
960 double sigmaAlpha = params.getDouble("SigmaAlpha");
961 GearDir surfaceParams(content, "Modules/Surface[@name='" + surfaceName + "']");
962 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
963 mirror.setSurface(quartzSurface, sigmaAlpha);
964
965 return mirror;
966 }

◆ createPrism()

TOPGeoPrism createPrism ( const GearDir & content,
const std::string & serialNumber )
private

Create a parameter object from gearbox for prism.

Parameters
contentXML data directory
serialNumberprism serial number

Definition at line 969 of file TOPGeometryPar.cc.

971 {
972 // dimensions and material
973 GearDir params(content, "Prisms/Prism[@SerialNumber='" + SN + "']");
974 TOPGeoPrism prism(params.getLength("Width"),
975 params.getLength("Thickness"),
976 params.getLength("Length"),
977 params.getLength("ExitThickness"),
978 0.,
979 params.getString("Material"));
980 prism.setAngle(params.getAngle("Angle"));
981 prism.setVendorData(params.getString("Vendor"), SN);
982
983 // optical surface
984 std::string surfaceName = params.getString("OpticalSurface");
985 double sigmaAlpha = params.getDouble("SigmaAlpha");
986 GearDir surfaceParams(content, "Modules/Surface[@name='" + surfaceName + "']");
987 auto& materials = geometry::Materials::getInstance();
988 auto quartzSurface = materials.createOpticalSurfaceConfig(surfaceParams);
989 prism.setSurface(quartzSurface, sigmaAlpha);
990
991 return prism;
992 }

◆ finalizeInitialization()

void finalizeInitialization ( )
private

finalize initialization

Definition at line 135 of file TOPGeometryPar.cc.

136 {
137 // set B field flag
138 m_BfieldOn = (BFieldManager::getField(0, 0, 0).R() / Unit::T) > 0.1;
139
140 // add call backs for PMT data
141 m_pmtInstalled.addCallback(this, &TOPGeometryPar::clearCache);
142 m_pmtQEData.addCallback(this, &TOPGeometryPar::clearCache);
143 m_pulseHeights.addCallback(this, &TOPGeometryPar::clearCache);
144
145 // print geometry if the debug level for 'top' is set 10000
146 const auto& logSystem = LogSystem::Instance();
147 if (logSystem.isLevelEnabled(LogConfig::c_Debug, 10000, "top")) {
148 getGeometry()->print();
149 if (m_oldPayload) {
150 cout << "Envelope QE same as nominal quantum efficiency" << endl << endl;
151 return;
152 }
153 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
154 m_envelopeQE.print("Envelope QE");
155 }
156 }

◆ getAbsorptionLength()

double getAbsorptionLength ( double energy) const
inline

Returns bulk absorption lenght of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
bulk absorption lenght

Definition at line 354 of file TOPGeometryPar.h.

355 {
356 double lambda = c_hc / energy;
357 return 15100 * pow(lambda / 405, 4); // Alan Schwartz, 2013 (private comunication)
358 }

◆ getChannelMapper() [1/2]

const ChannelMapper & getChannelMapper ( ) const
inline

Returns default channel mapper (mapping of channels to pixels)

Returns
channel mapper object

Definition at line 84 of file TOPGeometryPar.h.

84{return m_channelMapperIRSX;}

◆ getChannelMapper() [2/2]

const ChannelMapper & getChannelMapper ( ChannelMapper::EType type) const
inline

Returns channel mapper (mapping of channels to pixels) - Gearbox only.

Returns
channel mapper object

Definition at line 90 of file TOPGeometryPar.h.

91 {
92 switch (type) {
93 case ChannelMapper::c_IRS3B: return m_channelMapperIRS3B;
94 case ChannelMapper::c_IRSX: return m_channelMapperIRSX;
95 default: return m_channelMapperIRSX;
96 }
97 }

◆ getFrontEndMapper()

const FrontEndMapper & getFrontEndMapper ( ) const
inline

Returns front-end mapper (mapping of SCROD's to positions within TOP modules)

Returns
front-end mapper object

Definition at line 78 of file TOPGeometryPar.h.

78{return m_frontEndMapper;}

◆ getGeometry()

const TOPGeometry * getGeometry ( ) const

Returns pointer to geometry object using basf2 units.

Returns
pointer to geometry object

Definition at line 167 of file TOPGeometryPar.cc.

168 {
169 if (!m_valid) B2FATAL("No geometry available for TOP");
170
171 TOPGeometry::useBasf2Units();
172 if (m_fromDB) {
173 return &(**m_geoDB);
174 } else {
175 return m_geo;
176 }
177 }

◆ getGroupIndex()

double getGroupIndex ( double energy) const

Returns group refractive index of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
group refractive index

Definition at line 1029 of file TOPGeometryPar.cc.

1030 {
1031 double lambda = c_hc / energy;
1032 double dl = 1.0; // [nm]
1033 double n = refractiveIndex(lambda);
1034 double dndl = (refractiveIndex(lambda + dl / 2) - refractiveIndex(lambda - dl / 2)) / dl;
1035 return n / (1 + lambda / n * dndl);
1036 }

◆ getGroupIndexDerivative()

double getGroupIndexDerivative ( double energy) const
inline

Returns the derivative (dn_g/dE) of group refractive index of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
group refractive index

Definition at line 348 of file TOPGeometryPar.h.

349 {
350 double dE = 0.01; // [eV]
351 return (getGroupIndex(energy + dE / 2) - getGroupIndex(energy - dE / 2)) / dE;
352 }

◆ getPhaseIndex()

double getPhaseIndex ( double energy) const

Returns phase refractive index of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
phase refractive index

Definition at line 1023 of file TOPGeometryPar.cc.

1024 {
1025 double lambda = c_hc / energy;
1026 return refractiveIndex(lambda);
1027 }

◆ getPhaseIndexDerivative()

double getPhaseIndexDerivative ( double energy) const
inline

Returns the derivative (dn/dE) of phase refractive index of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
derivative of phase refractive index

Definition at line 342 of file TOPGeometryPar.h.

343 {
344 double dE = 0.01; // [eV]
345 return (getPhaseIndex(energy + dE / 2) - getPhaseIndex(energy - dE / 2)) / dE;
346 }

◆ getPMTEfficiency()

double getPMTEfficiency ( double energy,
int moduleID,
int pmtID,
double x,
double y ) const

Returns PMT pixel efficiency, a product of quantum and collection efficiency.

Parameters
energyphoton energy in [eV]
moduleIDslot ID
pmtIDPMT ID
xphoton detection position x in local PMT frame
yphoton detection position y in local PMT frame
Returns
the efficiency

Definition at line 191 of file TOPGeometryPar.cc.

194 {
195 const auto* geo = getGeometry();
196 if (!geo->isModuleIDValid(moduleID)) return 0;
197
198 double lambda = c_hc / energy;
199
200 if (m_oldPayload) { // filter transmittance is included in nominal QE, return it!
201 return geo->getNominalQE().getEfficiency(lambda);
202 }
203
204 if (m_pmts.empty()) mapPmtQEToPositions();
205
206 int id = getUniquePmtID(moduleID, pmtID);
207 const auto* pmtQE = m_pmts[id];
208 if (!pmtQE) return 0;
209
210 const auto& pmtArray = geo->getModule(moduleID).getPMTArray();
211 auto pmtPixel = pmtArray.getPMT().getPixelID(x, y);
212 if (pmtPixel == 0) return 0;
213
214 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
215 auto channel = getChannelMapper().getChannel(pixelID);
216
217 double RQE = geo->getPDETuningFactor(getPMTType(moduleID, pmtID));
218 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
219
220 return pmtQE->getEfficiency(pmtPixel, lambda, m_BfieldOn) * RQE;
221
222 }

◆ getPMTEfficiencyEnvelope()

double getPMTEfficiencyEnvelope ( double energy) const

Returns PMT efficiency envelope, e.g.

at given photon energy the maximum over all PMT's of a product of quantum and collection efficiency.

Parameters
energyphoton energy in [eV]
Returns
the maximal efficiency

Definition at line 179 of file TOPGeometryPar.cc.

180 {
181 double lambda = c_hc / energy;
182
183 if (m_oldPayload) { // filter transmittance is included in nominal QE, return it!
184 return getGeometry()->getNominalQE().getEfficiency(lambda);
185 }
186
187 if (m_envelopeQE.isEmpty()) setEnvelopeQE();
188 return m_envelopeQE.getEfficiency(lambda);
189 }

◆ getPMTType()

unsigned getPMTType ( int moduleID,
int pmtID ) const

Returns PMT type at a given position.

Parameters
moduleIDslot ID
pmtIDPMT ID
Returns
PMT type

Definition at line 262 of file TOPGeometryPar.cc.

263 {
264 if (m_pmtTypes.empty()) mapPmtTypeToPositions();
265
266 int id = getUniquePmtID(moduleID, pmtID);
267 return m_pmtTypes[id];
268 }

◆ getRelativePDEonMC()

double getRelativePDEonMC ( int moduleID,
int pixelID ) const

Returns relative PDE on MC (including CE, tuning factor and threshold efficiency)

Returns
pixel efficiency on MC relative to nominal photocathode

Definition at line 248 of file TOPGeometryPar.cc.

249 {
250 if (m_oldPayload) {
251 B2ERROR("TOPGeometryPar::getRelativePDEonMC: called using obsolete TOPGeometry payload revision - please, check global tags");
252 return 0; // to prevent wrong RQE calibration - see TOPPhotonYieldsAlgorithm.cc
253 }
254
255 if (m_relPDEonMC.empty()) prepareRelPDEonMC();
256
257 int id = getUniquePixelID(moduleID, pixelID);
258 return m_relPDEonMC[id];
259 }

◆ getRelativePixelEfficiency()

double getRelativePixelEfficiency ( int moduleID,
int pixelID ) const

Returns relative pixel efficiency (including CE, RQE and threshold efficiency)

Returns
pixel efficiency relative to nominal photocathode

Definition at line 225 of file TOPGeometryPar.cc.

226 {
227
228 auto channel = getChannelMapper().getChannel(pixelID);
229 auto pmtID = getChannelMapper().getPmtID(pixelID);
230
231 double RQE = getGeometry()->getPDETuningFactor(getPMTType(moduleID, pmtID));
232 if (m_channelRQE.isValid()) RQE *= m_channelRQE->getRQE(moduleID, channel);
233
234 double thrEffi = 1.0;
235 if (m_thresholdEff.isValid()) thrEffi = m_thresholdEff->getThrEff(moduleID, channel);
236
237 if (m_oldPayload) { // nominal QE is used
238 return RQE * thrEffi;
239 }
240
241 if (m_relEfficiencies.empty()) prepareRelEfficiencies();
242
243 int id = getUniquePixelID(moduleID, pixelID);
244 return m_relEfficiencies[id] * RQE * thrEffi;
245 }

◆ getTTS()

const TOPNominalTTS & getTTS ( int moduleID,
int pmtID ) const

Returns TTS of a PMT at given position.

Parameters
moduleIDslot ID
pmtIDPMT ID
Returns
TTS

Definition at line 271 of file TOPGeometryPar.cc.

272 {
273 auto pmtType = getPMTType(moduleID, pmtID);
274 return getGeometry()->getTTS(pmtType);
275 }

◆ getUniquePixelID()

int getUniquePixelID ( int moduleID,
int pixelID ) const
inlineprivate

Returns unique pixel ID within the detector.

Parameters
moduleIDslot ID
pixelIDpixel ID
Returns
unique ID

Definition at line 282 of file TOPGeometryPar.h.

283 {
284 return (moduleID << 16) + pixelID;
285 }

◆ getUniquePmtID()

int getUniquePmtID ( int moduleID,
int pmtID ) const
inlineprivate

Returns unique PMT ID within the detector.

Parameters
moduleIDslot ID
pmtIDPMT ID
Returns
unique ID

Definition at line 271 of file TOPGeometryPar.h.

272 {
273 return (moduleID << 16) + pmtID;
274 }

◆ Initialize() [1/2]

void Initialize ( )

Initialize from database.

Definition at line 89 of file TOPGeometryPar.cc.

90 {
91 m_fromDB = true;
92 m_valid = false;
93
94 if (m_geoDB) delete m_geoDB;
95 m_geoDB = new DBObjPtr<TOPGeometry>();
96
97 if (!m_geoDB->isValid()) {
98 B2ERROR("TOPGeometry: no payload found in database");
99 return;
100 }
101 if ((*m_geoDB)->getWavelengthFilter().getName().empty()) {
102 m_oldPayload = true;
103 B2WARNING("TOPGeometry: obsolete payload revision (pixel independent PDE) - please, check global tags");
104 }
105 if ((*m_geoDB)->getTTSes().empty()) {
106 B2WARNING("TOPGeometry: obsolete payload revision (nominal TTS only) - please, check global tags");
107 }
108 if ((*m_geoDB)->arePDETuningFactorsEmpty()) {
109 B2WARNING("TOPGeometry: obsolete payload revision (before bugfix and update of optical properties) - please, check global tags");
110 }
111
112 // Make sure that we abort as soon as the geometry changes
113 m_geoDB->addCallback([]() {
114 B2FATAL("Geometry cannot change during processing, "
115 "aborting (component TOP)");
116 });
117
118 m_frontEndMapper.initialize();
119 if (!m_frontEndMapper.isValid()) {
120 B2ERROR("TOPFrontEndMaps: no payload found in database");
121 return;
122 }
123
124 m_channelMapperIRSX.initialize();
125 if (!m_channelMapperIRSX.isValid()) {
126 B2ERROR("TOPChannelMaps: no payload found in database");
127 return;
128 }
129 m_valid = true;
130
131 finalizeInitialization();
132
133 }

◆ Initialize() [2/2]

void Initialize ( const GearDir & content)

Initialize from Gearbox (XML)

Parameters
contentXML data directory

Definition at line 52 of file TOPGeometryPar.cc.

53 {
54
55 m_fromDB = false;
56 m_valid = false;
57
58 if (m_geo) delete m_geo;
59 m_geo = createConfiguration(content);
60 if (!m_geo->isConsistent()) {
61 B2ERROR("TOPGeometryPar::createConfiguration: geometry not consistently defined");
62 return;
63 }
64
65 GearDir frontEndMapping(content, "FrontEndMapping");
66 m_frontEndMapper.initialize(frontEndMapping);
67 if (!m_frontEndMapper.isValid()) {
68 return;
69 }
70
71 GearDir channelMapping0(content, "ChannelMapping[@type='IRS3B']");
72 m_channelMapperIRS3B.initialize(channelMapping0);
73 if (!m_channelMapperIRS3B.isValid()) {
74 return;
75 }
76
77 GearDir channelMapping1(content, "ChannelMapping[@type='IRSX']");
78 m_channelMapperIRSX.initialize(channelMapping1);
79 if (!m_channelMapperIRSX.isValid()) {
80 return;
81 }
82 m_valid = true;
83
84 finalizeInitialization();
85
86 }

◆ Instance()

TOPGeometryPar * Instance ( )
static

Static method to obtain the pointer to its instance.

Returns
pointer to the instance of this class.

Definition at line 43 of file TOPGeometryPar.cc.

44 {
45 if (!s_instance) {
46 s_instance = new TOPGeometryPar();
47 }
48 return s_instance;
49 }

◆ integralOfQE()

double integralOfQE ( const std::vector< float > & qe,
double ce,
double lambdaFirst,
double lambdaStep ) const
private

Returns integral of quantum efficiency over photon energies.

Parameters
qequantum efficiency data points
cecollection efficiency data points
lambdaFirstwavelenght of the first data point [nm]
lambdaStepwavelength step [nm]
Returns
integral [eV]

Definition at line 464 of file TOPGeometryPar.cc.

466 {
467 if (qe.empty()) return 0;
468
469 const auto* geo = getGeometry();
470 const auto& filter = geo->getWavelengthFilter();
471
472 double s = 0;
473 double lambda = lambdaFirst;
474 double f1 = qe[0] * filter.getBulkTransmittance(lambda) / (lambda * lambda);
475 for (size_t i = 1; i < qe.size(); i++) {
476 lambda += lambdaStep;
477 double f2 = qe[i] * filter.getBulkTransmittance(lambda) / (lambda * lambda);
478 s += (f1 + f2) / 2;
479 f1 = f2;
480 }
481 return s * c_hc * lambdaStep * ce;
482 }

◆ isValid()

bool isValid ( ) const
inline

check if the geometry is available

Returns
true if available

Definition at line 66 of file TOPGeometryPar.h.

66{return m_valid;}

◆ mapPmtQEToPositions()

void mapPmtQEToPositions ( ) const
private

Maps PMT QE data to positions within the detector.

Definition at line 356 of file TOPGeometryPar.cc.

357 {
358 m_pmts.clear();
359
360 std::map<std::string, const TOPPmtQE*> map;
361 for (const auto& pmt : m_pmtQEData) {
362 map[pmt.getSerialNumber()] = &pmt;
363 }
364 for (const auto& pmt : m_pmtInstalled) {
365 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
366 m_pmts[id] = map[pmt.getSerialNumber()];
367 }
368
369 B2INFO("TOPGeometryPar: QE of PMT's mapped to positions, size = " << m_pmts.size());
370 }

◆ mapPmtTypeToPositions()

void mapPmtTypeToPositions ( ) const
private

Maps PMT type to positions within the detector.

Definition at line 373 of file TOPGeometryPar.cc.

374 {
375 for (const auto& pmt : m_pmtInstalled) {
376 int id = getUniquePmtID(pmt.getSlotNumber(), pmt.getPosition());
377 m_pmtTypes[id] = pmt.getType();
378 }
379
380 B2INFO("TOPGeometryPar: PMT types mapped to positions, size = "
381 << m_pmtTypes.size());
382
383
384 std::set<unsigned> types;
385 for (const auto& pmt : m_pmtInstalled) {
386 types.insert(pmt.getType());
387 }
388 const auto* geo = getGeometry();
389 for (const auto& type : types) {
390 if (geo->getTTS(type).getPMTType() != type) {
391 B2WARNING("No TTS found for an installed PMT type. Nominal one will be used."
392 << LogVar("PMT type", type));
393 }
394 }
395
396 }

◆ prepareRelEfficiencies()

void prepareRelEfficiencies ( ) const
private

Prepares a map of relative pixel quantum times collection efficiencies (relative to nominal one)

Definition at line 399 of file TOPGeometryPar.cc.

400 {
401 m_relEfficiencies.clear();
402 if (m_pmts.empty()) mapPmtQEToPositions();
403
404 const auto* geo = getGeometry();
405
406 const auto& nominalQE = geo->getNominalQE();
407 double s0 = integralOfQE(nominalQE.getQE(), nominalQE.getCE(),
408 nominalQE.getLambdaFirst(), nominalQE.getLambdaStep());
409
410 for (const auto& module : geo->getModules()) {
411 auto moduleID = module.getModuleID();
412 const auto& pmtArray = module.getPMTArray();
413 int numPMTs = pmtArray.getSize();
414 int numPMTPixels = pmtArray.getPMT().getNumPixels();
415 for (int pmtID = 1; pmtID <= numPMTs; pmtID++) {
416 const auto* pmtQE = m_pmts[getUniquePmtID(moduleID, pmtID)];
417 for (int pmtPixel = 1; pmtPixel <= numPMTPixels; pmtPixel++) {
418 double s = 0;
419 if (pmtQE) {
420 s = integralOfQE(pmtQE->getQE(pmtPixel), pmtQE->getCE(m_BfieldOn),
421 pmtQE->getLambdaFirst(), pmtQE->getLambdaStep());
422 }
423 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
424 auto id = getUniquePixelID(moduleID, pixelID);
425 m_relEfficiencies[id] = s / s0;
426 }
427 }
428 }
429
430 B2INFO("TOPGeometryPar: pixel relative quantum efficiencies have been set, size = "
431 << m_relEfficiencies.size());
432 }

◆ prepareRelPDEonMC()

void prepareRelPDEonMC ( ) const
private

Prepares a map of relative pixel photon detection efficiencies on MC.

Definition at line 434 of file TOPGeometryPar.cc.

435 {
436 m_relPDEonMC.clear();
437 if (m_relEfficiencies.empty()) prepareRelEfficiencies();
438
439 const auto* geo = getGeometry();
440
441 for (const auto& module : geo->getModules()) {
442 auto moduleID = module.getModuleID();
443 const auto& pmtArray = module.getPMTArray();
444 int numPMTs = pmtArray.getSize();
445 int numPMTPixels = pmtArray.getPMT().getNumPixels();
446 for (int pmtID = 1; pmtID <= numPMTs; pmtID++) {
447 double tuneFactor = getGeometry()->getPDETuningFactor(getPMTType(moduleID, pmtID));
448 for (int pmtPixel = 1; pmtPixel <= numPMTPixels; pmtPixel++) {
449 auto pixelID = pmtArray.getPixelID(pmtID, pmtPixel);
450 auto channel = getChannelMapper().getChannel(pixelID);
451 double thrEffi = 0.973; //TODO(rel-10) get rid of hard coding
452 if (m_pulseHeights->isCalibrated(moduleID, channel)) {
453 thrEffi = m_pulseHeights->getParameters(moduleID, channel).getThresholdEffi(40, 9.7); //TODO(rel-10) get rid of hard coding
454 }
455 int id = getUniquePixelID(moduleID, pixelID);
456 m_relPDEonMC[id] = m_relEfficiencies[id] * tuneFactor * thrEffi;
457 }
458 }
459 }
460
461 B2INFO("TOPGeometryPar: pixel relative PDE on MC have been set, size = " << m_relPDEonMC.size());
462 }

◆ refractiveIndex()

double refractiveIndex ( double lambda) const
private

Quartz refractive index (SellMeier equation)

Parameters
lambdaphoton wavelength [nm]
Returns
refractive index

Definition at line 1007 of file TOPGeometryPar.cc.

1008 {
1009 // parameters of SellMeier equation (Matsuoka-san, 24.11.2018)
1010 // from the specs of Corning HPFS 7980
1011 // https://www.corning.com/media/worldwide/csm/documents/5bf092438c5546dfa9b08e423348317b.pdf
1012 const double b[] = {0.683740494, 0.420323613, 0.585027480};
1013 const double c[] = {0.00460352869, 0.0133968856, 64.4932732};
1014
1015 double x = pow(lambda * 0.001, 2);
1016 double y = 1;
1017 for (int i = 0; i < 3; i++) {
1018 y += b[i] * x / (x - c[i]);
1019 }
1020 return sqrt(y);
1021 }
double sqrt(double a)
sqrt for double
Definition beamHelpers.h:28

◆ setEnvelopeQE()

void setEnvelopeQE ( ) const
private

Constructs envelope of quantum efficiency from PMT data.

Definition at line 278 of file TOPGeometryPar.cc.

279 {
280 if (m_pmtQEData.getEntries() == 0) {
281 B2ERROR("DBArray TOPPmtQEs is empty");
282 return;
283 }
284
285 double lambdaFirst = 0;
286 for (const auto& pmt : m_pmtQEData) {
287 if (pmt.getLambdaFirst() > 0) {
288 lambdaFirst = pmt.getLambdaFirst();
289 break;
290 }
291 }
292 if (lambdaFirst == 0) {
293 B2ERROR("DBArray TOPPmtQEs: lambdaFirst of all PMT found to be less or equal 0");
294 return;
295 }
296 for (const auto& pmt : m_pmtQEData) {
297 if (pmt.getLambdaFirst() > 0) {
298 lambdaFirst = std::min(lambdaFirst, pmt.getLambdaFirst());
299 }
300 }
301
302 double lambdaStep = 0;
303 for (const auto& pmt : m_pmtQEData) {
304 if (pmt.getLambdaStep() > 0) {
305 lambdaStep = pmt.getLambdaStep();
306 break;
307 }
308 }
309 if (lambdaStep == 0) {
310 B2ERROR("DBArray TOPPmtQEs: lambdaStep of all PMT found to be less or equal 0");
311 return;
312 }
313 for (const auto& pmt : m_pmtQEData) {
314 if (pmt.getLambdaStep() > 0) {
315 lambdaStep = std::min(lambdaStep, pmt.getLambdaStep());
316 }
317 }
318
319 std::map<std::string, const TOPPmtInstallation*> map;
320 for (const auto& pmt : m_pmtInstalled) {
321 map[pmt.getSerialNumber()] = &pmt;
322 }
323 const auto* geo = getGeometry();
324
325 std::vector<float> envelopeQE;
326 for (const auto& pmt : m_pmtQEData) {
327 float ce = pmt.getCE(m_BfieldOn);
328 auto pmtInstalled = map[pmt.getSerialNumber()];
329 if (pmtInstalled) ce *= geo->getPDETuningFactor(pmtInstalled->getType());
330 if (pmt.getLambdaFirst() == lambdaFirst and pmt.getLambdaStep() == lambdaStep) {
331 const auto& envelope = pmt.getEnvelopeQE();
332 if (envelopeQE.size() < envelope.size()) {
333 envelopeQE.resize(envelope.size() - envelopeQE.size(), 0);
334 }
335 for (size_t i = 0; i < std::min(envelopeQE.size(), envelope.size()); i++) {
336 envelopeQE[i] = std::max(envelopeQE[i], envelope[i] * ce);
337 }
338 } else {
339 double lambdaLast = pmt.getLambdaLast();
340 int nExtra = (lambdaLast - lambdaFirst) / lambdaStep + 1 - envelopeQE.size();
341 if (nExtra > 0) envelopeQE.resize(nExtra, 0);
342 for (size_t i = 0; i < envelopeQE.size(); i++) {
343 float qe = pmt.getEnvelopeQE(lambdaFirst + lambdaStep * i);
344 envelopeQE[i] = std::max(envelopeQE[i], qe * ce);
345 }
346 }
347 }
348
349 m_envelopeQE.set(lambdaFirst, lambdaStep, 1.0, envelopeQE, "EnvelopeQE");
350
351 B2INFO("TOPGeometryPar: envelope of PMT dependent QE has been set");
352
353 }

Member Data Documentation

◆ c_hc

const double c_hc = 1239.84193
static

Planck constant times speed of light in [eV*nm].

Definition at line 182 of file TOPGeometryPar.h.

◆ m_BfieldOn

bool m_BfieldOn = true
private

true if B field is on

Definition at line 313 of file TOPGeometryPar.h.

◆ m_channelMapperIRS3B

ChannelMapper m_channelMapperIRS3B
private

channel-pixel mapper

Definition at line 318 of file TOPGeometryPar.h.

◆ m_channelMapperIRSX

ChannelMapper m_channelMapperIRSX
private

channel-pixel mapper

Definition at line 319 of file TOPGeometryPar.h.

◆ m_channelRQE

DBObjPtr<TOPCalChannelRQE> m_channelRQE
private

channel relative quantum effi.

Definition at line 325 of file TOPGeometryPar.h.

◆ m_envelopeQE

TOPNominalQE m_envelopeQE
mutableprivate

envelope quantum efficiency

Definition at line 330 of file TOPGeometryPar.h.

◆ m_fromDB

bool m_fromDB = false
private

parameters from database or Gearbox

Definition at line 310 of file TOPGeometryPar.h.

◆ m_frontEndMapper

FrontEndMapper m_frontEndMapper
private

front end electronics mapper

Definition at line 317 of file TOPGeometryPar.h.

◆ m_geo

TOPGeometry* m_geo = 0
private

geometry parameters from Gearbox

Definition at line 308 of file TOPGeometryPar.h.

◆ m_geoDB

DBObjPtr<TOPGeometry>* m_geoDB = 0
private

geometry parameters from database

Definition at line 309 of file TOPGeometryPar.h.

◆ m_oldPayload

bool m_oldPayload = false
private

true if old payload found in DB

Definition at line 312 of file TOPGeometryPar.h.

◆ m_pmtInstalled

OptionalDBArray<TOPPmtInstallation> m_pmtInstalled
private

PMT installation data.

Definition at line 323 of file TOPGeometryPar.h.

◆ m_pmtQEData

OptionalDBArray<TOPPmtQE> m_pmtQEData
private

quantum efficiencies

Definition at line 324 of file TOPGeometryPar.h.

◆ m_pmts

std::map<int, const TOPPmtQE*> m_pmts
mutableprivate

QE data mapped to positions.

Definition at line 331 of file TOPGeometryPar.h.

◆ m_pmtTypes

std::map<int, unsigned> m_pmtTypes
mutableprivate

PMT types mapped to positions.

Definition at line 334 of file TOPGeometryPar.h.

◆ m_pulseHeights

DBObjPtr<TOPCalChannelPulseHeight> m_pulseHeights
private

channel pulse height parametrizations

Definition at line 327 of file TOPGeometryPar.h.

◆ m_relEfficiencies

std::map<int, double> m_relEfficiencies
mutableprivate

pixel relative QE

Definition at line 332 of file TOPGeometryPar.h.

◆ m_relPDEonMC

std::map<int, double> m_relPDEonMC
mutableprivate

pixel relative photon detection efficiencies on MC

Definition at line 333 of file TOPGeometryPar.h.

◆ m_thresholdEff

DBObjPtr<TOPCalChannelThresholdEff> m_thresholdEff
private

channel threshold effi.

Definition at line 326 of file TOPGeometryPar.h.

◆ m_valid

bool m_valid = false
private

true if geometry is available

Definition at line 311 of file TOPGeometryPar.h.

◆ s_instance

TOPGeometryPar * s_instance = 0
staticprivate

Pointer to the class instance.

Definition at line 338 of file TOPGeometryPar.h.


The documentation for this class was generated from the following files: