View Javadoc
1   package org.hps.recon.tracking;
2   
3   import java.util.ArrayList;
4   import java.util.List;
5   import org.hps.conditions.database.DatabaseConditionsManager;
6   import org.hps.conditions.svt.SvtTimingConstants;
7   import org.hps.readout.ecal.ReadoutTimestamp;
8   import org.hps.readout.svt.HPSSVTConstants;
9   import org.lcsim.detector.tracker.silicon.HpsSiSensor;
10  import org.lcsim.event.EventHeader;
11  import org.lcsim.event.RawTrackerHit;
12  import org.lcsim.geometry.Detector;
13  import org.lcsim.lcio.LCIOConstants;
14  import org.lcsim.recon.cat.util.Const;
15  import org.lcsim.util.Driver;
16  
17  /**
18   *
19   * @author Matt Graham
20   */
21  // TODO: Add class documentation.
22  public class RawTrackerHitFitterDriver extends Driver {
23  
24      private boolean debug = false;
25      private ShaperFitAlgorithm fitter = new DumbShaperFit();
26      private PulseShape shape = new PulseShape.FourPole();
27      private String rawHitCollectionName = "SVTRawTrackerHits";
28      private String fitCollectionName = "SVTShapeFitParameters";
29      private String fittedHitCollectionName = "SVTFittedRawTrackerHits";
30      private SvtTimingConstants timingConstants;
31      private int genericObjectFlags = 1 << LCIOConstants.GOBIT_FIXED;
32      private int relationFlags = 0;
33      private boolean correctTimeOffset = false;
34      private boolean correctT0Shift = false;
35      private boolean useTimestamps = false;
36      private boolean useTruthTime = false;
37      private boolean subtractTOF = false;
38      private boolean subtractTriggerTime = false;
39      private boolean correctChanT0 = true;
40  
41      private double tsCorrectionScale = 240;
42  
43      /**
44       * Report time relative to the nearest expected truth event time.
45       *
46       * @param useTruthTime
47       */
48      public void setUseTruthTime(boolean useTruthTime) {
49          this.useTruthTime = useTruthTime;
50      }
51  
52      public void setDebug(boolean debug) {
53          this.debug = debug;
54      }
55  
56      public void setCorrectTimeOffset(boolean correctTimeOffset) {
57          this.correctTimeOffset = correctTimeOffset;
58      }
59  
60      public void setCorrectT0Shift(boolean correctT0Shift) {
61          this.correctT0Shift = correctT0Shift;
62      }
63  
64      public void setUseTimestamps(boolean useTimestamps) {
65          this.useTimestamps = useTimestamps;
66      }
67  
68      public void setTsCorrectionScale(double tsCorrectionScale) {
69          this.tsCorrectionScale = tsCorrectionScale;
70      }
71  
72      public void setSubtractTOF(boolean subtractTOF) {
73          this.subtractTOF = subtractTOF;
74      }
75  
76      public void setSubtractTriggerTime(boolean subtractTriggerTime) {
77          this.subtractTriggerTime = subtractTriggerTime;
78      }
79  
80      public void setCorrectChanT0(boolean correctChanT0) {
81          this.correctChanT0 = correctChanT0;
82      }
83  
84      public void setFitAlgorithm(String fitAlgorithm) {
85          if (fitAlgorithm.equals("Analytic"))
86              fitter = new ShaperAnalyticFitAlgorithm();
87          else if (fitAlgorithm.equals("Linear"))
88              fitter = new ShaperLinearFitAlgorithm(1);
89          else if (fitAlgorithm.equals("PileupAlways"))
90              fitter = new ShaperPileupFitAlgorithm(1.0);
91          else if (fitAlgorithm.equals("Pileup"))
92              fitter = new ShaperPileupFitAlgorithm();
93          else
94              throw new RuntimeException("Unrecognized fitAlgorithm: " + fitAlgorithm);
95      }
96  
97      public void setPulseShape(String pulseShape) {
98          if (pulseShape.equals("CR-RC"))
99              shape = new PulseShape.CRRC();
100         else if (pulseShape.equals("FourPole"))
101             shape = new PulseShape.FourPole();
102         else
103             throw new RuntimeException("Unrecognized pulseShape: " + pulseShape);
104     }
105 
106     public void setFitCollectionName(String fitCollectionName) {
107         this.fitCollectionName = fitCollectionName;
108     }
109 
110     public void setFittedHitCollectionName(String fittedHitCollectionName) {
111         this.fittedHitCollectionName = fittedHitCollectionName;
112     }
113 
114     public void setRawHitCollectionName(String rawHitCollectionName) {
115         this.rawHitCollectionName = rawHitCollectionName;
116     }
117 
118     @Override
119     public void startOfData() {
120         fitter.setDebug(debug);
121         if (rawHitCollectionName == null)
122             throw new RuntimeException("The parameter ecalCollectionName was not set!");
123     }
124 
125     protected void detectorChanged(Detector detector) {
126         timingConstants = DatabaseConditionsManager.getInstance().getCachedConditions(SvtTimingConstants.SvtTimingConstantsCollection.class, "svt_timing_constants").getCachedData().get(0);
127     }
128 
129     @Override
130     public void process(EventHeader event) {
131         if (!event.hasCollection(RawTrackerHit.class, rawHitCollectionName))
132             // System.out.println(rawHitCollectionName + " does not exist; skipping event");
133             return;
134 
135         List<RawTrackerHit> rawHits = event.get(RawTrackerHit.class, rawHitCollectionName);
136         if (rawHits == null)
137             throw new RuntimeException("Event is missing SVT hits collection!");
138         List<FittedRawTrackerHit> hits = new ArrayList<FittedRawTrackerHit>();
139         List<ShapeFitParameters> fits = new ArrayList<ShapeFitParameters>();
140 
141         // Make a fitted hit from this cluster
142         for (RawTrackerHit hit : rawHits) {
143             int strip = hit.getIdentifierFieldValue("strip");
144             HpsSiSensor sensor = (HpsSiSensor) hit.getDetectorElement();
145             //===> ChannelConstants constants = HPSSVTCalibrationConstants.getChannelConstants((SiSensor) hit.getDetectorElement(), strip);
146             //for (ShapeFitParameters fit : _shaper.fitShape(hit, constants)) {
147             for (ShapeFitParameters fit : fitter.fitShape(hit, shape)) {
148                 if (correctTimeOffset)
149                     fit.setT0(fit.getT0() - timingConstants.getOffsetTime());
150                 if (subtractTriggerTime)
151                     fit.setT0(fit.getT0() - (((event.getTimeStamp() - 4 * timingConstants.getOffsetPhase()) % 24) - 12));
152                 if (correctChanT0)
153                     fit.setT0(fit.getT0() - sensor.getShapeFitParameters(strip)[HpsSiSensor.T0_INDEX]);
154                 if (correctT0Shift)
155                     //===> fit.setT0(fit.getT0() - constants.getT0Shift());
156                     fit.setT0(fit.getT0() - sensor.getT0Shift());
157                 if (subtractTOF) {
158                     double tof = hit.getDetectorElement().getGeometry().getPosition().magnitude() / (Const.SPEED_OF_LIGHT * Const.nanosecond);
159                     fit.setT0(fit.getT0() - tof);
160                 }
161                 if (useTimestamps) {
162                     double t0Svt = ReadoutTimestamp.getTimestamp(ReadoutTimestamp.SYSTEM_TRACKER, event);
163                     double t0Trig = ReadoutTimestamp.getTimestamp(ReadoutTimestamp.SYSTEM_TRIGGERBITS, event);
164                     // double corMod = (t0Svt - t0Trig) + 200.0;///where does 200.0 come from?  for 2016 MC, looks like should be 240
165                     double corMod = (t0Svt - t0Trig) + tsCorrectionScale;
166                     fit.setT0(fit.getT0() + corMod);
167                 }
168                 if (useTruthTime) {
169                     double t0Svt = ReadoutTimestamp.getTimestamp(ReadoutTimestamp.SYSTEM_TRACKER, event);
170                     double absoluteHitTime = fit.getT0() + t0Svt;
171                     double relativeHitTime = ((absoluteHitTime + 250.0) % 500.0) - 250.0;
172 
173                     fit.setT0(relativeHitTime);
174                 }
175                 if (debug)
176                     System.out.println(fit);
177                 fits.add(fit);
178                 FittedRawTrackerHit hth = new FittedRawTrackerHit(hit, fit);
179                 hits.add(hth);
180                 if (strip == HPSSVTConstants.TOTAL_STRIPS_PER_SENSOR) // drop unbonded channel
181                     continue;
182                 hit.getDetectorElement().getReadout().addHit(hth);
183             }
184         }
185         event.put(fitCollectionName, fits, ShapeFitParameters.class, genericObjectFlags);
186         event.put(fittedHitCollectionName, hits, FittedRawTrackerHit.class, relationFlags);
187     }
188 }