Skip to content

Commit c90777b

Browse files
authored
Decoder speedups (#784)
* add access by hash * use hash-based access in decoding * remove clas6 detectors * add docs * only if necessary * break loop upon first c/s/c-detector match * use table-name-only initializer * use DetectorType instead of String, preload tables once * remove clas6 detectors * change hash accessor names (workaround long->int... precedence) * 10k events per decoder test job * add a static for speed * speedup swap table initialization * use default (static) generator * more less hashing * speedup initialization * optimize swap table initialization * cleanup * more comments * check CCDB tanslation tables for crate/slot/channel conflicts * add more performant accessors and use them in decoding * remove cp, use cached
1 parent 01c939c commit c90777b

File tree

8 files changed

+238
-113
lines changed

8 files changed

+238
-113
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,8 @@ jobs:
152152
- name: untar build
153153
run: tar xzvf coatjava.tar.gz
154154
- name: run test
155-
run: ./coatjava/bin/decoder -n 10000 -o dog.hipo ./clas_005038.evio.00000
155+
run: |
156+
./coatjava/bin/decoder -n 10000 -o dog.hipo ./clas_005038.evio.00000
156157
157158
test_coatjava:
158159
needs: [ build ]

common-tools/clas-detector/src/main/java/org/jlab/detector/base/DetectorType.java

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,7 @@ public enum DetectorType {
3333
ATOF (25, "ATOF"),
3434
RECOIL (26, "RECOIL"),
3535
TARGET (100, "TARGET"),
36-
MAGNETS (101, "MAGNETS"),
37-
ECIN (110, "ECIN"),
38-
ECOUT (111, "ECOUT"),
39-
ECTOT (112, "ECTOT"),
40-
LAC (113, "LAC"),
41-
SC (114, "SC"),
42-
CC (115, "CC");
36+
MAGNETS (101, "MAGNETS");
4337

4438
private final int detectorId;
4539
private final String detectorName;
@@ -62,21 +56,32 @@ public String getName() {
6256
return detectorName;
6357
}
6458

65-
/**
59+
/**
6660
* Returns the id number of the detector.
6761
* @return the id number of the detector
6862
*/
6963
public int getDetectorId() {
7064
return detectorId;
7165
}
7266

67+
/**
68+
* Get type from string name
69+
* @param name
70+
* @return
71+
*/
7372
public static DetectorType getType(String name) {
7473
name = name.trim();
7574
for(DetectorType id: DetectorType.values())
7675
if (id.getName().equalsIgnoreCase(name))
7776
return id;
7877
return UNDEFINED;
7978
}
79+
80+
/**
81+
* Get type from integer id
82+
* @param detId
83+
* @return
84+
*/
8085
public static DetectorType getType(Integer detId) {
8186

8287
for(DetectorType id: DetectorType.values())

common-tools/clas-detector/src/main/java/org/jlab/detector/decode/DetectorEventDecoder.java

Lines changed: 86 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ public class DetectorEventDecoder {
2323
ConstantsManager scalerManager = new ConstantsManager();
2424

2525
List<String> tablesTrans = null;
26-
List<String> keysTrans = null;
2726
List<String> tablesFitter = null;
28-
List<String> keysFitter = null;
29-
List<String> keysFilter = null;
27+
28+
List<DetectorType> keysTrans = null;
29+
List<DetectorType> keysFitter = null;
30+
List<DetectorType> keysFilter = null;
3031

3132
private int runNumber = 10;
3233

@@ -76,50 +77,60 @@ public DetectorEventDecoder(){
7677
}
7778

7879
public final void initDecoderDev(){
79-
keysTrans = Arrays.asList(new String[]{ "HTCC","BST","RTPC"} );
80+
keysTrans = Arrays.asList(new DetectorType[]{ DetectorType.HTCC,DetectorType.BST,DetectorType.RTPC} );
8081
tablesTrans = Arrays.asList(new String[]{ "/daq/tt/clasdev/htcc","/daq/tt/clasdev/svt","/daq/tt/clasdev/rtpc" });
81-
keysFitter = Arrays.asList(new String[]{"HTCC"});
82+
keysFitter = Arrays.asList(new DetectorType[]{DetectorType.HTCC});
8283
tablesFitter = Arrays.asList(new String[]{"/daq/fadc/clasdev/htcc"});
83-
translationManager.init(keysTrans,tablesTrans);
84-
fitterManager.init(keysFitter, tablesFitter);
84+
translationManager.init(tablesTrans);
85+
fitterManager.init(tablesFitter);
8586
scalerManager.init(Arrays.asList(new String[]{"/runcontrol/fcup","/runcontrol/slm","/runcontrol/hwp",
8687
"/runcontrol/helicity","/daq/config/scalers/dsc1"}));
8788
}
8889

8990
public final void initDecoder(){
9091

9192
// Detector translation table
92-
keysTrans = Arrays.asList(new String[]{"FTCAL","FTHODO","FTTRK","LTCC","ECAL","FTOF",
93-
"HTCC","DC","CTOF","CND","BST","RF","BMT","FMT",
94-
"RICH","HEL","BAND","RTPC",
95-
"RASTER","ATOF","AHDC"
93+
keysTrans = Arrays.asList(new DetectorType[]{DetectorType.FTCAL,DetectorType.FTHODO,DetectorType.FTTRK,DetectorType.LTCC,DetectorType.ECAL,DetectorType.FTOF,
94+
DetectorType.HTCC,DetectorType.DC,DetectorType.CTOF,DetectorType.CND,DetectorType.BST,DetectorType.RF,DetectorType.BMT,DetectorType.FMT,
95+
DetectorType.RICH,DetectorType.HEL,DetectorType.BAND,DetectorType.RTPC,
96+
DetectorType.RASTER,DetectorType.ATOF,DetectorType.AHDC
9697
});
9798
tablesTrans = Arrays.asList(new String[]{
9899
"/daq/tt/ftcal","/daq/tt/fthodo","/daq/tt/fttrk","/daq/tt/ltcc",
99100
"/daq/tt/ec","/daq/tt/ftof","/daq/tt/htcc","/daq/tt/dc","/daq/tt/ctof","/daq/tt/cnd","/daq/tt/svt",
100101
"/daq/tt/rf","/daq/tt/bmt","/daq/tt/fmt","/daq/tt/rich2","/daq/tt/hel","/daq/tt/band","/daq/tt/rtpc",
101102
"/daq/tt/raster","/daq/tt/atof","/daq/tt/ahdc"
102103
});
103-
translationManager.init(keysTrans,tablesTrans);
104+
translationManager.init(tablesTrans);
104105

105106
// ADC waveform fitter translation table
106-
keysFitter = Arrays.asList(new String[]{"FTCAL","FTHODO","FTTRK","FTOF","LTCC",
107-
"ECAL","HTCC","CTOF","CND","BMT",
108-
"FMT","HEL","RF","BAND","RASTER",
109-
"AHDC"});
107+
keysFitter = Arrays.asList(new DetectorType[]{DetectorType.FTCAL,DetectorType.FTHODO,DetectorType.FTTRK,DetectorType.FTOF,DetectorType.LTCC,
108+
DetectorType.ECAL,DetectorType.HTCC,DetectorType.CTOF,DetectorType.CND,DetectorType.BMT,
109+
DetectorType.FMT,DetectorType.HEL,DetectorType.RF,DetectorType.BAND,DetectorType.RASTER,
110+
DetectorType.AHDC});
110111
tablesFitter = Arrays.asList(new String[]{
111112
"/daq/fadc/ftcal","/daq/fadc/fthodo","/daq/config/fttrk","/daq/fadc/ftof","/daq/fadc/ltcc",
112113
"/daq/fadc/ec", "/daq/fadc/htcc","/daq/fadc/ctof","/daq/fadc/cnd","/daq/config/bmt",
113114
"/daq/config/fmt","/daq/fadc/hel","/daq/fadc/rf","/daq/fadc/band","/daq/fadc/raster",
114115
"/daq/config/ahdc"
115116
});
116-
fitterManager.init(keysFitter, tablesFitter);
117+
fitterManager.init(tablesFitter);
117118

118119
// Data filter list
119-
keysFilter = Arrays.asList(new String[]{"DC"});
120+
keysFilter = Arrays.asList(new DetectorType[]{DetectorType.DC});
120121

121122
scalerManager.init(Arrays.asList(new String[]{"/runcontrol/fcup","/runcontrol/slm","/runcontrol/hwp",
122123
"/runcontrol/helicity","/daq/config/scalers/dsc1"}));
124+
125+
checkTables();
126+
}
127+
128+
public void checkTables() {
129+
for (int i=0; i<tablesTrans.size(); i++) {
130+
IndexedTable t = translationManager.getConstants(runNumber, tablesTrans.get(i));
131+
for (int j=0; j<i; j++)
132+
t.conflicts(translationManager.getConstants(runNumber, tablesTrans.get(j)));
133+
}
123134
}
124135

125136
/**
@@ -129,52 +140,74 @@ public final void initDecoder(){
129140
*/
130141
public void translate(List<DetectorDataDgtz> detectorData){
131142

132-
for(DetectorDataDgtz data : detectorData){
143+
// Preload CCDB tables:
144+
ArrayList<IndexedTable> tables = new ArrayList<>();
145+
for (String name : tablesTrans) {
146+
tables.add(translationManager.getConstants(runNumber, name));
147+
}
133148

149+
for (DetectorDataDgtz data : detectorData) {
150+
151+
// Get the hardware indexing for this detector hit:
134152
int crate = data.getDescriptor().getCrate();
135153
int slot = data.getDescriptor().getSlot();
136154
int channel = data.getDescriptor().getChannel();
155+
long hash = IndexedTable.DEFAULT_GENERATOR.hashCode(crate,slot,channel);
156+
157+
// Try to find it in the translation tables:
158+
for (int j=0; j<tablesTrans.size(); ++j) {
159+
160+
IndexedTable t = tables.get(j);
137161

138-
for(String table : keysTrans){
139-
IndexedTable tt = translationManager.getConstants(runNumber, table);
140-
DetectorType type = DetectorType.getType(table);
141-
if(tt.hasEntry(crate,slot,channel)==true){
142-
int sector = tt.getIntValue("sector", crate,slot,channel);
143-
int layer = tt.getIntValue("layer", crate,slot,channel);
144-
int component = tt.getIntValue("component", crate,slot,channel);
145-
int order = tt.getIntValue("order", crate,slot,channel);
162+
// Found it; now set the detector indexing for this hit:
163+
if (t.hasEntryByHash(hash)) {
164+
165+
int sector = t.getIntValueByHash(0, hash);
166+
int layer = t.getIntValueByHash(1, hash);
167+
int component = t.getIntValueByHash(2, hash);
168+
int order = t.getIntValueByHash(3, hash);
146169

147170
data.getDescriptor().setSectorLayerComponent(sector, layer, component);
148171
data.getDescriptor().setOrder(order);
149-
data.getDescriptor().setType(type);
172+
data.getDescriptor().setType(keysTrans.get(j));
150173

151-
for(int i = 0; i < data.getADCSize(); i++) {
152-
data.getADCData(i).setOrder(order);
153-
}
154-
for(int i = 0; i < data.getTDCSize(); i++) {
155-
data.getTDCData(i).setOrder(order);
156-
}
174+
for(int i = 0; i < data.getADCSize(); i++) data.getADCData(i).setOrder(order);
175+
for(int i = 0; i < data.getTDCSize(); i++) data.getTDCData(i).setOrder(order);
176+
177+
// Assume there's only one instance of this crate/slot/channel
178+
// in all translation tables, and we found it, so stop:
179+
break;
157180
}
158181
}
159182
}
160183
}
161184

162185
public void fitPulses(List<DetectorDataDgtz> detectorData){
186+
187+
// preload CCDB tables once:
188+
ArrayList<IndexedTable> tables = new ArrayList<>();
189+
for (String name : tablesFitter) {
190+
tables.add(fitterManager.getConstants(runNumber, name));
191+
}
192+
163193
for(DetectorDataDgtz data : detectorData){
164194
int crate = data.getDescriptor().getCrate();
165195
int slot = data.getDescriptor().getSlot();
166196
int channel = data.getDescriptor().getChannel();
167-
for(String table : keysFitter){
197+
long hash = IndexedTable.DEFAULT_GENERATOR.hashCode(crate,slot,channel);
198+
long hash0 = IndexedTable.DEFAULT_GENERATOR.hashCode(0,0,0);
199+
for (int j=0; j<keysFitter.size(); ++j) {
200+
IndexedTable daq = tables.get(j);
201+
DetectorType type = keysFitter.get(j);
168202
//custom MM fitter
169-
if( ( (table.equals("BMT"))&&(data.getDescriptor().getType().getName().equals("BMT")) )
170-
|| ( (table.equals("FMT"))&&(data.getDescriptor().getType().getName().equals("FMT")) )
171-
//|| ( (table.equals("AHDC"))&&(data.getDescriptor().getType().getName().equals("AHDC")) )
172-
|| ( (table.equals("FTTRK"))&&(data.getDescriptor().getType().getName().equals("FTTRK")) ) ){
173-
IndexedTable daq = fitterManager.getConstants(runNumber, table);
174-
short adcOffset = (short) daq.getDoubleValue("adc_offset", 0, 0, 0);
175-
double fineTimeStampResolution = (byte) daq.getDoubleValue("dream_clock", 0, 0, 0);
176-
double samplingTime = (byte) daq.getDoubleValue("sampling_time", 0, 0, 0);
177-
int sparseSample = daq.getIntValue("sparse", 0, 0 ,0);
203+
if( ( (type == DetectorType.BMT)&&(data.getDescriptor().getType().getName().equals("BMT")) )
204+
|| ( (type == DetectorType.FMT)&&(data.getDescriptor().getType().getName().equals("FMT")) )
205+
//|| ( (type == DetectorType.AHDC)&&(data.getDescriptor().getType().getName().equals("AHDC")) )
206+
|| ( (type == DetectorType.FTTRK)&&(data.getDescriptor().getType().getName().equals("FTTRK")) ) ){
207+
short adcOffset = (short) daq.getDoubleValueByHash("adc_offset", hash0);
208+
double fineTimeStampResolution = (byte) daq.getDoubleValueByHash("dream_clock", hash0);
209+
double samplingTime = (byte) daq.getDoubleValueByHash("sampling_time", hash0);
210+
int sparseSample = daq.getIntValueByHash("sparse", hash0);
178211
if (data.getADCSize() > 0) {
179212
ADCData adc = data.getADCData(0);
180213
mvtFitter.fit(adcOffset, fineTimeStampResolution, samplingTime, adc.getPulseArray(), adc.getTimeStamp(), sparseSample);
@@ -184,14 +217,14 @@ public void fitPulses(List<DetectorDataDgtz> detectorData){
184217
adc.setTimeStamp(mvtFitter.timestamp);
185218
}
186219
} else {
187-
IndexedTable daq = fitterManager.getConstants(runNumber, table);
188-
DetectorType type = DetectorType.getType(table);
189-
if(daq.hasEntry(crate,slot,channel)==true){
190-
int nsa = daq.getIntValue("nsa", crate,slot,channel);
191-
int nsb = daq.getIntValue("nsb", crate,slot,channel);
192-
int tet = daq.getIntValue("tet", crate,slot,channel);
220+
if(daq.hasEntryByHash(hash)==true){
221+
int nsa = daq.getIntValueByHash("nsa", hash);
222+
int nsb = daq.getIntValueByHash("nsb", hash);
223+
int tet = daq.getIntValueByHash("tet", hash);
193224
int ped = 0;
194-
if(table.equals("RF")&&data.getDescriptor().getType().getName().equals("RF")) ped = daq.getIntValue("pedestal", crate,slot,channel);
225+
if(type == DetectorType.RF&&data.getDescriptor().getType().getName().equals("RF")) {
226+
ped = daq.getIntValueByHash("pedestal", hash);
227+
}
195228
if(data.getADCSize()>0){
196229
for(int i = 0; i < data.getADCSize(); i++){
197230
ADCData adc = data.getADCData(i);
@@ -224,10 +257,10 @@ public void fitPulses(List<DetectorDataDgtz> detectorData){
224257

225258
public void filterTDCs(List<DetectorDataDgtz> detectorData){
226259
int maxMultiplicity = 1;
227-
for(String table : keysFilter){
260+
for(DetectorType type : keysFilter){
228261
Map<Integer,List<DetectorDataDgtz>> filteredData = new HashMap<>();
229262
for(DetectorDataDgtz data : detectorData){
230-
if(data.getDescriptor().getType()==DetectorType.getType(table)) {
263+
if(data.getDescriptor().getType() == type) {
231264
int key = data.getDescriptor().getHashCode();
232265
if(!filteredData.containsKey(key))
233266
filteredData.put(key, new ArrayList<>());

common-tools/clas-detector/src/main/java/org/jlab/detector/swaps/SwapTable.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,20 +70,22 @@ public SwapTable(IndexedTable fromTrans,IndexedTable toTrans) {
7070

7171
this.table = new IndexedTable(VAR_NAMES.length,String.join(":",VAR_NAMES));
7272

73-
for (int row=0; row<fromTrans.getRowCount(); row++) {
73+
// loop over the rows in the translation table:
74+
for (Object key : fromTrans.getList().getMap().keySet()) {
7475

75-
// crate/slot/channel is the base for mapping between the two tables:
76-
final int crate = Integer.valueOf((String)fromTrans.getValueAt(row,0));
77-
final int slot = Integer.valueOf((String)fromTrans.getValueAt(row,1));
78-
final int channel = Integer.valueOf((String)fromTrans.getValueAt(row,2));
76+
// get the hash for this row:
77+
int crate = IndexedTable.DEFAULT_GENERATOR.getIndex((long)key, 0);
78+
int slot = IndexedTable.DEFAULT_GENERATOR.getIndex((long)key, 1);
79+
int channel = IndexedTable.DEFAULT_GENERATOR.getIndex((long)key, 2);
80+
long hash = IndexedTable.DEFAULT_GENERATOR.hashCode(crate, slot, channel);
7981

8082
// load the previous and current values of sector/layer/component/order:
8183
boolean diff = false;
8284
int[] previous = new int[VAR_NAMES.length];
8385
int[] current = new int[VAR_NAMES.length];
8486
for (int ivar=0; ivar<VAR_NAMES.length; ivar++) {
85-
previous[ivar] = fromTrans.getIntValue(VAR_NAMES[ivar],crate,slot,channel);
86-
current[ivar] = toTrans.getIntValue(VAR_NAMES[ivar], crate, slot, channel);
87+
previous[ivar] = fromTrans.getIntValueByHash(VAR_NAMES[ivar],hash);
88+
current[ivar] = toTrans.getIntValueByHash(VAR_NAMES[ivar],hash);
8789
if (previous[ivar] != current[ivar]) {
8890
diff = true;
8991
}

common-tools/clas-utils/src/main/java/org/jlab/utils/groups/IndexedList.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ public boolean hasItem(int... index) {
115115
return this.collection.containsKey(code);
116116
}
117117

118+
/**
119+
* Checks whether an item exists for the specified hash code.
120+
*
121+
* @param hash the hash code to look up
122+
* @return true if an item exists at the index; false otherwise
123+
*/
124+
public boolean hasItemByHash(long hash) {
125+
return this.collection.containsKey(hash);
126+
}
127+
118128
/**
119129
* Retrieves an item by its index.
120130
*
@@ -129,6 +139,17 @@ public T getItem(int... index) {
129139
return this.collection.get(code);
130140
}
131141

142+
/**
143+
* Retrieves an item by its hash.
144+
*
145+
* @param hash the hash to find
146+
* @return the item with the hash, null if not found
147+
*/
148+
public T getItemByHash(long hash){
149+
if (!this.collection.containsKey(hash)) return null;
150+
return this.collection.get(hash);
151+
}
152+
132153
/**
133154
* Clears items from the collection.
134155
*/

0 commit comments

Comments
 (0)