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) { ncall++; ndep+=d; ndep2+=d*d;maxdep=std::max(d,maxdep);}
25  void str(double d) { nstr+=d; nstr2+=d*d;}
26  void val(double d) { ncv++; nval+=d; nval2+=d*d; maxv=std::max(d,maxv);}
27  void zero() { dzero++;}
28  ~Count() {
29  std::cout << "deposits " << ncall << " " << maxdep << " " << ndep/ncall << " " << std::sqrt(ndep2*ncall -ndep*ndep)/ncall << std::endl;
30  std::cout << "zeros " << dzero << std::endl;
31  std::cout << "strips " << nstr/ndep << " " << std::sqrt(nstr2*ndep -nstr*nstr)/ndep << std::endl;
32  std::cout << "vaules " << ncv << " " << maxv << " " << nval/ncv << " " << std::sqrt(nval2*ncv -nval*nval)/ncv << std::endl;
33  }
34  };
35  Count count;
36 #else
37  void dep(double) const {}
38  void str(double) const {}
39  void val(double) const {}
40  void zero() const {}
41  };
42  const Count count;
43 #endif
44 
45 }
46 
47 
48 namespace {
49  constexpr int Ntypes = 14;
50  // 0 1 2 3 4 5 6 7
51  const std::string type[Ntypes] = { "IB1", "IB2","OB1","OB2","W1a","W2a","W3a","W1b","W2b","W3b","W4","W5","W6","W7"};
52  enum { indexOfIB1=0, indexOfIB2=1, indexOfOB1=2, indexOfOB2=3, indexOfW1a=4, indexOfW1b=7};
53 
54  inline
55  std::vector<std::vector<float> >
56  fillSignalCoupling(const edm::ParameterSet& conf, int nTypes, const std::string* typeArray) {
57  std::vector<std::vector<float> > signalCoupling;
58  signalCoupling.reserve(nTypes);
59  std::string mode = conf.getParameter<bool>("APVpeakmode") ? "Peak" : "Dec";
60  for(int i=0; i<nTypes; ++i) {
61  auto dc = conf.getParameter<std::vector<double> >("CouplingConstant"+mode+typeArray[i]);
62  signalCoupling.emplace_back(dc.begin(),dc.end());
63  }
64  return signalCoupling;
65  }
66 
67  inline unsigned int indexOf(const std::string& t) { return std::find( type, type + Ntypes, t) - type;}
68 
69 
70  inline unsigned int typeOf(const StripGeomDetUnit& det, const TrackerTopology *tTopo) {
71  DetId id = det.geographicalId();
72  switch (det.specificType().subDetector()) {
73  case GeomDetEnumerators::TIB: {return (tTopo->tibLayer(id) < 3) ? indexOfIB1 : indexOfIB2;}
74  case GeomDetEnumerators::TOB: {return (tTopo->tobLayer(id) > 4) ? indexOfOB1 : indexOfOB2;}
75  case GeomDetEnumerators::TID: {return indexOfW1a -1 + tTopo->tidRing(id);} //fragile: relies on ordering of 'type'
76  case GeomDetEnumerators::TEC: {return indexOfW1b -1 + tTopo->tecRing(id);} //fragile: relies on ordering of 'type'
77  default: throw cms::Exception("Invalid subdetector") << id();
78  }
79  }
80 
81  inline double
82  chargeDeposited(size_t strip, size_t Nstrips, double amplitude, double chargeSpread, double chargePosition) {
83  double integralUpToStrip = (strip == 0) ? 0. : ( approx_erf( (strip-chargePosition)/chargeSpread/1.41421356237309515 ) );
84  double integralUpToNext = (strip+1 == Nstrips) ? 1. : ( approx_erf( (strip+1-chargePosition)/chargeSpread/1.41421356237309515 ) );
85 
86  return 0.5 * (integralUpToNext - integralUpToStrip) * amplitude;
87  }
88 
89 }
90 
91 
94  : signalCoupling(fillSignalCoupling(conf, Ntypes, type)), Nsigma(3.), geVperElectron(g) {
95 }
96 
97 void
100  const StripGeomDetUnit& det,
101  std::vector<float>& localAmplitudes,
102  size_t& recordMinAffectedStrip,
103  size_t& recordMaxAffectedStrip,
104  const TrackerTopology *tTopo) const {
105 
106 
107  induceVector(collection_points, det, localAmplitudes, recordMinAffectedStrip, recordMaxAffectedStrip, tTopo);
108 
109  /*
110  auto ominA=recordMinAffectedStrip, omaxA=recordMaxAffectedStrip;
111  std::vector<float> oampl(localAmplitudes);
112  induceOriginal(collection_points, det, oampl, ominA, omaxA, tTopo);
113 
114  // std::cout << "orig " << ominA << " " << omaxA << " ";
115  //for (auto a : oampl) std::cout << a << ",";
116  //std::cout << std::endl;
117 
118  auto minA=recordMinAffectedStrip, maxA=recordMaxAffectedStrip;
119  std::vector<float> ampl(localAmplitudes);
120  induceVector(collection_points, det, ampl, minA, maxA, tTopo);
121 
122  // std::cout << "vect " << minA << " " << maxA << " ";
123  //for (auto a : ampl) std::cout << a << ",";
124  //std::cout << std::endl;
125 
126  float diff=0;
127  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);}
128  if (diff> 1.e-4) {
129  std::cout << diff << std::endl;
130  std::cout << "orig " << ominA << " " << omaxA << " ";
131 // for (auto a : oampl) std::cout << a << ",";
132  std::cout << std::endl;
133  std::cout << "vect " << minA << " " << maxA << " ";
134 // for (auto a : ampl) std::cout << a << ",";
135  std::cout << std::endl;
136  }
137 
138  localAmplitudes.swap(ampl);
139  recordMinAffectedStrip=minA;
140  recordMaxAffectedStrip=maxA;
141  */
142 
143 }
144 
145 void
148  const StripGeomDetUnit& det,
149  std::vector<float>& localAmplitudes,
150  size_t& recordMinAffectedStrip,
151  size_t& recordMaxAffectedStrip,
152  const TrackerTopology *tTopo) const {
153 
154 
155  auto const & coupling = signalCoupling[typeOf(det,tTopo)];
156  const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
157  const int Nstrips = topology.nstrips();
158 
159  if (Nstrips == 0) return;
160 
161  const int NP = collection_points.size();
162  if(0==NP) return;
163 
164  constexpr int MaxN = 512;
165  // if NP too large split...
166 
167  for (int ip=0; ip<NP; ip+=MaxN) {
168  auto N = std::min(NP-ip,MaxN);
169 
170  count.dep(N);
171  float amplitude[N];
172  float chargePosition[N];
173  float chargeSpread[N];
174  int fromStrip[N];
175  int nStrip[N];
176 
177  // load not vectorize
178  //In strip coordinates:
179  for (int i=0; i!=N;++i) {
180  auto j = ip+i;
181  if (0==collection_points[j].amplitude()) count.zero();
182  chargePosition[i]=topology.strip(collection_points[j].position());
183  chargeSpread[i]= collection_points[j].sigma() / topology.localPitch(collection_points[j].position());
184  amplitude[i]=0.5f*collection_points[j].amplitude() / geVperElectron;
185  }
186 
187  // this vectorize
188  for (int i=0; i!=N;++i) {
189  fromStrip[i] = std::max( 0, int(std::floor( chargePosition[i] - Nsigma*chargeSpread[i])) );
190  nStrip[i] = std::min( Nstrips, int(std::ceil( chargePosition[i] + Nsigma*chargeSpread[i])) ) - fromStrip[i];
191  }
192  int tot=0;
193  for (int i=0; i!=N;++i) tot += nStrip[i];
194  tot+=N; // add last strip
195  count.val(tot);
196  float value[tot];
197 
198  // assign relative position (lower bound of strip) in value;
199  int kk=0;
200  for (int i=0; i!=N;++i) {
201  auto delta = 1.f/(std::sqrt(2.f)*chargeSpread[i]);
202  auto pos = delta*(float(fromStrip[i])-chargePosition[i]);
203 
204  // VI: before value[0] was not defined and value[tot] was filled
205  // to fix this the loop below was changed
206  for (int j=0;j<=nStrip[i]; ++j) {
207  value[kk] = pos+float(j)*delta;
208  ++kk;
209  }
210  }
211  assert(kk==tot);
212 
213  // main loop fully vectorized
214  for (int k=0;k!=tot; ++k)
215  value[k] = approx_erf(value[k]);
216 
217  // saturate 0 & NStrips strip to 0 and 1???
218  kk=0;
219  for (int i=0; i!=N;++i) {
220  if (0 == fromStrip[i]) value[kk]=0;
221  kk+=nStrip[i];
222  if (Nstrips == fromStrip[i]+nStrip[i]) value[kk]=1.f;
223  ++kk;
224  }
225  assert(kk==tot);
226 
227  // compute integral over strip (lower bound becomes the value)
228  for (int k=0;k!=tot-1; ++k)
229  value[k]-=value[k+1]; // this is negative!
230 
231 
232  float charge[Nstrips]; for (int i=0;i!=Nstrips; ++i) charge[i]=0;
233  kk=0;
234  for (int i=0; i!=N;++i){
235  for (int j=0;j!=nStrip[i]; ++j)
236  charge[fromStrip[i]+j]-= amplitude[i]*value[kk++];
237  ++kk; // skip last "strip"
238  }
239  assert(kk==tot);
240 
241 
243  int minA=recordMinAffectedStrip, maxA=recordMaxAffectedStrip;
244  int sc = coupling.size();
245  for (int i=0;i!=Nstrips; ++i) {
246  int strip = i;
247  if (0==charge[i]) continue;
248  auto affectedFromStrip = std::max( 0, strip - sc + 1);
249  auto affectedUntilStrip = std::min(Nstrips, strip + sc);
250  for (auto affectedStrip=affectedFromStrip; affectedStrip < affectedUntilStrip; ++affectedStrip)
251  localAmplitudes[affectedStrip] += charge[i] * coupling[std::abs(affectedStrip - strip)] ;
252 
253  if( affectedFromStrip < minA ) minA = affectedFromStrip;
254  if( affectedUntilStrip > maxA ) maxA = affectedUntilStrip;
255  }
256  recordMinAffectedStrip=minA;
257  recordMaxAffectedStrip=maxA;
258  } // end loop ip
259 
260 }
261 
262 void
265  const StripGeomDetUnit& det,
266  std::vector<float>& localAmplitudes,
267  size_t& recordMinAffectedStrip,
268  size_t& recordMaxAffectedStrip,
269  const TrackerTopology *tTopo) const {
270 
271 
272  auto const & coupling = signalCoupling[typeOf(det,tTopo)];
273  const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
274  size_t Nstrips = topology.nstrips();
275 
276  if (!collection_points.empty()) count.dep(collection_points.size());
277 
278  for (auto signalpoint = collection_points.begin(); signalpoint != collection_points.end(); signalpoint++ ) {
279 
280  //In strip coordinates:
281  double chargePosition = topology.strip(signalpoint->position());
282  double chargeSpread = signalpoint->sigma() / topology.localPitch(signalpoint->position());
283 
284  size_t fromStrip = size_t(std::max( 0, int(std::floor( chargePosition - Nsigma*chargeSpread))));
285  size_t untilStrip = size_t(std::min( Nstrips, size_t(std::ceil( chargePosition + Nsigma*chargeSpread) )));
286 
287  count.str(std::max(0,int(untilStrip)-int(fromStrip)));
288  for (size_t strip = fromStrip; strip < untilStrip; strip++) {
289 
290  double chargeDepositedOnStrip = chargeDeposited( strip, Nstrips, signalpoint->amplitude() / geVperElectron, chargeSpread, chargePosition);
291 
292  size_t affectedFromStrip = size_t(std::max( 0, int(strip - coupling.size() + 1)));
293  size_t affectedUntilStrip = size_t(std::min( Nstrips, strip + coupling.size()) );
294  for (size_t affectedStrip = affectedFromStrip; affectedStrip < affectedUntilStrip; affectedStrip++) {
295  localAmplitudes.at( affectedStrip ) += chargeDepositedOnStrip * coupling.at((size_t)std::abs( (int)affectedStrip - (int)strip )) ;
296  }
297 
298  if( affectedFromStrip < recordMinAffectedStrip ) recordMinAffectedStrip = affectedFromStrip;
299  if( affectedUntilStrip > recordMaxAffectedStrip ) recordMaxAffectedStrip = affectedUntilStrip;
300  }
301  }
302 
303 }
304 
dbl * delta
Definition: mlp_gen.cc:36
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
unsigned int tibLayer(const DetId &id) const
unsigned int tidRing(const DetId &id) const
CaloTopology const * topology(0)
unsigned int tecRing(const DetId &id) const
ring id
virtual float strip(const LocalPoint &) const =0
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:20
virtual const StripTopology & specificTopology() const
Returns a reference to the strip proxy topology.
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:570
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
#define constexpr
float approx_erf(float x)
Definition: approx_erf.h:6
virtual StripGeomDetType const & specificType() const
T sqrt(T t)
Definition: SSEVec.h:18
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
DetId geographicalId() const
The label of this GeomDet.
Definition: GeomDet.h:79
double f[11][100]
Definition: value.py:1
T min(T a, T b)
Definition: MathUtil.h:58
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
int k[5][pyjets_maxn]
Definition: DetId.h:18
#define N
Definition: blowfish.cc:9
virtual int nstrips() const =0
virtual float localPitch(const LocalPoint &) const =0
static int position[264][3]
Definition: ReadPGInfo.cc:509
SiTrivialInduceChargeOnStrips(const edm::ParameterSet &conf, double g)
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
SubDetector subDetector() const
Definition: GeomDetType.h:22
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