00001
00002
00003
00004
00012
00013
00014
00015
00016
00017
00018
00019 #include "HLTrigger/JetMET/interface/HLTHcalMETNoiseCleaner.h"
00020
00021 #include "DataFormats/Common/interface/Handle.h"
00022 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00023 #include "FWCore/Framework/interface/ESHandle.h"
00024 #include "FWCore/Framework/interface/Event.h"
00025 #include "FWCore/Framework/interface/EventSetup.h"
00026
00027 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00028
00029 #include "DataFormats/Candidate/interface/Candidate.h"
00030 #include "DataFormats/METReco/interface/HcalNoiseRBX.h"
00031 #include "DataFormats/METReco/interface/CaloMET.h"
00032 #include "DataFormats/METReco/interface/CaloMETCollection.h"
00033 #include "DataFormats/METReco/interface/SpecificCaloMETData.h"
00034 #include "DataFormats/CaloTowers/interface/CaloTower.h"
00035 #include "DataFormats/CaloTowers/interface/CaloTowerCollection.h"
00036 #include "DataFormats/Math/interface/LorentzVector.h"
00037 #include "DataFormats/Math/interface/Point3D.h"
00038
00039 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00040 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00041 #include "FWCore/Utilities/interface/InputTag.h"
00042
00043 #include <iostream>
00044 #include <string>
00045 #include <fstream>
00046 #include <TVector3.h>
00047 #include <TLorentzVector.h>
00048
00049
00050 HLTHcalMETNoiseCleaner::HLTHcalMETNoiseCleaner(const edm::ParameterSet& iConfig)
00051 : HcalNoiseRBXCollectionTag_(iConfig.getParameter<edm::InputTag>("HcalNoiseRBXCollection")),
00052 CaloMetCollectionTag_(iConfig.getParameter<edm::InputTag>("CaloMetCollection")),
00053 CaloMetCut_(iConfig.getParameter<double>("CaloMetCut")),
00054 severity_(iConfig.getParameter<int> ("severity")),
00055 maxNumRBXs_(iConfig.getParameter<int>("maxNumRBXs")),
00056 numRBXsToConsider_(iConfig.getParameter<int>("numRBXsToConsider")),
00057 accept2NoiseRBXEvents_(iConfig.getParameter<bool>("accept2NoiseRBXEvents")),
00058 needEMFCoincidence_(iConfig.getParameter<bool>("needEMFCoincidence")),
00059 minRBXEnergy_(iConfig.getParameter<double>("minRBXEnergy")),
00060 minRatio_(iConfig.getParameter<double>("minRatio")),
00061 maxRatio_(iConfig.getParameter<double>("maxRatio")),
00062 minHPDHits_(iConfig.getParameter<int>("minHPDHits")),
00063 minRBXHits_(iConfig.getParameter<int>("minRBXHits")),
00064 minHPDNoOtherHits_(iConfig.getParameter<int>("minHPDNoOtherHits")),
00065 minZeros_(iConfig.getParameter<int>("minZeros")),
00066 minHighEHitTime_(iConfig.getParameter<double>("minHighEHitTime")),
00067 maxHighEHitTime_(iConfig.getParameter<double>("maxHighEHitTime")),
00068 maxRBXEMF_(iConfig.getParameter<double>("maxRBXEMF")),
00069 minRecHitE_(iConfig.getParameter<double>("minRecHitE")),
00070 minLowHitE_(iConfig.getParameter<double>("minLowHitE")),
00071 minHighHitE_(iConfig.getParameter<double>("minHighHitE")),
00072 TS4TS5EnergyThreshold_(iConfig.getParameter<double>("TS4TS5EnergyThreshold"))
00073 {
00074
00075 std::vector<double> TS4TS5UpperThresholdTemp = iConfig.getParameter<std::vector<double> >("TS4TS5UpperThreshold");
00076 std::vector<double> TS4TS5UpperCutTemp = iConfig.getParameter<std::vector<double> >("TS4TS5UpperCut");
00077 std::vector<double> TS4TS5LowerThresholdTemp = iConfig.getParameter<std::vector<double> >("TS4TS5LowerThreshold");
00078 std::vector<double> TS4TS5LowerCutTemp = iConfig.getParameter<std::vector<double> >("TS4TS5LowerCut");
00079
00080 for(int i = 0; i < (int)TS4TS5UpperThresholdTemp.size() && i < (int)TS4TS5UpperCutTemp.size(); i++)
00081 TS4TS5UpperCut_.push_back(std::pair<double, double>(TS4TS5UpperThresholdTemp[i], TS4TS5UpperCutTemp[i]));
00082 sort(TS4TS5UpperCut_.begin(), TS4TS5UpperCut_.end());
00083
00084 for(int i = 0; i < (int)TS4TS5LowerThresholdTemp.size() && i < (int)TS4TS5LowerCutTemp.size(); i++)
00085 TS4TS5LowerCut_.push_back(std::pair<double, double>(TS4TS5LowerThresholdTemp[i], TS4TS5LowerCutTemp[i]));
00086 sort(TS4TS5LowerCut_.begin(), TS4TS5LowerCut_.end());
00087
00088 produces<reco::CaloMETCollection>();
00089 }
00090
00091
00092 HLTHcalMETNoiseCleaner::~HLTHcalMETNoiseCleaner(){}
00093
00094 void
00095 HLTHcalMETNoiseCleaner::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00096 edm::ParameterSetDescription desc;
00097 desc.add<edm::InputTag>("HcalNoiseRBXCollection",edm::InputTag("hltHcalNoiseInfoProducer"));
00098 desc.add<edm::InputTag>("CaloMetCollection",edm::InputTag("hltMet"));
00099 desc.add<double>("CaloMetCut",0.0);
00100 desc.add<int>("severity",1);
00101 desc.add<int>("maxNumRBXs",2);
00102 desc.add<int>("numRBXsToConsider",2);
00103 desc.add<bool>("accept2NoiseRBXEvents",true);
00104 desc.add<bool>("needEMFCoincidence",true);
00105 desc.add<double>("minRBXEnergy",50.0);
00106 desc.add<double>("minRatio",-999.);
00107 desc.add<double>("maxRatio",999.);
00108 desc.add<int>("minHPDHits",17);
00109 desc.add<int>("minRBXHits",999);
00110 desc.add<int>("minHPDNoOtherHits",10);
00111 desc.add<int>("minZeros",10);
00112 desc.add<double>("minHighEHitTime",-9999.0);
00113 desc.add<double>("maxHighEHitTime",9999.0);
00114 desc.add<double>("maxRBXEMF",0.02);
00115 desc.add<double>("minRecHitE",1.5);
00116 desc.add<double>("minLowHitE",10.0);
00117 desc.add<double>("minHighHitE",25.0);
00118 desc.add<double>("TS4TS5EnergyThreshold",50.0);
00119
00120 double TS4TS5UpperThresholdArray[5] = {70, 90, 100, 400, 4000 };
00121 double TS4TS5UpperCutArray[5] = {1, 0.8, 0.75, 0.72, 0.72};
00122 double TS4TS5LowerThresholdArray[7] = {100, 120, 150, 200, 300, 400, 500};
00123 double TS4TS5LowerCutArray[7] = {-1, -0.7, -0.4, -0.2, -0.08, 0, 0.1};
00124 std::vector<double> TS4TS5UpperThreshold(TS4TS5UpperThresholdArray, TS4TS5UpperThresholdArray+5);
00125 std::vector<double> TS4TS5UpperCut(TS4TS5UpperCutArray, TS4TS5UpperCutArray+5);
00126 std::vector<double> TS4TS5LowerThreshold(TS4TS5LowerThresholdArray, TS4TS5LowerThresholdArray+7);
00127 std::vector<double> TS4TS5LowerCut(TS4TS5LowerCutArray, TS4TS5LowerCutArray+7);
00128
00129 desc.add<std::vector<double> >("TS4TS5UpperThreshold", TS4TS5UpperThreshold);
00130 desc.add<std::vector<double> >("TS4TS5UpperCut", TS4TS5UpperCut);
00131 desc.add<std::vector<double> >("TS4TS5LowerThreshold", TS4TS5LowerThreshold);
00132 desc.add<std::vector<double> >("TS4TS5LowerCut", TS4TS5LowerCut);
00133 descriptions.add("hltHcalMETNoiseCleaner",desc);
00134 }
00135
00136
00137
00138
00139
00140 bool HLTHcalMETNoiseCleaner::filter(edm::Event& iEvent, const edm::EventSetup& iSetup)
00141 {
00142 using namespace reco;
00143
00144
00145 std::auto_ptr<CaloMETCollection> CleanedMET(new CaloMETCollection);
00146
00147
00148 edm::Handle<CaloMETCollection> met_h;
00149 iEvent.getByLabel(CaloMetCollectionTag_,met_h);
00150
00151 if(not met_h.isValid() or met_h->size()==0 or met_h->front().pt()<0){
00152 return true;
00153 }
00154
00155 reco::CaloMET inCaloMet = met_h->front();
00156
00157
00158
00159 if(severity_==0){
00160 CleanedMET->push_back(inCaloMet);
00161 iEvent.put(CleanedMET);
00162 return true;
00163 }
00164
00165
00166 edm::Handle<HcalNoiseRBXCollection> rbxs_h;
00167 iEvent.getByLabel(HcalNoiseRBXCollectionTag_,rbxs_h);
00168 if(!rbxs_h.isValid()) {
00169 edm::LogError("DataNotFound") << "HLTHcalMETNoiseCleaner: Could not find HcalNoiseRBXCollection product named "
00170 << HcalNoiseRBXCollectionTag_ << "." << std::endl;
00171 CleanedMET->push_back(inCaloMet);
00172 iEvent.put(CleanedMET);
00173 return true;
00174 }
00175
00176
00177 noisedataset_t data;
00178 for(HcalNoiseRBXCollection::const_iterator it=rbxs_h->begin(); it!=rbxs_h->end(); ++it) {
00179 const HcalNoiseRBX &rbx=(*it);
00180 CommonHcalNoiseRBXData d(rbx, minRecHitE_, minLowHitE_, minHighHitE_, TS4TS5EnergyThreshold_,
00181 TS4TS5UpperCut_, TS4TS5LowerCut_);
00182 data.insert(d);
00183 }
00184
00185 if(data.size()<1){
00186 CleanedMET->push_back(inCaloMet);
00187 iEvent.put(CleanedMET);
00188 return true;
00189 }
00190
00191
00192 int cntr=0;
00193 int nNoise=0;
00194
00195 TVector3 metVec;
00196 metVec.SetPtEtaPhi(met_h->front().pt(), 0, met_h->front().phi() );
00197
00198 TVector3 noiseHPDVector(0,0,0);
00199 TVector3 secondHPDVector(0,0,0);
00200 for(noisedataset_t::const_iterator it=data.begin();
00201 it!=data.end() && cntr<numRBXsToConsider_;
00202 it++, cntr++) {
00203 bool isNoise=false;
00204 bool passFilter=true;
00205 bool passEMF=true;
00206 if(it->energy()>minRBXEnergy_) {
00207 if(it->validRatio() && it->ratio()<minRatio_) passFilter=false;
00208 else if(it->validRatio() && it->ratio()>maxRatio_) passFilter=false;
00209 else if(it->numHPDHits()>=minHPDHits_) passFilter=false;
00210 else if(it->numRBXHits()>=minRBXHits_) passFilter=false;
00211 else if(it->numHPDNoOtherHits()>=minHPDNoOtherHits_) passFilter=false;
00212 else if(it->numZeros()>=minZeros_) passFilter=false;
00213 else if(it->minHighEHitTime()<minHighEHitTime_) passFilter=false;
00214 else if(it->maxHighEHitTime()>maxHighEHitTime_) passFilter=false;
00215 else if(!it->PassTS4TS5()) passFilter=false;
00216
00217 if(it->RBXEMF()<maxRBXEMF_){
00218 passEMF=false;
00219 }
00220 }
00221
00222 if((needEMFCoincidence_ && !passEMF && !passFilter) ||
00223 (!needEMFCoincidence_ && !passFilter)) {
00224 LogDebug("") << "HLTHcalMETNoiseCleaner debug: Found a noisy RBX: "
00225 << "energy=" << it->energy() << "; "
00226 << "ratio=" << it->ratio() << "; "
00227 << "# RBX hits=" << it->numRBXHits() << "; "
00228 << "# HPD hits=" << it->numHPDHits() << "; "
00229 << "# Zeros=" << it->numZeros() << "; "
00230 << "min time=" << it->minHighEHitTime() << "; "
00231 << "max time=" << it->maxHighEHitTime() << "; "
00232 << "passTS4TS5=" << it->PassTS4TS5() << "; "
00233 << "RBX EMF=" << it->RBXEMF()
00234 << std::endl;
00235 nNoise++;
00236 isNoise=true;
00237 }
00238
00239
00240 if(isNoise && nNoise==1){
00241 edm::RefVector<CaloTowerCollection> noiseTowers = it->rbxTowers();
00242 edm::RefVector<CaloTowerCollection>::const_iterator noiseTowersIt;
00243
00244 for( noiseTowersIt = noiseTowers.begin(); noiseTowersIt != noiseTowers.end(); noiseTowersIt++){
00245 TVector3 towerVec;
00246 towerVec.SetPtEtaPhi((*noiseTowersIt)->pt(),(*noiseTowersIt)->eta(),(*noiseTowersIt)->phi());
00247 noiseHPDVector+=towerVec;
00248 }
00249 if(noiseHPDVector.Mag()>0) noiseHPDVector.SetPtEtaPhi(noiseHPDVector.Pt(),0,noiseHPDVector.Phi());
00250 else noiseHPDVector.SetPtEtaPhi(0,0,0);
00251 }
00252
00253 if(isNoise && cntr > 0){
00254 CleanedMET->push_back(inCaloMet);
00255 iEvent.put(CleanedMET);
00256 return accept2NoiseRBXEvents_;
00257 }
00258
00259 if(!isNoise && cntr == 0){
00260 CleanedMET->push_back(inCaloMet);
00261 iEvent.put(CleanedMET);
00262 return true;
00263 }
00264
00265 if(!isNoise && nNoise>0){
00266 edm::RefVector<CaloTowerCollection> noiseTowers = it->rbxTowers();
00267 edm::RefVector<CaloTowerCollection>::const_iterator noiseTowersIt;
00268 for( noiseTowersIt = noiseTowers.begin(); noiseTowersIt != noiseTowers.end(); noiseTowersIt++){
00269 TVector3 towerVec;
00270 towerVec.SetPtEtaPhi((*noiseTowersIt)->pt(),(*noiseTowersIt)->eta(),(*noiseTowersIt)->phi());
00271 secondHPDVector+=towerVec;
00272 }
00273 if(secondHPDVector.Mag()>0) secondHPDVector.SetPtEtaPhi(secondHPDVector.Pt(),0,secondHPDVector.Phi());
00274 else secondHPDVector.SetPtEtaPhi(0,0,0);
00275 break;
00276 }
00277 }
00278
00279 if(noiseHPDVector.Mag()==0){
00280 CleanedMET->push_back(inCaloMet);
00281 iEvent.put(CleanedMET);
00282 return true;
00283 }
00284
00285
00286
00287
00288
00289 float METsumet = met_h->front().energy();
00290
00291 metVec+=noiseHPDVector;
00292
00293 float ZMETsumet = METsumet-noiseHPDVector.Mag();
00294 float ZMETpt = metVec.Pt();
00295 float ZMETphi = metVec.Phi();
00296
00297
00298
00299 float SMETsumet = 0;
00300 float SMETpt = 0;
00301 float SMETphi = 0;
00302 if(secondHPDVector.Mag()>0.){
00303 secondHPDVector.SetPtEtaPhi(secondHPDVector.Pt(),noiseHPDVector.Eta(),noiseHPDVector.Phi());
00304 metVec-= secondHPDVector;
00305 SMETsumet = METsumet-noiseHPDVector.Mag();
00306 SMETpt = metVec.Pt();
00307 SMETphi = metVec.Phi();
00308 }
00309
00310 float CorMetSumEt,CorMetPt,CorMetPhi;
00311 if(ZMETpt>SMETpt){
00312 CorMetSumEt = ZMETsumet;
00313 CorMetPt = ZMETpt;
00314 CorMetPhi = ZMETphi;
00315 }else{
00316 CorMetSumEt = SMETsumet;
00317 CorMetPt = SMETpt;
00318 CorMetPhi = SMETphi;
00319 }
00320
00321 reco::CaloMET corMet = BuildCaloMet(CorMetSumEt,CorMetPt,CorMetPhi);
00322 CleanedMET->push_back(corMet);
00323 iEvent.put(CleanedMET);
00324
00325 return (corMet.pt() > CaloMetCut_);
00326 }
00327
00328 reco::CaloMET HLTHcalMETNoiseCleaner::BuildCaloMet(float sumet, float pt, float phi){
00329
00330
00331 typedef math::XYZPoint Point;
00332 typedef math::XYZTLorentzVector LorentzVector;
00333
00334 SpecificCaloMETData specific;
00335
00336 specific.MaxEtInEmTowers = 0.0;
00337 specific.MaxEtInHadTowers = 0.0;
00338 specific.HadEtInHO = 0.0;
00339 specific.HadEtInHB = 0.0;
00340 specific.HadEtInHF = 0.0;
00341 specific.HadEtInHE = 0.0;
00342 specific.EmEtInEB = 0.0;
00343 specific.EmEtInEE = 0.0;
00344 specific.EmEtInHF = 0.0;
00345 specific.EtFractionHadronic = 0.0;
00346 specific.EtFractionEm = 0.0;
00347 specific.CaloSETInpHF = 0.0;
00348 specific.CaloSETInmHF = 0.0;
00349 specific.CaloMETInpHF = 0.0;
00350 specific.CaloMETInmHF = 0.0;
00351 specific.CaloMETPhiInpHF = 0.0;
00352 specific.CaloMETPhiInmHF = 0.0;
00353 specific.METSignificance = 0.0;
00354
00355 TLorentzVector p4TL;
00356 p4TL.SetPtEtaPhiM(pt,0.,phi,0.);
00357 const LorentzVector p4(p4TL.X(),p4TL.Y(),0,p4TL.T());
00358 const Point vtx( 0.0, 0.0, 0.0 );
00359 reco::CaloMET specificmet( specific, sumet, p4, vtx );
00360 return specificmet;
00361 }
00362