CMS 3D CMS Logo

List of all members | Public Member Functions | Private Types | Private Member Functions | Private Attributes
PseudoTopProducer Class Reference

#include <PseudoTopProducer.h>

Inheritance diagram for PseudoTopProducer:
edm::stream::EDProducer<>

Public Member Functions

void produce (edm::Event &event, const edm::EventSetup &eventSetup) override
 
 PseudoTopProducer (const edm::ParameterSet &pset)
 
- Public Member Functions inherited from edm::stream::EDProducer<>
 EDProducer ()=default
 
bool hasAbilityToProduceInLumis () const final
 
bool hasAbilityToProduceInRuns () const final
 

Private Types

typedef fastjet::JetDefinition JetDef
 
typedef reco::Particle::LorentzVector LorentzVector
 

Private Member Functions

reco::GenParticleRef buildGenParticle (const reco::Candidate *p, reco::GenParticleRefProd &refHandle, std::auto_ptr< reco::GenParticleCollection > &outColl) const
 
const reco::CandidategetLast (const reco::Candidate *p)
 
void insertAllDaughters (const reco::Candidate *p, std::set< const reco::Candidate * > &list) const
 
bool isBHadron (const reco::Candidate *p) const
 
bool isBHadron (const unsigned int pdgId) const
 
bool isFromHadron (const reco::Candidate *p) const
 

Private Attributes

const edm::EDGetTokenT< edm::View< reco::Candidate > > finalStateToken_
 
std::shared_ptr< JetDeffjJetDef_
 
std::shared_ptr< JetDeffjLepDef_
 
const edm::EDGetTokenT< edm::View< reco::Candidate > > genParticleToken_
 
reco::Particle::Point genVertex_
 
const double maxJetEta_
 
const double maxLeptonEta_
 
const double maxLeptonEtaDilepton_
 
const double maxLeptonEtaSemilepton_
 
const double maxVetoLeptonEtaSemilepton_
 
const double minDileptonMassDilepton_
 
const double minJetPt_
 
const double minLeptonPt_
 
const double minLeptonPtDilepton_
 
const double minLeptonPtSemilepton_
 
const double minMETSemiLepton_
 
const double minMtWSemiLepton_
 
const double minVetoLeptonPtSemilepton_
 
const double tMass_
 
const double wMass_
 

Additional Inherited Members

- Public Types inherited from edm::stream::EDProducer<>
typedef CacheContexts< T... > CacheTypes
 
typedef CacheTypes::GlobalCache GlobalCache
 
typedef AbilityChecker< T... > HasAbility
 
typedef CacheTypes::LuminosityBlockCache LuminosityBlockCache
 
typedef LuminosityBlockContextT< LuminosityBlockCache, RunCache, GlobalCacheLuminosityBlockContext
 
typedef CacheTypes::LuminosityBlockSummaryCache LuminosityBlockSummaryCache
 
typedef CacheTypes::RunCache RunCache
 
typedef RunContextT< RunCache, GlobalCacheRunContext
 
typedef CacheTypes::RunSummaryCache RunSummaryCache
 

Detailed Description

Definition at line 15 of file PseudoTopProducer.h.

Member Typedef Documentation

typedef fastjet::JetDefinition PseudoTopProducer::JetDef
private

Definition at line 43 of file PseudoTopProducer.h.

Definition at line 30 of file PseudoTopProducer.h.

Constructor & Destructor Documentation

PseudoTopProducer::PseudoTopProducer ( const edm::ParameterSet pset)

Definition at line 13 of file PseudoTopProducer.cc.

References fjJetDef_, fjLepDef_, genVertex_, edm::ParameterSet::getParameter(), particlelevel_cff::jetConeSize, and pseudoTop_cfi::leptonConeSize.

13  :
16  minLeptonPt_(pset.getParameter<double>("minLeptonPt")),
17  maxLeptonEta_(pset.getParameter<double>("maxLeptonEta")),
18  minJetPt_(pset.getParameter<double>("minJetPt")),
19  maxJetEta_(pset.getParameter<double>("maxJetEta")),
20  wMass_(pset.getParameter<double>("wMass")),
21  tMass_(pset.getParameter<double>("tMass")),
22  minLeptonPtDilepton_(pset.getParameter<double>("minLeptonPtDilepton")),
23  maxLeptonEtaDilepton_(pset.getParameter<double>("maxLeptonEtaDilepton")),
24  minDileptonMassDilepton_(pset.getParameter<double>("minDileptonMassDilepton")),
25  minLeptonPtSemilepton_(pset.getParameter<double>("minLeptonPtSemilepton")),
26  maxLeptonEtaSemilepton_(pset.getParameter<double>("maxLeptonEtaSemilepton")),
27  minVetoLeptonPtSemilepton_(pset.getParameter<double>("minVetoLeptonPtSemilepton")),
28  maxVetoLeptonEtaSemilepton_(pset.getParameter<double>("maxVetoLeptonEtaSemilepton")),
29  minMETSemiLepton_(pset.getParameter<double>("minMETSemiLepton")),
30  minMtWSemiLepton_(pset.getParameter<double>("minMtWSemiLepton"))
31 {
32  const double leptonConeSize = pset.getParameter<double>("leptonConeSize");
33  const double jetConeSize = pset.getParameter<double>("jetConeSize");
34  fjLepDef_ = std::make_shared<JetDef>(fastjet::antikt_algorithm, leptonConeSize);
35  fjJetDef_ = std::make_shared<JetDef>(fastjet::antikt_algorithm, jetConeSize);
36 
38 
39  produces<reco::GenParticleCollection>("neutrinos");
40  produces<reco::GenJetCollection>("leptons");
41  produces<reco::GenJetCollection>("jets");
42 
43  produces<reco::GenParticleCollection>();
44 
45 }
const edm::EDGetTokenT< edm::View< reco::Candidate > > genParticleToken_
T getParameter(std::string const &) const
reco::Particle::Point genVertex_
const double maxLeptonEtaSemilepton_
const double maxLeptonEta_
const double minVetoLeptonPtSemilepton_
const double maxLeptonEtaDilepton_
std::shared_ptr< JetDef > fjJetDef_
std::shared_ptr< JetDef > fjLepDef_
const double minMtWSemiLepton_
const double minMETSemiLepton_
const double maxJetEta_
const double minLeptonPtSemilepton_
math::XYZPoint Point
point in the space
Definition: Particle.h:25
const double maxVetoLeptonEtaSemilepton_
const double minLeptonPt_
const double minDileptonMassDilepton_
const edm::EDGetTokenT< edm::View< reco::Candidate > > finalStateToken_
const double minLeptonPtDilepton_
const double minJetPt_

Member Function Documentation

reco::GenParticleRef PseudoTopProducer::buildGenParticle ( const reco::Candidate p,
reco::GenParticleRefProd refHandle,
std::auto_ptr< reco::GenParticleCollection > &  outColl 
) const
private

Definition at line 508 of file PseudoTopProducer.cc.

References reco::CompositeRefCandidateT< D >::clearDaughters(), reco::CompositeRefCandidateT< D >::clearMothers(), edm::RefProd< C >::id(), reco::CompositeRefCandidateT< D >::resetDaughters(), and reco::CompositeRefCandidateT< D >::resetMothers().

510 {
511  reco::GenParticle pOut(*dynamic_cast<const reco::GenParticle*>(p));
512  pOut.clearMothers();
513  pOut.clearDaughters();
514  pOut.resetMothers(refHandle.id());
515  pOut.resetDaughters(refHandle.id());
516 
517  outColl->push_back(pOut);
518 
519  return reco::GenParticleRef(refHandle, outColl->size()-1);
520 }
edm::Ref< GenParticleCollection > GenParticleRef
persistent reference to a GenParticle
ProductID id() const
Accessor for product ID.
Definition: RefProd.h:137
const reco::Candidate * PseudoTopProducer::getLast ( const reco::Candidate p)
private

Definition at line 448 of file PseudoTopProducer.cc.

References reco::Candidate::daughter(), mps_fire::i, gen::n, reco::Candidate::numberOfDaughters(), AlCaHLTBitMon_ParallelJobs::p, and reco::Candidate::pdgId().

449 {
450  for ( size_t i=0, n=p->numberOfDaughters(); i<n; ++i )
451  {
452  const reco::Candidate* dau = p->daughter(i);
453  if ( p->pdgId() == dau->pdgId() ) return getLast(dau);
454  }
455  return p;
456 }
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
virtual int pdgId() const =0
PDG identifier.
const reco::Candidate * getLast(const reco::Candidate *p)
virtual size_type numberOfDaughters() const =0
number of daughters
void PseudoTopProducer::insertAllDaughters ( const reco::Candidate p,
std::set< const reco::Candidate * > &  list 
) const
private
bool PseudoTopProducer::isBHadron ( const reco::Candidate p) const
private

Definition at line 473 of file PseudoTopProducer.cc.

References funct::abs(), reco::Candidate::daughter(), mps_fire::i, gen::n, reco::Candidate::numberOfDaughters(), and reco::Candidate::pdgId().

Referenced by produce().

474 {
475  const unsigned int absPdgId = abs(p->pdgId());
476  if ( !isBHadron(absPdgId) ) return false;
477 
478  // Do not consider this particle if it has B hadron daughter
479  // For example, B* -> B0 + photon; then we drop B* and take B0 only
480  for ( int i=0, n=p->numberOfDaughters(); i<n; ++i )
481  {
482  const reco::Candidate* dau = p->daughter(i);
483  if ( isBHadron(abs(dau->pdgId())) ) return false;
484  }
485 
486  return true;
487 }
bool isBHadron(const reco::Candidate *p) const
virtual const Candidate * daughter(size_type i) const =0
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
virtual int pdgId() const =0
PDG identifier.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
virtual size_type numberOfDaughters() const =0
number of daughters
bool PseudoTopProducer::isBHadron ( const unsigned int  pdgId) const
private

Definition at line 489 of file PseudoTopProducer.cc.

490 {
491  if ( absPdgId <= 100 ) return false; // Fundamental particles and MC internals
492  if ( absPdgId >= 1000000000 ) return false; // Nuclei, +-10LZZZAAAI
493 
494  // General form of PDG ID is 7 digit form
495  // +- n nr nL nq1 nq2 nq3 nJ
496  //const int nJ = absPdgId % 10; // Spin
497  const int nq3 = (absPdgId / 10) % 10;
498  const int nq2 = (absPdgId / 100) % 10;
499  const int nq1 = (absPdgId / 1000) % 10;
500 
501  if ( nq3 == 0 ) return false; // Diquarks
502  if ( nq1 == 0 and nq2 == 5 ) return true; // B mesons
503  if ( nq1 == 5 ) return true; // B baryons
504 
505  return false;
506 }
bool PseudoTopProducer::isFromHadron ( const reco::Candidate p) const
private

Definition at line 458 of file PseudoTopProducer.cc.

References funct::abs(), mps_fire::i, reco::Candidate::mother(), gen::n, reco::Candidate::numberOfMothers(), or, common_cff::pdgId, reco::Candidate::pdgId(), and reco::Candidate::status().

Referenced by produce().

459 {
460  for ( size_t i=0, n=p->numberOfMothers(); i<n; ++i )
461  {
462  const reco::Candidate* mother = p->mother(i);
463  if ( !mother ) continue;
464  if ( mother->status() == 4 or mother->numberOfMothers() == 0 ) continue; // Skip incident beam
465  const int pdgId = abs(mother->pdgId());
466 
467  if ( pdgId > 100 ) return true;
468  else if ( isFromHadron(mother) ) return true;
469  }
470  return false;
471 }
bool isFromHadron(const reco::Candidate *p) const
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
virtual int status() const =0
status word
virtual int pdgId() const =0
PDG identifier.
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::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void PseudoTopProducer::produce ( edm::Event event,
const edm::EventSetup eventSetup 
)
override

Build jets

Definition at line 47 of file PseudoTopProducer.cc.

References funct::abs(), reco::CompositeRefCandidateT< D >::addDaughter(), RazorAnalyzer::bJet1, RazorAnalyzer::bJet2, reco::Candidate::charge(), funct::cos(), deltaR(), symbols::dm, PFRecoTauDiscriminationAgainstElectronDeadECAL_cfi::dR, MillePedeFileConverter_cfg::e, reco::Candidate::energy(), finalStateToken_, fjJetDef_, fjLepDef_, genParticleToken_, genVertex_, mps_fire::i, isBHadron(), isFromHadron(), edm::detail::isnan(), edm::Ptr< T >::isNonnull(), edm::Ptr< T >::isNull(), fwrapper::jets, AK4GenJetFlavourInfos_cfi::leptons, funct::m, ResonanceBuilder::mass, maxJetEta_, maxLeptonEta_, maxLeptonEtaDilepton_, maxLeptonEtaSemilepton_, maxVetoLeptonEtaSemilepton_, minDileptonMassDilepton_, electronTrackIsolations_cfi::minDR, minJetPt_, minLeptonPt_, minLeptonPtDilepton_, minLeptonPtSemilepton_, minMETSemiLepton_, minMtWSemiLepton_, minVetoLeptonPtSemilepton_, reco::Candidate::mother(), eostools::move(), gen::n, TtSemiLepHypHitFit_cfi::neutrinos, GetRecoTauVFromDQM_MC_cff::next, reco::Candidate::numberOfMothers(), or, reco::Candidate::p(), AlCaHLTBitMon_ParallelJobs::p, reco::Candidate::p4(), reco::Candidate::pdgId(), pseudoTop_cfi::pseudoTop, reco::Candidate::pt(), reco::Candidate::px(), reco::LeafCandidate::px(), reco::Candidate::py(), reco::Candidate::pz(), lumiQueryAPI::q, q1, q2, Scenarios_cff::scale, mathSSE::sqrt(), mps_update::status, reco::Candidate::status(), reco::t2, tMass_, MetAnalyzer::u2, reco::Candidate::vertex(), w2, wMass_, and reco::writeSpecific().

48 {
49  edm::Handle<edm::View<reco::Candidate> > finalStateHandle;
50  event.getByToken(finalStateToken_, finalStateHandle);
51 
52  edm::Handle<edm::View<reco::Candidate> > genParticleHandle;
53  event.getByToken(genParticleToken_, genParticleHandle);
54 
55  std::unique_ptr<reco::GenParticleCollection> neutrinos(new reco::GenParticleCollection);
56  std::unique_ptr<reco::GenJetCollection> leptons(new reco::GenJetCollection);
57  std::unique_ptr<reco::GenJetCollection> jets(new reco::GenJetCollection);
58  auto neutrinosRefHandle = event.getRefBeforePut<reco::GenParticleCollection>("neutrinos");
59  auto leptonsRefHandle = event.getRefBeforePut<reco::GenJetCollection>("leptons");
60  auto jetsRefHandle = event.getRefBeforePut<reco::GenJetCollection>("jets");
61 
62  std::unique_ptr<reco::GenParticleCollection> pseudoTop(new reco::GenParticleCollection);
63  auto pseudoTopRefHandle = event.getRefBeforePut<reco::GenParticleCollection>();
64 
65  // Collect unstable B-hadrons
66  std::set<int> bHadronIdxs;
67  for ( size_t i=0, n=genParticleHandle->size(); i<n; ++i ) {
68  const reco::Candidate& p = genParticleHandle->at(i);
69  const int status = p.status();
70  if ( status == 1 ) continue;
71 
72  // Collect B-hadrons, to be used in b tagging
73  if ( isBHadron(&p) ) bHadronIdxs.insert(-i-1);
74  }
75 
76  // Collect stable leptons and neutrinos
77  size_t nStables = 0;
78  std::vector<size_t> leptonIdxs;
79  for ( size_t i=0, n=finalStateHandle->size(); i<n; ++i ) {
80  const reco::Candidate& p = finalStateHandle->at(i);
81  const int absPdgId = abs(p.pdgId());
82  if ( p.status() != 1 ) continue;
83 
84  ++nStables;
85  if ( p.numberOfMothers() == 0 ) continue; // Skip orphans (if exists)
86  if ( p.mother()->status() == 4 ) continue; // Treat particle as hadronic if directly from the incident beam (protect orphans in MINIAOD)
87  if ( isFromHadron(&p) ) continue;
88  switch ( absPdgId ) {
89  case 11: case 13: // Leptons
90  case 22: // Photons
91  leptonIdxs.push_back(i);
92  break;
93  case 12: case 14: case 16:
94  neutrinos->push_back(reco::GenParticle(p.charge(), p.p4(), p.vertex(), p.pdgId(), p.status(), true));
95  break;
96  }
97  }
98 
99  // Sort neutrinos by pT.
100  std::sort(neutrinos->begin(), neutrinos->end(), GreaterByPt<reco::Candidate>());
101 
102  // Make dressed leptons with anti-kt(0.1) algorithm
104  std::vector<fastjet::PseudoJet> fjLepInputs;
105  fjLepInputs.reserve(leptonIdxs.size());
106  for ( auto index : leptonIdxs ) {
107  const reco::Candidate& p = finalStateHandle->at(index);
108  if ( std::isnan(p.pt()) or p.pt() <= 0 ) continue;
109 
110  fjLepInputs.push_back(fastjet::PseudoJet(p.px(), p.py(), p.pz(), p.energy()));
111  fjLepInputs.back().set_user_index(index);
112  }
113 
115  fastjet::ClusterSequence fjLepClusterSeq(fjLepInputs, *fjLepDef_);
116  std::vector<fastjet::PseudoJet> fjLepJets = fastjet::sorted_by_pt(fjLepClusterSeq.inclusive_jets(minLeptonPt_));
117 
119  leptons->reserve(fjLepJets.size());
120  std::set<size_t> lepDauIdxs; // keep lepton constituents to remove from GenJet construction
121  for ( auto& fjJet : fjLepJets ) {
122  if ( abs(fjJet.eta()) > maxLeptonEta_ ) continue;
123 
124  // Get jet constituents from fastJet
125  const std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
126  // Convert to CandidatePtr
127  std::vector<reco::CandidatePtr> constituents;
128  reco::CandidatePtr lepCand;
129  for ( auto& fjConstituent : fjConstituents ) {
130  const size_t index = fjConstituent.user_index();
131  reco::CandidatePtr cand = finalStateHandle->ptrAt(index);
132  const int absPdgId = abs(cand->pdgId());
133  if ( absPdgId == 11 or absPdgId == 13 ) {
134  if ( lepCand.isNonnull() and lepCand->pt() > cand->pt() ) continue; // Choose one with highest pt
135  lepCand = cand;
136  }
137  constituents.push_back(cand);
138  }
139  if ( lepCand.isNull() ) continue;
140 
141  const LorentzVector jetP4(fjJet.px(), fjJet.py(), fjJet.pz(), fjJet.E());
142  reco::GenJet lepJet;
143  reco::writeSpecific(lepJet, jetP4, genVertex_, constituents, eventSetup);
144 
145  lepJet.setPdgId(lepCand->pdgId());
146  lepJet.setCharge(lepCand->charge());
147 
148  const double jetArea = fjJet.has_area() ? fjJet.area() : 0;
149  lepJet.setJetArea(jetArea);
150 
151  leptons->push_back(lepJet);
152 
153  // Keep constituent indices to be used in the next step.
154  for ( auto& fjConstituent : fjConstituents ) {
155  lepDauIdxs.insert(fjConstituent.user_index());
156  }
157  }
158 
159  // Now proceed to jets.
160  // Jets: anti-kt excluding the e, mu, nu, and photons in selected leptons.
162  std::vector<fastjet::PseudoJet> fjJetInputs;
163  fjJetInputs.reserve(nStables);
164  for ( size_t i=0, n=finalStateHandle->size(); i<n; ++i ) {
165  const reco::Candidate& p = finalStateHandle->at(i);
166  if ( p.status() != 1 ) continue;
167  if ( std::isnan(p.pt()) or p.pt() <= 0 ) continue;
168 
169  const int absId = std::abs(p.pdgId());
170  if ( absId == 12 or absId == 14 or absId == 16 ) continue;
171  if ( lepDauIdxs.find(i) != lepDauIdxs.end() ) continue;
172 
173  fjJetInputs.push_back(fastjet::PseudoJet(p.px(), p.py(), p.pz(), p.energy()));
174  fjJetInputs.back().set_user_index(i);
175  }
177  for ( auto index : bHadronIdxs ) {
178  const reco::Candidate& p = genParticleHandle->at(abs(index+1));
179  if ( std::isnan(p.pt()) or p.pt() <= 0 ) continue;
180 
181  const double scale = 1e-20/p.p();
182  fjJetInputs.push_back(fastjet::PseudoJet(p.px()*scale, p.py()*scale, p.pz()*scale, p.energy()*scale));
183  fjJetInputs.back().set_user_index(index);
184  }
185 
187  fastjet::ClusterSequence fjJetClusterSeq(fjJetInputs, *fjJetDef_);
188  std::vector<fastjet::PseudoJet> fjJets = fastjet::sorted_by_pt(fjJetClusterSeq.inclusive_jets(minJetPt_));
189 
191  jets->reserve(fjJets.size());
192  std::vector<size_t> bjetIdxs, ljetIdxs;
193  for ( auto& fjJet : fjJets ) {
194  if ( abs(fjJet.eta()) > maxJetEta_ ) continue;
195 
196  // Get jet constituents from fastJet
197  const std::vector<fastjet::PseudoJet> fjConstituents = fastjet::sorted_by_pt(fjJet.constituents());
198  // Convert to CandidatePtr
199  std::vector<reco::CandidatePtr> constituents;
200  bool hasBHadron = false;
201  for ( size_t j=0, m=fjConstituents.size(); j<m; ++j ) {
202  const int index = fjConstituents[j].user_index();
203  if ( bHadronIdxs.find(index) != bHadronIdxs.end() ) {
204  hasBHadron = true;
205  continue;
206  }
207  reco::CandidatePtr cand = finalStateHandle->ptrAt(index);
208  constituents.push_back(cand);
209  }
210 
211  const LorentzVector jetP4(fjJet.px(), fjJet.py(), fjJet.pz(), fjJet.E());
212  reco::GenJet genJet;
213  reco::writeSpecific(genJet, jetP4, genVertex_, constituents, eventSetup);
214 
215  const double jetArea = fjJet.has_area() ? fjJet.area() : 0;
216  genJet.setJetArea(jetArea);
217  if ( hasBHadron ) {
218  genJet.setPdgId(5);
219  bjetIdxs.push_back(jets->size());
220  }
221  else {
222  ljetIdxs.push_back(jets->size());
223  }
224 
225  jets->push_back(genJet);
226  }
227 
228  // Every building blocks are ready. Continue to pseudo-W and pseudo-top combination
229  // NOTE : A C++ trick, use do-while instead of long-nested if-statements.
230  do {
231  if ( bjetIdxs.size() < 2 ) break;
232 
233  // Note : we will do dilepton or semilepton channel only
234  if ( leptons->size() == 2 and neutrinos->size() >= 2 ) {
235  // Start from dilepton channel
236  const int q1 = leptons->at(0).charge();
237  const int q2 = leptons->at(1).charge();
238  if ( q1*q2 > 0 ) break;
239 
240  const auto& lepton1 = q1 > 0 ? leptons->at(0) : leptons->at(1);
241  const auto& lepton2 = q1 > 0 ? leptons->at(1) : leptons->at(0);
242 
243  if ( lepton1.pt() < minLeptonPtDilepton_ or std::abs(lepton1.eta()) > maxLeptonEtaDilepton_ ) break;
244  if ( lepton2.pt() < minLeptonPtDilepton_ or std::abs(lepton2.eta()) > maxLeptonEtaDilepton_ ) break;
245  if ( (lepton1.p4()+lepton2.p4()).mass() < minDileptonMassDilepton_ ) break;
246 
247  double dm = 1e9;
248  int selNu1 = -1, selNu2 = -1;
249  for ( int i=0; i<2; ++i ) { // Consider leading 2 neutrinos. Neutrino vector is already sorted by pT
250  const double dm1 = std::abs((lepton1.p4()+neutrinos->at(i).p4()).mass()-wMass_);
251  for ( int j=0; j<2; ++j ) {
252  if ( i == j ) continue;
253  const double dm2 = std::abs((lepton2.p4()+neutrinos->at(j).p4()).mass()-wMass_);
254  const double newDm = dm1+dm2;
255 
256  if ( newDm < dm ) { dm = newDm; selNu1 = i; selNu2 = j; }
257  }
258  }
259  if ( dm >= 1e9 ) break;
260 
261  const auto& nu1 = neutrinos->at(selNu1);
262  const auto& nu2 = neutrinos->at(selNu2);
263  const auto w1LVec = lepton1.p4()+nu1.p4();
264  const auto w2LVec = lepton2.p4()+nu2.p4();
265 
266  // Contiue to top quarks
267  dm = 1e9; // Reset once again for top combination.
268  int selB1 = -1, selB2 = -1;
269  for ( auto i : bjetIdxs ) {
270  const double dm1 = std::abs((w1LVec+jets->at(i).p4()).mass()-tMass_);
271  for ( auto j : bjetIdxs ) {
272  if ( i == j ) continue;
273  const double dm2 = std::abs((w2LVec+jets->at(j).p4()).mass()-tMass_);
274  const double newDm = dm1+dm2;
275 
276  if ( newDm < dm ) { dm = newDm; selB1 = i; selB2 = j; }
277  }
278  }
279  if ( dm >= 1e9 ) break;
280 
281  const auto& bJet1 = jets->at(selB1);
282  const auto& bJet2 = jets->at(selB2);
283  const auto t1LVec = w1LVec + bJet1.p4();
284  const auto t2LVec = w2LVec + bJet2.p4();
285 
286  // Recalculate lepton charges (needed due to initialization of leptons wrt sign of a charge)
287  const int lepQ1 = lepton1.charge();
288  const int lepQ2 = lepton2.charge();
289 
290  // Put all of them into candidate collection
291  reco::GenParticle t1(lepQ1*2/3., t1LVec, genVertex_, lepQ1*6, 3, false);
292  reco::GenParticle w1(lepQ1, w1LVec, genVertex_, lepQ1*24, 3, true);
293  reco::GenParticle b1(-lepQ1/3., bJet1.p4(), genVertex_, lepQ1*5, 1, true);
294  reco::GenParticle l1(lepQ1, lepton1.p4(), genVertex_, lepton1.pdgId(), 1, true);
295  reco::GenParticle n1(0, nu1.p4(), genVertex_, nu1.pdgId(), 1, true);
296 
297  reco::GenParticle t2(lepQ2*2/3., t2LVec, genVertex_, lepQ2*6, 3, false);
298  reco::GenParticle w2(lepQ2, w2LVec, genVertex_, lepQ2*24, 3, true);
299  reco::GenParticle b2(-lepQ2/3., bJet2.p4(), genVertex_, lepQ2*5, 1, true);
300  reco::GenParticle l2(lepQ2, lepton2.p4(), genVertex_, lepton2.pdgId(), 1, true);
301  reco::GenParticle n2(0, nu2.p4(), genVertex_, nu2.pdgId(), 1, true);
302 
303  pseudoTop->push_back(t1);
304  pseudoTop->push_back(t2);
305 
306  pseudoTop->push_back(w1);
307  pseudoTop->push_back(b1);
308  pseudoTop->push_back(l1);
309  pseudoTop->push_back(n1);
310 
311  pseudoTop->push_back(w2);
312  pseudoTop->push_back(b2);
313  pseudoTop->push_back(l2);
314  pseudoTop->push_back(n2);
315  }
316  else if ( !leptons->empty() and !neutrinos->empty() and ljetIdxs.size() >= 2 ) {
317  // Then continue to the semi-leptonic channel
318  const auto& lepton = leptons->at(0);
319  if ( lepton.pt() < minLeptonPtSemilepton_ or std::abs(lepton.eta()) > maxLeptonEtaSemilepton_ ) break;
320 
321  // Skip event if there are veto leptons
322  bool hasVetoLepton = false;
323  for ( auto vetoLeptonItr = next(leptons->begin()); vetoLeptonItr != leptons->end(); ++vetoLeptonItr ) {
324  if ( vetoLeptonItr->pt() > minVetoLeptonPtSemilepton_ and
325  std::abs(vetoLeptonItr->eta()) < maxVetoLeptonEtaSemilepton_ ) {
326  hasVetoLepton = true;
327  }
328  }
329  if ( hasVetoLepton ) break;
330 
331  // Calculate MET
332  double metX = 0, metY = 0;
333  for ( auto neutrino : *neutrinos ) {
334  metX += neutrino.px();
335  metY += neutrino.py();
336  }
337  const double metPt = std::hypot(metX, metY);
338  if ( metPt < minMETSemiLepton_ ) break;
339 
340  const double mtW = std::sqrt( 2*lepton.pt()*metPt*cos(lepton.phi()-atan2(metX, metY)) );
341  if ( mtW < minMtWSemiLepton_ ) break;
342 
343  // Solve pz to give wMass_^2 = (lepE+energy)^2 - (lepPx+metX)^2 - (lepPy+metY)^2 - (lepPz+pz)^2
344  // -> (wMass_^2)/2 = lepE*sqrt(metPt^2+pz^2) - lepPx*metX - lepPy*metY - lepPz*pz
345  // -> C := (wMass_^2)/2 + lepPx*metX + lepPy*metY
346  // -> lepE^2*(metPt^2+pz^2) = C^2 + 2*C*lepPz*pz + lepPz^2*pz^2
347  // -> (lepE^2-lepPz^2)*pz^2 - 2*C*lepPz*pz - C^2 + lepE^2*metPt^2 = 0
348  // -> lepPt^2*pz^2 - 2*C*lepPz*pz - C^2 + lepE^2*metPt^2 = 0
349  const double lpz = lepton.pz(), le = lepton.energy(), lpt = lepton.pt();
350  const double cf = (wMass_*wMass_)/2 + lepton.px()*metX + lepton.py()*metY;
351  const double det = cf*cf*lpz*lpz - lpt*lpt*(le*le*metPt*metPt - cf*cf);
352  const double pz = (cf*lpz + (cf < 0 ? -sqrt(det) : sqrt(det)))/lpt/lpt;
353  const reco::Candidate::LorentzVector nu1P4(metX, metY, pz, std::hypot(metPt, pz));
354  const auto w1LVec = lepton.p4()+nu1P4;
355 
356  // Continue to build leptonic pseudo top
357  double minDR = 1e9;
358  int selB1 = -1;
359  for ( auto b1Itr = bjetIdxs.begin(); b1Itr != bjetIdxs.end(); ++b1Itr ) {
360  const double dR = deltaR(jets->at(*b1Itr).p4(), w1LVec);
361  if ( dR < minDR ) { selB1 = *b1Itr; minDR = dR; }
362  }
363  if ( selB1 == -1 ) break;
364  const auto& bJet1 = jets->at(selB1);
365  const auto t1LVec = w1LVec + bJet1.p4();
366 
367  // Build hadronic pseudo W, take leading two jets (ljetIdxs are (implicitly) sorted by pT)
368  const auto& wJet1 = jets->at(ljetIdxs[0]);
369  const auto& wJet2 = jets->at(ljetIdxs[1]);
370  const auto w2LVec = wJet1.p4() + wJet2.p4();
371 
372  // Contiue to top quarks
373  double dm = 1e9;
374  int selB2 = -1;
375  for ( auto i : bjetIdxs ) {
376  if ( int(i) == selB1 ) continue;
377  const double newDm = std::abs((w2LVec+jets->at(i).p4()).mass()-tMass_);
378  if ( newDm < dm ) { dm = newDm; selB2 = i; }
379  }
380  if ( dm >= 1e9 ) break;
381 
382  const auto& bJet2 = jets->at(selB2);
383  const auto t2LVec = w2LVec + bJet2.p4();
384 
385  const int q = lepton.charge();
386  // Put all of them into candidate collection
387  reco::GenParticle t1(q*2/3., t1LVec, genVertex_, q*6, 3, false);
388  reco::GenParticle w1(q, w1LVec, genVertex_, q*24, 3, true);
389  reco::GenParticle b1(-q/3., bJet1.p4(), genVertex_, q*5, 1, true);
390  reco::GenParticle l1(q, lepton.p4(), genVertex_, lepton.pdgId(), 1, true);
391  reco::GenParticle n1(0, nu1P4, genVertex_, q*(std::abs(lepton.pdgId())+1), 1, true);
392 
393  reco::GenParticle t2(-q*2/3., t2LVec, genVertex_, -q*6, 3, false);
394  reco::GenParticle w2(-q, w2LVec, genVertex_, -q*24, 3, true);
395  reco::GenParticle b2(0, bJet2.p4(), genVertex_, -q*5, 1, true);
396  reco::GenParticle u2(0, wJet1.p4(), genVertex_, -2*q, 1, true);
397  reco::GenParticle d2(0, wJet2.p4(), genVertex_, q, 1, true);
398 
399  pseudoTop->push_back(t1);
400  pseudoTop->push_back(t2);
401 
402  pseudoTop->push_back(w1);
403  pseudoTop->push_back(b1);
404  pseudoTop->push_back(l1);
405  pseudoTop->push_back(n1);
406 
407  pseudoTop->push_back(w2);
408  pseudoTop->push_back(b2);
409  pseudoTop->push_back(u2);
410  pseudoTop->push_back(d2);
411  }
412  } while (false);
413 
414  if ( pseudoTop->size() == 10 ) // If pseudtop decay tree is completed
415  {
416  // t->W+b
417  pseudoTop->at(0).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 2)); // t->W
418  pseudoTop->at(0).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 3)); // t->b
419  pseudoTop->at(2).addMother(reco::GenParticleRef(pseudoTopRefHandle, 0)); // t->W
420  pseudoTop->at(3).addMother(reco::GenParticleRef(pseudoTopRefHandle, 0)); // t->b
421 
422  // W->lv or W->jj
423  pseudoTop->at(2).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 4));
424  pseudoTop->at(2).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 5));
425  pseudoTop->at(4).addMother(reco::GenParticleRef(pseudoTopRefHandle, 2));
426  pseudoTop->at(5).addMother(reco::GenParticleRef(pseudoTopRefHandle, 2));
427 
428  // tbar->W-b
429  pseudoTop->at(1).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 6));
430  pseudoTop->at(1).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 7));
431  pseudoTop->at(6).addMother(reco::GenParticleRef(pseudoTopRefHandle, 1));
432  pseudoTop->at(7).addMother(reco::GenParticleRef(pseudoTopRefHandle, 1));
433 
434  // W->jj
435  pseudoTop->at(6).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 8));
436  pseudoTop->at(6).addDaughter(reco::GenParticleRef(pseudoTopRefHandle, 9));
437  pseudoTop->at(8).addMother(reco::GenParticleRef(pseudoTopRefHandle, 6));
438  pseudoTop->at(9).addMother(reco::GenParticleRef(pseudoTopRefHandle, 6));
439  }
440 
441  event.put(std::move(neutrinos), "neutrinos");
442  event.put(std::move(leptons), "leptons");
443  event.put(std::move(jets), "jets");
444 
445  event.put(std::move(pseudoTop));
446 }
const edm::EDGetTokenT< edm::View< reco::Candidate > > genParticleToken_
bool isBHadron(const reco::Candidate *p) const
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
reco::Particle::Point genVertex_
virtual double pz() const =0
z coordinate of momentum vector
const double maxLeptonEtaSemilepton_
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
const double maxLeptonEta_
const double minVetoLeptonPtSemilepton_
const double maxLeptonEtaDilepton_
std::shared_ptr< JetDef > fjJetDef_
std::vector< GenJet > GenJetCollection
collection of GenJet objects
bool isFromHadron(const reco::Candidate *p) const
virtual const Candidate * mother(size_type i=0) const =0
return pointer to mother
std::shared_ptr< JetDef > fjLepDef_
const double minMtWSemiLepton_
const double minMETSemiLepton_
double q2[4]
Definition: TauolaWrapper.h:88
const double maxJetEta_
const double minLeptonPtSemilepton_
virtual int status() const =0
status word
virtual double energy() const =0
energy
virtual double py() const =0
y coordinate of momentum vector
bJet1
do the razor with one or two b jets (medium CSV)
auto const T2 &decltype(t1.eta()) t2
Definition: deltaR.h:16
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
bool isnan(float x)
Definition: math.h:13
virtual int pdgId() const =0
PDG identifier.
T sqrt(T t)
Definition: SSEVec.h:18
vector< PseudoJet > jets
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::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
virtual size_type numberOfMothers() const =0
number of mothers (zero or one in most of but not all the cases)
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
bool isNull() const
Checks for null.
Definition: Ptr.h:164
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
Jets made from MC generator particles.
Definition: GenJet.h:24
math::XYZTLorentzVector LorentzVector
virtual double p() const =0
magnitude of momentum vector
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:168
double deltaR(double eta1, double eta2, double phi1, double phi2)
Definition: TreeUtility.cc:17
virtual double pt() const =0
transverse momentum
double q1[4]
Definition: TauolaWrapper.h:87
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
virtual int charge() const =0
electric charge
const double maxVetoLeptonEtaSemilepton_
const double minLeptonPt_
virtual const Point & vertex() const =0
vertex position
const double minDileptonMassDilepton_
virtual double px() const =0
x coordinate of momentum vector
const edm::EDGetTokenT< edm::View< reco::Candidate > > finalStateToken_
const double minLeptonPtDilepton_
const double minJetPt_
def move(src, dest)
Definition: eostools.py:510
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)
Definition: JetSpecific.cc:41

Member Data Documentation

const edm::EDGetTokenT<edm::View<reco::Candidate> > PseudoTopProducer::finalStateToken_
private

Definition at line 33 of file PseudoTopProducer.h.

Referenced by produce().

std::shared_ptr<JetDef> PseudoTopProducer::fjJetDef_
private

Definition at line 44 of file PseudoTopProducer.h.

Referenced by produce(), and PseudoTopProducer().

std::shared_ptr<JetDef> PseudoTopProducer::fjLepDef_
private

Definition at line 44 of file PseudoTopProducer.h.

Referenced by produce(), and PseudoTopProducer().

const edm::EDGetTokenT<edm::View<reco::Candidate> > PseudoTopProducer::genParticleToken_
private

Definition at line 34 of file PseudoTopProducer.h.

Referenced by produce().

reco::Particle::Point PseudoTopProducer::genVertex_
private

Definition at line 45 of file PseudoTopProducer.h.

Referenced by produce(), and PseudoTopProducer().

const double PseudoTopProducer::maxJetEta_
private

Definition at line 35 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::maxLeptonEta_
private

Definition at line 35 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::maxLeptonEtaDilepton_
private

Definition at line 37 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::maxLeptonEtaSemilepton_
private

Definition at line 39 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::maxVetoLeptonEtaSemilepton_
private

Definition at line 40 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minDileptonMassDilepton_
private

Definition at line 38 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minJetPt_
private

Definition at line 35 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minLeptonPt_
private

Definition at line 35 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minLeptonPtDilepton_
private

Definition at line 37 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minLeptonPtSemilepton_
private

Definition at line 39 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minMETSemiLepton_
private

Definition at line 41 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minMtWSemiLepton_
private

Definition at line 41 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::minVetoLeptonPtSemilepton_
private

Definition at line 40 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::tMass_
private

Definition at line 36 of file PseudoTopProducer.h.

Referenced by produce().

const double PseudoTopProducer::wMass_
private

Definition at line 36 of file PseudoTopProducer.h.

Referenced by produce().