CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
JetIDHelper.cc
Go to the documentation of this file.
2 
4 
11 
12 
14 // JetIDHelper needs a much more detailed description that the one in HcalTopology,
15 // so to be consistent, all needed constants are hardwired in JetIDHelper.cc itself
16 // #include "Geometry/CaloTopology/interface/HcalTopology.h"
17 
18 #include "TMath.h"
19 #include <vector>
20 #include <numeric>
21 #include <iostream>
22 
23 using namespace std;
24 
25 // defining stuff useful only for this class (not needed in header)
26 namespace reco {
27 
28  namespace helper {
29 
30  // select2nd exists only in some std and boost implementations, so let's control our own fate
31  // and it can't be a non-static member function.
32  static double select2nd (std::map<int,double>::value_type const &pair) {return pair.second;}
33 
35  return x.E <= 0;
36  }
37 
39  reco::helper::JetIDHelper::subtower j ) { return i.E > j.E; }
40  std::atomic<int> JetIDHelper::sanity_checks_left_{100};
41  }
42 }
43 
45 {
46  useRecHits_ = pset.getParameter<bool>("useRecHits");
47  if( useRecHits_ ) {
48  hbheRecHitsColl_ = pset.getParameter<edm::InputTag>("hbheRecHitsColl");
49  hoRecHitsColl_ = pset.getParameter<edm::InputTag>("hoRecHitsColl");
50  hfRecHitsColl_ = pset.getParameter<edm::InputTag>("hfRecHitsColl");
51  ebRecHitsColl_ = pset.getParameter<edm::InputTag>("ebRecHitsColl");
52  eeRecHitsColl_ = pset.getParameter<edm::InputTag>("eeRecHitsColl");
53  }
54  initValues();
55 
56  input_HBHERecHits_token_ = iC.consumes<HBHERecHitCollection>(hbheRecHitsColl_);
57  input_HORecHits_token_ = iC.consumes<HORecHitCollection>(hoRecHitsColl_);
58  input_HFRecHits_token_ = iC.consumes<HFRecHitCollection>(hfRecHitsColl_);
59  input_EBRecHits_token_ = iC.consumes<EBRecHitCollection>(ebRecHitsColl_);
60  input_EERecHits_token_ = iC.consumes<EERecHitCollection>(eeRecHitsColl_);
61 
62 
63 }
64 
66 {
67  fHPD_= -1.0;
68  fRBX_= -1.0;
69  n90Hits_ = -1;
70  fSubDetector1_= -1.0;
71  fSubDetector2_= -1.0;
72  fSubDetector3_= -1.0;
73  fSubDetector4_= -1.0;
74  restrictedEMF_= -1.0;
75  nHCALTowers_ = -1;
76  nECALTowers_ = -1;
77  approximatefHPD_ = -1.0;
78  approximatefRBX_ = -1.0;
79  hitsInN90_ = -1;
80  fEB_ = fEE_ = fHB_ = fHE_ = fHO_ = fLong_ = fShort_ = -1.0;
81  fLS_ = fHFOOT_ = -1.0;
82 }
83 
85 {
86  iDesc.ifValue( edm::ParameterDescription<bool>("useRecHits", true, true),
87  true >> (edm::ParameterDescription<edm::InputTag>("hbheRecHitsColl", edm::InputTag(), true) and
88  edm::ParameterDescription<edm::InputTag>("hoRecHitsColl", edm::InputTag(), true) and
89  edm::ParameterDescription<edm::InputTag>("hfRecHitsColl", edm::InputTag(), true) and
90  edm::ParameterDescription<edm::InputTag>("ebRecHitsColl", edm::InputTag(), true) and
92  )
93  )->setComment("If using RecHits to calculate the precise jet ID variables that need them, "
94  "their sources need to be specified");
95 }
96 
97 
99 {
100  initValues();
101 
102  // --------------------------------------------------
103  // 1) jet ID variable derived from existing fractions
104  // --------------------------------------------------
105 
106  double E_EM = TMath::Max( float(0.), jet.emEnergyInHF() )
107  + TMath::Max( float(0.), jet.emEnergyInEB() )
108  + TMath::Max( float(0.), jet.emEnergyInEE() );
109  double E_Had = TMath::Max( float(0.), jet.hadEnergyInHB() )
110  + TMath::Max( float(0.), jet.hadEnergyInHE() )
111  + TMath::Max( float(0.), jet.hadEnergyInHO() )
112  + TMath::Max( float(0.), jet.hadEnergyInHF() );
113  if( E_Had + E_EM > 0 ) restrictedEMF_ = E_EM / ( E_EM + E_Had );
114  if( iDbg > 1 ) cout<<"jet pT: "<<jet.pt()<<", eT: "<<jet.et()<<", E: "
115  <<jet.energy()<<" rEMF: "<<restrictedEMF_<<endl;
116 
117  // ------------------------
118  // 2) tower based variables
119  // ------------------------
120  vector<subtower> subtowers, Ecal_subtowers, Hcal_subtowers, HO_subtowers;
121  vector<double> HPD_energies, RBX_energies;
122 
123  classifyJetTowers( event, jet,
124  subtowers, Ecal_subtowers, Hcal_subtowers, HO_subtowers,
125  HPD_energies, RBX_energies, iDbg );
126  if( iDbg > 1 ) {
127  cout<<"E:";
128  for (unsigned int i=0; i<subtowers.size(); ++i) cout<<" "<<subtowers[i].E<<","<<subtowers[i].Nhit;
129  cout<<"\nECal_E:";
130  for (unsigned int i=0; i<Ecal_subtowers.size(); ++i) cout<<" "<<Ecal_subtowers[i].E<<","<<Ecal_subtowers[i].Nhit;
131  cout<<"\nHCal_E:";
132  for (unsigned int i=0; i<Hcal_subtowers.size(); ++i) cout<<" "<<Hcal_subtowers[i].E<<","<<Hcal_subtowers[i].Nhit;
133  cout<<"\nHO_E:";
134  for (unsigned int i=0; i<HO_subtowers.size(); ++i) cout<<" "<<HO_subtowers[i].E<<","<<HO_subtowers[i].Nhit;
135  cout<<"\nHPD_E:";
136  for (unsigned int i=0; i<HPD_energies.size(); ++i) cout<<" "<<HPD_energies[i];
137  cout<<"\nRBX_E:";
138  for (unsigned int i=0; i<RBX_energies.size(); ++i) cout<<" "<<RBX_energies[i];
139  cout<<endl;
140  }
141 
142  // counts
143  hitsInN90_ = hitsInNCarrying( 0.9, subtowers );
144  nHCALTowers_ = Hcal_subtowers.size();
145  vector<subtower>::const_iterator it;
146  it = find_if( Ecal_subtowers.begin(), Ecal_subtowers.end(), hasNonPositiveE );
147  nECALTowers_ = it - Ecal_subtowers.begin(); // ignores negative energies from HF!
148 
149  // energy fractions
150  double max_HPD_energy = 0., max_RBX_energy = 0.;
151  std::vector<double>::const_iterator it_max_HPD_energy = std::max_element( HPD_energies.begin(), HPD_energies.end() );
152  std::vector<double>::const_iterator it_max_RBX_energy = std::max_element( RBX_energies.begin(), RBX_energies.end() );
153  if ( it_max_HPD_energy != HPD_energies.end() ) {
154  max_HPD_energy = *it_max_HPD_energy;
155  }
156  if ( it_max_RBX_energy != RBX_energies.end() ) {
157  max_RBX_energy = *it_max_RBX_energy;
158  }
159  if( jet.energy() > 0 ) {
160  if( HPD_energies.size() > 0 ) approximatefHPD_ = max_HPD_energy / jet.energy();
161  if( RBX_energies.size() > 0 ) approximatefRBX_ = max_HPD_energy / jet.energy();
162  }
163 
164  // -----------------------
165  // 3) cell based variables
166  // -----------------------
167  if( useRecHits_ ) {
168  vector<double> energies, subdet_energies, Ecal_energies, Hcal_energies, HO_energies;
169  double LS_bad_energy, HF_OOT_energy;
170  classifyJetComponents( event, jet,
171  energies, subdet_energies, Ecal_energies, Hcal_energies, HO_energies,
172  HPD_energies, RBX_energies, LS_bad_energy, HF_OOT_energy, iDbg );
173 
174  // counts
175  n90Hits_ = nCarrying( 0.9, energies );
176 
177  // energy fractions
178  if( jet.energy() > 0 ) {
179  if( HPD_energies.size() > 0 ) fHPD_ = max_HPD_energy / jet.energy();
180  if( RBX_energies.size() > 0 ) fRBX_ = max_RBX_energy / jet.energy();
181  if( subdet_energies.size() > 0 ) fSubDetector1_ = subdet_energies.at( 0 ) / jet.energy();
182  if( subdet_energies.size() > 1 ) fSubDetector2_ = subdet_energies.at( 1 ) / jet.energy();
183  if( subdet_energies.size() > 2 ) fSubDetector3_ = subdet_energies.at( 2 ) / jet.energy();
184  if( subdet_energies.size() > 3 ) fSubDetector4_ = subdet_energies.at( 3 ) / jet.energy();
185  fLS_ = LS_bad_energy / jet.energy();
186  fHFOOT_ = HF_OOT_energy / jet.energy();
187 
188  if( iDbg > 0 && sanity_checks_left_.load(std::memory_order_acquire) > 0 ) {
189  --sanity_checks_left_;
190  double EH_sum = accumulate( Ecal_energies.begin(), Ecal_energies.end(), 0. );
191  EH_sum = accumulate( Hcal_energies.begin(), Hcal_energies.end(), EH_sum );
192  double EHO_sum = accumulate( HO_energies.begin(), HO_energies.end(), EH_sum );
193  if( jet.energy() > 0.001 && abs( EH_sum/jet.energy() - 1 ) > 0.01 && abs( EHO_sum/jet.energy() - 1 ) > 0.01 )
194  edm::LogWarning("BadInput")<<"Jet energy ("<<jet.energy()
195  <<") does not match the total energy in the recHits ("<<EHO_sum
196  <<", or without HO: "<<EH_sum<<") . Are these the right recHits? "
197  <<"Were jet energy corrections mistakenly applied before jet ID? A bug?";
198  if( iDbg > 1 ) cout<<"Sanity check - E: "<<jet.energy()<<" =? EH_sum: "<<EH_sum<<" / EHO_sum: "<<EHO_sum<<endl;
199  }
200  }
201 
202  if( iDbg > 1 ) {
203  cout<<"DBG - fHPD: "<<fHPD_<<", fRBX: "<<fRBX_<<", nh90: "<<n90Hits_<<", fLS: "<<fLS_<<", fHFOOT: "<<fHFOOT_<<endl;
204  cout<<" -~fHPD: "<<approximatefHPD_<<", ~fRBX: "<<approximatefRBX_
205  <<", hits in n90: "<<hitsInN90_<<endl;
206  cout<<" - nHCALTowers: "<<nHCALTowers_<<", nECALTowers: "<<nECALTowers_
207  <<"; subdet fractions: "<<fSubDetector1_<<", "<<fSubDetector2_<<", "<<fSubDetector3_<<", "<<fSubDetector4_<<endl;
208  }
209  }
210 }
211 
212 
213 unsigned int reco::helper::JetIDHelper::nCarrying( double fraction, const std::vector< double >& descending_energies )
214 {
215  double totalE = 0;
216  for( unsigned int i = 0; i < descending_energies.size(); ++i ) totalE += descending_energies[ i ];
217 
218  double runningE = 0;
219  unsigned int NC = descending_energies.size();
220 
221  // slightly odd loop structure avoids round-off problems when runningE never catches up with totalE
222  for( unsigned int i = descending_energies.size(); i > 0; --i ) {
223  runningE += descending_energies[ i-1 ];
224  if (runningE < ( 1-fraction ) * totalE) NC = i-1;
225  }
226  return NC;
227 }
228 
229 
230 unsigned int reco::helper::JetIDHelper::hitsInNCarrying( double fraction, const std::vector< subtower >& descending_towers )
231 {
232  double totalE = 0;
233  for( unsigned int i = 0; i < descending_towers.size(); ++i ) totalE += descending_towers[ i ].E;
234 
235  double runningE = 0;
236  unsigned int NH = 0;
237 
238  // slightly odd loop structure avoids round-off problems when runningE never catches up with totalE
239  for( unsigned int i = descending_towers.size(); i > 0; --i ) {
240  runningE += descending_towers[ i-1 ].E;
241  if (runningE >= ( 1-fraction ) * totalE) NH += descending_towers[ i-1 ].Nhit;
242  }
243  return NH;
244 }
245 
247  vector< double > &energies,
248  vector< double > &subdet_energies,
249  vector< double > &Ecal_energies,
250  vector< double > &Hcal_energies,
251  vector< double > &HO_energies,
252  vector< double > &HPD_energies,
253  vector< double > &RBX_energies,
254  double& LS_bad_energy, double& HF_OOT_energy, const int iDbg )
255 {
256  energies.clear(); subdet_energies.clear(); Ecal_energies.clear(); Hcal_energies.clear(); HO_energies.clear();
257  HPD_energies.clear(); RBX_energies.clear();
258  LS_bad_energy = HF_OOT_energy = 0.;
259 
260  std::map< int, double > HPD_energy_map, RBX_energy_map;
261  vector< double > EB_energies, EE_energies, HB_energies, HE_energies, short_energies, long_energies;
267  // the jet only contains DetIds, so first read recHit collection
268  event.getByToken(input_HBHERecHits_token_, HBHERecHits );
269  event.getByToken(input_HORecHits_token_, HORecHits );
270  event.getByToken(input_HFRecHits_token_, HFRecHits );
271  event.getByToken(input_EBRecHits_token_, EBRecHits );
272  event.getByToken(input_EERecHits_token_, EERecHits );
273  if( iDbg > 2 ) cout<<"# of rechits found - HBHE: "<<HBHERecHits->size()
274  <<", HO: "<<HORecHits->size()<<", HF: "<<HFRecHits->size()
275  <<", EB: "<<EBRecHits->size()<<", EE: "<<EERecHits->size()<<endl;
276 
277  vector< CaloTowerPtr > towers = jet.getCaloConstituents ();
278  int nTowers = towers.size();
279  if( iDbg > 9 ) cout<<"In classifyJetComponents. # of towers found: "<<nTowers<<endl;
280 
281  for( int iTower = 0; iTower <nTowers ; iTower++ ) {
282 
283  CaloTowerPtr& tower = towers[iTower];
284 
285  int nCells = tower->constituentsSize();
286  if( iDbg ) cout<<"tower #"<<iTower<<" has "<<nCells<<" cells. "
287  <<"It's at iEta: "<<tower->ieta()<<", iPhi: "<<tower->iphi()<<endl;
288 
289  const vector< DetId >& cellIDs = tower->constituents(); // cell == recHit
290 
291  for( int iCell = 0; iCell < nCells; ++iCell ) {
292  DetId::Detector detNum = cellIDs[iCell].det();
293  if( detNum == DetId::Hcal ) {
294  HcalDetId HcalID = cellIDs[ iCell ];
295  HcalSubdetector HcalNum = HcalID.subdet();
296  double hitE = 0;
297  if( HcalNum == HcalOuter ) {
298  HORecHitCollection::const_iterator theRecHit=HORecHits->find(HcalID);
299  if (theRecHit == HORecHits->end()) {
300  edm::LogWarning("UnexpectedEventContents")<<"Can't find the HO recHit with ID: "<<HcalID;
301  continue;
302  }
303  hitE = theRecHit->energy();
304  HO_energies.push_back( hitE );
305 
306  } else if( HcalNum == HcalForward ) {
307 
308  HFRecHitCollection::const_iterator theRecHit=HFRecHits->find( HcalID );
309  if( theRecHit == HFRecHits->end() ) {
310  edm::LogWarning("UnexpectedEventContents")<<"Can't find the HF recHit with ID: "<<HcalID;
311  continue;
312  }
313  hitE = theRecHit->energy();
314  if( iDbg>4 ) cout
315  << "hit #"<<iCell<<" is HF , E: "<<hitE<<" iEta: "<<theRecHit->id().ieta()
316  <<", depth: "<<theRecHit->id().depth()<<", iPhi: "
317  <<theRecHit->id().iphi();
318 
319  if( HcalID.depth() == 1 )
320  long_energies.push_back( hitE );
321  else
322  short_energies.push_back( hitE );
323 
324  uint32_t flags = theRecHit->flags();
325  if( flags & (1<<HcalCaloFlagLabels::HFLongShort) ) LS_bad_energy += hitE;
326  if( flags & ( (1<<HcalCaloFlagLabels::HFDigiTime) |
330  (1<<HcalCaloFlagLabels::TimingErrorBit) ) ) HF_OOT_energy += hitE;
331  if( iDbg>4 && flags ) cout<<"flags: "<<flags
332  <<" -> LS_bad_energy: "<<LS_bad_energy<<", HF_OOT_energy: "<<HF_OOT_energy<<endl;
333 
334  } else { // HBHE
335 
336  HBHERecHitCollection::const_iterator theRecHit = HBHERecHits->find( HcalID );
337  if( theRecHit == HBHERecHits->end() ) {
338  edm::LogWarning("UnexpectedEventContents")<<"Can't find the HBHE recHit with ID: "<<HcalID;
339  continue;
340  }
341  hitE = theRecHit->energy();
342  int iEta = theRecHit->id().ieta();
343  int depth = theRecHit->id().depth();
344  Region region = HBHE_region( iEta, depth );
345  int hitIPhi = theRecHit->id().iphi();
346  if( iDbg>3 ) cout<<"hit #"<<iCell<<" is HBHE, E: "<<hitE<<" iEta: "<<iEta
347  <<", depth: "<<depth<<", iPhi: "<<theRecHit->id().iphi()
348  <<" -> "<<region;
349  int absIEta = TMath::Abs( theRecHit->id().ieta() );
350  if( depth == 3 && (absIEta == 28 || absIEta == 29) ) {
351  hitE /= 2; // Depth 3 at the HE forward edge is split over tower 28 & 29, and jet reco. assigns half each
352  }
353  int iHPD = 100 * region;
354  int iRBX = 100 * region + ((hitIPhi + 1) % 72) / 4; // 71,72,1,2 are in the same RBX module
355 
356  if( std::abs( iEta ) >= 21 ) {
357  if( (0x1 & hitIPhi) == 0 ) {
358  edm::LogError("CodeAssumptionsViolated")<<"Bug?! Jet ID code assumes no even iPhi recHits at HE edges";
359  return;
360  }
361  bool oddnessIEta = HBHE_oddness( iEta, depth );
362  bool upperIPhi = (( hitIPhi%4 ) == 1 || ( hitIPhi%4 ) == 2); // the upper iPhi indices in the HE wedge
363  // remap the iPhi so it fits the one in the inner HE regions, change in needed in two cases:
364  // 1) in the upper iPhis of the module, the even iEtas belong to the higher iPhi
365  // 2) in the loewr iPhis of the module, the odd iEtas belong to the higher iPhi
366  if( upperIPhi != oddnessIEta ) ++hitIPhi;
367  // note that hitIPhi could not be 72 before, so it's still in the legal range [1,72]
368  }
369  iHPD += hitIPhi;
370 
371  // book the energies
372  HPD_energy_map[ iHPD ] += hitE;
373  RBX_energy_map[ iRBX ] += hitE;
374  if( iDbg > 5 ) cout<<" --> H["<<iHPD<<"]="<<HPD_energy_map[iHPD]
375  <<", R["<<iRBX<<"]="<<RBX_energy_map[iRBX];
376  if( iDbg > 1 ) cout<<endl;
377 
378  if( region == HBneg || region == HBpos )
379  HB_energies.push_back( hitE );
380  else
381  HE_energies.push_back( hitE );
382 
383  } // if HBHE
384  if( hitE == 0 ) edm::LogWarning("UnexpectedEventContents")<<"HCal hitE==0? (or unknown subdetector?)";
385 
386  } // if HCAL
387 
388  else if (detNum == DetId::Ecal) {
389 
390  int EcalNum = cellIDs[iCell].subdetId();
391  double hitE = 0;
392  if( EcalNum == 1 ){
393  EBDetId EcalID = cellIDs[iCell];
394  EBRecHitCollection::const_iterator theRecHit=EBRecHits->find(EcalID);
395  if( theRecHit == EBRecHits->end() ) {edm::LogWarning("UnexpectedEventContents")
396  <<"Can't find the EB recHit with ID: "<<EcalID; continue;}
397  hitE = theRecHit->energy();
398  EB_energies.push_back( hitE );
399  } else if( EcalNum == 2 ){
400  EEDetId EcalID = cellIDs[iCell];
401  EERecHitCollection::const_iterator theRecHit=EERecHits->find(EcalID);
402  if( theRecHit == EERecHits->end() ) {edm::LogWarning("UnexpectedEventContents")
403  <<"Can't find the EE recHit with ID: "<<EcalID; continue;}
404  hitE = theRecHit->energy();
405  EE_energies.push_back( hitE );
406  }
407  if( hitE == 0 ) edm::LogWarning("UnexpectedEventContents")<<"ECal hitE==0? (or unknown subdetector?)";
408  if( iDbg > 6 ) cout<<"EcalNum: "<<EcalNum<<" hitE: "<<hitE<<endl;
409  } //
410  } // loop on cells
411  } // loop on towers
412 
413  /* Disabling check until HO is accounted for in EMF. Check was used in CMSSW_2, where HE was excluded.
414  double expHcalE = jet.energy() * (1-jet.emEnergyFraction());
415  if( totHcalE + expHcalE > 0 &&
416  TMath::Abs( totHcalE - expHcalE ) > 0.01 &&
417  ( totHcalE - expHcalE ) / ( totHcalE + expHcalE ) > 0.0001 ) {
418  edm::LogWarning("CodeAssumptionsViolated")<<"failed to account for all Hcal energies"
419  <<totHcalE<<"!="<<expHcalE;
420  } */
421  // concatenate Hcal and Ecal lists
422  Hcal_energies.insert( Hcal_energies.end(), HB_energies.begin(), HB_energies.end() );
423  Hcal_energies.insert( Hcal_energies.end(), HE_energies.begin(), HE_energies.end() );
424  Hcal_energies.insert( Hcal_energies.end(), short_energies.begin(), short_energies.end() );
425  Hcal_energies.insert( Hcal_energies.end(), long_energies.begin(), long_energies.end() );
426  Ecal_energies.insert( Ecal_energies.end(), EB_energies.begin(), EB_energies.end() );
427  Ecal_energies.insert( Ecal_energies.end(), EE_energies.begin(), EE_energies.end() );
428 
429  // sort the energies
430  // std::sort( Hcal_energies.begin(), Hcal_energies.end(), greater<double>() );
431  // std::sort( Ecal_energies.begin(), Ecal_energies.end(), greater<double>() );
432 
433  // put the energy sums (the 2nd entry in each pair of the maps) into the output vectors and sort them
434  std::transform( HPD_energy_map.begin(), HPD_energy_map.end(),
435  std::inserter (HPD_energies, HPD_energies.end()), select2nd );
436  // std::select2nd<std::map<int,double>::value_type>());
437  // std::sort( HPD_energies.begin(), HPD_energies.end(), greater<double>() );
438  std::transform( RBX_energy_map.begin(), RBX_energy_map.end(),
439  std::inserter (RBX_energies, RBX_energies.end()), select2nd );
440  // std::select2nd<std::map<int,double>::value_type>());
441  // std::sort( RBX_energies.begin(), RBX_energies.end(), greater<double>() );
442 
443  energies.insert( energies.end(), Hcal_energies.begin(), Hcal_energies.end() );
444  energies.insert( energies.end(), Ecal_energies.begin(), Ecal_energies.end() );
445  energies.insert( energies.end(), HO_energies.begin(), HO_energies.end() );
446  std::sort( energies.begin(), energies.end(), greater<double>() );
447 
448  // prepare sub detector energies, then turn them into fractions
449  fEB_ = std::accumulate( EB_energies.begin(), EB_energies.end(), 0. );
450  fEE_ = std::accumulate( EE_energies.begin(), EE_energies.end(), 0. );
451  fHB_ = std::accumulate( HB_energies.begin(), HB_energies.end(), 0. );
452  fHE_ = std::accumulate( HE_energies.begin(), HE_energies.end(), 0. );
453  fHO_ = std::accumulate( HO_energies.begin(), HO_energies.end(), 0. );
454  fShort_ = std::accumulate( short_energies.begin(), short_energies.end(), 0. );
455  fLong_ = std::accumulate( long_energies.begin(), long_energies.end(), 0. );
456  subdet_energies.push_back( fEB_ );
457  subdet_energies.push_back( fEE_ );
458  subdet_energies.push_back( fHB_ );
459  subdet_energies.push_back( fHE_ );
460  subdet_energies.push_back( fHO_ );
461  subdet_energies.push_back( fShort_ );
462  subdet_energies.push_back( fLong_ );
463  std::sort( subdet_energies.begin(), subdet_energies.end(), greater<double>() );
464  if( jet.energy() > 0 ) {
465  fEB_ /= jet.energy();
466  fEE_ /= jet.energy();
467  fHB_ /= jet.energy();
468  fHE_ /= jet.energy();
469  fHO_ /= jet.energy();
470  fShort_ /= jet.energy();
471  fLong_ /= jet.energy();
472  } else {
473  if( fEB_ > 0 || fEE_ > 0 || fHB_ > 0 || fHE_ > 0 || fHO_ > 0 || fShort_ > 0 || fLong_ > 0 )
474  edm::LogError("UnexpectedEventContents")<<"Jet ID Helper found energy in subdetectors and jet E <= 0";
475  }
476 }
477 
479  vector< subtower > &subtowers,
480  vector< subtower > &Ecal_subtowers,
481  vector< subtower > &Hcal_subtowers,
482  vector< subtower > &HO_subtowers,
483  vector< double > &HPD_energies,
484  vector< double > &RBX_energies,
485  const int iDbg )
486 {
487  subtowers.clear(); Ecal_subtowers.clear(); Hcal_subtowers.clear(); HO_subtowers.clear();
488  HPD_energies.clear(); RBX_energies.clear();
489 
490  std::map< int, double > HPD_energy_map, RBX_energy_map;
491 
492  vector< CaloTowerPtr > towers = jet.getCaloConstituents ();
493  int nTowers = towers.size();
494  if( iDbg > 9 ) cout<<"classifyJetTowers started. # of towers found: "<<nTowers<<endl;
495 
496  for( int iTower = 0; iTower <nTowers ; iTower++ ) {
497 
498  CaloTowerPtr& tower = towers[iTower];
499 
500  int nEM = 0, nHad = 0, nHO = 0;
501  const vector< DetId >& cellIDs = tower->constituents(); // cell == recHit
502  int nCells = cellIDs.size();
503  if( iDbg ) cout<<"tower #"<<iTower<<" has "<<nCells<<" cells. "
504  <<"It's at iEta: "<<tower->ieta()<<", iPhi: "<<tower->iphi()<<endl;
505 
506  for( int iCell = 0; iCell < nCells; ++iCell ) {
507  DetId::Detector detNum = cellIDs[iCell].det();
508  if( detNum == DetId::Hcal ) {
509  HcalDetId HcalID = cellIDs[ iCell ];
510  HcalSubdetector HcalNum = HcalID.subdet();
511  if( HcalNum == HcalOuter ) {
512  ++nHO;
513  } else {
514  ++nHad;
515  }
516  } else if (detNum == DetId::Ecal) {
517  ++nEM;
518  }
519  }
520 
521  double E_em = tower->emEnergy();
522  if( E_em != 0 ) Ecal_subtowers.push_back( subtower( E_em, nEM ) );
523 
524  double E_HO = tower->outerEnergy();
525  if( E_HO != 0 ) HO_subtowers.push_back( subtower( E_HO, nHO ) );
526 
527  double E_had = tower->hadEnergy();
528  if( E_had != 0 ) {
529  Hcal_subtowers.push_back( subtower( E_had, nHad ) );
530  // totHcalE += E_had;
531 
532  int iEta = tower->ieta();
533  Region reg = region( iEta );
534  int iPhi = tower->iphi();
535  if( iDbg>3 ) cout<<"tower has E_had: "<<E_had<<" iEta: "<<iEta
536  <<", iPhi: "<<iPhi<<" -> "<<reg;
537 
538  if( reg == HEneg || reg == HBneg || reg == HBpos || reg == HEpos ) {
539  int oddnessIEta = HBHE_oddness( iEta );
540  if( oddnessIEta < 0 ) break; // can't assign this tower to a single readout component
541 
542  int iHPD = 100 * reg;
543  int iRBX = 100 * reg + ((iPhi + 1) % 72) / 4; // 71,72,1,2 are in the same RBX module
544 
545  if(( reg == HEneg || reg == HEpos ) && std::abs( iEta ) >= 21 ) { // at low-granularity edge of HE
546  if( (0x1 & iPhi) == 0 ) {
547  edm::LogError("CodeAssumptionsViolated")<<
548  "Bug?! Jet ID code assumes no even iPhi recHits at HE edges";
549  return;
550  }
551  bool boolOddnessIEta = oddnessIEta;
552  bool upperIPhi = (( iPhi%4 ) == 1 || ( iPhi%4 ) == 2); // the upper iPhi indices in the HE wedge
553  // remap the iPhi so it fits the one in the inner HE regions, change in needed in two cases:
554  // 1) in the upper iPhis of the module, the even IEtas belong to the higher iPhi
555  // 2) in the loewr iPhis of the module, the odd IEtas belong to the higher iPhi
556  if( upperIPhi != boolOddnessIEta ) ++iPhi;
557  // note that iPhi could not be 72 before, so it's still in the legal range [1,72]
558  } // if at low-granularity edge of HE
559  iHPD += iPhi;
560 
561  // book the energies
562  HPD_energy_map[ iHPD ] += E_had;
563  RBX_energy_map[ iRBX ] += E_had;
564  if( iDbg > 5 ) cout<<" --> H["<<iHPD<<"]="<<HPD_energy_map[iHPD]
565  <<", R["<<iRBX<<"]="<<RBX_energy_map[iRBX];
566  } // HBHE
567  } // E_had > 0
568  } // loop on towers
569 
570  // sort the subtowers
571  // std::sort( Hcal_subtowers.begin(), Hcal_subtowers.end(), subtower_has_greater_E );
572  // std::sort( Ecal_subtowers.begin(), Ecal_subtowers.end(), subtower_has_greater_E );
573 
574  // put the energy sums (the 2nd entry in each pair of the maps) into the output vectors and sort them
575  std::transform( HPD_energy_map.begin(), HPD_energy_map.end(),
576  std::inserter (HPD_energies, HPD_energies.end()), select2nd );
577  // std::select2nd<std::map<int,double>::value_type>());
578  // std::sort( HPD_energies.begin(), HPD_energies.end(), greater<double>() );
579  std::transform( RBX_energy_map.begin(), RBX_energy_map.end(),
580  std::inserter (RBX_energies, RBX_energies.end()), select2nd );
581  // std::select2nd<std::map<int,double>::value_type>());
582  // std::sort( RBX_energies.begin(), RBX_energies.end(), greater<double>() );
583 
584  subtowers.insert( subtowers.end(), Hcal_subtowers.begin(), Hcal_subtowers.end() );
585  subtowers.insert( subtowers.end(), Ecal_subtowers.begin(), Ecal_subtowers.end() );
586  subtowers.insert( subtowers.end(), HO_subtowers.begin(), HO_subtowers.end() );
587  std::sort( subtowers.begin(), subtowers.end(), subtower_has_greater_E );
588 }
589 
590 // ---------------------------------------------------------------------------------------------------------
591 // private helper functions to figure out detector & readout geometry as needed
592 
593 int reco::helper::JetIDHelper::HBHE_oddness( int iEta, int depth )
594 {
595  int ae = TMath::Abs( iEta );
596  if( ae == 29 && depth == 1 ) ae += 1; // observed that: hits are at depths 1 & 2; 1 goes with the even pattern
597  return ae & 0x1;
598 }
599 
601 {
602  // no error checking for HO indices (depth 2 & |ieta|<=14 or depth 3 & |ieta|=15)
603  if( iEta <= -17 || ( depth == 3 && iEta == -16 ) ) return HEneg;
604  if( iEta >= 17 || ( depth == 3 && iEta == 16 ) ) return HEpos;
605  if( iEta < 0 ) return HBneg;
606  return HBpos;
607 }
608 
610 {
611  int ae = TMath::Abs( iEta );
612  if( ae == 29 ) return -1; // can't figure it out without RecHits
613  return ae & 0x1;
614 }
615 
617 {
618  if( iEta == 16 || iEta == -16 ) return unknown_region; // both HB and HE cells belong to these towers
619  if( iEta == 29 || iEta == -29 ) return unknown_region; // both HE and HF cells belong to these towers
620  if( iEta <= -30 ) return HFneg;
621  if( iEta >= 30 ) return HFpos;
622  if( iEta <= -17 ) return HEneg;
623  if( iEta >= 17 ) return HEpos;
624  if( iEta < 0 ) return HBneg;
625  return HBpos;
626 }
float hadEnergyInHE() const
Definition: CaloJet.h:108
float emEnergyInEE() const
Definition: CaloJet.h:114
virtual double energy() const GCC11_FINAL
energy
T getParameter(std::string const &) const
void setComment(std::string const &value)
Region region(int iEta)
Definition: JetIDHelper.cc:616
virtual double et() const GCC11_FINAL
transverse energy
int i
Definition: DBlmapReader.cc:9
bool subtower_has_greater_E(reco::helper::JetIDHelper::subtower i, reco::helper::JetIDHelper::subtower j)
Definition: JetIDHelper.cc:38
Jets made from CaloTowers.
Definition: CaloJet.h:29
HcalSubdetector subdet() const
get the subdetector
Definition: HcalDetId.h:30
std::vector< HORecHit >::const_iterator const_iterator
float emEnergyInHF() const
Definition: CaloJet.h:116
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
unsigned int nCarrying(double fraction, const std::vector< double > &descending_energies)
Definition: JetIDHelper.cc:213
virtual std::vector< CaloTowerPtr > getCaloConstituents() const
get all constituents
Definition: CaloJet.cc:93
bool hasNonPositiveE(reco::helper::JetIDHelper::subtower x)
Definition: JetIDHelper.cc:34
float hadEnergyInHO() const
Definition: CaloJet.h:106
int depth() const
get the tower depth
Definition: HcalDetId.h:40
float emEnergyInEB() const
Definition: CaloJet.h:112
int ieta() const
get the cell ieta
Definition: HcalDetId.h:36
HcalSubdetector
Definition: HcalAssistant.h:31
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int j
Definition: DBlmapReader.cc:9
static double select2nd(std::map< int, double >::value_type const &pair)
Definition: JetIDHelper.cc:32
void fillDescription(edm::ParameterSetDescription &iDesc)
Definition: JetIDHelper.cc:84
void classifyJetTowers(const edm::Event &event, const reco::CaloJet &jet, std::vector< subtower > &subtowers, std::vector< subtower > &Ecal_subtowers, std::vector< subtower > &Hcal_subtowers, std::vector< subtower > &HO_subtowers, std::vector< double > &HPD_energies, std::vector< double > &RBX_energies, const int iDbg=0)
Definition: JetIDHelper.cc:478
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
Container::value_type value_type
Region HBHE_region(int iEta, int depth)
Definition: JetIDHelper.cc:600
ParameterDescriptionNode * ifValue(ParameterDescription< T > const &switchParameter, std::auto_ptr< ParameterDescriptionCases< T > > cases)
Detector
Definition: DetId.h:24
int HBHE_oddness(int iEta, int depth)
Definition: JetIDHelper.cc:593
void classifyJetComponents(const edm::Event &event, const reco::CaloJet &jet, std::vector< double > &energies, std::vector< double > &subdet_energies, std::vector< double > &Ecal_energies, std::vector< double > &Hcal_energies, std::vector< double > &HO_energies, std::vector< double > &HPD_energies, std::vector< double > &RBX_energies, double &LS_bad_energy, double &HF_OOT_energy, const int iDbg=0)
Definition: JetIDHelper.cc:246
float hadEnergyInHB() const
Definition: CaloJet.h:104
tuple cout
Definition: gather_cfg.py:121
Definition: DDAxes.h:10
float hadEnergyInHF() const
Definition: CaloJet.h:110
virtual float pt() const GCC11_FINAL
transverse momentum
void calculate(const edm::Event &event, const reco::CaloJet &jet, const int iDbg=0)
Definition: JetIDHelper.cc:98
unsigned int hitsInNCarrying(double fraction, const std::vector< subtower > &descending_towers)
Definition: JetIDHelper.cc:230