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