CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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_( 0 ) {
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 
95  int nStrips = strips.size();
96  int centStrip = nStrips/2 + 1;
97  std::vector<float> 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. * 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.* (t-1) + dt) + xtalks[1] + xtalksOffset;
147  xt_r[0][t] = xtalks[2] * (50.* (t-1) + dt) + xtalks[3] + xtalksOffset;
148  xt_l[1][t] = xtalks[4] * (50.* (t-1) + dt) + xtalks[5] + xtalksOffset;
149  xt_r[1][t] = xtalks[6] * (50.* (t-1) + dt) + xtalks[7] + xtalksOffset;
150  xt_l[2][t] = xtalks[8] * (50.* (t-1) + dt) + xtalks[9] + xtalksOffset;
151  xt_r[2][t] = xtalks[10]* (50.* (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  bool ME1_1 = false;
211  if("ME1/a" == specs_->chamberTypeName() || "ME1/b" == specs_->chamberTypeName()){
212  ME1_1 = true;
213  }
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  }
249  else{
250  //
251  xWithinStrip = float(calculateXonStripPosition(stripWidth, ME1_1));
252  }
253  xWithinChamber = xWithinChamber + (xWithinStrip * stripWidth);
254  if(peakMismatch){
255  sigma = stripWidth/sqrt(12);
256  }
257  else{
258 
259  //---- error estimation
260  int factorStripWidth = int( sqrt(stripWidth/0.38) );
261  int maxConsecutiveStrips = 8;
262  if(factorStripWidth){
263  maxConsecutiveStrips /= factorStripWidth ;
264  }
265  maxConsecutiveStrips++;
266 
267  std::map <std::string, int> chamberTypes;
268  chamberTypes["ME1/a"] = 1;
269  chamberTypes["ME1/b"] = 2;
270  chamberTypes["ME1/2"] = 3;
271  chamberTypes["ME1/3"] = 4;
272  chamberTypes["ME2/1"] = 5;
273  chamberTypes["ME2/2"] = 6;
274  chamberTypes["ME3/1"] = 7;
275  chamberTypes["ME3/2"] = 8;
276  chamberTypes["ME4/1"] = 9;
277  chamberTypes["ME4/2"] = 8;
278 
279  switch(chamberTypes[specs_->chamberTypeName()]){
280  case 1:
284  break;
285 
286  case 2:
290 
291  case 3:
295  break;
296 
297  case 4:
301  break;
302 
303  case 5:
307  break;
308 
309  case 6:
313  break;
314 
315  case 7:
319  break;
320 
321  case 8:
325  break;
326 
327  case 9:
331  break;
332 
333  default:
337 
338  }
339  if(0==stripHit.deadStrip() &&
340  stripHit.numberOfConsecutiveStrips()<maxConsecutiveStrips &&
341  fabs(stripHit.closestMaximum())>maxConsecutiveStrips/2 ){
342  sigma = float(calculateXonStripError(stripWidth, ME1_1));
343  }
344  else{ //---- near dead strip or too close maxima or too wide strip cluster
345  sigma = stripWidth/sqrt(12);
346  }
347  }
348  quality_flag = 1;
349 }
350 
351 /* setupMatrix
352  *
353  */
355  //---- a??? and v??[] could be skipped for now...; not used yet
356 
357  /*
358  double dd, a11t, a12t, a13t, a22t, a23t, a33t;
359  double syserr = adcSystematics;
360  double xtlk_err = xtalksSystematics;
361  // Left strip
362  a11t = a11[0] + syserr*syserr * ChargeSignal[0][0]*ChargeSignal[0][0] + xtlk_err*xtlk_err*ChargeSignal[1][0]*ChargeSignal[1][0];
363  a12t = a12[0] + syserr*syserr * ChargeSignal[0][0]*ChargeSignal[0][1];
364  a13t = a13[0] + syserr*syserr * ChargeSignal[0][0]*ChargeSignal[0][2];
365  a22t = a22[0] + syserr*syserr * ChargeSignal[0][1]*ChargeSignal[0][1] + xtlk_err*xtlk_err*ChargeSignal[1][1]*ChargeSignal[1][1];
366  a23t = a23[0] + syserr*syserr * ChargeSignal[0][1]*ChargeSignal[0][2];
367  a33t = a33[0] + syserr*syserr * ChargeSignal[0][2]*ChargeSignal[0][2] + xtlk_err*xtlk_err*ChargeSignal[1][2]*ChargeSignal[1][2];
368 
369  dd = (a11t*a33t*a22t - a11t*a23t*a23t - a33t*a12t*a12t
370  + 2.* a12t*a13t*a23t - a13t*a13t*a22t );
371 
372  v11[0] = (a33t*a22t - a23t*a23t)/dd;
373  v12[0] =-(a33t*a12t - a13t*a23t)/dd;
374  v13[0] = (a12t*a23t - a13t*a22t)/dd;
375  v22[0] = (a33t*a11t - a13t*a13t)/dd;
376  v23[0] =-(a23t*a11t - a12t*a13t)/dd;
377  v33[0] = (a22t*a11t - a12t*a12t)/dd;
378 
379  // Center strip
380  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]);
381  a12t = a12[1] + syserr*syserr * ChargeSignal[1][0]*ChargeSignal[1][1];
382  a13t = a13[1] + syserr*syserr * ChargeSignal[1][0]*ChargeSignal[1][2];
383  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]);
384  a23t = a23[1] + syserr*syserr * ChargeSignal[1][1]*ChargeSignal[1][2];
385  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]);
386 
387  dd = (a11t*a33t*a22t - a11t*a23t*a23t - a33t*a12t*a12t
388  + 2.* a12t*a13t*a23t - a13t*a13t*a22t );
389 
390  v11[1] = (a33t*a22t - a23t*a23t)/dd;
391  v12[1] =-(a33t*a12t - a13t*a23t)/dd;
392  v13[1] = (a12t*a23t - a13t*a22t)/dd;
393  v22[1] = (a33t*a11t - a13t*a13t)/dd;
394  v23[1] =-(a23t*a11t - a12t*a13t)/dd;
395  v33[1] = (a22t*a11t - a12t*a12t)/dd;
396 
397  // Right strip
398  a11t = a11[2] + syserr*syserr * ChargeSignal[2][0]*ChargeSignal[2][0] + xtlk_err*xtlk_err*ChargeSignal[1][0]*ChargeSignal[1][0];
399  a12t = a12[2] + syserr*syserr * ChargeSignal[2][0]*ChargeSignal[2][1];
400  a13t = a13[2] + syserr*syserr * ChargeSignal[2][0]*ChargeSignal[2][2];
401  a22t = a22[2] + syserr*syserr * ChargeSignal[2][1]*ChargeSignal[2][1] + xtlk_err*xtlk_err*ChargeSignal[1][1]*ChargeSignal[1][1];
402  a23t = a23[2] + syserr*syserr * ChargeSignal[2][1]*ChargeSignal[2][2];
403  a33t = a33[2] + syserr*syserr * ChargeSignal[2][2]*ChargeSignal[2][2] + xtlk_err*xtlk_err*ChargeSignal[1][2]*ChargeSignal[1][2];
404 
405  dd = (a11t*a33t*a22t - a11t*a23t*a23t - a33t*a12t*a12t
406  +2.* a12t*a13t*a23t - a13t*a13t*a22t );
407 
408  v11[2] = (a33t*a22t - a23t*a23t)/dd;
409  v12[2] =-(a33t*a12t - a13t*a23t)/dd;
410  v13[2] = (a12t*a23t - a13t*a22t)/dd;
411  v22[2] = (a33t*a11t - a13t*a13t)/dd;
412  v23[2] =-(a23t*a11t - a12t*a13t)/dd;
413  v33[2] = (a22t*a11t - a12t*a12t)/dd;
414 */
415  //---- Find the inverted XTalk matrix and apply it to the charge (3x3)
416  //---- Thus the charge before the XTalk is obtained
417  CLHEP::HepMatrix cross_talks(3,3);
418  CLHEP::HepMatrix cross_talks_inv(3,3);
419  int err = 0;
420  //---- q_sum is 3 time bins summed; L, C, R - left, central, right strips
421  q_sum = q_sumL = q_sumC = q_sumR = 0.;
422  double charge = 0.;
423  for(int iTime=0;iTime<3;iTime++){
424  cross_talks_inv(1,1) = cross_talks(1,1) = xt_lr0[iTime];
425  cross_talks_inv(1,2) = cross_talks(1,2) = xt_l[1][iTime];
426  cross_talks_inv(1,3) = cross_talks(1,3) = 0.;
427  cross_talks_inv(2,1) = cross_talks(2,1) = xt_r[0][iTime];
428  cross_talks_inv(2,2) = cross_talks(2,2) = xt_lr1[iTime];
429  cross_talks_inv(2,3) = cross_talks(2,3) = xt_l[2][iTime];
430  cross_talks_inv(3,1) = cross_talks(3,1) = 0.;
431  cross_talks_inv(3,2) = cross_talks(3,2) = xt_r[1][iTime];
432  cross_talks_inv(3,3) = cross_talks(3,3) = xt_lr2[iTime];
433  cross_talks_inv.invert(err);
434  if (err != 0) {
435  edm::LogWarning("FailedXTalkiInversionNoCrosstalkCorrection") <<"Failed to invert XTalks matrix. No cross-talk correction for this rechit.";
436  //edm::LogError("CSCRecHit") << "Failed to invert XTalks matrix. No cross-talk correction for this rechit.";
437  return;
438  }
439  //---- "charge" is XT-corrected charge
440  charge = chargeSignal[0][iTime]*cross_talks_inv(1,1) + chargeSignal[1][iTime]*cross_talks_inv(1,2) +
441  chargeSignal[2][iTime]*cross_talks_inv(1,3);
442  //---- Negative charge? According to studies (and logic) - better use 0 charge
443  //----- Later studies suggest that this only do harm. I am still worried about
444  // charges of -50 ADC and below (0.5% of the cases) but let see
445  //if(charge<0.){
446  //charge = 0.;
447  //}
448  q_sum+=charge;
449  q_sumL+=charge;
450  charge = chargeSignal[0][iTime]*cross_talks_inv(2,1) + chargeSignal[1][iTime]*cross_talks_inv(2,2) +
451  chargeSignal[2][iTime]* cross_talks_inv(2,3);
452  //if(charge<0.){
453  //charge = 0.;
454  //}
455  q_sum+=charge;
456  q_sumC+=charge;
457  charge = chargeSignal[0][iTime]*cross_talks_inv(3,1) + chargeSignal[1][iTime]*cross_talks_inv(3,2) +
458  chargeSignal[2][iTime]*cross_talks_inv(3,3);
459  //if(charge<0.){
460  //charge = 0.;
461  //}
462  q_sum+=charge;
463  q_sumR+=charge;
464  }
465 }
466 
467 
468 /* initChamberSpecs
469  *
470  */
472  // Not used directly but these are parameters used for extracting the correction values
473  // in coordinate and error estimators
474 
475  // Distance between anode and cathode
477  r = h / stripWidth;
478 
479  // Wire spacing
480  double wspace = specs_->wireSpacing();
481 
482  // Wire radius
483  double wradius = specs_->wireRadius();
484 
485  // Accepted parameters in Gatti function
486  const double parm[5] = {.1989337e-02, -.6901542e-04, .8665786, 154.6177, -.680163e-03 };
487 
488  k_3 = ( parm[0]*wspace/h + parm[1] )
489  * ( parm[2]*wspace/wradius + parm[3] + parm[4]*(wspace/wradius)*(wspace/wradius) );
490 
491  sqrt_k_3 = sqrt( k_3 );
492  norm = r * (0.5 / atan( sqrt_k_3 )); // changed from norm to r * norm
493  k_2 = M_PI_2 * ( 1. - sqrt_k_3 /2. );
494  k_1 = 0.25 * k_2 * sqrt_k_3 / atan( sqrt_k_3 );
495 }
496 
497 
500 }
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  }
511  else{
512  n_SW = n_SW_noME1_1;
513  min_SW = 6;// min SW calculated is 0.6 cm
514  }
515  int stripDown = int(10.*stripWidth) - min_SW; // 0 is at min strip width calculated
516  int stripUp = stripDown + 1;
517  if(stripUp>n_SW-1){
518  //---- to be checked...
519  //if(stripUp>n_SW){
520  //std::cout<<" Is strip width = "<<stripWidth<<" OK?" <<std::endl;
521  //}
522  stripUp = n_SW-1;
523  }
524 
525  double half_strip_width = 0.5;
526  //const int Nbins = 501;
527  const int n_bins = n_val;
528  double corr_2_xestim = 999.;
529  if(stripDown<0){
530  corr_2_xestim = 1;
531  }
532  else{
533  //---- Parametrized x_gatti minus x_estimated differences
534 
535  int xestim_bin = -999;
536  double delta_strip_width = 999.;
537  double delta_strip_widthUpDown = 999.;
538  double diff_2_strip_width = 999.;
539  delta_strip_width = stripWidth - int(stripWidth*10)/10.;
540  delta_strip_widthUpDown = 0.1;
541 
542  if(fabs(x_estimated)>0.5){
543  if(fabs(x_estimated)>1.){
544  corr_2_xestim = 1.;// for now; to be investigated
545  }
546  else{
547  //if(fabs(Xestimated)>0.55){
548  //std::cout<<"X position from the estimated position above 0.55 (safty margin)?! "<<std::endl;
549  //CorrToXc = 999.;
550  //}
551  xestim_bin = int((1.- fabs(x_estimated))/half_strip_width * n_bins);
552  if(ME1_1){
553  diff_2_strip_width = x_correction_ME1_1[stripUp][xestim_bin]-x_correction_ME1_1[stripDown][xestim_bin];
554  corr_2_xestim = x_correction_ME1_1[stripDown][xestim_bin] +
555  (delta_strip_width/delta_strip_widthUpDown)*diff_2_strip_width ;
556  }
557  else{
558  diff_2_strip_width = x_correction_noME1_1[stripUp][xestim_bin]-x_correction_noME1_1[stripDown][xestim_bin];
559  corr_2_xestim = x_correction_noME1_1[stripDown][xestim_bin] +
560  (delta_strip_width/delta_strip_widthUpDown)*diff_2_strip_width ;
561  }
562  corr_2_xestim = -corr_2_xestim;
563  }
564  }
565  else{
566  xestim_bin = int((fabs(x_estimated)/half_strip_width) * n_bins);
567  if(ME1_1){
568  diff_2_strip_width = x_correction_ME1_1[stripUp][xestim_bin] - x_correction_ME1_1[stripDown][xestim_bin];
569  corr_2_xestim = x_correction_ME1_1[stripDown][xestim_bin] +
570  (delta_strip_width/delta_strip_widthUpDown)*diff_2_strip_width ;
571  }
572  else{
573  diff_2_strip_width = x_correction_noME1_1[stripUp][xestim_bin] - x_correction_noME1_1[stripDown][xestim_bin];
574  corr_2_xestim = x_correction_noME1_1[stripDown][xestim_bin] +
575  (delta_strip_width/delta_strip_widthUpDown)*diff_2_strip_width ;
576  }
577  }
578  if(x_estimated<0.){
579  corr_2_xestim = -corr_2_xestim;
580  }
581  }
582 
583  return corr_2_xestim;
584 }
585 
586 
587 double CSCXonStrip_MatchGatti::estimated2Gatti(double x_estimated, float stripWidth, bool ME1_1) {
588 
589  double x_corr = estimated2GattiCorrection(x_estimated, stripWidth, ME1_1);
590  double x_gatti = x_estimated + x_corr;
591 
592  return x_gatti;
593 }
594 
596 
597  double min, max;
598  if(q_sumR>q_sumL){
599  min = q_sumL;
600  max = q_sumR;
601  }
602  else{
603  min = q_sumR;
604  max = q_sumL;
605  }
606  //---- Error propagation...
607  //---- Names here are fake! Due to technical features
608  double dr_L2 = pow(q_sumR-q_sumL,2);
609  double dr_C2 = pow(q_sumC-min,2);
610  double dr_R2 = pow(q_sumC-max,2);
611  double error = sqrt(dr_L2 + dr_C2 + dr_R2)*noise/pow(q_sumC-min,2)/2;
612 
613  return error;
614 }
615 
617 
618  double min;
619  if(q_sumR>q_sumL){
620  min = q_sumL;
621  }
622  else{
623  min = q_sumR;
624  }
625  //---- Error propagation
626  double dXTL = (pow(q_sumC,2)+pow(q_sumR,2)-q_sumL*q_sumR-q_sumR*q_sumC);
627  double dXTR = (pow(q_sumC,2)+pow(q_sumL,2)-q_sumL*q_sumR-q_sumL*q_sumC);
628  double dXT = sqrt(pow(dXTL,2) + pow(dXTR,2))/pow((q_sumC-min),2)/2;
629  double error = dXT * xt_asym;
630 
631  return error;
632 }
633 
634 
635 double CSCXonStrip_MatchGatti::calculateXonStripError(float stripWidth, bool ME1_1){
636  double min;
637  if(q_sumR>q_sumL){
638  min = q_sumL;
639  }
640  else{
641  min = q_sumR;
642  }
643 
644  double xf = (q_sumR - q_sumL)/(q_sumC - min)/2;
645  double xf_ErrorNoise = xfError_Noise(noise_level);
646  double xf_ErrorXTasym = xfError_XTasym(xt_asymmetry);
647  // x_G = x_F + correction_functon(x_F)
648  // 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)]
649  double d_xf = sqrt( pow( xf_ErrorNoise, 2) + pow( xf_ErrorXTasym, 2));
650  double d_corr = estimated2GattiCorrection(xf+d_xf, stripWidth, ME1_1) - estimated2GattiCorrection(xf, stripWidth, ME1_1);
651  double x_shift = d_xf + d_corr;
652  // double x_shift = sqrt( pow( xf_ErrorNoise, 2) + pow( xf_ErrorXTasym, 2)) *
653  //(1 + (estimated2GattiCorrection(xf+0.001, stripWidth, ME1_1) -
654  // estimated2GattiCorrection(xf, stripWidth, ME1_1))*1000.);
655  double x_error = sqrt( pow( fabs(x_shift)*stripWidth, 2) + pow(const_syst, 2) );
656  return x_error;
657 }
658 
659 double CSCXonStrip_MatchGatti::calculateXonStripPosition(float stripWidth, bool ME1_1){
660 
661  double x_estimated = -99.;
662  double min;
663  if(q_sumR>q_sumL){
664  min = q_sumL;
665  }
666  else{
667  min = q_sumR;
668  }
669  //---- This is XF ( X Florida - after the first group that used it)
670  x_estimated = (q_sumR - q_sumL)/(q_sumC - min)/2;
671  double x_gatti = estimated2Gatti(x_estimated, stripWidth, ME1_1);
672  return x_gatti;
673 }
674 
675 // Define space for statics
679 
int adc(sample_type sample)
get the ADC sample (12 bits)
T getParameter(std::string const &) const
float dt
Definition: AMPTWrapper.h:126
int i
Definition: DBlmapReader.cc:9
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
const CSCRecoConditions * recoConditions_
double charge(const std::vector< uint8_t > &Ampls)
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
const T & max(const T &a, const T &b)
T sqrt(T t)
Definition: SSEVec.h:48
double xfError_Noise(double noise)
double estimated2GattiCorrection(double Xestimated, float StripWidth, bool ME1_1)
int j
Definition: DBlmapReader.cc:9
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)