From b26bac5ceeabc03aa52904014ee91381bbe7152c Mon Sep 17 00:00:00 2001 From: Nathan Baltzell Date: Wed, 21 Oct 2026 19:20:07 -0400 Subject: [PATCH 1/3] add occupancer class --- .../org/jlab/detector/serial/Occupancer.java | 192 ++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java new file mode 100644 index 0000000000..fdf6b1c213 --- /dev/null +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java @@ -0,0 +1,192 @@ +package org.jlab.detector.serial; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Map; +import org.jlab.detector.banks.RawBank; +import org.jlab.utils.groups.IndexedTable; +import org.jlab.utils.groups.IndexedTable.IndexedEntry; +import org.jlab.detector.banks.RawBank.OrderGroups; +import org.jlab.jnp.hipo4.data.Bank; +import org.jlab.jnp.hipo4.data.Event; +import org.jlab.jnp.hipo4.data.Schema; +import org.jlab.jnp.hipo4.data.SchemaFactory; +import org.jlab.utils.system.ClasUtilsFile; + +/** + * Occupancy bookkeeper based on IndexedTable, with I/O helpers for indexed banks. + * + * @author baltzell + */ +public class Occupancer extends ArrayList { + + static final String OCC_BANK_DIR = ClasUtilsFile.getResourceDir("CLAS12DIR","etc/bankdefs/hipo4/singles/occupancy"); + static final SchemaFactory FULL_SCHEMA = new SchemaFactory(); + static { FULL_SCHEMA.initFromDirectory(ClasUtilsFile.getResourceDir("CLAS12DIR","etc/bankdefs/hipo4")); } + + long triggerMask; + int prescale; + int nevents = 0; + Schema cfgSchema; + + /** + * + * @param triggerMask + * @param prescale + */ + public Occupancer(long triggerMask, int prescale) { + super(); + this.triggerMask = triggerMask; + this.prescale = prescale; + init(); + } + + private void init() { + cfgSchema = FULL_SCHEMA.getSchema("RUN::config"); + try { + // Initialize list, by reading occupancy bank filenames from a directory + // and stripping ".json" suffix and "OCC::" prefix to get hit bank name: + addAll(Files.list(Paths.get(OCC_BANK_DIR)) + .filter(Files::isRegularFile) + .map(p -> p.getFileName().toString()) + .map(s -> s.substring(0, s.length()-5)) + .map(s -> s.substring(5, s.length())) + .map(OccupanceTable::new).toList()); + } catch (IOException ex) { + System.getLogger(Occupancer.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex); + } + } + + public boolean process(Event event) { + Bank cfgBank = event.read(new Bank(cfgSchema, 1)); + boolean passTrigger = cfgBank.getRows() > 0 && 0 != (triggerMask & cfgBank.getLong("trigger",0)); + if (triggerMask <= 0 || passTrigger) { + int size = size(); + for (int i=0; i 0) { + event.write(get(i).create(nevents)); + } + get(i).reset(); + } + nevents = 0; + } + } + return true; + } + + public void reset() { + int size = size(); + for (int i=0; i)table.getList().getMap()).keySet()) { + t.addEntry(IndexedTable.DEFAULT_GENERATOR.getIndices(hash, table.getList().getIndexSize())); + t.setDoubleValueByHash((table.getDoubleValueByHash(0, hash))/events, 0, hash); + } + return t; + } + + /** + * Fill the occupancy table. + * @param index + */ + public final void fill(int... index) { + for (int i=0; i m = table.getList().getMap(); + int i = 0; + for (long hash : m.keySet()) { + int[] idx = IndexedTable.DEFAULT_GENERATOR.getIndices(hash, table.getList().getIndexSize()); + for (int j=0; j Date: Wed, 21 Oct 2026 19:23:14 -0400 Subject: [PATCH 2/3] cleanup --- .../src/main/java/org/jlab/detector/serial/Occupancer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java index fdf6b1c213..64e9bd73ad 100644 --- a/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java @@ -13,6 +13,7 @@ import org.jlab.jnp.hipo4.data.Event; import org.jlab.jnp.hipo4.data.Schema; import org.jlab.jnp.hipo4.data.SchemaFactory; +import org.jlab.utils.CLASResources; import org.jlab.utils.system.ClasUtilsFile; /** @@ -23,8 +24,7 @@ public class Occupancer extends ArrayList { static final String OCC_BANK_DIR = ClasUtilsFile.getResourceDir("CLAS12DIR","etc/bankdefs/hipo4/singles/occupancy"); - static final SchemaFactory FULL_SCHEMA = new SchemaFactory(); - static { FULL_SCHEMA.initFromDirectory(ClasUtilsFile.getResourceDir("CLAS12DIR","etc/bankdefs/hipo4")); } + static final SchemaFactory FULL_SCHEMA = CLASResources.getFullSchema(); long triggerMask; int prescale; From 9fb2e8a0e89edf502e9ad182f7ae866a4bcf0ad2 Mon Sep 17 00:00:00 2001 From: Nathan Baltzell Date: Wed, 21 Oct 2026 19:24:43 -0400 Subject: [PATCH 3/3] use occupancer --- .../src/main/java/org/jlab/io/clara/Clas12Writer.java | 7 ++++--- .../src/main/java/org/jlab/clas/reco/EngineProcessor.java | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/common-tools/clara-io/src/main/java/org/jlab/io/clara/Clas12Writer.java b/common-tools/clara-io/src/main/java/org/jlab/io/clara/Clas12Writer.java index 75ae958d2e..e142e6bb5d 100644 --- a/common-tools/clara-io/src/main/java/org/jlab/io/clara/Clas12Writer.java +++ b/common-tools/clara-io/src/main/java/org/jlab/io/clara/Clas12Writer.java @@ -1,12 +1,10 @@ package org.jlab.io.clara; -import java.io.File; import java.nio.file.Path; -import java.util.List; import org.jlab.clara.std.services.EventWriterException; import org.jlab.detector.calib.utils.ConstantsManager; -import org.jlab.detector.helicity.HelicitySequenceDelayed; import org.jlab.detector.serial.SerialHoncho; +import org.jlab.detector.serial.Occupancer; import org.jlab.jnp.hipo4.data.Bank; import org.jlab.jnp.hipo4.data.Event; import org.jlab.jnp.hipo4.data.SchemaFactory; @@ -26,6 +24,7 @@ */ public class Clas12Writer extends HipoToHipoWriter { + Occupancer occupancer; SerialHoncho serial; Bank runConfig; ConstantsManager conman; @@ -37,6 +36,7 @@ public class Clas12Writer extends HipoToHipoWriter { int paraTriggerPrescale; private void init(JSONObject opts) { + occupancer = new Occupancer((long)1<<39,100); fullSchema = new SchemaFactory(); fullSchema.initFromDirectory(FileUtils.getEnvironmentPath("CLAS12DIR","etc/bankdefs/hipo4")); serial = new SerialHoncho(fullSchema); @@ -74,6 +74,7 @@ protected HipoWriterSorted createWriter(Path file, JSONObject opts) throws Event protected void writeEvent(Object event) throws EventWriterException { Event t = serial.read((Event)event); if (!t.isEmpty()) writer.addEvent(t, 1); + occupancer.process(((Event)event)); super.writeEvent(event); writeRaw((Event)event, t); } diff --git a/common-tools/clas-reco/src/main/java/org/jlab/clas/reco/EngineProcessor.java b/common-tools/clas-reco/src/main/java/org/jlab/clas/reco/EngineProcessor.java index dfa428f7ec..6e2271c4e3 100644 --- a/common-tools/clas-reco/src/main/java/org/jlab/clas/reco/EngineProcessor.java +++ b/common-tools/clas-reco/src/main/java/org/jlab/clas/reco/EngineProcessor.java @@ -19,6 +19,7 @@ import java.util.Arrays; import org.jlab.coda.jevio.EvioException; import org.jlab.detector.decode.CLASDecoder4; +import org.jlab.detector.serial.Occupancer; import org.jlab.io.evio.EvioDataEvent; import org.jlab.io.evio.EvioSource; import org.jlab.io.hipo.HipoDataEvent; @@ -42,7 +43,8 @@ public class EngineProcessor { private SchemaFactory banksToKeep = null; private final List schemaExempt = Arrays.asList("RUN::config","DC::tdc"); - private CLASDecoder4 decoder = new CLASDecoder4(); + private final CLASDecoder4 decoder = new CLASDecoder4(); + private final Occupancer occupancer = new Occupancer((long)1<<39,100); public EngineProcessor(){} @@ -316,6 +318,7 @@ public void processFile(String file, String output){ public void processEvent(DataEvent event, HipoDataSync writer) { processEvent(event); removeBanks(event); + occupancer.process(((HipoDataEvent)event).getHipoEvent()); writer.writeEvent(event); }