CMS 3D CMS Logo

SiTrivialInduceChargeOnStrips.cc
Go to the documentation of this file.
2 
10 
11 #include <algorithm>
12 #include <iostream>
13 
14 namespace {
15  struct Count {
16  Count() {}
17 #ifdef SISTRIP_COUNT
18  // note: this code is not thread safe, counts will be inaccurate if run with multiple threads
19  double ncall = 0;
20  double ndep = 0, ndep2 = 0, maxdep = 0;
21  double nstr = 0, nstr2 = 0;
22  double ncv = 0, nval = 0, nval2 = 0, maxv = 0;
23  double dzero = 0;
24  void dep(double d) {
25  ncall++;
26  ndep += d;
27  ndep2 += d * d;
28  maxdep = std::max(d, maxdep);
29  }
30  void str(double d) {
31  nstr += d;
32  nstr2 += d * d;
33  }
34  void val(double d) {
35  ncv++;
36  nval += d;
37  nval2 += d * d;
38  maxv = std::max(d, maxv);
39  }
40  void zero() { dzero++; }
41  ~Count() {
42  std::cout << "deposits " << ncall << " " << maxdep << " " << ndep / ncall << " "
43  << std::sqrt(ndep2 * ncall - ndep * ndep) / ncall << std::endl;
44  std::cout << "zeros " << dzero << std::endl;
45  std::cout << "strips " << nstr / ndep << " " << std::sqrt(nstr2 * ndep - nstr * nstr) / ndep << std::endl;
46  std::cout << "vaules " << ncv << " " << maxv << " " << nval / ncv << " "
47  << std::sqrt(nval2 * ncv - nval * nval) / ncv << std::endl;
48  }
49  };
50  Count count;
51 #else
52  void dep(double) const {}
53  void str(double) const {}
54  void val(double) const {}
55  void zero() const {}
56  };
57  const Count count;
58 #endif
59 
60 } // namespace
61 
62 namespace {
63  constexpr int Ntypes = 14;
64  // 0 1 2 3 4 5 6 7
65  const std::string type[Ntypes] = {
66  "IB1", "IB2", "OB1", "OB2", "W1a", "W2a", "W3a", "W1b", "W2b", "W3b", "W4", "W5", "W6", "W7"};
67  enum { indexOfIB1 = 0, indexOfIB2 = 1, indexOfOB1 = 2, indexOfOB2 = 3, indexOfW1a = 4, indexOfW1b = 7 };
68 
69  inline std::vector<std::vector<float> > fillSignalCoupling(const edm::ParameterSet& conf,
70  int nTypes,
71  const std::string* typeArray) {
72  std::vector<std::vector<float> > signalCoupling;
73  signalCoupling.reserve(nTypes);
74  std::string mode = conf.getParameter<bool>("APVpeakmode") ? "Peak" : "Dec";
75  for (int i = 0; i < nTypes; ++i) {
76  std::string version = "";
77  if (typeArray[i].find('W') != std::string::npos && mode == "Dec")
78  version = conf.getParameter<bool>("CouplingConstantsRunIIDecW") ? "RunII" : "";
79  else if (typeArray[i].find('B') != std::string::npos && mode == "Dec")
80  version = conf.getParameter<bool>("CouplingConstantsRunIIDecB") ? "RunII" : "";
81 
82  auto dc = conf.getParameter<std::vector<double> >("CouplingConstant" + version + mode + typeArray[i]);
83  signalCoupling.emplace_back(dc.begin(), dc.end());
84  }
85  return signalCoupling;
86  }
87 
88  inline unsigned int typeOf(const StripGeomDetUnit& det, const TrackerTopology* tTopo) {
89  DetId id = det.geographicalId();
90  switch (det.specificType().subDetector()) {
92  return (tTopo->tibLayer(id) < 3) ? indexOfIB1 : indexOfIB2;
93  }
95  return (tTopo->tobLayer(id) > 4) ? indexOfOB1 : indexOfOB2;
96  }
98  return indexOfW1a - 1 + tTopo->tidRing(id);
99  } //fragile: relies on ordering of 'type'
101  return indexOfW1b - 1 + tTopo->tecRing(id);
102  } //fragile: relies on ordering of 'type'
103  default:
104  throw cms::Exception("Invalid subdetector") << id();
105  }
106  }
107 
108  inline double chargeDeposited(
109  size_t strip, size_t Nstrips, double amplitude, double chargeSpread, double chargePosition) {
110  double integralUpToStrip =
111  (strip == 0) ? 0. : (approx_erf((strip - chargePosition) / chargeSpread / 1.41421356237309515));
112  double integralUpToNext =
113  (strip + 1 == Nstrips) ? 1. : (approx_erf((strip + 1 - chargePosition) / chargeSpread / 1.41421356237309515));
114 
115  return 0.5 * (integralUpToNext - integralUpToStrip) * amplitude;
116  }
117 
118 } // namespace
119 
121  : signalCoupling(fillSignalCoupling(conf, Ntypes, type)), Nsigma(3.), geVperElectron(g) {}
122 
124  const StripGeomDetUnit& det,
125  std::vector<float>& localAmplitudes,
126  size_t& recordMinAffectedStrip,
127  size_t& recordMaxAffectedStrip,
128  const TrackerTopology* tTopo) const {
129  induceVector(collection_points, det, localAmplitudes, recordMinAffectedStrip, recordMaxAffectedStrip, tTopo);
130 
131  /*
132  auto ominA=recordMinAffectedStrip, omaxA=recordMaxAffectedStrip;
133  std::vector<float> oampl(localAmplitudes);
134  induceOriginal(collection_points, det, oampl, ominA, omaxA, tTopo);
135 
136  // std::cout << "orig " << ominA << " " << omaxA << " ";
137  //for (auto a : oampl) std::cout << a << ",";
138  //std::cout << std::endl;
139 
140  auto minA=recordMinAffectedStrip, maxA=recordMaxAffectedStrip;
141  std::vector<float> ampl(localAmplitudes);
142  induceVector(collection_points, det, ampl, minA, maxA, tTopo);
143 
144  // std::cout << "vect " << minA << " " << maxA << " ";
145  //for (auto a : ampl) std::cout << a << ",";
146  //std::cout << std::endl;
147 
148  float diff=0;
149  for (size_t i=0; i!=ampl.size(); ++i) { diff = std::max(diff,ampl[i]>0 ? std::abs(ampl[i]-oampl[i])/ampl[i] : 0);}
150  if (diff> 1.e-4) {
151  std::cout << diff << std::endl;
152  std::cout << "orig " << ominA << " " << omaxA << " ";
153 // for (auto a : oampl) std::cout << a << ",";
154  std::cout << std::endl;
155  std::cout << "vect " << minA << " " << maxA << " ";
156 // for (auto a : ampl) std::cout << a << ",";
157  std::cout << std::endl;
158  }
159 
160  localAmplitudes.swap(ampl);
161  recordMinAffectedStrip=minA;
162  recordMaxAffectedStrip=maxA;
163  */
164 }
165 
167  const StripGeomDetUnit& det,
168  std::vector<float>& localAmplitudes,
169  size_t& recordMinAffectedStrip,
170  size_t& recordMaxAffectedStrip,
171  const TrackerTopology* tTopo) const {
172  auto const& coupling = signalCoupling[typeOf(det, tTopo)];
173  const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
174  const int Nstrips = topology.nstrips();
175 
176  if (Nstrips == 0)
177  return;
178 
179  const int NP = collection_points.size();
180  if (0 == NP)
181  return;
182 
183  constexpr int MaxN = 512;
184  // if NP too large split...
185 
186  for (int ip = 0; ip < NP; ip += MaxN) {
187  auto N = std::min(NP - ip, MaxN);
188 
189  count.dep(N);
190  float amplitude[N];
191  float chargePosition[N];
192  float chargeSpread[N];
193  int fromStrip[N];
194  int nStrip[N];
195 
196  // load not vectorize
197  //In strip coordinates:
198  for (int i = 0; i != N; ++i) {
199  auto j = ip + i;
200  if (0 == collection_points[j].amplitude())
201  count.zero();
202  chargePosition[i] = topology.strip(collection_points[j].position());
203  chargeSpread[i] = collection_points[j].sigma() / topology.localPitch(collection_points[j].position());
204  amplitude[i] = 0.5f * collection_points[j].amplitude() / geVperElectron;
205  }
206 
207  // this vectorize
208  for (int i = 0; i != N; ++i) {
209  fromStrip[i] = std::max(0, int(std::floor(chargePosition[i] - Nsigma * chargeSpread[i])));
210  nStrip[i] = std::min(Nstrips, int(std::ceil(chargePosition[i] + Nsigma * chargeSpread[i]))) - fromStrip[i];
211  }
212  int tot = 0;
213  for (int i = 0; i != N; ++i)
214  tot += nStrip[i];
215  tot += N; // add last strip
216  count.val(tot);
217  float value[tot];
218 
219  // assign relative position (lower bound of strip) in value;
220  int kk = 0;
221  for (int i = 0; i != N; ++i) {
222  auto delta = 1.f / (std::sqrt(2.f) * chargeSpread[i]);
223  auto pos = delta * (float(fromStrip[i]) - chargePosition[i]);
224 
225  // VI: before value[0] was not defined and value[tot] was filled
226  // to fix this the loop below was changed
227  for (int j = 0; j <= nStrip[i]; ++j) {
228  value[kk] = pos + float(j) * delta;
229  ++kk;
230  }
231  }
232  assert(kk == tot);
233 
234  // main loop fully vectorized
235  for (int k = 0; k != tot; ++k)
236  value[k] = approx_erf(value[k]);
237 
238  // saturate 0 & NStrips strip to 0 and 1???
239  kk = 0;
240  for (int i = 0; i != N; ++i) {
241  if (0 == fromStrip[i])
242  value[kk] = 0;
243  kk += nStrip[i];
244  if (Nstrips == fromStrip[i] + nStrip[i])
245  value[kk] = 1.f;
246  ++kk;
247  }
248  assert(kk == tot);
249 
250  // compute integral over strip (lower bound becomes the value)
251  for (int k = 0; k != tot - 1; ++k)
252  value[k] -= value[k + 1]; // this is negative!
253 
254  float charge[Nstrips];
255  for (int i = 0; i != Nstrips; ++i)
256  charge[i] = 0;
257  kk = 0;
258  for (int i = 0; i != N; ++i) {
259  for (int j = 0; j != nStrip[i]; ++j)
260  charge[fromStrip[i] + j] -= amplitude[i] * value[kk++];
261  ++kk; // skip last "strip"
262  }
263  assert(kk == tot);
264 
266  int minA = recordMinAffectedStrip, maxA = recordMaxAffectedStrip;
267  int sc = coupling.size();
268  for (int i = 0; i != Nstrips; ++i) {
269  int strip = i;
270  if (0 == charge[i])
271  continue;
272  auto affectedFromStrip = std::max(0, strip - sc + 1);
273  auto affectedUntilStrip = std::min(Nstrips, strip + sc);
274  for (auto affectedStrip = affectedFromStrip; affectedStrip < affectedUntilStrip; ++affectedStrip)
275  localAmplitudes[affectedStrip] += charge[i] * coupling[std::abs(affectedStrip - strip)];
276 
277  if (affectedFromStrip < minA)
278  minA = affectedFromStrip;
279  if (affectedUntilStrip > maxA)
280  maxA = affectedUntilStrip;
281  }
282  recordMinAffectedStrip = minA;
283  recordMaxAffectedStrip = maxA;
284  } // end loop ip
285 }
286 
288  const StripGeomDetUnit& det,
289  std::vector<float>& localAmplitudes,
290  size_t& recordMinAffectedStrip,
291  size_t& recordMaxAffectedStrip,
292  const TrackerTopology* tTopo) const {
293  auto const& coupling = signalCoupling[typeOf(det, tTopo)];
294  const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
295  size_t Nstrips = topology.nstrips();
296 
297  if (!collection_points.empty())
298  count.dep(collection_points.size());
299 
300  for (auto signalpoint = collection_points.begin(); signalpoint != collection_points.end(); signalpoint++) {
301  //In strip coordinates:
302  double chargePosition = topology.strip(signalpoint->position());
303  double chargeSpread = signalpoint->sigma() / topology.localPitch(signalpoint->position());
304 
305  size_t fromStrip = size_t(std::max(0, int(std::floor(chargePosition - Nsigma * chargeSpread))));
306  size_t untilStrip = size_t(std::min(Nstrips, size_t(std::ceil(chargePosition + Nsigma * chargeSpread))));
307 
308  count.str(std::max(0, int(untilStrip) - int(fromStrip)));
309  for (size_t strip = fromStrip; strip < untilStrip; strip++) {
310  double chargeDepositedOnStrip =
311  chargeDeposited(strip, Nstrips, signalpoint->amplitude() / geVperElectron, chargeSpread, chargePosition);
312 
313  size_t affectedFromStrip = size_t(std::max(0, int(strip - coupling.size() + 1)));
314  size_t affectedUntilStrip = size_t(std::min(Nstrips, strip + coupling.size()));
315  for (size_t affectedStrip = affectedFromStrip; affectedStrip < affectedUntilStrip; affectedStrip++) {
316  localAmplitudes.at(affectedStrip) +=
317  chargeDepositedOnStrip * coupling.at((size_t)std::abs((int)affectedStrip - (int)strip));
318  }
319 
320  if (affectedFromStrip < recordMinAffectedStrip)
321  recordMinAffectedStrip = affectedFromStrip;
322  if (affectedUntilStrip > recordMaxAffectedStrip)
323  recordMaxAffectedStrip = affectedUntilStrip;
324  }
325  }
326 }
constexpr int32_t ceil(float num)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
unsigned int tobLayer(const DetId &id) const
void induceOriginal(const SiChargeCollectionDrifter::collection_type &collection_points, const StripGeomDetUnit &det, std::vector< float > &localAmplitudes, size_t &recordMinAffectedStrip, size_t &recordMaxAffectedStrip, const TrackerTopology *tTopo) const
SubDetector subDetector() const
Definition: GeomDetType.h:21
const std::vector< std::vector< float > > signalCoupling
std::vector< SignalPoint > collection_type
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
int dzero(double a, double b, double &x0, double &rv, double eps, int mxf, F func)
Private version of the exponential integral.
Definition: VVIObj.cc:632
unsigned int tecRing(const DetId &id) const
ring id
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
T sqrt(T t)
Definition: SSEVec.h:23
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
virtual StripGeomDetType const & specificType() const
Definition: value.py:1
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:64
d
Definition: ztail.py:151
void induce(const SiChargeCollectionDrifter::collection_type &collection_points, const StripGeomDetUnit &det, std::vector< float > &localAmplitudes, size_t &recordMinAffectedStrip, size_t &recordMaxAffectedStrip, const TrackerTopology *tTopo) const override
Definition: DetId.h:17
#define N
Definition: blowfish.cc:9
constexpr float approx_erf(float x)
Definition: approx_erf.h:5
static int position[264][3]
Definition: ReadPGInfo.cc:289
unsigned int tidRing(const DetId &id) const
unsigned int tibLayer(const DetId &id) const
void induceVector(const SiChargeCollectionDrifter::collection_type &collection_points, const StripGeomDetUnit &det, std::vector< float > &localAmplitudes, size_t &recordMinAffectedStrip, size_t &recordMaxAffectedStrip, const TrackerTopology *tTopo) const
#define str(s)
SiTrivialInduceChargeOnStrips(const edm::ParameterSet &conf, double g)