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 773 of file ElectronAnalysisConfig.py.

Constructor & Destructor Documentation

◆ __init__()

def python.ElectronAnalysisConfig.ElectronTriggerAnalysisSFBlock.__init__ (   self)

Definition at line 775 of file ElectronAnalysisConfig.py.

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

Member Function Documentation

◆ instanceName()

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

Definition at line 807 of file ElectronAnalysisConfig.py.

807  def instanceName (self) :
808  """Return the instance name for this block"""
809  return self.containerName
810 

◆ makeAlgs()

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

Definition at line 811 of file ElectronAnalysisConfig.py.

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

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:307
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:127
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:801