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 
62  std::string version = "";
63  if( typeArray[i].find("W") != std::string::npos && mode == "Dec" )
64  version = conf.getParameter<bool>("CouplingConstantsRunIIDecW") ? "RunII" : "";
65  else if( typeArray[i].find("B") != std::string::npos && mode == "Dec")
66  version = conf.getParameter<bool>("CouplingConstantsRunIIDecB") ? "RunII" : "";
67 
68  auto dc = conf.getParameter<std::vector<double> >("CouplingConstant"+version+mode+typeArray[i]);
69  signalCoupling.emplace_back(dc.begin(),dc.end());
70  }
71  return signalCoupling;
72  }
73 
74  inline unsigned int indexOf(const std::string& t) { return std::find( type, type + Ntypes, t) - type;}
75 
76 
77  inline unsigned int typeOf(const StripGeomDetUnit& det, const TrackerTopology *tTopo) {
78  DetId id = det.geographicalId();
79  switch (det.specificType().subDetector()) {
80  case GeomDetEnumerators::TIB: {return (tTopo->tibLayer(id) < 3) ? indexOfIB1 : indexOfIB2;}
81  case GeomDetEnumerators::TOB: {return (tTopo->tobLayer(id) > 4) ? indexOfOB1 : indexOfOB2;}
82  case GeomDetEnumerators::TID: {return indexOfW1a -1 + tTopo->tidRing(id);} //fragile: relies on ordering of 'type'
83  case GeomDetEnumerators::TEC: {return indexOfW1b -1 + tTopo->tecRing(id);} //fragile: relies on ordering of 'type'
84  default: throw cms::Exception("Invalid subdetector") << id();
85  }
86  }
87 
88  inline double
89  chargeDeposited(size_t strip, size_t Nstrips, double amplitude, double chargeSpread, double chargePosition) {
90  double integralUpToStrip = (strip == 0) ? 0. : ( approx_erf( (strip-chargePosition)/chargeSpread/1.41421356237309515 ) );
91  double integralUpToNext = (strip+1 == Nstrips) ? 1. : ( approx_erf( (strip+1-chargePosition)/chargeSpread/1.41421356237309515 ) );
92 
93  return 0.5 * (integralUpToNext - integralUpToStrip) * amplitude;
94  }
95 
96 }
97 
98 
101  : signalCoupling(fillSignalCoupling(conf, Ntypes, type)), Nsigma(3.), geVperElectron(g) {
102 }
103 
104 void
107  const StripGeomDetUnit& det,
108  std::vector<float>& localAmplitudes,
109  size_t& recordMinAffectedStrip,
110  size_t& recordMaxAffectedStrip,
111  const TrackerTopology *tTopo) const {
112 
113 
114  induceVector(collection_points, det, localAmplitudes, recordMinAffectedStrip, recordMaxAffectedStrip, tTopo);
115 
116  /*
117  auto ominA=recordMinAffectedStrip, omaxA=recordMaxAffectedStrip;
118  std::vector<float> oampl(localAmplitudes);
119  induceOriginal(collection_points, det, oampl, ominA, omaxA, tTopo);
120 
121  // std::cout << "orig " << ominA << " " << omaxA << " ";
122  //for (auto a : oampl) std::cout << a << ",";
123  //std::cout << std::endl;
124 
125  auto minA=recordMinAffectedStrip, maxA=recordMaxAffectedStrip;
126  std::vector<float> ampl(localAmplitudes);
127  induceVector(collection_points, det, ampl, minA, maxA, tTopo);
128 
129  // std::cout << "vect " << minA << " " << maxA << " ";
130  //for (auto a : ampl) std::cout << a << ",";
131  //std::cout << std::endl;
132 
133  float diff=0;
134  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);}
135  if (diff> 1.e-4) {
136  std::cout << diff << std::endl;
137  std::cout << "orig " << ominA << " " << omaxA << " ";
138 // for (auto a : oampl) std::cout << a << ",";
139  std::cout << std::endl;
140  std::cout << "vect " << minA << " " << maxA << " ";
141 // for (auto a : ampl) std::cout << a << ",";
142  std::cout << std::endl;
143  }
144 
145  localAmplitudes.swap(ampl);
146  recordMinAffectedStrip=minA;
147  recordMaxAffectedStrip=maxA;
148  */
149 
150 }
151 
152 void
155  const StripGeomDetUnit& det,
156  std::vector<float>& localAmplitudes,
157  size_t& recordMinAffectedStrip,
158  size_t& recordMaxAffectedStrip,
159  const TrackerTopology *tTopo) const {
160 
161 
162  auto const & coupling = signalCoupling[typeOf(det,tTopo)];
163  const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
164  const int Nstrips = topology.nstrips();
165 
166  if (Nstrips == 0) return;
167 
168  const int NP = collection_points.size();
169  if(0==NP) return;
170 
171  constexpr int MaxN = 512;
172  // if NP too large split...
173 
174  for (int ip=0; ip<NP; ip+=MaxN) {
175  auto N = std::min(NP-ip,MaxN);
176 
177  count.dep(N);
178  float amplitude[N];
179  float chargePosition[N];
180  float chargeSpread[N];
181  int fromStrip[N];
182  int nStrip[N];
183 
184  // load not vectorize
185  //In strip coordinates:
186  for (int i=0; i!=N;++i) {
187  auto j = ip+i;
188  if (0==collection_points[j].amplitude()) count.zero();
189  chargePosition[i]=topology.strip(collection_points[j].position());
190  chargeSpread[i]= collection_points[j].sigma() / topology.localPitch(collection_points[j].position());
191  amplitude[i]=0.5f*collection_points[j].amplitude() / geVperElectron;
192  }
193 
194  // this vectorize
195  for (int i=0; i!=N;++i) {
196  fromStrip[i] = std::max( 0, int(std::floor( chargePosition[i] - Nsigma*chargeSpread[i])) );
197  nStrip[i] = std::min( Nstrips, int(std::ceil( chargePosition[i] + Nsigma*chargeSpread[i])) ) - fromStrip[i];
198  }
199  int tot=0;
200  for (int i=0; i!=N;++i) tot += nStrip[i];
201  tot+=N; // add last strip
202  count.val(tot);
203  float value[tot];
204 
205  // assign relative position (lower bound of strip) in value;
206  int kk=0;
207  for (int i=0; i!=N;++i) {
208  auto delta = 1.f/(std::sqrt(2.f)*chargeSpread[i]);
209  auto pos = delta*(float(fromStrip[i])-chargePosition[i]);
210 
211  // VI: before value[0] was not defined and value[tot] was filled
212  // to fix this the loop below was changed
213  for (int j=0;j<=nStrip[i]; ++j) {
214  value[kk] = pos+float(j)*delta;
215  ++kk;
216  }
217  }
218  assert(kk==tot);
219 
220  // main loop fully vectorized
221  for (int k=0;k!=tot; ++k)
222  value[k] = approx_erf(value[k]);
223 
224  // saturate 0 & NStrips strip to 0 and 1???
225  kk=0;
226  for (int i=0; i!=N;++i) {
227  if (0 == fromStrip[i]) value[kk]=0;
228  kk+=nStrip[i];
229  if (Nstrips == fromStrip[i]+nStrip[i]) value[kk]=1.f;
230  ++kk;
231  }
232  assert(kk==tot);
233 
234  // compute integral over strip (lower bound becomes the value)
235  for (int k=0;k!=tot-1; ++k)
236  value[k]-=value[k+1]; // this is negative!
237 
238 
239  float charge[Nstrips]; for (int i=0;i!=Nstrips; ++i) charge[i]=0;
240  kk=0;
241  for (int i=0; i!=N;++i){
242  for (int j=0;j!=nStrip[i]; ++j)
243  charge[fromStrip[i]+j]-= amplitude[i]*value[kk++];
244  ++kk; // skip last "strip"
245  }
246  assert(kk==tot);
247 
248 
250  int minA=recordMinAffectedStrip, maxA=recordMaxAffectedStrip;
251  int sc = coupling.size();
252  for (int i=0;i!=Nstrips; ++i) {
253  int strip = i;
254  if (0==charge[i]) continue;
255  auto affectedFromStrip = std::max( 0, strip - sc + 1);
256  auto affectedUntilStrip = std::min(Nstrips, strip + sc);
257  for (auto affectedStrip=affectedFromStrip; affectedStrip < affectedUntilStrip; ++affectedStrip)
258  localAmplitudes[affectedStrip] += charge[i] * coupling[std::abs(affectedStrip - strip)] ;
259 
260  if( affectedFromStrip < minA ) minA = affectedFromStrip;
261  if( affectedUntilStrip > maxA ) maxA = affectedUntilStrip;
262  }
263  recordMinAffectedStrip=minA;
264  recordMaxAffectedStrip=maxA;
265  } // end loop ip
266 
267 }
268 
269 void
272  const StripGeomDetUnit& det,
273  std::vector<float>& localAmplitudes,
274  size_t& recordMinAffectedStrip,
275  size_t& recordMaxAffectedStrip,
276  const TrackerTopology *tTopo) const {
277 
278 
279  auto const & coupling = signalCoupling[typeOf(det,tTopo)];
280  const StripTopology& topology = dynamic_cast<const StripTopology&>(det.specificTopology());
281  size_t Nstrips = topology.nstrips();
282 
283  if (!collection_points.empty()) count.dep(collection_points.size());
284 
285  for (auto signalpoint = collection_points.begin(); signalpoint != collection_points.end(); signalpoint++ ) {
286 
287  //In strip coordinates:
288  double chargePosition = topology.strip(signalpoint->position());
289  double chargeSpread = signalpoint->sigma() / topology.localPitch(signalpoint->position());
290 
291  size_t fromStrip = size_t(std::max( 0, int(std::floor( chargePosition - Nsigma*chargeSpread))));
292  size_t untilStrip = size_t(std::min( Nstrips, size_t(std::ceil( chargePosition + Nsigma*chargeSpread) )));
293 
294  count.str(std::max(0,int(untilStrip)-int(fromStrip)));
295  for (size_t strip = fromStrip; strip < untilStrip; strip++) {
296 
297  double chargeDepositedOnStrip = chargeDeposited( strip, Nstrips, signalpoint->amplitude() / geVperElectron, chargeSpread, chargePosition);
298 
299  size_t affectedFromStrip = size_t(std::max( 0, int(strip - coupling.size() + 1)));
300  size_t affectedUntilStrip = size_t(std::min( Nstrips, strip + coupling.size()) );
301  for (size_t affectedStrip = affectedFromStrip; affectedStrip < affectedUntilStrip; affectedStrip++) {
302  localAmplitudes.at( affectedStrip ) += chargeDepositedOnStrip * coupling.at((size_t)std::abs( (int)affectedStrip - (int)strip )) ;
303  }
304 
305  if( affectedFromStrip < recordMinAffectedStrip ) recordMinAffectedStrip = affectedFromStrip;
306  if( affectedUntilStrip > recordMaxAffectedStrip ) recordMaxAffectedStrip = affectedUntilStrip;
307  }
308  }
309 
310 }
311 
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
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
constexpr float approx_erf(float x)
Definition: approx_erf.h:6
virtual float localPitch(const LocalPoint &) const =0
static int position[264][3]
Definition: ReadPGInfo.cc:509
#define str(s)
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