CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
47 HcalHF_S9S1algorithm::HcalHF_S9S1algorithm(std::vector<double> short_optimumSlope,
48  std::vector<double> short_Energy,
49  std::vector<double> short_ET,
50  std::vector<double> long_optimumSlope,
51  std::vector<double> long_Energy,
52  std::vector<double> long_ET,
53  int HcalAcceptSeverityLevel,
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 
61  LongSlopes=long_optimumSlope;
62  ShortSlopes=short_optimumSlope;
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 
79  HcalAcceptSeverityLevel_=HcalAcceptSeverityLevel;
80  isS8S1_=isS8S1;
81 } // HcalHF_S9S1algorithm constructor with parameters
82 
84 
85 
87  HFRecHitCollection& rec,
88  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  double fEta = 0.5*(theHFEtaBounds[abs(ieta)-29] + theHFEtaBounds[abs(ieta)-28]); // calculate eta as average of eta values at ieta boundaries
96  double energy=hf.energy();
97  double ET = energy/fabs(cosh(fEta));
98 
99  // Step 1: Check eta-dependent energy and ET thresholds -- same as PET algorithm
100  double ETthresh=0, Energythresh=0; // set ET, energy thresholds
101  if (depth==1) // set thresholds for long fibers
102  {
103  Energythresh = LongEnergyThreshold[abs(ieta)-29];
104  ETthresh = LongETThreshold[abs(ieta)-29];
105  }
106  else if (depth==2) // short fibers
107  {
108  Energythresh = ShortEnergyThreshold[abs(ieta)-29];
109  ETthresh = ShortETThreshold[abs(ieta)-29];
110  }
111  if (energy<Energythresh || ET < ETthresh)
112  return;
113 
114  // Step 1A:
115  // Check that EL<ES when evaluating short fibers (S8S1 check only)
116  if (depth==2 && abs(ieta)>29 && isS8S1_)
117  {
118  double EL=0;
119  // look for long partner
120  HcalDetId neighbor(HcalForward, ieta,iphi,1);
121  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
122  if (neigh!=rec.end())
123  EL=neigh->energy();
124 
125  if (EL>=energy)
126  return;
127  }
128 
129  // Step 2: Find all neighbors, and calculate S9/S1
130  double S9S1=0;
131  int testphi=-99;
132 
133  // Part A: Check fixed iphi, and vary ieta
134  for (int d=1;d<=2;++d) // depth loop
135  {
136  for (int i=ieta-1;i<=ieta+1;++i) // ieta loop
137  {
138  testphi=iphi;
139  // Special case when ieta=39, since ieta=40 only has phi values at 3,7,11,...
140  // phi=3 covers 3,4,5,6
141  if (abs(ieta)==39 && abs(i)>39 && testphi%4==1)
142  testphi-=2;
143  while (testphi<0) testphi+=72;
144  if (i==ieta)
145  if (d==depth || isS8S1_==true) continue; // don't add the cell itself; don't count neighbor in same ieta-phi if S8S1 test enabled
146 
147  // Look to see if neighbor is in rechit collection
148  HcalDetId neighbor(HcalForward, i,testphi,d);
149  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
150  // require that neighbor exists, and that it doesn't have a prior flag already set
151  if (neigh!=rec.end())
152  {
153  const uint32_t chanstat = myqual->getValues(neighbor)->getValue();
154  int SeverityLevel=mySeverity->getSeverityLevel(neighbor, neigh->flags(),
155  chanstat);
156  if (SeverityLevel<=HcalAcceptSeverityLevel_)
157  S9S1+=neigh->energy();
158  }
159  }
160  }
161 
162  // Part B: Fix ieta, and loop over iphi. A bit more tricky, because of iphi wraparound and different segmentation at 40, 41
163 
164  int phiseg=2; // 10 degree segmentation for most of HF (1 iphi unit = 5 degrees)
165  if (abs(ieta)>39) phiseg=4; // 20 degree segmentation for |ieta|>39
166  for (int d=1;d<=2;++d)
167  {
168  for (int i=iphi-phiseg;i<=iphi+phiseg;i+=phiseg)
169  {
170  if (i==iphi) continue; // don't add the cell itself, or its depthwise partner (which is already counted above)
171  testphi=i;
172  // Our own modular function, since default produces results -1%72 = -1
173  while (testphi<0) testphi+=72;
174  while (testphi>72) testphi-=72;
175  // Look to see if neighbor is in rechit collection
176  HcalDetId neighbor(HcalForward, ieta,testphi,d);
177  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
178  if (neigh!=rec.end())
179  {
180  const uint32_t chanstat = myqual->getValues(neighbor)->getValue();
181  int SeverityLevel=mySeverity->getSeverityLevel(neighbor, neigh->flags(),
182  chanstat);
183  if (SeverityLevel<=HcalAcceptSeverityLevel_)
184  S9S1+=neigh->energy();
185  }
186  }
187  }
188 
189  if (abs(ieta)==40) // add extra cells for 39/40 boundary due to increased phi size at ieta=40.
190  {
191  for (int d=1;d<=2;++d) // add cells from both depths!
192  {
193  HcalDetId neighbor(HcalForward, 39*abs(ieta)/ieta,(iphi+2)%72,d);
194  HFRecHitCollection::const_iterator neigh=rec.find(neighbor);
195  if (neigh!=rec.end())
196  {
197  const uint32_t chanstat = myqual->getValues(neighbor)->getValue();
198  int SeverityLevel=mySeverity->getSeverityLevel(neighbor, neigh->flags(),
199  chanstat);
200  if (SeverityLevel<=HcalAcceptSeverityLevel_)
201  S9S1+=neigh->energy();
202  }
203 
204  }
205  }
206 
207  // So far, S9S1 is the sum of the neighbors; divide to form ratio
208  S9S1/=energy;
209 
210  // Now compare to threshold
211  double slope=0;
212  if (depth==1) slope = LongSlopes[abs(ieta)-29];
213  else if (depth==2) slope=ShortSlopes[abs(ieta)-29];
214  double intercept = 0;
215  if (depth==1) intercept = LongEnergyThreshold[abs(ieta)-29];
216  else if (depth==2) intercept = ShortEnergyThreshold[abs(ieta)-29];
217 
218  // S9S1 cut has the form [0] + [1]*log[E]; S9S1 value should be above this line
219  double S9S1cut = 0;
220  // 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?
221  if (intercept>0 && energy>0)
222  S9S1cut=-1.*slope*log(intercept) + slope*log(energy);
223  if (S9S1<S9S1cut)
224  {
225  // Only set HFS8S1Ratio if S8/S1 ratio test fails
226  if (isS8S1_==true)
228  // *Always* set the HFLongShort bit if either S8S1 or S9S1 fail
230  }
231  return;
232 } // void HcalHF_S9S1algorithm::HFSetFlagFromS9S1
233 
234 
235 
236 double HcalHF_S9S1algorithm::CalcSlope(int abs_ieta, std::vector<double> params)
237 {
238  /* CalcSlope calculates the polynomial [0]+[1]*x + [2]*x^2 + ....,
239  where x is an integer provided by the first argument (int abs_ieta),
240  and [0],[1],[2] is a vector of doubles provided by the second (std::vector<double> params).
241  The output of the polynomial calculation (threshold) is returned by the function.
242  This function should no longer be needed, since we pass slopes for all ietas into the function via the parameter set.
243  */
244  double threshold=0;
245  for (std::vector<double>::size_type i=0;i<params.size();++i)
246  {
247  threshold+=params[i]*pow(static_cast<double>(abs_ieta), (int)i);
248  }
249  return threshold;
250 } // HcalHF_S9S1algorithm::CalcRThreshold(int abs_ieta, std::vector<double> params)
251 
252 
253 
254 
255 double HcalHF_S9S1algorithm::CalcEnergyThreshold(double abs_energy,std::vector<double> params)
256 {
257  /* CalcEnergyThreshold calculates the polynomial [0]+[1]*x + [2]*x^2 + ....,
258  where x is an integer provided by the first argument (int abs_ieta),
259  and [0],[1],[2] is a vector of doubles provided by the second (std::vector<double> params).
260  The output of the polynomial calculation (threshold) is returned by the function.
261  */
262  double threshold=0;
263  for (std::vector<double>::size_type i=0;i<params.size();++i)
264  {
265  threshold+=params[i]*pow(abs_energy, (int)i);
266  }
267  return threshold;
268 } //double HcalHF_S9S1algorithm::CalcEnergyThreshold(double abs_energy,std::vector<double> params)
269 
int i
Definition: DBlmapReader.cc:9
std::vector< double > LongSlopes
double CalcSlope(int abs_ieta, std::vector< double > params)
static const double slope[3]
void setFlagField(uint32_t value, int base, int width=1)
Definition: CaloRecHit.cc:20
std::vector< T >::const_iterator const_iterator
std::vector< double > LongEnergyThreshold
#define abs(x)
Definition: mlp_lapack.h:159
std::vector< double > LongETThreshold
uint16_t size_type
int depth() const
get the tower depth
Definition: HcalDetId.h:42
std::vector< double > ShortSlopes
float energy() const
Definition: CaloRecHit.h:19
int ieta() const
get the cell ieta
Definition: HcalDetId.h:38
const_iterator end() const
int iphi() const
get the cell iphi
Definition: HcalDetId.h:40
void HFSetFlagFromS9S1(HFRecHit &hf, HFRecHitCollection &rec, HcalChannelQuality *myqual, const HcalSeverityLevelComputer *mySeverity)
static const double theHFEtaBounds[]
double CalcEnergyThreshold(double abs_energy, std::vector< double > params)
int getSeverityLevel(const DetId &myid, const uint32_t &myflag, const uint32_t &mystatus) const
iterator find(key_type k)
std::vector< double > ShortETThreshold
#define ET
HcalDetId id() const
get the id
Definition: HFRecHit.h:21
std::vector< double > ShortEnergyThreshold
uint32_t getValue() const
const Item * getValues(DetId fId) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40