1 #ifndef TRUTHRIVETTOOLS_HIGGSTEMPLATECROSSSECTIONS_CC
2 #define TRUTHRIVETTOOLS_HIGGSTEMPLATECROSSSECTIONS_CC
5 #include "Rivet/Analysis.hh"
6 #include "Rivet/Particle.hh"
7 #include "Rivet/Projections/FastJets.hh"
34 if (ptcl.genParticle()->end_vertex()) {
35 if (!
hasChild(ptcl.genParticle(), ptcl.pid()))
45 const ConstGenVertexPtr prodVtx = p.genParticle()->production_vertex();
46 if (prodVtx ==
nullptr)
49 for (
const auto &ancestor : HepMCUtils::particles(prodVtx, HepMC::ancestors)) {
50 for (
const auto &
part : ptcls)
51 if (ancestor ==
part.genParticle())
60 Particles ptcls = {p2};
65 bool hasChild(
const ConstGenParticlePtr &ptcl,
int pdgID) {
67 if (
child.pid() == pdgID) {
75 bool hasParent(
const ConstGenParticlePtr &ptcl,
int pdgID) {
77 if (
parent->pdg_id() == pdgID)
84 for (
const auto &
child : p.children()) {
85 if (PID::isQuark(
child.pid())) {
94 for (
const auto &
child : p.children()) {
95 if (PID::isChLepton(
child.pid())) {
104 HiggsClassification
error(HiggsClassification &
cat,
107 int NmaxWarnings = 20) {
113 static std::atomic<int> Nwarnings{0};
114 if (!
msg.empty() && ++Nwarnings < NmaxWarnings)
127 HiggsClassification
cat;
128 cat.prodMode = prodMode;
145 "Unkown Higgs production mechanism. Cannot classify event."
146 " Classification for all events will most likely fail.");
154 ConstGenVertexPtr HSvtx =
event.genEvent()->signal_process_vertex();
156 for (
const ConstGenParticlePtr ptcl : HepMCUtils::particles(event.genEvent())) {
158 if (!PID::isHiggs(ptcl->pdg_id()))
161 if (ptcl->end_vertex() && !
hasChild(ptcl, PID::HIGGS)) {
167 if (HSvtx ==
nullptr && ptcl->production_vertex() && !
hasParent(ptcl, PID::HIGGS))
168 HSvtx = ptcl->production_vertex();
175 "Current event has " + std::to_string(Nhiggs) +
" Higgs bosons. There must be only one.");
176 if (cat.higgs.children().size() < 2)
179 if (HSvtx ==
nullptr)
188 bool is_uncatdV =
false;
189 Particles uncatV_decays;
190 FourMomentum uncatV_p4(0, 0, 0, 0);
191 FourVector uncatV_v4(0, 0, 0, 0);
192 int nWs = 0, nZs = 0, nTop = 0;
193 if (
isVH(prodMode)) {
194 for (
auto ptcl : HepMCUtils::particles(HSvtx, HepMC::children)) {
195 if (PID::isW(ptcl->pdg_id())) {
199 if (PID::isZ(ptcl->pdg_id())) {
207 for (
auto ptcl : HepMCUtils::particles(HSvtx, HepMC::children)) {
208 if (!PID::isHiggs(ptcl->pdg_id())) {
210 uncatV_p4 +=
Particle(ptcl).momentum();
221 if (
isVH(prodMode) && !cat.V.genParticle()->end_vertex())
224 if (
isVH(prodMode) && cat.V.children().size() < 2)
227 if ((prodMode ==
HTXS::WH && (nZs > 0 || nWs != 1)) ||
231 "Found " + std::to_string(nWs) +
" W-bosons and " + std::to_string(nZs) +
232 " Z-bosons. Inconsitent with VH expectation.");
239 for (
auto ptcl : HepMCUtils::particles(HSvtx, HepMC::children)) {
240 if (!PID::isTop(ptcl->pdg_id()))
244 if (top.genParticle()->end_vertex())
245 for (
const auto &
child : top.children())
246 if (PID::isW(
child.pid()))
252 if ((prodMode ==
HTXS::TTH && Ws.size() < 2) || (prodMode ==
HTXS::TH && Ws.empty()))
264 Particles leptonicVs;
269 leptonicVs = uncatV_decays;
270 for (
const auto &W : Ws)
271 if (W.genParticle()->end_vertex() && !
quarkDecay(W))
275 const Particles FS = apply<FinalState>(
event,
"FS").particles();
277 FourMomentum sum(0, 0, 0, 0), vSum(0, 0, 0, 0), hSum(0, 0, 0, 0);
283 hSum +=
p.momentum();
288 vSum +=
p.momentum();
296 cat.p4decay_higgs = hSum;
297 cat.p4decay_V = vSum;
300 FastJets
jets(fps_temp, FastJets::ANTIKT, 0.4);
303 cat.jets25 = jets.jetsByPt(
Cuts::pT > 25.0);
304 cat.jets30 = jets.jetsByPt(
Cuts::pT > 30.0);
323 cat.isZ2vvDecay =
false;
325 cat.isZ2vvDecay =
true;
327 cat.stage1_cat_pTjet25GeV =
getStage1Category(prodMode, cat.higgs, cat.jets25, cat.V);
328 cat.stage1_cat_pTjet30GeV =
getStage1Category(prodMode, cat.higgs, cat.jets30, cat.V);
352 int getBin(
double x, std::vector<double> bins) {
353 for (
size_t i = 1;
i < bins.size(); ++
i)
356 return bins.size() - 1;
365 const FourMomentum &j1 = jets[0].momentum(), &j2 = jets[1].momentum();
366 bool VBFtopo = (j1 + j2).
mass() > 400.0 &&
std::abs(j1.rapidity() - j2.rapidity()) > 2.8;
367 return VBFtopo ? (j1 + j2 + higgs.momentum()).
pt() < 25 ? 2 : 1 : 0;
377 const FourMomentum &j1 = jets[0].momentum(), &j2 = jets[1].momentum();
378 double mjj = (j1 + j2).
mass();
379 if (mjj > 350 && mjj <= 700)
380 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 1 : 2;
382 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 3 : 4;
396 const FourMomentum &j1 = jets[0].momentum(), &j2 = jets[1].momentum();
397 double mjj = (j1 + j2).
mass();
398 if (mjj > 350 && mjj <= 700)
399 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 1 : 2;
400 else if (mjj > 700 && mjj <= 1000)
401 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 3 : 4;
402 else if (mjj > 1000 && mjj <= 1500)
403 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 5 : 6;
405 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 7 : 8;
417 using namespace HTXS::Stage0;
418 int ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5;
426 return Category(prodMode * 10 + ctrlHiggs);
431 const Particle &higgs,
434 using namespace HTXS::Stage1;
435 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
436 double pTj1 = !jets.empty() ? jets[0].momentum().pt() : 0;
448 else if (Njets >= 2) {
450 if (higgs.pt() <= 200) {
453 else if (vbfTopo == 1)
462 if (
std::abs(higgs.rapidity()) > 2.5)
470 double mjj = jets.size() > 1 ? (jets[0].mom() + jets[1].mom()).
mass() : 0;
471 if (60 < mjj && mjj < 120)
479 else if (V.pt() < 150)
481 else if (V.pt() > 250)
490 else if (V.pt() < 150)
492 else if (V.pt() > 250)
503 else if (jets.empty())
519 const Particle &higgs,
522 using namespace HTXS::Stage1_1;
523 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
531 if (higgs.pt() > 200)
548 if (
std::abs(higgs.rapidity()) > 2.5)
550 int Njets = jets.size();
555 else if (Njets >= 2) {
556 double mjj = (jets[0].mom() + jets[1].mom()).
mass();
559 else if (60 < mjj && mjj < 120)
561 else if (120 < mjj && mjj < 350)
563 else if (mjj > 350) {
564 if (higgs.pt() > 200)
575 else if (V.pt() < 75)
577 else if (V.pt() < 150)
579 else if (V.pt() > 250)
588 else if (V.pt() < 75)
590 else if (V.pt() < 150)
592 else if (V.pt() > 250)
601 else if (V.pt() < 75)
603 else if (V.pt() < 150)
605 else if (V.pt() > 250)
621 const Particle &higgs,
624 using namespace HTXS::Stage1_1_Fine;
625 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
633 if (higgs.pt() > 200)
641 double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).
pt();
655 if (
std::abs(higgs.rapidity()) > 2.5)
657 int Njets = jets.size();
662 else if (Njets >= 2) {
663 double mjj = (jets[0].mom() + jets[1].mom()).
mass();
664 double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).
pt();
671 if (higgs.pt() < 200) {
683 int Njets = jets.size();
694 int Njets = jets.size();
705 int Njets = jets.size();
724 const Particle &higgs,
727 using namespace HTXS::Stage1_2;
728 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
736 if (higgs.pt() > 200)
753 if (
std::abs(higgs.rapidity()) > 2.5)
755 int Njets = jets.size();
760 else if (Njets >= 2) {
761 double mjj = (jets[0].mom() + jets[1].mom()).
mass();
764 else if (60 < mjj && mjj < 120)
766 else if (120 < mjj && mjj < 350)
768 else if (mjj > 350) {
769 if (higgs.pt() > 200)
780 else if (V.pt() < 75)
782 else if (V.pt() < 150)
784 else if (V.pt() > 250)
793 else if (V.pt() < 75)
795 else if (V.pt() < 150)
797 else if (V.pt() > 250)
806 else if (V.pt() < 75)
808 else if (V.pt() < 150)
810 else if (V.pt() > 250)
829 const Particle &higgs,
832 using namespace HTXS::Stage1_2_Fine;
833 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
841 if (higgs.pt() > 200) {
843 double pTHj = (jets[0].momentum() + higgs.momentum()).
pt();
844 if (pTHj / higgs.pt() > 0.15)
857 double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).
pt();
871 if (
std::abs(higgs.rapidity()) > 2.5)
873 int Njets = jets.size();
878 else if (Njets >= 2) {
879 double mjj = (jets[0].mom() + jets[1].mom()).
mass();
880 double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).
pt();
887 if (higgs.pt() < 200) {
899 int Njets = jets.size();
910 int Njets = jets.size();
921 int Njets = jets.size();
953 printf(
"==============================================================\n");
954 printf(
"======== HiggsTemplateCrossSections Initialization =========\n");
955 printf(
"==============================================================\n");
959 char *pm_env = std::getenv(
"HIGGSPRODMODE");
960 string pm(pm_env ==
nullptr ?
"" : pm_env);
963 else if (pm ==
"VBF")
969 else if (pm ==
"QQ2ZH")
971 else if (pm ==
"GG2ZH")
973 else if (pm ==
"TTH")
975 else if (pm ==
"BBH")
980 MSG_WARNING(
"No HIGGSPRODMODE shell variable found. Needed when running Rivet stand-alone.");
992 printf(
"==============================================================\n");
994 printf(
"======== Sucessful Initialization =========\n");
995 printf(
"==============================================================\n");
1004 const double weight = 1.0;
1007 int F = cat.stage0_cat % 10,
P = cat.stage1_cat_pTjet30GeV / 100;
1008 hist_stage0->fill(cat.stage0_cat / 10 * 2 + F, weight);
1011 vector<int>
offset({0, 1, 13, 19, 24, 29, 33, 35, 37, 39});
1017 static vector<int> offset1_2({0, 1, 18, 29, 35, 41, 47, 53, 55, 57});
1018 int off1_2 = offset1_2[
P];
1020 static vector<int> offset1_2f({0, 1, 29, 54, 70, 86, 102, 109, 111, 113});
1021 int off1_2f = offset1_2f[
P];
1038 if (!cat.jets30.empty())
1040 if (cat.jets30.size() >= 2) {
1041 const FourMomentum &j1 = cat.jets30[0].momentum(), &j2 = cat.jets30[1].momentum();
1049 MSG_INFO(
" ====================================================== ");
1050 MSG_INFO(
" Higgs Template X-Sec Categorization Tool ");
1051 MSG_INFO(
" Status Code Summary ");
1052 MSG_INFO(
" ====================================================== ");
1058 MSG_INFO(
" >>>> --> the following errors occured:");
1062 <<
" failed to identify a valid Higgs boson.");
1064 <<
" failed to identify the hard scatter vertex.");
1067 <<
" failed to identify valid Ws from top decay.");
1069 MSG_INFO(
" ====================================================== ");
1070 MSG_INFO(
" ====================================================== ");
1143 #ifdef RIVET_ANALYSIS_PATH
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.
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
void printClassificationSummary()
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...
HiggsTemplateCrossSections()
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
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.
Histo1DPtr hist_dijet_mass
std::map< HTXS::ErrorCode, size_t > m_errorCount
void init() override
default Rivet Analysis::init method Booking of histograms, initializing Rivet projection Extracts Hig...
HTXS::HiggsProdMode m_HiggsProdMode
void analyze(const Event &event) override
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.
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t V
bool quarkDecay(const Particle &p)
Return true is particle decays to quarks.
failed momentum conservation
DECLARE_RIVET_PLUGIN(CMS_2013_I1224539_DIJET)
printf("params %d %f %f %f\n", minT, eps, errmax, chi2max)
Particle getLastInstance(Particle ptcl)
follow a "propagating" particle and return its last instance
Abs< T >::type abs(const T &t)
Histo1DPtr hist_stage1_2_pTjet25
bool hasChild(const ConstGenParticlePtr &ptcl, int pdgID)
Checks whether the input particle has a child with a given PDGID.
failed to identify associated vector boson decay products
void setHiggsProdMode(HTXS::HiggsProdMode prodMode)
Sets the Higgs production mode.
HiggsClassification classifyEvent(const Event &event, const HTXS::HiggsProdMode prodMode)
Main classificaion method.
failed to identify Higgs boson
Histo1DPtr hist_stage1_pTjet30
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
HTXS::Stage0::Category getStage0Category(const HTXS::HiggsProdMode prodMode, const Particle &higgs, const Particle &V)
Stage-0 HTXS categorization.
bool hasParent(const ConstGenParticlePtr &ptcl, int pdgID)
Checks whether the input particle has a parent with a given PDGID.
Histo1DPtr hist_stage1_2_pTjet30
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)
Histo1DPtr hist_stage1_2_fine_pTjet30
Histo1DPtr hist_stage1_pTjet25
production mode not defined
Histo1DPtr hist_deltay_jj
Histo1DPtr hist_stage1_2_fine_pTjet25
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...
failed to identify top decay