From fb80ca30840b7652f5262a68e6f93cf872e96cfc Mon Sep 17 00:00:00 2001 From: N-Plx Date: Tue, 20 Jan 2026 14:44:59 -0600 Subject: [PATCH] Updating how time offsets are applied, dealing with different start times --- .../java/org/jlab/rec/atof/hit/ATOFHit.java | 35 +++++----------- .../java/org/jlab/rec/atof/hit/BarHit.java | 40 +++++++++++-------- .../java/org/jlab/rec/atof/hit/HitFinder.java | 3 +- .../org/jlab/service/alert/ALERTEngine.java | 7 +--- .../org/jlab/service/atof/ATOFEngine.java | 5 +-- 5 files changed, 38 insertions(+), 52 deletions(-) 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 95a4d52584..81f1d6dc17 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 @@ -21,12 +21,11 @@ public class ATOFHit { private int sector, layer, component, order; private int tdc, tot; - private float startTime; + private Float startTime; private double time, energy, x, y, z; private String type; private boolean isInACluster; private int associatedClusterIndex; - private double meanTimeAligned; int idTDC; @@ -82,13 +81,9 @@ public double getTime() { return time; } - public double getStartTime() { + public Float getStartTime() { return this.startTime; } - - public double getMeanTimeAligned(){ - return this.meanTimeAligned; - } public void setTime(double time) { this.time = time; @@ -195,27 +190,18 @@ public final String makeType() { * unsupported. */ public final int convertTdcToTime() { - //Converting tdc to ns, event start time correction - this.time = Parameters.TDC2TIME*this.tdc - this.startTime; + this.time = Parameters.TDC2TIME*this.tdc; + //If the startTime has been defined, remove it + if(this.startTime!= null) this.time -= this.startTime; //TODO: When table structure evolves, pay attention to order. //Key for the current channel int key = this.sector*10000 + this.layer*1000 + this.component*10 + 0;//this.order; - //Key for the reference channel over which all the others sharing the same z are aligned - int referenceModuleKey = this.component*10; //Time offsets double[] timeOffsets = CalibrationConstantsLoader.ATOF_TIME_OFFSETS.get(key); - double[] timeOffsetsRef = CalibrationConstantsLoader.ATOF_TIME_OFFSETS.get(referenceModuleKey); - this.meanTimeAligned = timeOffsetsRef[0]; - //The names below correspond to the CCDB entries - //They will most probably evolve - //For now let's say t0 is used to store the bar-to-bar and wedge-to-wedge alignments double t0 = timeOffsets[0]; - double tChannelToChannelPhiAlignment = (t0 - this.meanTimeAligned); - if(this.type=="bar up" || this.type=="bar down") //bar alignment is done with the sum of the two times - tChannelToChannelPhiAlignment=tChannelToChannelPhiAlignment/2.; //tud is used to store the bar up - bar down alignment double tud = timeOffsets[1]; @@ -237,8 +223,6 @@ public final int convertTdcToTime() { double dtw3 = timeWalks[7]; double chi2ndf = timeWalks[8];*/ - //Veff corrections TO BE IMPLEMENTED - double veff, distance_to_sipm, timeOffset; if (null == this.type) { LOGGER.finest("Null hit type, cannot convert tdc to time."); @@ -249,19 +233,20 @@ public final int convertTdcToTime() { veff = Parameters.VEFF; //Wedge hits are placed at the center of wedges and sipm at their top distance_to_sipm = Parameters.WEDGE_THICKNESS / 2.; - timeOffset = - tChannelToChannelPhiAlignment; + timeOffset = - t0; } case "bar up" -> { veff = Parameters.VEFF; //The distance will be computed at barhit level when z information is available distance_to_sipm = 0; - timeOffset = - tud/2. - tChannelToChannelPhiAlignment; + //t0 for bars is the sum of up+down channels->need 1/2 + timeOffset = - tud/2. - t0/2; } case "bar down" -> { veff = Parameters.VEFF; //The distance will be computed at barhit level when z information is available distance_to_sipm = 0; - timeOffset = + tud/2. - tChannelToChannelPhiAlignment; + timeOffset = + tud/2. - t0/2; } case "bar" -> { LOGGER.finest("Bar hit type, cannot convert tdc to time."); @@ -418,7 +403,7 @@ 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) { this.sector = sector; this.layer = layer; this.component = component; 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 39bc582078..eba7640c4b 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,5 +1,7 @@ package org.jlab.rec.atof.hit; +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; @@ -30,15 +32,19 @@ public ATOFHit getHitUp() { * */ public boolean isInTime() { + //Undefined start time is when useStartTime option is false in the yaml + //for example for usage with simulations + //-> we keep all the hits + if(this.hitUp.getStartTime() == null) return true; double timeShift = 0; + //TO DO: make this more robust //For FT electron for which the startTime is set at -1000 //We need to shift where the cut is applied + //2180 = 2*1090 = 1000+90 for FD start time around 90ns + //if the data start time is not around 90, this will be a problem if(this.hitUp.getStartTime()<0) timeShift = 2180; - if(Math.abs( - this.hitUp.getTime()+this.hitDown.getTime() - -timeShift - -this.hitUp.getMeanTimeAligned()) - <40) + if(Math.abs(this.hitUp.getTime()+this.hitDown.getTime() + -timeShift)<40) return true; return false; } @@ -70,17 +76,19 @@ public final void computeZ() { * */ public final void computeTime() { - //We pick the most energetic signal as the timing signal - double time_at_sipm, distance_to_sipm; - if(this.hitDown.getEnergy() > this.hitUp.getEnergy()) { - time_at_sipm = this.hitDown.getTime(); - distance_to_sipm = Parameters.LENGTH_ATOF/2. - this.getZ(); - } - else { - time_at_sipm = this.hitUp.getTime(); - distance_to_sipm = Parameters.LENGTH_ATOF/2. + this.getZ(); - } - this.setTime(time_at_sipm - distance_to_sipm/this.vEff); + //Select the most energetic hit as the timing reference + final boolean useDownstream = hitDown.getEnergy() > hitUp.getEnergy(); + final double sipmTime = useDownstream ? hitDown.getTime() : hitUp.getTime(); + //veff correction + //t0 has already been removed. + //distance to SiPM is L/2+-z, part of it is absorbed into the t0 as: + //t0 = 2*offset+L/veff + //t_hit = t_u/d - 2*offset/2 -/+ tud/2 - 1/veff(L/2 -/+ z) + //t_hit = t_u/d - (t0)/2 -/+ tud/2 +/- z/veff + //Only the z part remains + final double zDirection = useDownstream ? +this.getZ() : -this.getZ(); + final double correctedTime = sipmTime + zDirection / vEff; + this.setTime(correctedTime); } /** 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 a4db3aa43e..1f7c04e901 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 @@ -5,7 +5,6 @@ import org.jlab.geom.base.Detector; import org.jlab.io.base.DataBank; import org.jlab.io.base.DataEvent; -import org.jlab.rec.alert.constants.CalibrationConstantsLoader; /** * The {@code HitFinder} class finds hits in the atof. @@ -64,7 +63,7 @@ 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) { //For each event a list of bar hits and a list of wedge hits are filled this.barHits.clear(); this.wedgeHits.clear(); 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 a52bb33c25..b0c2a4992a 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 @@ -175,7 +175,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, 0, ATOF); + ATOFHit hit_pred = new ATOFHit(sector_pred, layer_pred, wedge_pred, 0, 0, 0, 0f, ATOF); double pred_x = hit_pred.getX(); double pred_y = hit_pred.getY(); double pred_z = hit_pred.getZ(); @@ -193,7 +193,7 @@ public boolean processDataEvent(DataEvent event) { int sector = bank.getInt("sector", k); int layer = bank.getInt("layer", k); - ATOFHit hit = new ATOFHit(sector, layer, component, 0, 0, 0, 0, ATOF); + ATOFHit hit = new ATOFHit(sector, layer, component, 0, 0, 0, 0f, ATOF); double dx = pred_x - hit.getX(); double dy = pred_y - hit.getY(); @@ -212,9 +212,6 @@ public boolean processDataEvent(DataEvent event) { } catch (Exception ex) { System.out.println("Exception in ALERTEngine processDataEvent: " + ex); // TODO: proper logging } - - - } return true; } 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 7f66d442ef..4b847ff069 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 @@ -60,7 +60,7 @@ public boolean processDataEvent(DataEvent event) { if (!event.hasBank("RUN::config")) { return true; } - float startTime = 0; + Float startTime = null; if(useStartTime) { //This assumes the FD reconstruction produced an event with good startTime @@ -101,14 +101,11 @@ public boolean processDataEvent(DataEvent event) { //projector.projectTracks(event); //rbc.appendMatchBanks(event, projector.getProjections()); - // Why do we have to "find" hits? //Hit finder init HitFinder hitfinder = new HitFinder(); hitfinder.findHits(event, ATOF, startTime); - ArrayList WedgeHits = hitfinder.getWedgeHits(); ArrayList BarHits = hitfinder.getBarHits(); - //Exit if hit lists are empty if (WedgeHits.isEmpty() && BarHits.isEmpty()) { // System.out.println("No hits : ");