CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/TopQuarkAnalysis/TopJetCombination/src/TtSemiLepHypothesis.cc

Go to the documentation of this file.
00001 #include "CommonTools/CandUtils/interface/AddFourMomenta.h"
00002 #include "DataFormats/PatCandidates/interface/Electron.h"
00003 #include "DataFormats/PatCandidates/interface/Muon.h"
00004 #include "TopQuarkAnalysis/TopTools/interface/MEzCalculator.h"
00005 
00006 #include "TopQuarkAnalysis/TopJetCombination/interface/TtSemiLepHypothesis.h"
00007 
00009 TtSemiLepHypothesis::TtSemiLepHypothesis(const edm::ParameterSet& cfg):
00010   jets_(cfg.getParameter<edm::InputTag>("jets")),
00011   leps_(cfg.getParameter<edm::InputTag>("leps")),
00012   mets_(cfg.getParameter<edm::InputTag>("mets")),
00013   numberOfRealNeutrinoSolutions_(-1),
00014   lightQ_(0), lightQBar_(0), hadronicB_(0), 
00015   leptonicB_(0), neutrino_(0), lepton_(0)
00016 {
00017   getMatch_ = false;
00018   if( cfg.exists("match") ) {
00019     getMatch_ = true;
00020     match_ = cfg.getParameter<edm::InputTag>("match");
00021   }
00022   if( cfg.exists("jetCorrectionLevel") ) {
00023     jetCorrectionLevel_ = cfg.getParameter<std::string>("jetCorrectionLevel");
00024   }
00025   produces<std::vector<std::pair<reco::CompositeCandidate, std::vector<int> > > >();
00026   produces<int>("Key");
00027   produces<int>("NumberOfRealNeutrinoSolutions");
00028 }
00029 
00031 TtSemiLepHypothesis::~TtSemiLepHypothesis()
00032 {
00033   if( lightQ_    ) delete lightQ_;
00034   if( lightQBar_ ) delete lightQBar_;
00035   if( hadronicB_ ) delete hadronicB_;
00036   if( leptonicB_ ) delete leptonicB_;
00037   if( neutrino_  ) delete neutrino_;
00038   if( lepton_    ) delete lepton_;
00039 }
00040 
00042 void
00043 TtSemiLepHypothesis::produce(edm::Event& evt, const edm::EventSetup& setup)
00044 {
00045   edm::Handle<std::vector<pat::Jet> > jets;
00046   evt.getByLabel(jets_, jets);
00047   
00048   edm::Handle<edm::View<reco::RecoCandidate> > leps;
00049   evt.getByLabel(leps_, leps);
00050 
00051   edm::Handle<std::vector<pat::MET> > mets;
00052   evt.getByLabel(mets_, mets);
00053 
00054   std::vector<std::vector<int> > matchVec;
00055   if( getMatch_ ) {
00056     edm::Handle<std::vector<std::vector<int> > > matchHandle;
00057     evt.getByLabel(match_, matchHandle);
00058     matchVec = *matchHandle;
00059   }
00060   else {
00061     std::vector<int> dummyMatch;
00062     for(unsigned int i = 0; i < 4; ++i) 
00063       dummyMatch.push_back( -1 );
00064     matchVec.push_back( dummyMatch );
00065   }
00066 
00067   // declare auto_ptr for products
00068   std::auto_ptr<std::vector<std::pair<reco::CompositeCandidate, std::vector<int> > > >
00069     pOut( new std::vector<std::pair<reco::CompositeCandidate, std::vector<int> > > );
00070   std::auto_ptr<int> pKey(new int);
00071   std::auto_ptr<int> pNeutrinoSolutions(new int);
00072 
00073   // go through given vector of jet combinations
00074   unsigned int idMatch = 0;
00075   typedef std::vector<std::vector<int> >::iterator MatchVecIterator;
00076   for(MatchVecIterator match = matchVec.begin(); match != matchVec.end(); ++match) {
00077     // reset pointers
00078     resetCandidates();
00079     // build hypothesis
00080     buildHypo(evt, leps, mets, jets, *match, idMatch++);
00081     pOut->push_back( std::make_pair(hypo(), *match) );
00082   }
00083   // feed out hyps and matches
00084   evt.put(pOut);
00085 
00086   // build and feed out key
00087   buildKey();
00088   *pKey=key();
00089   evt.put(pKey, "Key");
00090 
00091   // feed out number of real neutrino solutions
00092   *pNeutrinoSolutions=numberOfRealNeutrinoSolutions_;
00093   evt.put(pNeutrinoSolutions, "NumberOfRealNeutrinoSolutions");
00094 }
00095 
00097 void
00098 TtSemiLepHypothesis::resetCandidates()
00099 {
00100   numberOfRealNeutrinoSolutions_ = -1;
00101   lightQ_    = 0;
00102   lightQBar_ = 0;
00103   hadronicB_ = 0;
00104   leptonicB_ = 0;
00105   neutrino_  = 0;
00106   lepton_    = 0;
00107 }
00108 
00110 reco::CompositeCandidate
00111 TtSemiLepHypothesis::hypo()
00112 {
00113   // check for sanity of the hypothesis
00114   if( !lightQ_ || !lightQBar_ || !hadronicB_ || 
00115       !leptonicB_ || !neutrino_ || !lepton_ )
00116     return reco::CompositeCandidate();
00117   
00118   // setup transient references
00119   reco::CompositeCandidate hyp, hadTop, hadW, lepTop, lepW;
00120 
00121   AddFourMomenta addFourMomenta;  
00122   // build up the top branch that decays leptonically
00123   lepW  .addDaughter(*lepton_,   TtSemiLepDaughter::Lep    );
00124   lepW  .addDaughter(*neutrino_, TtSemiLepDaughter::Nu     );
00125   addFourMomenta.set( lepW );
00126   lepTop.addDaughter( lepW,      TtSemiLepDaughter::LepW   );
00127   lepTop.addDaughter(*leptonicB_,TtSemiLepDaughter::LepB   );
00128   addFourMomenta.set( lepTop );
00129   
00130   // build up the top branch that decays hadronically
00131   hadW  .addDaughter(*lightQ_,   TtSemiLepDaughter::HadP   );
00132   hadW  .addDaughter(*lightQBar_,TtSemiLepDaughter::HadQ   );
00133   addFourMomenta.set( hadW );
00134   hadTop.addDaughter( hadW,      TtSemiLepDaughter::HadW   );
00135   hadTop.addDaughter(*hadronicB_,TtSemiLepDaughter::HadB   );
00136   addFourMomenta.set( hadTop );
00137 
00138   // build ttbar hypotheses
00139   hyp.addDaughter( lepTop,       TtSemiLepDaughter::LepTop );
00140   hyp.addDaughter( hadTop,       TtSemiLepDaughter::HadTop );
00141   addFourMomenta.set( hyp );
00142 
00143   return hyp;
00144 }
00145 
00147 WDecay::LeptonType
00148 TtSemiLepHypothesis::leptonType(const reco::RecoCandidate* cand)
00149 {
00150   // check whetherwe are dealing with a reco muon or a reco electron
00151   WDecay::LeptonType type = WDecay::kNone;
00152   if( dynamic_cast<const reco::Muon*>(cand) ){
00153     type = WDecay::kMuon;
00154   } 
00155   else if( dynamic_cast<const reco::GsfElectron*>(cand) ){
00156     type = WDecay::kElec;
00157   }
00158   return type;
00159 }
00160 
00162 std::string
00163 TtSemiLepHypothesis::jetCorrectionLevel(const std::string& quarkType)
00164 {
00165   // jetCorrectionLevel was not configured
00166   if(jetCorrectionLevel_.empty())
00167     throw cms::Exception("Configuration")
00168       << "Unconfigured jetCorrectionLevel. Please use an appropriate, non-empty string.\n";
00169 
00170   // quarkType is unknown
00171   if( !(quarkType=="wQuarkMix" ||
00172         quarkType=="udsQuark" ||
00173         quarkType=="cQuark" ||
00174         quarkType=="bQuark") )
00175     throw cms::Exception("Configuration")
00176       << quarkType << " is unknown as a quarkType for the jetCorrectionLevel.\n";
00177 
00178   // combine correction level; start with a ':' even if 
00179   // there is no flavor tag to be added, as it is needed
00180   // by setCandidate to disentangle the correction tag 
00181   // from a potential flavor tag, which can be empty
00182   std::string level=jetCorrectionLevel_+":";
00183   if( level=="L5Flavor:" || level=="L6UE:" || level=="L7Parton:" ){
00184     if(quarkType=="wQuarkMix"){level+="wMix";}
00185     if(quarkType=="udsQuark" ){level+="uds";}
00186     if(quarkType=="cQuark"   ){level+="charm";}
00187     if(quarkType=="bQuark"   ){level+="bottom";}
00188   }
00189   else{
00190     level+="none";
00191   }
00192   return level;
00193 }
00194 
00196 void 
00197 TtSemiLepHypothesis::setCandidate(const edm::Handle<std::vector<pat::Jet> >& handle, const int& idx,
00198                                   reco::ShallowClonePtrCandidate*& clone, const std::string& correctionLevel)
00199 {
00200   edm::Ptr<pat::Jet> ptr = edm::Ptr<pat::Jet>(handle, idx);
00201   // disentangle the correction from the potential flavor tag 
00202   // by the separating ':'; the flavor tag can be empty though
00203   std::string step   = correctionLevel.substr(0,correctionLevel.find(":"));
00204   std::string flavor = correctionLevel.substr(1+correctionLevel.find(":"));
00205   float corrFactor = 1.;
00206   if(flavor=="wMix")
00207     corrFactor = 0.75*ptr->jecFactor(step, "uds") + 0.25*ptr->jecFactor(step, "charm");
00208   else
00209     corrFactor = ptr->jecFactor(step, flavor);
00210   clone = new reco::ShallowClonePtrCandidate( ptr, ptr->charge(), ptr->p4()*corrFactor, ptr->vertex() );
00211 }
00212 
00214 void TtSemiLepHypothesis::setNeutrino(const edm::Handle<std::vector<pat::MET> >& met,
00215                                       const edm::Handle<edm::View<reco::RecoCandidate> >& leps, const int& idx, const int& type)
00216 {
00217   edm::Ptr<pat::MET> ptr = edm::Ptr<pat::MET>(met, 0);
00218   MEzCalculator mez;
00219   mez.SetMET( *(met->begin()) );
00220   if( leptonType( &(leps->front()) ) == WDecay::kMuon )
00221     mez.SetLepton( (*leps)[idx], true );
00222   else if( leptonType( &(leps->front()) ) == WDecay::kElec )
00223     mez.SetLepton( (*leps)[idx], false );
00224   else
00225     throw cms::Exception("UnimplementedFeature") << "Type of lepton given together with MET for solving neutrino kinematics is neither muon nor electron.\n";
00226   double pz = mez.Calculate(type);
00227   numberOfRealNeutrinoSolutions_ = mez.IsComplex() ? 0 : 2;
00228   const math::XYZTLorentzVector p4( ptr->px(), ptr->py(), pz, sqrt(ptr->px()*ptr->px() + ptr->py()*ptr->py() + pz*pz) );
00229   neutrino_ = new reco::ShallowClonePtrCandidate( ptr, ptr->charge(), p4, ptr->vertex() );
00230 }