CMS 3D CMS Logo

TtSemiLepJetCombWMassDeltaTopMass.cc
Go to the documentation of this file.
4 
10 
12 
14 public:
16 
17 private:
18  void produce(edm::StreamID, edm::Event& evt, const edm::EventSetup& setup) const override;
19 
20  bool isValid(const int& idx, const std::vector<pat::Jet>& jets) const {
21  return (0 <= idx && idx < (int)jets.size());
22  };
23 
27  int maxNJets_;
28  double wMass_;
34 };
35 
37  : jetsToken_(consumes<std::vector<pat::Jet>>(cfg.getParameter<edm::InputTag>("jets"))),
38  lepsToken_(consumes<edm::View<reco::RecoCandidate>>(cfg.getParameter<edm::InputTag>("leps"))),
39  metsToken_(consumes<std::vector<pat::MET>>(cfg.getParameter<edm::InputTag>("mets"))),
40  maxNJets_(cfg.getParameter<int>("maxNJets")),
41  wMass_(cfg.getParameter<double>("wMass")),
42  useBTagging_(cfg.getParameter<bool>("useBTagging")),
43  bTagAlgorithm_(cfg.getParameter<std::string>("bTagAlgorithm")),
44  minBDiscBJets_(cfg.getParameter<double>("minBDiscBJets")),
45  maxBDiscLightJets_(cfg.getParameter<double>("maxBDiscLightJets")),
46  neutrinoSolutionType_(cfg.getParameter<int>("neutrinoSolutionType")) {
47  if (maxNJets_ < 4 && maxNJets_ != -1)
48  throw cms::Exception("WrongConfig") << "Parameter maxNJets can not be set to " << maxNJets_ << ". \n"
49  << "It has to be larger than 4 or can be set to -1 to take all jets.";
50 
51  produces<std::vector<std::vector<int>>>();
52  produces<int>("NumberOfConsideredJets");
53 }
54 
56  auto pOut = std::make_unique<std::vector<std::vector<int>>>();
57  auto pJetsConsidered = std::make_unique<int>(0);
58 
59  std::vector<int> match;
60  for (unsigned int i = 0; i < 4; ++i)
61  match.push_back(-1);
62 
63  // get jets
64  const auto& jets = evt.get(jetsToken_);
65 
66  // get leptons
67  const auto& leps = evt.get(lepsToken_);
68 
69  // get MET
70  const auto& mets = evt.get(metsToken_);
71 
72  // skip events without lepton candidate or less than 4 jets or no MET
73  if (leps.empty() || jets.size() < 4 || mets.empty()) {
74  pOut->push_back(match);
75  evt.put(std::move(pOut));
76  *pJetsConsidered = jets.size();
77  evt.put(std::move(pJetsConsidered), "NumberOfConsideredJets");
78  return;
79  }
80 
81  unsigned maxNJets = maxNJets_;
82  if (maxNJets_ == -1 || (int)jets.size() < maxNJets_)
83  maxNJets = jets.size();
84  *pJetsConsidered = maxNJets;
85  evt.put(std::move(pJetsConsidered), "NumberOfConsideredJets");
86 
87  std::vector<bool> isBJet;
88  std::vector<bool> isLJet;
89  int cntBJets = 0;
90  if (useBTagging_) {
91  for (unsigned int idx = 0; idx < maxNJets; ++idx) {
92  isBJet.push_back((jets[idx].bDiscriminator(bTagAlgorithm_) > minBDiscBJets_));
93  isLJet.push_back((jets[idx].bDiscriminator(bTagAlgorithm_) < maxBDiscLightJets_));
94  if (jets[idx].bDiscriminator(bTagAlgorithm_) > minBDiscBJets_)
95  cntBJets++;
96  }
97  }
98 
99  // -----------------------------------------------------
100  // associate those jets that get closest to the W mass
101  // with their invariant mass to the hadronic W boson
102  // -----------------------------------------------------
103  double wDist = -1.;
104  std::vector<int> closestToWMassIndices;
105  closestToWMassIndices.push_back(-1);
106  closestToWMassIndices.push_back(-1);
107  for (unsigned idx = 0; idx < maxNJets; ++idx) {
108  if (useBTagging_ && (!isLJet[idx] || (cntBJets <= 2 && isBJet[idx])))
109  continue;
110  for (unsigned jdx = (idx + 1); jdx < maxNJets; ++jdx) {
111  if (useBTagging_ &&
112  (!isLJet[jdx] || (cntBJets <= 2 && isBJet[jdx]) || (cntBJets == 3 && isBJet[idx] && isBJet[jdx])))
113  continue;
114  reco::Particle::LorentzVector sum = jets[idx].p4() + jets[jdx].p4();
115  if (wDist < 0. || wDist > fabs(sum.mass() - wMass_)) {
116  wDist = fabs(sum.mass() - wMass_);
117  closestToWMassIndices.clear();
118  closestToWMassIndices.push_back(idx);
119  closestToWMassIndices.push_back(jdx);
120  }
121  }
122  }
123 
124  // -----------------------------------------------------
125  // build a leptonic W boson from the lepton and the MET
126  // -----------------------------------------------------
127  double neutrino_pz = 0.;
128  if (neutrinoSolutionType_ != -1) {
129  MEzCalculator mez;
130  mez.SetMET(*mets.begin());
131  if (dynamic_cast<const reco::Muon*>(&(leps.front())))
132  mez.SetLepton(leps[0], true);
133  else if (dynamic_cast<const reco::GsfElectron*>(&(leps.front())))
134  mez.SetLepton(leps[0], false);
135  else
136  throw cms::Exception("UnimplementedFeature")
137  << "Type of lepton given together with MET for solving neutrino kinematics is neither muon nor electron.\n";
138  neutrino_pz = mez.Calculate(neutrinoSolutionType_);
139  }
140  const math::XYZTLorentzVector neutrino(mets.begin()->px(),
141  mets.begin()->py(),
142  neutrino_pz,
143  sqrt(mets.begin()->px() * mets.begin()->px() +
144  mets.begin()->py() * mets.begin()->py() + neutrino_pz * neutrino_pz));
145  const reco::Particle::LorentzVector lepW = neutrino + leps.front().p4();
146 
147  // -----------------------------------------------------
148  // associate those jets to the hadronic and the leptonic
149  // b quark that minimize the difference between
150  // hadronic and leptonic top mass
151  // -----------------------------------------------------
152  double deltaTop = -1.;
153  int hadB = -1;
154  int lepB = -1;
155  if (isValid(closestToWMassIndices[0], jets) && isValid(closestToWMassIndices[1], jets)) {
156  const reco::Particle::LorentzVector hadW =
157  jets[closestToWMassIndices[0]].p4() + jets[closestToWMassIndices[1]].p4();
158  // find hadronic b candidate
159  for (unsigned idx = 0; idx < maxNJets; ++idx) {
160  if (useBTagging_ && !isBJet[idx])
161  continue;
162  // make sure it's not used up already from the hadronic W
163  if ((int)idx != closestToWMassIndices[0] && (int)idx != closestToWMassIndices[1]) {
164  reco::Particle::LorentzVector hadTop = hadW + jets[idx].p4();
165  // find leptonic b candidate
166  for (unsigned jdx = 0; jdx < maxNJets; ++jdx) {
167  if (useBTagging_ && !isBJet[jdx])
168  continue;
169  // make sure it's not used up already from the hadronic branch
170  if ((int)jdx != closestToWMassIndices[0] && (int)jdx != closestToWMassIndices[1] && jdx != idx) {
171  reco::Particle::LorentzVector lepTop = lepW + jets[jdx].p4();
172  if (deltaTop < 0. || deltaTop > fabs(hadTop.mass() - lepTop.mass())) {
173  deltaTop = fabs(hadTop.mass() - lepTop.mass());
174  hadB = idx;
175  lepB = jdx;
176  }
177  }
178  }
179  }
180  }
181  }
182 
183  match[TtSemiLepEvtPartons::LightQ] = closestToWMassIndices[0];
184  match[TtSemiLepEvtPartons::LightQBar] = closestToWMassIndices[1];
187 
188  pOut->push_back(match);
189  evt.put(std::move(pOut));
190 }
191 
edm::EDGetTokenT< std::vector< pat::Jet > > jetsToken_
void SetLepton(const pat::Particle &lepton, bool isMuon=true)
Set lepton.
Definition: MEzCalculator.h:31
bool isValid(const int &idx, const std::vector< pat::Jet > &jets) const
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:346
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void produce(edm::StreamID, edm::Event &evt, const edm::EventSetup &setup) const override
Definition: HeavyIon.h:7
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
void SetMET(const pat::MET &MET)
Set MET.
Definition: MEzCalculator.h:25
double Calculate(int type=1)
member functions
Definition: Jet.py:1
T sqrt(T t)
Definition: SSEVec.h:19
edm::EDGetTokenT< edm::View< reco::RecoCandidate > > lepsToken_
TtSemiLepJetCombWMassDeltaTopMass(const edm::ParameterSet &)
fixed size matrix
HLT enums.
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
Definition: Utils.h:10
edm::EDGetTokenT< std::vector< pat::MET > > metsToken_
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:21
def move(src, dest)
Definition: eostools.py:511