CMS 3D CMS Logo

ESRecHitSimAlgo.cc
Go to the documentation of this file.
3 
4 #include <cmath>
5 #include <vdt/vdtMath.h>
6 
7 #include<cstdlib>
8 #include<cstring>
9 #include<cassert>
10 #include <iostream>
11 
13 
14  float energy = 0;
15  float adc[3] {};
16  float pw[3] {};
17  pw[0] = w0_;
18  pw[1] = w1_;
19  pw[2] = w2_;
20 
21  for (int i=0; i<digi.size(); i++) {
22  energy += pw[i]*(digi.sample(i).adc()-ped);
23  LogDebug("ESRecHitSimAlgo") << "ESRecHitSimAlgo : Digi "<<i<<" ADC counts "<<digi.sample(i).adc()<<" Ped "<<ped;
24  //std::cout<<i<<" "<<digi.sample(i).adc()<<" "<<ped<<" "<<pw[i]<<std::endl;
25  adc[i] = digi.sample(i).adc() - ped;
26  }
27 
29  if (adc[0] > 20.f) status = EcalRecHit::kESTS13Sigmas; // 14;
30  if (adc[1] <= 0 || adc[2] <= 0) status = EcalRecHit::kESTS3Negative; // 10;
31  if (adc[0] > adc[1] && adc[0] > adc[2]) status = EcalRecHit::kESTS1Largest; // 8;
32  if (adc[2] > adc[1] && adc[2] > adc[0]) status = EcalRecHit::kESTS3Largest; // 9;
33  auto r12 = (adc[1] != 0) ? adc[0]/adc[1] : 99.f;
34  auto r23 = (adc[2] != 0) ? adc[1]/adc[2] : 99.f;
35  if (r12 > ratioCuts_->getR12High()) status = EcalRecHit::kESBadRatioFor12;// 5;
36  if (r23 > ratioCuts_->getR23High()) status = EcalRecHit::kESBadRatioFor23Upper; // 6;
37  if (r23 < ratioCuts_->getR23Low()) status = EcalRecHit::kESBadRatioFor23Lower; // 7
38 
39  auto A1 = adc[1];
40  auto A2 = adc[2];
41 
42  // t0 from analytical formula:
43  constexpr float n = 1.798;
44  constexpr float w = 0.07291;
45  constexpr float DeltaT = 25.;
46  auto aaa = (A2 > 0 && A1 > 0) ? std::log(A2/A1)/n : 20.f; // if A1=0, t0=20
47  constexpr float bbb = w/n*DeltaT;
48  auto ccc= std::exp(aaa+bbb);
49 
50  auto t0 = (2.f-ccc)/(1.f-ccc) * DeltaT - 5.f;
51 
52  // A from analytical formula:
53  constexpr float t1 = 20.;
54  #if defined(__clang__) || defined(__INTEL_COMPILER)
55  const float A_1 = 1./( std::pow(w/n*(t1),n) * std::exp(n-w*(t1)) );
56  #else
57  constexpr float A_1 = 1./( std::pow(w/n*(t1),n) * std::exp(n-w*(t1)) );
58  #endif
59  auto AA1 = A1 * A_1 ;
60 
61  if (adc[1] > 2800.f && adc[2] > 2800.f) status = EcalRecHit::kESSaturated;
62  else if (adc[1] > 2800.f) status = EcalRecHit::kESTS2Saturated;
63  else if (adc[2] > 2800.f) status = EcalRecHit::kESTS3Saturated;
64 
65  results[0] = energy; // energy with weight method
66  results[1] = t0; // timing
67  results[2] = AA1; // energy with analytic method
68 
69  return status;
70 
71 }
72 
74 
75 
76  auto ind = digi.id().hashedIndex();
77 
78  auto const & ped = peds_->preshower(ind);
79  auto const & mip = mips_->getMap().preshower(ind);
80  auto const & ang = ang_->getMap().preshower(ind);
81  auto const & statusCh = channelStatus_->getMap().preshower(ind);
82 
83  float results[3] {};
84 
85  auto status = evalAmplitude(results, digi, ped.getMean());
86 
87  auto energy = results[0];
88  auto t0 = results[1];
89  auto otenergy = results[2] * 1000000.f; // set out-of-time energy to keV
90 
91 
92  auto mipCalib = (mip != 0.f) ? MIPGeV_*std::abs(vdt::fast_cosf(ang))/(mip) : 0.f;
93  energy *= mipCalib;
94  otenergy *= mipCalib;
95 
96  LogDebug("ESRecHitSimAlgo") << "ESRecHitSimAlgo : reconstructed energy "<<energy;
97 
98  EcalRecHit rechit(digi.id(), energy, t0);
99  // edm: this is just a placeholder for alternative energy reconstruction,
100  // so put it in the same float, with different name
101  // rechit.setOutOfTimeEnergy(otenergy);
102  rechit.setEnergyError(otenergy);
103 
104  rechit.setFlag(statusCh.getStatusCode() == 1 ? EcalRecHit::kESDead : status);
105 
106  return rechit;
107 
108 }
109 
110 /*
111 
112  auto oldHit = oldreconstruct(digi);
113 
114  assert(rechit.recoFlag()==oldHit.recoFlag());
115 
116  if (oldHit.energy()>0)
117  std::cout << "ESd " << digi.id() <<" : "
118  << rechit.energy()<<"," << oldHit.energy() << " "
119  << rechit.time()<<"," << oldHit.time() << " "
120  << rechit.outOfTimeEnergy()<<"," << oldHit.outOfTimeEnergy() << std::endl;
121 
122 
123  auto bitdiff = [](float a, float b)->int {
124  int ia, ib;
125  memcpy(&ia,&a,4);
126  memcpy(&ib,&b,4);
127  return std::abs(ia-ib);
128  };
129 
130  auto d0 = bitdiff( rechit.energy(), rechit.energy() );
131  auto d1 = bitdiff( rechit.time(), rechit.time() );
132  auto d2 = bitdiff(rechit.outOfTimeEnergy(), oldHit.outOfTimeEnergy());
133 
134  struct aMax {
135  ~aMax() { std::cout << "\n\nmax deviation " << m << " " << mp << std::endl; }
136  int m=0;
137  int mp=0;
138  };
139 
140  static aMax am;
141  am.m = std::max(am.m,std::max(d0,std::max(d1,d2)));
142  if (oldHit.energy()>0) am.mp = std::max(am.m,std::max(d0,std::max(d1,d2)));
143 
144 
145  return rechit;
146 }
147 */
148 
149 //
150 
151 double* ESRecHitSimAlgo::oldEvalAmplitude(const ESDataFrame& digi, const double& ped, const double& w0, const double& w1, const double& w2) const {
152 
153  double *results = new double[4] {};
154  float energy = 0;
155  double adc[3] {};
156  float pw[3] {};
157  pw[0] = w0;
158  pw[1] = w1;
159  pw[2] = w2;
160 
161  for (int i=0; i<digi.size(); i++) {
162  energy += pw[i]*(digi.sample(i).adc()-ped);
163  LogDebug("ESRecHitSimAlgo") << "ESRecHitSimAlgo : Digi "<<i<<" ADC counts "<<digi.sample(i).adc()<<" Ped "<<ped;
164  //std::cout<<i<<" "<<digi.sample(i).adc()<<" "<<ped<<" "<<pw[i]<<std::endl;
165  adc[i] = digi.sample(i).adc() - ped;
166  }
167 
168  double status = 0;
169  if (adc[0] > 20) status = 14;
170  if (adc[1] <= 0 || adc[2] <= 0) status = 10;
171  if (adc[0] > adc[1] && adc[0] > adc[2]) status = 8;
172  if (adc[2] > adc[1] && adc[2] > adc[0]) status = 9;
173  double r12 = (adc[1] != 0) ? adc[0]/adc[1] : 99;
174  double r23 = (adc[2] != 0) ? adc[1]/adc[2] : 99;
175  if (r12 > ratioCuts_->getR12High()) status = 5;
176  if (r23 > ratioCuts_->getR23High()) status = 6;
177  if (r23 < ratioCuts_->getR23Low()) status = 7;
178 
179  double A1 = adc[1];
180  double A2 = adc[2];
181 
182  // t0 from analytical formula:
183  double n = 1.798;
184  double w = 0.07291;
185  double DeltaT = 25.;
186  double aaa = (A2 > 0 && A1 > 0) ? log(A2/A1)/n : 20.; // if A1=0, t0=20
187  double bbb = w/n*DeltaT;
188  double ccc= exp(aaa+bbb);
189 
190  double t0 = (2.-ccc)/(1.-ccc) * DeltaT - 5;
191 
192  // A from analytical formula:
193  double t1 = 20.;
194  double A_1 = pow(w/n*(t1),n) * exp(n-w*(t1));
195  double AA1 = (A_1 != 0.) ? A1 / A_1 : 0.;
196 
197  if (adc[1] > 2800 && adc[2] > 2800) status = 11;
198  else if (adc[1] > 2800) status = 12;
199  else if (adc[2] > 2800) status = 13;
200 
201  results[0] = energy; // energy with weight method
202  results[1] = t0; // timing
203  results[2] = status; // hit status
204  results[3] = AA1; // energy with analytic method
205 
206  return results;
207 }
208 
210 
211  ESPedestals::const_iterator it_ped = peds_->find(digi.id());
212 
215 
217 
218  double* results;
219 
220  results = oldEvalAmplitude(digi, it_ped->getMean(), w0_, w1_, w2_);
221 
222  double energy = results[0];
223  double t0 = results[1];
224  int status = (int) results[2];
225  double otenergy = results[3] * 1000000.; // set out-of-time energy to keV
226  delete[] results;
227 
228  double mipCalib = (fabs(cos(*it_ang)) != 0.) ? (*it_mip)/fabs(cos(*it_ang)) : 0.;
229  energy *= (mipCalib != 0.) ? MIPGeV_/mipCalib : 0.;
230  otenergy *= (mipCalib != 0.) ? MIPGeV_/mipCalib : 0.;
231 
232  LogDebug("ESRecHitSimAlgo") << "ESRecHitSimAlgo : reconstructed energy "<<energy;
233 
234  EcalRecHit rechit(digi.id(), energy, t0);
235  // edm: this is just a placeholder for alternative energy reconstruction,
236  // so put it in the same float, with different name
237  // rechit.setOutOfTimeEnergy(otenergy);
238  rechit.setEnergyError(otenergy);
239 
240  if (it_status->getStatusCode() == 1) {
241  rechit.setFlag(EcalRecHit::kESDead);
242  } else {
243  if (status == 0)
244  rechit.setFlag(EcalRecHit::kESGood);
245  else if (status == 5)
246  rechit.setFlag(EcalRecHit::kESBadRatioFor12);
247  else if (status == 6)
248  rechit.setFlag(EcalRecHit::kESBadRatioFor23Upper);
249  else if (status == 7)
250  rechit.setFlag(EcalRecHit::kESBadRatioFor23Lower);
251  else if (status == 8)
252  rechit.setFlag(EcalRecHit::kESTS1Largest);
253  else if (status == 9)
254  rechit.setFlag(EcalRecHit::kESTS3Largest);
255  else if (status == 10)
256  rechit.setFlag(EcalRecHit::kESTS3Negative);
257  else if (status == 11)
258  rechit.setFlag(EcalRecHit::kESSaturated);
259  else if (status == 12)
260  rechit.setFlag(EcalRecHit::kESTS2Saturated);
261  else if (status == 13)
262  rechit.setFlag(EcalRecHit::kESTS3Saturated);
263  else if (status == 14)
264  rechit.setFlag(EcalRecHit::kESTS13Sigmas);
265  }
266 
267  return rechit;
268 }
269 
#define LogDebug(id)
EcalRecHit reconstruct(const ESDataFrame &digi) const
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
const double w
Definition: UKUtility.cc:23
const ESDetId & id() const
Definition: ESDataFrame.h:21
const self & getMap() const
int size() const
Definition: ESDataFrame.h:23
const ESPedestals * peds_
const ESIntercalibConstants * mips_
void setEnergyError(float energy)
Definition: EcalRecHit.h:144
const ESChannelStatus * channelStatus_
EcalRecHit oldreconstruct(const ESDataFrame &digi) const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
const_iterator find(uint32_t rawId) const
const ESSample & sample(int i) const
Definition: ESDataFrame.h:26
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
constexpr int adc(sample_type sample)
get the ADC sample (12 bits)
const Item & preshower(size_t hashedIndex) const
double * oldEvalAmplitude(const ESDataFrame &digi, const double &ped, const double &w0, const double &w1, const double &w2) const
const ESRecHitRatioCuts * ratioCuts_
const ESAngleCorrectionFactors * ang_
std::vector< Item >::const_iterator const_iterator
float getR12High() const
float getR23High() const
EcalRecHit::ESFlags evalAmplitude(float *result, const ESDataFrame &digi, float ped) const
int adc() const
get the ADC sample (singed 16 bits)
Definition: ESSample.h:18
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
#define constexpr
int hashedIndex() const
get a compact index for arrays [TODO: NEEDS WORK]
Definition: ESDetId.cc:21