00001 #ifndef PhysicsTools_SelectorUtils_interface_PFJetIDSelectionFunctor_h
00002 #define PhysicsTools_SelectorUtils_interface_PFJetIDSelectionFunctor_h
00003
00015 #include "DataFormats/PatCandidates/interface/Jet.h"
00016 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00017
00018 #include "PhysicsTools/SelectorUtils/interface/Selector.h"
00019
00020 #include <TMath.h>
00021 class PFJetIDSelectionFunctor : public Selector<pat::Jet> {
00022
00023 public:
00024
00025 enum Version_t { FIRSTDATA, N_VERSIONS };
00026 enum Quality_t { LOOSE, TIGHT, N_QUALITY};
00027
00028 PFJetIDSelectionFunctor() {}
00029
00030 PFJetIDSelectionFunctor( edm::ParameterSet const & params )
00031 {
00032 std::string versionStr = params.getParameter<std::string>("version");
00033 std::string qualityStr = params.getParameter<std::string>("quality");
00034
00035 if ( versionStr == "FIRSTDATA" )
00036 version_ = FIRSTDATA;
00037 else
00038 version_ = FIRSTDATA;
00039
00040 if ( qualityStr == "LOOSE") quality_ = LOOSE;
00041 else if ( qualityStr == "TIGHT") quality_ = TIGHT;
00042 else quality_ = LOOSE;
00043
00044 push_back("CHF" );
00045 push_back("NHF" );
00046 push_back("CEF" );
00047 push_back("NEF" );
00048 push_back("NCH" );
00049 push_back("nConstituents");
00050
00051
00052
00053 if ( quality_ == LOOSE ) {
00054 set("CHF", 0.0);
00055 set("NHF", 0.99);
00056 set("CEF", 0.99);
00057 set("NEF", 0.99);
00058 set("NCH", 0);
00059 set("nConstituents", 1);
00060 } else if ( quality_ == TIGHT ) {
00061 set("CHF", 0.0);
00062 set("NHF", 0.9);
00063 set("CEF", 0.99);
00064 set("NEF", 0.9);
00065 set("NCH", 0);
00066 set("nConstituents", 1);
00067 }
00068
00069
00070
00071 if ( params.exists("CHF") ) set("CHF", params.getParameter<double>("CHF") );
00072 if ( params.exists("NHF") ) set("NHF", params.getParameter<double>("NHF") );
00073 if ( params.exists("CEF") ) set("CEF", params.getParameter<double>("CEF") );
00074 if ( params.exists("NEF") ) set("NEF", params.getParameter<double>("NEF") );
00075 if ( params.exists("NCH") ) set("NCH", params.getParameter<int> ("NCH") );
00076 if ( params.exists("nConstuents") ) set("nConstituents", params.getParameter<int> ("nConstituents") );
00077
00078 if ( params.exists("cutsToIgnore") )
00079 setIgnoredCuts( params.getParameter<std::vector<std::string> >("cutsToIgnore") );
00080
00081
00082 indexNConstituents_ = index_type (&bits_, "nConstituents");
00083 indexNEF_ = index_type (&bits_, "NEF");
00084 indexNHF_ = index_type (&bits_, "NHF");
00085 indexCEF_ = index_type (&bits_, "CEF");
00086 indexCHF_ = index_type (&bits_, "CHF");
00087 indexNCH_ = index_type (&bits_, "NCH");
00088
00089 retInternal_ = getBitTemplate();
00090
00091 }
00092
00093
00094 PFJetIDSelectionFunctor( Version_t version,
00095 Quality_t quality ) :
00096 version_(version), quality_(quality)
00097 {
00098
00099 push_back("CHF" );
00100 push_back("NHF" );
00101 push_back("CEF" );
00102 push_back("NEF" );
00103 push_back("NCH" );
00104 push_back("nConstituents");
00105
00106
00107
00108 if ( quality_ == LOOSE ) {
00109 set("CHF", 0.0);
00110 set("NHF", 0.99);
00111 set("CEF", 0.99);
00112 set("NEF", 0.99);
00113 set("NCH", 0);
00114 set("nConstituents", 1);
00115 } else if ( quality_ == TIGHT ) {
00116 set("CHF", 0.0);
00117 set("NHF", 0.9);
00118 set("CEF", 0.99);
00119 set("NEF", 0.9);
00120 set("NCH", 0);
00121 set("nConstituents", 1);
00122 }
00123
00124
00125 indexNConstituents_ = index_type (&bits_, "nConstituents");
00126 indexNEF_ = index_type (&bits_, "NEF");
00127 indexNHF_ = index_type (&bits_, "NHF");
00128 indexCEF_ = index_type (&bits_, "CEF");
00129 indexCHF_ = index_type (&bits_, "CHF");
00130 indexNCH_ = index_type (&bits_, "NCH");
00131
00132 retInternal_ = getBitTemplate();
00133 }
00134
00135
00136
00137
00138
00139 bool operator()( const pat::Jet & jet, pat::strbitset & ret )
00140 {
00141 if ( version_ == FIRSTDATA ) {
00142 if ( jet.currentJECLevel() == "Uncorrected" || !jet.jecSetsAvailable() )
00143 return firstDataCuts( jet, ret );
00144 else
00145 return firstDataCuts( jet.correctedJet("Uncorrected"), ret );
00146 }
00147 else {
00148 return false;
00149 }
00150 }
00151 using Selector<pat::Jet>::operator();
00152
00153
00154
00155
00156
00157 bool operator()( const reco::PFJet & jet, pat::strbitset & ret )
00158 {
00159 if ( version_ == FIRSTDATA ) return firstDataCuts( jet, ret );
00160 else {
00161 return false;
00162 }
00163 }
00164
00165 bool operator()( const reco::PFJet & jet )
00166 {
00167 retInternal_.set(false);
00168 operator()(jet, retInternal_);
00169 setIgnored(retInternal_);
00170 return (bool)retInternal_;
00171 }
00172
00173
00174
00175
00176 bool firstDataCuts( reco::Jet const & jet,
00177 pat::strbitset & ret)
00178 {
00179 ret.set(false);
00180
00181
00182 double chf = 0.0;
00183 double nhf = 0.0;
00184 double cef = 0.0;
00185 double nef = 0.0;
00186 int nch = 0;
00187 int nconstituents = 0;
00188
00189
00190 reco::PFJet const * pfJet = dynamic_cast<reco::PFJet const *>(&jet);
00191 pat::Jet const * patJet = dynamic_cast<pat::Jet const *>(&jet);
00192 reco::BasicJet const * basicJet = dynamic_cast<reco::BasicJet const *>(&jet);
00193
00194 if ( patJet != 0 ) {
00195 if ( patJet->isPFJet() ) {
00196 chf = patJet->chargedHadronEnergyFraction();
00197 nhf = ( patJet->neutralHadronEnergy() + patJet->HFHadronEnergy() ) / patJet->energy();
00198 cef = patJet->chargedEmEnergyFraction();
00199 nef = patJet->neutralEmEnergyFraction();
00200 nch = patJet->chargedMultiplicity();
00201 nconstituents = patJet->numberOfDaughters();
00202 }
00203
00204
00205 else if ( patJet->isBasicJet() ) {
00206 double e_chf = 0.0;
00207 double e_nhf = 0.0;
00208 double e_cef = 0.0;
00209 double e_nef = 0.0;
00210 nch = 0;
00211 nconstituents = 0;
00212
00213 for ( reco::Jet::const_iterator ibegin = patJet->begin(),
00214 iend = patJet->end(), isub = ibegin;
00215 isub != iend; ++isub ) {
00216 reco::PFJet const * pfsub = dynamic_cast<reco::PFJet const *>( &*isub );
00217 e_chf += pfsub->chargedHadronEnergy();
00218 e_nhf += (pfsub->neutralHadronEnergy() + pfsub->HFHadronEnergy());
00219 e_cef += pfsub->chargedEmEnergy();
00220 e_nef += pfsub->neutralEmEnergy();
00221 nch += pfsub->chargedMultiplicity();
00222 nconstituents += pfsub->numberOfDaughters();
00223 }
00224 double e = patJet->energy();
00225 if ( e > 0.000001 ) {
00226 chf = e_chf / e;
00227 nhf = e_nhf / e;
00228 cef = e_cef / e;
00229 nef = e_nef / e;
00230 } else {
00231 chf = nhf = cef = nef = 0.0;
00232 }
00233 }
00234 }
00235 else if ( pfJet != 0 ) {
00236
00237 double jetEnergyUncorrected =
00238 pfJet->chargedHadronEnergy()
00239 + pfJet->neutralHadronEnergy()
00240 + pfJet->photonEnergy()
00241 + pfJet->electronEnergy()
00242 + pfJet->muonEnergy()
00243 + pfJet->HFHadronEnergy()
00244 + pfJet->HFEMEnergy();
00245 if ( jetEnergyUncorrected > 0. ) {
00246 chf = pfJet->chargedHadronEnergy() / jetEnergyUncorrected;
00247 nhf = ( pfJet->neutralHadronEnergy() + pfJet->HFHadronEnergy() ) / jetEnergyUncorrected;
00248 cef = pfJet->chargedEmEnergy() / jetEnergyUncorrected;
00249 nef = pfJet->neutralEmEnergy() / jetEnergyUncorrected;
00250 }
00251 nch = pfJet->chargedMultiplicity();
00252 nconstituents = pfJet->numberOfDaughters();
00253 }
00254
00255
00256 else if ( basicJet != 0 ) {
00257 double e_chf = 0.0;
00258 double e_nhf = 0.0;
00259 double e_cef = 0.0;
00260 double e_nef = 0.0;
00261 nch = 0;
00262 nconstituents = 0;
00263
00264 for ( reco::Jet::const_iterator ibegin = basicJet->begin(),
00265 iend = patJet->end(), isub = ibegin;
00266 isub != iend; ++isub ) {
00267 reco::PFJet const * pfsub = dynamic_cast<reco::PFJet const *>( &*isub );
00268 e_chf += pfsub->chargedHadronEnergy();
00269 e_nhf += (pfsub->neutralHadronEnergy() + pfsub->HFHadronEnergy());
00270 e_cef += pfsub->chargedEmEnergy();
00271 e_nef += pfsub->neutralEmEnergy();
00272 nch += pfsub->chargedMultiplicity();
00273 nconstituents += pfsub->numberOfDaughters();
00274 }
00275 double e = basicJet->energy();
00276 if ( e > 0.000001 ) {
00277 chf = e_chf / e;
00278 nhf = e_nhf / e;
00279 cef = e_cef / e;
00280 nef = e_nef / e;
00281 }
00282 }
00283
00284
00285
00286 if ( ignoreCut(indexNConstituents_) || nconstituents > cut(indexNConstituents_, int() ) ) passCut( ret, indexNConstituents_);
00287 if ( ignoreCut(indexNEF_) || ( nef < cut(indexNEF_, double()) ) ) passCut( ret, indexNEF_);
00288 if ( ignoreCut(indexNHF_) || ( nhf < cut(indexNHF_, double()) ) ) passCut( ret, indexNHF_);
00289
00290 if ( ignoreCut(indexCEF_) || ( cef < cut(indexCEF_, double()) || std::abs(jet.eta()) > 2.4 ) ) passCut( ret, indexCEF_);
00291 if ( ignoreCut(indexCHF_) || ( chf > cut(indexCHF_, double()) || std::abs(jet.eta()) > 2.4 ) ) passCut( ret, indexCHF_);
00292 if ( ignoreCut(indexNCH_) || ( nch > cut(indexNCH_, int()) || std::abs(jet.eta()) > 2.4 ) ) passCut( ret, indexNCH_);
00293
00294
00295
00296
00297
00298 setIgnored( ret );
00299 return (bool)ret;
00300 }
00301
00302 private:
00303
00304 Version_t version_;
00305 Quality_t quality_;
00306
00307 index_type indexNConstituents_;
00308 index_type indexNEF_;
00309 index_type indexNHF_;
00310 index_type indexCEF_;
00311 index_type indexCHF_;
00312 index_type indexNCH_;
00313
00314 };
00315
00316 #endif