CMS 3D CMS Logo

HiggsTemplateCrossSections.cc
Go to the documentation of this file.
1 #ifndef TRUTHRIVETTOOLS_HIGGSTEMPLATECROSSSECTIONS_CC
2 #define TRUTHRIVETTOOLS_HIGGSTEMPLATECROSSSECTIONS_CC
3 // -*- C++ -*-
4 #include "Rivet/Analysis.hh"
5 #include "Rivet/Particle.hh"
6 #include "Rivet/Projections/FastJets.hh"
7 
8 // Definition of the StatusCode and Category enums
9 //#include "HiggsTemplateCrossSections.h"
11 
12 #include <atomic>
13 
14 namespace Rivet {
15 
20  class HiggsTemplateCrossSections : public Analysis {
21  public:
22  // Constructor
23  HiggsTemplateCrossSections() : Analysis("HiggsTemplateCrossSections"), m_HiggsProdMode(HTXS::UNKNOWN) {}
24 
25  public:
30 
33  if (ptcl.genParticle()->end_vertex()) {
34  if (!hasChild(ptcl.genParticle(), ptcl.pdgId()))
35  return ptcl;
36  else
37  return getLastInstance(ptcl.children()[0]);
38  }
39  return ptcl;
40  }
41 
43  bool originateFrom(const Particle &p, const Particles &ptcls) {
44  const GenVertex *prodVtx = p.genParticle()->production_vertex();
45  if (prodVtx == nullptr)
46  return false;
47  // for each ancestor, check if it matches any of the input particles
48  for (const auto &ancestor : particles(prodVtx, HepMC::ancestors)) {
49  for (auto part : ptcls)
50  if (ancestor == part.genParticle())
51  return true;
52  }
53  // if we get here, no ancetor matched any input particle
54  return false;
55  }
56 
58  bool originateFrom(const Particle &p, const Particle &p2) {
59  Particles ptcls = {p2};
60  return originateFrom(p, ptcls);
61  }
62 
64  bool hasChild(const GenParticle *ptcl, int pdgID) {
65  for (auto child : Particle(*ptcl).children()) {
66  if (child.pdgId() == pdgID) {
67  return true;
68  }
69  }
70  return false;
71  }
72 
74  bool hasParent(const GenParticle *ptcl, int pdgID) {
75  for (auto parent : particles(ptcl->production_vertex(), HepMC::parents))
76  if (parent->pdg_id() == pdgID)
77  return true;
78  return false;
79  }
80 
82  bool quarkDecay(const Particle &p) {
83  for (auto child : p.children()) {
84  if (PID::isQuark(child.pdgId())) {
85  return true;
86  }
87  }
88  return false;
89  }
90 
92  bool ChLeptonDecay(const Particle &p) {
93  for (auto child : p.children()) {
94  if (PID::isChLepton(child.pdgId())) {
95  return true;
96  }
97  }
98  return false;
99  }
100 
103  HiggsClassification error(HiggsClassification &cat,
104  HTXS::ErrorCode err,
105  std::string msg = "",
106  int NmaxWarnings = 20) {
107  // Set the error, and keep statistics
108  cat.errorCode = err;
109  ++m_errorCount[err];
110 
111  // Print warning message to the screen/log
112  static std::atomic<int> Nwarnings{0};
113  if (!msg.empty() && ++Nwarnings < NmaxWarnings)
114  MSG_WARNING(msg);
115 
116  return cat;
117  }
119 
121  HiggsClassification classifyEvent(const Event &event, const HTXS::HiggsProdMode prodMode) {
123  m_HiggsProdMode = prodMode;
124 
125  // the classification object
126  HiggsClassification cat;
127  cat.prodMode = prodMode;
128  cat.errorCode = HTXS::UNDEFINED;
129  cat.stage0_cat = HTXS::Stage0::UNKNOWN;
130  cat.stage1_cat_pTjet25GeV = HTXS::Stage1::UNKNOWN;
131  cat.stage1_cat_pTjet30GeV = HTXS::Stage1::UNKNOWN;
132  cat.stage1_1_cat_pTjet25GeV = HTXS::Stage1_1::UNKNOWN;
133  cat.stage1_1_cat_pTjet30GeV = HTXS::Stage1_1::UNKNOWN;
134  cat.stage1_1_fine_cat_pTjet25GeV = HTXS::Stage1_1_Fine::UNKNOWN;
135  cat.stage1_1_fine_cat_pTjet30GeV = HTXS::Stage1_1_Fine::UNKNOWN;
136  cat.stage1_2_cat_pTjet25GeV = HTXS::Stage1_2::UNKNOWN;
137  cat.stage1_2_cat_pTjet30GeV = HTXS::Stage1_2::UNKNOWN;
138  cat.stage1_2_fine_cat_pTjet25GeV = HTXS::Stage1_2_Fine::UNKNOWN;
139  cat.stage1_2_fine_cat_pTjet30GeV = HTXS::Stage1_2_Fine::UNKNOWN;
140 
141  if (prodMode == HTXS::UNKNOWN)
142  return error(cat,
144  "Unkown Higgs production mechanism. Cannot classify event."
145  " Classification for all events will most likely fail.");
146 
147  /*****
148  * Step 1.
149  * Idenfify the Higgs boson and the hard scatter vertex
150  * There should be only one of each.
151  */
152 
153  GenVertex *HSvtx = event.genEvent()->signal_process_vertex();
154  int Nhiggs = 0;
155  for (const GenParticle *ptcl : Rivet::particles(event.genEvent())) {
156  // a) Reject all non-Higgs particles
157  if (!PID::isHiggs(ptcl->pdg_id()))
158  continue;
159  // b) select only the final Higgs boson copy, prior to decay
160  if (ptcl->end_vertex() && !hasChild(ptcl, PID::HIGGS)) {
161  cat.higgs = Particle(ptcl);
162  ++Nhiggs;
163  }
164  // c) if HepMC::signal_proces_vertex is missing
165  // set hard-scatter vertex based on first Higgs boson
166  if (HSvtx == nullptr && ptcl->production_vertex() && !hasParent(ptcl, PID::HIGGS))
167  HSvtx = ptcl->production_vertex();
168  }
169 
170  // Make sure things are in order so far
171  if (Nhiggs != 1)
172  return error(cat,
174  "Current event has " + std::to_string(Nhiggs) + " Higgs bosons. There must be only one.");
175  if (cat.higgs.children().size() < 2)
176  return error(cat, HTXS::HIGGS_DECAY_IDENTIFICATION, "Could not identify Higgs boson decay products.");
177 
178  if (HSvtx == nullptr)
179  return error(cat, HTXS::HS_VTX_IDENTIFICATION, "Cannot find hard-scatter vertex of current event.");
180 
181  /*****
182  * Step 2.
183  * Identify associated vector bosons
184  */
185 
186  // Find associated vector bosons
187  bool is_uncatdV = false;
188  Particles uncatV_decays;
189  FourMomentum uncatV_p4(0, 0, 0, 0);
190  FourVector uncatV_v4(0, 0, 0, 0);
191  int nWs = 0, nZs = 0, nTop = 0;
192  if (isVH(prodMode)) {
193  for (auto ptcl : particles(HSvtx, HepMC::children)) {
194  if (PID::isW(ptcl->pdg_id())) {
195  ++nWs;
196  cat.V = Particle(ptcl);
197  }
198  if (PID::isZ(ptcl->pdg_id())) {
199  ++nZs;
200  cat.V = Particle(ptcl);
201  }
202  }
203  if (nWs + nZs > 0)
204  cat.V = getLastInstance(cat.V);
205  else {
206  for (auto ptcl : particles(HSvtx, HepMC::children)) {
207  if (!PID::isHiggs(ptcl->pdg_id())) {
208  uncatV_decays += Particle(ptcl);
209  uncatV_p4 += Particle(ptcl).momentum();
210  // uncatV_v4 += Particle(ptcl).origin();
211  }
212  }
213  // is_uncatdV = true; cat.V = Particle(24,uncatV_p4,uncatV_v4);
214  is_uncatdV = true;
215  cat.V = Particle(24, uncatV_p4);
216  }
217  }
218 
219  if (!is_uncatdV) {
220  if (isVH(prodMode) && !cat.V.genParticle()->end_vertex())
221  return error(cat, HTXS::VH_DECAY_IDENTIFICATION, "Vector boson does not decay!");
222 
223  if (isVH(prodMode) && cat.V.children().size() < 2)
224  return error(cat, HTXS::VH_DECAY_IDENTIFICATION, "Vector boson does not decay!");
225 
226  if ((prodMode == HTXS::WH && (nZs > 0 || nWs != 1)) ||
227  ((prodMode == HTXS::QQ2ZH || prodMode == HTXS::GG2ZH) && (nZs != 1 || nWs > 0)))
228  return error(cat,
230  "Found " + std::to_string(nWs) + " W-bosons and " + std::to_string(nZs) +
231  " Z-bosons. Inconsitent with VH expectation.");
232  }
233 
234  // Find and store the W-bosons from ttH->WbWbH
235  Particles Ws;
236  if (prodMode == HTXS::TTH || prodMode == HTXS::TH) {
237  // loop over particles produced in hard-scatter vertex
238  for (auto ptcl : particles(HSvtx, HepMC::children)) {
239  if (!PID::isTop(ptcl->pdg_id()))
240  continue;
241  ++nTop;
242  Particle top = getLastInstance(Particle(ptcl));
243  if (top.genParticle()->end_vertex())
244  for (auto child : top.children())
245  if (PID::isW(child.pdgId()))
246  Ws += getLastInstance(child);
247  }
248  }
249 
250  // Make sure result make sense
251  if ((prodMode == HTXS::TTH && Ws.size() < 2) || (prodMode == HTXS::TH && Ws.empty()))
252  return error(cat, HTXS::TOP_W_IDENTIFICATION, "Failed to identify W-boson(s) from t-decay!");
253 
254  /*****
255  * Step 3.
256  * Build jets
257  * Make sure all stable particles are present
258  */
259 
260  // Create a list of the vector bosons that decay leptonically
261  // Either the vector boson produced in association with the Higgs boson,
262  // or the ones produced from decays of top quarks produced with the Higgs
263  Particles leptonicVs;
264  if (!is_uncatdV) {
265  if (isVH(prodMode) && !quarkDecay(cat.V))
266  leptonicVs += cat.V;
267  } else
268  leptonicVs = uncatV_decays;
269  for (auto W : Ws)
270  if (W.genParticle()->end_vertex() && !quarkDecay(W))
271  leptonicVs += W;
272 
273  // Obtain all stable, final-state particles
274  const ParticleVector FS = applyProjection<FinalState>(event, "FS").particles();
275  Particles hadrons;
276  FourMomentum sum(0, 0, 0, 0), vSum(0, 0, 0, 0), hSum(0, 0, 0, 0);
277  for (const Particle &p : FS) {
278  // Add up the four momenta of all stable particles as a cross check
279  sum += p.momentum();
280  // ignore particles from the Higgs boson
281  if (originateFrom(p, cat.higgs)) {
282  hSum += p.momentum();
283  continue;
284  }
285  // Cross-check the V decay products for VH
286  if (isVH(prodMode) && !is_uncatdV && originateFrom(p, Ws))
287  vSum += p.momentum();
288  // ignore final state particles from leptonic V decays
289  if (!leptonicVs.empty() && originateFrom(p, leptonicVs))
290  continue;
291  // All particles reaching here are considered hadrons and will be used to build jets
292  hadrons += p;
293  }
294 
295  cat.p4decay_higgs = hSum;
296  cat.p4decay_V = vSum;
297 
298  FinalState fps_temp;
299  FastJets jets(fps_temp, FastJets::ANTIKT, 0.4);
300  jets.calc(hadrons);
301 
302  cat.jets25 = jets.jetsByPt(Cuts::pT > 25.0);
303  cat.jets30 = jets.jetsByPt(Cuts::pT > 30.0);
304 
305  // check that four mometum sum of all stable particles satisfies momentum consevation
306  /*
307  if ( sum.pt()>0.1 )
308  return error(cat,HTXS::MOMENTUM_CONSERVATION,"Four vector sum does not amount to pT=0, m=E=sqrt(s), but pT="+
309  std::to_string(sum.pt())+" GeV and m = "+std::to_string(sum.mass())+" GeV");
310 */
311  // check if V-boson was not included in the event record but decay particles were
312  // EFT contact interaction: return UNKNOWN for category but set all event/particle kinematics
313  if (is_uncatdV)
314  return error(cat, HTXS::VH_IDENTIFICATION, "Failed to identify associated V-boson!");
315 
316  /*****
317  * Step 4.
318  * Classify and save output
319  */
320 
321  // Apply the categorization categorization
322  cat.isZ2vvDecay = false;
323  if ((prodMode == HTXS::GG2ZH || prodMode == HTXS::QQ2ZH) && !quarkDecay(cat.V) && !ChLeptonDecay(cat.V))
324  cat.isZ2vvDecay = true;
325  cat.stage0_cat = getStage0Category(prodMode, cat.higgs, cat.V);
326  cat.stage1_cat_pTjet25GeV = getStage1Category(prodMode, cat.higgs, cat.jets25, cat.V);
327  cat.stage1_cat_pTjet30GeV = getStage1Category(prodMode, cat.higgs, cat.jets30, cat.V);
328  cat.stage1_1_cat_pTjet25GeV = getStage1_1_Category(prodMode, cat.higgs, cat.jets25, cat.V);
329  cat.stage1_1_cat_pTjet30GeV = getStage1_1_Category(prodMode, cat.higgs, cat.jets30, cat.V);
330  cat.stage1_1_fine_cat_pTjet25GeV = getStage1_1_Fine_Category(prodMode, cat.higgs, cat.jets25, cat.V);
331  cat.stage1_1_fine_cat_pTjet30GeV = getStage1_1_Fine_Category(prodMode, cat.higgs, cat.jets30, cat.V);
332  cat.stage1_2_cat_pTjet25GeV = getStage1_2_Category(prodMode, cat.higgs, cat.jets25, cat.V);
333  cat.stage1_2_cat_pTjet30GeV = getStage1_2_Category(prodMode, cat.higgs, cat.jets30, cat.V);
334  cat.stage1_2_fine_cat_pTjet25GeV = getStage1_2_Fine_Category(prodMode, cat.higgs, cat.jets25, cat.V);
335  cat.stage1_2_fine_cat_pTjet30GeV = getStage1_2_Fine_Category(prodMode, cat.higgs, cat.jets30, cat.V);
336 
337  cat.errorCode = HTXS::SUCCESS;
339 
340  return cat;
341  }
342 
348 
350  int getBin(double x, std::vector<double> bins) {
351  for (size_t i = 1; i < bins.size(); ++i)
352  if (x < bins[i])
353  return i - 1;
354  return bins.size() - 1;
355  }
356 
360  int vbfTopology(const Jets &jets, const Particle &higgs) {
361  if (jets.size() < 2)
362  return 0;
363  const FourMomentum &j1 = jets[0].momentum(), &j2 = jets[1].momentum();
364  bool VBFtopo = (j1 + j2).mass() > 400.0 && std::abs(j1.rapidity() - j2.rapidity()) > 2.8;
365  return VBFtopo ? (j1 + j2 + higgs.momentum()).pt() < 25 ? 2 : 1 : 0;
366  }
367 
372  int vbfTopology_Stage1_X(const Jets &jets, const Particle &higgs) {
373  if (jets.size() < 2)
374  return 0;
375  const FourMomentum &j1 = jets[0].momentum(), &j2 = jets[1].momentum();
376  double mjj = (j1 + j2).mass();
377  if (mjj > 350 && mjj <= 700)
378  return (j1 + j2 + higgs.momentum()).pt() < 25 ? 1 : 2;
379  else if (mjj > 700)
380  return (j1 + j2 + higgs.momentum()).pt() < 25 ? 3 : 4;
381  else
382  return 0;
383  }
384 
391  int vbfTopology_Stage1_X_Fine(const Jets &jets, const Particle &higgs) {
392  if (jets.size() < 2)
393  return 0;
394  const FourMomentum &j1 = jets[0].momentum(), &j2 = jets[1].momentum();
395  double mjj = (j1 + j2).mass();
396  if (mjj > 350 && mjj <= 700)
397  return (j1 + j2 + higgs.momentum()).pt() < 25 ? 1 : 2;
398  else if (mjj > 700 && mjj <= 1000)
399  return (j1 + j2 + higgs.momentum()).pt() < 25 ? 3 : 4;
400  else if (mjj > 1000 && mjj <= 1500)
401  return (j1 + j2 + higgs.momentum()).pt() < 25 ? 5 : 6;
402  else if (mjj > 1500)
403  return (j1 + j2 + higgs.momentum()).pt() < 25 ? 7 : 8;
404  else
405  return 0;
406  }
407 
409  bool isVH(HTXS::HiggsProdMode p) { return p == HTXS::WH || p == HTXS::QQ2ZH || p == HTXS::GG2ZH; }
410 
413  const Particle &higgs,
414  const Particle &V) {
415  using namespace HTXS::Stage0;
416  int ctrlHiggs = std::abs(higgs.rapidity()) < 2.5;
417  // Special cases first, qq→Hqq
418  if ((prodMode == HTXS::WH || prodMode == HTXS::QQ2ZH) && quarkDecay(V)) {
419  return ctrlHiggs ? VH2HQQ : VH2HQQ_FWDH;
420  } else if (prodMode == HTXS::GG2ZH && quarkDecay(V)) {
421  return Category(HTXS::GGF * 10 + ctrlHiggs);
422  }
423  // General case after
424  return Category(prodMode * 10 + ctrlHiggs);
425  }
426 
429  const Particle &higgs,
430  const Jets &jets,
431  const Particle &V) {
432  using namespace HTXS::Stage1;
433  int Njets = jets.size(), ctrlHiggs = std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
434  double pTj1 = !jets.empty() ? jets[0].momentum().pt() : 0;
435  int vbfTopo = vbfTopology(jets, higgs);
436 
437  // 1. GGF Stage 1 categories
438  // Following YR4 write-up: XXXXX
439  if (prodMode == HTXS::GGF || (prodMode == HTXS::GG2ZH && quarkDecay(V))) {
440  if (fwdHiggs)
441  return GG2H_FWDH;
442  if (Njets == 0)
443  return GG2H_0J;
444  else if (Njets == 1)
445  return Category(GG2H_1J_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
446  else if (Njets >= 2) {
447  // events with pT_H>200 get priority over VBF cuts
448  if (higgs.pt() <= 200) {
449  if (vbfTopo == 2)
450  return GG2H_VBFTOPO_JET3VETO;
451  else if (vbfTopo == 1)
452  return GG2H_VBFTOPO_JET3;
453  }
454  // Njets >= 2jets without VBF topology
455  return Category(GG2H_GE2J_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
456  }
457  }
458  // 2. Electroweak qq->Hqq Stage 1 categories
459  else if (prodMode == HTXS::VBF || (isVH(prodMode) && quarkDecay(V))) {
460  if (std::abs(higgs.rapidity()) > 2.5)
461  return QQ2HQQ_FWDH;
462  if (pTj1 > 200)
463  return QQ2HQQ_PTJET1_GT200;
464  if (vbfTopo == 2)
466  if (vbfTopo == 1)
467  return QQ2HQQ_VBFTOPO_JET3;
468  double mjj = jets.size() > 1 ? (jets[0].mom() + jets[1].mom()).mass() : 0;
469  if (60 < mjj && mjj < 120)
470  return QQ2HQQ_VH2JET;
471  return QQ2HQQ_REST;
472  }
473  // 3. WH->Hlv categories
474  else if (prodMode == HTXS::WH) {
475  if (fwdHiggs)
476  return QQ2HLNU_FWDH;
477  else if (V.pt() < 150)
478  return QQ2HLNU_PTV_0_150;
479  else if (V.pt() > 250)
480  return QQ2HLNU_PTV_GT250;
481  // 150 < pTV/GeV < 250
482  return jets.empty() ? QQ2HLNU_PTV_150_250_0J : QQ2HLNU_PTV_150_250_GE1J;
483  }
484  // 4. qq->ZH->llH categories
485  else if (prodMode == HTXS::QQ2ZH) {
486  if (fwdHiggs)
487  return QQ2HLL_FWDH;
488  else if (V.pt() < 150)
489  return QQ2HLL_PTV_0_150;
490  else if (V.pt() > 250)
491  return QQ2HLL_PTV_GT250;
492  // 150 < pTV/GeV < 250
493  return jets.empty() ? QQ2HLL_PTV_150_250_0J : QQ2HLL_PTV_150_250_GE1J;
494  }
495  // 5. gg->ZH->llH categories
496  else if (prodMode == HTXS::GG2ZH) {
497  if (fwdHiggs)
498  return GG2HLL_FWDH;
499  if (V.pt() < 150)
500  return GG2HLL_PTV_0_150;
501  else if (jets.empty())
502  return GG2HLL_PTV_GT150_0J;
503  return GG2HLL_PTV_GT150_GE1J;
504  }
505  // 6.ttH,bbH,tH categories
506  else if (prodMode == HTXS::TTH)
507  return Category(TTH_FWDH + ctrlHiggs);
508  else if (prodMode == HTXS::BBH)
509  return Category(BBH_FWDH + ctrlHiggs);
510  else if (prodMode == HTXS::TH)
511  return Category(TH_FWDH + ctrlHiggs);
512  return UNKNOWN;
513  }
514 
517  const Particle &higgs,
518  const Jets &jets,
519  const Particle &V) {
520  using namespace HTXS::Stage1_1;
521  int Njets = jets.size(), ctrlHiggs = std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
522  int vbfTopo = vbfTopology_Stage1_X(jets, higgs);
523 
524  // 1. GGF Stage 1 categories
525  // Following YR4 write-up: XXXXX
526  if (prodMode == HTXS::GGF || (prodMode == HTXS::GG2ZH && quarkDecay(V))) {
527  if (fwdHiggs)
528  return GG2H_FWDH;
529  if (higgs.pt() > 200)
530  return GG2H_PTH_GT200;
531  if (Njets == 0)
532  return higgs.pt() < 10 ? GG2H_0J_PTH_0_10 : GG2H_0J_PTH_GT10;
533  if (Njets == 1)
534  return Category(GG2H_1J_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
535  if (Njets > 1) {
536  //VBF topology
537  if (vbfTopo)
538  return Category(GG2H_MJJ_350_700_PTHJJ_0_25 + vbfTopo - 1);
539  //Njets >= 2jets without VBF topology (mjj<350)
540  return Category(GG2H_GE2J_MJJ_0_350_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
541  }
542  }
543 
544  // 2. Electroweak qq->Hqq Stage 1.1 categories
545  else if (prodMode == HTXS::VBF || (isVH(prodMode) && quarkDecay(V))) {
546  if (std::abs(higgs.rapidity()) > 2.5)
547  return QQ2HQQ_FWDH;
548  int Njets = jets.size();
549  if (Njets == 0)
550  return QQ2HQQ_0J;
551  else if (Njets == 1)
552  return QQ2HQQ_1J;
553  else if (Njets >= 2) {
554  double mjj = (jets[0].mom() + jets[1].mom()).mass();
555  if (mjj < 60)
556  return QQ2HQQ_MJJ_0_60;
557  else if (60 < mjj && mjj < 120)
558  return QQ2HQQ_MJJ_60_120;
559  else if (120 < mjj && mjj < 350)
560  return QQ2HQQ_MJJ_120_350;
561  else if (mjj > 350) {
562  if (higgs.pt() > 200)
564  if (vbfTopo)
565  return Category(QQ2HQQ_MJJ_GT350_PTH_GT200 + vbfTopo);
566  }
567  }
568  }
569  // 3. WH->Hlv categories
570  else if (prodMode == HTXS::WH) {
571  if (fwdHiggs)
572  return QQ2HLNU_FWDH;
573  else if (V.pt() < 75)
574  return QQ2HLNU_PTV_0_75;
575  else if (V.pt() < 150)
576  return QQ2HLNU_PTV_75_150;
577  else if (V.pt() > 250)
578  return QQ2HLNU_PTV_GT250;
579  // 150 < pTV/GeV < 250
580  return jets.empty() ? QQ2HLNU_PTV_150_250_0J : QQ2HLNU_PTV_150_250_GE1J;
581  }
582  // 4. qq->ZH->llH categories
583  else if (prodMode == HTXS::QQ2ZH) {
584  if (fwdHiggs)
585  return QQ2HLL_FWDH;
586  else if (V.pt() < 75)
587  return QQ2HLL_PTV_0_75;
588  else if (V.pt() < 150)
589  return QQ2HLL_PTV_75_150;
590  else if (V.pt() > 250)
591  return QQ2HLL_PTV_GT250;
592  // 150 < pTV/GeV < 250
593  return jets.empty() ? QQ2HLL_PTV_150_250_0J : QQ2HLL_PTV_150_250_GE1J;
594  }
595  // 5. gg->ZH->llH categories
596  else if (prodMode == HTXS::GG2ZH) {
597  if (fwdHiggs)
598  return GG2HLL_FWDH;
599  else if (V.pt() < 75)
600  return GG2HLL_PTV_0_75;
601  else if (V.pt() < 150)
602  return GG2HLL_PTV_75_150;
603  else if (V.pt() > 250)
604  return GG2HLL_PTV_GT250;
605  return jets.empty() ? GG2HLL_PTV_150_250_0J : GG2HLL_PTV_150_250_GE1J;
606  }
607  // 6.ttH,bbH,tH categories
608  else if (prodMode == HTXS::TTH)
609  return Category(TTH_FWDH + ctrlHiggs);
610  else if (prodMode == HTXS::BBH)
611  return Category(BBH_FWDH + ctrlHiggs);
612  else if (prodMode == HTXS::TH)
613  return Category(TH_FWDH + ctrlHiggs);
614  return UNKNOWN;
615  }
616 
619  const Particle &higgs,
620  const Jets &jets,
621  const Particle &V) {
622  using namespace HTXS::Stage1_1_Fine;
623  int Njets = jets.size(), ctrlHiggs = std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
624  int vbfTopo = vbfTopology_Stage1_X_Fine(jets, higgs);
625 
626  // 1. GGF Stage 1.1 categories
627  // Following YR4 write-up: XXXXX
628  if (prodMode == HTXS::GGF || (prodMode == HTXS::GG2ZH && quarkDecay(V))) {
629  if (fwdHiggs)
630  return GG2H_FWDH;
631  if (higgs.pt() > 200)
632  return GG2H_PTH_GT200;
633  if (Njets == 0)
634  return higgs.pt() < 10 ? GG2H_0J_PTH_0_10 : GG2H_0J_PTH_GT10;
635  if (Njets == 1)
636  return Category(GG2H_1J_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
637  if (Njets > 1) {
638  //double mjj = (jets[0].mom()+jets[1].mom()).mass();
639  double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).pt();
640  //VBF topology
641  if (vbfTopo)
642  return Category(GG2H_MJJ_350_700_PTHJJ_0_25 + vbfTopo - 1);
643  //Njets >= 2jets without VBF topology (mjj<350)
644  if (pTHjj < 25)
645  return Category(GG2H_GE2J_MJJ_0_350_PTH_0_60_PTHJJ_0_25 + getBin(higgs.pt(), {0, 60, 120, 200}));
646  else
647  return Category(GG2H_GE2J_MJJ_0_350_PTH_0_60_PTHJJ_GT25 + getBin(higgs.pt(), {0, 60, 120, 200}));
648  }
649  }
650 
651  // 2. Electroweak qq->Hqq Stage 1.1 categories
652  else if (prodMode == HTXS::VBF || (isVH(prodMode) && quarkDecay(V))) {
653  if (std::abs(higgs.rapidity()) > 2.5)
654  return QQ2HQQ_FWDH;
655  int Njets = jets.size();
656  if (Njets == 0)
657  return QQ2HQQ_0J;
658  else if (Njets == 1)
659  return QQ2HQQ_1J;
660  else if (Njets >= 2) {
661  double mjj = (jets[0].mom() + jets[1].mom()).mass();
662  double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).pt();
663  if (mjj < 350) {
664  if (pTHjj < 25)
665  return Category(QQ2HQQ_MJJ_0_60_PTHJJ_0_25 + getBin(mjj, {0, 60, 120, 350}));
666  else
667  return Category(QQ2HQQ_MJJ_0_60_PTHJJ_GT25 + getBin(mjj, {0, 60, 120, 350}));
668  } else { //mjj>350 GeV
669  if (higgs.pt() < 200) {
670  return Category(QQ2HQQ_MJJ_350_700_PTHJJ_0_25 + vbfTopo - 1);
671  } else {
673  }
674  }
675  }
676  }
677  // 3. WH->Hlv categories
678  else if (prodMode == HTXS::WH) {
679  if (fwdHiggs)
680  return QQ2HLNU_FWDH;
681  int Njets = jets.size();
682  if (Njets == 0)
683  return Category(QQ2HLNU_PTV_0_75_0J + getBin(V.pt(), {0, 75, 150, 250, 400}));
684  if (Njets == 1)
685  return Category(QQ2HLNU_PTV_0_75_1J + getBin(V.pt(), {0, 75, 150, 250, 400}));
686  return Category(QQ2HLNU_PTV_0_75_GE2J + getBin(V.pt(), {0, 75, 150, 250, 400}));
687  }
688  // 4. qq->ZH->llH categories
689  else if (prodMode == HTXS::QQ2ZH) {
690  if (fwdHiggs)
691  return QQ2HLL_FWDH;
692  int Njets = jets.size();
693  if (Njets == 0)
694  return Category(QQ2HLL_PTV_0_75_0J + getBin(V.pt(), {0, 75, 150, 250, 400}));
695  if (Njets == 1)
696  return Category(QQ2HLL_PTV_0_75_1J + getBin(V.pt(), {0, 75, 150, 250, 400}));
697  return Category(QQ2HLL_PTV_0_75_GE2J + getBin(V.pt(), {0, 75, 150, 250, 400}));
698  }
699  // 5. gg->ZH->llH categories
700  else if (prodMode == HTXS::GG2ZH) {
701  if (fwdHiggs)
702  return GG2HLL_FWDH;
703  int Njets = jets.size();
704  if (Njets == 0)
705  return Category(GG2HLL_PTV_0_75_0J + getBin(V.pt(), {0, 75, 150, 250, 400}));
706  if (Njets == 1)
707  return Category(GG2HLL_PTV_0_75_1J + getBin(V.pt(), {0, 75, 150, 250, 400}));
708  return Category(GG2HLL_PTV_0_75_GE2J + getBin(V.pt(), {0, 75, 150, 250, 400}));
709  }
710  // 6.ttH,bbH,tH categories
711  else if (prodMode == HTXS::TTH)
712  return Category(TTH_FWDH + ctrlHiggs);
713  else if (prodMode == HTXS::BBH)
714  return Category(BBH_FWDH + ctrlHiggs);
715  else if (prodMode == HTXS::TH)
716  return Category(TH_FWDH + ctrlHiggs);
717  return UNKNOWN;
718  }
719 
722  const Particle &higgs,
723  const Jets &jets,
724  const Particle &V) {
725  using namespace HTXS::Stage1_2;
726  int Njets = jets.size(), ctrlHiggs = std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
727  int vbfTopo = vbfTopology_Stage1_X(jets, higgs);
728 
729  // 1. GGF Stage 1 categories
730  // Following YR4 write-up: XXXXX
731  if (prodMode == HTXS::GGF || (prodMode == HTXS::GG2ZH && quarkDecay(V))) {
732  if (fwdHiggs)
733  return GG2H_FWDH;
734  if (higgs.pt() > 200)
735  return Category(GG2H_PTH_200_300 + getBin(higgs.pt(), {200, 300, 450, 650}));
736  if (Njets == 0)
737  return higgs.pt() < 10 ? GG2H_0J_PTH_0_10 : GG2H_0J_PTH_GT10;
738  if (Njets == 1)
739  return Category(GG2H_1J_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
740  if (Njets > 1) {
741  //VBF topology
742  if (vbfTopo)
744  //Njets >= 2jets without VBF topology (mjj<350)
745  return Category(GG2H_GE2J_MJJ_0_350_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
746  }
747  }
748 
749  // 2. Electroweak qq->Hqq Stage 1.2 categories
750  else if (prodMode == HTXS::VBF || (isVH(prodMode) && quarkDecay(V))) {
751  if (std::abs(higgs.rapidity()) > 2.5)
752  return QQ2HQQ_FWDH;
753  int Njets = jets.size();
754  if (Njets == 0)
755  return QQ2HQQ_0J;
756  else if (Njets == 1)
757  return QQ2HQQ_1J;
758  else if (Njets >= 2) {
759  double mjj = (jets[0].mom() + jets[1].mom()).mass();
760  if (mjj < 60)
761  return QQ2HQQ_GE2J_MJJ_0_60;
762  else if (60 < mjj && mjj < 120)
763  return QQ2HQQ_GE2J_MJJ_60_120;
764  else if (120 < mjj && mjj < 350)
766  else if (mjj > 350) {
767  if (higgs.pt() > 200)
769  if (vbfTopo)
770  return Category(QQ2HQQ_GE2J_MJJ_GT350_PTH_GT200 + vbfTopo);
771  }
772  }
773  }
774  // 3. WH->Hlv categories
775  else if (prodMode == HTXS::WH) {
776  if (fwdHiggs)
777  return QQ2HLNU_FWDH;
778  else if (V.pt() < 75)
779  return QQ2HLNU_PTV_0_75;
780  else if (V.pt() < 150)
781  return QQ2HLNU_PTV_75_150;
782  else if (V.pt() > 250)
783  return QQ2HLNU_PTV_GT250;
784  // 150 < pTV/GeV < 250
785  return jets.empty() ? QQ2HLNU_PTV_150_250_0J : QQ2HLNU_PTV_150_250_GE1J;
786  }
787  // 4. qq->ZH->llH categories
788  else if (prodMode == HTXS::QQ2ZH) {
789  if (fwdHiggs)
790  return QQ2HLL_FWDH;
791  else if (V.pt() < 75)
792  return QQ2HLL_PTV_0_75;
793  else if (V.pt() < 150)
794  return QQ2HLL_PTV_75_150;
795  else if (V.pt() > 250)
796  return QQ2HLL_PTV_GT250;
797  // 150 < pTV/GeV < 250
798  return jets.empty() ? QQ2HLL_PTV_150_250_0J : QQ2HLL_PTV_150_250_GE1J;
799  }
800  // 5. gg->ZH->llH categories
801  else if (prodMode == HTXS::GG2ZH) {
802  if (fwdHiggs)
803  return GG2HLL_FWDH;
804  else if (V.pt() < 75)
805  return GG2HLL_PTV_0_75;
806  else if (V.pt() < 150)
807  return GG2HLL_PTV_75_150;
808  else if (V.pt() > 250)
809  return GG2HLL_PTV_GT250;
810  return jets.empty() ? GG2HLL_PTV_150_250_0J : GG2HLL_PTV_150_250_GE1J;
811  }
812  // 6.ttH,bbH,tH categories
813  else if (prodMode == HTXS::TTH) {
814  if (fwdHiggs)
815  return TTH_FWDH;
816  else
817  return Category(TTH_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200, 300}));
818  } else if (prodMode == HTXS::BBH)
819  return Category(BBH_FWDH + ctrlHiggs);
820  else if (prodMode == HTXS::TH)
821  return Category(TH_FWDH + ctrlHiggs);
822  return UNKNOWN;
823  }
824 
827  const Particle &higgs,
828  const Jets &jets,
829  const Particle &V) {
830  using namespace HTXS::Stage1_2_Fine;
831  int Njets = jets.size(), ctrlHiggs = std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
832  int vbfTopo = vbfTopology_Stage1_X_Fine(jets, higgs);
833 
834  // 1. GGF Stage 1.2 categories
835  // Following YR4 write-up: XXXXX
836  if (prodMode == HTXS::GGF || (prodMode == HTXS::GG2ZH && quarkDecay(V))) {
837  if (fwdHiggs)
838  return GG2H_FWDH;
839  if (higgs.pt() > 200) {
840  if (Njets > 0) {
841  double pTHj = (jets[0].momentum() + higgs.momentum()).pt();
842  if (pTHj / higgs.pt() > 0.15)
843  return Category(GG2H_PTH_200_300_PTHJoverPTH_GT15 + getBin(higgs.pt(), {200, 300, 450, 650}));
844  else
845  return Category(GG2H_PTH_200_300_PTHJoverPTH_0_15 + getBin(higgs.pt(), {200, 300, 450, 650}));
846  } else
847  return Category(GG2H_PTH_200_300_PTHJoverPTH_0_15 + getBin(higgs.pt(), {200, 300, 450, 650}));
848  }
849  if (Njets == 0)
850  return higgs.pt() < 10 ? GG2H_0J_PTH_0_10 : GG2H_0J_PTH_GT10;
851  if (Njets == 1)
852  return Category(GG2H_1J_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200}));
853  if (Njets > 1) {
854  //double mjj = (jets[0].mom()+jets[1].mom()).mass();
855  double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).pt();
856  //VBF topology
857  if (vbfTopo)
859  //Njets >= 2jets without VBF topology (mjj<350)
860  if (pTHjj < 25)
861  return Category(GG2H_GE2J_MJJ_0_350_PTH_0_60_PTHJJ_0_25 + getBin(higgs.pt(), {0, 60, 120, 200}));
862  else
863  return Category(GG2H_GE2J_MJJ_0_350_PTH_0_60_PTHJJ_GT25 + getBin(higgs.pt(), {0, 60, 120, 200}));
864  }
865  }
866 
867  // 2. Electroweak qq->Hqq Stage 1.2 categories
868  else if (prodMode == HTXS::VBF || (isVH(prodMode) && quarkDecay(V))) {
869  if (std::abs(higgs.rapidity()) > 2.5)
870  return QQ2HQQ_FWDH;
871  int Njets = jets.size();
872  if (Njets == 0)
873  return QQ2HQQ_0J;
874  else if (Njets == 1)
875  return QQ2HQQ_1J;
876  else if (Njets >= 2) {
877  double mjj = (jets[0].mom() + jets[1].mom()).mass();
878  double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).pt();
879  if (mjj < 350) {
880  if (pTHjj < 25)
881  return Category(QQ2HQQ_GE2J_MJJ_0_60_PTHJJ_0_25 + getBin(mjj, {0, 60, 120, 350}));
882  else
883  return Category(QQ2HQQ_GE2J_MJJ_0_60_PTHJJ_GT25 + getBin(mjj, {0, 60, 120, 350}));
884  } else { //mjj>350 GeV
885  if (higgs.pt() < 200) {
887  } else {
889  }
890  }
891  }
892  }
893  // 3. WH->Hlv categories
894  else if (prodMode == HTXS::WH) {
895  if (fwdHiggs)
896  return QQ2HLNU_FWDH;
897  int Njets = jets.size();
898  if (Njets == 0)
899  return Category(QQ2HLNU_PTV_0_75_0J + getBin(V.pt(), {0, 75, 150, 250, 400}));
900  if (Njets == 1)
901  return Category(QQ2HLNU_PTV_0_75_1J + getBin(V.pt(), {0, 75, 150, 250, 400}));
902  return Category(QQ2HLNU_PTV_0_75_GE2J + getBin(V.pt(), {0, 75, 150, 250, 400}));
903  }
904  // 4. qq->ZH->llH categories
905  else if (prodMode == HTXS::QQ2ZH) {
906  if (fwdHiggs)
907  return QQ2HLL_FWDH;
908  int Njets = jets.size();
909  if (Njets == 0)
910  return Category(QQ2HLL_PTV_0_75_0J + getBin(V.pt(), {0, 75, 150, 250, 400}));
911  if (Njets == 1)
912  return Category(QQ2HLL_PTV_0_75_1J + getBin(V.pt(), {0, 75, 150, 250, 400}));
913  return Category(QQ2HLL_PTV_0_75_GE2J + getBin(V.pt(), {0, 75, 150, 250, 400}));
914  }
915  // 5. gg->ZH->llH categories
916  else if (prodMode == HTXS::GG2ZH) {
917  if (fwdHiggs)
918  return GG2HLL_FWDH;
919  int Njets = jets.size();
920  if (Njets == 0)
921  return Category(GG2HLL_PTV_0_75_0J + getBin(V.pt(), {0, 75, 150, 250, 400}));
922  if (Njets == 1)
923  return Category(GG2HLL_PTV_0_75_1J + getBin(V.pt(), {0, 75, 150, 250, 400}));
924  return Category(GG2HLL_PTV_0_75_GE2J + getBin(V.pt(), {0, 75, 150, 250, 400}));
925  }
926  // 6.ttH,bbH,tH categories
927  else if (prodMode == HTXS::TTH) {
928  if (fwdHiggs)
929  return TTH_FWDH;
930  else
931  return Category(TTH_PTH_0_60 + getBin(higgs.pt(), {0, 60, 120, 200, 300, 450}));
932  } else if (prodMode == HTXS::BBH)
933  return Category(BBH_FWDH + ctrlHiggs);
934  else if (prodMode == HTXS::TH)
935  return Category(TH_FWDH + ctrlHiggs);
936  return UNKNOWN;
937  }
938 
940 
943 
945  void setHiggsProdMode(HTXS::HiggsProdMode prodMode) { m_HiggsProdMode = prodMode; }
946 
950  void init() override {
951  printf("==============================================================\n");
952  printf("======== HiggsTemplateCrossSections Initialization =========\n");
953  printf("==============================================================\n");
954  // check that the production mode has been set
955  // if running in standalone Rivet the production mode is set through an env variable
957  char *pm_env = getenv("HIGGSPRODMODE");
958  string pm(pm_env == nullptr ? "" : pm_env);
959  if (pm == "GGF")
961  else if (pm == "VBF")
963  else if (pm == "WH")
965  else if (pm == "ZH")
967  else if (pm == "QQ2ZH")
969  else if (pm == "GG2ZH")
971  else if (pm == "TTH")
973  else if (pm == "BBH")
975  else if (pm == "TH")
977  else {
978  MSG_WARNING("No HIGGSPRODMODE shell variable found. Needed when running Rivet stand-alone.");
979  }
980  }
981 
982  // Projections for final state particles
983  const FinalState FS;
984  addProjection(FS, "FS");
985 
986  // initialize the histograms with for each of the stages
988  m_sumw = 0.0;
989  printf("==============================================================\n");
990  printf("======== Higgs prod mode %d =========\n", m_HiggsProdMode);
991  printf("======== Sucessful Initialization =========\n");
992  printf("==============================================================\n");
993  }
994 
995  // Perform the per-event analysis
996  void analyze(const Event &event) override {
997  // get the classification
998  HiggsClassification cat = classifyEvent(event, m_HiggsProdMode);
999 
1000  // Fill histograms: categorization --> linerize the categories
1001  const double weight = event.weight();
1002  m_sumw += weight;
1003 
1004  int F = cat.stage0_cat % 10, P = cat.stage1_cat_pTjet30GeV / 100;
1005  hist_stage0->fill(cat.stage0_cat / 10 * 2 + F, weight);
1006 
1007  // Stage 1 enum offsets for each production mode: GGF=12, VBF=6, WH= 5, QQ2ZH=5, GG2ZH=4, TTH=2, BBH=2, TH=2
1008  vector<int> offset({0, 1, 13, 19, 24, 29, 33, 35, 37, 39});
1009  int off = offset[P];
1010  hist_stage1_pTjet25->fill(cat.stage1_cat_pTjet25GeV % 100 + off, weight);
1011  hist_stage1_pTjet30->fill(cat.stage1_cat_pTjet30GeV % 100 + off, weight);
1012 
1013  // Stage 1_2 enum offsets for each production mode: GGF=17, VBF=11, WH= 6, QQ2ZH=6, GG2ZH=6, TTH=6, BBH=2, TH=2
1014  static vector<int> offset1_2({0, 1, 18, 29, 35, 41, 47, 53, 55, 57});
1015  int off1_2 = offset1_2[P];
1016  // Stage 1_2 Fine enum offsets for each production mode: GGF=28, VBF=25, WH= 16, QQ2ZH=16, GG2ZH=16, TTH=7, BBH=2, TH=2
1017  static vector<int> offset1_2f({0, 1, 29, 54, 70, 86, 102, 109, 111, 113});
1018  int off1_2f = offset1_2f[P];
1019  hist_stage1_2_pTjet25->fill(cat.stage1_2_cat_pTjet25GeV % 100 + off1_2, weight);
1020  hist_stage1_2_pTjet30->fill(cat.stage1_2_cat_pTjet30GeV % 100 + off1_2, weight);
1021  hist_stage1_2_fine_pTjet25->fill(cat.stage1_2_fine_cat_pTjet25GeV % 100 + off1_2f, weight);
1022  hist_stage1_2_fine_pTjet30->fill(cat.stage1_2_fine_cat_pTjet30GeV % 100 + off1_2f, weight);
1023 
1024  // Fill histograms: variables used in the categorization
1025  hist_pT_Higgs->fill(cat.higgs.pT(), weight);
1026  hist_y_Higgs->fill(cat.higgs.rapidity(), weight);
1027  hist_pT_V->fill(cat.V.pT(), weight);
1028 
1029  hist_Njets25->fill(cat.jets25.size(), weight);
1030  hist_Njets30->fill(cat.jets30.size(), weight);
1031 
1032  hist_isZ2vv->fill(cat.isZ2vvDecay, weight);
1033 
1034  // Jet variables. Use jet collection with pT threshold at 30 GeV
1035  if (!cat.jets30.empty())
1036  hist_pT_jet1->fill(cat.jets30[0].pt(), weight);
1037  if (cat.jets30.size() >= 2) {
1038  const FourMomentum &j1 = cat.jets30[0].momentum(), &j2 = cat.jets30[1].momentum();
1039  hist_deltay_jj->fill(std::abs(j1.rapidity() - j2.rapidity()), weight);
1040  hist_dijet_mass->fill((j1 + j2).mass(), weight);
1041  hist_pT_Hjj->fill((j1 + j2 + cat.higgs.momentum()).pt(), weight);
1042  }
1043  }
1044 
1046  MSG_INFO(" ====================================================== ");
1047  MSG_INFO(" Higgs Template X-Sec Categorization Tool ");
1048  MSG_INFO(" Status Code Summary ");
1049  MSG_INFO(" ====================================================== ");
1050  bool allSuccess = (numEvents() == m_errorCount[HTXS::SUCCESS]);
1051  if (allSuccess)
1052  MSG_INFO(" >>>> All " << m_errorCount[HTXS::SUCCESS] << " events successfully categorized!");
1053  else {
1054  MSG_INFO(" >>>> " << m_errorCount[HTXS::SUCCESS] << " events successfully categorized");
1055  MSG_INFO(" >>>> --> the following errors occured:");
1056  MSG_INFO(" >>>> " << m_errorCount[HTXS::PRODMODE_DEFINED] << " had an undefined Higgs production mode.");
1057  MSG_INFO(" >>>> " << m_errorCount[HTXS::MOMENTUM_CONSERVATION] << " failed momentum conservation.");
1058  MSG_INFO(" >>>> " << m_errorCount[HTXS::HIGGS_IDENTIFICATION]
1059  << " failed to identify a valid Higgs boson.");
1060  MSG_INFO(" >>>> " << m_errorCount[HTXS::HS_VTX_IDENTIFICATION]
1061  << " failed to identify the hard scatter vertex.");
1062  MSG_INFO(" >>>> " << m_errorCount[HTXS::VH_IDENTIFICATION] << " VH: to identify a valid V-boson.");
1063  MSG_INFO(" >>>> " << m_errorCount[HTXS::TOP_W_IDENTIFICATION]
1064  << " failed to identify valid Ws from top decay.");
1065  }
1066  MSG_INFO(" ====================================================== ");
1067  MSG_INFO(" ====================================================== ");
1068  }
1069 
1070  void finalize() override {
1072  double sf = m_sumw > 0 ? 1.0 / m_sumw : 1.0;
1073  for (auto hist : {hist_stage0,
1080  hist_Njets25,
1081  hist_Njets30,
1082  hist_pT_Higgs,
1083  hist_y_Higgs,
1084  hist_pT_V,
1085  hist_pT_jet1,
1088  hist_pT_Hjj})
1089  scale(hist, sf);
1090  }
1091 
1092  /*
1093  * initialize histograms
1094  */
1095 
1097  hist_stage0 = bookHisto1D("HTXS_stage0", 20, 0, 20);
1098  hist_stage1_pTjet25 = bookHisto1D("HTXS_stage1_pTjet25", 40, 0, 40);
1099  hist_stage1_pTjet30 = bookHisto1D("HTXS_stage1_pTjet30", 40, 0, 40);
1100  hist_stage1_2_pTjet25 = bookHisto1D("HTXS_stage1_2_pTjet25", 57, 0, 57);
1101  hist_stage1_2_pTjet30 = bookHisto1D("HTXS_stage1_2_pTjet30", 57, 0, 57);
1102  hist_stage1_2_fine_pTjet25 = bookHisto1D("HTXS_stage1_2_fine_pTjet25", 113, 0, 113);
1103  hist_stage1_2_fine_pTjet30 = bookHisto1D("HTXS_stage1_2_fine_pTjet30", 113, 0, 113);
1104  hist_pT_Higgs = bookHisto1D("pT_Higgs", 80, 0, 400);
1105  hist_y_Higgs = bookHisto1D("y_Higgs", 80, -4, 4);
1106  hist_pT_V = bookHisto1D("pT_V", 80, 0, 400);
1107  hist_pT_jet1 = bookHisto1D("pT_jet1", 80, 0, 400);
1108  hist_deltay_jj = bookHisto1D("deltay_jj", 50, 0, 10);
1109  hist_dijet_mass = bookHisto1D("m_jj", 50, 0, 2000);
1110  hist_pT_Hjj = bookHisto1D("pT_Hjj", 50, 0, 250);
1111  hist_Njets25 = bookHisto1D("Njets25", 10, 0, 10);
1112  hist_Njets30 = bookHisto1D("Njets30", 10, 0, 10);
1113  hist_isZ2vv = bookHisto1D("isZ2vv", 2, 0, 2);
1114  }
1116 
1117  /*
1118  * initialize private members used in the classification procedure
1119  */
1120 
1121  private:
1122  double m_sumw;
1124  std::map<HTXS::ErrorCode, size_t> m_errorCount;
1125  Histo1DPtr hist_stage0;
1133  Histo1DPtr hist_isZ2vv;
1134  };
1135 
1136  // the PLUGIN only needs to be decleared when running standalone Rivet
1137  // and causes compilation / linking issues if included in Athena / RootCore
1138  //check for Rivet environment variable RIVET_ANALYSIS_PATH
1139 #ifdef RIVET_ANALYSIS_PATH
1140  // The hook for the plugin system
1142 #endif
1143 
1144 } // namespace Rivet
1145 
1146 #endif
int vbfTopology(const Jets &jets, const Particle &higgs)
VBF topolog selection 0 = fail loose selction: m_jj > 400 GeV and Dy_jj > 2.8 1 pass loose...
bool isVH(HTXS::HiggsProdMode p)
Whether the Higgs is produced in association with a vector boson (VH)
failed to identify associated vector boson
int getBin(double x, std::vector< double > bins)
Return bin index of x given the provided bin edges. 0=first bin, -1=underflow bin.
ErrorCode
Error code: whether the classification was successful or failed.
TPRegexp parents
Definition: eve_filter.cc:21
HTXS::Stage1_2_Fine::Category getStage1_2_Fine_Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Jets &jets, const Particle &V)
Stage-1.2 Fine categorization.
bool originateFrom(const Particle &p, const Particle &p2)
Whether particle p originates from p2.
successful classification
bool hasParent(const GenParticle *ptcl, int pdgID)
Checks whether the input particle has a parent with a given PDGID.
int vbfTopology_Stage1_X_Fine(const Jets &jets, const Particle &higgs)
VBF topology selection for Stage1.1 and Stage 1.2 Fine 0 = fail loose selection: m_jj > 350 GeV 1 pas...
0: Unidentified isolated particle
Definition: ParticleCode.h:19
HTXS::Stage1::Category getStage1Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Jets &jets, const Particle &V)
Stage-1 categorization.
failed to identify Higgs boson decay products
Definition: weight.py:1
HiggsProdMode
Higgs production modes, corresponding to input sample.
HTXS::Stage1_1::Category getStage1_1_Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Jets &jets, const Particle &V)
Stage-1.1 categorization.
bool ChLeptonDecay(const Particle &p)
Return true if particle decays to charged leptons.
std::map< HTXS::ErrorCode, size_t > m_errorCount
void init() override
default Rivet Analysis::init method Booking of histograms, initializing Rivet projection Extracts Hig...
void analyze(const Event &event) override
def cat(path)
Definition: eostools.py:401
HTXS::Stage1_1_Fine::Category getStage1_1_Fine_Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Jets &jets, const Particle &V)
Stage-1_1 categorization.
bool hasChild(const GenParticle *ptcl, int pdgID)
Checks whether the input particle has a child with a given PDGID.
bool quarkDecay(const Particle &p)
Return true is particle decays to quarks.
failed momentum conservation
vector< PseudoJet > jets
DECLARE_RIVET_PLUGIN(CMS_2013_I1224539_DIJET)
Particle getLastInstance(Particle ptcl)
follow a "propagating" particle and return its last instance
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Namespace for Stage0 categorization.
Higgs Template Cross Section namespace.
failed to identify associated vector boson decay products
void setHiggsProdMode(HTXS::HiggsProdMode prodMode)
Sets the Higgs production mode.
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
double p2[4]
Definition: TauolaWrapper.h:90
HiggsClassification classifyEvent(const Event &event, const HTXS::HiggsProdMode prodMode)
Main classificaion method.
failed to identify Higgs boson
part
Definition: HCALResponse.h:20
Rivet routine for classifying MC events according to the Higgs template cross section categories...
failed to identify hard scatter vertex
std::pair< OmniClusterRef, TrackingParticleRef > P
tuple msg
Definition: mps_check.py:285
HTXS::Stage0::Category getStage0Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Particle &V)
Stage-0 HTXS categorization.
HiggsClassification error(HiggsClassification &cat, HTXS::ErrorCode err, std::string msg="", int NmaxWarnings=20)
Returns the classification object with the error code set. Prints an warning message, and keeps track of number of errors.
bool originateFrom(const Particle &p, const Particles &ptcls)
Whether particle p originate from any of the ptcls.
HTXS::Stage1_2::Category getStage1_2_Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Jets &jets, const Particle &V)
Stage-1.2 categorization.
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:281
production mode not defined
int vbfTopology_Stage1_X(const Jets &jets, const Particle &higgs)
VBF topology selection Stage1.1 and Stage1.2 0 = fail loose selection: m_jj > 350 GeV 1 pass loose...
Definition: event.py:1
failed to identify top decay