Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-01-25 05:52:12

0001 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
0002 #include "TopQuarkAnalysis/TopJetCombination/interface/TtFullHadHypothesis.h"
0003 
0004 /// default constructor
0005 TtFullHadHypothesis::TtFullHadHypothesis(const edm::ParameterSet& cfg)
0006     : jetsToken_(consumes<std::vector<pat::Jet> >(cfg.getParameter<edm::InputTag>("jets"))) {
0007   getMatch_ = false;
0008   if (cfg.exists("match")) {
0009     getMatch_ = true;
0010     matchToken_ = consumes<std::vector<std::vector<int> > >(cfg.getParameter<edm::InputTag>("match"));
0011   }
0012   if (cfg.exists("jetCorrectionLevel")) {
0013     jetCorrectionLevel_ = cfg.getParameter<std::string>("jetCorrectionLevel");
0014   }
0015   produces<std::vector<std::pair<reco::CompositeCandidate, std::vector<int> > > >();
0016   produces<int>("Key");
0017 }
0018 
0019 /// produce the event hypothesis as CompositeCandidate and Key
0020 void TtFullHadHypothesis::produce(edm::Event& evt, const edm::EventSetup& setup) {
0021   edm::Handle<std::vector<pat::Jet> > jets;
0022   evt.getByToken(jetsToken_, jets);
0023 
0024   std::vector<std::vector<int> > matchVec;
0025   if (getMatch_) {
0026     edm::Handle<std::vector<std::vector<int> > > matchHandle;
0027     evt.getByToken(matchToken_, matchHandle);
0028     matchVec = *matchHandle;
0029   } else {
0030     std::vector<int> dummyMatch;
0031     for (unsigned int i = 0; i < 4; ++i)
0032       dummyMatch.push_back(-1);
0033     matchVec.push_back(dummyMatch);
0034   }
0035 
0036   // declare unique_ptr for products
0037   std::unique_ptr<std::vector<std::pair<reco::CompositeCandidate, std::vector<int> > > > pOut(
0038       new std::vector<std::pair<reco::CompositeCandidate, std::vector<int> > >);
0039   std::unique_ptr<int> pKey(new int);
0040 
0041   // go through given vector of jet combinations
0042   unsigned int idMatch = 0;
0043   typedef std::vector<std::vector<int> >::iterator MatchVecIterator;
0044   for (MatchVecIterator match = matchVec.begin(); match != matchVec.end(); ++match) {
0045     // reset pointers
0046     resetCandidates();
0047     // build hypothesis
0048     buildHypo(evt, jets, *match, idMatch++);
0049     pOut->push_back(std::make_pair(hypo(), *match));
0050   }
0051   // feed out hyps and matches
0052   evt.put(std::move(pOut));
0053 
0054   // build and feed out key
0055   buildKey();
0056   *pKey = key();
0057   evt.put(std::move(pKey), "Key");
0058 }
0059 
0060 /// reset candidate pointers before hypo build process
0061 void TtFullHadHypothesis::resetCandidates() {
0062   lightQ_.reset();
0063   lightQBar_.reset();
0064   b_.reset();
0065   bBar_.reset();
0066   lightP_.reset();
0067   lightPBar_.reset();
0068 }
0069 
0070 /// return event hypothesis
0071 reco::CompositeCandidate TtFullHadHypothesis::hypo() {
0072   // check for sanity of the hypothesis
0073   if (!lightQ_ || !lightQBar_ || !b_ || !bBar_ || !lightP_ || !lightPBar_)
0074     return reco::CompositeCandidate();
0075 
0076   // setup transient references
0077   reco::CompositeCandidate hyp, top, w, topBar, wBar;
0078 
0079   AddFourMomenta addFourMomenta;
0080   // build up the top bar branch
0081   wBar.addDaughter(std::move(lightP_), TtFullHadDaughter::LightP);
0082   wBar.addDaughter(std::move(lightPBar_), TtFullHadDaughter::LightPBar);
0083   addFourMomenta.set(wBar);
0084   topBar.addDaughter(wBar, TtFullHadDaughter::WMinus);
0085   topBar.addDaughter(std::move(bBar_), TtFullHadDaughter::BBar);
0086   addFourMomenta.set(topBar);
0087 
0088   // build up the top branch that decays hadronically
0089   w.addDaughter(std::move(lightQ_), TtFullHadDaughter::LightQ);
0090   w.addDaughter(std::move(lightQBar_), TtFullHadDaughter::LightQBar);
0091   addFourMomenta.set(w);
0092   top.addDaughter(w, TtFullHadDaughter::WPlus);
0093   top.addDaughter(std::move(b_), TtFullHadDaughter::B);
0094   addFourMomenta.set(top);
0095 
0096   // build ttbar hypotheses
0097   hyp.addDaughter(topBar, TtFullHadDaughter::TopBar);
0098   hyp.addDaughter(top, TtFullHadDaughter::Top);
0099   addFourMomenta.set(hyp);
0100 
0101   return hyp;
0102 }
0103 
0104 /// helper function to construct the proper correction level string for corresponding quarkType
0105 std::string TtFullHadHypothesis::jetCorrectionLevel(const std::string& quarkType) {
0106   // jetCorrectionLevel was not configured
0107   if (jetCorrectionLevel_.empty())
0108     throw cms::Exception("Configuration")
0109         << "Unconfigured jetCorrectionLevel. Please use an appropriate, non-empty string.\n";
0110 
0111   // quarkType is unknown
0112   if (!(quarkType == "wQuarkMix" || quarkType == "udsQuark" || quarkType == "cQuark" || quarkType == "bQuark"))
0113     throw cms::Exception("Configuration") << quarkType << " is unknown as a quarkType for the jetCorrectionLevel.\n";
0114 
0115   // combine correction level; start with a ':' even if
0116   // there is no flavor tag to be added, as it is needed
0117   // by makeCandidate to disentangle the correction tag
0118   // from a potential flavor tag, which can be empty
0119   std::string level = jetCorrectionLevel_ + ":";
0120   if (level == "L5Flavor:" || level == "L6UE:" || level == "L7Parton:") {
0121     if (quarkType == "wQuarkMix") {
0122       level += "wMix";
0123     }
0124     if (quarkType == "udsQuark") {
0125       level += "uds";
0126     }
0127     if (quarkType == "cQuark") {
0128       level += "charm";
0129     }
0130     if (quarkType == "bQuark") {
0131       level += "bottom";
0132     }
0133   } else {
0134     level += "none";
0135   }
0136   return level;
0137 }
0138 
0139 /// use one object in a jet collection to set a ShallowClonePtrCandidate with proper jet corrections
0140 std::unique_ptr<reco::ShallowClonePtrCandidate> TtFullHadHypothesis::makeCandidate(
0141     const edm::Handle<std::vector<pat::Jet> >& handle, const int& idx, const std::string& correctionLevel) {
0142   edm::Ptr<pat::Jet> ptr = edm::Ptr<pat::Jet>(handle, idx);
0143   // disentangle the correction from the potential flavor tag
0144   // by the separating ':'; the flavor tag can be empty though
0145   std::string step = correctionLevel.substr(0, correctionLevel.find(':'));
0146   std::string flavor = correctionLevel.substr(1 + correctionLevel.find(':'));
0147   float corrFactor = 1.;
0148   if (flavor == "wMix")
0149     corrFactor = 0.75 * ptr->jecFactor(step, "uds") + 0.25 * ptr->jecFactor(step, "charm");
0150   else
0151     corrFactor = ptr->jecFactor(step, flavor);
0152   return std::make_unique<reco::ShallowClonePtrCandidate>(ptr, ptr->charge(), ptr->p4() * corrFactor, ptr->vertex());
0153 }