Skip to content

CPAlgorithms: separate trigger matching with loose and tight objects

@adohnalo has been looking into a lepton+jets ttbar analysis with tight and loose leptons (for fake estimation purposes), and discrepancies have been observed between running two different YAML configs (tight and loose separately) vs running both selections from a single YAML config (desired outcome). The differences have been traced to the trigger matching, which could only been run once. This MR extends the interface to allow to run a second instance of trigger matching.

Specifically:

  • the trigger matching config block is registered separately in the YAML as TriggerMatching. This means that users can schedule either trigger selection+matching (Trigger) or just the matching part (TriggerMatching), to avoid running the selection multiple times (not needed!)
  • unfortunately, a postfix option has to be re-introduced into the trigger matching block, to differentiate between different instances of the block both in the naming of algorithms and of output variables / decorations. The user needs to be able to identify which matching branches (efficiency SF and decision) in the output correspond to which setup, so it does make sense to let them name postfix (rather than making up a name internally)
  • I took the opportunity to refactor a piece of the trigger matching config that was essentially the same function repeated 4 times, @mrimoldi might want to double-check since it came from his previous MR
  • for the EventSelection, the GLOBALTRIGMATCH flag (which checks the trigger matching decision) now accepts a selection name to retrieve any such alternative matching setup

A loose+tight lepton setup might then look like this:

Trigger:
    triggerChainsPerYear:
        '2015':
            - 'HLT_e24_lhmedium_L1EM20VH || HLT_e60_lhmedium || HLT_e120_lhloose'
            - 'HLT_mu20_iloose_L1MU15 || HLT_mu50'
        '2016':
            - 'HLT_e26_lhtight_nod0_ivarloose || HLT_e60_lhmedium_nod0 || HLT_e140_lhloose_nod0'
            - 'HLT_mu26_ivarmedium || HLT_mu50'
        '2017':
            - 'HLT_e26_lhtight_nod0_ivarloose || HLT_e60_lhmedium_nod0 || HLT_e140_lhloose_nod0'
            - 'HLT_mu26_ivarmedium || HLT_mu50'
        '2018':
            - 'HLT_e26_lhtight_nod0_ivarloose || HLT_e60_lhmedium_nod0 || HLT_e140_lhloose_nod0'
            - 'HLT_mu26_ivarmedium || HLT_mu50'
        '2022':
            - 'HLT_e26_lhtight_ivarloose_L1EM22VHI || HLT_e60_lhmedium_L1EM22VHI || HLT_e140_lhloose_L1EM22VHI'
            - 'HLT_mu26_ivarmedium_L1MU14FCH || HLT_mu50_L1MU14FCH'
    noFilter: True
    electrons: 'AnaElectrons.tight'
    muons: 'AnaMuons.tight'
    electronID: 'Tight'
    electronIsol: 'Tight_VarRad'
    muonID: 'Medium'
    postfix: 'tight'

TriggerMatching:
    triggerChainsPerYear:
        '2015':
            - 'HLT_e24_lhmedium_L1EM20VH || HLT_e60_lhmedium || HLT_e120_lhloose'
            - 'HLT_mu20_iloose_L1MU15 || HLT_mu50'
        '2016':
            - 'HLT_e26_lhtight_nod0_ivarloose || HLT_e60_lhmedium_nod0 || HLT_e140_lhloose_nod0'
            - 'HLT_mu26_ivarmedium || HLT_mu50'
        '2017':
            - 'HLT_e26_lhtight_nod0_ivarloose || HLT_e60_lhmedium_nod0 || HLT_e140_lhloose_nod0'
            - 'HLT_mu26_ivarmedium || HLT_mu50'
        '2018':
            - 'HLT_e26_lhtight_nod0_ivarloose || HLT_e60_lhmedium_nod0 || HLT_e140_lhloose_nod0'
            - 'HLT_mu26_ivarmedium || HLT_mu50'
        '2022':
            - 'HLT_e26_lhtight_ivarloose_L1EM22VHI || HLT_e60_lhmedium_L1EM22VHI || HLT_e140_lhloose_L1EM22VHI'
            - 'HLT_mu26_ivarmedium_L1MU14FCH || HLT_mu50_L1MU14FCH'
    noFilter: True
    electrons: 'AnaElectrons.loose'
    muons: 'AnaMuons.loose'
    electronID: 'Medium'
    electronIsol: 'Medium_VarRad'
    muonID: 'Medium'
    postfix: 'loose'

where the triggers unfortunately have to be repeated at the moment (maybe someone can think of a nice way to get around this? it does allow for more flexibility, but I'm not sure it's actually needed by anyone...), but now the matching proceeds twice on separate electron and muon selections, and two postfixes are created ("loose" and "tight").

A suitable lepton+jets ttbar EventSelection can then be created for the main analysis AND the fake estimation as e.g.:

EventSelection:
  - electrons: 'AnaElectrons.tight||loose'
    muons: 'AnaMuons.tight||loose'
    jets: 'AnaJets.baselineJvtTight||baselineJvtLoose'
    noFilter: False
    selectionCutsDict:
      'SUBcommon_loose': |
        GLOBALTRIGMATCH loose
        JET_N baselineJvtLoose 20000 >= 4
        SAVE
      'SUBcommon_tight': |
        GLOBALTRIGMATCH tight
        JET_N baselineJvtTight 20000 >= 4
        SAVE
      'ejets_tight': |
        IMPORT SUBcommon_tight
        EL_N tight 27000 == 1
        MU_N tight 27000 == 0
        SAVE
      'mujets_tight': |
        IMPORT SUBcommon_tight
        EL_N tight 27000 == 0
        MU_N tight 27000 == 1
        SAVE
      'ejets_loose': |
        IMPORT SUBcommon_loose
        EL_N loose 27000 == 1
        MU_N loose 27000 == 0
        SAVE
      'mujets_loose': |
        IMPORT SUBcommon_loose
        EL_N loose 27000 == 0
        MU_N loose 27000 == 1
        SAVE

Merge request reports