From 97599dc244a1e969c9ff002afc2d58d7d5943850 Mon Sep 17 00:00:00 2001 From: Raffaella De Vita Date: Fri, 18 Sep 2026 18:49:46 -0400 Subject: [PATCH 1/5] do not ignore struck scaler readings with gated clock equal to zero as it can happen due to dead time --- .../src/main/java/org/jlab/detector/scalers/StruckScalers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java index ee28e0b744..ee766c6969 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java @@ -158,7 +158,7 @@ private void disentangle() { for (int ii=0; ii0) { - if (this.get(ii).gatedClock>0 && this.get(ii+2).gatedClock<0) { + if (this.get(ii).gatedClock>=0 && this.get(ii+2).gatedClock<0) { d.put(this.get(ii+2), this.get(ii)); } } From a20696a67c3eec28c36b1075222c4c14874fbe11 Mon Sep 17 00:00:00 2001 From: Raffaella De Vita Date: Fri, 18 Sep 2026 18:59:20 -0400 Subject: [PATCH 2/5] strip reafings starting from the end of the list (bug fix) --- .../src/main/java/org/jlab/detector/scalers/StruckScalers.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java index ee766c6969..a74b8cb109 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java @@ -194,7 +194,7 @@ private void add() { * @param interval the type of helicity interval to preserve */ private void strip(HelicityInterval interval) { - for (int ii=0; ii=0; ii--) { if (this.get(ii).getHelicityInterval(this.helTable) != interval) { this.remove(ii); } From c6a5e487302d327ab868604ec31a4f1c798731ae Mon Sep 17 00:00:00 2001 From: Raffaella De Vita Date: Wed, 23 Sep 2026 17:45:37 -0400 Subject: [PATCH 3/5] make requirements for building struck scaler readouts more tight --- .../jlab/detector/scalers/StruckScaler.java | 1 + .../jlab/detector/scalers/StruckScalers.java | 49 +++++++++++++++++-- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScaler.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScaler.java index 14237ebe62..624d07c337 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScaler.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScaler.java @@ -30,6 +30,7 @@ public class StruckScaler extends DaqScaler { public HelicityBit getQuartet() { return this.quartet; } // These slots corrspond to gated/ungated scalers in RAW::scaler. + public static final int NSLOT=2; public static final int SLOT_GATED=0; public static final int SLOT_UNGATED=1; diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java index a74b8cb109..39572cd52f 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/scalers/StruckScalers.java @@ -102,6 +102,8 @@ else if (Input.equals(Input.CLOCK, chan)) { break; case StruckScaler.SLOT_UNGATED: if (Input.equals(Input.FCUP, chan)) { + reading.helicity = HelicityBit.createFromRawBit(bank.getByte("helicity",k)); + reading.quartet = HelicityBit.createFromRawBit(bank.getByte("quartet",k)); reading.fcup = bank.getLong("value",k); } else if (Input.equals(Input.SLM, chan)) { @@ -115,6 +117,12 @@ else if (Input.equals(Input.CLOCK, chan)) { break; } } + + // ignore banks with more than the tegular 4 ( (tsettle+tstable) x (gated+ungated) ) readings + // or unbalance between gated/ungated readngs (allow difference by 1) + if(this.size()>(Interval.values().length-1)*StruckScaler.NSLOT || + Math.abs(this.count(StruckScaler.SLOT_GATED)-count(StruckScaler.SLOT_UNGATED))>1) + this.clear(); } /** @@ -147,6 +155,31 @@ private void copyGate(int source, int destination) { this.copyGate(this.get(source), this.get(destination)); } + /** + * Counts the number of raw readouts for the selected slot + * @param slot the index of the slot + * @return the number + **/ + private int count(int slot) { + int n = 0; + for (StruckScaler ss : this) { + switch(slot) { + case StruckScaler.SLOT_GATED: + if(ss.gatedClock>=0 && ss.clock<0) + n++; + break; + case StruckScaler.SLOT_UNGATED: + if(ss.gatedClock<0 && ss.clock>=0) + n++; + break; + default: + break; + } + } + return n; + } + + /** * When there's one interval in a RAW::scaler bank, that interval is * represented by (6) contiguous bank rows. But when there's multiple @@ -154,12 +187,18 @@ private void copyGate(int source, int destination) { * (and the ungated doesn't contain the helicity bit). Here we fix. */ private void disentangle() { + int n = Interval.values().length-1; HashMap d = new HashMap<>(); - for (int ii=0; ii0) { - if (this.get(ii).gatedClock>=0 && this.get(ii+2).gatedClock<0) { - d.put(this.get(ii+2), this.get(ii)); + for (int ii=0; ii0) { + if (this.get(ii).gatedClock>=0 && this.get(ii+n).gatedClock<0) { + d.put(this.get(ii+n), this.get(ii)); } } } From c249b0a6f3ec7f23c1b2481d7f922359e481bf31 Mon Sep 17 00:00:00 2001 From: Raffaella De Vita Date: Wed, 23 Sep 2026 19:07:30 -0400 Subject: [PATCH 4/5] assign scaler helicity shifting its timestamp by half (instead of one) state in the helicity sequence --- .../analysis/postprocess/RebuildScalers.java | 2 +- .../detector/helicity/HelicitySequence.java | 4 ++++ .../org/jlab/detector/serial/SerialUtil.java | 21 +++++++++++-------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java b/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java index 6fb4fe3d0c..db9e30b896 100644 --- a/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java +++ b/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java @@ -123,7 +123,7 @@ else if (seq != null) { runScalerBank = ds.createRunBank(writer.getSchemaFactory()); helScalerBank = ds.createHelicityBank(writer.getSchemaFactory()); - SerialUtil.assignScalerHelicity(event, helScalerBank, helSeq); + SerialUtil.assignScalerHelicity(runConfigBank.getLong("timestamp",0), helScalerBank, helSeq.getSequence(runConfigBank.getInt("run",0))); // put modified HEL/RUN::scaler back in the event: event.write(runScalerBank); diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/helicity/HelicitySequence.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/helicity/HelicitySequence.java index 11ff2f9ea0..6c2718dfb2 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/helicity/HelicitySequence.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/helicity/HelicitySequence.java @@ -68,6 +68,10 @@ public boolean getHalfWavePlate() { return this.halfWavePlate; } + public double getHelicityClock() { + return helicityClock; + } + /** * Get the the number of states in the sequence. * @return the number of states diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/SerialUtil.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/SerialUtil.java index 8967760c25..f4e6526eb2 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/SerialUtil.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/SerialUtil.java @@ -36,8 +36,9 @@ public class SerialUtil { * @param bank the HEL::scaler bank * @param seq previously initialized helicity sequence */ + @Deprecated public static void assignScalerHelicity(Event event, Bank bank, HelicitySequenceManager seq) { - + // Struck (helicity) scaler readout is always slightly after the helicity // state change, i.e., as registered in the FADCs, so its true helicity // is offset by one state from its event: @@ -69,10 +70,12 @@ public static void assignScalerHelicity(Event event, Bank bank, HelicitySequence */ public static void assignScalerHelicity(Long timestamp, Bank bank, HelicitySequence seq) { - // Struck (helicity) scaler readout is always slightly after the helicity - // state change, i.e., as registered in the FADCs, so its true helicity - // is offset by one state from its event: - final int readoutStateOffset = -1; + // Struck (helicity) scaler readout is always after the helicity + // state change, so its true helicity is offset by one state from its event; + // to avoid ambiguities arising from whether the scaler bznk appears before + // the helicity change is registered in the FADCs, shift by half a state: + final int readoutTimestampOffset = (int) (-0.5 * HelicitySequence.TIMESTAMP_CLOCK + / seq.getHelicityClock()); // Rows in the HEL::scaler bank correspond to the most recent, consecutive, // time-ordered, T-stable intervals. The first row is the earliest in @@ -81,14 +84,14 @@ public static void assignScalerHelicity(Long timestamp, Bank bank, HelicitySeque // This is the helicity state offset for this HEL::scaler row, where // the last row has an offset of -1: - final int offset = bank.getRows() - row - 1 + readoutStateOffset; + final int offset = bank.getRows() - row - 1; // Assign delay-corrected helicity to this HEL::scaler row: - bank.putByte("helicity",row,seq.search(timestamp,offset).value()); + bank.putByte("helicity",row,seq.search(timestamp+readoutTimestampOffset,offset).value()); if (seq.getHalfWavePlate()) - bank.putByte("helicityRaw",0,(byte)(-1*seq.search(timestamp,offset).value())); + bank.putByte("helicityRaw",0,(byte)(-1*seq.search(timestamp+readoutTimestampOffset,offset).value())); else - bank.putByte("helicityRaw",0,seq.search(timestamp,offset).value()); + bank.putByte("helicityRaw",0,seq.search(timestamp+readoutTimestampOffset,offset).value()); } } From cc3c9b316a33f9d094207296853c543627ade700 Mon Sep 17 00:00:00 2001 From: Raffaella De Vita Date: Thu, 24 Sep 2026 17:54:45 -0400 Subject: [PATCH 5/5] add check on hellicity sequence being non null --- .../java/org/jlab/analysis/postprocess/RebuildScalers.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java b/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java index db9e30b896..776e8c18a0 100644 --- a/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java +++ b/common-tools/clas-analysis/src/main/java/org/jlab/analysis/postprocess/RebuildScalers.java @@ -123,7 +123,8 @@ else if (seq != null) { runScalerBank = ds.createRunBank(writer.getSchemaFactory()); helScalerBank = ds.createHelicityBank(writer.getSchemaFactory()); - SerialUtil.assignScalerHelicity(runConfigBank.getLong("timestamp",0), helScalerBank, helSeq.getSequence(runConfigBank.getInt("run",0))); + if(helSeq.getSequence(runConfigBank.getInt("run",0))!=null) + SerialUtil.assignScalerHelicity(runConfigBank.getLong("timestamp",0), helScalerBank, helSeq.getSequence(runConfigBank.getInt("run",0))); // put modified HEL/RUN::scaler back in the event: event.write(runScalerBank);