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.
 

Static Public Member Functions

static TOPGeometryParInstance ()
 Static method to obtain the pointer to its instance.
 
static double getPhaseIndex (double energy)
 Returns phase refractive index of quartz at given photon energy.
 
static double getGroupIndex (double energy)
 Returns group refractive index of quartz at given photon energy.
 
static double getPhaseIndexDerivative (double energy)
 Returns the derivative (dn/dE) of phase refractive index of quartz at given photon energy.
 
static double getGroupIndexDerivative (double energy)
 Returns the derivative (dn_g/dE) of group refractive index of quartz at given photon energy.
 
static double getAbsorptionLength (double energy)
 Returns bulk absorption length of quartz at given photon energy.
 

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.
 
 TOPGeometryPar (const TOPGeometryPar &)=delete
 Deleted copy constructor since it is a singleton class.
 
TOPGeometryParoperator= (const TOPGeometryPar &)=delete
 Deleted assignment operator since it is a singleton class.
 
void finalizeInitialization ()
 finalize initialization
 
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.
 
double integralOfQE (const std::vector< float > &qe, double ce, double lambdaFirst, double lambdaStep) const
 Returns integral of quantum efficiency over photon energies.
 

Static Private Member Functions

static TOPGeometrycreateConfiguration (const GearDir &content)
 Create a parameter object from gearbox.
 
static TOPGeoBarSegment createBarSegment (const GearDir &content, const std::string &serialNumber)
 Create a parameter object from gearbox for bar segment.
 
static TOPGeoMirrorSegment createMirrorSegment (const GearDir &content, const std::string &serialNumber)
 Create a parameter object from gearbox for mirror segment.
 
static TOPGeoPrism createPrism (const GearDir &content, const std::string &serialNumber)
 Create a parameter object from gearbox for prism.
 
static std::string addNumber (const std::string &str, unsigned number)
 Adds number to string.
 
static int getUniquePmtID (int moduleID, int pmtID)
 Returns unique PMT ID within the detector.
 
static int getUniquePixelID (int moduleID, int pixelID)
 Returns unique pixel ID within the detector.
 
static double refractiveIndex (double lambda)
 Quartz refractive index (SellMeier equation)
 

Private Attributes

TOPGeometrym_geo = 0
 geometry parameters from Gearbox
 
DBObjPtr< TOPGeometrym_geoDB
 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 s_instance = 0;
39 }

◆ 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 )
staticprivate

Adds number to string.

Parameters
strstring
numbernumber to be added
Returns
string with a number

Definition at line 990 of file TOPGeometryPar.cc.

991 {
992 stringstream ss;
993 if (number < 10) {
994 ss << str << "0" << number;
995 } else {
996 ss << str << number;
997 }
998 string out;
999 ss >> out;
1000 return out;
1001 }

◆ clearCache()

void clearCache ( )
private

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

Definition at line 154 of file TOPGeometryPar.cc.

155 {
156 m_envelopeQE.clear();
157 m_pmts.clear();
158 m_relEfficiencies.clear();
159 m_relPDEonMC.clear();
160 m_pmtTypes.clear();
161 }

◆ createBarSegment()

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

Create a parameter object from gearbox for bar segment.

Parameters
contentXML data directory
serialNumberbar segment serial number

Definition at line 912 of file TOPGeometryPar.cc.

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

◆ createConfiguration()

TOPGeometry * createConfiguration ( const GearDir & content)
staticprivate

Create a parameter object from gearbox.

Parameters
contentXML data directory

Definition at line 481 of file TOPGeometryPar.cc.

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

◆ createMirrorSegment()

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

Create a parameter object from gearbox for mirror segment.

Parameters
contentXML data directory
serialNumbermirror segment serial number

Definition at line 935 of file TOPGeometryPar.cc.

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

◆ createPrism()

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

Create a parameter object from gearbox for prism.

Parameters
contentXML data directory
serialNumberprism serial number

Definition at line 965 of file TOPGeometryPar.cc.

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

◆ finalizeInitialization()

void finalizeInitialization ( )
private

finalize initialization

Definition at line 131 of file TOPGeometryPar.cc.

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

◆ getAbsorptionLength()

double getAbsorptionLength ( double energy)
inlinestatic

Returns bulk absorption length of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
bulk absorption length

Definition at line 364 of file TOPGeometryPar.h.

365 {
366 double lambda = c_hc / energy;
367 return 15100 * pow(lambda / 405, 4); // Alan Schwartz, 2013 (private communication)
368 }

◆ 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 163 of file TOPGeometryPar.cc.

164 {
165 if (!m_valid) B2FATAL("No geometry available for TOP");
166
167 TOPGeometry::useBasf2Units();
168 if (m_fromDB) {
169 return &(*m_geoDB);
170 } else {
171 return m_geo;
172 }
173 }

◆ getGroupIndex()

double getGroupIndex ( double energy)
static

Returns group refractive index of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
group refractive index

Definition at line 1025 of file TOPGeometryPar.cc.

1026 {
1027 double lambda = c_hc / energy;
1028 double dl = 1.0; // [nm]
1029 double n = refractiveIndex(lambda);
1030 double dndl = (refractiveIndex(lambda + dl / 2) - refractiveIndex(lambda - dl / 2)) / dl;
1031 return n / (1 + lambda / n * dndl);
1032 }

◆ getGroupIndexDerivative()

double getGroupIndexDerivative ( double energy)
inlinestatic

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 358 of file TOPGeometryPar.h.

359 {
360 double dE = 0.01; // [eV]
361 return (getGroupIndex(energy + dE / 2) - getGroupIndex(energy - dE / 2)) / dE;
362 }

◆ getPhaseIndex()

double getPhaseIndex ( double energy)
static

Returns phase refractive index of quartz at given photon energy.

Parameters
energyphoton energy [eV]
Returns
phase refractive index

Definition at line 1019 of file TOPGeometryPar.cc.

1020 {
1021 double lambda = c_hc / energy;
1022 return refractiveIndex(lambda);
1023 }

◆ getPhaseIndexDerivative()

double getPhaseIndexDerivative ( double energy)
inlinestatic

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 352 of file TOPGeometryPar.h.

353 {
354 double dE = 0.01; // [eV]
355 return (getPhaseIndex(energy + dE / 2) - getPhaseIndex(energy - dE / 2)) / dE;
356 }

◆ 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 187 of file TOPGeometryPar.cc.

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

◆ 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 175 of file TOPGeometryPar.cc.

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

◆ 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 258 of file TOPGeometryPar.cc.

259 {
260 if (m_pmtTypes.empty()) mapPmtTypeToPositions();
261
262 int id = getUniquePmtID(moduleID, pmtID);
263 return m_pmtTypes[id];
264 }

◆ 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 244 of file TOPGeometryPar.cc.

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

◆ 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 221 of file TOPGeometryPar.cc.

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

◆ 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 267 of file TOPGeometryPar.cc.

268 {
269 auto pmtType = getPMTType(moduleID, pmtID);
270 return getGeometry()->getTTS(pmtType);
271 }

◆ getUniquePixelID()

static int getUniquePixelID ( int moduleID,
int pixelID )
inlinestaticprivate

Returns unique pixel ID within the detector.

Parameters
moduleIDslot ID
pixelIDpixel ID
Returns
unique ID

Definition at line 292 of file TOPGeometryPar.h.

293 {
294 return (moduleID << 16) + pixelID;
295 }

◆ getUniquePmtID()

static int getUniquePmtID ( int moduleID,
int pmtID )
inlinestaticprivate

Returns unique PMT ID within the detector.

Parameters
moduleIDslot ID
pmtIDPMT ID
Returns
unique ID

Definition at line 281 of file TOPGeometryPar.h.

282 {
283 return (moduleID << 16) + pmtID;
284 }

◆ Initialize() [1/2]

void Initialize ( )

Initialize from database.

Definition at line 88 of file TOPGeometryPar.cc.

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

◆ Initialize() [2/2]

void Initialize ( const GearDir & content)

Initialize from Gearbox (XML)

Parameters
contentXML data directory

Definition at line 51 of file TOPGeometryPar.cc.

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

◆ Instance()

TOPGeometryPar * Instance ( )
static

Static method to obtain the pointer to its instance.

Returns
pointer to the instance of this class.

Definition at line 42 of file TOPGeometryPar.cc.

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

◆ 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
lambdaFirstwavelength of the first data point [nm]
lambdaStepwavelength step [nm]
Returns
integral [eV]

Definition at line 460 of file TOPGeometryPar.cc.

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

◆ 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 352 of file TOPGeometryPar.cc.

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

◆ mapPmtTypeToPositions()

void mapPmtTypeToPositions ( ) const
private

Maps PMT type to positions within the detector.

Definition at line 369 of file TOPGeometryPar.cc.

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

◆ prepareRelEfficiencies()

void prepareRelEfficiencies ( ) const
private

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

Definition at line 395 of file TOPGeometryPar.cc.

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

◆ prepareRelPDEonMC()

void prepareRelPDEonMC ( ) const
private

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

Definition at line 430 of file TOPGeometryPar.cc.

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

◆ refractiveIndex()

double refractiveIndex ( double lambda)
staticprivate

Quartz refractive index (SellMeier equation)

Parameters
lambdaphoton wavelength [nm]
Returns
refractive index

Definition at line 1003 of file TOPGeometryPar.cc.

1004 {
1005 // parameters of SellMeier equation (Matsuoka-san, 24.11.2018)
1006 // from the specs of Corning HPFS 7980
1007 // https://www.corning.com/media/worldwide/csm/documents/5bf092438c5546dfa9b08e423348317b.pdf
1008 const double b[] = {0.683740494, 0.420323613, 0.585027480};
1009 const double c[] = {0.00460352869, 0.0133968856, 64.4932732};
1010
1011 double x = pow(lambda * 0.001, 2);
1012 double y = 1;
1013 for (int i = 0; i < 3; i++) {
1014 y += b[i] * x / (x - c[i]);
1015 }
1016 return sqrt(y);
1017 }
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 274 of file TOPGeometryPar.cc.

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

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 323 of file TOPGeometryPar.h.

◆ m_channelMapperIRS3B

ChannelMapper m_channelMapperIRS3B
private

channel-pixel mapper

Definition at line 328 of file TOPGeometryPar.h.

◆ m_channelMapperIRSX

ChannelMapper m_channelMapperIRSX
private

channel-pixel mapper

Definition at line 329 of file TOPGeometryPar.h.

◆ m_channelRQE

DBObjPtr<TOPCalChannelRQE> m_channelRQE
private

channel relative quantum effi.

Definition at line 335 of file TOPGeometryPar.h.

◆ m_envelopeQE

TOPNominalQE m_envelopeQE
mutableprivate

envelope quantum efficiency

Definition at line 340 of file TOPGeometryPar.h.

◆ m_fromDB

bool m_fromDB = false
private

parameters from database or Gearbox

Definition at line 320 of file TOPGeometryPar.h.

◆ m_frontEndMapper

FrontEndMapper m_frontEndMapper
private

front end electronics mapper

Definition at line 327 of file TOPGeometryPar.h.

◆ m_geo

TOPGeometry* m_geo = 0
private

geometry parameters from Gearbox

Definition at line 318 of file TOPGeometryPar.h.

◆ m_geoDB

DBObjPtr<TOPGeometry> m_geoDB
private

geometry parameters from database

Definition at line 319 of file TOPGeometryPar.h.

◆ m_oldPayload

bool m_oldPayload = false
private

true if old payload found in DB

Definition at line 322 of file TOPGeometryPar.h.

◆ m_pmtInstalled

OptionalDBArray<TOPPmtInstallation> m_pmtInstalled
private

PMT installation data.

Definition at line 333 of file TOPGeometryPar.h.

◆ m_pmtQEData

OptionalDBArray<TOPPmtQE> m_pmtQEData
private

quantum efficiencies

Definition at line 334 of file TOPGeometryPar.h.

◆ m_pmts

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

QE data mapped to positions.

Definition at line 341 of file TOPGeometryPar.h.

◆ m_pmtTypes

std::map<int, unsigned> m_pmtTypes
mutableprivate

PMT types mapped to positions.

Definition at line 344 of file TOPGeometryPar.h.

◆ m_pulseHeights

DBObjPtr<TOPCalChannelPulseHeight> m_pulseHeights
private

channel pulse height parametrizations

Definition at line 337 of file TOPGeometryPar.h.

◆ m_relEfficiencies

std::map<int, double> m_relEfficiencies
mutableprivate

pixel relative QE

Definition at line 342 of file TOPGeometryPar.h.

◆ m_relPDEonMC

std::map<int, double> m_relPDEonMC
mutableprivate

pixel relative photon detection efficiencies on MC

Definition at line 343 of file TOPGeometryPar.h.

◆ m_thresholdEff

DBObjPtr<TOPCalChannelThresholdEff> m_thresholdEff
private

channel threshold effi.

Definition at line 336 of file TOPGeometryPar.h.

◆ m_valid

bool m_valid = false
private

true if geometry is available

Definition at line 321 of file TOPGeometryPar.h.

◆ s_instance

TOPGeometryPar * s_instance = 0
staticprivate

Pointer to the class instance.

Definition at line 348 of file TOPGeometryPar.h.


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