692 def makeAlgs (self, config) :
693
694 if self.forceFullSimConfig:
695 warnings.warn_explicit(
696 "You are running ElectronWorkingPointSelectionConfig forcing"
697 " full sim config. This is only intended to be used for"
698 " testing purposes.",
699 TestingOnlyWarning, filename='', lineno=0)
700
701 selectionPostfix = self.selectionName
702 if selectionPostfix != '' and selectionPostfix[0] != '_' :
703 selectionPostfix = '_' + selectionPostfix
704
705
706 if config.geometry() is LHCPeriod.Run1:
707 raise ValueError ("Can't set up the ElectronWorkingPointSelectionConfig with %s, there must be something wrong!" % config.geometry().value)
708
709 postfix = self.postfix
710 if postfix is None :
711 postfix = self.selectionName
712 if postfix != '' and postfix[0] != '_' :
713 postfix = '_' + postfix
714
715 correlationModels = ["SIMPLIFIED", "FULL", "TOTAL", "TOYS"]
716 map_file = 'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v3/map1.txt' \
717 if config.geometry() is LHCPeriod.Run2 else \
718 'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run3_Consolidated_Recommendation_v4/map2.txt'
719 sfList = []
720
721 if config.dataType() is not DataType.Data and not self.noEffSF:
722 if 'DNN' in self.identificationWP:
723 raise ValueError('DNN does not yet have efficiency correction, '
724 'please disable it by setting `noEffSF` to True.')
725
726 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
727 'ElectronEfficiencyCorrectionAlgReco' )
728 config.addPrivateTool( 'efficiencyCorrectionTool',
729 'AsgElectronEfficiencyCorrectionTool' )
730 alg.scaleFactorDecoration = 'el_reco_effSF' + selectionPostfix + '_%SYS%'
731 alg.efficiencyCorrectionTool.MapFilePath = map_file
732 alg.efficiencyCorrectionTool.RecoKey = "Reconstruction"
733 if self.correlationModelReco not in correlationModels:
734 raise ValueError('Invalid correlation model for reconstruction efficiency, '
735 f'has to be one of: {", ".join(correlationModels)}')
736 if config.geometry() >= LHCPeriod.Run3 and self.correlationModelReco != "TOTAL":
737 warnings.warn_explicit(
738 "Only TOTAL correlation model is currently supported "
739 "for reconstruction efficiency correction in Run 3.",
740 ElectronEfficiencyCorrelationWarning,
741 filename='', lineno=0)
742 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
743 else:
744 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelReco
745 if config.dataType() is DataType.FastSim:
746 alg.efficiencyCorrectionTool.ForceDataType = (
747 PATCore.ParticleDataType.Full if self.forceFullSimConfig
748 else PATCore.ParticleDataType.Fast)
749 elif config.dataType() is DataType.FullSim:
750 alg.efficiencyCorrectionTool.ForceDataType = \
751 PATCore.ParticleDataType.Full
752 alg.outOfValidity = 2
753 alg.outOfValidityDeco = 'el_reco_bad_eff' + selectionPostfix
754 alg.electrons = config.readName (self.containerName)
755 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
756 if self.saveDetailedSF:
757 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
758 'reco_effSF' + postfix)
759 sfList += [alg.scaleFactorDecoration]
760
761
762 if config.dataType() is not DataType.Data and not self.noEffSF and self.identificationWP != 'NoID':
763
764 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
765 'ElectronEfficiencyCorrectionAlgID' )
766 config.addPrivateTool( 'efficiencyCorrectionTool',
767 'AsgElectronEfficiencyCorrectionTool' )
768 alg.scaleFactorDecoration = 'el_id_effSF' + selectionPostfix + '_%SYS%'
769 alg.efficiencyCorrectionTool.MapFilePath = map_file
770 alg.efficiencyCorrectionTool.IdKey = self.identificationWP.
replace(
"LH",
"")
771 if self.correlationModelId not in correlationModels:
772 raise ValueError('Invalid correlation model for identification efficiency, '
773 f'has to be one of: {", ".join(correlationModels)}')
774 alg.efficiencyCorrectionTool.CorrelationModel = self.correlationModelId
775 if config.dataType() is DataType.FastSim:
776 alg.efficiencyCorrectionTool.ForceDataType = (
777 PATCore.ParticleDataType.Full if self.forceFullSimConfig
778 else PATCore.ParticleDataType.Fast)
779 elif config.dataType() is DataType.FullSim:
780 alg.efficiencyCorrectionTool.ForceDataType = \
781 PATCore.ParticleDataType.Full
782 alg.outOfValidity = 2
783 alg.outOfValidityDeco = 'el_id_bad_eff' + selectionPostfix
784 alg.electrons = config.readName (self.containerName)
785 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
786 if self.saveDetailedSF:
787 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
788 'id_effSF' + postfix)
789 sfList += [alg.scaleFactorDecoration]
790
791
792 if config.dataType() is not DataType.Data and self.isolationWP != 'NonIso' and not self.noEffSF:
793 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
794 'ElectronEfficiencyCorrectionAlgIsol' )
795 config.addPrivateTool( 'efficiencyCorrectionTool',
796 'AsgElectronEfficiencyCorrectionTool' )
797 alg.scaleFactorDecoration = 'el_isol_effSF' + selectionPostfix + '_%SYS%'
798 alg.efficiencyCorrectionTool.MapFilePath = map_file
799 alg.efficiencyCorrectionTool.IdKey = self.identificationWP.
replace(
"LH",
"")
800 alg.efficiencyCorrectionTool.IsoKey = self.isolationWP
801 if self.correlationModelIso not in correlationModels:
802 raise ValueError('Invalid correlation model for isolation efficiency, '
803 f'has to be one of: {", ".join(correlationModels)}')
804 if self.correlationModelIso != 'TOTAL':
805 warnings.warn_explicit(
806 "Only TOTAL correlation model is currently supported "
807 "for isolation efficiency correction in Run 3.",
808 ElectronEfficiencyCorrelationWarning,
809 filename='', lineno=0)
810 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
811 if config.dataType() is DataType.FastSim:
812 alg.efficiencyCorrectionTool.ForceDataType = (
813 PATCore.ParticleDataType.Full if self.forceFullSimConfig
814 else PATCore.ParticleDataType.Fast)
815 elif config.dataType() is DataType.FullSim:
816 alg.efficiencyCorrectionTool.ForceDataType = \
817 PATCore.ParticleDataType.Full
818 alg.outOfValidity = 2
819 alg.outOfValidityDeco = 'el_isol_bad_eff' + selectionPostfix
820 alg.electrons = config.readName (self.containerName)
821 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
822 if self.saveDetailedSF:
823 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
824 'isol_effSF' + postfix)
825 sfList += [alg.scaleFactorDecoration]
826
827 if (self.chargeIDSelectionRun2 and config.geometry() < LHCPeriod.Run3 and
828 config.dataType() is not DataType.Data and not self.noEffSF):
829 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
830 'ElectronEfficiencyCorrectionAlgEcids' )
831 config.addPrivateTool( 'efficiencyCorrectionTool',
832 'AsgElectronEfficiencyCorrectionTool' )
833 alg.scaleFactorDecoration = 'el_ecids_effSF' + selectionPostfix + '_%SYS%'
834 if self.isolationWP != 'Tight_VarRad':
835 raise ValueError('ECIDS SFs are supported only for Tight_VarRad isolation.')
836 if self.identificationWP == 'LooseBLayerLH':
837 ecids_lh = 'loose'
838 elif self.identificationWP == 'MediumLH':
839 ecids_lh = 'medium'
840 elif self.identificationWP == 'TightLH':
841 ecids_lh = 'tight'
842 else:
843 raise ValueError('ECIDS SFs are supported only for ID LooseBLayerLH, MediumLH, or TightLH')
844
845 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
846 alg.efficiencyCorrectionTool.CorrectionFileNameList = \
847 [f'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v2/ecids/efficiencySF.ChargeID.{ecids_lh}_ECIDS_Tight_VarRad.root']
848 if config.dataType() is DataType.FastSim:
849 alg.efficiencyCorrectionTool.ForceDataType = (
850 PATCore.ParticleDataType.Full if self.forceFullSimConfig
851 else PATCore.ParticleDataType.Fast)
852 elif config.dataType() is DataType.FullSim:
853 alg.efficiencyCorrectionTool.ForceDataType = \
854 PATCore.ParticleDataType.Full
855 alg.outOfValidity = 2
856 alg.outOfValidityDeco = 'el_ecids_bad_eff' + selectionPostfix
857 alg.electrons = config.readName (self.containerName)
858 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
859 if self.saveDetailedSF:
860 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
861 'ecids_effSF' + postfix)
862 sfList += [alg.scaleFactorDecoration]
863
864 if self.addChargeMisIDSF and config.dataType() is not DataType.Data and not self.noEffSF and config.geometry() >= LHCPeriod.Run3:
865 warnings.warn_explicit(
866 "Charge mis-ID SFs are only available for Run 2 and will not"
867 " have any effect in Run 3.",
868 Run2OnlyFeatureWarning, filename='', lineno=0)
869
870 elif self.addChargeMisIDSF and config.dataType() is not DataType.Data and not self.noEffSF and config.geometry() < LHCPeriod.Run3:
871 alg = config.createAlgorithm( 'CP::ElectronEfficiencyCorrectionAlg',
872 'ElectronEfficiencyCorrectionAlgMisid' )
873 config.addPrivateTool( 'efficiencyCorrectionTool',
874 'CP::ElectronChargeEfficiencyCorrectionTool' )
875 alg.scaleFactorDecoration = 'el_charge_misid_effSF' + selectionPostfix + '_%SYS%'
876 if self.isolationWP != 'Tight_VarRad':
877 raise ValueError('Charge mis-ID SFs are supported only for Tight_VarRad isolation.')
878 if self.identificationWP == 'LooseBLayerLH':
879 misid_lh = 'LooseAndBLayerLLH'
880 elif self.identificationWP == 'MediumLH':
881 misid_lh = 'MediumLLH'
882 elif self.identificationWP == 'TightLH':
883 misid_lh = 'TightLLH'
884 else:
885 raise ValueError('Charge mis-ID SFs are supported only for ID LooseBLayerLH, MediumLH, or TightLH')
886 misid_suffix = '_ECIDSloose' if self.chargeIDSelectionRun2 else ''
887
888 alg.efficiencyCorrectionTool.CorrectionFileName = \
889 f'ElectronEfficiencyCorrection/2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v2/charge_misID/chargeEfficiencySF.{misid_lh}_d0z0_TightVarRad{misid_suffix}.root'
890 if config.dataType() is DataType.FastSim:
891 alg.efficiencyCorrectionTool.ForceDataType = (
892 PATCore.ParticleDataType.Full if self.forceFullSimConfig
893 else PATCore.ParticleDataType.Fast)
894 elif config.dataType() is DataType.FullSim:
895 alg.efficiencyCorrectionTool.ForceDataType = \
896 PATCore.ParticleDataType.Full
897 alg.outOfValidity = 2
898 alg.outOfValidityDeco = 'el_misid_bad_eff' + selectionPostfix
899 alg.electrons = config.readName (self.containerName)
900 alg.preselection = config.getPreselection (self.containerName, self.selectionName)
901 if self.saveDetailedSF:
902 config.addOutputVar (self.containerName, alg.scaleFactorDecoration,
903 'charge_misid_effSF' + postfix)
904 sfList += [alg.scaleFactorDecoration]
905
906 if config.dataType() is not DataType.Data and not self.noEffSF and self.saveCombinedSF:
907 alg = config.createAlgorithm( 'CP::AsgObjectScaleFactorAlg',
908 'ElectronCombinedEfficiencyScaleFactorAlg' )
909 alg.particles = config.readName (self.containerName)
910 alg.inScaleFactors = sfList
911 alg.outScaleFactor = 'effSF' + postfix + '_%SYS%'
912 config.addOutputVar (self.containerName, alg.outScaleFactor, 'effSF' + postfix)
913
std::string replace(std::string s, const std::string &s2, const std::string &s3)