Skip to content

Commit 1bd4e65

Browse files
authored
Clean bad AHDC hits and use ATOF wedges in the Kalman Filter (#1309)
* extends the bank AHDC::kftrack and allow re-cooking of AHDC only * convenient use of PID in RK4 * create KFHit and refactor the kalman filter * activate atof hit * rename methods * remove unused variables and methods * use a logger * fix innovation vector for RadialKFHit * cleaning * let registerOutputBank removes the banks
1 parent a722886 commit 1bd4e65

14 files changed

Lines changed: 1005 additions & 301 deletions

File tree

etc/bankdefs/hipo4/alert.json

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,74 @@
408408
"name": "sum_residuals",
409409
"type": "F",
410410
"info": "Sum of residuals (mm)"
411+
}, {
412+
"name": "atof_region",
413+
"type": "I",
414+
"info": "a flag to know if a track reach S1, S2, or S3; is n if Sn is reached; is 0 otherwise"
415+
}, {
416+
"name": "atof_s1_x",
417+
"type": "F",
418+
"info": "x position of the track if it reaches the surface s1"
419+
}, {
420+
"name": "atof_s1_y",
421+
"type": "F",
422+
"info": "y position of the track if it reaches the surface s1"
423+
}, {
424+
"name": "atof_s1_z",
425+
"type": "F",
426+
"info": "z position of the track if it reaches the surface s1"
427+
}, {
428+
"name": "atof_s1_path",
429+
"type": "F",
430+
"info": "total path from the beamline to the surface s1"
431+
}, {
432+
"name": "atof_s1_p",
433+
"type": "F",
434+
"info": "momentum whith which the track reaches the surface s1"
435+
}, {
436+
"name": "atof_s2_x",
437+
"type": "F",
438+
"info": "x position of the track if it reaches the surface s2"
439+
}, {
440+
"name": "atof_s2_y",
441+
"type": "F",
442+
"info": "y position of the track if it reaches the surface s2"
443+
}, {
444+
"name": "atof_s2_z",
445+
"type": "F",
446+
"info": "z position of the track if it reaches the surface s2"
447+
}, {
448+
"name": "atof_s2_path",
449+
"type": "F",
450+
"info": "total path from the beamline to the surface s2"
451+
}, {
452+
"name": "atof_s2_p",
453+
"type": "F",
454+
"info": "momentum whith which the track reaches the surface s2"
455+
}, {
456+
"name": "atof_s3_x",
457+
"type": "F",
458+
"info": "x position of the track if it reaches the surface s3"
459+
}, {
460+
"name": "atof_s3_y",
461+
"type": "F",
462+
"info": "y position of the track if it reaches the surface s3"
463+
}, {
464+
"name": "atof_s3_z",
465+
"type": "F",
466+
"info": "z position of the track if it reaches the surface s3"
467+
}, {
468+
"name": "atof_s3_path",
469+
"type": "F",
470+
"info": "total path from the beamline to the surface s3"
471+
}, {
472+
"name": "atof_s3_p",
473+
"type": "F",
474+
"info": "momentum whith which the track reaches the surface s3"
475+
}, {
476+
"name": "atof_match",
477+
"type": "B",
478+
"info": "1 if there is a ATOF match, 0 if not"
411479
}
412480
]
413481
}, {

reconstruction/alert/src/main/java/org/jlab/rec/ahdc/Banks/RecoBankWriter.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.jlab.rec.ahdc.AHDCCluster.AHDCCluster;
88
import org.jlab.rec.ahdc.DocaCluster.DocaCluster;
99
import org.jlab.rec.ahdc.Hit.Hit;
10+
import org.jlab.rec.ahdc.KalmanFilter.Stepper;
1011
import org.jlab.rec.ahdc.PreCluster.PreCluster;
1112
import org.jlab.rec.alert.Track.Track;
1213

@@ -153,6 +154,39 @@ public DataBank fillAHDCKFTrackBank(DataEvent event, ArrayList<Track> tracks) {
153154
bank.setFloat("chi2", row, (float) track.get_chi2());
154155
bank.setFloat("sum_residuals", row, (float) track.get_sum_residuals());
155156

157+
// track projection on ATOF surface S1
158+
Stepper stepper_s1 = track.get_ATOF_S1_stepper();
159+
if (stepper_s1 != null) {
160+
bank.setFloat("atof_s1_x", row, (float) stepper_s1.y[0]);
161+
bank.setFloat("atof_s1_y", row, (float) stepper_s1.y[1]);
162+
bank.setFloat("atof_s1_z", row, (float) stepper_s1.y[2]);
163+
bank.setFloat("atof_s1_path", row, (float) stepper_s1.sTot);
164+
bank.setFloat("atof_s1_p", row, (float) stepper_s1.p());
165+
}
166+
167+
// track projection on ATOF surface S2
168+
Stepper stepper_s2 = track.get_ATOF_S2_stepper();
169+
if (stepper_s2 != null) {
170+
bank.setFloat("atof_s2_x", row, (float) stepper_s2.y[0]);
171+
bank.setFloat("atof_s2_y", row, (float) stepper_s2.y[1]);
172+
bank.setFloat("atof_s2_z", row, (float) stepper_s2.y[2]);
173+
bank.setFloat("atof_s2_path", row, (float) stepper_s2.sTot);
174+
bank.setFloat("atof_s2_p", row, (float) stepper_s2.p());
175+
}
176+
177+
// track projection on ATOF surface S3
178+
Stepper stepper_s3 = track.get_ATOF_S3_stepper();
179+
if (stepper_s3 != null) {
180+
bank.setFloat("atof_s3_x", row, (float) stepper_s3.y[0]);
181+
bank.setFloat("atof_s3_y", row, (float) stepper_s3.y[1]);
182+
bank.setFloat("atof_s3_z", row, (float) stepper_s3.y[2]);
183+
bank.setFloat("atof_s3_path", row, (float) stepper_s3.sTot);
184+
bank.setFloat("atof_s3_p", row, (float) stepper_s3.p());
185+
}
186+
187+
bank.setInt("atof_region", row, track.get_ATOF_region());
188+
bank.setByte("atof_match", row, (byte) ((track.getATOFHits().size() > 0) ? 1 : 0));
189+
156190
row++;
157191
}
158192

reconstruction/alert/src/main/java/org/jlab/rec/ahdc/Hit/Hit.java

Lines changed: 65 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22

33
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
44
import org.apache.commons.math3.linear.ArrayRealVector;
5+
import org.apache.commons.math3.linear.MatrixUtils;
56
import org.apache.commons.math3.linear.RealMatrix;
67
import org.apache.commons.math3.linear.RealVector;
78
import org.jlab.detector.calib.utils.DatabaseConstantProvider;
89
import org.jlab.geom.detector.alert.AHDC.AlertDCDetector;
910
import org.jlab.geom.prim.Line3D;
1011
import org.jlab.geom.prim.Point3D;
1112
import org.jlab.geom.detector.alert.AHDC.AlertDCFactory;
13+
import org.jlab.rec.ahdc.KalmanFilter.KFHit;
1214

13-
public class Hit implements Comparable<Hit> {
15+
public class Hit implements Comparable<Hit>, KFHit {
1416

1517
private final int id;
1618
private final int superLayerId;
@@ -33,6 +35,16 @@ public class Hit implements Comparable<Hit> {
3335
private int trackId;
3436

3537
//updated constructor with ADC
38+
/**
39+
*
40+
* @param _Id is AHDC::adc row id + 1
41+
* @param _Super_layer super layer id
42+
* @param _Layer layer id
43+
* @param _Wire wire id
44+
* @param _Doca distance from the timing information using the time2distance, matches {@link Hit.#time}
45+
* @param _ADC raw ADC
46+
* @param _Time calibrated time
47+
*/
3648
public Hit(int _Id, int _Super_layer, int _Layer, int _Wire, double _Doca, double _ADC, double _Time) {
3749
this.id = _Id;
3850
this.superLayerId = _Super_layer;
@@ -110,6 +122,7 @@ public Line3D getLine() {
110122
return wireLine;
111123
}
112124

125+
@Override
113126
public double getRadius() {
114127
return radius;
115128
}
@@ -136,6 +149,7 @@ public double getY() {
136149

137150
public double getPhi() {return phi;}
138151

152+
/** Get calibrated ADC */
139153
public double getADC() {return adc;}
140154

141155
public double getResidual() {
@@ -146,18 +160,22 @@ public void setResidual(double resid) {
146160
this.residual = resid;
147161
}
148162

163+
/** Set calibrated ToT */
149164
public void setToT(double _tot) {
150165
this.tot = _tot;
151166
}
152167

168+
/** Get calibrated ToT */
153169
public double getToT() {
154170
return tot;
155171
}
156172

173+
/** Set calibrated ADC */
157174
public void setADC(double _adc) {
158175
this.adc = _adc;
159176
}
160177

178+
/** Get raw ADC */
161179
public double getRawADC() {
162180
return raw_adc;
163181
}
@@ -174,11 +192,13 @@ public void setTrackId(int _trackId) {
174192
this.trackId = _trackId;
175193
}
176194

177-
public RealVector get_Vector() {
195+
@Override
196+
public RealVector getMeasurementVector() {
178197
return new ArrayRealVector(new double[]{this.doca});
179198
}
180199

181-
public RealMatrix get_MeasurementNoise() {
200+
@Override
201+
public RealMatrix getMeasurementNoiseMatrix() {
182202
double mean_error = 0.471; // mm (no difference between adc and time)
183203
double error_on_adc = (1.15146*raw_adc + 437.63)/(3.21187*raw_adc + 878.855); // mm
184204
double error_on_time = (0.4423*time + 13.7215)/(0.846038*time + 31.9867); // mm
@@ -188,11 +208,50 @@ public RealMatrix get_MeasurementNoise() {
188208
//return new Array2DRowRealMatrix(new double[][]{{0.09}});
189209
}
190210

191-
// a signature for KalmanFilter.Hit_beam
192-
public RealVector get_Vector_beam() {
193-
return null;
211+
// Projection function
212+
@Override
213+
public RealVector getProjectionVector(RealVector x) {
214+
double d = this.distance(new Point3D(x.getEntry(0), x.getEntry(1), x.getEntry(2)));
215+
return MatrixUtils.createRealVector(new double[]{d});
194216
}
195217

218+
@Override
219+
public RealVector getInnovationVector(RealVector x) {
220+
RealVector measured = getMeasurementVector();
221+
RealVector predicted = getProjectionVector(x);
222+
return measured.subtract(predicted);
223+
}
224+
225+
// Jacobian matrix of the measurement with respect to (x, y, z, px, py, pz)
226+
@Override
227+
public RealMatrix getProjectionMatrix(RealVector x) {
228+
229+
double ddocadx = partialProjectionMatrix(x, 0);
230+
double ddocady = partialProjectionMatrix(x, 1);
231+
double ddocadz = partialProjectionMatrix(x, 2);
232+
double ddocadpx = partialProjectionMatrix(x, 3);
233+
double ddocadpy = partialProjectionMatrix(x, 4);
234+
double ddocadpz = partialProjectionMatrix(x, 5);
235+
236+
return MatrixUtils.createRealMatrix(new double[][]{
237+
{ddocadx, ddocady, ddocadz, ddocadpx, ddocadpy, ddocadpz}});
238+
}
239+
240+
private double partialProjectionMatrix(RealVector x, int i) {
241+
double h = 1e-8;// in mm
242+
RealVector x_plus = x.copy();
243+
RealVector x_minus = x.copy();
244+
245+
x_plus.setEntry(i, x_plus.getEntry(i) + h);
246+
x_minus.setEntry(i, x_minus.getEntry(i) - h);
247+
248+
double doca_plus = this.getProjectionVector(x_plus).getEntry(0);
249+
double doca_minus = this.getProjectionVector(x_minus).getEntry(0);
250+
251+
return (doca_plus - doca_minus) / (2 * h);
252+
}
253+
254+
@Override
196255
public double distance(Point3D point3D) {
197256
return this.wireLine.distance(point3D).length();
198257
}

reconstruction/alert/src/main/java/org/jlab/rec/ahdc/KalmanFilter/Hit_beam.java

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.jlab.rec.ahdc.KalmanFilter;
2+
3+
import org.apache.commons.math3.linear.RealMatrix;
4+
import org.apache.commons.math3.linear.RealVector;
5+
import org.jlab.geom.prim.Point3D;
6+
/**
7+
* An interface to unify the hits used the Kalman Filter (e.g AHDC hits, ATOF hits, beamline)
8+
*
9+
* @author Felix Touchte Codjo
10+
*/
11+
public interface KFHit {
12+
public double distance(Point3D point3D);
13+
public double getRadius();
14+
/** Return the measurement encoded in this KFHit */
15+
public RealVector getMeasurementVector();
16+
/** Return the measurement noise matrix for this this KFHit */
17+
public RealMatrix getMeasurementNoiseMatrix();
18+
/** Compute the measurement for a given state vector */
19+
public RealVector getProjectionVector(RealVector x);
20+
/** Compute the Jacobian matrix of the {@link #getProjectionVector(RealVector)} with respect of the components of the state vector */
21+
public RealMatrix getProjectionMatrix(RealVector x);
22+
23+
/**
24+
* Compute the innovation by subtracting {@link #getMeasurementVector()} and {@link #getProjectionVector(RealVector)}
25+
* @param x current state estimation
26+
* @return return the innovation vector
27+
*/
28+
public RealVector getInnovationVector(RealVector x);
29+
}

0 commit comments

Comments
 (0)