File indexing completed on 2024-04-06 12:31:14
0001 #include "AnalysisDataFormats/TopObjects/interface/TtDilepEvtSolution.h"
0002 #include "DataFormats/Math/interface/deltaR.h"
0003 #include "DataFormats/Candidate/interface/Candidate.h"
0004
0005 #include "FWCore/Framework/interface/stream/EDProducer.h"
0006 #include "FWCore/Framework/interface/Event.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0009 #include "FWCore/Utilities/interface/InputTag.h"
0010
0011 #include "TopQuarkAnalysis/TopKinFitter/interface/TtFullLepKinSolver.h"
0012 #include "TopQuarkAnalysis/TopEventSelection/interface/TtDilepLRSignalSelObservables.h"
0013
0014 #include <memory>
0015 #include <string>
0016 #include <vector>
0017
0018 class TtDilepEvtSolutionMaker : public edm::stream::EDProducer<> {
0019 public:
0020 explicit TtDilepEvtSolutionMaker(const edm::ParameterSet& iConfig);
0021 ~TtDilepEvtSolutionMaker() override;
0022
0023 void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0024
0025 private:
0026
0027 inline bool PTComp(const reco::Candidate*, const reco::Candidate*) const;
0028 inline bool LepDiffCharge(const reco::Candidate*, const reco::Candidate*) const;
0029 inline bool HasPositiveCharge(const reco::Candidate*) const;
0030
0031 private:
0032 edm::EDGetTokenT<std::vector<pat::Electron> > electronSourceToken_;
0033 edm::EDGetTokenT<std::vector<pat::Muon> > muonSourceToken_;
0034 edm::EDGetTokenT<std::vector<pat::Tau> > tauSourceToken_;
0035 edm::EDGetTokenT<std::vector<pat::MET> > metSourceToken_;
0036 edm::EDGetTokenT<std::vector<pat::Jet> > jetSourceToken_;
0037 edm::EDGetTokenT<TtGenEvent> evtSourceToken_;
0038 int jetCorrScheme_;
0039 unsigned int nrCombJets_;
0040 bool matchToGenEvt_, calcTopMass_, useMCforBest_;
0041 bool eeChannel_, emuChannel_, mumuChannel_, etauChannel_, mutauChannel_, tautauChannel_;
0042 double tmassbegin_, tmassend_, tmassstep_;
0043 std::vector<double> nupars_;
0044
0045 TtDilepLRSignalSelObservables* myLRSignalSelObservables;
0046 TtFullLepKinSolver* solver;
0047 };
0048
0049 inline bool TtDilepEvtSolutionMaker::PTComp(const reco::Candidate* l1, const reco::Candidate* l2) const {
0050 return (l1->pt() > l2->pt());
0051 }
0052
0053 inline bool TtDilepEvtSolutionMaker::LepDiffCharge(const reco::Candidate* l1, const reco::Candidate* l2) const {
0054 return (l1->charge() != l2->charge());
0055 }
0056
0057 inline bool TtDilepEvtSolutionMaker::HasPositiveCharge(const reco::Candidate* l) const { return (l->charge() > 0); }
0058
0059 TtDilepEvtSolutionMaker::TtDilepEvtSolutionMaker(const edm::ParameterSet& iConfig) {
0060
0061 electronSourceToken_ = consumes<std::vector<pat::Electron> >(iConfig.getParameter<edm::InputTag>("electronSource"));
0062 muonSourceToken_ = consumes<std::vector<pat::Muon> >(iConfig.getParameter<edm::InputTag>("muonSource"));
0063 tauSourceToken_ = consumes<std::vector<pat::Tau> >(iConfig.getParameter<edm::InputTag>("tauSource"));
0064 metSourceToken_ = consumes<std::vector<pat::MET> >(iConfig.getParameter<edm::InputTag>("metSource"));
0065 jetSourceToken_ = consumes<std::vector<pat::Jet> >(iConfig.getParameter<edm::InputTag>("jetSource"));
0066 jetCorrScheme_ = iConfig.getParameter<int>("jetCorrectionScheme");
0067 evtSourceToken_ = mayConsume<TtGenEvent>(iConfig.getParameter<edm::InputTag>("evtSource"));
0068 nrCombJets_ = iConfig.getParameter<unsigned int>("nrCombJets");
0069 matchToGenEvt_ = iConfig.getParameter<bool>("matchToGenEvt");
0070 calcTopMass_ = iConfig.getParameter<bool>("calcTopMass");
0071 useMCforBest_ = iConfig.getParameter<bool>("bestSolFromMC");
0072 eeChannel_ = iConfig.getParameter<bool>("eeChannel");
0073 emuChannel_ = iConfig.getParameter<bool>("emuChannel");
0074 mumuChannel_ = iConfig.getParameter<bool>("mumuChannel");
0075 mutauChannel_ = iConfig.getParameter<bool>("mutauChannel");
0076 etauChannel_ = iConfig.getParameter<bool>("etauChannel");
0077 tautauChannel_ = iConfig.getParameter<bool>("tautauChannel");
0078 tmassbegin_ = iConfig.getParameter<double>("tmassbegin");
0079 tmassend_ = iConfig.getParameter<double>("tmassend");
0080 tmassstep_ = iConfig.getParameter<double>("tmassstep");
0081 nupars_ = iConfig.getParameter<std::vector<double> >("neutrino_parameters");
0082
0083
0084 produces<std::vector<TtDilepEvtSolution> >();
0085
0086 myLRSignalSelObservables = new TtDilepLRSignalSelObservables(consumesCollector(), jetSourceToken_);
0087
0088 solver = new TtFullLepKinSolver(tmassbegin_, tmassend_, tmassstep_, nupars_);
0089 }
0090
0091 TtDilepEvtSolutionMaker::~TtDilepEvtSolutionMaker() {}
0092
0093 void TtDilepEvtSolutionMaker::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0094 edm::Handle<std::vector<pat::Tau> > taus;
0095 iEvent.getByToken(tauSourceToken_, taus);
0096 edm::Handle<std::vector<pat::Muon> > muons;
0097 iEvent.getByToken(muonSourceToken_, muons);
0098 edm::Handle<std::vector<pat::Electron> > electrons;
0099 iEvent.getByToken(electronSourceToken_, electrons);
0100 edm::Handle<std::vector<pat::MET> > mets;
0101 iEvent.getByToken(metSourceToken_, mets);
0102 edm::Handle<std::vector<pat::Jet> > jets;
0103 iEvent.getByToken(jetSourceToken_, jets);
0104
0105 int selMuonp = -1, selMuonm = -1;
0106 int selElectronp = -1, selElectronm = -1;
0107 int selTaup = -1, selTaum = -1;
0108 bool leptonFound = false;
0109 bool mumu = false;
0110 bool emu = false;
0111 bool ee = false;
0112 bool etau = false;
0113 bool mutau = false;
0114 bool tautau = false;
0115 bool leptonFoundEE = false;
0116 bool leptonFoundMM = false;
0117 bool leptonFoundTT = false;
0118 bool leptonFoundEpMm = false;
0119 bool leptonFoundEmMp = false;
0120 bool leptonFoundEpTm = false;
0121 bool leptonFoundEmTp = false;
0122 bool leptonFoundMpTm = false;
0123 bool leptonFoundMmTp = false;
0124 bool jetsFound = false;
0125 bool METFound = false;
0126 std::vector<int> JetVetoByTaus;
0127
0128
0129 if (!mets->empty()) {
0130 METFound = true;
0131 }
0132
0133
0134
0135 if (muons->size() + electrons->size() >= 2) {
0136
0137 if (electrons->empty())
0138 mumu = true;
0139 else if (muons->empty())
0140 ee = true;
0141 else if (electrons->size() == 1) {
0142 if (muons->size() == 1)
0143 emu = true;
0144 else if (PTComp(&(*electrons)[0], &(*muons)[1]))
0145 emu = true;
0146 else
0147 mumu = true;
0148 } else if (electrons->size() > 1) {
0149 if (PTComp(&(*electrons)[1], &(*muons)[0]))
0150 ee = true;
0151 else if (muons->size() == 1)
0152 emu = true;
0153 else if (PTComp(&(*electrons)[0], &(*muons)[1]))
0154 emu = true;
0155 else
0156 mumu = true;
0157 }
0158 if (ee) {
0159 if (LepDiffCharge(&(*electrons)[0], &(*electrons)[1])) {
0160 leptonFound = true;
0161 leptonFoundEE = true;
0162 if (HasPositiveCharge(&(*electrons)[0])) {
0163 selElectronp = 0;
0164 selElectronm = 1;
0165 } else {
0166 selElectronp = 1;
0167 selElectronm = 0;
0168 }
0169 }
0170 } else if (emu) {
0171 if (LepDiffCharge(&(*electrons)[0], &(*muons)[0])) {
0172 leptonFound = true;
0173 if (HasPositiveCharge(&(*electrons)[0])) {
0174 leptonFoundEpMm = true;
0175 selElectronp = 0;
0176 selMuonm = 0;
0177 } else {
0178 leptonFoundEmMp = true;
0179 selMuonp = 0;
0180 selElectronm = 0;
0181 }
0182 }
0183 } else if (mumu) {
0184 if (LepDiffCharge(&(*muons)[0], &(*muons)[1])) {
0185 leptonFound = true;
0186 leptonFoundMM = true;
0187 if (HasPositiveCharge(&(*muons)[0])) {
0188 selMuonp = 0;
0189 selMuonm = 1;
0190 } else {
0191 selMuonp = 1;
0192 selMuonm = 0;
0193 }
0194 }
0195 }
0196
0197 if (jets->size() >= 2) {
0198 jetsFound = true;
0199 }
0200 }
0201
0202
0203
0204 else if (muons->size() + electrons->size() == 1 && !taus->empty()) {
0205
0206 if (muons->size() == 1) {
0207 mutau = true;
0208
0209 int expectedCharge = -muons->begin()->charge();
0210 int* tauIdx = nullptr;
0211 if (expectedCharge < 0) {
0212 selMuonp = 0;
0213 tauIdx = &selTaum;
0214 leptonFoundMpTm = true;
0215 } else {
0216 selMuonm = 0;
0217 tauIdx = &selTaup;
0218 leptonFoundMmTp = true;
0219 }
0220
0221
0222 std::vector<std::vector<pat::Tau>::const_iterator> subset1;
0223 for (std::vector<pat::Tau>::const_iterator tau = taus->begin(); tau < taus->end(); ++tau) {
0224 if (tau->charge() * expectedCharge >= 0 && DeltaR<pat::Particle>()(*tau, *(muons->begin())) > 0.1) {
0225 *tauIdx = tau - taus->begin();
0226 leptonFound = true;
0227 subset1.push_back(tau);
0228 }
0229 }
0230
0231 float iso = 999.;
0232 for (std::vector<std::vector<pat::Tau>::const_iterator>::const_iterator tau = subset1.begin();
0233 tau < subset1.end();
0234 ++tau) {
0235 if ((*tau)->isPFTau() && (*tau)->isolationPFChargedHadrCandsPtSum() < iso) {
0236 *tauIdx = *tau - taus->begin();
0237 iso = (*tau)->isolationPFChargedHadrCandsPtSum();
0238 }
0239 }
0240
0241
0242 if (!leptonFound) {
0243 leptonFoundMpTm = false;
0244 leptonFoundMmTp = false;
0245 }
0246
0247 if (leptonFound) {
0248 for (std::vector<pat::Jet>::const_iterator jet = jets->begin(); jet < jets->end(); ++jet) {
0249 if (DeltaR<pat::Particle, pat::Jet>()(*(taus->begin() + *tauIdx), *jet) < 0.1) {
0250 JetVetoByTaus.push_back(jet - jets->begin());
0251 }
0252 }
0253 }
0254 } else {
0255 etau = true;
0256
0257 int expectedCharge = -electrons->begin()->charge();
0258 int* tauIdx = nullptr;
0259 if (expectedCharge < 0) {
0260 selElectronp = 0;
0261 tauIdx = &selTaum;
0262 leptonFoundEpTm = true;
0263 } else {
0264 selElectronm = 0;
0265 tauIdx = &selTaup;
0266 leptonFoundEmTp = true;
0267 }
0268
0269
0270 std::vector<std::vector<pat::Tau>::const_iterator> subset1;
0271 for (std::vector<pat::Tau>::const_iterator tau = taus->begin(); tau < taus->end(); ++tau) {
0272 if (tau->charge() * expectedCharge >= 0 && DeltaR<pat::Particle>()(*tau, *(electrons->begin())) > 0.1) {
0273 *tauIdx = tau - taus->begin();
0274 leptonFound = true;
0275 subset1.push_back(tau);
0276 }
0277 }
0278
0279 float iso = 999.;
0280 for (std::vector<std::vector<pat::Tau>::const_iterator>::const_iterator tau = subset1.begin();
0281 tau < subset1.end();
0282 ++tau) {
0283 if ((*tau)->isPFTau() && (*tau)->isolationPFChargedHadrCandsPtSum() < iso) {
0284 *tauIdx = *tau - taus->begin();
0285 iso = (*tau)->isolationPFChargedHadrCandsPtSum();
0286 }
0287 }
0288
0289
0290 if (!leptonFound) {
0291 leptonFoundEpTm = false;
0292 leptonFoundEmTp = false;
0293 }
0294
0295 if (leptonFound) {
0296 for (std::vector<pat::Jet>::const_iterator jet = jets->begin(); jet < jets->end(); ++jet) {
0297 if (DeltaR<pat::Particle, pat::Jet>()(*(taus->begin() + *tauIdx), *jet) < 0.1) {
0298 JetVetoByTaus.push_back(jet - jets->begin());
0299 }
0300 }
0301 }
0302 }
0303
0304 jetsFound = ((jets->size() - JetVetoByTaus.size()) >= 2);
0305 } else if (taus->size() > 1) {
0306 tautau = true;
0307 if (LepDiffCharge(&(*taus)[0], &(*taus)[1])) {
0308 leptonFound = true;
0309 leptonFoundTT = true;
0310 if (HasPositiveCharge(&(*taus)[0])) {
0311 selTaup = 0;
0312 selTaum = 1;
0313 } else {
0314 selTaup = 1;
0315 selTaum = 0;
0316 }
0317 }
0318 for (std::vector<pat::Jet>::const_iterator jet = jets->begin(); jet < jets->end(); ++jet) {
0319 if (DeltaR<pat::Particle, pat::Jet>()((*taus)[0], *jet) < 0.1 ||
0320 DeltaR<pat::Particle, pat::Jet>()((*taus)[1], *jet) < 0.1) {
0321 JetVetoByTaus.push_back(jet - jets->begin());
0322 }
0323 }
0324
0325 jetsFound = ((jets->size() - JetVetoByTaus.size()) >= 2);
0326 }
0327
0328
0329 if (int(ee) + int(emu) + int(mumu) + int(etau) + int(mutau) + int(tautau) > 1)
0330 std::cout << "[TtDilepEvtSolutionMaker]: "
0331 << "Lepton selection criteria uncorrectly defined" << std::endl;
0332
0333 bool correctLepton = (leptonFoundEE && eeChannel_) || ((leptonFoundEmMp || leptonFoundEpMm) && emuChannel_) ||
0334 (leptonFoundMM && mumuChannel_) || ((leptonFoundMmTp || leptonFoundMpTm) && mutauChannel_) ||
0335 ((leptonFoundEmTp || leptonFoundEpTm) && etauChannel_) || (leptonFoundTT && tautauChannel_);
0336
0337 std::vector<TtDilepEvtSolution>* evtsols = new std::vector<TtDilepEvtSolution>();
0338 if (correctLepton && METFound && jetsFound) {
0339
0340 unsigned int nrCombJets = 0;
0341 unsigned int numberOfJets = 0;
0342 for (; nrCombJets < jets->size() && numberOfJets < nrCombJets_; ++nrCombJets) {
0343 if (find(JetVetoByTaus.begin(), JetVetoByTaus.end(), int(nrCombJets)) == JetVetoByTaus.end())
0344 ++numberOfJets;
0345 }
0346
0347 for (unsigned int ib = 0; ib < nrCombJets; ib++) {
0348
0349 if (find(JetVetoByTaus.begin(), JetVetoByTaus.end(), int(ib)) != JetVetoByTaus.end())
0350 continue;
0351
0352 for (unsigned int ibbar = 0; ibbar < nrCombJets; ibbar++) {
0353
0354 if (ib == ibbar)
0355 continue;
0356
0357 if (find(JetVetoByTaus.begin(), JetVetoByTaus.end(), int(ibbar)) != JetVetoByTaus.end())
0358 continue;
0359
0360 TtDilepEvtSolution asol;
0361 asol.setJetCorrectionScheme(jetCorrScheme_);
0362 double xconstraint = 0, yconstraint = 0;
0363
0364 if (leptonFoundEE || leptonFoundEpMm || leptonFoundEpTm) {
0365 asol.setElectronp(electrons, selElectronp);
0366 xconstraint += (*electrons)[selElectronp].px();
0367 yconstraint += (*electrons)[selElectronp].py();
0368 }
0369
0370 if (leptonFoundEE || leptonFoundEmMp || leptonFoundEmTp) {
0371 asol.setElectronm(electrons, selElectronm);
0372 xconstraint += (*electrons)[selElectronm].px();
0373 yconstraint += (*electrons)[selElectronm].py();
0374 }
0375
0376 if (leptonFoundMM || leptonFoundEmMp || leptonFoundMpTm) {
0377 asol.setMuonp(muons, selMuonp);
0378 xconstraint += (*muons)[selMuonp].px();
0379 yconstraint += (*muons)[selMuonp].py();
0380 }
0381
0382 if (leptonFoundMM || leptonFoundEpMm || leptonFoundMmTp) {
0383 asol.setMuonm(muons, selMuonm);
0384 xconstraint += (*muons)[selMuonm].px();
0385 yconstraint += (*muons)[selMuonm].py();
0386 }
0387
0388 if (leptonFoundEpTm || leptonFoundMpTm || leptonFoundTT) {
0389 asol.setTaum(taus, selTaum);
0390 xconstraint += (*taus)[selTaum].px();
0391 yconstraint += (*taus)[selTaum].py();
0392 }
0393
0394 if (leptonFoundEmTp || leptonFoundMmTp || leptonFoundTT) {
0395 asol.setTaup(taus, selTaup);
0396 xconstraint += (*taus)[selTaup].px();
0397 yconstraint += (*taus)[selTaup].py();
0398 }
0399
0400 asol.setB(jets, ib);
0401 asol.setBbar(jets, ibbar);
0402 asol.setMET(mets, 0);
0403 xconstraint += (*jets)[ib].px() + (*jets)[ibbar].px() + (*mets)[0].px();
0404 yconstraint += (*jets)[ib].py() + (*jets)[ibbar].py() + (*mets)[0].py();
0405
0406 if (matchToGenEvt_) {
0407 edm::Handle<TtGenEvent> genEvt;
0408 iEvent.getByToken(evtSourceToken_, genEvt);
0409 asol.setGenEvt(genEvt);
0410 }
0411
0412 if (calcTopMass_) {
0413 solver->SetConstraints(xconstraint, yconstraint);
0414 solver->useWeightFromMC(useMCforBest_);
0415 asol = solver->addKinSolInfo(&asol);
0416 }
0417
0418
0419 (*myLRSignalSelObservables)(asol, iEvent);
0420
0421 evtsols->push_back(asol);
0422 }
0423 }
0424
0425 if (matchToGenEvt_) {
0426 double bestSolDR = 9999.;
0427 int bestSol = -1;
0428 double dR = 0.;
0429 for (size_t s = 0; s < evtsols->size(); s++) {
0430 dR = (*evtsols)[s].getJetResidual();
0431 if (dR < bestSolDR) {
0432 bestSolDR = dR;
0433 bestSol = s;
0434 }
0435 }
0436 if (bestSol != -1)
0437 (*evtsols)[bestSol].setBestSol(true);
0438 }
0439
0440 std::unique_ptr<std::vector<TtDilepEvtSolution> > pOut(evtsols);
0441 iEvent.put(std::move(pOut));
0442 } else {
0443
0444 TtDilepEvtSolution asol;
0445 evtsols->push_back(asol);
0446 std::unique_ptr<std::vector<TtDilepEvtSolution> > pOut(evtsols);
0447 iEvent.put(std::move(pOut));
0448 }
0449 }
0450
0451 #include "FWCore/Framework/interface/MakerMacros.h"
0452 DEFINE_FWK_MODULE(TtDilepEvtSolutionMaker);