ATLAS Offline Software
Public Member Functions | List of all members
python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock Class Reference
Inheritance diagram for python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock:
Collaboration diagram for python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock:

Public Member Functions

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

Detailed Description

Definition at line 781 of file ElectronAnalysisConfig.py.

Constructor & Destructor Documentation

◆ __init__()

def python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.__init__ (   self)

Definition at line 783 of file ElectronAnalysisConfig.py.

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

Member Function Documentation

◆ instanceName()

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

Definition at line 815 of file ElectronAnalysisConfig.py.

815  def instanceName (self) :
816  """Return the instance name for this block"""
817  return self.containerName
818 

◆ makeAlgs()

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

Definition at line 819 of file ElectronAnalysisConfig.py.

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

The documentation for this class was generated from the following file:
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:310
python.processes.powheg.ZZj_MiNNLO.ZZj_MiNNLO.__init__
def __init__(self, base_directory, **kwargs)
Constructor: all process options are set here.
Definition: ZZj_MiNNLO.py:18
TriggerLeg_DictHelpers.MapKeysDict
def MapKeysDict(target_version)
Definition: TriggerLeg_DictHelpers.py:37
python.TriggerAnalysisConfig.is_year_in_current_period
bool is_year_in_current_period(ConfigAccumulator config, int|str year)
Definition: TriggerAnalysisConfig.py:9
python.TriggerAnalysisSFConfig.get_input_years
list[int] get_input_years(ConfigAccumulator config)
Definition: TriggerAnalysisSFConfig.py:35
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
TriggerLeg_DictHelpers.TriggerDict
def TriggerDict()
Definition: TriggerLeg_DictHelpers.py:8
TrigJetMonitorAlgorithm.items
items
Definition: TrigJetMonitorAlgorithm.py:71
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:130
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801