ATLAS Offline Software
Loading...
Searching...
No Matches
DiTauMassConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
2
3from AnalysisAlgorithmsConfig.ConfigBlock import ConfigBlock
4from AthenaConfiguration.Enums import LHCPeriod
5
6
7class DiTauMassBlock(ConfigBlock):
8 """ConfigBlock for the di-tau Missing Mass Calculator algorithm"""
9 """Further notes on the tool are available at [DiTauMassTools](https://gitlab.cern.ch/atlas/athena/-/tree/main/PhysicsAnalysis/TauID/DiTauMassTools)."""
10 r"""Usage in the ATLAS Run 2 $H\to\tau\tau$ analysis is documented in Section 10 of [ATL-COM-PHYS-2020-721](https://cds.cern.ch/record/2741326)."""
11 """A detailed description of the Missing Mass Calculator (MMC) method and its alternatives is given in Chapter 4 of [Michael Hübner's PhD thesis](https://bonndoc.ulb.uni-bonn.de/xmlui/bitstream/handle/20.500.11811/9734/6567.pdf)."""
12 r"""
13 The MMC method can be applied to had-had, had-lep and lep-lep di-tau decays. Based on the input collections given to the algorithm, the following priority ordering is made internally:
14
15 1. $\tau$-had + $\tau$-had
16 1. $\tau$-had + e
17 1. $\tau$-had + $\mu$
18 1. e + $\mu$
19 1. $\mu$ + $\mu$
20 1. e + e
21
22 This means that if your event has 2 hadronic tau-jets and 1 electron, the MMC fit will be run under the assumption of a had-had event. To force the MMC fit to consider the 1 electron in a had-lep topology, you'd need to edit the C++ code. Alternatively, if you have determined that some objects should not be used as inputs (e.g. hadronic tau-jet already assigned to top reconstruction, pair of leptons assigned to a Z boson), you should decorate these objects with a flag and use the relevant `container.selection` options of the algorithm. In that way, the MMC fit will only be run on the "left-over" objects.
23 """
24 """ WARNING """
25 r""" The MMC method assumes that the MET in a given event originates mostly from the neutrinos associated to the decay of the di-tau system. If your topology has additional sources of MET (e.g. $t\bar{t}H(\to\tau\tau)$, $W(\to\ell\nu)H(\to\tau\tau)$), the MMC method is not recommended and will give nonsensical answers. See e.g. the ATLAS Run 2 search for BSM $VH(\to\tau\tau)$ in [ATL-COM-PHYS-2022-022](https://cds.cern.ch/record/2799543) where the MMC method is combined with alternatives. Additional neutrinos from the decay of B-hadrons typically do not lead to significant enough MET to be a problem, i.e. $t\bar{t}(\to\text{jets})H(\to\tau\tau)$ should be safe."""
26
27 def __init__(self):
28 super().__init__()
29 self.addOption('algName', '', type=str,
30 info='optional name to distinguish between multiple instances of the algorithm.')
31 self.addOption('electrons', '', type=str,
32 info='the input electron container, with a possible selection, in the format `container` or `container.selection`.',
33 meta={'role':'containerRef'})
34 self.addOption('muons', '', type=str,
35 info='the input muon container, with a possible selection, in the format `container` or `container.selection`.',
36 meta={'role':'containerRef'})
37 self.addOption('jets', '', type=str,
38 info='the input jet container, with a possible selection, in the format `container` or `container.selection`.',
39 meta={'role':'containerRef'})
40 self.addOption('taus', '', type=str,
41 info='the input tau-jet container, with a possible selection, in the format `container` or `container.selection`.',
42 meta={'role':'containerRef'})
43 self.addOption('met', '', type=str,
44 info='the input MET container.',
45 meta={'role':'containerRef'})
46 self.addOption('eventSelection', '', type=str,
47 info='optional event filter to run on. If left empty, processes all events.',
48 meta={'role':'region'})
49 self.addOption('saveExtraVariables', False, type=bool,
50 info='whether to save additional output information from the MMC.')
51 self.addOption('floatStopCriterion', True, type=bool,
52 info='whether to activate the floating stopping criterion.')
53 self.addOption('floatStopCriterionMinIter', 10000, type=int,
54 info='minimum number of iteration to activate the floating stopping criterion.')
55 self.addOption('floatStopCriterionCheckFreq', 1000, type=int,
56 info='event frequency for floating stopping criterion to be checked after minimum number of iteration.')
57 self.addOption('floatStopCriterionComp', 0.05, type=float,
58 info='percentage used to assess compatibility for floating stopping criterion to be applied.')
59 self.addOption('calibration', '2024', type=str,
60 info='the calibration set to use.')
61 self.addOption('nSigmaMet', -1, type=int,
62 info='the number of sigmas for the MET resolution scan. Set to -1 to not run the scan.')
63 self.addOption('useTailCleanup', -1, type=int,
64 info='whether to activate the tail cleanup feature.')
65 self.addOption('niterFit2', -1, type=int,
66 info='the number of iterations for each MET scan loop.')
67 self.addOption('niterFit3', -1, type=int,
68 info='the number of iterations for each Mnu loop.')
69 self.addOption('useTauProbability', 1, type=int,
70 info='whether to apply tau probability (additional PDF term corresponding to the ratio of the neutrino momentum to the reconstructed tau momentum).')
71 self.addOption('useMnuProbability', False, type=bool,
72 info=r'whether to apply $m_\nu$ probability (additional PDF term corresponding to the mass of the neutrino system per tau decay, only applied to leptonic tau decays).')
73 self.addOption('useDefaultSettings', -1, type=int,
74 info='whether to take all default options from the tool itself.')
75 self.addOption('useEfficiencyRecovery', -1, type=int,
76 info='whether to enable refitting for failed events, to improve efficiency.')
77 self.addOption('useMETdphiLL', False, type=bool,
78 info='whether to parameterise the MET resolution using `sumET` and `dphiLL` (only for the lep-lep case).')
79 self.addOption('paramFilePath', 'MMC_params_v051224_angle_noLikelihoodFit.root', type=str,
80 info='path to the ROOT file used with `calibSet` ≥ 2024, containing the PDFs for the likelihood.')
81 self.addOption('doMLNU3P', False, type=bool,
82 info='save information about the reconstruction with the best-fit neutrino kinematics.')
83 self.addOption('doMAXW', False, type=bool,
84 info='save information about the reconstruction with the maximum-weight estimator.')
85 self.addOption('saveLlhHisto', False, type=bool,
86 info='save likelihood histograms for debugging purpose. If enabled, it can slow down MMC running time.')
87 self.addOption('doCollinearApprox', False, type=bool,
88 info='save additional variables (mass, x0, x1) from collinear approximation')
89
90 def instanceName (self) :
91 """Return the instance name for this block"""
92 if self.algName:
93 return self.taus.replace('.', '_') + self.algName
94 else:
95 return self.taus.replace('.', '_')
96
97 def makeAlgs(self, config):
98
99 alg = config.createAlgorithm('CP::DiTauMassCalculatorAlg', 'DiTauMMCAlg')
100
101 alg.electrons, alg.electronSelection = config.readNameAndSelection(self.electrons)
102 alg.muons, alg.muonSelection = config.readNameAndSelection(self.muons)
103 alg.jets, alg.jetSelection = config.readNameAndSelection(self.jets)
104 alg.taus, alg.tauSelection = config.readNameAndSelection(self.taus)
105 alg.met = config.readName(self.met)
106
107 config.addPrivateTool( 'mmcTool', 'DiTauMassTools::MissingMassTool' )
108 alg.mmcTool.FloatStoppingCrit = self.floatStopCriterion
109 alg.mmcTool.FloatStoppingCritMinIter = self.floatStopCriterionMinIter
110 alg.mmcTool.FloatStoppingCritCheckFreq = self.floatStopCriterionCheckFreq
111 alg.mmcTool.FloatStoppingCritCheckComp = self.floatStopCriterionComp
112 alg.mmcTool.CalibSet = self.calibration
113 alg.mmcTool.NsigmaMET = self.nSigmaMet
114 alg.mmcTool.UseTailCleanup = self.useTailCleanup
115 alg.mmcTool.NiterFit2 = self.niterFit2
116 alg.mmcTool.NiterFit3 = self.niterFit3
117 alg.mmcTool.UseTauProbability = self.useTauProbability
118 alg.mmcTool.UseMnuProbability = self.useMnuProbability
119 alg.mmcTool.UseDefaults = self.useDefaultSettings
120 alg.mmcTool.UseEfficiencyRecovery = self.useEfficiencyRecovery
121 alg.mmcTool.UseMETDphiLL = self.useMETdphiLL
122 alg.mmcTool.ParamFilePath = self.paramFilePath
123 alg.mmcTool.SaveLlhHisto = self.saveLlhHisto
124
125 if config.geometry() is LHCPeriod.Run2:
126 alg.mmcTool.BeamEnergy = 6500.0
127 else:
128 alg.mmcTool.BeamEnergy = 6800.0
129
130 alg.eventSelection = self.eventSelection
131 alg.doMAXW = self.doMAXW
132 alg.doMLNU3P = self.doMLNU3P
133 alg.doCollinearApprox = self.doCollinearApprox
134
135 config.addOutputVar('EventInfo', 'mmc_fit_status_%SYS%', self.algName + 'mmc_fit_status')
136 config.addOutputVar('EventInfo', 'mmc_mlm_mass_%SYS%', self.algName + 'mmc_mlm_mass')
137 if self.doMAXW:
138 config.addOutputVar('EventInfo', 'mmc_maxw_mass_%SYS%', self.algName + 'mmc_maxw_mass')
139 if self.doMLNU3P:
140 config.addOutputVar('EventInfo', 'mmc_mlnu3p_mass_%SYS%', self.algName + 'mmc_mlnu3p_mass')
141
143 if self.doMLNU3P:
144 config.addOutputVar('EventInfo', 'mmc_mlnu3p_res_4vect_%SYS%', self.algName + 'mmc_mlnu3p_res_4vect')
145 config.addOutputVar('EventInfo', 'mmc_mlnu3p_nu1_4vect_%SYS%', self.algName + 'mmc_mlnu3p_nu1_4vect')
146 config.addOutputVar('EventInfo', 'mmc_mlnu3p_nu2_4vect_%SYS%', self.algName + 'mmc_mlnu3p_nu2_4vect')
147 config.addOutputVar('EventInfo', 'mmc_mlnu3p_tau1_4vect_%SYS%', self.algName + 'mmc_mlnu3p_tau1_4vect')
148 config.addOutputVar('EventInfo', 'mmc_mlnu3p_tau2_4vect_%SYS%', self.algName + 'mmc_mlnu3p_tau2_4vect')
149 if self.doMAXW:
150 config.addOutputVar('EventInfo', 'mmc_maxw_res_4vect_%SYS%', self.algName + 'mmc_maxw_res_4vect')
151 config.addOutputVar('EventInfo', 'mmc_maxw_nu1_4vect_%SYS%', self.algName + 'mmc_maxw_nu1_4vect')
152 config.addOutputVar('EventInfo', 'mmc_maxw_nu2_4vect_%SYS%', self.algName + 'mmc_maxw_nu2_4vect')
153 config.addOutputVar('EventInfo', 'mmc_maxw_tau1_4vect_%SYS%', self.algName + 'mmc_maxw_tau1_4vect')
154 config.addOutputVar('EventInfo', 'mmc_maxw_tau2_4vect_%SYS%', self.algName + 'mmc_maxw_tau2_4vect')
156 config.addOutputVar('EventInfo', 'coll_approx_mass_%SYS%', self.algName + 'coll_approx_mass')
157 config.addOutputVar('EventInfo', 'coll_approx_x0_%SYS%', self.algName + 'coll_approx_x0')
158 config.addOutputVar('EventInfo', 'coll_approx_x1_%SYS%', self.algName + 'coll_approx_x1')
159
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:312