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 c262aa3d2b..6baf40f047 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 @@ -8,6 +8,7 @@ import org.jlab.detector.helicity.HelicitySequenceDelayed; import org.jlab.detector.serial.SerialHoncho; import org.jlab.detector.serial.PostProcessor; +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; @@ -28,6 +29,7 @@ */ public class Clas12Writer extends HipoToHipoWriter { + Occupancer occupancer; SerialHoncho serial; Bank runConfig; ConstantsManager conman; @@ -40,6 +42,7 @@ public class Clas12Writer extends HipoToHipoWriter { int paraTriggerPrescale; private void init(JSONObject opts) { + occupancer = new Occupancer(); fullSchema = new SchemaFactory(); fullSchema.initFromDirectory(FileUtils.getEnvironmentPath("CLAS12DIR","etc/bankdefs/hipo4")); serial = new SerialHoncho(fullSchema); @@ -78,6 +81,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-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..23c00e77a9 --- /dev/null +++ b/common-tools/clas-detector/src/main/java/org/jlab/detector/serial/Occupancer.java @@ -0,0 +1,184 @@ +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")); } + + int prescale = 1000; + int nevents = 0; + + public Occupancer() { + super(); + init(); + } + + public Occupancer(int prescale) { + super(); + this.prescale = prescale; + init(); + } + + private void init() { + 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) { + 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 schemaExempt = Arrays.asList("RUN::config","DC::tdc"); - private CLASDecoder4 decoder = new CLASDecoder4(); + private final CLASDecoder4 decoder = new CLASDecoder4(); + private final Occupancer occupancer = new Occupancer(); 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); } diff --git a/etc/bankdefs/hipo4/occupancy.json b/etc/bankdefs/hipo4/occupancy.json new file mode 100644 index 0000000000..ec02d1efdb --- /dev/null +++ b/etc/bankdefs/hipo4/occupancy.json @@ -0,0 +1,272 @@ +[ + { + "name": "OCC::DC::tdc", + "group": 500, + "item": 10, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::DC::tot", + "group": 500, + "item": 11, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::ECAL::adc", + "group": 500, + "item": 12, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::ECAL::tdc", + "group": 500, + "item": 13, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::FTOF::adc", + "group": 500, + "item": 14, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"order" , "type":"B", "info":"order"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::FTOF::tdc", + "group": 500, + "item": 15, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"order" , "type":"B", "info":"order"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::CTOF::adc", + "group": 500, + "item": 16, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"order" , "type":"B", "info":"order"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::CTOF::tdc", + "group": 500, + "item": 17, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"order" , "type":"B", "info":"order"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::HTCC::adc", + "group": 500, + "item": 18, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::HTCC::tdc", + "group": 500, + "item": 19, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::LTCC::adc", + "group": 500, + "item": 20, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::LTCC::tdc", + "group": 500, + "item": 21, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::BST::adc", + "group": 500, + "item": 22, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::BMT::adc", + "group": 500, + "item": 23, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::FTCAL::adc", + "group": 500, + "item": 24, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::FTHODO::adc", + "group": 500, + "item": 25, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::FTTRK::adc", + "group": 500, + "item": 26, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::RICH::tdc", + "group": 500, + "item": 27, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::BAND::adc", + "group": 500, + "item": 28, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::BAND::tdc", + "group": 500, + "item": 29, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::CND::adc", + "group": 500, + "item": 30, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"order" , "type":"B", "info":"order"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + }, + { + "name": "OCC::CND::tdc", + "group": 500, + "item": 31, + "info": "Occupancy Bank", + "entries": [ + { "name":"sector" , "type":"B", "info":"sector"}, + { "name":"layer" , "type":"B", "info":"layer"}, + { "name":"component" , "type":"S", "info":"component"}, + { "name":"order" , "type":"B", "info":"order"}, + { "name":"hits" , "type":"F", "info":"number of hits"} + ] + } +] diff --git a/etc/bankdefs/util/bankSplit.py b/etc/bankdefs/util/bankSplit.py index a8449ecf42..ec0ea5bf71 100755 --- a/etc/bankdefs/util/bankSplit.py +++ b/etc/bankdefs/util/bankSplit.py @@ -1,8 +1,9 @@ #!/usr/bin/env python -import json -import sys import os +import sys +import json +import glob # print usage if len(sys.argv)<2: @@ -54,6 +55,9 @@ def create(dirname, banklist): print("Single json files saved in " + workdirectory + singledirectory) +# occupancy banks: +occ = [os.path.basename(x)[:-5] for x in glob.glob('./singles/occupancy/*.json')] + # these should *always* be kept: mc = ["MC::Event", "MC::GenMatch", "MC::Header", "MC::Lund", "MC::Particle", "MC::RecMatch", "MC::True"] tag1 = ["RUN::config", "RAW::epics", "RAW::scaler", "RUN::scaler", "HEL::scaler", "COAT::config", "HEL::flip", "HEL::online", "HEL::decoder"] @@ -83,7 +87,7 @@ def create(dirname, banklist): trig = ["RAW::vtp","HTCC::rec","ECAL::adc","ECAL::calib","ECAL::clusters","ECAL::hits","ECAL::moments","ECAL::peaks","ECAL::tdc","ECAL::trigger"] # accumulate all the DST banks: -dst = rectbai + rectb + mc + tag1 + dets +dst = rectbai + rectb + mc + tag1 + occ + dets dsthb = dst + rechbai + rechb # generate the calib and mon schema: @@ -112,8 +116,7 @@ def create(dirname, banklist): level3 = list(dst) level3.extend(["DC::tdc", "DC::tot", "ECAL::adc", "ECAL::clusters", "FTOF::tdc", "FTOF::adc", "HitBasedTrkg::HBClusters", "HitBasedTrkg::HBTracks", "HTCC::adc", "RF::adc", "RF::tdc", "RUN::rf", "TimeBasedTrkg::TBClusters", "TimeBasedTrkg::TBTracks"]) -import glob - +# Raw bank schema: raw = glob.glob('./singles/data/*.json') raw.extend(glob.glob('./singles/header/*.json')) raw.extend(glob.glob('./singles/tag1/*.json'))