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
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
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
00078 resetCandidates();
00079
00080 buildHypo(evt, leps, mets, jets, *match, idMatch++);
00081 pOut->push_back( std::make_pair(hypo(), *match) );
00082 }
00083
00084 evt.put(pOut);
00085
00086
00087 buildKey();
00088 *pKey=key();
00089 evt.put(pKey, "Key");
00090
00091
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
00114 if( !lightQ_ || !lightQBar_ || !hadronicB_ ||
00115 !leptonicB_ || !neutrino_ || !lepton_ )
00116 return reco::CompositeCandidate();
00117
00118
00119 reco::CompositeCandidate hyp, hadTop, hadW, lepTop, lepW;
00120
00121 AddFourMomenta addFourMomenta;
00122
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
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
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
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
00166 if(jetCorrectionLevel_.empty())
00167 throw cms::Exception("Configuration")
00168 << "Unconfigured jetCorrectionLevel. Please use an appropriate, non-empty string.\n";
00169
00170
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
00179
00180
00181
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
00202
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 }