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