Skip to content

Commit 96e0892

Browse files
AHDC: skip raw-hit cut lookups in sim and tidy HitReader
In simulation mode fetch_AHDCHits was still reading the per-wire rawHitCuts table even though the pass/fail result was discarded, which is wasted work and can fail when the sim CCDB run has no cut entries. The cut lookups and pass check are now nested inside the existing !sim branch alongside the ToT and ADC-gain corrections, so sim events go straight from time calibration to DOCA. While in the file: - Drop the rawHitCutsTable/timeOffsetsTable/... instance fields; the IndexedTables are passed through to fetch_AHDCHits and T2Dfunction as parameters, matching how they are used. - Make T2Dfunction / fetch_AHDCHits / fetch_TrueAHDCHits private; nothing outside HitReader calls them. - Collapse the DOCA branch to a single ternary. - Add Javadoc on the class, constructor, calibration pipeline, T2D function, and the hit/true-hit accessors.
1 parent 7d517dc commit 96e0892

1 file changed

Lines changed: 121 additions & 54 deletions

File tree

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

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

Lines changed: 121 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,64 @@
99
import org.jlab.geom.detector.alert.AHDC.AlertDCDetector;
1010
import org.jlab.utils.groups.IndexedTable;
1111

12+
/**
13+
* Reads raw AHDC hits from the {@code AHDC::adc} bank, applies calibration corrections
14+
* (time offsets, time-over-threshold, ADC gains), filters them against per-wire cuts in
15+
* data mode, and builds the list of {@link Hit} objects used by downstream reconstruction.
16+
* In simulation mode, the per-wire cuts and data-only ADC/ToT corrections are bypassed,
17+
* and truth information is additionally read from the {@code MC::True} bank into {@link TrueHit}s.
18+
*/
1219
public class HitReader {
1320

1421
private ArrayList<Hit> _AHDCHits;
1522
private ArrayList<TrueHit> _TrueAHDCHits;
1623
private boolean sim = false;
1724

18-
private IndexedTable rawHitCutsTable;
19-
private IndexedTable timeOffsetsTable;
20-
private IndexedTable timeToDistanceWireTable;
21-
private IndexedTable timeOverThresholdTable;
22-
private IndexedTable adcGainsTable;
23-
24-
public HitReader(DataEvent event, AlertDCDetector detector, boolean simulation,
25-
IndexedTable rawHitCuts,
26-
IndexedTable timeOffsets,
27-
IndexedTable timeToDistanceWire,
28-
IndexedTable timeOverThreshold,
29-
IndexedTable adcGains) {
25+
/**
26+
* Constructs a HitReader and eagerly populates the hit lists from the given event.
27+
* After construction, retrieve the results via {@link #get_AHDCHits()} and
28+
* (in simulation) {@link #get_TrueAHDCHits()}.
29+
*
30+
* @param event current event containing the {@code AHDC::adc} bank (and {@code MC::True} in sim)
31+
* @param detector AHDC geometry used to resolve wire positions on each hit
32+
* @param simulation {@code true} for Monte Carlo events; disables data-only cuts and corrections
33+
* @param rawHitCuts per-wire acceptance cuts (time, ToT, ADC, pedestal min/max)
34+
* @param timeOffsets per-wire {@code t0} offsets applied to the leading-edge time
35+
* @param timeToDistanceWire per-wire T2D calibration coefficients used to convert time to DOCA
36+
* @param timeOverThreshold per-wire ToT correction factors (applied in data mode only)
37+
* @param adcGains per-wire ADC gain corrections (applied in data mode only)
38+
*/
39+
public HitReader(DataEvent event, AlertDCDetector detector, boolean simulation, IndexedTable rawHitCuts, IndexedTable timeOffsets,
40+
IndexedTable timeToDistanceWire, IndexedTable timeOverThreshold, IndexedTable adcGains) {
3041
sim = simulation;
3142
fetch_AHDCHits(event, detector, rawHitCuts, timeOffsets, timeToDistanceWire, timeOverThreshold, adcGains);
3243
if (simulation) fetch_TrueAHDCHits(event);
3344
}
3445

35-
public double T2Dfunction(int sector, int layer, int wire, double time){
36-
long hash = timeToDistanceWireTable.getList().getIndexGenerator().hashCode(sector, layer, wire);
37-
List<Double> t2d = timeToDistanceWireTable.getDoublesByHash(hash);
38-
39-
// T2D function consists of three 1st order polynomials (p1, p2, p3) and two transition functions (t1, t2).
40-
// Column order: p1_int(0), p1_slope(1), p2_int(2), p2_slope(3), p3_int(4), p3_slope(5),
41-
// t1_x0(6), t1_width(7), t2_x0(8), t2_width(9), z0(10), z1(11), z2(12), extra1(13), extra2(14), chi2ndf(15)
46+
/**
47+
* Converts a calibrated drift time into a distance-of-closest-approach (DOCA) for a
48+
* given wire, using the piecewise T2D calibration stored in {@code timeToDistanceWire}.
49+
*
50+
* <p>The result is a blend of three 1st-order polynomials {@code p1, p2, p3} stitched
51+
* together by two logistic transition functions {@code t1, t2}:
52+
* {@code doca = p1·(1-t1) + t1·p2·(1-t2) + t2·p3}. The coefficients are looked up
53+
* once per call via a hashed index on (sector, layer, wire).
54+
*
55+
* <p>Expected column order of the calibration row:
56+
* p1_int(0), p1_slope(1), p2_int(2), p2_slope(3), p3_int(4), p3_slope(5),
57+
* t1_x0(6), t1_width(7), t2_x0(8), t2_width(9), z0(10), z1(11), z2(12),
58+
* extra1(13), extra2(14), chi2ndf(15).
59+
*
60+
* @param sector AHDC sector index
61+
* @param layer packed layer index ({@code superlayer*10 + layer})
62+
* @param wire wire (component) id within the layer
63+
* @param time calibrated drift time in ns
64+
* @param timeToDistanceWire per-wire T2D calibration table
65+
* @return the DOCA in mm
66+
*/
67+
private double T2Dfunction(int sector, int layer, int wire, double time, IndexedTable timeToDistanceWire){
68+
long hash = timeToDistanceWire.getList().getIndexGenerator().hashCode(sector, layer, wire);
69+
List<Double> t2d = timeToDistanceWire.getDoublesByHash(hash);
4270

4371
double p1 = (t2d.get(0) + t2d.get(1)*time);
4472
double p2 = (t2d.get(2) + t2d.get(3)*time);
@@ -50,16 +78,31 @@ public double T2Dfunction(int sector, int layer, int wire, double time){
5078
return (p1)*(1.0 - t1) + (t1)*(p2)*(1.0 - t2) + (t2)*(p3);
5179
}
5280

53-
public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector,
54-
IndexedTable rawHitCuts, IndexedTable timeOffsets,
55-
IndexedTable timeToDistanceWire, IndexedTable totCorrTable,
56-
IndexedTable adcGains) {
57-
this.rawHitCutsTable = rawHitCuts;
58-
this.timeOffsetsTable = timeOffsets;
59-
this.timeToDistanceWireTable = timeToDistanceWire;
60-
this.timeOverThresholdTable = totCorrTable;
61-
this.adcGainsTable = adcGains;
62-
81+
/**
82+
* Reads the {@code AHDC::adc} bank, calibrates each raw row, and builds the list of
83+
* reconstructed {@link Hit}s. For each row the method:
84+
* <ol>
85+
* <li>applies the per-wire time offset {@code t0} (subtracting event start time in data mode),</li>
86+
* <li>in data mode, corrects time-over-threshold and enforces per-wire acceptance cuts
87+
* (time, ToT, ADC, pedestal, and {@code wfType <= 2}) — hits failing the cuts are dropped,</li>
88+
* <li>computes the DOCA from the calibrated time via {@link #T2Dfunction} (DOCA forced to 0
89+
* when {@code time < 0}),</li>
90+
* <li>in data mode, applies the per-wire ADC gain correction,</li>
91+
* <li>instantiates a {@link Hit}, resolves its wire position via the geometry, and stores the
92+
* calibrated ADC and ToT on it.</li>
93+
* </ol>
94+
* The resulting list is stored via {@link #set_AHDCHits(ArrayList)} (empty if the bank is absent).
95+
*
96+
* @param event current event
97+
* @param detector AHDC geometry used to set each hit's wire position
98+
* @param rawHitCuts per-wire acceptance cuts (data mode only)
99+
* @param timeOffsets per-wire {@code t0}
100+
* @param timeToDistanceWire per-wire T2D coefficients
101+
* @param timeOverThresholdTable per-wire ToT correction factors (data mode only)
102+
* @param adcGains per-wire ADC gain corrections (data mode only)
103+
*/
104+
private void fetch_AHDCHits(DataEvent event, AlertDCDetector detector, IndexedTable rawHitCuts, IndexedTable timeOffsets,
105+
IndexedTable timeToDistanceWire, IndexedTable timeOverThresholdTable, IndexedTable adcGains) {
63106
ArrayList<Hit> hits = new ArrayList<>();
64107

65108
if (!event.hasBank("AHDC::adc")) {
@@ -92,45 +135,43 @@ public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector,
92135
double adcOffset = bankDGTZ.getFloat("ped", i);
93136
int wfType = bankDGTZ.getShort("wfType", i);
94137

95-
// Raw hit cuts
96-
double t_min = rawHitCutsTable.getDoubleValue("t_min", sector, number, wire);
97-
double t_max = rawHitCutsTable.getDoubleValue("t_max", sector, number, wire);
98-
double tot_min = rawHitCutsTable.getDoubleValue("tot_min", sector, number, wire);
99-
double tot_max = rawHitCutsTable.getDoubleValue("tot_max", sector, number, wire);
100-
double adc_min = rawHitCutsTable.getDoubleValue("adc_min", sector, number, wire);
101-
double adc_max = rawHitCutsTable.getDoubleValue("adc_max", sector, number, wire);
102-
double ped_min = rawHitCutsTable.getDoubleValue("ped_min", sector, number, wire);
103-
double ped_max = rawHitCutsTable.getDoubleValue("ped_max", sector, number, wire);
104-
105138
// Time calibration
106-
double t0 = timeOffsetsTable.getDoubleValue("t0", sector, number, wire);
139+
double t0 = timeOffsets.getDoubleValue("t0", sector, number, wire);
107140
double time = leadingEdgeTime - t0 - startTime;
108141

109142
// ToT correction
110143
double totUsed = timeOverThreshold;
111144
if (!sim) {
112145
double totCorr = timeOverThresholdTable.getDoubleValue("totCorr", sector, number, wire);
113146
if (totCorr != 0.0) totUsed = timeOverThreshold * totCorr;
114-
}
115-
116-
// Hit selection (cuts)
117-
boolean passCuts =
118-
(wfType <= 2) &&
119-
(adcRaw >= adc_min) && (adcRaw <= adc_max) &&
120-
(time >= t_min) && (time <= t_max) &&
121-
(timeOverThreshold >= tot_min) && (timeOverThreshold <= tot_max) &&
122-
(adcOffset >= ped_min) && (adcOffset <= ped_max);
123147

124-
if (!passCuts && !sim) continue;
148+
// Hit selection (cuts) — only applied on data, bypassed in sim
149+
double t_min = rawHitCuts.getDoubleValue("t_min", sector, number, wire);
150+
double t_max = rawHitCuts.getDoubleValue("t_max", sector, number, wire);
151+
double tot_min = rawHitCuts.getDoubleValue("tot_min", sector, number, wire);
152+
double tot_max = rawHitCuts.getDoubleValue("tot_max", sector, number, wire);
153+
double adc_min = rawHitCuts.getDoubleValue("adc_min", sector, number, wire);
154+
double adc_max = rawHitCuts.getDoubleValue("adc_max", sector, number, wire);
155+
double ped_min = rawHitCuts.getDoubleValue("ped_min", sector, number, wire);
156+
double ped_max = rawHitCuts.getDoubleValue("ped_max", sector, number, wire);
157+
158+
boolean passCuts =
159+
(wfType <= 2) &&
160+
(adcRaw >= adc_min) && (adcRaw <= adc_max) &&
161+
(time >= t_min) && (time <= t_max) &&
162+
(timeOverThreshold >= tot_min) && (timeOverThreshold <= tot_max) &&
163+
(adcOffset >= ped_min) && (adcOffset <= ped_max);
164+
165+
if (!passCuts) continue;
166+
}
125167

126168
// DOCA from calibrated time
127-
double doca = T2Dfunction(sector, number, wire, time);
128-
if (time < 0) doca = 0.0;
169+
double doca = (time < 0) ? 0.0 : T2Dfunction(sector, number, wire, time, timeToDistanceWire);
129170

130171
// ADC gain calibration
131172
double adcCal = adcRaw;
132173
if (!sim) {
133-
double gainCorr = adcGainsTable.getDoubleValue("gainCorr", sector, number, wire);
174+
double gainCorr = adcGains.getDoubleValue("gainCorr", sector, number, wire);
134175
if (gainCorr != 0.0) adcCal = adcRaw * gainCorr;
135176
}
136177

@@ -144,7 +185,15 @@ public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector,
144185
this.set_AHDCHits(hits);
145186
}
146187

147-
public final void fetch_TrueAHDCHits(DataEvent event) {
188+
/**
189+
* Reads Monte-Carlo truth information from the {@code MC::True} bank into a list of
190+
* {@link TrueHit}s (particle id and average hit position/energy). Called only when
191+
* the reader is constructed with {@code simulation = true}. If the bank is absent,
192+
* the resulting list is empty.
193+
*
194+
* @param event current event
195+
*/
196+
private void fetch_TrueAHDCHits(DataEvent event) {
148197

149198
ArrayList<TrueHit> truehits = new ArrayList<>();
150199

@@ -164,18 +213,36 @@ public final void fetch_TrueAHDCHits(DataEvent event) {
164213
this.set_TrueAHDCHits(truehits);
165214
}
166215

216+
/**
217+
* @return the calibrated AHDC hits produced from the current event; never {@code null}
218+
* (empty if the {@code AHDC::adc} bank is missing)
219+
*/
167220
public ArrayList<Hit> get_AHDCHits() {
168221
return _AHDCHits;
169222
}
170223

224+
/**
225+
* Replaces the internally stored list of AHDC hits. Primarily used by {@link #fetch_AHDCHits}.
226+
*
227+
* @param hits the list to store
228+
*/
171229
public void set_AHDCHits(ArrayList<Hit> hits) {
172230
this._AHDCHits = hits;
173231
}
174232

233+
/**
234+
* @return the MC-truth hits for the current event (populated only in simulation mode;
235+
* {@code null} for data events where {@code fetch_TrueAHDCHits} was not called)
236+
*/
175237
public ArrayList<TrueHit> get_TrueAHDCHits() {
176238
return _TrueAHDCHits;
177239
}
178240

241+
/**
242+
* Replaces the internally stored list of MC-truth hits. Primarily used by {@link #fetch_TrueAHDCHits}.
243+
*
244+
* @param trueHits the list to store
245+
*/
179246
public void set_TrueAHDCHits(ArrayList<TrueHit> trueHits) {
180247
this._TrueAHDCHits = trueHits;
181248
}

0 commit comments

Comments
 (0)