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
00023 virtual void produce(edm::Event&, const edm::EventSetup&);
00024
00025
00026 TtSemiLepKinFitter::Param param(unsigned);
00027
00028 TtSemiLepKinFitter::Constraint constraint(unsigned);
00029
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
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
00149
00150
00151
00152 if( leps->empty() || mets->empty() || jets->size()<nPartons || unvalidMatch ) {
00153
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
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
00166 pChi2->push_back( -1. );
00167
00168 pProb->push_back( -1. );
00169
00170 pStatus->push_back( -1 );
00171
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
00187
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
00209
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
00221 int status = fitter->fit(jetCombi, (*leps)[0], (*mets)[0]);
00222
00223 if( status != -10 ) {
00224
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;
00242 next_permutation( combi.begin(), combi.end() );
00243 }
00244 if(useOnlyMatch_) break;
00245 }
00246 while(stdcomb::next_combination( jetIndices.begin(), jetIndices.end(), combi.begin(), combi.end() ));
00247
00248
00249 FitResultList.sort();
00250
00251
00252
00253
00254
00255
00256 if( FitResultList.size() < 1 ) {
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
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
00269 pChi2->push_back( -1. );
00270
00271 pProb->push_back( -1. );
00272
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
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
00286 pLeptons->push_back( result->LepL );
00287
00288 pNeutrinos->push_back( result->LepN );
00289
00290 pCombi->push_back( result->JetCombi );
00291
00292 pChi2->push_back( result->Chi2 );
00293
00294 pProb->push_back( result->Prob );
00295
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