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)
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()) {
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 =
nullptr;
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;
193 if (
isVH(prodMode)) {
195 if (PID::isW(ptcl->pdg_id())) {
199 if (PID::isZ(ptcl->pdg_id())) {
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)) ||
232 " Z-bosons. Inconsitent with VH expectation.");
240 if (!PID::isTop(ptcl->pdg_id()))
243 if (top.genParticle()->end_vertex())
244 for (
const auto &
child : top.children())
245 if (PID::isW(
child.pid()))
251 if ((prodMode ==
HTXS::TTH && Ws.size() < 2) || (prodMode ==
HTXS::TH && Ws.empty()))
263 Particles leptonicVs;
268 leptonicVs = uncatV_decays;
269 for (
const auto &W : Ws)
270 if (W.genParticle()->end_vertex() && !
quarkDecay(W))
276 FourMomentum sum(0, 0, 0, 0), vSum(0, 0, 0, 0), hSum(0, 0, 0, 0);
282 hSum +=
p.momentum();
287 vSum +=
p.momentum();
295 cat.p4decay_higgs = hSum;
296 cat.p4decay_V = vSum;
299 FastJets
jets(fps_temp, JetAlg::ANTIKT, 0.4);
307 if (
isVH(prodMode)) {
313 if (
cat.jets30.size() >= 2) {
314 cat.Mjj = (
cat.jets30[0].mom() +
cat.jets30[1].mom()).
mass();
315 cat.ptHjj = (
cat.jets30[0].mom() +
cat.jets30[1].mom() +
cat.higgs.momentum()).
pt();
316 cat.dPhijj =
cat.jets30[0].mom().phi() -
cat.jets30[1].mom().phi();
345 cat.isZ2vvDecay =
false;
347 cat.isZ2vvDecay =
true;
375 for (
size_t i = 1;
i <
bins.size(); ++
i)
378 return bins.size() - 1;
387 const FourMomentum &j1 =
jets[0].momentum(), &j2 =
jets[1].momentum();
388 bool VBFtopo = (j1 + j2).
mass() > 400.0 &&
std::abs(j1.rapidity() - j2.rapidity()) > 2.8;
389 return VBFtopo ? (j1 + j2 + higgs.momentum()).
pt() < 25 ? 2 : 1 : 0;
399 const FourMomentum &j1 =
jets[0].momentum(), &j2 =
jets[1].momentum();
400 double mjj = (j1 + j2).
mass();
401 if (mjj > 350 && mjj <= 700)
402 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 1 : 2;
404 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 3 : 4;
418 const FourMomentum &j1 =
jets[0].momentum(), &j2 =
jets[1].momentum();
419 double mjj = (j1 + j2).
mass();
420 if (mjj > 350 && mjj <= 700)
421 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 1 : 2;
422 else if (mjj > 700 && mjj <= 1000)
423 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 3 : 4;
424 else if (mjj > 1000 && mjj <= 1500)
425 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 5 : 6;
427 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 7 : 8;
440 int ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5;
448 return Category(prodMode * 10 + ctrlHiggs);
457 int Njets =
jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
458 double pTj1 = !
jets.empty() ?
jets[0].momentum().pt() : 0;
470 else if (
Njets >= 2) {
472 if (higgs.pt() <= 200) {
475 else if (vbfTopo == 1)
484 if (
std::abs(higgs.rapidity()) > 2.5)
493 if (60 < mjj && mjj < 120)
501 else if (
V.pt() < 150)
503 else if (
V.pt() > 250)
512 else if (
V.pt() < 150)
514 else if (
V.pt() > 250)
525 else if (
jets.empty())
545 int Njets =
jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
553 if (higgs.pt() > 200)
570 if (
std::abs(higgs.rapidity()) > 2.5)
577 else if (
Njets >= 2) {
581 else if (60 < mjj && mjj < 120)
583 else if (120 < mjj && mjj < 350)
585 else if (mjj > 350) {
586 if (higgs.pt() > 200)
597 else if (
V.pt() < 75)
599 else if (
V.pt() < 150)
601 else if (
V.pt() > 250)
610 else if (
V.pt() < 75)
612 else if (
V.pt() < 150)
614 else if (
V.pt() > 250)
623 else if (
V.pt() < 75)
625 else if (
V.pt() < 150)
627 else if (
V.pt() > 250)
647 int Njets =
jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
655 if (higgs.pt() > 200)
663 double pTHjj = (
jets[0].momentum() +
jets[1].momentum() + higgs.momentum()).
pt();
677 if (
std::abs(higgs.rapidity()) > 2.5)
684 else if (
Njets >= 2) {
686 double pTHjj = (
jets[0].momentum() +
jets[1].momentum() + higgs.momentum()).
pt();
693 if (higgs.pt() < 200) {
750 int Njets =
jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
758 if (higgs.pt() > 200)
775 if (
std::abs(higgs.rapidity()) > 2.5)
782 else if (
Njets >= 2) {
786 else if (60 < mjj && mjj < 120)
788 else if (120 < mjj && mjj < 350)
790 else if (mjj > 350) {
791 if (higgs.pt() > 200)
802 else if (
V.pt() < 75)
804 else if (
V.pt() < 150)
806 else if (
V.pt() > 250)
815 else if (
V.pt() < 75)
817 else if (
V.pt() < 150)
819 else if (
V.pt() > 250)
828 else if (
V.pt() < 75)
830 else if (
V.pt() < 150)
832 else if (
V.pt() > 250)
855 int Njets =
jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
863 if (higgs.pt() > 200) {
865 double pTHj = (
jets[0].momentum() + higgs.momentum()).
pt();
866 if (pTHj / higgs.pt() > 0.15)
879 double pTHjj = (
jets[0].momentum() +
jets[1].momentum() + higgs.momentum()).
pt();
893 if (
std::abs(higgs.rapidity()) > 2.5)
900 else if (
Njets >= 2) {
902 double pTHjj = (
jets[0].momentum() +
jets[1].momentum() + higgs.momentum()).
pt();
909 if (higgs.pt() < 200) {
975 printf(
"==============================================================\n");
976 printf(
"======== HiggsTemplateCrossSections Initialization =========\n");
977 printf(
"==============================================================\n");
981 char *pm_env = std::getenv(
"HIGGSPRODMODE");
982 string pm(pm_env ==
nullptr ?
"" : pm_env);
985 else if (pm ==
"VBF")
991 else if (pm ==
"QQ2ZH")
993 else if (pm ==
"GG2ZH")
995 else if (pm ==
"TTH")
997 else if (pm ==
"BBH")
1002 MSG_WARNING(
"No HIGGSPRODMODE shell variable found. Needed when running Rivet stand-alone.");
1007 const FinalState FS;
1014 printf(
"==============================================================\n");
1016 printf(
"======== Sucessful Initialization =========\n");
1017 printf(
"==============================================================\n");
1026 const double weight = 1.0;
1029 int F =
cat.stage0_cat % 10,
P =
cat.stage1_cat_pTjet30GeV / 100;
1033 vector<int>
offset({0, 1, 13, 19, 24, 29, 33, 35, 37, 39});
1039 static vector<int> offset1_2({0, 1, 18, 29, 35, 41, 47, 53, 55, 57});
1040 int off1_2 = offset1_2[
P];
1042 static vector<int> offset1_2f({0, 1, 29, 54, 70, 86, 102, 109, 111, 113});
1043 int off1_2f = offset1_2f[
P];
1060 if (!
cat.jets30.empty())
1062 if (
cat.jets30.size() >= 2) {
1063 const FourMomentum &j1 =
cat.jets30[0].momentum(), &j2 =
cat.jets30[1].momentum();
1071 MSG_INFO(
" ====================================================== ");
1072 MSG_INFO(
" Higgs Template X-Sec Categorization Tool ");
1073 MSG_INFO(
" Status Code Summary ");
1074 MSG_INFO(
" ====================================================== ");
1080 MSG_INFO(
" >>>> --> the following errors occured:");
1084 <<
" failed to identify a valid Higgs boson.");
1086 <<
" failed to identify the hard scatter vertex.");
1089 <<
" failed to identify valid Ws from top decay.");
1091 MSG_INFO(
" ====================================================== ");
1092 MSG_INFO(
" ====================================================== ");
1165 #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
bool isChargedLepton(const HepMC::GenParticle *part)
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...
static std::string to_string(const XMLCh *ch)
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
Particle getLastInstance(Particle ptcl)
follow a "propagating" particle and return its last instance
Abs< T >::type abs(const T &t)
Namespace for Stage0 categorization.
Histo1DPtr hist_stage1_2_pTjet25
Higgs Template Cross Section namespace.
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