rivet is hosted by Hepforge, IPPP Durham

Rivet analyses reference

ATLAS_2024_I2809112

ttbb production at 13 TeV
Experiment: ATLAS (LHC)
Inspire ID: 2809112
Status: VALIDATED
Authors:
  • Mahsana Haleem
References: Beams: p+ p+
Beam energies: (6500.0, 6500.0) GeV
Run details:
  • pp -> ttbb in the e-mu channel

This paper presents measurements of top-antitop quark pair ($t\bar{t}) production in association with additional $b$-jets. The analysis utilises 140 fbi${}^{-1}$ of proton-proton collision data collected with the ATLAS detector at the Large Hadron Collider at a centre-of-mass energy of 13 TeV. Fiducial cross-sections are extracted in a final state featuring one electron and one muon, with at least three or four $b$-jets. Results are presented at the particle level for both integrated cross-sections and normalised differential cross-sections, as functions of global event properties, jet kinematics, and $b$-jet pair properties. Observable quantities characterising $b$-jets originating from the top quark decay and additional b-jets are also measured at the particle level, after correcting for detector effects. The measured integrated fiducial cross-sections are consistent with $t\bar{t}b\bar{b}$ predictions from various next-to-leading-order matrix element calculations matched to a parton shower within the uncertainties ofthe predictions. State-of-the-art theoretical predictions are compared with the differential measurements; none of them simultaneously describes all observables. Differences between any two predictions are smaller than the measurement uncertainties for most observables.

Source code: ATLAS_2024_I2809112.cc
  1// -*- C++ -*-
  2#include "Rivet/Analysis.hh"
  3#include "Rivet/Projections/FastJets.hh"
  4#include "Rivet/Projections/FinalState.hh"
  5#include "Rivet/Projections/LeptonFinder.hh"
  6#include "Rivet/Projections/PromptFinalState.hh"
  7#include "Rivet/Projections/VetoedFinalState.hh"
  8#include "Rivet/Projections/MissingMomentum.hh"
  9#include "Rivet/Projections/InvisibleFinalState.hh"
 10
 11namespace Rivet {
 12
 13
 14class ATLAS_2024_I2809112 : public Analysis {
 15 public:
 16
 17  /// @brief ttbb production at 13 TeV
 18  RIVET_DEFAULT_ANALYSIS_CTOR(ATLAS_2024_I2809112);
 19
 20  void init() {
 21
 22    // Photons
 23    PromptFinalState photons(Cuts::abspid == PID::PHOTON);
 24
 25    // Kinematic cuts for leptons
 26    const Cut cuts_lep = Cuts::pT > 25*GeV && Cuts::abseta < 2.5;
 27
 28    // Muons
 29    PromptFinalState bare_mu(Cuts::abspid == PID::MUON, TauDecaysAs::PROMPT);
 30    LeptonFinder all_dressed_mu(bare_mu, photons, 0.1, cuts_lep);
 31    declare(all_dressed_mu, "DressedMuons");
 32
 33    // Electrons
 34    PromptFinalState bare_el(Cuts::abspid == PID::ELECTRON, TauDecaysAs::PROMPT);
 35    LeptonFinder all_dressed_el(bare_el, photons, 0.1, cuts_lep);
 36    declare(all_dressed_el, "DressedElectrons");
 37
 38    //Jet forming
 39    const InvisibleFinalState neutrinos(OnlyPrompt::YES, TauDecaysAs::PROMPT);
 40
 41    VetoedFinalState vfs(FinalState(Cuts::abseta < 5.0));
 42    vfs.addVetoOnThisFinalState(all_dressed_el);
 43    vfs.addVetoOnThisFinalState(all_dressed_mu);
 44    vfs.addVetoOnThisFinalState(neutrinos);
 45
 46    FastJets jet(vfs, JetAlg::ANTIKT, 0.4, JetMuons::ALL, JetInvisibles::ALL);
 47    declare(jet, "Jets");
 48
 49    const FinalState fs(Cuts::abseta < 5.);
 50    declare(MissingMomentum(fs), "ETmiss");
 51
 52    // Njets
 53    book(_d["nbjets_emu2b"],     71, 1, 1);
 54    book(_d["nlightjets_emu3b"], 95, 1, 1);
 55    book(_d["nlightjets_emu4b"], 134, 1, 1);
 56
 57    // HT
 58    book(_h["ht_had_emu3b"],  72, 1, 1);
 59    book(_h["ht_all_emu3b"],  73, 1, 1);
 60    book(_h["ht_had_emu4b"], 102, 1, 1);
 61    book(_h["ht_all_emu4b"], 103, 1, 1);
 62
 63    // b-jet pTs
 64    book(_h["lead_bjet_pt_emu3b"],     76, 1, 1);
 65    book(_h["sublead_bjet_pt_emu3b"],  78, 1, 1);
 66    book(_h["third_bjet_pt_emu3b"],    80, 1, 1);
 67    book(_h["lead_bjet_pt_emu4b"],    106, 1, 1);
 68    book(_h["sublead_bjet_pt_emu4b"], 108, 1, 1);
 69    book(_h["third_bjet_pt_emu4b"],   110, 1, 1);
 70    book(_h["fourth_bjet_pt_emu4b"],  112, 1, 1);
 71    // bjet eta
 72    book(_h["lead_bjet_eta_emu3b"],     82, 1, 1);
 73    book(_h["sublead_bjet_eta_emu3b"],  84, 1, 1);
 74    book(_h["third_bjet_eta_emu3b"],    86, 1, 1);
 75    book(_h["lead_bjet_eta_emu4b"],    114, 1, 1);
 76    book(_h["sublead_bjet_eta_emu4b"], 116, 1, 1);
 77    book(_h["third_bjet_eta_emu4b"],   118, 1, 1);
 78    book(_h["fourth_bjet_eta_emu4b"],  120, 1, 1);
 79
 80    //bjets from top with limited accuracy
 81    book(_h["lead_bjetfromtop_pt_emu3b"],      77, 1, 1);
 82    book(_h["sublead_bjetfromtop_pt_emu3b"],   79, 1, 1);
 83    book(_h["lead_bjetfromtop_pt_emu4b"],     107, 1, 1);
 84    book(_h["sublead_bjetfromtop_pt_emu4b"],  109, 1, 1);
 85    book(_h["lead_bjetfromtop_eta_emu3b"],     83, 1, 1);
 86    book(_h["sublead_bjetfromtop_eta_emu3b"],  85, 1, 1);
 87    book(_h["lead_bjetfromtop_eta_emu4b"],    115, 1, 1);
 88    book(_h["sublead_bjetfromtop_eta_emu4b"], 117, 1, 1);
 89
 90    //additional bjets
 91    book(_h["lead_bjetfromQCD_pt_emu3b"],      81, 1, 1);
 92    book(_h["lead_bjetfromQCD_eta_emu3b"],     87, 1, 1);
 93    book(_h["lead_bjetfromQCD_pt_emu4b"],     111, 1, 1);
 94    book(_h["sublead_bjetfromQCD_pt_emu4b"],  113, 1, 1);
 95    book(_h["lead_bjetfromQCD_eta_emu4b"],    119, 1, 1);
 96    book(_h["sublead_bjetfromQCD_eta_emu4b"], 121, 1, 1);
 97
 98    // leading bb pair
 99    book(_h["m_bb_leading_emu3b"],   88, 1, 1);
100    book(_h["pt_bb_leading_emu3b"],  89, 1, 1);
101    book(_h["dR_bb_leading_emu3b"],  94, 1, 1);
102    book(_h["m_bb_leading_emu4b"],  122, 1, 1);
103    book(_h["pt_bb_leading_emu4b"], 123, 1, 1);
104    book(_h["dR_bb_leading_emu4b"], 133, 1, 1);
105
106    // closest bb pair
107    book(_h["m_bb_closest_emu4b"],  128, 1, 1);
108    book(_h["pt_bb_closest_emu4b"], 129, 1, 1);
109    book(_h["dR_bb_closest_emu4b"], 132, 1, 1);
110
111    // bb pair from top
112    book(_h["m_bbfromtop_emu3b"],   90, 1, 1);
113    book(_h["pt_bbfromtop_emu3b"],  91, 1, 1);
114    book(_h["m_bbfromtop_emu4b"],  124, 1, 1);
115    book(_h["pt_bbfromtop_emu4b"], 125, 1, 1);
116
117    book(_h["m_bbadd_emu4b"],  130, 1, 1);
118    book(_h["pt_bbadd_emu4b"], 131, 1, 1);
119
120    // light-jets
121    book(_h["lead_lightjet_eta_emu3b"], 100, 1, 1);
122    book(_h["lead_lightjet_pt_emu3b"],  101, 1, 1);
123    book(_h["lead_lightjet_eta_emu4b"], 139, 1, 1);
124    book(_h["lead_lightjet_pt_emu4b"],  140, 1, 1);
125
126    // global variables
127    book(_h["dR_avg_emu3b"],       74, 1, 1);
128    book(_h["deta_jj_max_emu3b"],  75, 1, 1);
129    book(_h["dR_avg_emu4b"],      104, 1, 1);
130    book(_h["deta_jj_max_emu4b"], 105, 1, 1);
131
132    book(_h["m_emubblead_emu3b"],    92, 1, 1);
133    book(_h["m_emubbfromtop_emu3b"], 93, 1, 1);
134
135    book(_h["dR_emubblead_thirdbjet_emu3b"],          96, 1, 1);
136    book(_h["dR_emubbfromtop_leadaddb_emu3b"],        97, 1, 1);
137    book(_h["dR_emubbfromtop_leadlightjet_emu3b"],    98, 1, 1);
138    book(_h["ptdiff_leadaddbjet_leadlightjet_emu3b"], 99, 1, 1);
139
140    book(_h["m_emubblead_emu4b"],    126, 1, 1);
141    book(_h["m_emubbfromtop_emu4b"], 127, 1, 1);
142
143    book(_h["dR_emubblead_thirdbjet_emu4b"],          135, 1, 1);
144    book(_h["dR_emubbfromtop_leadaddb_emu4b"],        136, 1, 1);
145    book(_h["dR_emubbfromtop_leadlightjet_emu4b"],    137, 1, 1);
146    book(_h["ptdiff_leadaddbjet_leadlightjet_emu4b"], 138, 1, 1);
147
148  }
149
150
151  void analyze(const Event& event) {
152
153    DressedLeptons muons = apply<LeptonFinder>(event, "DressedMuons").dressedLeptons();
154    DressedLeptons electrons = apply<LeptonFinder>(event, "DressedElectrons").dressedLeptons();
155    const double met = apply<MissingMomentum>(event, "ETmiss").missingPt();
156
157    // lepton-jet overlap removal (note: muons are not included in jet finding)
158    Jets jets = apply<FastJets>(event, "Jets").jetsByPt(Cuts::pT > 25*GeV && Cuts::abseta < 2.5);
159
160    // Remove leptons within dR < 0.4 of a jet
161    idiscardIfAnyDeltaRLess(muons, jets, 0.4);
162    idiscardIfAnyDeltaRLess(electrons, jets, 0.4);
163
164    Jets bjets, lightjets;
165    for (const Jet& jet: jets) {
166      if (jet.bTagged(Cuts::pT > 5.0*GeV))  bjets += jet;
167      else                                  lightjets += jet;
168    }
169
170    // Evaluate basic event selection
171    size_t nElecs = electrons.size(), nMuons = muons.size();
172    const bool pass_emu = (nElecs == 1) && (nMuons ==1) &&
173                          (electrons[0].pT() >= 28*GeV) && (muons[0].pT() >= 28*GeV) &&
174                          (electrons[0].charge() * muons[0].charge() < 0.);
175
176
177    // If we don't have exactly 2 leptons then veto the event
178    size_t nbjets = bjets.size();
179    if (!pass_emu || nbjets < 2) vetoEvent;
180
181    _d["nbjets_emu2b"]->fill(nbjets>=5? "≥5"s : toString(nbjets));
182    if (nbjets < 3) vetoEvent;
183
184    DressedLeptons leptons = electrons + muons;
185    const double hthad = sum(jets, Kin::pT, 0.0);
186    const double htvis = sum(leptons, Kin::pT, hthad);
187    const double htall = htvis + met;
188
189    const FourMomentum jsum = bjets[0].mom() + bjets[1].mom();
190    const double dr_leading = deltaR(bjets[0], bjets[1]);
191
192    size_t idx1 = 0, idx2 = 1, npairs = 0;
193    double dr_closest = 1e3, dr_avg = 0., maxdR_bb = 0.;
194    for (size_t i = 0; i < bjets.size(); ++i) {
195      for (size_t j = i+1; j < bjets.size(); ++j) {
196        const double dr = deltaR(bjets[i], bjets[j]);
197        dr_avg += dr;
198        ++npairs;
199        if (dr >= maxdR_bb)  maxdR_bb = dr;
200        if (dr < dr_closest) {
201          idx1 = i;
202          idx2 = j;
203          dr_closest = dr;
204        }
205      }
206    }
207    dr_avg /= npairs;
208
209    const FourMomentum bb_closest = bjets[idx1].mom() + bjets[idx2].mom();
210    const double mindR_l1b = drlb_min(leptons[0], bjets);
211    const double mindR_l2b = drlb_min(leptons[1], bjets);
212
213    double deta_max = 0.;
214    for (size_t i = 0; i < jets.size(); ++i) {
215      for (size_t j = i+1; j < jets.size(); ++j) {
216        const double abs_eta = fabs(deltaEta(jets[i], jets[j]));
217        if (abs_eta >= deta_max)  deta_max = abs_eta;
218      }
219    }
220
221    const FourMomentum emubb = leptons[0].mom() + leptons[1].mom() + bjets[0].mom() + bjets[1].mom();
222    const double mass_emubb = emubb.mass();
223    const double dR_emubblead_thirdbjet = deltaR(emubb, bjets[2].mom());
224
225    // permuted set of jets
226    vector<Jets> bjet_sets;
227    do {
228      bjet_sets.push_back(bjets);
229    } while (next_permutation(bjets.begin(), bjets.end()));
230
231    //find jet pairs from top
232    double m_bestweight_max = -9.;
233    Jets m_bjets_bestweight;
234    for (const Jets& bjet_vec : bjet_sets) {
235    	if (bjet_vec.size() < 2) continue;
236    	// calculate bjet from top weights using algorithm
237      const double bfromtop_weight = bjetOriginWeight(leptons, bjet_vec, dr_closest,
238                                                      maxdR_bb, mindR_l1b, mindR_l2b);
239      if (bfromtop_weight > m_bestweight_max) {
240        m_bestweight_max = bfromtop_weight;
241        m_bjets_bestweight = bjet_vec;
242      }
243    }
244
245    Jets bfromtop, bfromQCD;
246    bfromtop += m_bjets_bestweight[0];
247    bfromtop += m_bjets_bestweight[1];
248    bfromQCD += m_bjets_bestweight[2];
249    if (m_bjets_bestweight.size()>=4) bfromQCD += m_bjets_bestweight[3];
250
251    isortByPt(bfromtop);
252    isortByPt(bfromQCD);
253
254    const FourMomentum jfromtopsum = bfromtop[0].mom() + bfromtop[1].mom();
255    const FourMomentum dilepton = leptons[0].mom() + leptons[1].mom();
256    const FourMomentum lljjfromtop = dilepton + jfromtopsum;
257    const double mass_emubbfromtop = lljjfromtop.mass();
258    const double dR_emubbfromtop_leadadd = deltaR(lljjfromtop, bfromQCD[0].mom());
259
260
261    //nlight jets
262    size_t nlightjets = lightjets.size();
263    _d["nlightjets_emu3b"]->fill(nlightjets>=3? "≥3"s : toString(nlightjets));
264    // b-jet pTs
265    _h["lead_bjet_pt_emu3b"]->fill(bjets[0].pT()/GeV);
266    _h["sublead_bjet_pt_emu3b"]->fill(bjets[1].pT()/GeV);
267    _h["third_bjet_pt_emu3b"]->fill(bjets[2].pT()/GeV);
268    // b-jet eta
269    _h["lead_bjet_eta_emu3b"]->fill(fabs(bjets[0].eta()));
270    _h["sublead_bjet_eta_emu3b"]->fill(bjets[1].abseta());
271    _h["third_bjet_eta_emu3b"]->fill(bjets[2].abseta());
272
273    // bjets assigned to top
274    _h["lead_bjetfromtop_pt_emu3b"]->fill(bfromtop[0].pT()/GeV);
275    _h["sublead_bjetfromtop_pt_emu3b"]->fill(bfromtop[1].pT()/GeV);
276    _h["lead_bjetfromtop_eta_emu3b"]->fill(bfromtop[0].abseta());
277    _h["sublead_bjetfromtop_eta_emu3b"]->fill(bfromtop[1].abseta());
278
279    //additional bjets
280    _h["lead_bjetfromQCD_pt_emu3b"]->fill(bfromQCD[0].pT()/GeV);
281    _h["lead_bjetfromQCD_eta_emu3b"]->fill(bfromQCD[0].abseta());
282
283    // HT
284    _h["ht_had_emu3b"]->fill(hthad/GeV);
285    _h["ht_all_emu3b"]->fill(htall/GeV);
286
287    // leading bb pair
288    _h["m_bb_leading_emu3b"]->fill(jsum.mass()/GeV);
289    _h["pt_bb_leading_emu3b"]->fill(jsum.pT()/GeV);
290    _h["dR_bb_leading_emu3b"]->fill(dr_leading);
291
292    // b-jets pair assigned to top
293    _h["m_bbfromtop_emu3b"]->fill(jfromtopsum.mass()/GeV);
294    _h["pt_bbfromtop_emu3b"]->fill(jfromtopsum.pT()/GeV);
295
296    // global
297    _h["dR_avg_emu3b"]->fill(dr_avg);
298    _h["deta_jj_max_emu3b"]->fill(deta_max);
299
300    _h["m_emubblead_emu3b"]->fill(mass_emubb/GeV);
301
302    _h["m_emubbfromtop_emu3b"]->fill(mass_emubbfromtop/GeV);
303
304    _h["dR_emubblead_thirdbjet_emu3b"]->fill(dR_emubblead_thirdbjet);
305    _h["dR_emubbfromtop_leadaddb_emu3b"]->fill(dR_emubbfromtop_leadadd);
306
307    // light jets
308    if (lightjets.size()>0) {
309      _h["lead_lightjet_pt_emu3b"]->fill(lightjets[0].pT()/GeV);
310      _h["lead_lightjet_eta_emu3b"]->fill(lightjets[0].abseta());
311
312      const double dR_emubbfromtop_leadlightjet = deltaR(lljjfromtop, lightjets[0].mom());
313      _h["dR_emubbfromtop_leadlightjet_emu3b"]->fill(dR_emubbfromtop_leadlightjet);
314      _h["ptdiff_leadaddbjet_leadlightjet_emu3b"]->fill((lightjets[0].pT() - bfromQCD[0].pT())/GeV);
315    }
316
317    if (nbjets < 4) vetoEvent;
318
319     //nlight jets
320     _d["nlightjets_emu4b"]->fill(nlightjets>=3? "≥3"s : toString(nlightjets));
321     // b-jet pTs
322     _h["lead_bjet_pt_emu4b"]->fill(bjets[0].pT()/GeV);
323     _h["sublead_bjet_pt_emu4b"]->fill(bjets[1].pT()/GeV);
324     _h["third_bjet_pt_emu4b"]->fill(bjets[2].pT()/GeV);
325     _h["fourth_bjet_pt_emu4b"]->fill(bjets[3].pT()/GeV);
326     // bjets eta
327     _h["lead_bjet_eta_emu4b"]->fill(bjets[0].abseta());
328     _h["sublead_bjet_eta_emu4b"]->fill(bjets[1].abseta());
329     _h["third_bjet_eta_emu4b"]->fill(bjets[2].abseta());
330     _h["fourth_bjet_eta_emu4b"]->fill(bjets[3].abseta());
331
332     // bjets assigned to top
333     _h["lead_bjetfromtop_pt_emu4b"]->fill(bfromtop[0].pT()/GeV);
334     _h["sublead_bjetfromtop_pt_emu4b"]->fill(bfromtop[1].pT()/GeV);
335     _h["lead_bjetfromtop_eta_emu4b"]->fill(bfromtop[0].abseta());
336     _h["sublead_bjetfromtop_eta_emu4b"]->fill(bfromtop[1].abseta());
337
338     // additional b-jets
339     _h["lead_bjetfromQCD_pt_emu4b"]->fill(bfromQCD[0].pT()/GeV);
340     _h["sublead_bjetfromQCD_pt_emu4b"]->fill(bfromQCD[1].pT()/GeV);
341     _h["lead_bjetfromQCD_eta_emu4b"]->fill(bfromQCD[0].abseta());
342     _h["sublead_bjetfromQCD_eta_emu4b"]->fill(bfromQCD[1].abseta());
343
344     // HT
345     _h["ht_had_emu4b"]->fill(hthad/GeV);
346     _h["ht_all_emu4b"]->fill(htall/GeV);
347
348     // leading bb pair
349     _h["m_bb_leading_emu4b"]->fill(jsum.mass()/GeV);
350     _h["pt_bb_leading_emu4b"]->fill(jsum.pT()/GeV);
351     _h["dR_bb_leading_emu4b"]->fill(dr_leading);
352
353     // b-jets pair assigned to top
354     _h["m_bbfromtop_emu4b"]->fill(jfromtopsum.mass()/GeV);
355     _h["pt_bbfromtop_emu4b"]->fill(jfromtopsum.pT()/GeV);
356
357     // closest bb pair
358     _h["m_bb_closest_emu4b"]->fill(bb_closest.mass()/GeV);
359     _h["pt_bb_closest_emu4b"]->fill(bb_closest.pT()/GeV);
360     _h["dR_bb_closest_emu4b"]->fill(dr_closest);
361
362
363     const FourMomentum bb_add = bfromQCD[0].mom() + bfromQCD[1].mom();
364     _h["m_bbadd_emu4b"]->fill(bb_add.mass()/GeV);
365     _h["pt_bbadd_emu4b"]->fill(bb_add.pT()/GeV);
366
367     // global
368     _h["dR_avg_emu4b"]->fill(dr_avg);
369     _h["deta_jj_max_emu4b"]->fill(deta_max);
370     _h["m_emubblead_emu4b"]->fill(mass_emubb/GeV);
371     _h["m_emubbfromtop_emu4b"]->fill(mass_emubbfromtop/GeV);
372     _h["dR_emubblead_thirdbjet_emu4b"]->fill(dR_emubblead_thirdbjet);
373     _h["dR_emubbfromtop_leadaddb_emu4b"]->fill(dR_emubbfromtop_leadadd);
374
375     if (lightjets.size()>0) {
376       _h["lead_lightjet_pt_emu4b"]->fill(lightjets[0].pT()/GeV);
377       _h["lead_lightjet_eta_emu4b"]->fill(lightjets[0].abseta());
378
379       const double dR_emubbfromtop_leadlightjet = deltaR(lljjfromtop, lightjets[0].mom());
380       _h["dR_emubbfromtop_leadlightjet_emu4b"]->fill(dR_emubbfromtop_leadlightjet);
381       _h["ptdiff_leadaddbjet_leadlightjet_emu4b"]->fill((lightjets[0].pT() - bfromQCD[0].pT())/GeV);
382     }
383
384  }
385
386  void finalize() {
387    // Normalise all histograms
388    normalize(_h, 1000.);
389    normalize(_d, 1000.);
390  }
391
392  double drlb_min(const DressedLepton& lepton, const Jets& bjets) const {
393    double mindr = 1e3;
394    for (size_t i = 0; i < bjets.size(); ++i) {
395      const double dr = deltaR(lepton, bjets[i]);
396      if (dr < mindr)  mindr = dr;
397    }
398    return mindr;
399  }
400
401  /// @todo Replace with std::next_permutation when adopting C++20
402  bool next_permutation(vector<Jet>::iterator first, vector<Jet>::iterator last) const {
403    auto r_first = std::make_reverse_iterator(last);
404    auto r_last = std::make_reverse_iterator(first);
405    auto left = std::is_sorted_until(r_first, r_last,
406                                     [](const Jet& l, const Jet& r) { return l.pT() > r.pT(); });
407
408    if (left != r_last) {
409      auto right = std::upper_bound(r_first, left, *left,
410                                    [](const Jet& l, const Jet& r) { return l.pT() > r.pT(); });
411      std::iter_swap(left, right);
412    }
413
414    std::reverse(left.base(), last);
415    return left != r_last;
416  }
417
418  double bjetOriginWeight(const DressedLeptons& lepton, const Jets& bjets,
419                          double mindRbb, double maxdRbb,
420                          double mindRl1b, double mindRl2b) const {
421
422    if (bjets.size() == 2) return 1.; //Return 1 if only two bjets are available
423
424    if (lepton.size() < 2) return 0.;
425    if (bjets.size() < 2)  return 0.;
426
427    double diff_mindRl1b_dRl1b = mindRl1b - deltaR(lepton[0], bjets[0]);
428    double diff_mindRl2b_dRl2b = mindRl2b - deltaR(lepton[1], bjets[1]);
429
430    double weight = 1.0;
431    if (bjets.size() < 4) {
432      //dR between top and gluon b-jet
433      const double dR_b1b3 = deltaR(bjets[0], bjets[2]);
434      const double dR_b2b3 = deltaR(bjets[1], bjets[2]);
435      const double maxdR_btop_bgluon = max(dR_b1b3, dR_b2b3);
436      const double diff_maxdRbb_maxdRbb3 = maxdRbb - maxdR_btop_bgluon;
437      weight *= exp(-1.*diff_mindRl1b_dRl1b*diff_mindRl1b_dRl1b);
438      weight *= exp(-1.*diff_mindRl2b_dRl2b*diff_mindRl2b_dRl2b);
439      weight *= exp(-1.*diff_maxdRbb_maxdRbb3*diff_maxdRbb_maxdRbb3);
440    }
441    else {
442      const double dR_b3b4 = deltaR(bjets[2], bjets[3]);
443      const double diff_mindRbb_dRb3b4 = mindRbb - dR_b3b4;
444      weight *= exp(-1.*diff_mindRbb_dRb3b4*diff_mindRbb_dRb3b4);
445      weight *= exp(-1.*diff_mindRl1b_dRl1b*diff_mindRl1b_dRl1b);
446      weight *= exp(-1.*diff_mindRl2b_dRl2b*diff_mindRl2b_dRl2b);
447    }
448
449    return weight;
450  }
451
452 private:
453
454  map<string,Histo1DPtr> _h;
455  map<string,BinnedHistoPtr<string>> _d;
456
457};
458
459  // The hook for the plugin system
460  RIVET_DECLARE_PLUGIN(ATLAS_2024_I2809112);
461
462}