6 #include "fastjet/ClusterSequence.hh"
13 leptonMinPt_(pset.getParameter<double>(
"leptonMinPt")),
14 leptonMaxEta_(pset.getParameter<double>(
"leptonMaxEta")),
15 jetMinPt_(pset.getParameter<double>(
"jetMinPt")),
16 jetMaxEta_(pset.getParameter<double>(
"jetMaxEta")),
17 wMass_(pset.getParameter<double>(
"wMass")),
18 tMass_(pset.getParameter<double>(
"tMass"))
23 const double leptonConeSize = pset.
getParameter<
double>(
"leptonConeSize");
24 const double jetConeSize = pset.
getParameter<
double>(
"jetConeSize");
25 fjLepDef_ = std::shared_ptr<JetDef>(
new JetDef(fastjet::antikt_algorithm, leptonConeSize));
26 fjJetDef_ = std::shared_ptr<JetDef>(
new JetDef(fastjet::antikt_algorithm, jetConeSize));
30 produces<reco::GenParticleCollection>(
"neutrinos");
31 produces<reco::GenJetCollection>(
"leptons");
32 produces<reco::GenJetCollection>(
"jets");
34 produces<reco::GenParticleCollection>();
57 std::set<size_t> bHadronIdxs;
58 for (
size_t i=0,
n=genParticleHandle->size();
i<
n; ++
i )
62 if ( status == 1 )
continue;
70 std::vector<size_t> leptonIdxs;
71 std::set<size_t> neutrinoIdxs;
72 for (
size_t i=0, n=finalStateHandle->size();
i<
n; ++
i )
76 if ( p.
status() != 1 )
continue;
86 leptonIdxs.push_back(
i);
88 case 12:
case 14:
case 16:
89 neutrinoIdxs.insert(
i);
100 std::vector<fastjet::PseudoJet> fjLepInputs;
101 fjLepInputs.reserve(leptonIdxs.size());
102 for (
auto index : leptonIdxs )
107 fjLepInputs.push_back(fastjet::PseudoJet(p.
px(), p.
py(), p.
pz(), p.
energy()));
108 fjLepInputs.back().set_user_index(
index);
112 fastjet::ClusterSequence fjLepClusterSeq(fjLepInputs, *
fjLepDef_);
113 std::vector<fastjet::PseudoJet> fjLepJets = fastjet::sorted_by_pt(fjLepClusterSeq.inclusive_jets(
leptonMinPt_));
116 leptons->reserve(fjLepJets.size());
117 std::set<size_t> lepDauIdxs;
118 for (
auto& fjJet : fjLepJets )
123 const std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
125 std::vector<reco::CandidatePtr> constituents;
127 for (
auto& fjConstituent : fjConstituents )
129 const size_t index = fjConstituent.user_index();
131 const int absPdgId =
abs(cand->pdgId());
132 if ( absPdgId == 11
or absPdgId == 13 )
134 if ( lepCand.
isNonnull() and lepCand->pt() > cand->pt() )
continue;
137 constituents.push_back(cand);
139 if ( lepCand.
isNull() )
continue;
140 if ( lepCand->pt() < fjJet.pt()/2 )
continue;
142 const LorentzVector jetP4(fjJet.px(), fjJet.py(), fjJet.pz(), fjJet.E());
146 lepJet.setPdgId(lepCand->pdgId());
147 lepJet.setCharge(lepCand->charge());
149 const double jetArea = fjJet.has_area() ? fjJet.area() : 0;
150 lepJet.setJetArea(jetArea);
152 leptons->push_back(lepJet);
155 for (
auto& fjConstituent : fjConstituents )
157 lepDauIdxs.insert(fjConstituent.user_index());
164 std::vector<fastjet::PseudoJet> fjJetInputs;
165 fjJetInputs.reserve(nStables);
166 for (
size_t i=0, n=finalStateHandle->size();
i<
n; ++
i )
169 if ( p.
status() != 1 )
continue;
172 if ( neutrinoIdxs.find(
i) != neutrinoIdxs.end() )
continue;
173 if ( lepDauIdxs.find(
i) != lepDauIdxs.end() )
continue;
175 fjJetInputs.push_back(fastjet::PseudoJet(p.
px(), p.
py(), p.
pz(), p.
energy()));
176 fjJetInputs.back().set_user_index(
i);
179 for (
auto index : bHadronIdxs )
184 const double scale = 1
e-20/p.
p();
186 fjJetInputs.back().set_user_index(
index);
190 fastjet::ClusterSequence fjJetClusterSeq(fjJetInputs, *
fjJetDef_);
191 std::vector<fastjet::PseudoJet> fjJets = fastjet::sorted_by_pt(fjJetClusterSeq.inclusive_jets(
jetMinPt_));
194 jets->reserve(fjJets.size());
195 std::vector<size_t> bjetIdxs, ljetIdxs;
196 for (
auto& fjJet : fjJets )
201 const std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
203 std::vector<reco::CandidatePtr> constituents;
204 bool hasBHadron =
false;
205 for (
size_t j=0,
m=fjConstituents.size();
j<
m; ++
j )
207 const size_t index = fjConstituents[
j].user_index();
208 if ( bHadronIdxs.find(index) != bHadronIdxs.end() ) hasBHadron =
true;
210 constituents.push_back(cand);
213 const LorentzVector jetP4(fjJet.px(), fjJet.py(), fjJet.pz(), fjJet.E());
217 const double jetArea = fjJet.has_area() ? fjJet.area() : 0;
218 genJet.setJetArea(jetArea);
222 bjetIdxs.push_back(jets->size());
226 ljetIdxs.push_back(jets->size());
229 jets->push_back(genJet);
237 const size_t nLepton = leptons->size();
240 std::vector<std::pair<int, int> > wCandIdxs;
241 for (
auto lep = leptons->begin(); lep != leptons->end(); ++lep )
243 const size_t iLep = lep-leptons->begin();
244 for (
auto nu = neutrinos->begin(); nu != neutrinos->end(); ++nu )
247 const double m = (lep->p4()+nu->p4()).mass();
248 if ( m > 300 )
continue;
250 const size_t iNu = nu-neutrinos->begin();
251 wCandIdxs.push_back(make_pair(iLep, iNu));
255 if ( nLepton == 0
or wCandIdxs.empty() )
break;
256 else if ( nLepton == 1 and wCandIdxs.size() >= 1 )
259 int bestLepIdx = -1, bestNuIdx = -1;
260 for (
auto wCandIdx : wCandIdxs )
262 const int lepIdx = wCandIdx.first;
263 const int nuIdx = wCandIdx.second;
266 const double mW = (lepLVec + nuLVec).mass();
267 if ( mW > 300 )
continue;
277 if ( bestLepIdx < 0 )
break;
278 const auto& lepton = leptons->at(bestLepIdx);
279 const auto& neutrino = neutrinos->at(bestNuIdx);
285 int bestJ1Idx = -1, bestJ2Idx = -1;
286 for (
auto j1Idx = ljetIdxs.begin(); j1Idx != ljetIdxs.end(); ++j1Idx )
288 const auto& j1 = jets->at(*j1Idx);
289 for (
auto j2Idx = j1Idx+1; j2Idx != ljetIdxs.end(); ++j2Idx )
291 const auto& j2 = jets->at(*j2Idx);
292 const double mW = (j1.p4()+j2.p4()).mass();
293 if ( mW > 300 )
continue;
304 if ( bestJ1Idx < 0 )
break;
305 const auto& wJet1 = jets->at(bestJ1Idx);
306 const auto& wJet2 = jets->at(bestJ2Idx);
312 int bestB1Idx = -1, bestB2Idx = -1;
313 if ( bjetIdxs.size() < 2 )
break;
314 for (
auto b1Idx : bjetIdxs )
316 const double t1Mass = (w1LVec + jets->at(b1Idx).p4()).mass();
317 if ( t1Mass > 300 )
continue;
318 for (
auto b2Idx : bjetIdxs )
320 if ( b1Idx == b2Idx )
continue;
321 const double t2Mass = (w2LVec + jets->at(b2Idx).p4()).mass();
322 if ( t2Mass > 300 )
continue;
333 if ( bestB1Idx < 0 )
break;
334 const auto&
bJet1 = jets->at(bestB1Idx);
335 const auto&
bJet2 = jets->at(bestB2Idx);
342 const int lepQ = lepton.charge();
356 pseudoTop->push_back(t1);
357 pseudoTop->push_back(w1);
358 pseudoTop->push_back(b1);
359 pseudoTop->push_back(l1);
360 pseudoTop->push_back(n1);
362 pseudoTop->push_back(t2);
363 pseudoTop->push_back(w2);
364 pseudoTop->push_back(b2);
365 pseudoTop->push_back(qA);
366 pseudoTop->push_back(qB);
369 else if ( nLepton == 2 and wCandIdxs.size() >= 2 )
372 int bestLep1Idx = -1, bestLep2Idx = -1, bestNu1Idx = -1, bestNu2Idx = -1;
373 for (
auto i : wCandIdxs )
375 const auto& lepton1 = leptons->at(
i.first);
376 if ( lepton1.charge() < 0 )
continue;
377 const auto& neutrino1 = neutrinos->at(
i.second);
378 const double mW1 = (lepton1.p4()+neutrino1.p4()).mass();
379 if ( mW1 > 300 )
continue;
380 for (
auto j : wCandIdxs )
382 if (
i ==
j )
continue;
383 const auto& lepton2 = leptons->at(
j.first);
384 if ( lepton2.charge() > 0 )
continue;
385 const auto& neutrino2 = neutrinos->at(
j.second);
386 const double mW2 = (lepton2.p4()+neutrino2.p4()).mass();
387 if ( mW2 > 300 )
continue;
393 bestLep1Idx =
i.first;
394 bestLep2Idx =
j.first;
395 bestNu1Idx =
i.second;
396 bestNu2Idx =
j.second;
400 if ( bestLep1Idx < 0 )
break;
401 const auto& lepton1 = leptons->at(bestLep1Idx);
402 const auto& lepton2 = leptons->at(bestLep2Idx);
403 const auto& neutrino1 = neutrinos->at(bestNu1Idx);
404 const auto& neutrino2 = neutrinos->at(bestNu2Idx);
410 int bestB1Idx = -1, bestB2Idx = -1;
411 if ( bjetIdxs.size() < 2 )
break;
412 for (
auto b1Idx : bjetIdxs )
414 const double t1Mass = (w1LVec + jets->at(b1Idx).p4()).mass();
415 if ( t1Mass > 300 )
continue;
416 for (
auto b2Idx : bjetIdxs )
418 if ( b1Idx == b2Idx )
continue;
419 const double t2Mass = (w2LVec + jets->at(b2Idx).p4()).mass();
420 if ( t2Mass > 300 )
continue;
431 if ( bestB1Idx < 0 )
break;
432 const auto&
bJet1 = jets->at(bestB1Idx);
433 const auto&
bJet2 = jets->at(bestB2Idx);
440 const int lep1Q = lepton1.charge();
441 const int lep2Q = lepton2.charge();
455 pseudoTop->push_back(t1);
456 pseudoTop->push_back(w1);
457 pseudoTop->push_back(b1);
458 pseudoTop->push_back(l1);
459 pseudoTop->push_back(n1);
461 pseudoTop->push_back(t2);
462 pseudoTop->push_back(w2);
463 pseudoTop->push_back(b2);
464 pseudoTop->push_back(l2);
465 pseudoTop->push_back(n2);
469 if ( pseudoTop->size() == 10 )
497 event.put(neutrinos,
"neutrinos");
498 event.put(leptons,
"leptons");
499 event.put(jets,
"jets");
501 event.put(pseudoTop);
522 if ( pdgId > 100 )
return true;
530 const unsigned int absPdgId =
abs(p->
pdgId());
531 if ( !
isBHadron(absPdgId) )
return false;
546 if ( absPdgId <= 100 )
return false;
547 if ( absPdgId >= 1000000000 )
return false;
552 const int nq3 = (absPdgId / 10) % 10;
553 const int nq2 = (absPdgId / 100) % 10;
554 const int nq1 = (absPdgId / 1000) % 10;
556 if ( nq3 == 0 )
return false;
557 if ( nq1 == 0 and nq2 == 5 )
return true;
558 if ( nq1 == 5 )
return true;
564 std::auto_ptr<reco::GenParticleCollection>& outColl)
const
572 outColl->push_back(pOut);
bool isBHadron(const reco::Candidate *p) const
PseudoTopProducer(const edm::ParameterSet &pset)
const double leptonMaxEta_
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
reco::Particle::Point genVertex_
virtual double energy() const =0
energy
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
const double leptonMinPt_
common ppss p3p6s2 common epss epspn46 common const1 w2
edm::EDGetTokenT< edm::View< reco::Candidate > > finalStateToken_
tuple bJet1
do the razor with one or two b jets (medium CSV)
fastjet::JetDefinition JetDef
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
virtual double pt() const =0
transverse momentum
std::shared_ptr< JetDef > fjJetDef_
virtual int status() const =0
status word
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
std::vector< GenJet > GenJetCollection
collection of GenJet objects
virtual double pz() const =0
z coordinate of momentum vector
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
bool isFromHadron(const reco::Candidate *p) const
std::shared_ptr< JetDef > fjLepDef_
reco::Particle::LorentzVector LorentzVector
void clearDaughters()
clear daughter references
void addDaughter(const typename daughters::value_type &)
add a daughter via a reference
void resetDaughters(const edm::ProductID &id)
set daughters product ID
virtual size_type numberOfDaughters() const =0
number of daughters
virtual double p() const =0
magnitude of momentum vector
const reco::Candidate * getLast(const reco::Candidate *p)
void produce(edm::Event &event, const edm::EventSetup &eventSetup) override
bool isNull() const
Checks for null.
math::XYZPoint Point
point in the space
Abs< T >::type abs(const T &t)
Jets made from MC generator particles.
virtual const Point & vertex() const =0
vertex position
virtual int charge() const =0
electric charge
virtual double py() const =0
y coordinate of momentum vector
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
edm::EDGetTokenT< edm::View< reco::Candidate > > genParticleToken_
bool isNonnull() const
Checks for non-null.
virtual double px() const =0
x coordinate of momentum vector
virtual int pdgId() const =0
PDG identifier.
reco::GenParticleRef buildGenParticle(const reco::Candidate *p, reco::GenParticleRefProd &refHandle, std::auto_ptr< reco::GenParticleCollection > &outColl) const
ProductID id() const
Accessor for product ID.
void resetMothers(const edm::ProductID &id)
set mother product ID
void clearMothers()
clear mother references
void writeSpecific(reco::CaloJet &jet, reco::Particle::LorentzVector const &p4, reco::Particle::Point const &point, std::vector< reco::CandidatePtr > const &constituents, edm::EventSetup const &c)
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector