1 #ifndef TRUTHRIVETTOOLS_HIGGSTEMPLATECROSSSECTIONS_CC 2 #define TRUTHRIVETTOOLS_HIGGSTEMPLATECROSSSECTIONS_CC 4 #include "Rivet/Analysis.hh" 5 #include "Rivet/Particle.hh" 6 #include "Rivet/Projections/FastJets.hh" 33 if (ptcl.genParticle()->end_vertex()) {
34 if (!
hasChild(ptcl.genParticle(), ptcl.pdgId()))
44 const GenVertex *prodVtx = p.genParticle()->production_vertex();
45 if (prodVtx ==
nullptr)
48 for (
const auto &ancestor :
particles(prodVtx, HepMC::ancestors)) {
49 for (
auto part : ptcls)
50 if (ancestor ==
part.genParticle())
59 Particles ptcls = {p2};
66 if (
child.pdgId() == pdgID) {
76 if (
parent->pdg_id() == pdgID)
83 for (
auto child : p.children()) {
84 if (PID::isQuark(
child.pdgId())) {
93 for (
auto child : p.children()) {
94 if (PID::isChLepton(
child.pdgId())) {
103 HiggsClassification
error(HiggsClassification &
cat,
106 int NmaxWarnings = 20) {
112 static std::atomic<int> Nwarnings{0};
113 if (!
msg.empty() && ++Nwarnings < NmaxWarnings)
126 HiggsClassification
cat;
127 cat.prodMode = prodMode;
144 "Unkown Higgs production mechanism. Cannot classify event." 145 " Classification for all events will most likely fail.");
153 GenVertex *HSvtx =
event.genEvent()->signal_process_vertex();
157 if (!PID::isHiggs(ptcl->pdg_id()))
160 if (ptcl->end_vertex() && !
hasChild(ptcl, PID::HIGGS)) {
166 if (HSvtx ==
nullptr && ptcl->production_vertex() && !
hasParent(ptcl, PID::HIGGS))
167 HSvtx = ptcl->production_vertex();
174 "Current event has " + std::to_string(Nhiggs) +
" Higgs bosons. There must be only one.");
175 if (cat.higgs.children().size() < 2)
178 if (HSvtx ==
nullptr)
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)) {
194 if (PID::isW(ptcl->pdg_id())) {
198 if (PID::isZ(ptcl->pdg_id())) {
207 if (!PID::isHiggs(ptcl->pdg_id())) {
209 uncatV_p4 +=
Particle(ptcl).momentum();
220 if (
isVH(prodMode) && !cat.V.genParticle()->end_vertex())
223 if (
isVH(prodMode) && cat.V.children().size() < 2)
226 if ((prodMode ==
HTXS::WH && (nZs > 0 || nWs != 1)) ||
230 "Found " + std::to_string(nWs) +
" W-bosons and " + std::to_string(nZs) +
231 " Z-bosons. Inconsitent with VH expectation.");
239 if (!PID::isTop(ptcl->pdg_id()))
243 if (top.genParticle()->end_vertex())
244 for (
auto child : top.children())
245 if (PID::isW(
child.pdgId()))
251 if ((prodMode ==
HTXS::TTH && Ws.size() < 2) || (prodMode ==
HTXS::TH && Ws.empty()))
263 Particles leptonicVs;
268 leptonicVs = uncatV_decays;
270 if (W.genParticle()->end_vertex() && !
quarkDecay(W))
274 const ParticleVector FS = applyProjection<FinalState>(
event,
"FS").
particles();
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, FastJets::ANTIKT, 0.4);
302 cat.jets25 = jets.jetsByPt(
Cuts::pT > 25.0);
303 cat.jets30 = jets.jetsByPt(
Cuts::pT > 30.0);
322 cat.isZ2vvDecay =
false;
324 cat.isZ2vvDecay =
true;
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);
351 for (
size_t i = 1;
i < bins.size(); ++
i)
354 return bins.size() - 1;
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;
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;
380 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 3 : 4;
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;
403 return (j1 + j2 + higgs.momentum()).
pt() < 25 ? 7 : 8;
416 int ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5;
424 return Category(prodMode * 10 + ctrlHiggs);
433 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
434 double pTj1 = !jets.empty() ? jets[0].momentum().pt() : 0;
446 else if (Njets >= 2) {
448 if (higgs.pt() <= 200) {
451 else if (vbfTopo == 1)
460 if (
std::abs(higgs.rapidity()) > 2.5)
468 double mjj = jets.size() > 1 ? (jets[0].mom() + jets[1].mom()).
mass() : 0;
469 if (60 < mjj && mjj < 120)
477 else if (V.pt() < 150)
479 else if (V.pt() > 250)
488 else if (V.pt() < 150)
490 else if (V.pt() > 250)
501 else if (jets.empty())
521 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
529 if (higgs.pt() > 200)
546 if (
std::abs(higgs.rapidity()) > 2.5)
548 int Njets = jets.size();
553 else if (Njets >= 2) {
554 double mjj = (jets[0].mom() + jets[1].mom()).
mass();
557 else if (60 < mjj && mjj < 120)
559 else if (120 < mjj && mjj < 350)
561 else if (mjj > 350) {
562 if (higgs.pt() > 200)
573 else if (V.pt() < 75)
575 else if (V.pt() < 150)
577 else if (V.pt() > 250)
586 else if (V.pt() < 75)
588 else if (V.pt() < 150)
590 else if (V.pt() > 250)
599 else if (V.pt() < 75)
601 else if (V.pt() < 150)
603 else if (V.pt() > 250)
623 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
631 if (higgs.pt() > 200)
639 double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).
pt();
653 if (
std::abs(higgs.rapidity()) > 2.5)
655 int Njets = jets.size();
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();
669 if (higgs.pt() < 200) {
681 int Njets = jets.size();
692 int Njets = jets.size();
703 int Njets = jets.size();
726 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
734 if (higgs.pt() > 200)
751 if (
std::abs(higgs.rapidity()) > 2.5)
753 int Njets = jets.size();
758 else if (Njets >= 2) {
759 double mjj = (jets[0].mom() + jets[1].mom()).
mass();
762 else if (60 < mjj && mjj < 120)
764 else if (120 < mjj && mjj < 350)
766 else if (mjj > 350) {
767 if (higgs.pt() > 200)
778 else if (V.pt() < 75)
780 else if (V.pt() < 150)
782 else if (V.pt() > 250)
791 else if (V.pt() < 75)
793 else if (V.pt() < 150)
795 else if (V.pt() > 250)
804 else if (V.pt() < 75)
806 else if (V.pt() < 150)
808 else if (V.pt() > 250)
831 int Njets = jets.size(), ctrlHiggs =
std::abs(higgs.rapidity()) < 2.5, fwdHiggs = !ctrlHiggs;
839 if (higgs.pt() > 200) {
841 double pTHj = (jets[0].momentum() + higgs.momentum()).
pt();
842 if (pTHj / higgs.pt() > 0.15)
855 double pTHjj = (jets[0].momentum() + jets[1].momentum() + higgs.momentum()).
pt();
869 if (
std::abs(higgs.rapidity()) > 2.5)
871 int Njets = jets.size();
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();
885 if (higgs.pt() < 200) {
897 int Njets = jets.size();
908 int Njets = jets.size();
919 int Njets = jets.size();
951 printf(
"==============================================================\n");
952 printf(
"======== HiggsTemplateCrossSections Initialization =========\n");
953 printf(
"==============================================================\n");
957 char *pm_env = getenv(
"HIGGSPRODMODE");
958 string pm(pm_env ==
nullptr ?
"" : pm_env);
961 else if (pm ==
"VBF")
967 else if (pm ==
"QQ2ZH")
969 else if (pm ==
"GG2ZH")
971 else if (pm ==
"TTH")
973 else if (pm ==
"BBH")
978 MSG_WARNING(
"No HIGGSPRODMODE shell variable found. Needed when running Rivet stand-alone.");
984 addProjection(FS,
"FS");
989 printf(
"==============================================================\n");
991 printf(
"======== Sucessful Initialization =========\n");
992 printf(
"==============================================================\n");
1001 const double weight =
event.weight();
1004 int F = cat.stage0_cat % 10,
P = cat.stage1_cat_pTjet30GeV / 100;
1005 hist_stage0->fill(cat.stage0_cat / 10 * 2 + F, weight);
1008 vector<int>
offset({0, 1, 13, 19, 24, 29, 33, 35, 37, 39});
1014 static vector<int> offset1_2({0, 1, 18, 29, 35, 41, 47, 53, 55, 57});
1015 int off1_2 = offset1_2[
P];
1017 static vector<int> offset1_2f({0, 1, 29, 54, 70, 86, 102, 109, 111, 113});
1018 int off1_2f = offset1_2f[
P];
1035 if (!cat.jets30.empty())
1037 if (cat.jets30.size() >= 2) {
1038 const FourMomentum &j1 = cat.jets30[0].momentum(), &j2 = cat.jets30[1].momentum();
1046 MSG_INFO(
" ====================================================== ");
1047 MSG_INFO(
" Higgs Template X-Sec Categorization Tool ");
1048 MSG_INFO(
" Status Code Summary ");
1049 MSG_INFO(
" ====================================================== ");
1055 MSG_INFO(
" >>>> --> the following errors occured:");
1059 <<
" failed to identify a valid Higgs boson.");
1061 <<
" failed to identify the hard scatter vertex.");
1064 <<
" failed to identify valid Ws from top decay.");
1066 MSG_INFO(
" ====================================================== ");
1067 MSG_INFO(
" ====================================================== ");
1097 hist_stage0 = bookHisto1D(
"HTXS_stage0", 20, 0, 20);
1106 hist_pT_V = bookHisto1D(
"pT_V", 80, 0, 400);
1139 #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()
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
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.
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
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)
Namespace for Stage0 categorization.
Histo1DPtr hist_stage1_2_pTjet25
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
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.
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