CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/TopQuarkAnalysis/TopJetCombination/plugins/TtSemiLepJetCombMVATrainer.cc

Go to the documentation of this file.
00001 #include "TMath.h"
00002 #include <algorithm>
00003 
00004 #include "DataFormats/PatCandidates/interface/Jet.h"
00005 #include "DataFormats/PatCandidates/interface/MET.h"
00006 #include "DataFormats/RecoCandidate/interface/RecoCandidate.h"
00007 
00008 #include "AnalysisDataFormats/TopObjects/interface/TtGenEvent.h"
00009 #include "AnalysisDataFormats/TopObjects/interface/TtSemiLepEvtPartons.h"
00010 
00011 #include "TopQuarkAnalysis/TopJetCombination/interface/TtSemiLepJetCombEval.h"
00012 #include "TopQuarkAnalysis/TopJetCombination/plugins/TtSemiLepJetCombMVATrainer.h"
00013 
00014 #include "PhysicsTools/JetMCUtils/interface/combination.h"
00015 #include "PhysicsTools/MVATrainer/interface/HelperMacros.h"
00016 
00017 TtSemiLepJetCombMVATrainer::TtSemiLepJetCombMVATrainer(const edm::ParameterSet& cfg):
00018   leps_      (cfg.getParameter<edm::InputTag>("leps"    )),
00019   jets_      (cfg.getParameter<edm::InputTag>("jets"    )),
00020   mets_      (cfg.getParameter<edm::InputTag>("mets"    )),
00021   matching_  (cfg.getParameter<edm::InputTag>("matching")),
00022   maxNJets_  (cfg.getParameter<int>          ("maxNJets")),
00023   leptonType_(readLeptonType(cfg.getParameter<std::string>("leptonType")))
00024 {
00025 }
00026 
00027 TtSemiLepJetCombMVATrainer::~TtSemiLepJetCombMVATrainer()
00028 {
00029 }
00030 
00031 void 
00032 TtSemiLepJetCombMVATrainer::beginJob()
00033 {
00034   for(unsigned int i = 0; i < 5; i++)
00035     nEvents[i] = 0;
00036 }
00037 
00038 void
00039 TtSemiLepJetCombMVATrainer::analyze(const edm::Event& evt, const edm::EventSetup& setup)
00040 {
00041   mvaComputer.update<TtSemiLepJetCombMVARcd>("trainer", setup, "ttSemiLepJetCombMVA");
00042 
00043   // can occur in the last iteration when the 
00044   // MVATrainer is about to save the result
00045   if(!mvaComputer) return;
00046 
00047   nEvents[0]++;
00048 
00049   edm::Handle<TtGenEvent> genEvt;
00050   evt.getByLabel("genEvt", genEvt);
00051 
00052   edm::Handle< edm::View<reco::RecoCandidate> > leptons; 
00053   evt.getByLabel(leps_, leptons);
00054 
00055   // skip events with no appropriate lepton candidate
00056   if( leptons->empty() ) return;
00057 
00058   nEvents[1]++;
00059 
00060   const math::XYZTLorentzVector lepton = leptons->begin()->p4();
00061 
00062   edm::Handle< std::vector<pat::MET> > mets;
00063   evt.getByLabel(mets_, mets);
00064 
00065   // skip events with empty METs vector
00066   if( mets->empty() ) return;
00067 
00068   nEvents[2]++;
00069 
00070   const pat::MET *met = &(*mets)[0];
00071 
00072   edm::Handle< std::vector<pat::Jet> > jets;
00073   evt.getByLabel(jets_, jets);
00074 
00075   // skip events with less jets than partons
00076   unsigned int nPartons = 4;
00077   if( jets->size() < nPartons ) return;
00078 
00079   nEvents[3]++;
00080 
00081   edm::Handle< std::vector< std::vector<int> > > matchingHandle;
00082   std::vector<int> matching;
00083   // get jet-parton matching if signal channel
00084   if(genEvt->semiLeptonicChannel() == leptonType_) {
00085     evt.getByLabel(matching_, matchingHandle);
00086     if( matchingHandle->empty() )
00087       throw cms::Exception("EmptyProduct")
00088         << "Empty vector from jet-parton matching. This should not happen! \n";
00089     matching = *(matchingHandle->begin());
00090     if(matching.size() < nPartons) return;
00091     // skip events that were affected by the outlier 
00092     // rejection in the jet-parton matching
00093     for(unsigned int i = 0; i < matching.size(); ++i) {
00094       if(matching[i] == -3) continue; // -3: parton was chosen to be excluded from jet-parton matching
00095       if(matching[i] < 0 || matching[i] >= (int)jets->size())
00096         return;
00097     }
00098   }
00099   // use dummy for matching if not signal channel
00100   else
00101     for(unsigned int i = 0; i < nPartons; i++)
00102       matching.push_back( -1 );
00103 
00104   nEvents[4]++;
00105 
00106   // take into account indistinguishability of the two jets from the hadr. W decay,
00107   // reduces combinatorics by a factor of 2
00108   if(matching[TtSemiLepEvtPartons::LightQ] > matching[TtSemiLepEvtPartons::LightQBar]) {
00109     int iTemp = matching[TtSemiLepEvtPartons::LightQ];
00110     matching[TtSemiLepEvtPartons::LightQ] = matching[TtSemiLepEvtPartons::LightQBar];
00111     matching[TtSemiLepEvtPartons::LightQBar] = iTemp;
00112   }
00113 
00114   std::vector<int> jetIndices;
00115   for(unsigned int i=0; i<jets->size(); ++i) {
00116     if(maxNJets_ >= (int) nPartons && i == (unsigned int) maxNJets_) break;
00117     jetIndices.push_back(i);
00118   }
00119 
00120   std::vector<int> combi;
00121   for(unsigned int i = 0; i < nPartons; ++i) 
00122     combi.push_back(i);
00123 
00124   // use a ValueList to collect all variables for the MVAComputer
00125   PhysicsTools::Variable::ValueList values;
00126 
00127   // set target variable to false like for background
00128   // this is necessary when passing all combinations at once
00129   values.add( PhysicsTools::Variable::Value(PhysicsTools::MVATrainer::kTargetId, false) );
00130 
00131   do {
00132     // number of possible combinations from number of partons: e.g. 4! = 24
00133     for(unsigned int cnt = 0; cnt < TMath::Factorial( combi.size() ); ++cnt) {
00134 
00135       // take into account indistinguishability of the two jets from the hadr. W decay,
00136       // reduces combinatorics by a factor of 2
00137       if(combi[TtSemiLepEvtPartons::LightQ] < combi[TtSemiLepEvtPartons::LightQBar]) {
00138         
00139         TtSemiLepJetComb jetComb(*jets, combi, lepton, *met);
00140 
00141         bool trueCombi = false;
00142         // true combination only if signal channel
00143         // and in agreement with matching
00144         if(genEvt->semiLeptonicChannel()==leptonType_) {
00145           trueCombi = true;
00146           for(unsigned int i = 0; i < matching.size(); ++i) {
00147             if(combi[i]!=matching[i] && matching[i]!=-3) {
00148               trueCombi = false;
00149               break;
00150             }
00151           }
00152         }
00153 
00154         // feed MVA input variables for this jetComb into the ValueList
00155         values.add("target", trueCombi);
00156         evaluateTtSemiLepJetComb(values, jetComb);
00157 
00158       }
00159 
00160       next_permutation( combi.begin() , combi.end() );
00161     }
00162   }
00163   while(stdcomb::next_combination( jetIndices.begin(), jetIndices.end(), combi.begin(), combi.end() ));
00164 
00165   // pass MVA input variables for all jet combinations in this event
00166   // to the MVAComputer for training
00167   mvaComputer->eval( values );
00168 }
00169 
00170 void
00171 TtSemiLepJetCombMVATrainer::endJob() 
00172 {
00173   edm::LogInfo log("TtSemiLepJetCombMVATrainer");
00174   log << "Number of events... \n"
00175       << "...passed to the trainer                   : " << std::setw(7) << nEvents[0] << "\n"
00176       << "...rejected since no lepton candidate      : " << std::setw(7) << nEvents[0]-nEvents[1] << "\n"
00177       << "...rejected since no MET object            : " << std::setw(7) << nEvents[1]-nEvents[2] << "\n"
00178       << "...rejected since not enough jets          : " << std::setw(7) << nEvents[2]-nEvents[3] << "\n"
00179       << "...rejected due to bad jet-parton matching : " << std::setw(7) << nEvents[3]-nEvents[4] << "\n"
00180       << "...accepted for training                   : " << std::setw(7) << nEvents[4] << "\n";
00181 }
00182 
00183 WDecay::LeptonType
00184 TtSemiLepJetCombMVATrainer::readLeptonType(const std::string& str)
00185 {
00186   if     (str == "kElec") return WDecay::kElec;
00187   else if(str == "kMuon") return WDecay::kMuon;
00188   else if(str == "kTau" ) return WDecay::kTau;
00189   else throw cms::Exception("Configuration")
00190     << "Chosen leptonType is not supported: " << str << "\n";
00191 }
00192 
00193 // implement the plugins for the trainer
00194 // -> defines TtSemiLepJetCombMVAContainerSaveCondDB
00195 // -> defines TtSemiLepJetCombMVASaveFile
00196 // -> defines TtSemiLepJetCombMVATrainerLooper
00197 MVA_TRAINER_IMPLEMENT(TtSemiLepJetCombMVA);