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" 25 : Analysis(
"HiggsTemplateCrossSections"),
37 if ( ptcl.genParticle()->end_vertex() ) {
38 if ( !
hasChild(ptcl.genParticle(),ptcl.pdgId()) )
return ptcl;
46 const GenVertex* prodVtx = p.genParticle()->production_vertex();
47 if (prodVtx ==
nullptr)
return false;
49 for (
const auto & ancestor:
particles(prodVtx, HepMC::ancestors)){
50 for (
auto part:ptcls )
51 if ( ancestor==
part.genParticle() )
return true;
65 if (
child.pdgId()==pdgID)
return true;
72 if (
parent->pdg_id()==pdgID)
return true;
78 for (
auto child:p.children())
79 if (PID::isQuark(
child.pdgId()))
return true;
92 static std::atomic<int> Nwarnings{0};
93 if (
msg!=
"" && ++Nwarnings < NmaxWarnings )
106 HiggsClassification
cat;
107 cat.prodMode = prodMode;
115 "Unkown Higgs production mechanism. Cannot classify event." 116 " Classification for all events will most likely fail.");
124 GenVertex *HSvtx =
event.genEvent()->signal_process_vertex();
129 if ( !PID::isHiggs(ptcl->pdg_id()) )
continue;
131 if ( ptcl->end_vertex() && !
hasChild(ptcl,PID::HIGGS) ) {
132 cat.higgs =
Particle(ptcl); ++Nhiggs;
136 if ( HSvtx==
nullptr && ptcl->production_vertex() && !
hasParent(ptcl,PID::HIGGS) )
137 HSvtx = ptcl->production_vertex();
143 "Current event has "+std::to_string(Nhiggs)+
" Higgs bosons. There must be only one.");
144 if (cat.higgs.children().size()<2)
146 "Could not identify Higgs boson decay products.");
148 if (HSvtx ==
nullptr)
157 bool is_uncatdV =
false;
158 Particles uncatV_decays;
159 FourMomentum uncatV_p4(0,0,0,0);
160 FourVector uncatV_v4(0,0,0,0);
161 int nWs=0, nZs=0, nTop=0;
162 if (
isVH(prodMode) ) {
164 if (PID::isW(ptcl->pdg_id())) { ++nWs; cat.V=
Particle(ptcl); }
165 if (PID::isZ(ptcl->pdg_id())) { ++nZs; cat.V=
Particle(ptcl); }
170 if (!PID::isHiggs(ptcl->pdg_id())) {
172 uncatV_p4 +=
Particle(ptcl).momentum();
177 is_uncatdV =
true; cat.V =
Particle(24,uncatV_p4);
183 if (
isVH(prodMode) && !cat.V.genParticle()->end_vertex() )
186 if (
isVH(prodMode) && cat.V.children().size()<2 )
189 if ( ( prodMode==
HTXS::WH && (nZs>0||nWs!=1) ) ||
192 std::to_string(nZs)+
" Z-bosons. Inconsitent with VH expectation.");
200 if ( !PID::isTop(ptcl->pdg_id()) )
continue;
203 if ( top.genParticle()->end_vertex() )
204 for (
auto child:top.children())
210 if ( (prodMode==
HTXS::TTH && Ws.size()<2) || (prodMode==
HTXS::TH && Ws.empty() ) )
222 Particles leptonicVs;
225 }
else leptonicVs = uncatV_decays;
226 for (
auto W:Ws )
if ( W.genParticle()->end_vertex() && !
quarkDecay(W) ) leptonicVs += W;
229 const ParticleVector FS = applyProjection<FinalState>(
event,
"FS").
particles();
231 FourMomentum sum(0,0,0,0), vSum(0,0,0,0), hSum(0,0,0,0);
240 if ( !leptonicVs.empty() &&
originateFrom(
p,leptonicVs) )
continue;
245 cat.p4decay_higgs = hSum;
246 cat.p4decay_V = vSum;
249 FastJets
jets(fps_temp, FastJets::ANTIKT, 0.4 );
252 cat.jets25 = jets.jetsByPt(
Cuts::pT > 25.0 );
253 cat.jets30 = jets.jetsByPt(
Cuts::pT > 30.0 );
273 cat.stage1_cat_pTjet25GeV =
getStage1Category(prodMode,cat.higgs,cat.jets25,cat.V);
274 cat.stage1_cat_pTjet30GeV =
getStage1Category(prodMode,cat.higgs,cat.jets30,cat.V);
288 for (
size_t i=1;
i<bins.size();++
i)
289 if (x<bins[
i])
return i-1;
290 return bins.size()-1;
297 if (jets.size()<2)
return 0;
298 const FourMomentum &j1=jets[0].momentum(), &j2=jets[1].momentum();
299 bool VBFtopo = (j1+j2).
mass() > 400.0 &&
std::abs(j1.rapidity()-j2.rapidity()) > 2.8;
300 return VBFtopo ? (j1+j2+higgs.momentum()).
pt()<25 ? 2 : 1 : 0;
311 int ctrlHiggs =
std::abs(higgs.rapidity())<2.5;
319 return Category(prodMode*10 + ctrlHiggs);
328 int Njets=jets.size(), ctrlHiggs =
std::abs(higgs.rapidity())<2.5, fwdHiggs = !ctrlHiggs;
329 double pTj1 = !jets.empty() ? jets[0].momentum().pt() : 0;
354 double mjj = jets.size()>1 ? (jets[0].mom()+jets[1].mom()).
mass():0;
401 printf(
"==============================================================\n");
402 printf(
"======== HiggsTemplateCrossSections Initialization =========\n");
403 printf(
"==============================================================\n");
407 char *pm_env = getenv(
"HIGGSPRODMODE");
408 string pm(pm_env==
nullptr?
"":pm_env);
419 MSG_WARNING(
"No HIGGSPRODMODE shell variable found. Needed when running Rivet stand-alone.");
425 addProjection(FS,
"FS");
430 printf(
"==============================================================\n");
432 printf(
"======== Sucessful Initialization =========\n");
433 printf(
"==============================================================\n");
443 const double weight =
event.weight();
446 int F=cat.stage0_cat%10,
P=cat.stage1_cat_pTjet30GeV/100;
447 hist_stage0->fill( cat.stage0_cat/10*2+F, weight );
450 vector<int>
offset({0,1,13,19,24,29,33,35,37,39});
465 if (cat.jets30.size()>=2) {
466 const FourMomentum &j1 = cat.jets30[0].momentum(), &j2 = cat.jets30[1].momentum();
474 MSG_INFO (
" ====================================================== ");
475 MSG_INFO (
" Higgs Template X-Sec Categorization Tool ");
476 MSG_INFO (
" Status Code Summary ");
477 MSG_INFO (
" ====================================================== ");
482 MSG_INFO (
" >>>> --> the following errors occured:");
490 MSG_INFO (
" ====================================================== ");
491 MSG_INFO (
" ====================================================== ");
513 hist_pT_V = bookHisto1D(
"pT_V",80,0,400);
542 #ifdef RIVET_ANALYSIS_PATH
std::map< HTXS::ErrorCode, size_t > m_errorCount
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.
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.
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.
Histo1DPtr hist_dijet_mass
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
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.
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.
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.
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Histo1DPtr hist_stage1_pTjet25
production mode not defined
Histo1DPtr hist_deltay_jj
failed to identify top decay