Skip to content

Commit a4f5cdc

Browse files
committed
prepare for on-the-fly post-processing
1 parent fcfbe21 commit a4f5cdc

2 files changed

Lines changed: 183 additions & 40 deletions

File tree

common-tools/clara-io/src/main/java/org/jlab/io/clara/Clas12Writer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ protected void writeEvent(Object event) throws EventWriterException {
7070

7171
@Override
7272
protected void closeWriter() {
73-
serial.finish(writer);
73+
serial.closure(writer);
7474
super.closeWriter();
7575
if (postprocess) postprocess();
7676
serial.clear();
Lines changed: 182 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
package org.jlab.detector.serial;
22

3+
import java.util.Arrays;
4+
import java.util.List;
5+
import java.util.ListIterator;
36
import java.util.TreeMap;
47
import java.util.TreeSet;
8+
import java.util.stream.Collectors;
59
import org.jlab.detector.calib.utils.ConstantsManager;
610
import org.jlab.detector.decode.CLASDecoder;
11+
import org.jlab.detector.helicity.HelicityBit;
712
import org.jlab.detector.helicity.HelicitySequence;
13+
import org.jlab.detector.helicity.HelicitySequenceDelayed;
814
import org.jlab.detector.helicity.HelicityState;
15+
import org.jlab.detector.scalers.DaqScalers;
916
import org.jlab.detector.scalers.DaqScalersSequence;
1017
import org.jlab.jnp.hipo4.data.Bank;
1118
import org.jlab.jnp.hipo4.data.Event;
19+
import org.jlab.jnp.hipo4.data.Schema;
1220
import org.jlab.jnp.hipo4.data.SchemaFactory;
1321
import org.jlab.jnp.hipo4.io.HipoWriterSorted;
1422

@@ -19,54 +27,144 @@
1927
public class SerialHoncho {
2028

2129
static final String[] TAG1BANKS = {"RUN::scaler","HEL::scaler","RAW::scaler","RAW::epics","HEL::flip","COAT::config"};
22-
2330
SchemaFactory schema;
24-
Bank[] tag1banks;
25-
Bank runConfig;
26-
Bank helicityAdc;
31+
Schema[] tag1banks;
32+
Schema runConfig;
33+
Schema recEvent;
34+
Schema helScaler;
35+
Schema helicityAdc;
2736
ConstantsManager conman;
28-
TreeMap<Integer,Integer> eventUnix;
29-
TreeSet<HelicityState> helicities;
30-
DaqScalersSequence scalers;
31-
37+
volatile TreeMap<Integer,Integer> eventUnix;
38+
volatile HelicitySequence helicitySequence;
39+
volatile TreeSet<HelicityState> helicities;
40+
volatile DaqScalersSequence scalers;
41+
int run = 0;
42+
3243
public SerialHoncho(SchemaFactory schema) {
3344
this.schema = schema;
3445
conman = new ConstantsManager();
3546
conman.init("/runcontrol/hwp","/runcontrol/helicity");
36-
runConfig = new Bank(schema.getSchema("RUN::config"));
37-
helicityAdc = new Bank(schema.getSchema("HEL::adc"));
38-
helicities = new TreeSet<>();
47+
runConfig = schema.getSchema("RUN::config");
48+
recEvent = schema.getSchema("REC::Event");
49+
helicityAdc = schema.getSchema("HEL::adc");
50+
helScaler = schema.getSchema("HEL::scaler");
3951
scalers = new DaqScalersSequence(schema);
52+
helicities = new TreeSet<>();
4053
eventUnix = new TreeMap<>();
41-
tag1banks = new Bank[TAG1BANKS.length];
54+
tag1banks = new Schema[TAG1BANKS.length];
4255
for (int i=0; i<tag1banks.length; ++i)
43-
tag1banks[i] = new Bank(schema.getSchema(TAG1BANKS[i]));
56+
tag1banks[i] = schema.getSchema(TAG1BANKS[i]);
4457
}
4558

46-
public synchronized Event read(Event event) {
47-
scalers.add(event);
48-
event.read(runConfig);
49-
event.read(helicityAdc);
50-
if (runConfig.getRows() > 0) {
51-
int unix = runConfig.getInt("unixtime",0);
52-
int evno = runConfig.getInt("event",0);
53-
if (unix > 0 && evno > 0) eventUnix.put(evno, unix);
59+
/**
60+
* Register an event's serial data and return a (possibly empty) tag-1 event.
61+
* @param event
62+
* @return new tag-1 event
63+
*/
64+
public Event read(Event event) {
65+
Bank cfg = new Bank(runConfig);
66+
Bank hel = new Bank(helicityAdc);
67+
event.read(cfg);
68+
event.read(hel);
69+
read(event, cfg, hel);
70+
return CLASDecoder.createTaggedEvent(event, cfg, createTaggedBanks(tag1banks));
71+
}
72+
73+
/**
74+
* Modify a physics event's helicity and charge information.
75+
* @param event
76+
*/
77+
public void process(Event event) {
78+
Bank cfg = new Bank(runConfig);
79+
Bank evt = new Bank(recEvent);
80+
event.read(cfg);
81+
event.read(evt);
82+
if (cfg.getRows() > 0) {
83+
processEventUnix(event, cfg);
84+
if (evt.getRows() > 0) {
85+
event.remove(evt.getSchema());
86+
processHelicity(event, cfg, evt);
87+
processScalers(cfg, evt);
88+
event.write(evt);
89+
}
5490
}
55-
helicities.add(HelicityState.createFromFadcBank(helicityAdc, runConfig, conman));
56-
return CLASDecoder.createTaggedEvent(event, runConfig, tag1banks);
5791
}
5892

59-
public void finish(HipoWriterSorted writer) {
60-
writer.addEvent(getUnixEvent(runConfig),1);
61-
HelicitySequence.writeFlips(schema, writer, helicities);
93+
/**
94+
* Add helicity and unixtime sequence banks.
95+
* @param writer
96+
*/
97+
public void closure(HipoWriterSorted writer) {
98+
Bank cfg = new Bank(runConfig, 1);
99+
cfg.putInt("run",0,run);
100+
writer.addEvent(getUnixEvent(cfg),1);
101+
helicitySequence.writeFlips(writer, 1);
62102
}
63103

104+
/**
105+
* Zero all the sequences.
106+
*/
64107
public void clear() {
65-
while (helicities.size() > 100) helicities.pollFirst();
66-
scalers.clear(100);
108+
eventUnix.clear();
109+
helicities.clear();
110+
scalers.clear();
111+
helicitySequence = null;
112+
}
113+
114+
public TreeSet<HelicityState> getHelicities() {
115+
return helicities;
116+
}
117+
118+
public DaqScalersSequence getScalers() {
119+
return scalers;
120+
}
121+
122+
public ConstantsManager getConstantsManager() {
123+
return conman;
124+
}
125+
126+
public SchemaFactory getSchemaFactory() {
127+
return schema;
128+
}
129+
130+
public void updateHelicitySequence() {
131+
helicitySequence = new HelicitySequenceDelayed(
132+
conman.getConstants(run, "/runcontrol/helicity").getIntValue("delay",0,0,0));
133+
helicitySequence.addStream(helicities);
67134
}
68135

69-
Event getUnixEvent(Bank config) {
136+
void read(Event event, Bank runConfig, Bank helicityAdc) {
137+
scalers.add(event);
138+
helicities.add(HelicityState.createFromFadcBank(helicityAdc, runConfig, conman));
139+
prune();
140+
if (runConfig.getRows() > 0) {
141+
int r = runConfig.getInt("run", 0);
142+
if (r > 0) {
143+
if (r != run) {
144+
clear();
145+
run = r;
146+
}
147+
}
148+
if (run > 0) {
149+
int unix = runConfig.getInt("unixtime",0);
150+
int evno = runConfig.getInt("event",0);
151+
if (unix > 0 && evno > 0) eventUnix.put(evno, unix);
152+
}
153+
}
154+
}
155+
156+
void prune() {
157+
// Estimated size of HelicityState is ~22 bytes.
158+
// 1 million states, ~22 MB, 1 minute at 10 kHz trigger.
159+
if (helicities.size() > 2e6)
160+
pruneHelicities(helicities, (int)1e6);
161+
// Assuming scalers are 50x larger.
162+
// 10,000 events is 2.7 hours at 1 Hz.
163+
if (scalers.size() > 2e4)
164+
scalers.clear((int)1e4);
165+
}
166+
167+
Event getUnixEvent(Bank runConfig) {
70168
Bank unix = new Bank(schema.getSchema("RUN::unix"));
71169
unix.setRows(eventUnix.size());
72170
int row = 0;
@@ -76,24 +174,69 @@ Event getUnixEvent(Bank config) {
76174
row++;
77175
}
78176
Event e = new Event();
79-
e.write(config);
177+
e.write(runConfig);
80178
e.write(unix);
81179
return e;
82180
}
83181

84-
public DaqScalersSequence getScalers() {
85-
return scalers;
182+
int getUnixTime(Bank runConfig) {
183+
if (runConfig.getRows() < 1) {
184+
Integer key = eventUnix.floorKey(runConfig.getInt("event",0));
185+
if (key != null) {
186+
Integer unix = eventUnix.get(key);
187+
if (unix != null) return unix;
188+
}
189+
}
190+
return 0;
86191
}
87-
88-
public TreeSet<HelicityState> getHelicities() {
89-
return helicities;
192+
193+
void processEventUnix(Event event, Bank runConfig) {
194+
int ut = getUnixTime(runConfig);
195+
event.remove(runConfig.getSchema());
196+
runConfig.putInt("unixtime", 0, ut);
197+
event.write(runConfig);
90198
}
91199

92-
public ConstantsManager getConstantsManager() {
93-
return conman;
200+
void processScalers(Bank runConfig, Bank recEvent) {
201+
DaqScalers ds = scalers.get(runConfig.getLong("timestamp", 0));
202+
if (ds != null) {
203+
recEvent.putFloat("beamCharge",0, (float) ds.dsc2.getBeamChargeGated());
204+
recEvent.putDouble("liveTime",0,ds.dsc2.getLivetime());
205+
}
94206
}
95207

96-
public SchemaFactory getSchemaFactory() {
97-
return schema;
208+
void processHelicity(Event event, Bank runConfig, Bank recEvent) {
209+
HelicityBit hb = helicitySequence.search(runConfig.getLong("timestamp", 0));
210+
HelicityBit hbraw = helicitySequence.getHalfWavePlate() ? HelicityBit.getFlipped(hb) : hb;
211+
recEvent.putByte("helicity",0,hb.value());
212+
recEvent.putByte("helicityRaw",0,hbraw.value());
213+
Bank scaler = new Bank(helScaler);
214+
event.read(scaler);
215+
if (scaler.getRows()>0) {
216+
event.remove(helScaler);
217+
SerialUtil.assignScalerHelicity(runConfig.getLong("timestamp",0), scaler, helicitySequence);
218+
event.write(scaler);
219+
}
98220
}
221+
222+
static void pruneHelicities(TreeSet<HelicityState> helicities, int depth) {
223+
HelicityState prev = null;
224+
ListIterator<HelicityState> iter = (ListIterator)helicities.iterator();
225+
final int size = helicities.size();
226+
while (iter.hasNext() && iter.nextIndex() < size-depth) {
227+
HelicityState next = iter.next();
228+
if (prev != null && prev == next)
229+
helicities.remove(next);
230+
}
231+
}
232+
233+
static Bank[] createTaggedBanks(Schema[] tag1banks) {
234+
List<Bank> lbank = Arrays.asList(tag1banks).stream().map(s -> new Bank(s)).collect(Collectors.toList());
235+
ListIterator<Bank> ibank = lbank.listIterator();
236+
Bank[] banks = new Bank[lbank.size()];
237+
while (ibank.hasNext())
238+
banks[ibank.nextIndex()] = ibank.next();
239+
return banks;
240+
}
241+
99242
}

0 commit comments

Comments
 (0)