View Javadoc
1   package org.hps.recon.tracking;
2   
3   import java.util.ArrayList;
4   import java.util.Collection;
5   
6   import org.apache.commons.math3.special.Gamma;
7   import org.hps.readout.svt.HPSSVTConstants;
8   //===> import org.hps.conditions.deprecated.HPSSVTCalibrationConstants.ChannelConstants;
9   import org.lcsim.detector.tracker.silicon.HpsSiSensor;
10  import org.lcsim.event.RawTrackerHit;
11  
12  /**
13   * Fast fitter; currently only fits single hits. Uses Tp from ChannelConstants;
14   * fits values and errors for T0 and amplitude.
15   *
16   * @author Sho Uemura
17   */
18  public class ShaperAnalyticFitAlgorithm implements ShaperFitAlgorithm {
19  
20      private boolean debug = false;
21  
22      public void setDebug(boolean debug) {
23          this.debug = debug;
24      }
25  
26      @Override
27      public Collection<ShapeFitParameters> fitShape(RawTrackerHit rth, PulseShape shape) {
28          short[] samples = rth.getADCValues();
29          HpsSiSensor sensor = (HpsSiSensor) rth.getDetectorElement();
30          int channel = rth.getIdentifierFieldValue("strip");
31          return this.fitShape(channel, samples, sensor);
32          //===> return this.fitShape(rth.getADCValues(), constants);
33      }
34  
35      public Collection<ShapeFitParameters> fitShape(int channel, short[] samples, HpsSiSensor sensor) {
36          double minChisq = Double.POSITIVE_INFINITY;
37          int bestStart = 0;
38          ShapeFitParameters fit = new ShapeFitParameters();
39          for (int i = 0; i < samples.length - 2; i++) {
40              double chisq = fitSection(channel, samples, sensor, fit, i);
41              // System.out.println("i = " + i + ", " + fit);
42              if (chisq < minChisq) {
43                  minChisq = chisq;
44                  bestStart = i;
45              }
46          }
47          fitSection(channel, samples, sensor, fit, bestStart);
48          // System.out.format("%f\t%f\t%f\t%f\t%f\t%f\n", samples[0] - constants.getPedestal(),
49          // samples[1] - constants.getPedestal(), samples[2] - constants.getPedestal(), samples[3] -
50          // constants.getPedestal(), samples[4] - constants.getPedestal(), samples[5] -
51          // constants.getPedestal());
52          // System.out.println("start = " + bestStart + ", " + fit);
53          ArrayList<ShapeFitParameters> fits = new ArrayList<ShapeFitParameters>();
54          fits.add(fit);
55          return fits;
56      }
57  
58      private double fitSection(int channel, short[] samples, HpsSiSensor sensor, ShapeFitParameters fit, int start) {
59          int length = samples.length - start;
60          double[] y = new double[length];
61          double[] t = new double[length];
62  
63          double tp = 2.5*Math.pow(sensor.getShapeFitParameters(channel)[HpsSiSensor.TP_INDEX], 0.25) * Math.pow(sensor.getShapeFitParameters(channel)[HpsSiSensor.TP_INDEX + 1], 0.75);
64  
65          for (int i = 0; i < length; i++) {
66              //===> y[i] = samples[start + i] - constants.getPedestal();
67              y[i] = samples[start + i] - sensor.getPedestal(channel, i);
68              t[i] = HPSSVTConstants.SAMPLING_INTERVAL * i;
69          }
70  
71          double[] p = new double[length];
72          double[] a = new double[length];
73          for (int i = 0; i < length; i++) {
74              //===> p[i] = y[i] / constants.getNoise();
75              p[i] = y[i] / sensor.getNoise(channel, i);
76              //===> a[i] = Math.exp(1 - t[i] / constants.getTp()) / (constants.getTp() * constants.getNoise());
77  
78              a[i] = Math.exp(1 - t[i] / tp) / (tp * sensor.getNoise(channel, i));
79          }
80  
81          double pa, aatt, pat, aat, aa;
82          pa = 0;
83          aatt = 0;
84          pat = 0;
85          aat = 0;
86          aa = 0;
87          for (int i = 0; i < length; i++) {
88              pa += p[i] * a[i];
89              aatt += a[i] * a[i] * t[i] * t[i];
90              pat += p[i] * a[i] * t[i];
91              aat += a[i] * a[i] * t[i];
92              aa += a[i] * a[i];
93          }
94  
95          double t0 = (pa * aatt - pat * aat) / (pa * aat - aa * pat);
96          //===> double A = pa / ((Math.exp(t0 / constants.getTp()) * (aat - t0 * aa)));
97          double A = pa / ((Math.exp(t0 / tp) * (aat - t0 * aa)));
98  
99          double time_var = 0;
100         double height_var = 0;
101         for (int i = 0; i < length; i++) {
102             double dt_dp = a[i] * (aatt - t[i] * aat - t0 * (aat - t[i] * aa)) / (pa * aat - aa * pat);
103             //===> double dh_dp = (a[i] * Math.exp(-1.0 * t0 / constants.getTp()) + A * dt_dp * aa) / (aat - t0 * aa) - A * dt_dp / constants.getTp();
104             double dh_dp = (a[i] * Math.exp(-1.0 * t0 / tp) + A * dt_dp * aa) / (aat - t0 * aa) - A * dt_dp / tp;
105             time_var += dt_dp * dt_dp;
106             height_var += dh_dp * dh_dp;
107         }
108         t0 += HPSSVTConstants.SAMPLING_INTERVAL * start;
109         fit.setAmp(A);
110         fit.setAmpErr(Math.sqrt(height_var));
111         fit.setT0(t0);
112         fit.setT0Err(Math.sqrt(time_var));
113 
114         double chisq = 0;
115         for (int i = 0; i < samples.length; i++) {
116             double ti = HPSSVTConstants.SAMPLING_INTERVAL * i;
117             //===> double fit_y = A * (Math.max(0, (ti - t0)) / constants.getTp()) * Math.exp(1 - (ti - t0) / constants.getTp()) + constants.getPedestal();
118             double fit_y = A * (Math.max(0, (ti - t0)) / tp) * Math.exp(1 - (ti - t0) / tp) + sensor.getPedestal(channel, i);
119             //===> chisq += Math.pow((fit_y - samples[i]) / constants.getNoise(), 2);
120             chisq += Math.pow((fit_y - samples[i]) / sensor.getNoise(channel, i), 2);
121         }
122 
123         if (A > 0 && chisq < Double.POSITIVE_INFINITY) {
124             // return ChisqProb.gammp(samples.length - 2, chisq);
125             fit.setChiProb(Gamma.regularizedGammaQ(samples.length - 2, chisq));
126             return chisq / (samples.length - 2);
127         } else {
128             return Double.POSITIVE_INFINITY;
129         }
130     }
131 }