72 #include <Math/VectorUtil.h>
78 using namespace ROOT::Math::VectorUtil;
97 std::vector<const reco::Candidate*> findCandidates(
const reco::Candidate*,
100 void fillLeptons(
const std::vector<const reco::Candidate*>&,
105 static int heaviestFlavour(
int);
119 produces<JetFlavourMatchingCollection>();
120 sourceByReferToken_ = consumes<JetMatchedPartonsCollection>(iConfig.
getParameter<
InputTag>(
"srcByReference"));
121 physDefinition = iConfig.
getParameter<
bool>(
"physicsDefinition");
122 leptonInfo_ = iConfig.
exists(
"leptonInfo") ? iConfig.
getParameter<
bool>(
"leptonInfo") :
false;
127 if (iConfig.
exists(
"definition")) {
130 definition = NULL_DEF;
136 JetFlavourIdentifier::~JetFlavourIdentifier() {}
143 iEvent.
getByToken(sourceByReferToken_, theTagByRef);
147 if (!theTagByRef->empty()) {
153 std::unique_ptr<reco::JetFlavourMatchingCollection> jetFlavMatching(jfmc);
163 int thePartonFlavour = 0;
167 switch (definition) {
171 thePartonLorentzVector = aPartPhy.
get()->p4();
172 thePartonVertex = aPartPhy.
get()->vertex();
173 thePartonFlavour = aPartPhy.
get()->pdgId();
175 theLeptons = findLeptons(aPartPhy);
182 thePartonLorentzVector = aPartAlg.
get()->p4();
183 thePartonVertex = aPartAlg.
get()->vertex();
184 thePartonFlavour = aPartAlg.
get()->pdgId();
186 theLeptons = findLeptons(aPartAlg);
190 case NEAREST_STATUS2: {
193 thePartonLorentzVector = aPartN2.
get()->p4();
194 thePartonVertex = aPartN2.
get()->vertex();
195 thePartonFlavour = aPartN2.
get()->pdgId();
197 theLeptons = findLeptons(aPartN2);
201 case NEAREST_STATUS3: {
204 thePartonLorentzVector = aPartN3.
get()->p4();
205 thePartonVertex = aPartN3.
get()->vertex();
206 thePartonFlavour = aPartN3.
get()->pdgId();
208 theLeptons = findLeptons(aPartN3);
215 thePartonLorentzVector = aPartHeaviest.
get()->p4();
216 thePartonVertex = aPartHeaviest.
get()->vertex();
217 thePartonFlavour = aPartHeaviest.
get()->pdgId();
219 theLeptons = findLeptons(aPartHeaviest);
225 if (physDefinition) {
228 thePartonLorentzVector = aPartPhy.
get()->p4();
229 thePartonVertex = aPartPhy.
get()->vertex();
230 thePartonFlavour = aPartPhy.
get()->pdgId();
232 theLeptons = findLeptons(aPartPhy);
237 thePartonLorentzVector = aPartAlg.
get()->p4();
238 thePartonVertex = aPartAlg.
get()->vertex();
239 thePartonFlavour = aPartAlg.
get()->pdgId();
241 theLeptons = findLeptons(aPartAlg);
250 if (thePartonFlavour == 0) {
251 if (physDefinition) {
254 thePartonLorentzVector = aPartPhy.
get()->p4();
255 thePartonVertex = aPartPhy.
get()->vertex();
256 thePartonFlavour = aPartPhy.
get()->pdgId();
258 theLeptons = findLeptons(aPartPhy);
263 thePartonLorentzVector = aPartAlg.
get()->p4();
264 thePartonVertex = aPartAlg.
get()->vertex();
265 thePartonFlavour = aPartAlg.
get()->pdgId();
267 theLeptons = findLeptons(aPartAlg);
279 (*jetFlavMatching)[(*j).first] =
JetFlavour(thePartonLorentzVector, thePartonVertex, thePartonFlavour, theLeptons);
289 auto const& thePartonLV = parton->p4();
293 int partonFlavour =
std::abs(parton->pdgId());
297 std::vector<const reco::Candidate*>
candidates = findCandidates(mcstring, partonFlavour, parton->p4());
302 fillLeptons(candidates, theLeptons, 1, partonFlavour, thePartonLV);
307 std::vector<const reco::Candidate*> JetFlavourIdentifier::findCandidates(
309 std::vector<const reco::Candidate*>
cands;
323 int flavour = heaviestFlavour(pdgId);
324 if (flavour == partonFlavour || (flavour >= 10 && partonFlavour >= 10)) {
326 std::vector<const reco::Candidate*> newcands = findCandidates(cand->
daughter(
i), partonFlavour, thePartonLV);
328 std::copy(newcands.begin(), newcands.end(), std::back_inserter(cands));
330 if (partonFlavour >= 10)
336 !(partonFlavour >= 4 && partonFlavour < 10 && heaviestFlavour(cand->
pdgId()) < 4))
337 cands.push_back(cand);
342 void JetFlavourIdentifier::fillLeptons(
const std::vector<const reco::Candidate*>&
cands,
347 for (
unsigned int j = 0;
j < cands.size();
j++) {
348 for (
unsigned int i = 0;
i < cands[
j]->numberOfDaughters();
i++) {
349 int pdgId =
std::abs(cands[
j]->daughter(
i)->pdgId());
357 else if (pdgId == 14)
358 leptons.
muon += rank;
359 else if (pdgId == 16)
362 int heaviest = heaviestFlavour(pdgId);
363 int heaviest_ = heaviest < 10 ? heaviest : 0;
364 if (!heaviest || (flavour < 4 ? (heaviest_ < 4) : (heaviest >= 4))) {
365 std::vector<const reco::Candidate*> newcands = findCandidates(cands[
j]->daughter(
i), heaviest, thePartonLV);
367 newcands.push_back(cands[
j]->daughter(
i));
368 fillLeptons(newcands, leptons, rank * 10,
std::max(heaviest_, flavour), thePartonLV);
375 int JetFlavourIdentifier::heaviestFlavour(
int pdgId) {
380 while (pdgId % 10 > 0 && pdgId % 10 < 6) {
382 if (pdgId % 10 > flavour)
383 flavour = pdgId % 10;
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
bool isNonnull() const
Checks for non-null.
transient_vector_type::const_iterator const_iterator
const GenParticleRef & nearest_status3() const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
#define DEFINE_FWK_MODULE(type)
bool exists(std::string const ¶meterName) const
checks if a parameter exists
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
virtual size_type numberOfDaughters() const =0
number of daughters
const GenParticleRef & algoDefinitionParton() const
Abs< T >::type abs(const T &t)
T const * get() const
Returns C++ pointer to the item.
const GenParticleRef & nearest_status2() const
virtual int pdgId() const =0
PDG identifier.
const GenParticleRef heaviest() const
XYZPointD XYZPoint
point in space with cartesian internal representation
const GenParticleRef & physicsDefinitionParton() const
T getParameter(std::string const &) const
RefToBaseProd< T > makeRefToBaseProdFrom(RefToBase< T > const &iRef, Event const &iEvent)
EDGetTokenT< JetMatchedPartonsCollection > sourceByReferToken_
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector