72 #include <Math/VectorUtil.h>
78 using namespace ROOT::Math::VectorUtil;
80 namespace reco {
namespace modules {
99 std::vector<const reco::Candidate*> findCandidates(
const reco::Candidate*,
int);
100 void fillLeptons(
const std::vector<const reco::Candidate*> &,
JetFlavour::Leptons &,
int,
int);
101 static int heaviestFlavour(
int);
118 produces<JetFlavourMatchingCollection>();
120 physDefinition = iConfig.
getParameter<
bool>(
"physicsDefinition");
121 leptonInfo_ = iConfig.
exists(
"leptonInfo") ? iConfig.
getParameter<
bool>(
"leptonInfo") :
true;
126 if ( iConfig.
exists(
"definition") ) {
129 definition = NULL_DEF;
135 JetFlavourIdentifier::~JetFlavourIdentifier()
144 iEvent.
getByLabel (sourceByRefer_, theTagByRef);
148 if (!theTagByRef->empty()) {
154 auto_ptr<reco::JetFlavourMatchingCollection> jetFlavMatching(jfmc);
158 j != theTagByRef->end();
168 int thePartonFlavour = 0;
172 switch (definition) {
176 thePartonLorentzVector = aPartPhy.
get()->p4();
177 thePartonVertex = aPartPhy.
get()->vertex();
178 thePartonFlavour = aPartPhy.
get()->pdgId();
179 if (leptonInfo_) theLeptons = findLeptons(aPartPhy);
186 thePartonLorentzVector = aPartAlg.
get()->p4();
187 thePartonVertex = aPartAlg.
get()->vertex();
188 thePartonFlavour = aPartAlg.
get()->pdgId();
189 if (leptonInfo_) theLeptons = findLeptons(aPartAlg);
193 case NEAREST_STATUS2 : {
196 thePartonLorentzVector = aPartN2.
get()->p4();
197 thePartonVertex = aPartN2.
get()->vertex();
198 thePartonFlavour = aPartN2.
get()->pdgId();
199 if (leptonInfo_) theLeptons = findLeptons(aPartN2);
203 case NEAREST_STATUS3: {
206 thePartonLorentzVector = aPartN3.
get()->p4();
207 thePartonVertex = aPartN3.
get()->vertex();
208 thePartonFlavour = aPartN3.
get()->pdgId();
209 if (leptonInfo_) theLeptons = findLeptons(aPartN3);
216 thePartonLorentzVector = aPartHeaviest.
get()->p4();
217 thePartonVertex = aPartHeaviest.
get()->vertex();
218 thePartonFlavour = aPartHeaviest.
get()->pdgId();
219 if (leptonInfo_) theLeptons = findLeptons(aPartHeaviest);
225 if (physDefinition) {
228 thePartonLorentzVector = aPartPhy.
get()->p4();
229 thePartonVertex = aPartPhy.
get()->vertex();
230 thePartonFlavour = aPartPhy.
get()->pdgId();
231 if (leptonInfo_) theLeptons = findLeptons(aPartPhy);
236 thePartonLorentzVector = aPartAlg.
get()->p4();
237 thePartonVertex = aPartAlg.
get()->vertex();
238 thePartonFlavour = aPartAlg.
get()->pdgId();
239 if (leptonInfo_) theLeptons = findLeptons(aPartAlg);
248 if (thePartonFlavour == 0) {
249 if (physDefinition) {
252 thePartonLorentzVector = aPartPhy.
get()->p4();
253 thePartonVertex = aPartPhy.
get()->vertex();
254 thePartonFlavour = aPartPhy.
get()->pdgId();
255 if (leptonInfo_) theLeptons = findLeptons(aPartPhy);
260 thePartonLorentzVector = aPartAlg.
get()->p4();
261 thePartonVertex = aPartAlg.
get()->vertex();
262 thePartonFlavour = aPartAlg.
get()->pdgId();
263 if (leptonInfo_) theLeptons = findLeptons(aPartAlg);
275 (*jetFlavMatching)[(*j).first] =
JetFlavour(thePartonLorentzVector, thePartonVertex, thePartonFlavour, theLeptons);
280 iEvent.
put( jetFlavMatching );
288 thePartonLV = parton->p4();
292 int partonFlavour =
std::abs(parton->pdgId());
296 std::vector<const reco::Candidate*> candidates = findCandidates(mcstring, partonFlavour);
301 fillLeptons(candidates, theLeptons, 1, partonFlavour);
306 std::vector<const reco::Candidate*> JetFlavourIdentifier::findCandidates(
const reco::Candidate *cand,
int partonFlavour)
308 std::vector<const reco::Candidate*> cands;
321 int flavour = heaviestFlavour(pdgId);
322 if (flavour == partonFlavour ||
323 (flavour >= 10 && partonFlavour >= 10)) {
325 std::vector<const reco::Candidate*> newcands = findCandidates(cand->
daughter(
i), partonFlavour);
327 std::copy(newcands.begin(), newcands.end(), std::back_inserter(cands));
329 if (partonFlavour >= 10)
335 !(partonFlavour >= 4 && partonFlavour < 10 &&
336 heaviestFlavour(cand->
pdgId()) < 4))
337 cands.push_back(cand);
344 for(
unsigned int j = 0;
j < cands.size();
j++) {
345 for(
unsigned int i = 0;
i < cands[
j]->numberOfDaughters();
i++) {
354 else if (pdgId == 14)
355 leptons.
muon += rank;
356 else if (pdgId == 16)
359 int heaviest = heaviestFlavour(pdgId);
360 int heaviest_ = heaviest < 10 ? heaviest : 0;
361 if (!heaviest || (flavour < 4 ? (heaviest_ < 4) : (heaviest >= 4))) {
362 std::vector<const reco::Candidate*> newcands = findCandidates(cands[
j]->daughter(
i), heaviest);
363 if (pdgId <= 110) newcands.push_back(cands[
j]->daughter(
i));
364 fillLeptons(newcands, leptons, rank * 10,
std::max(heaviest_, flavour));
371 int JetFlavourIdentifier::heaviestFlavour(
int pdgId)
377 while(pdgId % 10 > 0 && pdgId % 10 < 6) {
379 if (pdgId % 10 > flavour)
380 flavour = pdgId % 10;
T getParameter(std::string const &) const
Handle< JetMatchedPartonsCollection > theTagByRef
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
transient_vector_type::const_iterator const_iterator
const GenParticleRef & nearest_status3() 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.
bool isNonnull() const
Checks for non-null.
virtual size_type numberOfDaughters() const =0
number of daughters
const T & max(const T &a, const T &b)
const GenParticleRef & algoDefinitionParton() const
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
const GenParticleRef & nearest_status2() const
bool getByLabel(InputTag const &tag, Handle< PROD > &result) 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 const * get() const
Returns C++ pointer to the item.
int flavour(const Candidate &part)
math::XYZTLorentzVector thePartonLV
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector