CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/RecoParticleFlow/PFRootEvent/src/FastJetFWLiteWrapper.cc

Go to the documentation of this file.
00001 // File: FastJetFWLiteWrapper.cc
00002 // Description:  see FastJetProducer.h
00003 // Author:  Andreas Oehler, University Karlsruhe (TH)
00004 // Author:  Dorian Kcira, Institut de Physique Nucleaire,
00005 //          Departement de Physique, Universite Catholique de Louvain
00006 // Author:  Joanna Weng, IPP, ETH Zurich
00007 // Creation Date:  Nov. 06 2006 Initial version.
00008 //--------------------------------------------
00009  
00010 #include "DataFormats/Candidate/interface/Candidate.h"
00011 #include "RecoParticleFlow/PFRootEvent/interface/ProtoJet.h"
00012 #include "RecoParticleFlow/PFRootEvent/interface/FastJetFWLiteWrapper.h"
00013 #include "fastjet/PseudoJet.hh"
00014 #include "fastjet/ClusterSequence.hh"
00015 #include "fastjet/ClusterSequenceActiveArea.hh"
00016 #include <string.h>
00017 #include "fastjet/ClusterSequence.hh"
00018 #include "fastjet/ClusterSequenceActiveArea.hh"
00019 //  Wrapper around fastjet-package written by Matteo Cacciari and Gavin Salam.
00020 //
00021 //  The algorithms that underlie FastJet have required considerable
00022 //  development and are described in hep-ph/0512210. If you use
00023 //  FastJet as part of work towards a scientific publication, please
00024 //  include a citation to the FastJet paper.
00025 //
00026 //  Also see: https://www.lpthe.jussieu.fr/~salam/fastjet/
00027 
00028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00029 
00030 using namespace edm;
00031 using namespace std;
00032 
00033 FastJetFWLiteWrapper::~FastJetFWLiteWrapper(){
00034   delete mJetDefinition;
00035   delete mActiveArea;
00036 }
00037 
00038 FastJetFWLiteWrapper::FastJetFWLiteWrapper()
00039   : mJetDefinition (0), 
00040     mActiveArea (0)
00041 {
00042 
00043   //default ktRParam should be 1
00044   theRparam_=1;
00045   //default PtMin should be 10
00046   thePtMin_=10.;
00047   //default JetFinder should be "kt_algorithm"
00048   string JetFinder="kt_algorithm";; 
00049   //default Strategy should be "Best" 
00050   string Strategy="Best";
00051   //default dcut should be -1 (off)
00052   theDcut_=-1.;
00053   //default njets should be -1 (off)
00054   theNjets_=-1;  
00055   //default UE_Subtraction should be false (off)
00056   theDoSubtraction_=false; 
00057   //default Ghost_EtaMax should be 6
00058   theGhost_EtaMax_=6;
00059   //default Active_Area_Repeats 5
00060   theActive_Area_Repeats_=5;
00061   //default GhostArea 0.01  
00062   theGhostArea_=0.01;
00063   mActiveArea = new fastjet::ActiveAreaSpec ( theGhost_EtaMax_, theActive_Area_Repeats_ , theGhostArea_);       
00064 
00065   
00066   //configuring algorithm 
00067   
00068   
00069   fastjet::JetFinder jet_finder;
00070   if (JetFinder=="cambridge_algorithm") jet_finder=fastjet::cambridge_algorithm;
00071   else jet_finder=fastjet::kt_algorithm;
00072         
00073   //choosing search-strategy:
00074         
00075   fastjet::Strategy strategy;
00076   if (Strategy=="N2Plain") strategy=fastjet::N2Plain;
00077   // N2Plain is best for N<50
00078   else if (Strategy=="N2Tiled") strategy=fastjet::N2Tiled;
00079   // N2Tiled is best for 50<N<400
00080   else if (Strategy=="N2MinHeapTiled") strategy=fastjet::N2MinHeapTiled;
00081   // N2MinHeapTiles is best for 400<N<15000
00082   else if (Strategy=="NlnN") strategy=fastjet::NlnN;
00083   // NlnN is best for N>15000
00084   else if (Strategy=="NlnNCam") strategy=fastjet::NlnNCam;
00085   // NlnNCam is best for N>6000
00086   else strategy=fastjet::Best;
00087   // Chooses best Strategy for every event, depending on N and ktRParam
00088         
00089   //additional strategies are possible, but not documented in the manual as they are experimental,
00090   //they are also not used by the "Best" method. Note: "NlnNCam" only works with 
00091   //the cambridge_algorithm and does not link against CGAL, "NlnN" is only 
00092   //available if fastjet is linked against CGAL.
00093   //The above given numbers of N are for ktRaram=1.0, for other ktRParam the numbers would be 
00094   //different.
00095   
00096   theMode_=0;
00097   if ((theNjets_!=-1)&&(theDcut_==-1)){
00098     theMode_=3;
00099   }
00100   else if ((theNjets_==-1)&&(theDcut_!=-1)){
00101     theMode_=2;
00102   }
00103   else if ((theNjets_!=-1)&&(theDcut_!=-1)){
00104     cout  <<"[FastJetWrapper] `njets` and `dcut` set!=-1! - running inclusive Mode"<<endl;
00105     theMode_=1;
00106   }
00107   else {
00108     theMode_=0;     
00109   }
00110         
00111   // theJetConfig_->theJetDef=fastjet::JetDefinition(jet_finder, theRparam_, strategy);
00112   cout <<"*******************************************"<<endl;
00113   cout <<"* Configuration of FastJet                "<<endl;
00114   if (theDoSubtraction_) cout <<"* running with ActiveAreaSubtraction(median)"<<endl;
00115   switch (theMode_){
00116   case 0:
00117     cout <<"* Mode     : inclusive"<<endl;
00118     cout <<"* PtMin    : "<<thePtMin_<<endl;
00119     break;
00120   case 1:
00121     cout <<"* [WARNING] Mode     : inclusive - dcut and njets set!"<<endl;
00122     cout <<"* PtMin    : "<<thePtMin_<<endl;
00123     break;
00124   case 2:    
00125     cout <<"* Mode     : exclusive"<<endl;
00126     cout <<"* dcut     : "<<theDcut_<<endl;
00127     break;
00128   case 3:
00129     cout <<"* Mode     : exclusive"<<endl;
00130     cout <<"* njets    : "<<theNjets_<<endl;
00131     break;
00132   }
00133   cout <<"* Rparam   : "<<theRparam_<<endl;
00134   cout <<"* JetFinder: "<<JetFinder<<endl;
00135   cout <<"* Strategy : "<<Strategy<<endl;
00136   cout <<"*******************************************"<<endl;
00137   
00138 }
00139 
00140 void FastJetFWLiteWrapper::run(const JetReco::InputCollection& fInput, JetReco::OutputCollection* fOutput) {
00141   if (!fOutput) return;
00142   fOutput->clear();
00143   
00144   // convert inputs
00145   std::vector<fastjet::PseudoJet> fjInputs;
00146   fjInputs.reserve (fInput.size());
00147   
00148   JetReco::InputCollection::const_iterator input = fInput.begin();
00149   for (unsigned i = 0; i < fInput.size(); ++i) {
00150     const JetReco::InputItem& c = fInput[i];
00151     fjInputs.push_back (fastjet::PseudoJet (c->px(),c->py(),c->pz(),c->energy()));
00152     fjInputs.back().set_user_index(i);
00153   }
00154    
00155   // create an object that represents your choice of jet finder and 
00156   // the associated parameters
00157   // run the jet clustering with the above jet definition
00158 
00159   // here we need to keep both pointers, as "area" interfaces are missing in base class
00160   fastjet::ClusterSequenceActiveArea* clusterSequenceWithArea = 0;
00161   fastjet::ClusterSequenceWithArea* clusterSequence = 0;
00162   //  if (mActiveArea) {
00163   // clusterSequenceWithArea = new fastjet::ClusterSequenceActiveArea (fjInputs, *mJetDefinition, *mActiveArea);
00164   // clusterSequence = clusterSequenceWithArea;
00165   // }
00166   // else {
00167   clusterSequence = new fastjet::ClusterSequenceWithArea (fjInputs, *mJetDefinition);
00168   // }
00169   // retrieve jets for selected mode
00170   std::vector<fastjet::PseudoJet> jets = clusterSequence->inclusive_jets (thePtMin_);
00171 
00172   // get PU pt
00173   double median_Pt_Per_Area = clusterSequenceWithArea ? clusterSequenceWithArea->pt_per_unit_area() : 0.;
00174 
00175   // process found jets
00176   for (std::vector<fastjet::PseudoJet>::const_iterator jet=jets.begin(); jet!=jets.end();++jet) {
00177     // jet itself
00178     double px=jet->px();
00179     double py=jet->py();
00180     double pz=jet->pz();
00181     double E=jet->E();
00182     double jetArea=clusterSequence->area(*jet);
00183     double pu=0.;
00184     // PU subtraction
00185     if (clusterSequenceWithArea) {
00186       fastjet::PseudoJet pu_p4 = median_Pt_Per_Area * clusterSequenceWithArea->area_4vector(*jet);
00187       pu = pu_p4.E();
00188       if (pu_p4.perp2() >= jet->perp2() || pu_p4.E() >= jet->E()) { // if the correction is too large, set the jet to zero
00189         px = py = pz = E = 0.;
00190       } 
00191       else {   // otherwise do an E-scheme subtraction
00192         px -= pu_p4.px();
00193         py -= pu_p4.py();
00194         pz -= pu_p4.pz();
00195         E -= pu_p4.E();
00196       }
00197     }
00198     math::XYZTLorentzVector p4(px,py,pz,E);
00199     // constituents
00200     std::vector<fastjet::PseudoJet> fastjet_constituents = clusterSequence->constituents(*jet);
00201     JetReco::InputCollection jetConstituents; 
00202     jetConstituents.reserve (fastjet_constituents.size());
00203     for (std::vector<fastjet::PseudoJet>::const_iterator itConst=fastjet_constituents.begin();
00204          itConst!=fastjet_constituents.end();itConst++){
00205       jetConstituents.push_back(fInput[(*itConst).user_index()]);
00206     }
00207     // Build ProtoJet
00208     fOutput->push_back(ProtoJet(p4,jetConstituents));
00209     fOutput->back().setJetArea (jetArea);
00210     fOutput->back().setPileup (pu);
00211   }
00212   // cleanup
00213   if (clusterSequenceWithArea) delete clusterSequenceWithArea;
00214   else delete clusterSequence; // sigh... No plymorphism in fastjet
00215 }
00216 
00217