CMS 3D CMS Logo

BTVMCFlavourTableProducer.cc
Go to the documentation of this file.
1 // system include files
2 #include <memory>
3 
4 // user include files
7 
9 
13 
17 
19 
22 
24 public:
26  : name_(iConfig.getParameter<std::string>("name")),
27  src_(consumes<std::vector<pat::Jet> >(iConfig.getParameter<edm::InputTag>("src"))),
28  genParticlesToken_(consumes<reco::GenParticleCollection>(iConfig.getParameter<edm::InputTag>("genparticles"))) {
29  produces<nanoaod::FlatTable>();
30  }
31 
33  int jet_flavour(const pat::Jet& jet,
34  const std::vector<reco::GenParticle>& gToBB,
35  const std::vector<reco::GenParticle>& gToCC,
36  const std::vector<reco::GenParticle>& neutrinosLepB,
37  const std::vector<reco::GenParticle>& neutrinosLepB_C,
38  const std::vector<reco::GenParticle>& alltaus,
40  int hflav = abs(jet.hadronFlavour());
41  int pflav = abs(jet.partonFlavour());
42  int physflav = 0;
43  if (!(jet.genJet())) {
44  if (pflav == 0)
45  return 999;
46  else
47  return 1000;
48  }
49  if (jet.genParton())
50  physflav = abs(jet.genParton()->pdgId());
51  std::size_t nbs = jet.jetFlavourInfo().getbHadrons().size();
52  std::size_t ncs = jet.jetFlavourInfo().getcHadrons().size();
53 
54  unsigned int nbFromGSP(0);
55  for (const reco::GenParticle& p : gToBB) {
56  double dr2(reco::deltaR2(jet, p));
57  if (dr2 < jetR_ * jetR_)
58  ++nbFromGSP;
59  }
60 
61  unsigned int ncFromGSP(0);
62  for (const reco::GenParticle& p : gToCC) {
63  double dr2(reco::deltaR2(jet, p));
64  if (dr2 < jetR_ * jetR_)
65  ++ncFromGSP;
66  }
67 
68  //std::cout << " jet pt = " << jet.pt() << " hfl = " << hflav << " pfl = " << pflav << " genpart = " << physflav
69  // << " nbFromGSP = " << nbFromGSP << " ncFromGSP = " << ncFromGSP
70  // << " nBhadrons " << nbs << " nCHadrons " << ncs << std::endl;
71  if (hflav == 5) { //B jet
72  if (nbs > 1) {
73  if (nbFromGSP > 0)
74  return 511;
75  else
76  return 510;
77  } else if (nbs == 1) {
78  for (std::vector<reco::GenParticle>::const_iterator it = neutrinosLepB.begin(); it != neutrinosLepB.end();
79  ++it) {
80  if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) {
81  return 520;
82  }
83  }
84  for (std::vector<reco::GenParticle>::const_iterator it = neutrinosLepB_C.begin(); it != neutrinosLepB_C.end();
85  ++it) {
86  if (reco::deltaR2(it->eta(), it->phi(), jet.eta(), jet.phi()) < 0.4 * 0.4) {
87  return 521;
88  }
89  }
90  return 500;
91  } else {
93  if (physflav == 21)
94  return 0;
95  else if (physflav == 3)
96  return 2;
97  else if (physflav == 2 || physflav == 1)
98  return 1;
99  else
100  return 1000;
101  } else
102  return 1000;
103  }
104  } else if (hflav == 4) { //C jet
105  if (ncs > 1) {
106  if (ncFromGSP > 0)
107  return 411;
108  else
109  return 410;
110  } else
111  return 400;
112  } else { //not a heavy jet
113  if (!alltaus.empty()) { //check for tau in a simplistic way
114  bool ishadrtaucontained = true;
115  for (const auto& p : alltaus) {
116  size_t ndau = p.numberOfDaughters();
117  for (size_t i = 0; i < ndau; i++) {
118  const reco::Candidate* dau = p.daughter(i);
119  int daupid = std::abs(dau->pdgId());
120  if (daupid == 13 || daupid == 11) {
121  ishadrtaucontained = false;
122  break;
123  }
124  if (daupid != 12 && daupid != 14 && daupid != 16 && reco::deltaR2(*dau, jet) > jetR_ * jetR_) {
125  ishadrtaucontained = false;
126  break;
127  }
128  }
129  }
130  if (ishadrtaucontained)
131  return 600;
132  }
133  if (std::abs(pflav) == 4 || std::abs(pflav) == 5 || nbs || ncs) {
135  if (physflav == 21)
136  return 0;
137  else if (physflav == 3)
138  return 2;
139  else if (physflav == 2 || physflav == 1)
140  return 1;
141  else
142  return 1000;
143  } else
144  return 1000;
145  } else if (usePhysForLightAndUndefined) {
146  if (physflav == 21)
147  return 0;
148  else if (physflav == 3)
149  return 2;
150  else if (physflav == 2 || physflav == 1)
151  return 1;
152  else
153  return 1000;
154  } else {
155  if (pflav == 21)
156  return 0;
157  else if (pflav == 3)
158  return 2;
159  else if (pflav == 2 || pflav == 1)
160  return 1;
161  else
162  return 1000;
163  }
164  }
165  }
166 
169  desc.add<edm::InputTag>("src")->setComment("input Jet collection");
170  desc.add<edm::InputTag>("genparticles")->setComment("input genparticles info collection");
171  desc.add<std::string>("name")->setComment("name of the genJet FlatTable we are extending with flavour information");
172  descriptions.add("btvMCTable", desc);
173  }
174 
175 private:
176  void produce(edm::Event&, edm::EventSetup const&) override;
177 
179 
181  constexpr static double jetR_ = 0.4;
182 
185 };
186 
187 // ------------ method called to produce the data ------------
189  auto jets = iEvent.getHandle(src_);
190  // const auto& jetFlavourInfosProd = iEvent.get(genParticlesToken_);
191  edm::Handle<reco::GenParticleCollection> genParticlesHandle;
192  iEvent.getByToken(genParticlesToken_, genParticlesHandle);
193  std::vector<reco::GenParticle> neutrinosLepB;
194  std::vector<reco::GenParticle> neutrinosLepB_C;
195 
196  std::vector<reco::GenParticle> gToBB;
197  std::vector<reco::GenParticle> gToCC;
198  std::vector<reco::GenParticle> alltaus;
199 
200  unsigned int nJets = jets->size();
201 
202  std::vector<unsigned> jet_FlavSplit(nJets);
203  for (const reco::Candidate& genC : *genParticlesHandle) {
204  const reco::GenParticle& gen = static_cast<const reco::GenParticle&>(genC);
205  if (abs(gen.pdgId()) == 12 || abs(gen.pdgId()) == 14 || abs(gen.pdgId()) == 16) {
206  const reco::GenParticle* mother = static_cast<const reco::GenParticle*>(gen.mother());
207  if (mother != nullptr) {
208  if ((abs(mother->pdgId()) > 500 && abs(mother->pdgId()) < 600) ||
209  (abs(mother->pdgId()) > 5000 && abs(mother->pdgId()) < 6000)) {
210  neutrinosLepB.emplace_back(gen);
211  }
212  if ((abs(mother->pdgId()) > 400 && abs(mother->pdgId()) < 500) ||
213  (abs(mother->pdgId()) > 4000 && abs(mother->pdgId()) < 5000)) {
214  neutrinosLepB_C.emplace_back(gen);
215  }
216  } else {
217  std::cout << "No mother" << std::endl;
218  }
219  }
220 
221  int id(std::abs(gen.pdgId()));
222  int status(gen.status());
223 
224  if (id == 21 && status >= 21 && status <= 59) {
225  if (gen.numberOfDaughters() == 2) {
226  const reco::Candidate* d0 = gen.daughter(0);
227  const reco::Candidate* d1 = gen.daughter(1);
228  if (std::abs(d0->pdgId()) == 5 && std::abs(d1->pdgId()) == 5 && d0->pdgId() * d1->pdgId() < 0 &&
229  reco::deltaR2(*d0, *d1) < jetR_ * jetR_)
230  gToBB.push_back(gen);
231  if (std::abs(d0->pdgId()) == 4 && std::abs(d1->pdgId()) == 4 && d0->pdgId() * d1->pdgId() < 0 &&
232  reco::deltaR2(*d0, *d1) < jetR_ * jetR_)
233  gToCC.push_back(gen);
234  }
235  }
236 
237  if (id == 15 && false) {
238  alltaus.push_back(gen);
239  }
240  }
241  for (unsigned i_jet = 0; i_jet < nJets; ++i_jet) {
242  // from DeepNTuples
243  const auto& jet = jets->at(i_jet);
244 
245  jet_FlavSplit[i_jet] =
246  jet_flavour(jet, gToBB, gToCC, neutrinosLepB, neutrinosLepB_C, alltaus, usePhysForLightAndUndefined);
247  }
248  auto newtab = std::make_unique<nanoaod::FlatTable>(nJets, name_, false, true);
249  newtab->addColumn<int>("FlavSplit",
250  jet_FlavSplit,
251  "Flavour of the jet, numerical codes: "
252  "isG: 0, "
253  "isUD: 1, "
254  "isS: 2, "
255  "isC: 400, "
256  "isCC: 410, "
257  "isGCC: 411, "
258  "isB: 500, "
259  "isBB: 510, "
260  "isGBB: 511, "
261  "isLeptonicB: 520, "
262  "isLeptonicB_C: 521, "
263  "isTAU: 600, "
264  "isPU: 999,"
265  "isUndefined: 1000. "
266  "May be combined to form coarse labels for tagger training and flavour dependent attacks "
267  "using the loss surface.");
268  iEvent.put(std::move(newtab));
269 }
270 
272 //define this as a plug-in
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
BTVMCFlavourTableProducer(const edm::ParameterSet &iConfig)
edm::EDGetTokenT< std::vector< pat::Jet > > src_
static constexpr bool usePhysForLightAndUndefined
static constexpr int nJets
edm::EDGetTokenT< reco::GenParticleCollection > genParticlesToken_
Definition: HeavyIon.h:7
int pdgId() const final
PDG identifier.
int iEvent
Definition: GenABIO.cc:224
Definition: Jet.py:1
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
virtual int pdgId() const =0
PDG identifier.
static constexpr float d0
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
Analysis-level calorimeter jet class.
Definition: Jet.h:77
void add(std::string const &label, ParameterSetDescription const &psetDescription)
int jet_flavour(const pat::Jet &jet, const std::vector< reco::GenParticle > &gToBB, const std::vector< reco::GenParticle > &gToCC, const std::vector< reco::GenParticle > &neutrinosLepB, const std::vector< reco::GenParticle > &neutrinosLepB_C, const std::vector< reco::GenParticle > &alltaus, bool usePhysForLightAndUndefined)
fixed size matrix
HLT enums.
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
static constexpr float d1
def move(src, dest)
Definition: eostools.py:511
void produce(edm::Event &, edm::EventSetup const &) override