From e82e721e438f3dd5a254de6a54e7e7c143a1d665 Mon Sep 17 00:00:00 2001 From: Mathieu Ouillon Date: Tue, 7 Apr 2026 17:19:04 -0400 Subject: [PATCH 1/4] fix: update requireConstants to handle varying column counts in calibration tables --- .../java/org/jlab/service/ahdc/AHDCEngine.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java b/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java index eb3dbdca24..2c7b442801 100644 --- a/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java +++ b/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java @@ -94,10 +94,21 @@ else if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.CV_ "/calibration/alert/atof/attenuation", "/calibration/alert/atof/time_offsets", "/calibration/alert/ahdc/gains", - "/calibration/alert/ahdc/time_over_threshold" + "/calibration/alert/ahdc/time_over_threshold" }; - requireConstants(Arrays.asList(alertTables)); + + // New code to handle the fact that some tables have 3 columns and some have 4 columns + Map tableMap = new HashMap<>(); + for (String table : alertTables) { + if (table.equals("/calibration/alert/atof/time_offsets") || + table.equals("/calibration/alert/atof/time_walk")) { + tableMap.put(table, 4); + } else { + tableMap.put(table, 3); + } + } + requireConstants(tableMap); this.getConstantsManager().setVariation("default"); From b4de3eb9fa988af8ff45478efc82c21bef2396f7 Mon Sep 17 00:00:00 2001 From: MathieuOuillon Date: Wed, 8 Apr 2026 20:12:43 -0400 Subject: [PATCH 2/4] fix: remove CalibrationConstantsLoader and fix calibration reload bugs CalibrationConstantsLoader had three critical issues: 1. CSTLOADED gate prevented reload across runs: once constants loaded for the first run, the flag blocked all subsequent loads. If the data stream (hipo files) switched to a different run number, all engines kept using the first run's calibration. The first event in a files is often run number 0. 2. ATOFEngine never updated its Run field after calling Load(), so the run-change check (Run != newRun) was always true. This would have caused a reload on every event, but bug #1 masked it. 3. All calibration data lived in static HashMap fields shared across engine instances. Not thread-safe. The fix removes CalibrationConstantsLoader entirely. Each engine now: - Holds its own calibration maps as instance fields - Rebuilds them from ConstantsManager (which already caches per run with proper synchronization) only when the run number changes - Passes the maps explicitly to consumer code (HitReader, ATOFHit, BarHit) instead of relying on static access - Only requires its own detector's CCDB tables in init() --- .../java/org/jlab/rec/ahdc/Hit/HitReader.java | 46 ++- .../constants/CalibrationConstantsLoader.java | 304 ------------------ .../java/org/jlab/rec/atof/hit/ATOFHit.java | 15 +- .../java/org/jlab/rec/atof/hit/BarHit.java | 8 +- .../java/org/jlab/rec/atof/hit/HitFinder.java | 9 +- .../org/jlab/service/ahdc/AHDCEngine.java | 152 +++++++-- .../org/jlab/service/alert/ALERTEngine.java | 4 +- .../org/jlab/service/atof/ATOFEngine.java | 124 +++++-- 8 files changed, 267 insertions(+), 395 deletions(-) delete mode 100644 reconstruction/alert/src/main/java/org/jlab/rec/alert/constants/CalibrationConstantsLoader.java diff --git a/reconstruction/alert/src/main/java/org/jlab/rec/ahdc/Hit/HitReader.java b/reconstruction/alert/src/main/java/org/jlab/rec/ahdc/Hit/HitReader.java index f7d2e3d444..89b070141e 100644 --- a/reconstruction/alert/src/main/java/org/jlab/rec/ahdc/Hit/HitReader.java +++ b/reconstruction/alert/src/main/java/org/jlab/rec/ahdc/Hit/HitReader.java @@ -1,12 +1,12 @@ package org.jlab.rec.ahdc.Hit; import java.util.ArrayList; +import java.util.Map; import org.jlab.io.base.DataBank; import org.jlab.io.base.DataEvent; import org.jlab.detector.banks.RawDataBank; import org.jlab.geom.detector.alert.AHDC.AlertDCDetector; -import org.jlab.rec.alert.constants.CalibrationConstantsLoader; public class HitReader { @@ -14,13 +14,23 @@ public class HitReader { private ArrayList _TrueAHDCHits; private boolean sim = false; - public HitReader(DataEvent event, AlertDCDetector detector, boolean simulation) { + public HitReader(DataEvent event, AlertDCDetector detector, boolean simulation, + Map rawHitCuts, + Map timeOffsets, + Map timeToDistance, + Map timeOverThreshold, + Map adcGains) { sim = simulation; - fetch_AHDCHits(event, detector); + fetch_AHDCHits(event, detector, rawHitCuts, timeOffsets, timeToDistance, timeOverThreshold, adcGains); if (simulation) fetch_TrueAHDCHits(event); } - public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector) { + public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector, + Map rawHitCutsMap, + Map timeOffsetsMap, + Map timeToDistanceMap, + Map timeOverThresholdMap, + Map adcGainsMap) { ArrayList hits = new ArrayList<>(); @@ -60,12 +70,9 @@ public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector) { // ----------------------------- // Raw hit cuts // ----------------------------- - // double[] rawHitCuts = CalibrationConstantsLoader.AHDC_RAW_HIT_CUTS.get(key_value); - //if (rawHitCuts == null) continue; - - - double[] rawHitCuts = CalibrationConstantsLoader.AHDC_RAW_HIT_CUTS.get(key_value); - if (rawHitCuts == null) {throw new IllegalStateException("Missing CCDB table /calibration/alert/ahdc/raw_hit_cuts for key=" + key_value+ " (check run/variation + key mapping)"); + double[] rawHitCuts = rawHitCutsMap.get(key_value); + if (rawHitCuts == null) { + throw new IllegalStateException("Missing CCDB table /calibration/alert/ahdc/raw_hit_cuts for key=" + key_value + " (check run/variation + key mapping)"); } double t_min = rawHitCuts[0]; @@ -80,24 +87,15 @@ public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector) { // ----------------------------- // Time calibration + t->d // ----------------------------- - //double[] timeOffsets = CalibrationConstantsLoader.AHDC_TIME_OFFSETS.get(key_value); - //if (timeOffsets == null) continue; - - // double[] timeOffsets = CalibrationConstantsLoader.AHDC_TIME_OFFSETS.get(key_value); - //if (timeOffsets == null) { - //throw new IllegalStateException("Missing AHDC time_offsets for key=" + key_value); - //} - - double[] timeOffsets = CalibrationConstantsLoader.AHDC_TIME_OFFSETS.get(key_value); - + double[] timeOffsets = timeOffsetsMap.get(key_value); if (timeOffsets == null) { - throw new IllegalStateException("Missing CCDB /calibration/alert/ahdc/time_offsets for key=" + key_value + " (check run/variation + key mapping)"); + throw new IllegalStateException("Missing CCDB /calibration/alert/ahdc/time_offsets for key=" + key_value + " (check run/variation + key mapping)"); } - double[] time2distance = CalibrationConstantsLoader.AHDC_TIME_TO_DISTANCE.get(10101); + double[] time2distance = timeToDistanceMap.get(10101); if (time2distance == null) continue; double t0 = timeOffsets[0]; @@ -117,7 +115,7 @@ public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector) { // ----------------------------- double totUsed = timeOverThreshold; if (!sim) { - double[] totArr = CalibrationConstantsLoader.AHDC_TIME_OVER_THRESHOLD.get(key_value); + double[] totArr = timeOverThresholdMap.get(key_value); if (totArr != null && totArr.length > 0) { double totCorr = totArr[0]; totUsed = timeOverThreshold * totCorr; @@ -157,7 +155,7 @@ public final void fetch_AHDCHits(DataEvent event, AlertDCDetector detector) { // ----------------------------- double adcCal = adcRaw; if (!sim) { - double[] gainArr = CalibrationConstantsLoader.AHDC_ADC_GAINS.get(key_value); + double[] gainArr = adcGainsMap.get(key_value); if (gainArr != null && gainArr.length > 0) { double gainCorr = gainArr[0]; adcCal = adcRaw * gainCorr; diff --git a/reconstruction/alert/src/main/java/org/jlab/rec/alert/constants/CalibrationConstantsLoader.java b/reconstruction/alert/src/main/java/org/jlab/rec/alert/constants/CalibrationConstantsLoader.java deleted file mode 100644 index 0da9fef09c..0000000000 --- a/reconstruction/alert/src/main/java/org/jlab/rec/alert/constants/CalibrationConstantsLoader.java +++ /dev/null @@ -1,304 +0,0 @@ -package org.jlab.rec.alert.constants; - -import org.jlab.detector.calib.utils.ConstantsManager; -import org.jlab.detector.calib.utils.DatabaseConstantProvider; -import org.jlab.utils.groups.IndexedTable; - -import java.util.HashMap; -import java.util.Map; - -/** - * This class loads constants from CCDB - * - * inspired by the one of the BAND subsystem - * - * @author ftouchte - */ -public class CalibrationConstantsLoader { - - public CalibrationConstantsLoader() { - // default ctor - } - - public static boolean CSTLOADED = false; - - // Maps for constants from database - // AHDC - public static Map AHDC_TIME_OFFSETS = new HashMap<>(); ///< {t0,dt0,extra1,extra2,chi2ndf} - public static Map AHDC_TIME_TO_DISTANCE = new HashMap<>(); ///< {p0..p5, dp0..dp5, chi2ndf} - public static Map AHDC_RAW_HIT_CUTS = new HashMap<>(); ///< {t_min,t_max,tot_min,tot_max,adc_min,adc_max,ped_min,ped_max} - - // UPDATED SCHEMA: keys (sector,layer,component), columns: gainCorr,dgainCorr,extra1,extra2,extra3 - public static Map AHDC_ADC_GAINS = new HashMap<>(); ///< {gainCorr, dgainCorr, extra1, extra2, extra3} - - // NEW ToT TABLE: keys (sector,layer,component), columns: totCorr,dtotCorr,extra1,extra2,extra3 - public static Map AHDC_TIME_OVER_THRESHOLD = new HashMap<>(); ///< {totCorr, dtotCorr, extra1, extra2, extra3} - - // ATOF - public static Map ATOF_EFFECTIVE_VELOCITY = new HashMap<>(); ///< {veff,dveff,extra1,extra2} - public static Map ATOF_TIME_WALK = new HashMap<>(); ///< {tw0..tw3, dtw0..dtw3, chi2ndf} - public static Map ATOF_ATTENUATION_LENGTH = new HashMap<>(); ///< {attlen,dattlen,extra1,extra2} - public static Map ATOF_TIME_OFFSETS = new HashMap<>(); ///< {t0,upstream_downstream,wedge_bar,extra1,extra2} - - public static synchronized void Load(int runno, ConstantsManager manager) { - - if (CSTLOADED) return; - - IndexedTable ahdc_timeOffsets = manager.getConstants(runno, "/calibration/alert/ahdc/time_offsets"); - IndexedTable ahdc_time2distance = manager.getConstants(runno, "/calibration/alert/ahdc/time_to_distance"); - IndexedTable ahdc_rawHitCuts = manager.getConstants(runno, "/calibration/alert/ahdc/raw_hit_cuts"); - - // Gains table (UPDATED SCHEMA) - IndexedTable ahdc_adcGains = manager.getConstants(runno, "/calibration/alert/ahdc/gains"); - - // NEW ToT table - IndexedTable ahdc_timeOverThreshold = manager.getConstants(runno, "/calibration/alert/ahdc/time_over_threshold"); - - IndexedTable atof_effectiveVelocity = manager.getConstants(runno, "/calibration/alert/atof/effective_velocity"); - IndexedTable atof_timeWalk = manager.getConstants(runno, "/calibration/alert/atof/time_walk"); - IndexedTable atof_attenuationLength = manager.getConstants(runno, "/calibration/alert/atof/attenuation"); - IndexedTable atof_timeOffsets = manager.getConstants(runno, "/calibration/alert/atof/time_offsets"); - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // AHDC time offsets - for (int i = 0; i < ahdc_timeOffsets.getRowCount(); i++) { - int sector = Integer.parseInt((String) ahdc_timeOffsets.getValueAt(i, 0)); - int layer = Integer.parseInt((String) ahdc_timeOffsets.getValueAt(i, 1)); - int component = Integer.parseInt((String) ahdc_timeOffsets.getValueAt(i, 2)); - - double t0 = ahdc_timeOffsets.getDoubleValue("t0", sector, layer, component); - double dt0 = ahdc_timeOffsets.getDoubleValue("dt0", sector, layer, component); - double extra1 = ahdc_timeOffsets.getDoubleValue("extra1", sector, layer, component); - double extra2 = ahdc_timeOffsets.getDoubleValue("extra2", sector, layer, component); - double chi2ndf = ahdc_timeOffsets.getDoubleValue("chi2ndf", sector, layer, component); - - int key = sector * 10000 + layer * 100 + component; - double params[] = { t0, dt0, extra1, extra2, chi2ndf }; - AHDC_TIME_OFFSETS.put(Integer.valueOf(key), params); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // AHDC time to distance - // Caution, this table has only one row - // the corresponding identifiers are (sector, layer, component) == (1,1,1) - // but it applies for all AHDC wires ! - for (int i = 0; i < ahdc_time2distance.getRowCount(); i++) { - int sector = Integer.parseInt((String) ahdc_time2distance.getValueAt(i, 0)); - int layer = Integer.parseInt((String) ahdc_time2distance.getValueAt(i, 1)); - int component = Integer.parseInt((String) ahdc_time2distance.getValueAt(i, 2)); - - double p0 = ahdc_time2distance.getDoubleValue("p0", sector, layer, component); - double p1 = ahdc_time2distance.getDoubleValue("p1", sector, layer, component); - double p2 = ahdc_time2distance.getDoubleValue("p2", sector, layer, component); - double p3 = ahdc_time2distance.getDoubleValue("p3", sector, layer, component); - double p4 = ahdc_time2distance.getDoubleValue("p4", sector, layer, component); - double p5 = ahdc_time2distance.getDoubleValue("p5", sector, layer, component); - double dp0 = ahdc_time2distance.getDoubleValue("dp0", sector, layer, component); - double dp1 = ahdc_time2distance.getDoubleValue("dp1", sector, layer, component); - double dp2 = ahdc_time2distance.getDoubleValue("dp2", sector, layer, component); - double dp3 = ahdc_time2distance.getDoubleValue("dp3", sector, layer, component); - double dp4 = ahdc_time2distance.getDoubleValue("dp4", sector, layer, component); - double dp5 = ahdc_time2distance.getDoubleValue("dp5", sector, layer, component); - double chi2ndf = ahdc_time2distance.getDoubleValue("chi2ndf", sector, layer, component); - - int key = sector * 10000 + layer * 100 + component; - double params[] = { p0, p1, p2, p3, p4, p5, dp0, dp1, dp2, dp3, dp4, dp5, chi2ndf }; - AHDC_TIME_TO_DISTANCE.put(Integer.valueOf(key), params); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // AHDC raw hit cuts - for (int i = 0; i < ahdc_rawHitCuts.getRowCount(); i++) { - int sector = Integer.parseInt((String) ahdc_rawHitCuts.getValueAt(i, 0)); - int layer = Integer.parseInt((String) ahdc_rawHitCuts.getValueAt(i, 1)); - int component = Integer.parseInt((String) ahdc_rawHitCuts.getValueAt(i, 2)); - - double t_min = ahdc_rawHitCuts.getDoubleValue("t_min", sector, layer, component); - double t_max = ahdc_rawHitCuts.getDoubleValue("t_max", sector, layer, component); - double tot_min = ahdc_rawHitCuts.getDoubleValue("tot_min", sector, layer, component); - double tot_max = ahdc_rawHitCuts.getDoubleValue("tot_max", sector, layer, component); - double adc_min = ahdc_rawHitCuts.getDoubleValue("adc_min", sector, layer, component); - double adc_max = ahdc_rawHitCuts.getDoubleValue("adc_max", sector, layer, component); - double ped_min = ahdc_rawHitCuts.getDoubleValue("ped_min", sector, layer, component); - double ped_max = ahdc_rawHitCuts.getDoubleValue("ped_max", sector, layer, component); - - int key = sector * 10000 + layer * 100 + component; - double params[] = { t_min, t_max, tot_min, tot_max, adc_min, adc_max, ped_min, ped_max }; - AHDC_RAW_HIT_CUTS.put(Integer.valueOf(key), params); - } - - - // AHDC ADC gains table - // keys : sector, layer, component - // cols : gainCorr, dgainCorr, extra1, extra2, extra3 - - if (ahdc_adcGains != null) { - for (int i = 0; i < ahdc_adcGains.getRowCount(); i++) { - - int sector = Integer.parseInt((String) ahdc_adcGains.getValueAt(i, 0)); - int layer = Integer.parseInt((String) ahdc_adcGains.getValueAt(i, 1)); - int component = Integer.parseInt((String) ahdc_adcGains.getValueAt(i, 2)); - - double gainCorr = ahdc_adcGains.getDoubleValue("gainCorr", sector, layer, component); - double dgainCorr = ahdc_adcGains.getDoubleValue("dgainCorr", sector, layer, component); - - double extra1 = 0.0, extra2 = 0.0, extra3 = 0.0; - try { extra1 = ahdc_adcGains.getDoubleValue("extra1", sector, layer, component); } catch (Exception e) {} - try { extra2 = ahdc_adcGains.getDoubleValue("extra2", sector, layer, component); } catch (Exception e) {} - try { extra3 = ahdc_adcGains.getDoubleValue("extra3", sector, layer, component); } catch (Exception e) {} - - int key = sector * 10000 + layer * 100 + component; - AHDC_ADC_GAINS.put(key, new double[]{gainCorr, dgainCorr, extra1, extra2, extra3}); - } -} - -/////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// AHDC time_over_threshold (NEW TABLE) -// keys : sector, layer, component -// columns: totCorr, dtotCorr, extra1, extra2, extra3 - -// always clear so behavior is deterministic if Load() is ever called again -AHDC_TIME_OVER_THRESHOLD.clear(); - -// Table may not exist for some runs/variations -> treat as "no correction" -if (ahdc_timeOverThreshold != null) { - - for (int i = 0; i < ahdc_timeOverThreshold.getRowCount(); i++) { - int sector = Integer.parseInt((String) ahdc_timeOverThreshold.getValueAt(i, 0)); - int layer = Integer.parseInt((String) ahdc_timeOverThreshold.getValueAt(i, 1)); - int component = Integer.parseInt((String) ahdc_timeOverThreshold.getValueAt(i, 2)); - - double totCorr = ahdc_timeOverThreshold.getDoubleValue("totCorr", sector, layer, component); - double dtotCorr = ahdc_timeOverThreshold.getDoubleValue("dtotCorr", sector, layer, component); - - double extra1 = 0.0, extra2 = 0.0, extra3 = 0.0; - try { extra1 = ahdc_timeOverThreshold.getDoubleValue("extra1", sector, layer, component); } catch (Exception e) {} - try { extra2 = ahdc_timeOverThreshold.getDoubleValue("extra2", sector, layer, component); } catch (Exception e) {} - try { extra3 = ahdc_timeOverThreshold.getDoubleValue("extra3", sector, layer, component); } catch (Exception e) {} - - int key = sector * 10000 + layer * 100 + component; - double[] params = { totCorr, dtotCorr, extra1, extra2, extra3 }; - AHDC_TIME_OVER_THRESHOLD.put(Integer.valueOf(key), params); - } -} - - - - - - - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // AHDC time_over_threshold (NEW TABLE) - // keys : sector, layer, component - // columns: totCorr, dtotCorr, extra1, extra2, extra3 -// for (int i = 0; i < ahdc_timeOverThreshold.getRowCount(); i++) { -// int sector = Integer.parseInt((String) ahdc_timeOverThreshold.getValueAt(i, 0)); -// int layer = Integer.parseInt((String) ahdc_timeOverThreshold.getValueAt(i, 1)); -// int component = Integer.parseInt((String) ahdc_timeOverThreshold.getValueAt(i, 2)); -// -// double totCorr = ahdc_timeOverThreshold.getDoubleValue("totCorr", sector, layer, component); -// double dtotCorr = ahdc_timeOverThreshold.getDoubleValue("dtotCorr", sector, layer, component); - -// double extra1 = 0.0, extra2 = 0.0, extra3 = 0.0; -// try { extra1 = ahdc_timeOverThreshold.getDoubleValue("extra1", sector, layer, component); } catch (Exception e) {} -//// try { extra2 = ahdc_timeOverThreshold.getDoubleValue("extra2", sector, layer, component); } catch (Exception e) {} -// try { extra3 = ahdc_timeOverThreshold.getDoubleValue("extra3", sector, layer, component); } catch (Exception e) {} - -// int key = sector * 10000 + layer * 100 + component; -// double params[] = { totCorr, dtotCorr, extra1, extra2, extra3 }; -// AHDC_TIME_OVER_THRESHOLD.put(Integer.valueOf(key), params); -// } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ATOF effective velocity - for (int i = 0; i < atof_effectiveVelocity.getRowCount(); i++) { - int sector = Integer.parseInt((String) atof_effectiveVelocity.getValueAt(i, 0)); - int layer = Integer.parseInt((String) atof_effectiveVelocity.getValueAt(i, 1)); - int component = Integer.parseInt((String) atof_effectiveVelocity.getValueAt(i, 2)); - - double veff = atof_effectiveVelocity.getDoubleValue("veff", sector, layer, component); - double dveff = atof_effectiveVelocity.getDoubleValue("dveff", sector, layer, component); - double extra1 = atof_effectiveVelocity.getDoubleValue("extra1", sector, layer, component); - double extra2 = atof_effectiveVelocity.getDoubleValue("extra2", sector, layer, component); - - int key = sector * 10000 + layer * 1000 + component * 10; - double params[] = { veff, dveff, extra1, extra2 }; - ATOF_EFFECTIVE_VELOCITY.put(Integer.valueOf(key), params); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ATOF time walk - for (int i = 0; i < atof_timeWalk.getRowCount(); i++) { - int sector = Integer.parseInt((String) atof_timeWalk.getValueAt(i, 0)); - int layer = Integer.parseInt((String) atof_timeWalk.getValueAt(i, 1)); - int component = Integer.parseInt((String) atof_timeWalk.getValueAt(i, 2)); - int order = Integer.parseInt((String) atof_timeWalk.getValueAt(i, 3)); - - double tw0 = atof_timeWalk.getDoubleValue("tw0", sector, layer, component, order); - double tw1 = atof_timeWalk.getDoubleValue("tw1", sector, layer, component, order); - double tw2 = atof_timeWalk.getDoubleValue("tw2", sector, layer, component, order); - double tw3 = atof_timeWalk.getDoubleValue("tw3", sector, layer, component, order); - double dtw0 = atof_timeWalk.getDoubleValue("dtw0", sector, layer, component, order); - double dtw1 = atof_timeWalk.getDoubleValue("dtw1", sector, layer, component, order); - double dtw2 = atof_timeWalk.getDoubleValue("dtw2", sector, layer, component, order); - double dtw3 = atof_timeWalk.getDoubleValue("dtw3", sector, layer, component, order); - double chi2ndf = atof_timeWalk.getDoubleValue("chi2ndf", sector, layer, component, order); - - int key = sector * 10000 + layer * 1000 + component * 10 + order; - double params[] = { tw0, tw1, tw2, tw3, dtw0, dtw1, dtw2, dtw3, chi2ndf }; - ATOF_TIME_WALK.put(Integer.valueOf(key), params); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ATOF attenuation length - for (int i = 0; i < atof_attenuationLength.getRowCount(); i++) { - int sector = Integer.parseInt((String) atof_attenuationLength.getValueAt(i, 0)); - int layer = Integer.parseInt((String) atof_attenuationLength.getValueAt(i, 1)); - int component = Integer.parseInt((String) atof_attenuationLength.getValueAt(i, 2)); - - double attlen = atof_attenuationLength.getDoubleValue("attlen", sector, layer, component); - double dattlen = atof_attenuationLength.getDoubleValue("dattlen", sector, layer, component); - double extra1 = atof_attenuationLength.getDoubleValue("extra1", sector, layer, component); - double extra2 = atof_attenuationLength.getDoubleValue("extra2", sector, layer, component); - - int key = sector * 10000 + layer * 1000 + component * 10; - double params[] = { attlen, dattlen, extra1, extra2 }; - ATOF_ATTENUATION_LENGTH.put(Integer.valueOf(key), params); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // ATOF time offsets - for (int i = 0; i < atof_timeOffsets.getRowCount(); i++) { - int sector = Integer.parseInt((String) atof_timeOffsets.getValueAt(i, 0)); - int layer = Integer.parseInt((String) atof_timeOffsets.getValueAt(i, 1)); - int component = Integer.parseInt((String) atof_timeOffsets.getValueAt(i, 2)); - int order = Integer.parseInt((String) atof_timeOffsets.getValueAt(i, 3)); // we have to use it here ! - - double t0 = atof_timeOffsets.getDoubleValue("t0", sector, layer, component, order); - double upstream_downstream = atof_timeOffsets.getDoubleValue("upstream_downstream", sector, layer, component, order); - double wedge_bar = atof_timeOffsets.getDoubleValue("wedge_bar", sector, layer, component, order); - double extra1 = atof_timeOffsets.getDoubleValue("extra1", sector, layer, component, order); - double extra2 = atof_timeOffsets.getDoubleValue("extra2", sector, layer, component, order); - - int key = sector * 10000 + layer * 1000 + component * 10 + order; - double params[] = { t0, upstream_downstream, wedge_bar, extra1, extra2 }; - ATOF_TIME_OFFSETS.put(Integer.valueOf(key), params); - } - - CSTLOADED = true; - } - - private static DatabaseConstantProvider DB; - - public static final DatabaseConstantProvider getDB() { - return DB; - } - - public static final void setDB(DatabaseConstantProvider dB) { - DB = dB; - } - - public static void main(String arg[]) { - } -} diff --git a/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/ATOFHit.java b/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/ATOFHit.java index 81f1d6dc17..9878f65f00 100644 --- a/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/ATOFHit.java +++ b/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/ATOFHit.java @@ -3,8 +3,8 @@ import org.jlab.geom.base.*; import org.jlab.geom.prim.Point3D; import org.jlab.rec.atof.constants.Parameters; +import java.util.Map; import java.util.logging.Logger; -import org.jlab.rec.alert.constants.CalibrationConstantsLoader; /** * @@ -27,6 +27,7 @@ public class ATOFHit { private boolean isInACluster; private int associatedClusterIndex; int idTDC; + private Map atofTimeOffsets; public int getSector() { @@ -196,11 +197,13 @@ public final int convertTdcToTime() { if(this.startTime!= null) this.time -= this.startTime; //TODO: When table structure evolves, pay attention to order. - //Key for the current channel + //Key for the current channel int key = this.sector*10000 + this.layer*1000 + this.component*10 + 0;//this.order; - + //Time offsets - double[] timeOffsets = CalibrationConstantsLoader.ATOF_TIME_OFFSETS.get(key); + if (atofTimeOffsets == null) return 0; + double[] timeOffsets = atofTimeOffsets.get(key); + if (timeOffsets == null) return 1; double t0 = timeOffsets[0]; //tud is used to store the bar up - bar down alignment @@ -403,7 +406,8 @@ public double getPhi() { * @param atof Detector object representing the atof, used to calculate * spatial coordinates. */ - public ATOFHit(int sector, int layer, int component, int order, int tdc, int tot, Float startTime, Detector atof) { + public ATOFHit(int sector, int layer, int component, int order, int tdc, int tot, Float startTime, Detector atof, + Map atofTimeOffsets) { this.sector = sector; this.layer = layer; this.component = component; @@ -411,6 +415,7 @@ public ATOFHit(int sector, int layer, int component, int order, int tdc, int tot this.tdc = tdc; this.tot = tot; this.startTime = startTime; + this.atofTimeOffsets = atofTimeOffsets; this.isInACluster = false; this.makeType(); diff --git a/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/BarHit.java b/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/BarHit.java index eba7640c4b..2084dcbe35 100644 --- a/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/BarHit.java +++ b/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/BarHit.java @@ -1,9 +1,9 @@ package org.jlab.rec.atof.hit; +import java.util.Map; import org.jlab.io.base.DataEvent; import org.jlab.io.hipo.HipoDataSource; import org.jlab.rec.atof.constants.Parameters; -import org.jlab.rec.alert.constants.CalibrationConstantsLoader; /** * @@ -106,7 +106,7 @@ public final void computeEnergy() { this.setEnergy(Edep_up + Edep_down); } - public BarHit(ATOFHit hit_down, ATOFHit hit_up) { + public BarHit(ATOFHit hit_down, ATOFHit hit_up, Map atofEffectiveVelocity) { boolean hits_match = hit_down.matchBar(hit_up); if (!hits_match) { throw new UnsupportedOperationException("Hits do not match \n"); @@ -120,10 +120,10 @@ public BarHit(ATOFHit hit_down, ATOFHit hit_up) { this.setComponent(10); this.setX(hit_up.getX()); this.setY(hit_up.getY()); - + //CCDB readout for the effective velocity int key = this.getSector()*10000 + this.getLayer()*1000 + this.getComponent()*10; - double[] vEffTable = CalibrationConstantsLoader.ATOF_EFFECTIVE_VELOCITY.get(key); + double[] vEffTable = atofEffectiveVelocity.get(key); this.vEff = vEffTable[0]; this.computeZ(); this.computeTime(); diff --git a/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/HitFinder.java b/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/HitFinder.java index 1f7c04e901..13f17d9454 100644 --- a/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/HitFinder.java +++ b/reconstruction/alert/src/main/java/org/jlab/rec/atof/hit/HitFinder.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.Collections; +import java.util.Map; import org.jlab.geom.base.Detector; import org.jlab.io.base.DataBank; import org.jlab.io.base.DataEvent; @@ -63,7 +64,9 @@ public void setWedgeHits(ArrayList wedge_hits) { * @param atof the {@link Detector} representing the atof geometry to match * the sector/layer/component to x/y/z. */ - public void findHits(DataEvent event, Detector atof, Float startTime) { + public void findHits(DataEvent event, Detector atof, Float startTime, + Map atofTimeOffsets, + Map atofEffectiveVelocity) { //For each event a list of bar hits and a list of wedge hits are filled this.barHits.clear(); this.wedgeHits.clear(); @@ -89,7 +92,7 @@ public void findHits(DataEvent event, Detector atof, Float startTime) { int tot = bank.getInt("ToT", i); //Building a Hit - ATOFHit hit = new ATOFHit(sector, layer, component, order, tdc, tot, startTime, atof); + ATOFHit hit = new ATOFHit(sector, layer, component, order, tdc, tot, startTime, atof, atofTimeOffsets); if (hit.getEnergy() < 0.01) { continue; //energy threshold } @@ -124,7 +127,7 @@ public void findHits(DataEvent event, Detector atof, Float startTime) { //Matching the hits: if same module and different order, they make up a bar hit if (this_hit_up.matchBar(this_hit_down)) { //Bar hits are matched to ahdc tracks and listed - BarHit this_bar_hit = new BarHit(this_hit_down, this_hit_up); + BarHit this_bar_hit = new BarHit(this_hit_down, this_hit_up, atofEffectiveVelocity); //Only add bar hits for which the time sum is in time if(!this_bar_hit.isInTime()) continue; this.barHits.add(this_bar_hit); diff --git a/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java b/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java index 2c7b442801..9e3d01e2ef 100644 --- a/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java +++ b/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java @@ -27,9 +27,10 @@ import java.util.logging.Logger; import org.jlab.detector.calib.utils.DatabaseConstantProvider; +import org.jlab.detector.calib.utils.ConstantsManager; import org.jlab.geom.detector.alert.AHDC.AlertDCDetector; import org.jlab.geom.detector.alert.AHDC.AlertDCFactory; -import org.jlab.rec.alert.constants.CalibrationConstantsLoader; +import org.jlab.utils.groups.IndexedTable; import org.jlab.detector.pulse.ModeAHDC; /** AHDCEngine reconstruction service. @@ -56,6 +57,13 @@ public class AHDCEngine extends ReconstructionEngine { private AlertDCDetector factory = null; private ModeAHDC ahdcExtractor = new ModeAHDC(); + // AHDC calibration maps (instance-level, rebuilt on run change) + private Map ahdcTimeOffsets; + private Map ahdcTimeToDistance; + private Map ahdcRawHitCuts; + private Map ahdcAdcGains; + private Map ahdcTimeOverThreshold; + public AHDCEngine() { super("ALERT", "ouillon", "1.0.1"); } public boolean init(ModeTrackFinding m) { @@ -84,30 +92,13 @@ else if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.CV_ modelTrackFinding = new ModelTrackFinding(); } - // Requires calibration constants - String[] alertTables = new String[] { - "/calibration/alert/ahdc/time_offsets", - "/calibration/alert/ahdc/time_to_distance", - "/calibration/alert/ahdc/raw_hit_cuts", - "/calibration/alert/atof/effective_velocity", - "/calibration/alert/atof/time_walk", - "/calibration/alert/atof/attenuation", - "/calibration/alert/atof/time_offsets", - "/calibration/alert/ahdc/gains", - "/calibration/alert/ahdc/time_over_threshold" - - }; - - // New code to handle the fact that some tables have 3 columns and some have 4 columns + // Requires AHDC calibration constants Map tableMap = new HashMap<>(); - for (String table : alertTables) { - if (table.equals("/calibration/alert/atof/time_offsets") || - table.equals("/calibration/alert/atof/time_walk")) { - tableMap.put(table, 4); - } else { - tableMap.put(table, 3); - } - } + tableMap.put("/calibration/alert/ahdc/time_offsets", 3); + tableMap.put("/calibration/alert/ahdc/time_to_distance", 3); + tableMap.put("/calibration/alert/ahdc/raw_hit_cuts", 3); + tableMap.put("/calibration/alert/ahdc/gains", 3); + tableMap.put("/calibration/alert/ahdc/time_over_threshold", 3); requireConstants(tableMap); this.getConstantsManager().setVariation("default"); @@ -119,6 +110,112 @@ else if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.CV_ int Run = -1; + private void loadAHDCConstants(int run) { + ConstantsManager manager = this.getConstantsManager(); + + IndexedTable tblTimeOffsets = manager.getConstants(run, "/calibration/alert/ahdc/time_offsets"); + IndexedTable tblTime2Dist = manager.getConstants(run, "/calibration/alert/ahdc/time_to_distance"); + IndexedTable tblRawHitCuts = manager.getConstants(run, "/calibration/alert/ahdc/raw_hit_cuts"); + IndexedTable tblAdcGains = manager.getConstants(run, "/calibration/alert/ahdc/gains"); + IndexedTable tblTimeOverThreshold = manager.getConstants(run, "/calibration/alert/ahdc/time_over_threshold"); + + ahdcTimeOffsets = new HashMap<>(); + ahdcTimeToDistance = new HashMap<>(); + ahdcRawHitCuts = new HashMap<>(); + ahdcAdcGains = new HashMap<>(); + ahdcTimeOverThreshold = new HashMap<>(); + + // Time offsets + for (int i = 0; i < tblTimeOffsets.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblTimeOffsets.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblTimeOffsets.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblTimeOffsets.getValueAt(i, 2)); + int key = sector * 10000 + layer * 100 + component; + ahdcTimeOffsets.put(key, new double[]{ + tblTimeOffsets.getDoubleValue("t0", sector, layer, component), + tblTimeOffsets.getDoubleValue("dt0", sector, layer, component), + tblTimeOffsets.getDoubleValue("extra1", sector, layer, component), + tblTimeOffsets.getDoubleValue("extra2", sector, layer, component), + tblTimeOffsets.getDoubleValue("chi2ndf", sector, layer, component) + }); + } + + // Time to distance + for (int i = 0; i < tblTime2Dist.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblTime2Dist.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblTime2Dist.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblTime2Dist.getValueAt(i, 2)); + int key = sector * 10000 + layer * 100 + component; + ahdcTimeToDistance.put(key, new double[]{ + tblTime2Dist.getDoubleValue("p0", sector, layer, component), + tblTime2Dist.getDoubleValue("p1", sector, layer, component), + tblTime2Dist.getDoubleValue("p2", sector, layer, component), + tblTime2Dist.getDoubleValue("p3", sector, layer, component), + tblTime2Dist.getDoubleValue("p4", sector, layer, component), + tblTime2Dist.getDoubleValue("p5", sector, layer, component), + tblTime2Dist.getDoubleValue("dp0", sector, layer, component), + tblTime2Dist.getDoubleValue("dp1", sector, layer, component), + tblTime2Dist.getDoubleValue("dp2", sector, layer, component), + tblTime2Dist.getDoubleValue("dp3", sector, layer, component), + tblTime2Dist.getDoubleValue("dp4", sector, layer, component), + tblTime2Dist.getDoubleValue("dp5", sector, layer, component), + tblTime2Dist.getDoubleValue("chi2ndf", sector, layer, component) + }); + } + + // Raw hit cuts + for (int i = 0; i < tblRawHitCuts.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblRawHitCuts.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblRawHitCuts.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblRawHitCuts.getValueAt(i, 2)); + int key = sector * 10000 + layer * 100 + component; + ahdcRawHitCuts.put(key, new double[]{ + tblRawHitCuts.getDoubleValue("t_min", sector, layer, component), + tblRawHitCuts.getDoubleValue("t_max", sector, layer, component), + tblRawHitCuts.getDoubleValue("tot_min", sector, layer, component), + tblRawHitCuts.getDoubleValue("tot_max", sector, layer, component), + tblRawHitCuts.getDoubleValue("adc_min", sector, layer, component), + tblRawHitCuts.getDoubleValue("adc_max", sector, layer, component), + tblRawHitCuts.getDoubleValue("ped_min", sector, layer, component), + tblRawHitCuts.getDoubleValue("ped_max", sector, layer, component) + }); + } + + // ADC gains + for (int i = 0; i < tblAdcGains.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblAdcGains.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblAdcGains.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblAdcGains.getValueAt(i, 2)); + int key = sector * 10000 + layer * 100 + component; + double extra1 = 0.0, extra2 = 0.0, extra3 = 0.0; + try { extra1 = tblAdcGains.getDoubleValue("extra1", sector, layer, component); } catch (Exception e) {} + try { extra2 = tblAdcGains.getDoubleValue("extra2", sector, layer, component); } catch (Exception e) {} + try { extra3 = tblAdcGains.getDoubleValue("extra3", sector, layer, component); } catch (Exception e) {} + ahdcAdcGains.put(key, new double[]{ + tblAdcGains.getDoubleValue("gainCorr", sector, layer, component), + tblAdcGains.getDoubleValue("dgainCorr", sector, layer, component), + extra1, extra2, extra3 + }); + } + + // Time over threshold + for (int i = 0; i < tblTimeOverThreshold.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblTimeOverThreshold.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblTimeOverThreshold.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblTimeOverThreshold.getValueAt(i, 2)); + int key = sector * 10000 + layer * 100 + component; + double extra1 = 0.0, extra2 = 0.0, extra3 = 0.0; + try { extra1 = tblTimeOverThreshold.getDoubleValue("extra1", sector, layer, component); } catch (Exception e) {} + try { extra2 = tblTimeOverThreshold.getDoubleValue("extra2", sector, layer, component); } catch (Exception e) {} + try { extra3 = tblTimeOverThreshold.getDoubleValue("extra3", sector, layer, component); } catch (Exception e) {} + ahdcTimeOverThreshold.put(key, new double[]{ + tblTimeOverThreshold.getDoubleValue("totCorr", sector, layer, component), + tblTimeOverThreshold.getDoubleValue("dtotCorr", sector, layer, component), + extra1, extra2, extra3 + }); + } + } + @Override public boolean processDataEvent(DataEvent event) { @@ -134,9 +231,8 @@ public boolean processDataEvent(DataEvent event) { return false; } // Load the constants - //------------------- if(Run != newRun) { - CalibrationConstantsLoader.Load(newRun, this.getConstantsManager()); + loadAHDCConstants(newRun); Run = newRun; } } @@ -145,7 +241,9 @@ public boolean processDataEvent(DataEvent event) { if (event.hasBank("AHDC::adc")) { // I) Read raw hits - HitReader hitReader = new HitReader(event, factory, simulation); + HitReader hitReader = new HitReader(event, factory, simulation, + ahdcRawHitCuts, ahdcTimeOffsets, ahdcTimeToDistance, + ahdcTimeOverThreshold, ahdcAdcGains); ArrayList AHDC_Hits = hitReader.get_AHDCHits(); // II) Create PreClusters diff --git a/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java b/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java index 5465ec29d8..26bb502758 100644 --- a/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java +++ b/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java @@ -190,7 +190,7 @@ public boolean processDataEvent(DataEvent event) { int layer_pred = (int) pred[1]; int wedge_pred = (int) pred[2]; - ATOFHit hit_pred = new ATOFHit(sector_pred, layer_pred, wedge_pred, 0, 0, 0, 0f, ATOF); + ATOFHit hit_pred = new ATOFHit(sector_pred, layer_pred, wedge_pred, 0, 0, 0, 0f, ATOF, null); double pred_x = hit_pred.getX(); double pred_y = hit_pred.getY(); double pred_z = hit_pred.getZ(); @@ -208,7 +208,7 @@ public boolean processDataEvent(DataEvent event) { int sector = bank_ATOFHits.getInt("sector", k); int layer = bank_ATOFHits.getInt("layer", k); - ATOFHit hit = new ATOFHit(sector, layer, component, 0, 0, 0, 0f, ATOF); + ATOFHit hit = new ATOFHit(sector, layer, component, 0, 0, 0, 0f, ATOF, null); double dx = pred_x - hit.getX(); double dy = pred_y - hit.getY(); diff --git a/reconstruction/alert/src/main/java/org/jlab/service/atof/ATOFEngine.java b/reconstruction/alert/src/main/java/org/jlab/service/atof/ATOFEngine.java index 4b847ff069..acd90a3ed3 100644 --- a/reconstruction/alert/src/main/java/org/jlab/service/atof/ATOFEngine.java +++ b/reconstruction/alert/src/main/java/org/jlab/service/atof/ATOFEngine.java @@ -19,7 +19,8 @@ import org.jlab.rec.atof.hit.ATOFHit; import org.jlab.rec.atof.hit.BarHit; import org.jlab.rec.atof.hit.HitFinder; -import org.jlab.rec.alert.constants.CalibrationConstantsLoader; +import org.jlab.detector.calib.utils.ConstantsManager; +import org.jlab.utils.groups.IndexedTable; /** * Service to return reconstructed ATOF hits and clusters @@ -54,7 +55,91 @@ public Detector getATOF() { } int Run = -1; - + + // ATOF calibration maps (instance-level, rebuilt on run change) + private Map atofEffectiveVelocity; + private Map atofTimeWalk; + private Map atofAttenuationLength; + private Map atofTimeOffsets; + + private void loadATOFConstants(int run) { + ConstantsManager manager = this.getConstantsManager(); + + IndexedTable tblEffVel = manager.getConstants(run, "/calibration/alert/atof/effective_velocity"); + IndexedTable tblTimeWalk = manager.getConstants(run, "/calibration/alert/atof/time_walk"); + IndexedTable tblAttLen = manager.getConstants(run, "/calibration/alert/atof/attenuation"); + IndexedTable tblTimeOff = manager.getConstants(run, "/calibration/alert/atof/time_offsets"); + + atofEffectiveVelocity = new HashMap<>(); + atofTimeWalk = new HashMap<>(); + atofAttenuationLength = new HashMap<>(); + atofTimeOffsets = new HashMap<>(); + + // Effective velocity + for (int i = 0; i < tblEffVel.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblEffVel.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblEffVel.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblEffVel.getValueAt(i, 2)); + int key = sector * 10000 + layer * 1000 + component * 10; + atofEffectiveVelocity.put(key, new double[]{ + tblEffVel.getDoubleValue("veff", sector, layer, component), + tblEffVel.getDoubleValue("dveff", sector, layer, component), + tblEffVel.getDoubleValue("extra1", sector, layer, component), + tblEffVel.getDoubleValue("extra2", sector, layer, component) + }); + } + + // Time walk + for (int i = 0; i < tblTimeWalk.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblTimeWalk.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblTimeWalk.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblTimeWalk.getValueAt(i, 2)); + int order = Integer.parseInt((String) tblTimeWalk.getValueAt(i, 3)); + int key = sector * 10000 + layer * 1000 + component * 10 + order; + atofTimeWalk.put(key, new double[]{ + tblTimeWalk.getDoubleValue("tw0", sector, layer, component, order), + tblTimeWalk.getDoubleValue("tw1", sector, layer, component, order), + tblTimeWalk.getDoubleValue("tw2", sector, layer, component, order), + tblTimeWalk.getDoubleValue("tw3", sector, layer, component, order), + tblTimeWalk.getDoubleValue("dtw0", sector, layer, component, order), + tblTimeWalk.getDoubleValue("dtw1", sector, layer, component, order), + tblTimeWalk.getDoubleValue("dtw2", sector, layer, component, order), + tblTimeWalk.getDoubleValue("dtw3", sector, layer, component, order), + tblTimeWalk.getDoubleValue("chi2ndf", sector, layer, component, order) + }); + } + + // Attenuation length + for (int i = 0; i < tblAttLen.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblAttLen.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblAttLen.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblAttLen.getValueAt(i, 2)); + int key = sector * 10000 + layer * 1000 + component * 10; + atofAttenuationLength.put(key, new double[]{ + tblAttLen.getDoubleValue("attlen", sector, layer, component), + tblAttLen.getDoubleValue("dattlen", sector, layer, component), + tblAttLen.getDoubleValue("extra1", sector, layer, component), + tblAttLen.getDoubleValue("extra2", sector, layer, component) + }); + } + + // Time offsets + for (int i = 0; i < tblTimeOff.getRowCount(); i++) { + int sector = Integer.parseInt((String) tblTimeOff.getValueAt(i, 0)); + int layer = Integer.parseInt((String) tblTimeOff.getValueAt(i, 1)); + int component = Integer.parseInt((String) tblTimeOff.getValueAt(i, 2)); + int order = Integer.parseInt((String) tblTimeOff.getValueAt(i, 3)); + int key = sector * 10000 + layer * 1000 + component * 10 + order; + atofTimeOffsets.put(key, new double[]{ + tblTimeOff.getDoubleValue("t0", sector, layer, component, order), + tblTimeOff.getDoubleValue("upstream_downstream", sector, layer, component, order), + tblTimeOff.getDoubleValue("wedge_bar", sector, layer, component, order), + tblTimeOff.getDoubleValue("extra1", sector, layer, component, order), + tblTimeOff.getDoubleValue("extra2", sector, layer, component, order) + }); + } + } + @Override public boolean processDataEvent(DataEvent event) { if (!event.hasBank("RUN::config")) { @@ -80,11 +165,12 @@ public boolean processDataEvent(DataEvent event) { System.err.println("ATOFEngine: got run <= 0 in RUN::config, skipping event."); return false; } - int newRun = runNo; - // Load the constants + int newRun = runNo; + // Load the constants if(Run!=newRun) { - CalibrationConstantsLoader.Load(newRun, this.getConstantsManager()); - } + loadATOFConstants(newRun); + Run = newRun; + } ////Do we need to read the event vx,vy,vz? ////If not, this part can be moved in the initialization of the engine. @@ -103,7 +189,7 @@ public boolean processDataEvent(DataEvent event) { //Hit finder init HitFinder hitfinder = new HitFinder(); - hitfinder.findHits(event, ATOF, startTime); + hitfinder.findHits(event, ATOF, startTime, atofTimeOffsets, atofEffectiveVelocity); ArrayList WedgeHits = hitfinder.getWedgeHits(); ArrayList BarHits = hitfinder.getBarHits(); //Exit if hit lists are empty @@ -131,26 +217,12 @@ public boolean init() { DatabaseConstantProvider cp = new DatabaseConstantProvider(11, "default"); this.ATOF = factory.createDetectorCLAS(cp); - String[] alertTables = new String[] { - "/calibration/alert/ahdc/time_offsets", - "/calibration/alert/ahdc/time_to_distance", - "/calibration/alert/ahdc/raw_hit_cuts", - "/calibration/alert/atof/effective_velocity", - "/calibration/alert/atof/time_walk", - "/calibration/alert/atof/attenuation", - "/calibration/alert/atof/time_offsets" - }; - + // Requires ATOF calibration constants Map tableMap = new HashMap<>(); - for (String table : alertTables) { - if (table.equals("/calibration/alert/atof/time_offsets") || - table.equals("/calibration/alert/atof/time_walk")) { - tableMap.put(table, 4); - } else { - tableMap.put(table, 3); - } - } - + tableMap.put("/calibration/alert/atof/effective_velocity", 3); + tableMap.put("/calibration/alert/atof/time_walk", 4); + tableMap.put("/calibration/alert/atof/attenuation", 3); + tableMap.put("/calibration/alert/atof/time_offsets", 4); requireConstants(tableMap); this.getConstantsManager().setVariation("default"); this.registerOutputBank("ATOF::hits", "ATOF::clusters"); From 9edb7d487d4aa9e50e6ceb731ad524fee0aac58e Mon Sep 17 00:00:00 2001 From: MathieuOuillon Date: Thu, 9 Apr 2026 09:00:27 -0400 Subject: [PATCH 3/4] fix: streamline mode configuration handling and remove redundant code --- .../org/jlab/service/ahdc/AHDCEngine.java | 46 +++++++------------ 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java b/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java index 9e3d01e2ef..3ab949b355 100644 --- a/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java +++ b/reconstruction/alert/src/main/java/org/jlab/service/ahdc/AHDCEngine.java @@ -64,6 +64,8 @@ public class AHDCEngine extends ReconstructionEngine { private Map ahdcAdcGains; private Map ahdcTimeOverThreshold; + int Run = -1; + public AHDCEngine() { super("ALERT", "ouillon", "1.0.1"); } public boolean init(ModeTrackFinding m) { @@ -79,18 +81,9 @@ public boolean init() { if (materialMap == null) materialMap = MaterialMap.generateMaterials(); - if(this.getEngineConfigString("Mode")!=null) { - if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.AI_Track_Finding.name())) - modeTrackFinding = ModeTrackFinding.AI_Track_Finding; - else if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.CV_Distance.name())) - modeTrackFinding = ModeTrackFinding.CV_Distance; - else if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.CV_Hough.name())) - modeTrackFinding = ModeTrackFinding.CV_Hough; - } - - if (modeTrackFinding == ModeTrackFinding.AI_Track_Finding) { - modelTrackFinding = new ModelTrackFinding(); - } + String modeConfig = this.getEngineConfigString("Mode"); + if (modeConfig != null) modeTrackFinding = ModeTrackFinding.valueOf(modeConfig); + if (modeTrackFinding == ModeTrackFinding.AI_Track_Finding) modelTrackFinding = new ModelTrackFinding(); // Requires AHDC calibration constants Map tableMap = new HashMap<>(); @@ -108,21 +101,20 @@ else if (Objects.equals(this.getEngineConfigString("Mode"), ModeTrackFinding.CV_ return true; } - int Run = -1; - + private void loadAHDCConstants(int run) { ConstantsManager manager = this.getConstantsManager(); - IndexedTable tblTimeOffsets = manager.getConstants(run, "/calibration/alert/ahdc/time_offsets"); - IndexedTable tblTime2Dist = manager.getConstants(run, "/calibration/alert/ahdc/time_to_distance"); - IndexedTable tblRawHitCuts = manager.getConstants(run, "/calibration/alert/ahdc/raw_hit_cuts"); - IndexedTable tblAdcGains = manager.getConstants(run, "/calibration/alert/ahdc/gains"); + IndexedTable tblTimeOffsets = manager.getConstants(run, "/calibration/alert/ahdc/time_offsets"); + IndexedTable tblTime2Dist = manager.getConstants(run, "/calibration/alert/ahdc/time_to_distance"); + IndexedTable tblRawHitCuts = manager.getConstants(run, "/calibration/alert/ahdc/raw_hit_cuts"); + IndexedTable tblAdcGains = manager.getConstants(run, "/calibration/alert/ahdc/gains"); IndexedTable tblTimeOverThreshold = manager.getConstants(run, "/calibration/alert/ahdc/time_over_threshold"); - ahdcTimeOffsets = new HashMap<>(); - ahdcTimeToDistance = new HashMap<>(); - ahdcRawHitCuts = new HashMap<>(); - ahdcAdcGains = new HashMap<>(); + ahdcTimeOffsets = new HashMap<>(); + ahdcTimeToDistance = new HashMap<>(); + ahdcRawHitCuts = new HashMap<>(); + ahdcAdcGains = new HashMap<>(); ahdcTimeOverThreshold = new HashMap<>(); // Time offsets @@ -187,6 +179,8 @@ private void loadAHDCConstants(int run) { int layer = Integer.parseInt((String) tblAdcGains.getValueAt(i, 1)); int component = Integer.parseInt((String) tblAdcGains.getValueAt(i, 2)); int key = sector * 10000 + layer * 100 + component; + + // TODO: Try and catch here that is weird no? double extra1 = 0.0, extra2 = 0.0, extra3 = 0.0; try { extra1 = tblAdcGains.getDoubleValue("extra1", sector, layer, component); } catch (Exception e) {} try { extra2 = tblAdcGains.getDoubleValue("extra2", sector, layer, component); } catch (Exception e) {} @@ -237,13 +231,9 @@ public boolean processDataEvent(DataEvent event) { } } - - if (event.hasBank("AHDC::adc")) { // I) Read raw hits - HitReader hitReader = new HitReader(event, factory, simulation, - ahdcRawHitCuts, ahdcTimeOffsets, ahdcTimeToDistance, - ahdcTimeOverThreshold, ahdcAdcGains); + HitReader hitReader = new HitReader(event, factory, simulation, ahdcRawHitCuts, ahdcTimeOffsets, ahdcTimeToDistance, ahdcTimeOverThreshold, ahdcAdcGains); ArrayList AHDC_Hits = hitReader.get_AHDCHits(); // II) Create PreClusters @@ -360,7 +350,6 @@ else if (modeTrackFinding == ModeTrackFinding.CV_Hough) { all_interclusters.addAll(track.getInterclusters()); } DataBank recoInterClusterBank = writer.fillInterClusterBank(event, all_interclusters); - // DataBank AIPredictionBanks = writer.fillAIPrediction(event, predictions); //event.removeBanks("AHDC::hits","AHDC::preclusters","AHDC::clusters","AHDC::track","AHDC::kftrack","AHDC::mc","AHDC::ai:prediction"); event.appendBank(recoHitsBank); @@ -369,7 +358,6 @@ else if (modeTrackFinding == ModeTrackFinding.CV_Hough) { event.appendBank(recoTracksBank); event.appendBank(recoInterClusterBank); event.appendBank(clustersDocaBank); - // event.appendBank(AIPredictionBanks); if (simulation) { DataBank recoMCBank = writer.fillAHDCMCTrackBank(event); From fabcaf3995e45c7ed1a5d03a9863ae1385a2bbc6 Mon Sep 17 00:00:00 2001 From: MathieuOuillon Date: Thu, 9 Apr 2026 09:03:38 -0400 Subject: [PATCH 4/4] fix: guard against empty hit list in ALERTEngine Kalman filter loop --- .../alert/src/main/java/org/jlab/service/alert/ALERTEngine.java | 1 + 1 file changed, 1 insertion(+) diff --git a/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java b/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java index 26bb502758..d1d56b647a 100644 --- a/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java +++ b/reconstruction/alert/src/main/java/org/jlab/service/alert/ALERTEngine.java @@ -346,6 +346,7 @@ public boolean processDataEvent(DataEvent event) { AHDC_hits.add(hit); } } + if (AHDC_hits.isEmpty()) continue; // It can happen that a track has no associated hit, in this case we skip it for the Kalman Filter AHDC_tracks.add(new Track(AHDC_hits)); // Initialise the position and the momentum using the information of the AHDC::track // position : mm