ATLAS Offline Software
Loading...
Searching...
No Matches
python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock Class Reference
Inheritance diagram for python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock:
Collaboration diagram for python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock:

Public Member Functions

 __init__ (self)
 instanceName (self)
 makeAlgs (self, config)

Public Attributes

 useToolKeyAsOutput
 includeAllYearsPerRun
 saveEff
 containerName

Detailed Description

Definition at line 791 of file ElectronAnalysisConfig.py.

Constructor & Destructor Documentation

◆ __init__()

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.__init__ ( self)

Definition at line 793 of file ElectronAnalysisConfig.py.

793 def __init__ (self) :
794 super (ElectronTriggerAnalysisSFBlock, self).__init__ ()
795
796 self.addOption ('triggerChainsPerYear', {}, type=None,
797 info="a dictionary with key (string) the year and value (list of "
798 "strings) the trigger chains. The default is {} (empty dictionary).")
799 self.addOption ('electronID', '', type=str,
800 info="the electron ID WP (string) to use.")
801 self.addOption ('electronIsol', '', type=str,
802 info="the electron isolation WP (string) to use.")
803 self.addOption ('saveEff', False, type=bool,
804 info="define whether we decorate also the trigger scale efficiency "
805 "The default is false.")
806 self.addOption ('prefixSF', 'trigEffSF', type=str,
807 info="the decoration prefix for trigger scale factors, "
808 "the default is 'trigEffSF'")
809 self.addOption ('prefixEff', 'trigEff', type=str,
810 info="the decoration prefix for MC trigger efficiencies, "
811 "the default is 'trigEff'")
812 self.addOption ('includeAllYearsPerRun', False, type=bool,
813 info="if True, all configured years in the LHC run will "
814 "be included in all jobs. The default is False.")
815 self.addOption ('removeHLTPrefix', True, type=bool,
816 info="remove the HLT prefix from trigger chain names, "
817 "The default is True.")
818 self.addOption ('useToolKeyAsOutput', False, type=bool,
819 info="use tool trigger key as output, "
820 "The default is False.")
821 self.addOption ('containerName', '', type=str,
822 info="the input electron container, with a possible selection, in "
823 "the format container or container.selection.")
824

Member Function Documentation

◆ instanceName()

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.instanceName ( self)
Return the instance name for this block

Definition at line 825 of file ElectronAnalysisConfig.py.

825 def instanceName (self) :
826 """Return the instance name for this block"""
827 return self.containerName
828

◆ makeAlgs()

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.makeAlgs ( self,
config )

Definition at line 829 of file ElectronAnalysisConfig.py.

829 def makeAlgs (self, config) :
830
831 if config.dataType() is not DataType.Data:
832 log = logging.getLogger('ElectronTriggerSFConfig')
833
834 if self.includeAllYearsPerRun and not self.useToolKeyAsOutput:
835 log.warning('`includeAllYearsPerRun` is set to True, but `useToolKeyAsOutput` is set to False. '
836 'This will cause multiple branches to be written out with the same content.')
837
838 # Dictionary from TrigGlobalEfficiencyCorrection/Triggers.cfg
839 # Key is trigger chain (w/o HLT prefix)
840 # Value is empty for single leg trigger or list of legs
841 triggerDict = TriggerDict()
842
843 # currently recommended versions
844 version_Run2 = "2015_2025/rel22.2/2025_Run2Rel22_Recommendation_v3"
845 map_Run2 = f"ElectronEfficiencyCorrection/{version_Run2}/map1.txt"
846 version_Run3 = "2015_2025/rel22.2/2025_Run3_Consolidated_Recommendation_v4"
847 map_Run3 = f"ElectronEfficiencyCorrection/{version_Run3}/map2.txt"
848
849 version = version_Run2 if config.geometry() is LHCPeriod.Run2 else version_Run3
850 # Dictionary from TrigGlobalEfficiencyCorrection/MapKeys.cfg
851 # Key is year_leg
852 # Value is list of configs available, first one will be used
853 mapKeysDict = MapKeysDict(version)
854
855 # helper function for leg filtering, very hardcoded but allows autoconfiguration
856 def filterConfFromMap(conf, electronMapKeys):
857 if not conf:
858 raise ValueError("No configuration found for trigger chain.")
859 if len(conf) == 1:
860 return conf[0]
861
862 for c in conf:
863 if c in electronMapKeys:
864 return c
865
866 return conf[0]
867
868 if self.includeAllYearsPerRun:
869 years = [int(year) for year in self.triggerChainsPerYear.keys()]
870 else:
871 from TriggerAnalysisAlgorithms.TriggerAnalysisSFConfig import (
872 get_input_years)
873 years = get_input_years(config)
874
875 # prepare keys
876 import ROOT
877 triggerChainsPerYear_Run2 = {}
878 triggerChainsPerYear_Run3 = {}
879 for year, chains in self.triggerChainsPerYear.items():
880 if not chains:
881 log.warning("No trigger chains configured for year %s. "
882 "Assuming this is intended, no Electron trigger SF will be computed.", year)
883 continue
884
885 chains_split = [chain.replace("HLT_", "").replace(" || ", "_OR_") for chain in chains]
886 if int(year) >= 2022:
887 triggerChainsPerYear_Run3[str(year)] = ' || '.join(chains_split)
888 else:
889 triggerChainsPerYear_Run2[str(year)] = ' || '.join(chains_split)
890 electronMapKeys_Run2 = ROOT.std.map("string", "string")()
891 electronMapKeys_Run3 = ROOT.std.map("string", "string")()
892
893 sc_Run2 = ROOT.TrigGlobalEfficiencyCorrectionTool.suggestElectronMapKeys(triggerChainsPerYear_Run2, version_Run2, electronMapKeys_Run2)
894 sc_Run3 = ROOT.TrigGlobalEfficiencyCorrectionTool.suggestElectronMapKeys(triggerChainsPerYear_Run3, version_Run3, electronMapKeys_Run3)
895 if sc_Run2.code() != 2 or sc_Run3.code() != 2:
896 raise RuntimeError("Failed to suggest electron map keys")
897 electronMapKeys = dict(electronMapKeys_Run2) | dict(electronMapKeys_Run3)
898
899 # collect configurations
900 from TriggerAnalysisAlgorithms.TriggerAnalysisConfig import is_year_in_current_period
901 triggerConfigs = {}
902 for year in years:
903 if not is_year_in_current_period(config, year):
904 continue
905
906 triggerChains = self.triggerChainsPerYear.get(int(year), self.triggerChainsPerYear.get(str(year), []))
907 for chain in triggerChains:
908 chain = chain.replace(" || ", "_OR_")
909 chain_noHLT = chain.replace("HLT_", "")
910 chain_out = chain_noHLT if self.removeHLTPrefix else chain
911 legs = triggerDict[chain_noHLT]
912 if not legs:
913 if chain_noHLT[0] == 'e' and chain_noHLT[1].isdigit:
914 chain_key = f"{year}_{chain_noHLT}"
915 chain_conf = mapKeysDict[chain_key][0]
916 triggerConfigs[chain_conf if self.useToolKeyAsOutput else chain_out] = chain_conf
917 else:
918 for leg in legs:
919 if leg[0] == 'e' and leg[1].isdigit:
920 leg_out = leg if self.removeHLTPrefix else f"HLT_{leg}"
921 leg_key = f"{year}_{leg}"
922 leg_conf = filterConfFromMap(mapKeysDict[leg_key], electronMapKeys)
923 triggerConfigs[leg_conf if self.useToolKeyAsOutput else leg_out] = leg_conf
924
925 decorations = [self.prefixSF]
926 if self.saveEff:
927 decorations += [self.prefixEff]
928
929 for label, conf in triggerConfigs.items():
930 for deco in decorations:
931 alg = config.createAlgorithm('CP::ElectronEfficiencyCorrectionAlg',
932 'EleTrigEfficiencyCorrectionsAlg' + deco +
933 '_' + label)
934 config.addPrivateTool( 'efficiencyCorrectionTool',
935 'AsgElectronEfficiencyCorrectionTool' )
936
937 # Reproduce config from TrigGlobalEfficiencyAlg
938 alg.efficiencyCorrectionTool.MapFilePath = map_Run3 if config.geometry() is LHCPeriod.Run3 else map_Run2
939 alg.efficiencyCorrectionTool.IdKey = self.electronID.replace("LH","")
940 alg.efficiencyCorrectionTool.IsoKey = self.electronIsol
941 alg.efficiencyCorrectionTool.TriggerKey = (
942 ("Eff_" if deco == self.prefixEff else "") + conf)
943 alg.efficiencyCorrectionTool.CorrelationModel = "TOTAL"
944 alg.efficiencyCorrectionTool.ForceDataType = \
945 PATCore.ParticleDataType.Full
946
947 alg.scaleFactorDecoration = f"el_{deco}_{label}_%SYS%"
948
949 alg.outOfValidity = 2 #silent
950 alg.outOfValidityDeco = f"bad_eff_ele{deco}_{label}"
951 alg.electrons = config.readName (self.containerName)
952 alg.preselection = config.getPreselection (self.containerName, "")
953 config.addOutputVar (self.containerName, alg.scaleFactorDecoration, f"{deco}_{label}")
954
955
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130

Member Data Documentation

◆ containerName

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.containerName

Definition at line 953 of file ElectronAnalysisConfig.py.

◆ includeAllYearsPerRun

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.includeAllYearsPerRun

Definition at line 868 of file ElectronAnalysisConfig.py.

◆ saveEff

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.saveEff

Definition at line 926 of file ElectronAnalysisConfig.py.

◆ useToolKeyAsOutput

python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.useToolKeyAsOutput

Definition at line 834 of file ElectronAnalysisConfig.py.


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