CMS 3D CMS Logo

HcalHF_S9S1algorithm.cc
Go to the documentation of this file.
8 
9 #include <algorithm> // for "max"
10 #include <cmath>
11 #include <iostream>
12 
14 {
15  // Default settings: Energy > 50 GeV, slope = 0, ET = 0
16  std::vector<double> blank;
17  blank.clear();
18  blank.push_back(0);
19  std::vector<double> EnergyDefault;
20  EnergyDefault.clear();
21  EnergyDefault.push_back(50);
22 
23  // Thresholds only need to be computed once, not every event!
24  LongSlopes.clear();
25  ShortSlopes.clear();
26  for (int i=29;i<=41;++i)
27  {
28  LongSlopes.push_back(0);
29  ShortSlopes.push_back(0);
30  }
31  LongEnergyThreshold.clear();
32  LongETThreshold.clear();
33  ShortEnergyThreshold.clear();
34  ShortETThreshold.clear();
35  for (int i=29;i<=41;++i)
36  {
37  LongEnergyThreshold.push_back(EnergyDefault[0]);
38  LongETThreshold.push_back(blank[0]);
39  ShortEnergyThreshold.push_back(EnergyDefault[0]);
40  ShortETThreshold.push_back(blank[0]);
41  }
43  isS8S1_=false; // S8S1 is almost the same as S9S1
44 }
45 
46 
48  const std::vector<double>& short_Energy,
49  const std::vector<double>& short_ET,
50  const std::vector<double>& long_optimumSlope,
51  const std::vector<double>& long_Energy,
52  const std::vector<double>& long_ET,
54  bool isS8S1)
55 
56 {
57  // Constructor in the case where all parameters are provided by the user
58 
59  // Thresholds only need to be computed once, not every event!
60 
63 
64  while (LongSlopes.size()<13)
65  LongSlopes.push_back(0); // should be unnecessary, but include this protection to avoid crashes
66  while (ShortSlopes.size()<13)
67  ShortSlopes.push_back(0);
68 
69  // Get long, short energy thresholds (different threshold for each |ieta|)
70  LongEnergyThreshold.clear();
71  LongETThreshold.clear();
72  ShortEnergyThreshold.clear();
73  ShortETThreshold.clear();
74  LongEnergyThreshold=long_Energy;
75  LongETThreshold=long_ET;
76  ShortEnergyThreshold=short_Energy;
77  ShortETThreshold=short_ET;
78 
81 } // HcalHF_S9S1algorithm constructor with parameters
82 
84 
85 
87  HFRecHitCollection& rec,
88  const HcalChannelQuality* myqual,
89  const HcalSeverityLevelComputer* mySeverity)
90 
91 {
92  int ieta=hf.id().ieta(); // get coordinates of rechit being checked
93  int depth=hf.id().depth();
94  int iphi=hf.id().iphi();
95  std::pair<double,double> etas = myqual->topo()->etaRange(HcalForward,abs(ieta));
96  double eta1 = etas.first;
97  double eta2 = etas.second;
98  double fEta = 0.5*(eta1 + eta2); // calculate eta as average of eta values at ieta boundaries
99  double energy=hf.energy();
100  double ET = energy/fabs(cosh(fEta));
101 
102  // Step 1: Check eta-dependent energy and ET thresholds -- same as PET algorithm
103  double ETthresh=0, Energythresh=0; // set ET, energy thresholds
104  if (depth==1) // set thresholds for long fibers
105  {
106  Energythresh = LongEnergyThreshold[abs(ieta)-29];
107  ETthresh = LongETThreshold[abs(ieta)-29];
108  }
109  else if (depth==2) // short fibers
110  {
111  Energythresh = ShortEnergyThreshold[abs(ieta)-29];
112  ETthresh = ShortETThreshold[abs(ieta)-29];
113  }
114  if (energy<Energythresh || ET < ETthresh)
115  return;
116 
117  // Step 1A:
118  // Check that EL<ES when evaluating short fibers (S8S1 check only)
119  if (depth==2 && abs(ieta)>29 && isS8S1_)
120  {
121  double EL=0;
122  // look for long partner
123  HcalDetId neighbor(HcalForward, ieta,iphi,1);
124  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
125  if (neigh!=rec.end())
126  EL=neigh->energy();
127 
128  if (EL>=energy)
129  return;
130  }
131 
132  // Step 2: Find all neighbors, and calculate S9/S1
133  double S9S1=0;
134  int testphi=-99;
135 
136  // Part A: Check fixed iphi, and vary ieta
137  for (int d=1;d<=2;++d) // depth loop
138  {
139  for (int i=ieta-1;i<=ieta+1;++i) // ieta loop
140  {
141  testphi=iphi;
142  // Special case when ieta=39, since ieta=40 only has phi values at 3,7,11,...
143  // phi=3 covers 3,4,5,6
144  if (abs(ieta)==39 && abs(i)>39 && testphi%4==1)
145  testphi-=2;
146  while (testphi<0) testphi+=72;
147  if (i==ieta)
148  if (d==depth || isS8S1_==true) continue; // don't add the cell itself; don't count neighbor in same ieta-phi if S8S1 test enabled
149 
150  // Look to see if neighbor is in rechit collection
151  HcalDetId neighbor(HcalForward, i,testphi,d);
152  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
153  // require that neighbor exists, and that it doesn't have a prior flag already set
154  if (neigh!=rec.end())
155  {
156  const uint32_t chanstat = myqual->getValues(neighbor)->getValue();
157  int SeverityLevel=mySeverity->getSeverityLevel(neighbor, neigh->flags(),
158  chanstat);
159  if (SeverityLevel<=HcalAcceptSeverityLevel_)
160  S9S1+=neigh->energy();
161  }
162  }
163  }
164 
165  // Part B: Fix ieta, and loop over iphi. A bit more tricky, because of iphi wraparound and different segmentation at 40, 41
166 
167  int phiseg=2; // 10 degree segmentation for most of HF (1 iphi unit = 5 degrees)
168  if (abs(ieta)>39) phiseg=4; // 20 degree segmentation for |ieta|>39
169  for (int d=1;d<=2;++d)
170  {
171  for (int i=iphi-phiseg;i<=iphi+phiseg;i+=phiseg)
172  {
173  if (i==iphi) continue; // don't add the cell itself, or its depthwise partner (which is already counted above)
174  testphi=i;
175  // Our own modular function, since default produces results -1%72 = -1
176  while (testphi<0) testphi+=72;
177  while (testphi>72) testphi-=72;
178  // Look to see if neighbor is in rechit collection
179  HcalDetId neighbor(HcalForward, ieta,testphi,d);
180  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
181  if (neigh!=rec.end())
182  {
183  const uint32_t chanstat = myqual->getValues(neighbor)->getValue();
184  int SeverityLevel=mySeverity->getSeverityLevel(neighbor, neigh->flags(),
185  chanstat);
186  if (SeverityLevel<=HcalAcceptSeverityLevel_)
187  S9S1+=neigh->energy();
188  }
189  }
190  }
191 
192  if (abs(ieta)==40) // add extra cells for 39/40 boundary due to increased phi size at ieta=40.
193  {
194  for (int d=1;d<=2;++d) // add cells from both depths!
195  {
196  HcalDetId neighbor(HcalForward, 39*abs(ieta)/ieta,(iphi+2)%72,d);
197  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
198  if (neigh!=rec.end())
199  {
200  const uint32_t chanstat = myqual->getValues(neighbor)->getValue();
201  int SeverityLevel=mySeverity->getSeverityLevel(neighbor, neigh->flags(),
202  chanstat);
203  if (SeverityLevel<=HcalAcceptSeverityLevel_)
204  S9S1+=neigh->energy();
205  }
206 
207  }
208  }
209 
210  // So far, S9S1 is the sum of the neighbors; divide to form ratio
211  S9S1/=energy;
212 
213  // Now compare to threshold
214  double slope=0;
215  if (depth==1) slope = LongSlopes[abs(ieta)-29];
216  else if (depth==2) slope=ShortSlopes[abs(ieta)-29];
217  double intercept = 0;
218  if (depth==1) intercept = LongEnergyThreshold[abs(ieta)-29];
219  else if (depth==2) intercept = ShortEnergyThreshold[abs(ieta)-29];
220 
221  // S9S1 cut has the form [0] + [1]*log[E]; S9S1 value should be above this line
222  double S9S1cut = 0;
223  // Protection in case intercept or energy are ever less than 0. Do we have some other default value of S9S1cut we'd like touse in this case?
224  if (intercept>0 && energy>0)
225  S9S1cut=-1.*slope*log(intercept) + slope*log(energy);
226  if (S9S1<S9S1cut)
227  {
228  // Only set HFS8S1Ratio if S8/S1 ratio test fails
229  if (isS8S1_==true)
231  // *Always* set the HFLongShort bit if either S8S1 or S9S1 fail
233  }
234  return;
235 } // void HcalHF_S9S1algorithm::HFSetFlagFromS9S1
236 
237 
238 
239 double HcalHF_S9S1algorithm::CalcSlope(int abs_ieta, const std::vector<double>& params)
240 {
241  /* CalcSlope calculates the polynomial [0]+[1]*x + [2]*x^2 + ....,
242  where x is an integer provided by the first argument (int abs_ieta),
243  and [0],[1],[2] is a vector of doubles provided by the second (std::vector<double> params).
244  The output of the polynomial calculation (threshold) is returned by the function.
245  This function should no longer be needed, since we pass slopes for all ietas into the function via the parameter set.
246  */
247  double threshold=0;
248  for (std::vector<double>::size_type i=0;i<params.size();++i)
249  {
250  threshold+=params[i]*pow(static_cast<double>(abs_ieta), (int)i);
251  }
252  return threshold;
253 } // HcalHF_S9S1algorithm::CalcRThreshold(int abs_ieta, std::vector<double> params)
254 
255 
256 
257 
258 double HcalHF_S9S1algorithm::CalcEnergyThreshold(double abs_energy,const std::vector<double>& params)
259 {
260  /* CalcEnergyThreshold calculates the polynomial [0]+[1]*x + [2]*x^2 + ....,
261  where x is an integer provided by the first argument (int abs_ieta),
262  and [0],[1],[2] is a vector of doubles provided by the second (std::vector<double> params).
263  The output of the polynomial calculation (threshold) is returned by the function.
264  */
265  double threshold=0;
266  for (std::vector<double>::size_type i=0;i<params.size();++i)
267  {
268  threshold+=params[i]*pow(abs_energy, (int)i);
269  }
270  return threshold;
271 } //double HcalHF_S9S1algorithm::CalcEnergyThreshold(double abs_energy,std::vector<double> params)
272 
constexpr float energy() const
Definition: CaloRecHit.h:31
std::vector< double > LongSlopes
void HFSetFlagFromS9S1(HFRecHit &hf, HFRecHitCollection &rec, const HcalChannelQuality *myqual, const HcalSeverityLevelComputer *mySeverity)
static const double slope[3]
std::vector< T >::const_iterator const_iterator
std::vector< double > LongEnergyThreshold
const Item * getValues(DetId fId, bool throwOnFail=true) const
std::vector< double > LongETThreshold
uint16_t size_type
constexpr void setFlagField(uint32_t value, int base, int width=1)
Definition: CaloRecHit.h:38
int depth() const
get the tower depth
Definition: HcalDetId.h:166
std::vector< double > ShortSlopes
double CalcSlope(int abs_ieta, const std::vector< double > &params)
int ieta() const
get the cell ieta
Definition: HcalDetId.h:159
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
const_iterator end() const
int iphi() const
get the cell iphi
Definition: HcalDetId.h:161
int getSeverityLevel(const DetId &myid, const uint32_t &myflag, const uint32_t &mystatus) const
std::pair< double, double > etaRange(HcalSubdetector subdet, int ieta) const
iterator find(key_type k)
std::vector< double > ShortETThreshold
#define ET
HcalDetId id() const
Definition: HFRecHit.h:31
std::vector< double > ShortEnergyThreshold
uint32_t getValue() const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
const HcalTopology * topo() const
double CalcEnergyThreshold(double abs_energy, const std::vector< double > &params)