CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
HLTHcalMETNoiseCleaner.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Class: HLTHcalMETNoiseCleaner
4 //
12 //
13 // Original Author: Alexander Mott
14 // Created: Mon Nov 21 11:32:00 CEST 2011
15 //
16 //
17 //
18 
20 
26 
28 
35 
39 
40 #include <iostream>
41 #include <string>
42 #include <fstream>
43 #include <TVector3.h>
44 #include <TLorentzVector.h>
45 //#include <Point.h>
46 
48  : HcalNoiseRBXCollectionTag_(iConfig.getParameter<edm::InputTag>("HcalNoiseRBXCollection")),
49  CaloMetCollectionTag_(iConfig.getParameter<edm::InputTag>("CaloMetCollection")),
50  CaloMetCut_(iConfig.getParameter<double>("CaloMetCut")),
51  severity_(iConfig.getParameter<int> ("severity")),
52  maxNumRBXs_(iConfig.getParameter<int>("maxNumRBXs")),
53  numRBXsToConsider_(iConfig.getParameter<int>("numRBXsToConsider")),
54  accept2NoiseRBXEvents_(iConfig.getParameter<bool>("accept2NoiseRBXEvents")),
55  needEMFCoincidence_(iConfig.getParameter<bool>("needEMFCoincidence")),
56  minRBXEnergy_(iConfig.getParameter<double>("minRBXEnergy")),
57  minRatio_(iConfig.getParameter<double>("minRatio")),
58  maxRatio_(iConfig.getParameter<double>("maxRatio")),
59  minHPDHits_(iConfig.getParameter<int>("minHPDHits")),
60  minRBXHits_(iConfig.getParameter<int>("minRBXHits")),
61  minHPDNoOtherHits_(iConfig.getParameter<int>("minHPDNoOtherHits")),
62  minZeros_(iConfig.getParameter<int>("minZeros")),
63  minHighEHitTime_(iConfig.getParameter<double>("minHighEHitTime")),
64  maxHighEHitTime_(iConfig.getParameter<double>("maxHighEHitTime")),
65  maxRBXEMF_(iConfig.getParameter<double>("maxRBXEMF")),
66  minRecHitE_(iConfig.getParameter<double>("minRecHitE")),
67  minLowHitE_(iConfig.getParameter<double>("minLowHitE")),
68  minHighHitE_(iConfig.getParameter<double>("minHighHitE")),
69  TS4TS5EnergyThreshold_(iConfig.getParameter<double>("TS4TS5EnergyThreshold"))
70 {
71 
72  std::vector<double> TS4TS5UpperThresholdTemp = iConfig.getParameter<std::vector<double> >("TS4TS5UpperThreshold");
73  std::vector<double> TS4TS5UpperCutTemp = iConfig.getParameter<std::vector<double> >("TS4TS5UpperCut");
74  std::vector<double> TS4TS5LowerThresholdTemp = iConfig.getParameter<std::vector<double> >("TS4TS5LowerThreshold");
75  std::vector<double> TS4TS5LowerCutTemp = iConfig.getParameter<std::vector<double> >("TS4TS5LowerCut");
76 
77  for(int i = 0; i < (int)TS4TS5UpperThresholdTemp.size() && i < (int)TS4TS5UpperCutTemp.size(); i++)
78  TS4TS5UpperCut_.push_back(std::pair<double, double>(TS4TS5UpperThresholdTemp[i], TS4TS5UpperCutTemp[i]));
79  sort(TS4TS5UpperCut_.begin(), TS4TS5UpperCut_.end());
80 
81  for(int i = 0; i < (int)TS4TS5LowerThresholdTemp.size() && i < (int)TS4TS5LowerCutTemp.size(); i++)
82  TS4TS5LowerCut_.push_back(std::pair<double, double>(TS4TS5LowerThresholdTemp[i], TS4TS5LowerCutTemp[i]));
83  sort(TS4TS5LowerCut_.begin(), TS4TS5LowerCut_.end());
84 
85  m_theCaloMetToken = consumes<reco::CaloMETCollection>(CaloMetCollectionTag_);
86  m_theHcalNoiseToken = consumes<reco::HcalNoiseRBXCollection>(HcalNoiseRBXCollectionTag_);
87 
88  produces<reco::CaloMETCollection>();
89 }
90 
91 
93 
94 void
97  desc.add<edm::InputTag>("HcalNoiseRBXCollection",edm::InputTag("hltHcalNoiseInfoProducer"));
98  desc.add<edm::InputTag>("CaloMetCollection",edm::InputTag("hltMet"));
99  desc.add<double>("CaloMetCut",0.0);
100  desc.add<int>("severity",1);
101  desc.add<int>("maxNumRBXs",2);
102  desc.add<int>("numRBXsToConsider",2);
103  desc.add<bool>("accept2NoiseRBXEvents",true);
104  desc.add<bool>("needEMFCoincidence",true);
105  desc.add<double>("minRBXEnergy",50.0);
106  desc.add<double>("minRatio",-999.);
107  desc.add<double>("maxRatio",999.);
108  desc.add<int>("minHPDHits",17);
109  desc.add<int>("minRBXHits",999);
110  desc.add<int>("minHPDNoOtherHits",10);
111  desc.add<int>("minZeros",10);
112  desc.add<double>("minHighEHitTime",-9999.0);
113  desc.add<double>("maxHighEHitTime",9999.0);
114  desc.add<double>("maxRBXEMF",0.02);
115  desc.add<double>("minRecHitE",1.5);
116  desc.add<double>("minLowHitE",10.0);
117  desc.add<double>("minHighHitE",25.0);
118  desc.add<double>("TS4TS5EnergyThreshold",50.0);
119 
120  double TS4TS5UpperThresholdArray[5] = {70, 90, 100, 400, 4000 };
121  double TS4TS5UpperCutArray[5] = {1, 0.8, 0.75, 0.72, 0.72};
122  double TS4TS5LowerThresholdArray[7] = {100, 120, 150, 200, 300, 400, 500};
123  double TS4TS5LowerCutArray[7] = {-1, -0.7, -0.4, -0.2, -0.08, 0, 0.1};
124  std::vector<double> TS4TS5UpperThreshold(TS4TS5UpperThresholdArray, TS4TS5UpperThresholdArray+5);
125  std::vector<double> TS4TS5UpperCut(TS4TS5UpperCutArray, TS4TS5UpperCutArray+5);
126  std::vector<double> TS4TS5LowerThreshold(TS4TS5LowerThresholdArray, TS4TS5LowerThresholdArray+7);
127  std::vector<double> TS4TS5LowerCut(TS4TS5LowerCutArray, TS4TS5LowerCutArray+7);
128 
129  desc.add<std::vector<double> >("TS4TS5UpperThreshold", TS4TS5UpperThreshold);
130  desc.add<std::vector<double> >("TS4TS5UpperCut", TS4TS5UpperCut);
131  desc.add<std::vector<double> >("TS4TS5LowerThreshold", TS4TS5LowerThreshold);
132  desc.add<std::vector<double> >("TS4TS5LowerCut", TS4TS5LowerCut);
133  descriptions.add("hltHcalMETNoiseCleaner",desc);
134 }
135 
136 //
137 // member functions
138 //
139 
141 {
142  using namespace reco;
143 
144  //output collection
145  std::auto_ptr<CaloMETCollection> CleanedMET(new CaloMETCollection);
146 
147  //get the calo MET / MHT
149  iEvent.getByToken(m_theCaloMetToken,met_h);
150 
151  if(not met_h.isValid() or met_h->size()==0 or met_h->front().pt()<0){ //No Valid MET, don't do anything and accept the event
152  return true; // we shouldn't get here, but lets not crash
153  }
154 
155  reco::CaloMET inCaloMet = met_h->front();
156 
157 
158  // in this case, do not filter anything
159  if(severity_==0){
160  CleanedMET->push_back(inCaloMet);
161  iEvent.put(CleanedMET);
162  return true;
163  }
164 
165  // get the RBXs produced by RecoMET/METProducers/HcalNoiseInfoProducer
167  iEvent.getByToken(m_theHcalNoiseToken,rbxs_h);
168  if(!rbxs_h.isValid()) {
169  edm::LogError("DataNotFound") << "HLTHcalMETNoiseCleaner: Could not find HcalNoiseRBXCollection product named "
170  << HcalNoiseRBXCollectionTag_ << "." << std::endl;
171  CleanedMET->push_back(inCaloMet);
172  iEvent.put(CleanedMET);
173  return true; // no valid RBXs
174  }
175 
176  // create a sorted set of the RBXs, ordered by energy
178  for(HcalNoiseRBXCollection::const_iterator it=rbxs_h->begin(); it!=rbxs_h->end(); ++it) {
179  const HcalNoiseRBX &rbx=(*it);
182  data.insert(d);
183  }
184  //if 0 RBXs are in the list, just accept
185  if(data.size()<1){
186  CleanedMET->push_back(inCaloMet);
187  iEvent.put(CleanedMET);
188  return true;
189  }
190  // data is now sorted by RBX energy
191  // only consider top N=numRBXsToConsider_ energy RBXs
192  int cntr=0;
193  int nNoise=0;
194 
195  TVector3 metVec;
196  metVec.SetPtEtaPhi(met_h->front().pt(), 0, met_h->front().phi() );
197 
198  TVector3 noiseHPDVector(0,0,0);
199  TVector3 secondHPDVector(0,0,0);
200  for(noisedataset_t::const_iterator it=data.begin();
201  it!=data.end() && cntr<numRBXsToConsider_;
202  it++, cntr++) {
203  bool isNoise=false;
204  bool passFilter=true;
205  bool passEMF=true;
206  if(it->energy()>minRBXEnergy_) {
207  if(it->validRatio() && it->ratio()<minRatio_) passFilter=false;
208  else if(it->validRatio() && it->ratio()>maxRatio_) passFilter=false;
209  else if(it->numHPDHits()>=minHPDHits_) passFilter=false;
210  else if(it->numRBXHits()>=minRBXHits_) passFilter=false;
211  else if(it->numHPDNoOtherHits()>=minHPDNoOtherHits_) passFilter=false;
212  else if(it->numZeros()>=minZeros_) passFilter=false;
213  else if(it->minHighEHitTime()<minHighEHitTime_) passFilter=false;
214  else if(it->maxHighEHitTime()>maxHighEHitTime_) passFilter=false;
215  else if(!it->PassTS4TS5()) passFilter=false;
216 
217  if(it->RBXEMF()<maxRBXEMF_){
218  passEMF=false;
219  }
220  }
221 
222  if((needEMFCoincidence_ && !passEMF && !passFilter) ||
223  (!needEMFCoincidence_ && !passFilter)) { // check for noise
224  LogDebug("") << "HLTHcalMETNoiseCleaner debug: Found a noisy RBX: "
225  << "energy=" << it->energy() << "; "
226  << "ratio=" << it->ratio() << "; "
227  << "# RBX hits=" << it->numRBXHits() << "; "
228  << "# HPD hits=" << it->numHPDHits() << "; "
229  << "# Zeros=" << it->numZeros() << "; "
230  << "min time=" << it->minHighEHitTime() << "; "
231  << "max time=" << it->maxHighEHitTime() << "; "
232  << "passTS4TS5=" << it->PassTS4TS5() << "; "
233  << "RBX EMF=" << it->RBXEMF()
234  << std::endl;
235  nNoise++;
236  isNoise=true;
237  }// OK, checked for noise
238 
239  //------------First Noisy RBX-----------------------
240  if(isNoise && nNoise==1){
241  edm::RefVector<CaloTowerCollection> noiseTowers = it->rbxTowers();
243  // get the energy vector for this RBX from the calotowers
244  for( noiseTowersIt = noiseTowers.begin(); noiseTowersIt != noiseTowers.end(); noiseTowersIt++){
245  TVector3 towerVec;
246  towerVec.SetPtEtaPhi((*noiseTowersIt)->pt(),(*noiseTowersIt)->eta(),(*noiseTowersIt)->phi());
247  noiseHPDVector+=towerVec; // add this tower to the vector for the RBX
248  }
249  if(noiseHPDVector.Mag()>0) noiseHPDVector.SetPtEtaPhi(noiseHPDVector.Pt(),0,noiseHPDVector.Phi()); // make the noise transverse
250  else noiseHPDVector.SetPtEtaPhi(0,0,0);
251  }
252  //-----------FOUND a SECOND NOISY RBX-------------------
253  if(isNoise && cntr > 0){
254  CleanedMET->push_back(inCaloMet);
255  iEvent.put(CleanedMET);
256  return accept2NoiseRBXEvents_; // don't try to clean these for the moment, just keep or throw away
257  }
258  //----------LEADING RBX is NOT NOISY--------------------
259  if(!isNoise && cntr == 0){
260  CleanedMET->push_back(inCaloMet);
261  iEvent.put(CleanedMET);
262  return true; // don't reject the event if the leading RBX isn't noise
263  }
264  //-----------SUBLEADING RBX is NOT NOISY: STORE INFO----
265  if(!isNoise && nNoise>0){ //second RBX isn't noisy (and first one was), so clean
266  edm::RefVector<CaloTowerCollection> noiseTowers = it->rbxTowers();
268  for( noiseTowersIt = noiseTowers.begin(); noiseTowersIt != noiseTowers.end(); noiseTowersIt++){
269  TVector3 towerVec;
270  towerVec.SetPtEtaPhi((*noiseTowersIt)->pt(),(*noiseTowersIt)->eta(),(*noiseTowersIt)->phi());
271  secondHPDVector+=towerVec; // add this tower to the vector for the RBX
272  }
273  if(secondHPDVector.Mag()>0) secondHPDVector.SetPtEtaPhi(secondHPDVector.Pt(),0,secondHPDVector.Phi()); // make the second transverse
274  else secondHPDVector.SetPtEtaPhi(0,0,0);
275  break;
276  }
277  } // end RBX loop
278 
279  if(noiseHPDVector.Mag()==0){
280  CleanedMET->push_back(inCaloMet);
281  iEvent.put(CleanedMET);
282  return true; // don't reject the event if the leading RBX isn't noise
283  }
284 
285  //********************************************************************************
286  //The Event gets here only if it had exactly 1 noisy RBX in the lead position
287  //********************************************************************************
288 
289  float METsumet = met_h->front().energy();
290 
291  metVec+=noiseHPDVector;
292 
293  float ZMETsumet = METsumet-noiseHPDVector.Mag();
294  float ZMETpt = metVec.Pt();
295  float ZMETphi = metVec.Phi();
296 
297  //put the second RBX vector in the eta phi position of the leading RBX vector
298 
299  float SMETsumet = 0;
300  float SMETpt = 0;
301  float SMETphi = 0;
302  if(secondHPDVector.Mag()>0.){
303  secondHPDVector.SetPtEtaPhi(secondHPDVector.Pt(),noiseHPDVector.Eta(),noiseHPDVector.Phi());
304  metVec-= secondHPDVector;
305  SMETsumet = METsumet-noiseHPDVector.Mag();
306  SMETpt = metVec.Pt();
307  SMETphi = metVec.Phi();
308  }
309  //Get the maximum MET:
310  float CorMetSumEt,CorMetPt,CorMetPhi;
311  if(ZMETpt>SMETpt){
312  CorMetSumEt = ZMETsumet;
313  CorMetPt = ZMETpt;
314  CorMetPhi = ZMETphi;
315  }else{
316  CorMetSumEt = SMETsumet;
317  CorMetPt = SMETpt;
318  CorMetPhi = SMETphi;
319  }
320 
321  reco::CaloMET corMet = BuildCaloMet(CorMetSumEt,CorMetPt,CorMetPhi);
322  CleanedMET->push_back(corMet);
323  iEvent.put(CleanedMET);
324 
325  return (corMet.pt() > CaloMetCut_);
326 }
327 
329  // Instantiate the container to hold the calorimeter specific information
330 
331  typedef math::XYZPoint Point;
333 
335  // Initialise the container
336  specific.MaxEtInEmTowers = 0.0; // Maximum energy in EM towers
337  specific.MaxEtInHadTowers = 0.0; // Maximum energy in HCAL towers
338  specific.HadEtInHO = 0.0; // Hadronic energy fraction in HO
339  specific.HadEtInHB = 0.0; // Hadronic energy in HB
340  specific.HadEtInHF = 0.0; // Hadronic energy in HF
341  specific.HadEtInHE = 0.0; // Hadronic energy in HE
342  specific.EmEtInEB = 0.0; // Em energy in EB
343  specific.EmEtInEE = 0.0; // Em energy in EE
344  specific.EmEtInHF = 0.0; // Em energy in HF
345  specific.EtFractionHadronic = 0.0; // Hadronic energy fraction
346  specific.EtFractionEm = 0.0; // Em energy fraction
347  specific.CaloSETInpHF = 0.0; // CaloSET in HF+
348  specific.CaloSETInmHF = 0.0; // CaloSET in HF-
349  specific.CaloMETInpHF = 0.0; // CaloMET in HF+
350  specific.CaloMETInmHF = 0.0; // CaloMET in HF-
351  specific.CaloMETPhiInpHF = 0.0; // CaloMET-phi in HF+
352  specific.CaloMETPhiInmHF = 0.0; // CaloMET-phi in HF-
353  specific.METSignificance = 0.0;
354 
355  TLorentzVector p4TL;
356  p4TL.SetPtEtaPhiM(pt,0.,phi,0.);
357  const LorentzVector p4(p4TL.X(),p4TL.Y(),0,p4TL.T());
358  const Point vtx( 0.0, 0.0, 0.0 );
359  reco::CaloMET specificmet( specific, sumet, p4, vtx );
360  return specificmet;
361  }
362 
#define LogDebug(id)
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
dictionary specific
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
std::vector< std::pair< double, double > > TS4TS5UpperCut_
edm::EDGetTokenT< reco::CaloMETCollection > m_theCaloMetToken
std::set< CommonHcalNoiseRBXData, noisedatacomp > noisedataset_t
MET made from CaloTowers.
const_iterator end() const
Termination of iteration.
Definition: RefVector.h:249
std::pair< double, double > Point
Definition: CaloEllipse.h:18
reco::CaloMET BuildCaloMet(float sumet, float pt, float phi)
const_iterator begin() const
Initialize an iterator over the RefVector.
Definition: RefVector.h:244
virtual bool filter(edm::Event &, const edm::EventSetup &)
Collection of Calo MET.
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
int iEvent
Definition: GenABIO.cc:243
OrphanHandle< PROD > put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Event.h:116
double p4[4]
Definition: TauolaWrapper.h:92
HLTHcalMETNoiseCleaner(const edm::ParameterSet &)
ParameterDescriptionBase * add(U const &iLabel, T const &value)
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::InputTag HcalNoiseRBXCollectionTag_
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
edm::EDGetTokenT< reco::HcalNoiseRBXCollection > m_theHcalNoiseToken
void add(std::string const &label, ParameterSetDescription const &psetDescription)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
math::PtEtaPhiELorentzVectorF LorentzVector
std::vector< std::pair< double, double > > TS4TS5LowerCut_
Definition: DDAxes.h:10