A trigger, sometimes also called a chain, is the combination of a level-1 (L1) hardware trigger seed and some high-level trigger (HLT) software reconstruction algorithms (that e.g. reconstruct some muons) and hypotheses (that e.g. make sure these muons pass the correct thresholds). Both the L1 and HLT components have an associated prescale, which says what fraction of possible times you want the trigger to actually run and select events.
Let’s start by going through a simple trigger that some of you might use in your analyses:
This trigger has a level-1 seed of
L1_2MU10. This means that, in order for the HLT algorithms to run, the hardware trigger must satisfy the requirement of two, 10 GeV muon regions of interest (RoIs).
This trigger is a primary trigger, meaning it is identified as being one of the key triggers for the ATLAS physics programme. Additionally, it is unprescaled, meaning the prescale of this trigger is always exactly one at both L1 and HLT: there is no artificial reduction in the fraction of events that could pass this chain. The
L1_2MU10 item is flagged as passing in all events that have two, 10 GeV muon RoIs, and we process the HLT algorithms on all events that the L1 item passes.
In events where the L1 item has been satisfied, the HLT runs muon reconstruction around all the muon regions of interest that are of the correct
pT. These RoIs are said to seed the HLT reconstruction. For example, in
HLT_2mu14_L12MU10, the muon reconstruction is seeded by all
MU10 RoIs, but the pT thresholds do not have to match - this is a choice that we make when configuring the trigger.
After each step in the reconstruction, a
ComboHypo runs, and makes sure that there are actually two unique HLT objects - i.e. that the trigger satisfies a multiplicity of 2.
Triggers have legs, which each leg being something that has multiplicity
N > 0 that is unique from everything else in the chain. Each leg must have its own L1 seed, but these seeds do not have to actually match the L1 item that seeds the trigger itself.
For example, the chain
HLT_2mu14_L12MU10 has one leg with multiplicity two, and
2mu14 is seeded by
2MU10. The chain
HLT_2mu10_j40_L12MU10 has two legs, one with multiplicity two and one with multiplicity one, and the seeding must be explicitly defined in the menu, since it is not implicit in the L1 item. The chain
HLT_2mu10_mu6noL1_L12MU10 also has two legs (and needs explicit L1 seeding), as does
An example of a real, five leg chain that is currently in the menu is
HLT_j70_0eta320_j50_0eta490_j0_dijetSEP50j12etSEP1000djmassSEPdjdphi240_xe90_tcpufit_xe50_cell_L1MJJ-500-NFF, where each of the five legs have multiplicity one. The legs are:
j0_dijetSEP50j12etSEP1000djmassSEPdjdphi240 ==> this is not an object in the traditional sense, but is the calculated dijet pairs that have
dPhi and invariant mass cuts applied
xe50_cell ==> MET algorithms are combined with different thresholds to have optimal signal efficiency and background rejection.
Menu/folder, but all the config and setup files go into
ChainDefInMenu.pyis confusing, because we use
ChainDefto refer to something else. This should be changed to
ChainPropInMenu.py, at the very least.
jargon alert: menu file, menu python file, menu - these refer to the file that has a the long list of triggers in it - for example,
Chains are defined with a
ChainProp inside of the menu files themselves. The
ChainProp object is a
namedtuple, defined inside
ChainProp has a very limited set of properties:
||the name of the trigger||-|
||what L1 threshold seeds each leg||
||what stream(s) does this trigger seed||
||what prescale/rate groups should this trigger be in|||
||should the legs be parallel or serial merged, or should the menu determine which automatically||
We can now go through these one-by-one:
The trigger name (often also called the chain name) encodes nearly everything for the chain. Every piece of the name holds some important meaning, and it must follow the Run 3 naming convention.
Names are structured
HLT_ + the important stuff +
The L1 seed threshold must be a list with the same length as the number of legs in the trigger. Jets, MET, and noL1 muons run unseeded, and must be seeded by
FSNOSEED. Electrons and photons must be seeded by an EM threshold, muons by a MU threshold, and taus by a TAU threshold.
Thresholds must be defined in the L1 menu, but do not need to correspond to the L1 item that seeds the chain.
For example, the chain
HLT_2mu10_e5_L12MU10 should be seeded by
['MU10','EM3']: but this does not mean that the L1 item needs to actually contain
EM3. In this case, what happens is the very first HLT step applies a requirement on
EM3 in addition to
2MU10, and if there are no
EM3 RoIs in the event the reconstruction does not proceed and the trigger is marked as failing.
In the muon case discussed above, the choice of
MU10 to seed muon reconstruction seems obvious, but it is not always so cut and dry: for example, should
e9 be seeded by
EM7? Never guess, always check with the relevant signature!
The stream indicates where the events selected by the trigger are going to be written out. All possible choices are listed inside
StreamInfo.py. For physics triggers, this is generally
physics_Main, but this will not always be the case. You should be especially careful to clarify exactly which stream the trigger should go into when preparing monitoring or partial event partial event building (PEB) triggers!
As you can see in the table above, the
stream parameter is set to default as
['Main']. Thus, for many triggers in the menu this stream is not explicitly defined.
The only case in which a trigger should go into more than one stream is when one of those streams is
'express'. No trigger should go only into
express, so if you are requested to add a trigger into the express stream when it does not already have an explicit
stream=[PhysicsStream] in the
ChainProp, make sure to add this. i.e. we want this:
The groups list is used for three purposes:
PS:Online, which means that these triggers do not run in either MC or data reprocessings - we only intend them to run online. They are disabled in the default prescale sets prepared when the menu is generated.
HLT_timeburner_L1All, beamspot triggers, and minimum bias triggers.
RATE) and bandwidth (
pbeastand are saved into IS for later plotting.
Most of the groups should be designated using the variables set inside
Physics_pp_run3_v1.py. These are imported at the top of the menu file (if the required group is not yet imported, you can add it). Please be careful to add the variables in a way such that the list has depth 1, i.e. do this:
SingleMuonGroup = ['RATE:SingleMuon', 'BW:Muon'] PrimaryGroup = ['Primary'] ... groups = SingleMuonGroup + PrimaryGroup
groups = [SingleMuonGroup + PrimaryGroup]
Be careful to set the groups in the Run 3 style - if you are implementing Run 2 triggers, don’t blindly copy over the groups!
mergingStrategy: Unless you are performing a specific test, there is no reason to specify this variable. The default is
auto, which means that alignment strategy hardcoded in
MenuAlignmentTools.py is what specifies how the legs are going to be merged. If the default merging is not doing what you think the chain should be, do not attempt to force the strategy to
serial. This will likely cause stalls at runtime. Instead, this should be discussed in detail on JIRA.
mergingOrder: ?? no idea, we don’t use it
mergingOffset: ?? no idea, we don’t use it
I think this isn’t used either - maybe a holdover from Run 2?
Not really sure, to be filled in.
Chain dictionaries (what we colloquially call a chainDict) are an expanded dictionary created from default parameters set by each signature and the parameters configured in the
ChainProp (i.e. the chain name). Since each signature has a different set of necessary parameters, the
ChainDicts look different between signatures. However, they all follow the same basic structure.
The parsing from
ChainDict happens inside the file
SignatureFromChainDict.py, and which is called per-chain from the function
It is crucial that the parameters in the
ChainDict be correctly set, since this is what the signature code later uses to configure the the algorithms and hypos that comprise a trigger.
We’ll start by walking through a simple, single