CMS 3D CMS Logo

CSCXonStrip_MatchGatti.cc
Go to the documentation of this file.
1 // This is CSCXonStrip_MatchGatti.cc
2 
3 //---- Large part is copied from RecHitB
4 //---- author: Stoyan Stoynev - NU
5 
8 
11 
18 
21 
23 
24 #include <vector>
25 #include <cmath>
26 #include <iostream>
27 #include <fstream>
28 //#include <iomanip.h>
29 //#include <iomanip>
30 
31 #ifndef M_PI_2
32 #define M_PI_2 1.57079632679489661923
33 #endif
34 
36  useCalib = ps.getParameter<bool>("CSCUseCalibrations");
37  xtalksOffset = ps.getParameter<double>("CSCStripxtalksOffset");
38  noise_level_ME1a = ps.getParameter<double>("NoiseLevel_ME1a");
39  xt_asymmetry_ME1a = ps.getParameter<double>("XTasymmetry_ME1a");
40  const_syst_ME1a = ps.getParameter<double>("ConstSyst_ME1a");
41  noise_level_ME1b = ps.getParameter<double>("NoiseLevel_ME1b");
42  xt_asymmetry_ME1b = ps.getParameter<double>("XTasymmetry_ME1b");
43  const_syst_ME1b = ps.getParameter<double>("ConstSyst_ME1b");
44  noise_level_ME12 = ps.getParameter<double>("NoiseLevel_ME12");
45  xt_asymmetry_ME12 = ps.getParameter<double>("XTasymmetry_ME12");
46  const_syst_ME12 = ps.getParameter<double>("ConstSyst_ME12");
47  noise_level_ME13 = ps.getParameter<double>("NoiseLevel_ME13");
48  xt_asymmetry_ME13 = ps.getParameter<double>("XTasymmetry_ME13");
49  const_syst_ME13 = ps.getParameter<double>("ConstSyst_ME13");
50  noise_level_ME21 = ps.getParameter<double>("NoiseLevel_ME21");
51  xt_asymmetry_ME21 = ps.getParameter<double>("XTasymmetry_ME21");
52  const_syst_ME21 = ps.getParameter<double>("ConstSyst_ME21");
53  noise_level_ME22 = ps.getParameter<double>("NoiseLevel_ME22");
54  xt_asymmetry_ME22 = ps.getParameter<double>("XTasymmetry_ME22");
55  const_syst_ME22 = ps.getParameter<double>("ConstSyst_ME22");
56  noise_level_ME31 = ps.getParameter<double>("NoiseLevel_ME31");
57  xt_asymmetry_ME31 = ps.getParameter<double>("XTasymmetry_ME31");
58  const_syst_ME31 = ps.getParameter<double>("ConstSyst_ME31");
59  noise_level_ME32 = ps.getParameter<double>("NoiseLevel_ME32");
60  xt_asymmetry_ME32 = ps.getParameter<double>("XTasymmetry_ME32");
61  const_syst_ME32 = ps.getParameter<double>("ConstSyst_ME32");
62  noise_level_ME41 = ps.getParameter<double>("NoiseLevel_ME41");
63  xt_asymmetry_ME41 = ps.getParameter<double>("XTasymmetry_ME41");
64  const_syst_ME41 = ps.getParameter<double>("ConstSyst_ME41");
65 
66  getCorrectionValues("StringCurrentlyNotUsed");
67 }
68 
70 
71 /* findPosition
72  *
73  */
75  const CSCLayer* layer,
76  const CSCStripHit& stripHit,
77  int centralStrip,
78  float& xWithinChamber,
79  float& sWidth,
80  const float& tpeak,
81  float& xWithinStrip,
82  float& sigma,
83  int& quality_flag) {
84  quality_flag = 0;
85  // Initialize Gatti parameters using chamberSpecs
86  // Cache specs_ info for ease of access
87  specs_ = layer->chamber()->specs();
88  stripWidth = sWidth;
89  //initChamberSpecs();
90  // Initialize output parameters
91  xWithinStrip = xWithinChamber;
92 
93  CSCStripHit::ChannelContainer const& strips = stripHit.strips();
94  int nStrips = strips.size();
95  int centStrip = nStrips / 2 + 1;
96  std::vector<float> const& adcs = stripHit.s_adc();
97  int tmax = stripHit.tmax();
98 
100  //float t_peak = tpeak;
101  //float t_zero = 0.;
102  //float adc[4];
103  //
104  //if ( useCalib ) {
105  //
106  // for ( int t = 0; t < 4; ++t ) {
107  // int k = t + 4 * (centStrip-1);
108  // adc[t] = adcs[k];
109  // }
110  //
111  // // t_peak from peak finder is now 'absolute' i.e. in ns from start of sca time bin 0
112  // t_peak = peakTimeFinder_->peakTime( tmax, adc, t_peak );
113  // // Just for completeness, the start time of the pulse is 133 ns earlier, according to Stan :)
114  // t_zero = t_peak - 133.;
115  // // and reset tpeak since that's the way it gets passed out of this function (Argh!)
116  // tpeak = t_peak;
117  // LogTrace("CSCRecHit|CSCXonStrip_MatchGatti") << "CSCXonStrip_MatchGatti: " <<
118  // id << " strip=" << centralStrip << ", t_zero=" << t_zero << ", t_peak=" << t_peak;
119  //}
120 
121  //---- fill the charge matrix (3x3)
122  float adc[4];
123  int j = 0;
124  for (int i = 1; i <= nStrips; ++i) {
125  if (i > (centStrip - 2) && i < (centStrip + 2)) {
126  std::vector<float> adcsFit;
127  for (int t = 0; t < 4; ++t) {
128  int k = t + 4 * (i - 1);
129  adc[t] = adcs[k];
130  if (t < 3)
131  chargeSignal[j][t] = adc[t];
132  }
133  j++;
134  }
135  }
136 
137  // Load in x-talks:
138 
139  if (useCalib) {
140  std::vector<float> xtalks;
141  recoConditions_->crossTalk(id, centralStrip, xtalks);
142  float dt = 50.f * tmax - tpeak;
143  // XTalks; l,r are for left, right XTalk; lr0,1,2 are for what charge "remains" in the strip
144  for (int t = 0; t < 3; ++t) {
145  xt_l[0][t] = xtalks[0] * (50.f * (t - 1) + dt) + xtalks[1] + xtalksOffset;
146  xt_r[0][t] = xtalks[2] * (50.f * (t - 1) + dt) + xtalks[3] + xtalksOffset;
147  xt_l[1][t] = xtalks[4] * (50.f * (t - 1) + dt) + xtalks[5] + xtalksOffset;
148  xt_r[1][t] = xtalks[6] * (50.f * (t - 1) + dt) + xtalks[7] + xtalksOffset;
149  xt_l[2][t] = xtalks[8] * (50.f * (t - 1) + dt) + xtalks[9] + xtalksOffset;
150  xt_r[2][t] = xtalks[10] * (50.f * (t - 1) + dt) + xtalks[11] + xtalksOffset;
151 
152  xt_lr0[t] = (1. - xt_l[0][t] - xt_r[0][t]);
153  xt_lr1[t] = (1. - xt_l[1][t] - xt_r[1][t]);
154  xt_lr2[t] = (1. - xt_l[2][t] - xt_r[2][t]);
155  }
156  } else {
157  for (int t = 0; t < 3; ++t) {
158  xt_l[0][t] = xtalksOffset;
159  xt_r[0][t] = xtalksOffset;
160  xt_l[1][t] = xtalksOffset;
161  xt_r[1][t] = xtalksOffset;
162  xt_l[2][t] = xtalksOffset;
163  xt_r[2][t] = xtalksOffset;
164 
165  xt_lr0[t] = (1. - xt_l[0][t] - xt_r[0][t]);
166  xt_lr1[t] = (1. - xt_l[1][t] - xt_r[1][t]);
167  xt_lr2[t] = (1. - xt_l[2][t] - xt_r[2][t]);
168  }
169  }
170 
171  // vector containing noise starts at tmax - 1, and tmax > 3, but....
172  int tbin = tmax - 4;
173 
174  // .... originally, suppose to have tmax in tbin 4 or 5, but noticed in MTCC lots of
175  // hits with tmax == 3, so let's allow these, and shift down noise matrix by one element...
176  // This is a patch because the calibration database doesn't have elements for tbin = 2,
177  // e.g. there is no element e[tmax-1,tmax+1] = e[2,4].
178 
179  if (tmax < 4)
180  tbin = 0; // patch
181 
182  // Load in auto-correlation noise matrices
183  if (useCalib) {
184  std::vector<float> nmatrix;
185  recoConditions_->noiseMatrix(id, centralStrip, nmatrix);
186  for (int istrip = 0; istrip < 3; ++istrip) {
187  a11[istrip] = nmatrix[0 + tbin * 3 + istrip * 15];
188  a12[istrip] = nmatrix[1 + tbin * 3 + istrip * 15];
189  a13[istrip] = nmatrix[2 + tbin * 3 + istrip * 15];
190  a22[istrip] = nmatrix[3 + tbin * 3 + istrip * 15];
191  a23[istrip] = nmatrix[4 + tbin * 3 + istrip * 15];
192  a33[istrip] = nmatrix[6 + tbin * 3 + istrip * 15];
193  }
194  } else {
195  // FIXME: NO HARD WIRED VALUES !!!
196  for (int istrip = 0; istrip < 3; ++istrip) {
197  a11[istrip] = 10.0;
198  a12[istrip] = 0.0;
199  a13[istrip] = 0.0;
200  a22[istrip] = 10.0;
201  a23[istrip] = 0.0;
202  a33[istrip] = 10.0;
203  }
204  }
205 
206  //---- Set up noise, XTalk matrices
207  setupMatrix();
208  //---- Calculate the coordinate within the strip and associate uncertainty
209 
210  static const std::string ME1a("ME1/a");
211  static const std::string ME1b("ME1/b");
212 
213  bool ME1_1 = (ME1a == specs_->chamberTypeName() || ME1b == specs_->chamberTypeName());
214 
215  // due to cross talks and 3 time bin sum it is in principe possible that the center strip is not the maximum strip
216  // in some cases the consequences could be quite extreme
217  // take some measures against the extreme cases
218  bool peakMismatch = false;
219  std::vector<float> charges(3);
220  charges[0] = q_sumL;
221  charges[1] = q_sumC;
222  charges[2] = q_sumR;
223  int min_index = min_element(charges.begin(), charges.end()) - charges.begin();
224  int max_index = max_element(charges.begin(), charges.end()) - charges.begin();
225  if (1 != max_index && (1 == min_index ||
226  // the condition below means that if the initial position estimate within strip (|xF|)
227  // is above 1.1/2 = 0.55 "strip widths" peakMismatch is set to true (so special case);
228  // in normal cases |xF|<=0.5 (0.5 is at the edge of the "central" strip)
229  (charges[max_index] - charges[min_index]) > 1.1 * (q_sumC - charges[min_index]))) {
230  peakMismatch = true;
231  switch (max_index) {
232  case 0:
233  xWithinStrip = -1;
234  break;
235  case 2:
236  xWithinStrip = 1;
237  break;
238  default:
239  // should be an error message here
240  xWithinStrip = 0; // in case?
241  break;
242  }
243  }
244  // we don't have the needed information (it's similar to the "edge" strip case)
245  //else if(stripHit.isNearDeadStrip()){
246  else if (stripHit.deadStrip() > 0) {
247  xWithinStrip = 0;
248  } else {
249  //
250  xWithinStrip = float(calculateXonStripPosition(stripWidth, ME1_1));
251  }
252  xWithinChamber = xWithinChamber + (xWithinStrip * stripWidth);
253  if (peakMismatch) {
254  sigma = stripWidth / std::sqrt(12.f);
255  } else {
256  //---- error estimation
257  int factorStripWidth = int(std::sqrt(stripWidth / 0.38f));
258  int maxConsecutiveStrips = 8;
259  if (factorStripWidth) {
260  maxConsecutiveStrips /= factorStripWidth;
261  }
262  maxConsecutiveStrips++;
263 
264  struct ChamberTypes {
265  std::map<std::string, int> chamberTypes;
266  int operator()(std::string const& s) const {
267  auto p = chamberTypes.find(s);
268  return p != chamberTypes.end() ? (*p).second : 0;
269  }
270  ChamberTypes() {
271  chamberTypes["ME1/a"] = 1;
272  chamberTypes["ME1/b"] = 2;
273  chamberTypes["ME1/2"] = 3;
274  chamberTypes["ME1/3"] = 4;
275  chamberTypes["ME2/1"] = 5;
276  chamberTypes["ME2/2"] = 6;
277  chamberTypes["ME3/1"] = 7;
278  chamberTypes["ME3/2"] = 8;
279  chamberTypes["ME4/1"] = 9;
280  chamberTypes["ME4/2"] = 8;
281  }
282  };
283  static const ChamberTypes chamberTypes;
284 
285  switch (chamberTypes(specs_->chamberTypeName())) {
286  case 1:
290  break;
291 
292  case 2:
296  break;
297 
298  case 3:
302  break;
303 
304  case 4:
308  break;
309 
310  case 5:
314  break;
315 
316  case 6:
320  break;
321 
322  case 7:
326  break;
327 
328  case 8:
332  break;
333 
334  case 9:
338  break;
339 
340  default:
344  }
345  if (0 == stripHit.deadStrip() && stripHit.numberOfConsecutiveStrips() < maxConsecutiveStrips &&
346  std::abs(stripHit.closestMaximum()) > maxConsecutiveStrips / 2) {
347  sigma = float(calculateXonStripError(stripWidth, ME1_1));
348  } else { //---- near dead strip or too close maxima or too wide strip cluster
349  sigma = stripWidth / std::sqrt(12.f);
350  }
351  }
352  quality_flag = 1;
353 }
354 
355 /* setupMatrix
356  *
357  */
359  //---- a??? and v??[] could be skipped for now...; not used yet
360 
361  /*
362  double dd, a11t, a12t, a13t, a22t, a23t, a33t;
363  double syserr = adcSystematics;
364  double xtlk_err = xtalksSystematics;
365  // Left strip
366  a11t = a11[0] + syserr*syserr * ChargeSignal[0][0]*ChargeSignal[0][0] + xtlk_err*xtlk_err*ChargeSignal[1][0]*ChargeSignal[1][0];
367  a12t = a12[0] + syserr*syserr * ChargeSignal[0][0]*ChargeSignal[0][1];
368  a13t = a13[0] + syserr*syserr * ChargeSignal[0][0]*ChargeSignal[0][2];
369  a22t = a22[0] + syserr*syserr * ChargeSignal[0][1]*ChargeSignal[0][1] + xtlk_err*xtlk_err*ChargeSignal[1][1]*ChargeSignal[1][1];
370  a23t = a23[0] + syserr*syserr * ChargeSignal[0][1]*ChargeSignal[0][2];
371  a33t = a33[0] + syserr*syserr * ChargeSignal[0][2]*ChargeSignal[0][2] + xtlk_err*xtlk_err*ChargeSignal[1][2]*ChargeSignal[1][2];
372 
373  dd = (a11t*a33t*a22t - a11t*a23t*a23t - a33t*a12t*a12t
374  + 2.* a12t*a13t*a23t - a13t*a13t*a22t );
375 
376  v11[0] = (a33t*a22t - a23t*a23t)/dd;
377  v12[0] =-(a33t*a12t - a13t*a23t)/dd;
378  v13[0] = (a12t*a23t - a13t*a22t)/dd;
379  v22[0] = (a33t*a11t - a13t*a13t)/dd;
380  v23[0] =-(a23t*a11t - a12t*a13t)/dd;
381  v33[0] = (a22t*a11t - a12t*a12t)/dd;
382 
383  // Center strip
384  a11t = a11[1] + syserr*syserr * ChargeSignal[1][0]*ChargeSignal[1][0] + xtlk_err*xtlk_err*(ChargeSignal[0][0]*ChargeSignal[0][0]+ChargeSignal[2][0]*ChargeSignal[2][0]);
385  a12t = a12[1] + syserr*syserr * ChargeSignal[1][0]*ChargeSignal[1][1];
386  a13t = a13[1] + syserr*syserr * ChargeSignal[1][0]*ChargeSignal[1][2];
387  a22t = a22[1] + syserr*syserr * ChargeSignal[1][1]*ChargeSignal[1][1] + xtlk_err*xtlk_err*(ChargeSignal[0][1]*ChargeSignal[0][1]+ChargeSignal[2][1]*ChargeSignal[2][1]);
388  a23t = a23[1] + syserr*syserr * ChargeSignal[1][1]*ChargeSignal[1][2];
389  a33t = a33[1] + syserr*syserr * ChargeSignal[1][2]*ChargeSignal[1][2] + xtlk_err*xtlk_err*(ChargeSignal[0][2]*ChargeSignal[0][2]+ChargeSignal[2][2]*ChargeSignal[2][2]);
390 
391  dd = (a11t*a33t*a22t - a11t*a23t*a23t - a33t*a12t*a12t
392  + 2.* a12t*a13t*a23t - a13t*a13t*a22t );
393 
394  v11[1] = (a33t*a22t - a23t*a23t)/dd;
395  v12[1] =-(a33t*a12t - a13t*a23t)/dd;
396  v13[1] = (a12t*a23t - a13t*a22t)/dd;
397  v22[1] = (a33t*a11t - a13t*a13t)/dd;
398  v23[1] =-(a23t*a11t - a12t*a13t)/dd;
399  v33[1] = (a22t*a11t - a12t*a12t)/dd;
400 
401  // Right strip
402  a11t = a11[2] + syserr*syserr * ChargeSignal[2][0]*ChargeSignal[2][0] + xtlk_err*xtlk_err*ChargeSignal[1][0]*ChargeSignal[1][0];
403  a12t = a12[2] + syserr*syserr * ChargeSignal[2][0]*ChargeSignal[2][1];
404  a13t = a13[2] + syserr*syserr * ChargeSignal[2][0]*ChargeSignal[2][2];
405  a22t = a22[2] + syserr*syserr * ChargeSignal[2][1]*ChargeSignal[2][1] + xtlk_err*xtlk_err*ChargeSignal[1][1]*ChargeSignal[1][1];
406  a23t = a23[2] + syserr*syserr * ChargeSignal[2][1]*ChargeSignal[2][2];
407  a33t = a33[2] + syserr*syserr * ChargeSignal[2][2]*ChargeSignal[2][2] + xtlk_err*xtlk_err*ChargeSignal[1][2]*ChargeSignal[1][2];
408 
409  dd = (a11t*a33t*a22t - a11t*a23t*a23t - a33t*a12t*a12t
410  +2.* a12t*a13t*a23t - a13t*a13t*a22t );
411 
412  v11[2] = (a33t*a22t - a23t*a23t)/dd;
413  v12[2] =-(a33t*a12t - a13t*a23t)/dd;
414  v13[2] = (a12t*a23t - a13t*a22t)/dd;
415  v22[2] = (a33t*a11t - a13t*a13t)/dd;
416  v23[2] =-(a23t*a11t - a12t*a13t)/dd;
417  v33[2] = (a22t*a11t - a12t*a12t)/dd;
418 */
419  //---- Find the inverted XTalk matrix and apply it to the charge (3x3)
420  //---- Thus the charge before the XTalk is obtained
421  CLHEP::HepMatrix cross_talks_inv(3, 3);
422  int err = 0;
423  //---- q_sum is 3 time bins summed; L, C, R - left, central, right strips
424  q_sum = q_sumL = q_sumC = q_sumR = 0.;
425  double charge = 0.;
426  for (int iTime = 0; iTime < 3; iTime++) {
427  cross_talks_inv(1, 1) = xt_lr0[iTime];
428  cross_talks_inv(1, 2) = xt_l[1][iTime];
429  cross_talks_inv(1, 3) = 0.;
430  cross_talks_inv(2, 1) = xt_r[0][iTime];
431  cross_talks_inv(2, 2) = xt_lr1[iTime];
432  cross_talks_inv(2, 3) = xt_l[2][iTime];
433  cross_talks_inv(3, 1) = 0.;
434  cross_talks_inv(3, 2) = xt_r[1][iTime];
435  cross_talks_inv(3, 3) = xt_lr2[iTime];
436  cross_talks_inv.invert(err);
437  if (err != 0) {
438  edm::LogWarning("FailedXTalkiInversionNoCrosstalkCorrection")
439  << "Failed to invert XTalks matrix. No cross-talk correction for this rechit.";
440  //edm::LogError("CSCRecHit") << "Failed to invert XTalks matrix. No cross-talk correction for this rechit.";
441  return;
442  }
443  //---- "charge" is XT-corrected charge
444  charge = chargeSignal[0][iTime] * cross_talks_inv(1, 1) + chargeSignal[1][iTime] * cross_talks_inv(1, 2) +
445  chargeSignal[2][iTime] * cross_talks_inv(1, 3);
446  //---- Negative charge? According to studies (and logic) - better use 0 charge
447  //----- Later studies suggest that this only do harm. I am still worried about
448  // charges of -50 ADC and below (0.5% of the cases) but let see
449  //if(charge<0.){
450  //charge = 0.;
451  //}
452  q_sum += charge;
453  q_sumL += charge;
454  charge = chargeSignal[0][iTime] * cross_talks_inv(2, 1) + chargeSignal[1][iTime] * cross_talks_inv(2, 2) +
455  chargeSignal[2][iTime] * cross_talks_inv(2, 3);
456  //if(charge<0.){
457  //charge = 0.;
458  //}
459  q_sum += charge;
460  q_sumC += charge;
461  charge = chargeSignal[0][iTime] * cross_talks_inv(3, 1) + chargeSignal[1][iTime] * cross_talks_inv(3, 2) +
462  chargeSignal[2][iTime] * cross_talks_inv(3, 3);
463  //if(charge<0.){
464  //charge = 0.;
465  //}
466  q_sum += charge;
467  q_sumR += charge;
468  }
469 }
470 
471 /* initChamberSpecs
472  *
473  */
475  // Not used directly but these are parameters used for extracting the correction values
476  // in coordinate and error estimators
477 
478  // Distance between anode and cathode
480  r = h / stripWidth;
481 
482  // Wire spacing
483  double wspace = specs_->wireSpacing();
484 
485  // Wire radius
486  double wradius = specs_->wireRadius();
487 
488  // Accepted parameters in Gatti function
489  const double parm[5] = {.1989337e-02, -.6901542e-04, .8665786, 154.6177, -.680163e-03};
490 
491  k_3 = (parm[0] * wspace / h + parm[1]) *
492  (parm[2] * wspace / wradius + parm[3] + parm[4] * (wspace / wradius) * (wspace / wradius));
493 
495  norm = r * (0.5 / std::atan(sqrt_k_3)); // changed from norm to r * norm
496  k_2 = M_PI_2 * (1. - sqrt_k_3 / 2.);
497  k_1 = 0.25 * k_2 * sqrt_k_3 / std::atan(sqrt_k_3);
498 }
499 
501 
502 double CSCXonStrip_MatchGatti::estimated2GattiCorrection(double x_estimated, float stripWidth, bool ME1_1) {
503  //---- 11 "nominal" strip widths : 0.6 - 1.6 cm; for ME1_1 just 6 "nominal" strip widths : 0.3 - 0.8 cm; see HardCodedCorrectionInitialization()
504  //---- Calculate corrections at specific Xestimated (linear interpolation between points)
505  int n_SW;
506  int min_SW;
507  if (ME1_1) {
508  n_SW = n_SW_ME1_1;
509  min_SW = 3; // min SW calculated is 0.3 cm
510  } else {
511  n_SW = n_SW_noME1_1;
512  min_SW = 6; // min SW calculated is 0.6 cm
513  }
514  int stripDown = int(10. * stripWidth) - min_SW; // 0 is at min strip width calculated
515  int stripUp = stripDown + 1;
516  if (stripUp > n_SW - 1) {
517  //---- to be checked...
518  //if(stripUp>n_SW){
519  //std::cout<<" Is strip width = "<<stripWidth<<" OK?" <<std::endl;
520  //}
521  stripUp = n_SW - 1;
522  }
523 
524  double half_strip_width = 0.5;
525  //const int Nbins = 501;
526  const int n_bins = n_val;
527  double corr_2_xestim = 999.;
528  if (stripDown < 0) {
529  corr_2_xestim = 1;
530  } else {
531  //---- Parametrized x_gatti minus x_estimated differences
532 
533  int xestim_bin = -999;
534  double delta_strip_width = 999.;
535  double delta_strip_widthUpDown = 999.;
536  double diff_2_strip_width = 999.;
537  delta_strip_width = stripWidth - int(stripWidth * 10) / 10.;
538  delta_strip_widthUpDown = 0.1;
539 
540  if (std::abs(x_estimated) > 0.5) {
541  if (std::abs(x_estimated) > 1.) {
542  corr_2_xestim = 1.; // for now; to be investigated
543  } else {
544  //if(std::abs(Xestimated)>0.55){
545  //std::cout<<"X position from the estimated position above 0.55 (safty margin)?! "<<std::endl;
546  //CorrToXc = 999.;
547  //}
548  xestim_bin = int((1. - std::abs(x_estimated)) / half_strip_width * n_bins);
549  if (ME1_1) {
550  diff_2_strip_width = x_correction_ME1_1[stripUp][xestim_bin] - x_correction_ME1_1[stripDown][xestim_bin];
551  corr_2_xestim = x_correction_ME1_1[stripDown][xestim_bin] +
552  (delta_strip_width / delta_strip_widthUpDown) * diff_2_strip_width;
553  } else {
554  diff_2_strip_width = x_correction_noME1_1[stripUp][xestim_bin] - x_correction_noME1_1[stripDown][xestim_bin];
555  corr_2_xestim = x_correction_noME1_1[stripDown][xestim_bin] +
556  (delta_strip_width / delta_strip_widthUpDown) * diff_2_strip_width;
557  }
558  corr_2_xestim = -corr_2_xestim;
559  }
560  } else {
561  xestim_bin = int((std::abs(x_estimated) / half_strip_width) * n_bins);
562  if (ME1_1) {
563  diff_2_strip_width = x_correction_ME1_1[stripUp][xestim_bin] - x_correction_ME1_1[stripDown][xestim_bin];
564  corr_2_xestim = x_correction_ME1_1[stripDown][xestim_bin] +
565  (delta_strip_width / delta_strip_widthUpDown) * diff_2_strip_width;
566  } else {
567  diff_2_strip_width = x_correction_noME1_1[stripUp][xestim_bin] - x_correction_noME1_1[stripDown][xestim_bin];
568  corr_2_xestim = x_correction_noME1_1[stripDown][xestim_bin] +
569  (delta_strip_width / delta_strip_widthUpDown) * diff_2_strip_width;
570  }
571  }
572  if (x_estimated < 0.) {
573  corr_2_xestim = -corr_2_xestim;
574  }
575  }
576 
577  return corr_2_xestim;
578 }
579 
580 double CSCXonStrip_MatchGatti::estimated2Gatti(double x_estimated, float stripWidth, bool ME1_1) {
581  double x_corr = estimated2GattiCorrection(x_estimated, stripWidth, ME1_1);
582  double x_gatti = x_estimated + x_corr;
583 
584  return x_gatti;
585 }
586 
588  double min, max;
589  if (q_sumR > q_sumL) {
590  min = q_sumL;
591  max = q_sumR;
592  } else {
593  min = q_sumR;
594  max = q_sumL;
595  }
596  //---- Error propagation...
597  //---- Names here are fake! Due to technical features
598  double dr_L2 = pow(q_sumR - q_sumL, 2);
599  double dr_C2 = pow(q_sumC - min, 2);
600  double dr_R2 = pow(q_sumC - max, 2);
601  double error = std::sqrt(dr_L2 + dr_C2 + dr_R2) * noise / std::pow(q_sumC - min, 2) / 2;
602 
603  return error;
604 }
605 
607  double min;
608  if (q_sumR > q_sumL) {
609  min = q_sumL;
610  } else {
611  min = q_sumR;
612  }
613  //---- Error propagation
614  double dXTL = (std::pow(q_sumC, 2) + std::pow(q_sumR, 2) - q_sumL * q_sumR - q_sumR * q_sumC);
615  double dXTR = (std::pow(q_sumC, 2) + std::pow(q_sumL, 2) - q_sumL * q_sumR - q_sumL * q_sumC);
616  double dXT = std::sqrt(std::pow(dXTL, 2) + std::pow(dXTR, 2)) / std::pow((q_sumC - min), 2) / 2;
617  double error = dXT * xt_asym;
618 
619  return error;
620 }
621 
622 double CSCXonStrip_MatchGatti::calculateXonStripError(float stripWidth, bool ME1_1) {
623  double min;
624  if (q_sumR > q_sumL) {
625  min = q_sumL;
626  } else {
627  min = q_sumR;
628  }
629 
630  double xf = (q_sumR - q_sumL) / (q_sumC - min) / 2;
631  double xf_ErrorNoise = xfError_Noise(noise_level);
632  double xf_ErrorXTasym = xfError_XTasym(xt_asymmetry);
633  // x_G = x_F + correction_functon(x_F)
634  // as these are correlated the error should be simply d(x_G) = |d(x_F)| + [correction_functon(x_F+|d(x_F)|) - correction_functon(x_F)]
635  double d_xf = std::sqrt(std::pow(xf_ErrorNoise, 2) + std::pow(xf_ErrorXTasym, 2));
636  double d_corr =
638  double x_shift = d_xf + d_corr;
639  // double x_shift = sqrt( pow( xf_ErrorNoise, 2) + pow( xf_ErrorXTasym, 2)) *
640  //(1 + (estimated2GattiCorrection(xf+0.001, stripWidth, ME1_1) -
641  // estimated2GattiCorrection(xf, stripWidth, ME1_1))*1000.);
642  double x_error = std::sqrt(std::pow(std::abs(x_shift) * stripWidth, 2) + std::pow(const_syst, 2));
643  return x_error;
644 }
645 
646 double CSCXonStrip_MatchGatti::calculateXonStripPosition(float stripWidth, bool ME1_1) {
647  double x_estimated = -99.;
648  double min;
649  if (q_sumR > q_sumL) {
650  min = q_sumL;
651  } else {
652  min = q_sumR;
653  }
654  //---- This is XF ( X Florida - after the first group that used it)
655  x_estimated = (q_sumR - q_sumL) / (q_sumC - min) / 2;
656  double x_gatti = estimated2Gatti(x_estimated, stripWidth, ME1_1);
657  return x_gatti;
658 }
659 
660 // Define space for statics
const StripHitADCContainer & s_adc() const
L1A.
Definition: CSCStripHit.h:56
float dt
Definition: AMPTWrapper.h:136
double xfError_XTasym(double XTasym)
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
float wireSpacing() const
const ChannelContainer & strips() const
L1A.
Definition: CSCStripHit.h:50
float a11[3]
Store elements of auto-correlation matrices: 0 = left, 1 = middle, 2 = right.
void noiseMatrix(const CSCDetId &id, int centralStrip, std::vector< float > &nme) const
void getCorrectionValues(std::string Estimator)
int numberOfConsecutiveStrips() const
Number of consecutive strips with charge.
Definition: CSCStripHit.h:62
float xt_l[3][3]
x-talks 0 = left, 1 = middle, 2 = right ; and then second [] is for time bin tmax-1, tmax, tmax+1
double estimated2Gatti(double Xestimated, float StripWidth, bool ME1_1)
#define M_PI_2
float anodeCathodeSpacing() const
std::string chamberTypeName() const
const CSCRecoConditions * recoConditions_
short int deadStrip() const
is a neighbouring string a dead strip?
Definition: CSCStripHit.h:68
nStrips
1.2 is to make the matching window safely the two nearest strips 0.35 is the size of an ME0 chamber i...
constexpr std::array< uint8_t, layerIndexSize< TrackerTraits > > layer
void crossTalk(const CSCDetId &id, int centralStrip, std::vector< float > &xtalks) const
T sqrt(T t)
Definition: SSEVec.h:19
double xfError_Noise(double noise)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double estimated2GattiCorrection(double Xestimated, float StripWidth, bool ME1_1)
double f[11][100]
double calculateXonStripError(float stripWidth, bool ME1_1)
const CSCChamberSpecs * specs_
double calculateXonStripPosition(float stripWidth, bool ME1_1)
static const double tmax[3]
void setupMatrix()
Set matrix for XT corrections and noise.
int closestMaximum() const
Number of strips to the closest other maximum.
Definition: CSCStripHit.h:65
float x_correction_noME1_1[n_SW_noME1_1][n_val]
std::vector< int > ChannelContainer
Definition: CSCStripHit.h:19
void findXOnStrip(const CSCDetId &id, const CSCLayer *layer, const CSCStripHit &stripHit, int centralStrip, float &xWithinChamber, float &stripWidth, const float &tpeak, float &xWithinStrip, float &sigma, int &quality_flag)
Returns fitted local x position and its estimated error.
float wireRadius() const
float x_correction_ME1_1[n_SW_ME1_1][n_val]
int tmax() const
Strip hit maximum time bin.
Definition: CSCStripHit.h:44
strips
#turn off noise in all subdetectors simHcalUnsuppressedDigis.doNoise = False mix.digitizers.hcal.doNoise = False simEcalUnsuppressedDigis.doNoise = False mix.digitizers.ecal.doNoise = False simEcalUnsuppressedDigis.doESNoise = False simSiPixelDigis.AddNoise = False mix.digitizers.pixel.AddNoise = False simSiStripDigis.Noise = False mix.digitizers.strip.AddNoise = False
Definition: DigiDM_cff.py:32
size_t max_index(const std::vector< T > &v)
charges
only generated particles of these IDs are considered
Log< level::Warning, false > LogWarning
void initChamberSpecs()
Use specs to setup Gatti parameters.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
CSCXonStrip_MatchGatti(const edm::ParameterSet &ps)
uint16_t *__restrict__ uint16_t const *__restrict__ adc