File indexing completed on 2023-03-17 11:26:03
0001 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/Utilities/interface/InputTag.h"
0004 #include "FWCore/Framework/interface/stream/EDProducer.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006
0007 #include "DataFormats/Math/interface/deltaR.h"
0008
0009 #include "TopQuarkAnalysis/TopTools/interface/JetPartonMatching.h"
0010 #include "AnalysisDataFormats/TopObjects/interface/TtSemiEvtSolution.h"
0011 #include "TopQuarkAnalysis/TopJetCombination/interface/TtSemiSimpleBestJetComb.h"
0012 #include "TopQuarkAnalysis/TopJetCombination/interface/TtSemiLRJetCombObservables.h"
0013 #include "TopQuarkAnalysis/TopJetCombination/interface/TtSemiLRJetCombCalc.h"
0014 #include "TopQuarkAnalysis/TopEventSelection/interface/TtSemiLRSignalSelObservables.h"
0015 #include "TopQuarkAnalysis/TopEventSelection/interface/TtSemiLRSignalSelCalc.h"
0016 #include "TopQuarkAnalysis/TopKinFitter/interface/TtSemiLepKinFitter.h"
0017
0018 #include <memory>
0019 #include <string>
0020 #include <vector>
0021
0022 class TtSemiEvtSolutionMaker : public edm::stream::EDProducer<> {
0023 public:
0024 explicit TtSemiEvtSolutionMaker(const edm::ParameterSet& iConfig);
0025 ~TtSemiEvtSolutionMaker() override;
0026
0027 void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0028
0029
0030 TtSemiLepKinFitter::Param param(unsigned);
0031
0032 TtSemiLepKinFitter::Constraint constraint(unsigned);
0033
0034 std::vector<TtSemiLepKinFitter::Constraint> constraints(std::vector<unsigned>&);
0035
0036 private:
0037
0038 edm::EDGetTokenT<std::vector<pat::Electron> > electronSrcToken_;
0039 edm::EDGetTokenT<std::vector<pat::Muon> > muonSrcToken_;
0040 edm::EDGetTokenT<std::vector<pat::MET> > metSrcToken_;
0041 edm::EDGetTokenT<std::vector<pat::Jet> > jetSrcToken_;
0042 std::string leptonFlavour_;
0043 int jetCorrScheme_;
0044 unsigned int nrCombJets_;
0045 std::string lrSignalSelFile_, lrJetCombFile_;
0046 bool addLRSignalSel_, addLRJetComb_, doKinFit_, matchToGenEvt_;
0047 int matchingAlgo_;
0048 bool useMaxDist_, useDeltaR_;
0049 double maxDist_;
0050 int maxNrIter_;
0051 double maxDeltaS_, maxF_;
0052 int jetParam_, lepParam_, metParam_;
0053 std::vector<int> lrSignalSelObs_, lrJetCombObs_;
0054 std::vector<unsigned> constraints_;
0055 edm::EDGetTokenT<TtGenEvent> genEvtToken_;
0056
0057 TtSemiLepKinFitter* myKinFitter;
0058 TtSemiSimpleBestJetComb* mySimpleBestJetComb;
0059 TtSemiLRJetCombObservables* myLRJetCombObservables;
0060 TtSemiLRJetCombCalc* myLRJetCombCalc;
0061 TtSemiLRSignalSelObservables* myLRSignalSelObservables;
0062 TtSemiLRSignalSelCalc* myLRSignalSelCalc;
0063 };
0064
0065
0066 TtSemiEvtSolutionMaker::TtSemiEvtSolutionMaker(const edm::ParameterSet& iConfig) {
0067
0068 electronSrcToken_ = mayConsume<std::vector<pat::Electron> >(iConfig.getParameter<edm::InputTag>("electronSource"));
0069 muonSrcToken_ = mayConsume<std::vector<pat::Muon> >(iConfig.getParameter<edm::InputTag>("muonSource"));
0070 metSrcToken_ = consumes<std::vector<pat::MET> >(iConfig.getParameter<edm::InputTag>("metSource"));
0071 jetSrcToken_ = consumes<std::vector<pat::Jet> >(iConfig.getParameter<edm::InputTag>("jetSource"));
0072 leptonFlavour_ = iConfig.getParameter<std::string>("leptonFlavour");
0073 jetCorrScheme_ = iConfig.getParameter<int>("jetCorrectionScheme");
0074 nrCombJets_ = iConfig.getParameter<unsigned int>("nrCombJets");
0075 doKinFit_ = iConfig.getParameter<bool>("doKinFit");
0076 addLRSignalSel_ = iConfig.getParameter<bool>("addLRSignalSel");
0077 lrSignalSelObs_ = iConfig.getParameter<std::vector<int> >("lrSignalSelObs");
0078 lrSignalSelFile_ = iConfig.getParameter<std::string>("lrSignalSelFile");
0079 addLRJetComb_ = iConfig.getParameter<bool>("addLRJetComb");
0080 lrJetCombObs_ = iConfig.getParameter<std::vector<int> >("lrJetCombObs");
0081 lrJetCombFile_ = iConfig.getParameter<std::string>("lrJetCombFile");
0082 maxNrIter_ = iConfig.getParameter<int>("maxNrIter");
0083 maxDeltaS_ = iConfig.getParameter<double>("maxDeltaS");
0084 maxF_ = iConfig.getParameter<double>("maxF");
0085 jetParam_ = iConfig.getParameter<int>("jetParametrisation");
0086 lepParam_ = iConfig.getParameter<int>("lepParametrisation");
0087 metParam_ = iConfig.getParameter<int>("metParametrisation");
0088 constraints_ = iConfig.getParameter<std::vector<unsigned> >("constraints");
0089 matchToGenEvt_ = iConfig.getParameter<bool>("matchToGenEvt");
0090 matchingAlgo_ = iConfig.getParameter<int>("matchingAlgorithm");
0091 useMaxDist_ = iConfig.getParameter<bool>("useMaximalDistance");
0092 useDeltaR_ = iConfig.getParameter<bool>("useDeltaR");
0093 maxDist_ = iConfig.getParameter<double>("maximalDistance");
0094 genEvtToken_ = mayConsume<TtGenEvent>(edm::InputTag("genEvt"));
0095
0096
0097 if (doKinFit_) {
0098 myKinFitter = new TtSemiLepKinFitter(
0099 param(jetParam_), param(lepParam_), param(metParam_), maxNrIter_, maxDeltaS_, maxF_, constraints(constraints_));
0100 }
0101
0102
0103 mySimpleBestJetComb = new TtSemiSimpleBestJetComb();
0104 myLRSignalSelObservables = new TtSemiLRSignalSelObservables();
0105 myLRJetCombObservables = new TtSemiLRJetCombObservables(consumesCollector(), jetSrcToken_);
0106 if (addLRJetComb_)
0107 myLRJetCombCalc = new TtSemiLRJetCombCalc(edm::FileInPath(lrJetCombFile_).fullPath(), lrJetCombObs_);
0108
0109
0110 if (addLRSignalSel_)
0111 myLRSignalSelCalc = new TtSemiLRSignalSelCalc(edm::FileInPath(lrSignalSelFile_).fullPath(), lrSignalSelObs_);
0112
0113
0114 produces<std::vector<TtSemiEvtSolution> >();
0115 }
0116
0117
0118 TtSemiEvtSolutionMaker::~TtSemiEvtSolutionMaker() {
0119 if (doKinFit_)
0120 delete myKinFitter;
0121 delete mySimpleBestJetComb;
0122 delete myLRSignalSelObservables;
0123 delete myLRJetCombObservables;
0124 if (addLRSignalSel_)
0125 delete myLRSignalSelCalc;
0126 if (addLRJetComb_)
0127 delete myLRJetCombCalc;
0128 }
0129
0130 void TtSemiEvtSolutionMaker::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0131
0132
0133
0134
0135
0136 bool leptonFound = false;
0137 edm::Handle<std::vector<pat::Muon> > muons;
0138 if (leptonFlavour_ == "muon") {
0139 iEvent.getByToken(muonSrcToken_, muons);
0140 if (!muons->empty())
0141 leptonFound = true;
0142 }
0143 edm::Handle<std::vector<pat::Electron> > electrons;
0144 if (leptonFlavour_ == "electron") {
0145 iEvent.getByToken(electronSrcToken_, electrons);
0146 if (!electrons->empty())
0147 leptonFound = true;
0148 }
0149
0150
0151 bool metFound = false;
0152 edm::Handle<std::vector<pat::MET> > mets;
0153 iEvent.getByToken(metSrcToken_, mets);
0154 if (!mets->empty())
0155 metFound = true;
0156
0157
0158 bool jetsFound = false;
0159 edm::Handle<std::vector<pat::Jet> > jets;
0160 iEvent.getByToken(jetSrcToken_, jets);
0161 if (jets->size() >= 4)
0162 jetsFound = true;
0163
0164
0165
0166
0167 std::vector<TtSemiEvtSolution>* evtsols = new std::vector<TtSemiEvtSolution>();
0168 if (leptonFound && metFound && jetsFound) {
0169
0170 unsigned int nrCombJets = nrCombJets_;
0171 if (jets->size() < nrCombJets)
0172 nrCombJets = jets->size();
0173
0174 for (unsigned int p = 0; p < nrCombJets; p++) {
0175 for (unsigned int q = 0; q < nrCombJets; q++) {
0176 for (unsigned int bh = 0; bh < nrCombJets; bh++) {
0177 if (q > p && !(bh == p || bh == q)) {
0178 for (unsigned int bl = 0; bl < nrCombJets; bl++) {
0179 if (!(bl == p || bl == q || bl == bh)) {
0180 TtSemiEvtSolution asol;
0181 asol.setJetCorrectionScheme(jetCorrScheme_);
0182 if (leptonFlavour_ == "muon")
0183 asol.setMuon(muons, 0);
0184 if (leptonFlavour_ == "electron")
0185 asol.setElectron(electrons, 0);
0186 asol.setNeutrino(mets, 0);
0187 asol.setHadp(jets, p);
0188 asol.setHadq(jets, q);
0189 asol.setHadb(jets, bh);
0190 asol.setLepb(jets, bl);
0191 if (doKinFit_) {
0192 asol = myKinFitter->addKinFitInfo(&asol);
0193
0194 asol.setJetParametrisation(jetParam_);
0195 asol.setLeptonParametrisation(lepParam_);
0196 asol.setNeutrinoParametrisation(metParam_);
0197 }
0198 if (matchToGenEvt_) {
0199 edm::Handle<TtGenEvent> genEvt;
0200 iEvent.getByToken(genEvtToken_, genEvt);
0201 if (genEvt->numberOfBQuarks() ==
0202 2 &&
0203 genEvt->numberOfLeptons() ==
0204 1) {
0205 asol.setGenEvt(genEvt);
0206 }
0207 }
0208
0209 (*myLRSignalSelObservables)(asol, *jets);
0210
0211
0212
0213
0214 if (addLRSignalSel_)
0215 (*myLRSignalSelCalc)(asol);
0216
0217
0218
0219
0220 (*myLRJetCombObservables)(asol, iEvent);
0221
0222
0223
0224 if (addLRJetComb_)
0225 (*myLRJetCombCalc)(asol);
0226
0227
0228
0229
0230
0231 asol.setupHyp();
0232 evtsols->push_back(asol);
0233 }
0234 }
0235 }
0236 }
0237 }
0238 }
0239
0240
0241 if (matchToGenEvt_) {
0242 int bestSolution = -999;
0243 int bestSolutionChangeWQ = -999;
0244 edm::Handle<TtGenEvent> genEvt;
0245 iEvent.getByToken(genEvtToken_, genEvt);
0246 if (genEvt->numberOfBQuarks() ==
0247 2 &&
0248 genEvt->numberOfLeptons() ==
0249 1) {
0250 std::vector<const reco::Candidate*> quarks;
0251 const reco::Candidate& genp = *(genEvt->hadronicDecayQuark());
0252 const reco::Candidate& genq = *(genEvt->hadronicDecayQuarkBar());
0253 const reco::Candidate& genbh = *(genEvt->hadronicDecayB());
0254 const reco::Candidate& genbl = *(genEvt->leptonicDecayB());
0255 quarks.push_back(&genp);
0256 quarks.push_back(&genq);
0257 quarks.push_back(&genbh);
0258 quarks.push_back(&genbl);
0259 std::vector<const reco::Candidate*> recjets;
0260 for (size_t s = 0; s < evtsols->size(); s++) {
0261 recjets.clear();
0262 const reco::Candidate& jetp = (*evtsols)[s].getRecHadp();
0263 const reco::Candidate& jetq = (*evtsols)[s].getRecHadq();
0264 const reco::Candidate& jetbh = (*evtsols)[s].getRecHadb();
0265 const reco::Candidate& jetbl = (*evtsols)[s].getRecLepb();
0266 recjets.push_back(&jetp);
0267 recjets.push_back(&jetq);
0268 recjets.push_back(&jetbh);
0269 recjets.push_back(&jetbl);
0270 JetPartonMatching aMatch(quarks, recjets, matchingAlgo_, useMaxDist_, useDeltaR_, maxDist_);
0271 (*evtsols)[s].setGenEvt(genEvt);
0272 (*evtsols)[s].setMCBestSumAngles(aMatch.getSumDistances());
0273 (*evtsols)[s].setMCBestAngleHadp(aMatch.getDistanceForParton(0));
0274 (*evtsols)[s].setMCBestAngleHadq(aMatch.getDistanceForParton(1));
0275 (*evtsols)[s].setMCBestAngleHadb(aMatch.getDistanceForParton(2));
0276 (*evtsols)[s].setMCBestAngleLepb(aMatch.getDistanceForParton(3));
0277 if (aMatch.getMatchForParton(2) == 2 && aMatch.getMatchForParton(3) == 3) {
0278 if (aMatch.getMatchForParton(0) == 0 && aMatch.getMatchForParton(1) == 1) {
0279 bestSolution = s;
0280 bestSolutionChangeWQ = 0;
0281 } else if (aMatch.getMatchForParton(0) == 1 && aMatch.getMatchForParton(1) == 0) {
0282 bestSolution = s;
0283 bestSolutionChangeWQ = 1;
0284 }
0285 }
0286 }
0287 }
0288 for (size_t s = 0; s < evtsols->size(); s++) {
0289 (*evtsols)[s].setMCBestJetComb(bestSolution);
0290 (*evtsols)[s].setMCChangeWQ(bestSolutionChangeWQ);
0291 }
0292 }
0293
0294
0295 int simpleBestJetComb = (*mySimpleBestJetComb)(*evtsols);
0296 for (size_t s = 0; s < evtsols->size(); s++)
0297 (*evtsols)[s].setSimpleBestJetComb(simpleBestJetComb);
0298
0299
0300 if (addLRJetComb_ && !evtsols->empty()) {
0301 float bestLRVal = -1000000;
0302 int bestSol = (*evtsols)[0].getLRBestJetComb();
0303 for (size_t s = 0; s < evtsols->size(); s++) {
0304 if ((*evtsols)[s].getLRJetCombLRval() > bestLRVal) {
0305 bestLRVal = (*evtsols)[s].getLRJetCombLRval();
0306 bestSol = s;
0307 }
0308 }
0309 for (size_t s = 0; s < evtsols->size(); s++) {
0310 (*evtsols)[s].setLRBestJetComb(bestSol);
0311 }
0312 }
0313
0314
0315 std::unique_ptr<std::vector<TtSemiEvtSolution> > pOut(evtsols);
0316 iEvent.put(std::move(pOut));
0317
0318 } else {
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 std::unique_ptr<std::vector<TtSemiEvtSolution> > pOut(evtsols);
0329 iEvent.put(std::move(pOut));
0330 }
0331 }
0332
0333 TtSemiLepKinFitter::Param TtSemiEvtSolutionMaker::param(unsigned val) {
0334 TtSemiLepKinFitter::Param result;
0335 switch (val) {
0336 case TtSemiLepKinFitter::kEMom:
0337 result = TtSemiLepKinFitter::kEMom;
0338 break;
0339 case TtSemiLepKinFitter::kEtEtaPhi:
0340 result = TtSemiLepKinFitter::kEtEtaPhi;
0341 break;
0342 case TtSemiLepKinFitter::kEtThetaPhi:
0343 result = TtSemiLepKinFitter::kEtThetaPhi;
0344 break;
0345 default:
0346 throw cms::Exception("WrongConfig") << "Chosen jet parametrization is not supported: " << val << "\n";
0347 break;
0348 }
0349 return result;
0350 }
0351
0352 TtSemiLepKinFitter::Constraint TtSemiEvtSolutionMaker::constraint(unsigned val) {
0353 TtSemiLepKinFitter::Constraint result;
0354 switch (val) {
0355 case TtSemiLepKinFitter::kWHadMass:
0356 result = TtSemiLepKinFitter::kWHadMass;
0357 break;
0358 case TtSemiLepKinFitter::kWLepMass:
0359 result = TtSemiLepKinFitter::kWLepMass;
0360 break;
0361 case TtSemiLepKinFitter::kTopHadMass:
0362 result = TtSemiLepKinFitter::kTopHadMass;
0363 break;
0364 case TtSemiLepKinFitter::kTopLepMass:
0365 result = TtSemiLepKinFitter::kTopLepMass;
0366 break;
0367 case TtSemiLepKinFitter::kNeutrinoMass:
0368 result = TtSemiLepKinFitter::kNeutrinoMass;
0369 break;
0370 default:
0371 throw cms::Exception("WrongConfig") << "Chosen fit constraint is not supported: " << val << "\n";
0372 break;
0373 }
0374 return result;
0375 }
0376
0377 std::vector<TtSemiLepKinFitter::Constraint> TtSemiEvtSolutionMaker::constraints(std::vector<unsigned>& val) {
0378 std::vector<TtSemiLepKinFitter::Constraint> result;
0379 for (unsigned i = 0; i < val.size(); ++i) {
0380 result.push_back(constraint(val[i]));
0381 }
0382 return result;
0383 }
0384
0385 #include "FWCore/Framework/interface/MakerMacros.h"
0386 DEFINE_FWK_MODULE(TtSemiEvtSolutionMaker);