CMS 3D CMS Logo

TtSemiLepKinFitProducer.h

Go to the documentation of this file.
00001 #ifndef TtSemiLepKinFitProducer_h
00002 #define TtSemiLepKinFitProducer_h
00003 
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "FWCore/Framework/interface/EDProducer.h"
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007 
00008 #include "PhysicsTools/JetMCUtils/interface/combination.h"
00009 #include "AnalysisDataFormats/TopObjects/interface/TtGenEvent.h"
00010 #include "TopQuarkAnalysis/TopKinFitter/interface/TtSemiLepKinFitter.h"
00011 
00012 
00013 template <typename LeptonCollection>
00014 class TtSemiLepKinFitProducer : public edm::EDProducer {
00015   
00016  public:
00017   
00018   explicit TtSemiLepKinFitProducer(const edm::ParameterSet&);
00019   ~TtSemiLepKinFitProducer();
00020   
00021  private:
00022   // produce
00023   virtual void produce(edm::Event&, const edm::EventSetup&);
00024 
00025   // convert unsigned to Param
00026   TtSemiLepKinFitter::Param param(unsigned);
00027   // convert unsigned to Param
00028   TtSemiLepKinFitter::Constraint constraint(unsigned);
00029   // convert unsigned to Param
00030   std::vector<TtSemiLepKinFitter::Constraint> constraints(std::vector<unsigned>&);
00031   
00032   edm::InputTag jets_;
00033   edm::InputTag leps_;
00034   edm::InputTag mets_;
00035   
00036   edm::InputTag match_;
00037   bool useOnlyMatch_;
00038   
00039   int maxNJets_;
00040   int maxNComb_;
00041   
00042   unsigned int maxNrIter_;
00043   double maxDeltaS_;
00044   double maxF_;
00045   unsigned int jetParam_;
00046   unsigned int lepParam_;
00047   unsigned int metParam_;
00048   std::vector<unsigned> constraints_;
00049 
00050   TtSemiLepKinFitter* fitter;
00051 
00052   struct KinFitResult {
00053     int Status;
00054     double Chi2;
00055     double Prob;
00056     pat::Particle HadB;
00057     pat::Particle HadP;
00058     pat::Particle HadQ;
00059     pat::Particle LepB;
00060     pat::Particle LepL;
00061     pat::Particle LepN;
00062     std::vector<int> JetCombi;
00063     bool operator< (const KinFitResult& rhs) { return Chi2 < rhs.Chi2; };
00064   };
00065 };
00066 
00067 template<typename LeptonCollection>
00068 TtSemiLepKinFitProducer<LeptonCollection>::TtSemiLepKinFitProducer(const edm::ParameterSet& cfg):
00069   jets_        (cfg.getParameter<edm::InputTag>("jets")),
00070   leps_        (cfg.getParameter<edm::InputTag>("leps")),
00071   mets_        (cfg.getParameter<edm::InputTag>("mets")),
00072   match_       (cfg.getParameter<edm::InputTag>("match")),
00073   useOnlyMatch_(cfg.getParameter<bool>             ("useOnlyMatch"      )),
00074   maxNJets_    (cfg.getParameter<int>              ("maxNJets"          )),
00075   maxNComb_    (cfg.getParameter<int>              ("maxNComb"          )),
00076   maxNrIter_   (cfg.getParameter<unsigned>         ("maxNrIter"         )),
00077   maxDeltaS_   (cfg.getParameter<double>           ("maxDeltaS"         )),
00078   maxF_        (cfg.getParameter<double>           ("maxF"              )),
00079   jetParam_    (cfg.getParameter<unsigned>         ("jetParametrisation")),
00080   lepParam_    (cfg.getParameter<unsigned>         ("lepParametrisation")),
00081   metParam_    (cfg.getParameter<unsigned>         ("metParametrisation")),
00082   constraints_ (cfg.getParameter<std::vector<unsigned> >("constraints"  ))
00083 {
00084   fitter = new TtSemiLepKinFitter(param(jetParam_), param(lepParam_), param(metParam_), maxNrIter_, maxDeltaS_, maxF_, constraints(constraints_));
00085 
00086   produces< std::vector<pat::Particle> >("PartonsHadP");
00087   produces< std::vector<pat::Particle> >("PartonsHadQ");
00088   produces< std::vector<pat::Particle> >("PartonsHadB");
00089   produces< std::vector<pat::Particle> >("PartonsLepB");
00090   produces< std::vector<pat::Particle> >("Leptons");
00091   produces< std::vector<pat::Particle> >("Neutrinos");
00092 
00093   produces< std::vector<std::vector<int> > >();
00094   produces< std::vector<double> >("Chi2");
00095   produces< std::vector<double> >("Prob");
00096   produces< std::vector<int> >("Status");
00097 }
00098 
00099 template<typename LeptonCollection>
00100 TtSemiLepKinFitProducer<LeptonCollection>::~TtSemiLepKinFitProducer()
00101 {
00102   delete fitter;
00103 }
00104 
00105 template<typename LeptonCollection>
00106 void TtSemiLepKinFitProducer<LeptonCollection>::produce(edm::Event& evt, const edm::EventSetup& setup)
00107 {
00108   std::auto_ptr< std::vector<pat::Particle> > pPartonsHadP( new std::vector<pat::Particle> );
00109   std::auto_ptr< std::vector<pat::Particle> > pPartonsHadQ( new std::vector<pat::Particle> );
00110   std::auto_ptr< std::vector<pat::Particle> > pPartonsHadB( new std::vector<pat::Particle> );
00111   std::auto_ptr< std::vector<pat::Particle> > pPartonsLepB( new std::vector<pat::Particle> );
00112   std::auto_ptr< std::vector<pat::Particle> > pLeptons    ( new std::vector<pat::Particle> );
00113   std::auto_ptr< std::vector<pat::Particle> > pNeutrinos  ( new std::vector<pat::Particle> );
00114 
00115   std::auto_ptr< std::vector<std::vector<int> > > pCombi ( new std::vector<std::vector<int> > );
00116   std::auto_ptr< std::vector<double>            > pChi2  ( new std::vector<double> );
00117   std::auto_ptr< std::vector<double>            > pProb  ( new std::vector<double> );
00118   std::auto_ptr< std::vector<int>               > pStatus( new std::vector<int> );
00119 
00120   edm::Handle<std::vector<pat::Jet> > jets;
00121   evt.getByLabel(jets_, jets);
00122 
00123   edm::Handle<std::vector<pat::MET> > mets;
00124   evt.getByLabel(mets_, mets);
00125 
00126   edm::Handle<LeptonCollection> leps;
00127   evt.getByLabel(leps_, leps);
00128 
00129   unsigned int nPartons = 4;
00130 
00131   edm::Handle<std::vector<int> > match;
00132   bool unvalidMatch = false;
00133   if(useOnlyMatch_) {
00134     evt.getByLabel(match_, match);
00135     // check if match is valid
00136     if(match->size()!=nPartons) unvalidMatch=true;
00137     else {
00138       for(unsigned int idx=0; idx<jets->size(); ++idx) {
00139         if(idx<0 || idx>=jets->size()) {
00140           unvalidMatch=true;
00141           break;
00142         }
00143       }
00144     }
00145   }
00146 
00147   // -----------------------------------------------------
00148   // skip events with no appropriate lepton candidate in
00149   // or empty MET or less jets than partons or unvalid match
00150   // -----------------------------------------------------
00151 
00152   if( leps->empty() || mets->empty() || jets->size()<nPartons || unvalidMatch ) {
00153     // the kinFit getters return empty objects here
00154     pPartonsHadP->push_back( fitter->fittedHadP()     );
00155     pPartonsHadQ->push_back( fitter->fittedHadQ()     );
00156     pPartonsHadB->push_back( fitter->fittedHadB()     );
00157     pPartonsLepB->push_back( fitter->fittedLepB()     );
00158     pLeptons    ->push_back( fitter->fittedLepton()   );
00159     pNeutrinos  ->push_back( fitter->fittedNeutrino() );
00160     // indices referring to the jet combination
00161     std::vector<int> invalidCombi;
00162     for(unsigned int i = 0; i < nPartons; ++i) 
00163       invalidCombi.push_back( -1 );
00164     pCombi->push_back( invalidCombi );
00165     // chi2
00166     pChi2->push_back( -1. );
00167     // chi2 probability
00168     pProb->push_back( -1. );
00169     // status of the fitter
00170     pStatus->push_back( -1 );
00171     // feed out all products
00172     evt.put(pCombi);
00173     evt.put(pPartonsHadP, "PartonsHadP");
00174     evt.put(pPartonsHadQ, "PartonsHadQ");
00175     evt.put(pPartonsHadB, "PartonsHadB");
00176     evt.put(pPartonsLepB, "PartonsLepB");
00177     evt.put(pLeptons    , "Leptons"    );
00178     evt.put(pNeutrinos  , "Neutrinos"  );
00179     evt.put(pChi2       , "Chi2"       );
00180     evt.put(pProb       , "Prob"       );
00181     evt.put(pStatus     , "Status"     );
00182     return;
00183   }
00184 
00185   // -----------------------------------------------------
00186   // analyze different jet combinations using the KinFitter
00187   // (or only a given jet combination if useOnlyMatch=true)
00188   // -----------------------------------------------------
00189   
00190   std::vector<int> jetIndices;
00191   if(!useOnlyMatch_) {
00192     for(unsigned int i=0; i<jets->size(); ++i){
00193       if(maxNJets_ >= (int) nPartons && maxNJets_ == (int) i) break;
00194       jetIndices.push_back(i);
00195     }
00196   }
00197   
00198   std::vector<int> combi;
00199   for(unsigned int i=0; i<nPartons; ++i) {
00200     if(useOnlyMatch_) combi.push_back( (*match)[i] );
00201     else combi.push_back(i);
00202   }
00203 
00204   std::list<KinFitResult> FitResultList;
00205 
00206   do{
00207     for(int cnt = 0; cnt < TMath::Factorial( combi.size() ); ++cnt){
00208       // take into account indistinguishability of the two jets from the hadr. W decay,
00209       // reduces combinatorics by a factor of 2
00210       if( combi[TtSemiLepEvtPartons::LightQ] < combi[TtSemiLepEvtPartons::LightQBar]
00211          || useOnlyMatch_ ) {
00212         
00213         std::vector<pat::Jet> jetCombi;
00214         jetCombi.resize(nPartons);
00215         jetCombi[TtSemiLepEvtPartons::LightQ   ] = (*jets)[combi[TtSemiLepEvtPartons::LightQ   ]];
00216         jetCombi[TtSemiLepEvtPartons::LightQBar] = (*jets)[combi[TtSemiLepEvtPartons::LightQBar]];
00217         jetCombi[TtSemiLepEvtPartons::HadB     ] = (*jets)[combi[TtSemiLepEvtPartons::HadB     ]];
00218         jetCombi[TtSemiLepEvtPartons::LepB     ] = (*jets)[combi[TtSemiLepEvtPartons::LepB     ]];
00219 
00220         // do the kinematic fit
00221         int status = fitter->fit(jetCombi, (*leps)[0], (*mets)[0]);
00222 
00223         if( status != -10 ) { // skip this jet combination if kinematic fit was aborted
00224                               // (due to errors during fitting)
00225           KinFitResult result;
00226           result.Status = status;
00227           result.Chi2 = fitter->fitS();
00228           result.Prob = fitter->fitProb();
00229           result.HadB = fitter->fittedHadB();
00230           result.HadP = fitter->fittedHadP();
00231           result.HadQ = fitter->fittedHadQ();
00232           result.LepB = fitter->fittedLepB();
00233           result.LepL = fitter->fittedLepton();
00234           result.LepN = fitter->fittedNeutrino();
00235           result.JetCombi = combi;
00236 
00237           FitResultList.push_back(result);
00238         }
00239 
00240       }
00241       if(useOnlyMatch_) break; // don't go through combinatorics if useOnlyMatch was chosen
00242       next_permutation( combi.begin(), combi.end() );
00243     }
00244     if(useOnlyMatch_) break; // don't go through combinatorics if useOnlyMatch was chosen
00245   }
00246   while(stdcomb::next_combination( jetIndices.begin(), jetIndices.end(), combi.begin(), combi.end() ));
00247 
00248   // sort results w.r.t. chi2 values
00249   FitResultList.sort();
00250   
00251   // -----------------------------------------------------
00252   // feed out result
00253   // starting with the JetComb having the smallest chi2
00254   // -----------------------------------------------------
00255 
00256   if( FitResultList.size() < 1 ) { // in case no fit results were stored in the list (all fits aborted)
00257     pPartonsHadP->push_back( fitter->fittedHadP()     );
00258     pPartonsHadQ->push_back( fitter->fittedHadQ()     );
00259     pPartonsHadB->push_back( fitter->fittedHadB()     );
00260     pPartonsLepB->push_back( fitter->fittedLepB()     );
00261     pLeptons    ->push_back( fitter->fittedLepton()   );
00262     pNeutrinos  ->push_back( fitter->fittedNeutrino() );
00263     // indices referring to the jet combination
00264     std::vector<int> invalidCombi;
00265     for(unsigned int i = 0; i < nPartons; ++i) 
00266       invalidCombi.push_back( -1 );
00267     pCombi->push_back( invalidCombi );
00268     // chi2
00269     pChi2->push_back( -1. );
00270     // chi2 probability
00271     pProb->push_back( -1. );
00272     // status of the fitter
00273     pStatus->push_back( -1 );
00274   }
00275   else {
00276     unsigned int iComb = 0;
00277     for(typename std::list<KinFitResult>::const_iterator result = FitResultList.begin(); result != FitResultList.end(); ++result) {
00278       if(maxNComb_ >= 1 && iComb == (unsigned int) maxNComb_) break;
00279       iComb++;
00280       // partons
00281       pPartonsHadP->push_back( result->HadP );
00282       pPartonsHadQ->push_back( result->HadQ );
00283       pPartonsHadB->push_back( result->HadB );
00284       pPartonsLepB->push_back( result->LepB );
00285       // lepton
00286       pLeptons->push_back( result->LepL );
00287       // neutrino
00288       pNeutrinos->push_back( result->LepN );
00289       // indices referring to the jet combination
00290       pCombi->push_back( result->JetCombi );
00291       // chi2
00292       pChi2->push_back( result->Chi2 );
00293       // chi2 probability
00294       pProb->push_back( result->Prob );
00295       // status of the fitter
00296       pStatus->push_back( result->Status );
00297     }
00298   }
00299   evt.put(pCombi);
00300   evt.put(pPartonsHadP, "PartonsHadP");
00301   evt.put(pPartonsHadQ, "PartonsHadQ");
00302   evt.put(pPartonsHadB, "PartonsHadB");
00303   evt.put(pPartonsLepB, "PartonsLepB");
00304   evt.put(pLeptons    , "Leptons"    );
00305   evt.put(pNeutrinos  , "Neutrinos"  );
00306   evt.put(pChi2       , "Chi2"       );
00307   evt.put(pProb       , "Prob"       );
00308   evt.put(pStatus     , "Status"     );
00309 }
00310  
00311 template<typename LeptonCollection>
00312 TtSemiLepKinFitter::Param TtSemiLepKinFitProducer<LeptonCollection>::param(unsigned val) 
00313 {
00314   TtSemiLepKinFitter::Param result;
00315   switch(val){
00316   case TtSemiLepKinFitter::kEMom       : result=TtSemiLepKinFitter::kEMom;       break;
00317   case TtSemiLepKinFitter::kEtEtaPhi   : result=TtSemiLepKinFitter::kEtEtaPhi;   break;
00318   case TtSemiLepKinFitter::kEtThetaPhi : result=TtSemiLepKinFitter::kEtThetaPhi; break;
00319   default: 
00320     throw cms::Exception("WrongConfig") 
00321       << "Chosen jet parametrization is not supported: " << val << "\n";
00322     break;
00323   }
00324   return result;
00325 } 
00326 
00327 template<typename LeptonCollection>
00328 TtSemiLepKinFitter::Constraint TtSemiLepKinFitProducer<LeptonCollection>::constraint(unsigned val) 
00329 {
00330   TtSemiLepKinFitter::Constraint result;
00331   switch(val){
00332   case TtSemiLepKinFitter::kWHadMass     : result=TtSemiLepKinFitter::kWHadMass;     break;
00333   case TtSemiLepKinFitter::kWLepMass     : result=TtSemiLepKinFitter::kWLepMass;     break;
00334   case TtSemiLepKinFitter::kTopHadMass   : result=TtSemiLepKinFitter::kTopHadMass;   break;
00335   case TtSemiLepKinFitter::kTopLepMass   : result=TtSemiLepKinFitter::kTopLepMass;   break;
00336   case TtSemiLepKinFitter::kNeutrinoMass : result=TtSemiLepKinFitter::kNeutrinoMass; break;
00337   default: 
00338     throw cms::Exception("WrongConfig") 
00339       << "Chosen fit constraint is not supported: " << val << "\n";
00340     break;
00341   }
00342   return result;
00343 } 
00344 
00345 template<typename LeptonCollection>
00346 std::vector<TtSemiLepKinFitter::Constraint> TtSemiLepKinFitProducer<LeptonCollection>::constraints(std::vector<unsigned>& val)
00347 {
00348   std::vector<TtSemiLepKinFitter::Constraint> result;
00349   for(unsigned i=0; i<val.size(); ++i){
00350     result.push_back(constraint(val[i]));
00351   }
00352   return result; 
00353 }
00354 
00355 #endif

Generated on Tue Jun 9 17:48:14 2009 for CMSSW by  doxygen 1.5.4