1
|
/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus
|
2
|
*
|
3
|
* MAUS is free software: you can redistribute it and/or modify
|
4
|
* it under the terms of the GNU General Public License as published by
|
5
|
* the Free Software Foundation, either version 3 of the License, or
|
6
|
* (at your option) any later version.
|
7
|
*
|
8
|
* MAUS is distributed in the hope that it will be useful,
|
9
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
* GNU General Public License for more details.
|
12
|
*
|
13
|
* You should have received a copy of the GNU General Public License
|
14
|
* along with MAUS. If not, see <http://www.gnu.org/licenses/>.
|
15
|
*
|
16
|
*/
|
17
|
|
18
|
#include "src/input/InputCppDAQData/InputCppDAQData.hh"
|
19
|
|
20
|
InputCppDAQData::InputCppDAQData(std::string pDataPath,
|
21
|
std::string pRunNum) {
|
22
|
_eventPtr = NULL;
|
23
|
_dataPaths = pDataPath;
|
24
|
_datafiles = pRunNum;
|
25
|
|
26
|
_v1290PartEventProc = NULL;
|
27
|
_v1724PartEventProc = NULL;
|
28
|
_v1731PartEventProc = NULL;
|
29
|
_v830FragmentProc = NULL;
|
30
|
_vLSBFragmentProc = NULL;
|
31
|
_DBBFragmentProc = NULL;
|
32
|
|
33
|
_next_event = Json::Value();
|
34
|
}
|
35
|
|
36
|
|
37
|
bool InputCppDAQData::birth(std::string jsonDataCards) {
|
38
|
// JsonCpp setup
|
39
|
Json::Value configJSON; // this will contain the configuration
|
40
|
Json::Reader reader;
|
41
|
|
42
|
// Check if the JSON document can be parsed, else return error only
|
43
|
bool parsingSuccessful = reader.parse(jsonDataCards, configJSON);
|
44
|
if (!parsingSuccessful) {
|
45
|
return false;
|
46
|
}
|
47
|
|
48
|
if ( _dataFileManager.GetNFiles() ) {
|
49
|
return false; // Faile because files are already open
|
50
|
}
|
51
|
|
52
|
//
|
53
|
if (_dataPaths == "") {
|
54
|
assert(configJSON.isMember("daq_data_path"));
|
55
|
_dataPaths = configJSON["daq_data_path"].asString();
|
56
|
}
|
57
|
if (_datafiles == "") {
|
58
|
assert(configJSON.isMember("daq_data_file"));
|
59
|
_datafiles = configJSON["daq_data_file"].asString();
|
60
|
}
|
61
|
_dataFileManager.SetList(_datafiles);
|
62
|
_dataFileManager.SetPath(_dataPaths);
|
63
|
_dataFileManager.OpenFile();
|
64
|
unsigned int nfiles = _dataFileManager.GetNFiles();
|
65
|
if (!nfiles) {
|
66
|
Squeak::mout(Squeak::error) << "Unable to load any data files from "
|
67
|
<< "daq_data_path " <<_dataPaths << " and daq_data_file "
|
68
|
<< _datafiles << std::endl;
|
69
|
return false;
|
70
|
}
|
71
|
assert(configJSON.isMember("DAQ_cabling_file"));
|
72
|
std::string map_file_name = configJSON["DAQ_cabling_file"].asString();
|
73
|
char* pMAUS_ROOT_DIR = getenv("MAUS_ROOT_DIR");
|
74
|
if (!pMAUS_ROOT_DIR) {
|
75
|
Squeak::mout(Squeak::error) << "Could not find the $MAUS_ROOT_DIR environmental variable."
|
76
|
<< std::endl;
|
77
|
Squeak::mout(Squeak::error) << "Did you try running: source env.sh ?" << std::endl;
|
78
|
return false;
|
79
|
}
|
80
|
|
81
|
// Initialize the map by using text file.
|
82
|
bool loaded = _map.InitFromFile(std::string(pMAUS_ROOT_DIR) + map_file_name);
|
83
|
if (!loaded) {
|
84
|
return false;
|
85
|
}
|
86
|
|
87
|
// Comfigure the V1290 (TDC) data processor.
|
88
|
assert(configJSON.isMember("Enable_V1290_Unpacking"));
|
89
|
if ( configJSON["Enable_V1290_Unpacking"].asBool() ) {
|
90
|
_v1290PartEventProc = new V1290DataProcessor();
|
91
|
_v1290PartEventProc->set_DAQ_map(&_map);
|
92
|
|
93
|
_dataProcessManager.SetPartEventProc("V1290", _v1290PartEventProc);
|
94
|
} else {
|
95
|
this->disableEquipment("V1290");
|
96
|
}
|
97
|
|
98
|
// Comfigure the V1724 (fADC) data processor.
|
99
|
assert(configJSON.isMember("Enable_V1724_Unpacking"));
|
100
|
if ( configJSON["Enable_V1724_Unpacking"].asBool() ) {
|
101
|
_v1724PartEventProc = new V1724DataProcessor();
|
102
|
_v1724PartEventProc->set_DAQ_map(&_map);
|
103
|
|
104
|
assert(configJSON.isMember("Do_V1724_Zero_Suppression"));
|
105
|
bool zs = configJSON["Do_V1724_Zero_Suppression"].asBool();
|
106
|
_v1724PartEventProc->set_zero_supression(zs);
|
107
|
|
108
|
assert(configJSON.isMember("V1724_Zero_Suppression_Threshold"));
|
109
|
int zs_threshold = configJSON["V1724_Zero_Suppression_Threshold"].asInt();
|
110
|
_v1724PartEventProc->set_zs_threshold(zs_threshold);
|
111
|
|
112
|
_dataProcessManager.SetPartEventProc("V1724", _v1724PartEventProc);
|
113
|
} else {
|
114
|
this->disableEquipment("V1724");
|
115
|
}
|
116
|
|
117
|
// Comfigure the V1731 (fADC) data processor.
|
118
|
assert(configJSON.isMember("Enable_V1731_Unpacking"));
|
119
|
if ( configJSON["Enable_V1731_Unpacking"].asBool() ) {
|
120
|
_v1731PartEventProc = new V1731DataProcessor();
|
121
|
_v1731PartEventProc->set_DAQ_map(&_map);
|
122
|
|
123
|
assert(configJSON.isMember("Do_V1731_Zero_Suppression"));
|
124
|
bool zs = configJSON["Do_V1731_Zero_Suppression"].asBool();
|
125
|
_v1731PartEventProc->set_zero_supression(zs);
|
126
|
|
127
|
assert(configJSON.isMember("V1731_Zero_Suppression_Threshold"));
|
128
|
int zs_threshold = configJSON["V1731_Zero_Suppression_Threshold"].asInt();
|
129
|
_v1731PartEventProc->set_zs_threshold(zs_threshold);
|
130
|
|
131
|
_dataProcessManager.SetPartEventProc("V1731", _v1731PartEventProc);
|
132
|
} else {
|
133
|
this->disableEquipment("V1731");
|
134
|
}
|
135
|
|
136
|
// Comfigure the V830 (scaler) data processor.
|
137
|
assert(configJSON.isMember("Enable_V830_Unpacking"));
|
138
|
if ( configJSON["Enable_V830_Unpacking"].asBool() ) {
|
139
|
_v830FragmentProc = new V830DataProcessor();
|
140
|
_v830FragmentProc->set_DAQ_map(&_map);
|
141
|
|
142
|
_dataProcessManager.SetFragmentProc("V830", _v830FragmentProc);
|
143
|
} else {
|
144
|
this->disableEquipment("V830");
|
145
|
}
|
146
|
|
147
|
// Comfigure the VLSB (tracker board) data processor.
|
148
|
assert(configJSON.isMember("Enable_VLSB_Unpacking"));
|
149
|
if (configJSON["Enable_VLSB_Unpacking"].asBool()) {
|
150
|
_vLSBFragmentProc = new VLSBDataProcessor();
|
151
|
_vLSBFragmentProc->set_DAQ_map(&_map);
|
152
|
|
153
|
_dataProcessManager.SetFragmentProc("VLSB_C", _vLSBFragmentProc);
|
154
|
} else {
|
155
|
this->disableEquipment("VLSB_C");
|
156
|
}
|
157
|
|
158
|
// Comfigure the DBB (EMR board) data processor.
|
159
|
assert(configJSON.isMember("Enable_DBB_Unpacking"));
|
160
|
if ( configJSON["Enable_DBB_Unpacking"].asBool() ) {
|
161
|
_DBBFragmentProc = new DBBDataProcessor();
|
162
|
_DBBFragmentProc->set_DAQ_map(&_map);
|
163
|
|
164
|
_dataProcessManager.SetFragmentProc("DBB", _DBBFragmentProc);
|
165
|
} else {
|
166
|
this->disableEquipment("DBB");
|
167
|
}
|
168
|
|
169
|
// _dataProcessManager.DumpProcessors();
|
170
|
|
171
|
return true;
|
172
|
}
|
173
|
|
174
|
|
175
|
bool InputCppDAQData::readNextEvent() {
|
176
|
// Use the MDfileManager object to get the next event.
|
177
|
_eventPtr = _dataFileManager.GetNextEvent();
|
178
|
if (!_eventPtr)
|
179
|
return false;
|
180
|
|
181
|
return true;
|
182
|
}
|
183
|
|
184
|
bool InputCppDAQData::getCurEvent() {
|
185
|
// Create new Json documents.
|
186
|
Json::Value xDocRoot; // Root of the event
|
187
|
Json::FastWriter xJSONWr;
|
188
|
Json::Value xDocSpill;
|
189
|
|
190
|
// Order all processor classes to fill in xDocSpill.
|
191
|
if (_v1290PartEventProc)
|
192
|
_v1290PartEventProc->set_JSON_doc(&xDocSpill);
|
193
|
|
194
|
if (_v1724PartEventProc)
|
195
|
_v1724PartEventProc->set_JSON_doc(&xDocSpill);
|
196
|
|
197
|
if (_v1731PartEventProc)
|
198
|
_v1731PartEventProc->set_JSON_doc(&xDocSpill);
|
199
|
|
200
|
if (_v830FragmentProc)
|
201
|
_v830FragmentProc->set_JSON_doc(&xDocSpill);
|
202
|
|
203
|
if (_vLSBFragmentProc)
|
204
|
_vLSBFragmentProc->set_JSON_doc(&xDocSpill);
|
205
|
|
206
|
if (_DBBFragmentProc)
|
207
|
_DBBFragmentProc->set_JSON_doc(&xDocSpill);
|
208
|
|
209
|
// Now do the loop over the binary DAQ data.
|
210
|
try {
|
211
|
_dataProcessManager.Process(_eventPtr);
|
212
|
}
|
213
|
// Deal with exceptions
|
214
|
catch(MDexception & lExc) {
|
215
|
Squeak::mout(Squeak::error) << "Unpacking exception, DAQ Event skipped" << std::endl;
|
216
|
Squeak::mout(Squeak::error) << lExc.GetDescription() << endl;
|
217
|
}
|
218
|
catch(std::exception & lExc) {
|
219
|
Squeak::mout(Squeak::error) << "Standard exception" << std::endl;
|
220
|
Squeak::mout(Squeak::error) << lExc.what() << std::endl;
|
221
|
}
|
222
|
catch(...) {
|
223
|
Squeak::mout(Squeak::error) << "Unknown exception occurred..." << std::endl;
|
224
|
}
|
225
|
|
226
|
// Finally attach the spill to the document root
|
227
|
xDocRoot["event_data"] = xDocSpill;
|
228
|
xDocRoot["spill_num"] = _dataProcessManager.GetSpillNumber();
|
229
|
unsigned int event_type = _dataProcessManager.GetEventType();
|
230
|
xDocRoot["daq_event_type"] = event_type_to_str(event_type);
|
231
|
// cout<<xDocRoot<<endl;
|
232
|
|
233
|
_next_event = xDocRoot;
|
234
|
return true;
|
235
|
}
|
236
|
|
237
|
bool InputCppDAQData::death() {
|
238
|
// Free the memory.
|
239
|
if (_v1290PartEventProc) delete _v1290PartEventProc;
|
240
|
if (_v1724PartEventProc) delete _v1724PartEventProc;
|
241
|
if (_v1731PartEventProc) delete _v1731PartEventProc;
|
242
|
if (_v830FragmentProc) delete _v830FragmentProc;
|
243
|
if (_vLSBFragmentProc) delete _vLSBFragmentProc;
|
244
|
if (_DBBFragmentProc) delete _DBBFragmentProc;
|
245
|
|
246
|
return true;
|
247
|
}
|
248
|
|
249
|
std::string InputCppDAQData::event_type_to_str(int pType) {
|
250
|
std::string event_type;
|
251
|
switch (pType) {
|
252
|
case START_OF_BURST :
|
253
|
event_type = "start_of_burst";
|
254
|
break;
|
255
|
|
256
|
case END_OF_BURST:
|
257
|
event_type = "end_of_burst";
|
258
|
break;
|
259
|
|
260
|
case PHYSICS_EVENT :
|
261
|
event_type = "physics_event";
|
262
|
break;
|
263
|
|
264
|
case CALIBRATION_EVENT :
|
265
|
event_type = "calibration_event";
|
266
|
break;
|
267
|
|
268
|
case START_OF_RUN :
|
269
|
event_type = "start_of_run";
|
270
|
break;
|
271
|
|
272
|
case END_OF_RUN:
|
273
|
event_type = "end_of_run";
|
274
|
break;
|
275
|
|
276
|
default :
|
277
|
std::stringstream xConv;
|
278
|
xConv << pType << " (unknown)";
|
279
|
event_type = xConv.str();
|
280
|
break;
|
281
|
}
|
282
|
return event_type;
|
283
|
}
|
284
|
|
285
|
std::string InputCppDAQData::getNextEvent() {
|
286
|
Json::FastWriter xJsonWr;
|
287
|
if (readNextEvent()) {
|
288
|
getCurEvent();
|
289
|
return xJsonWr.write(_next_event);
|
290
|
}
|
291
|
return "";
|
292
|
}
|
293
|
|
294
|
int InputCppDAQData::getSpillNumber(Json::Value xDocRoot) {
|
295
|
assert(xDocRoot.isMember("spill_num"));
|
296
|
return xDocRoot["spill_num"].asInt();
|
297
|
}
|
298
|
|
299
|
std::string InputCppDAQData::getNextSpill() {
|
300
|
// we need to check spill number for next event to decide whether it should
|
301
|
// be added to the spill; means the first event for the next spill gets filled
|
302
|
// on the previous loop, which makes the logic a bit more obscure
|
303
|
Json::FastWriter xJsonWr;
|
304
|
|
305
|
Json::Value spill(Json::objectValue);
|
306
|
spill["daq_data"] = Json::Value(Json::arrayValue);
|
307
|
if (_next_event.isNull()) { // if first event, call unpack once
|
308
|
getNextEvent();
|
309
|
if (_next_event.isNull()) {
|
310
|
return "";
|
311
|
}
|
312
|
}
|
313
|
// next event is always the first event of this spill
|
314
|
int spill_number = getSpillNumber(_next_event);
|
315
|
spill["daq_data"].append(_next_event);
|
316
|
|
317
|
// loop over events; if the spill number changes, then we're done
|
318
|
bool finished = true;
|
319
|
while (_eventPtr != NULL) {
|
320
|
getNextEvent();
|
321
|
finished = false;
|
322
|
if (getSpillNumber(_next_event) != spill_number) {
|
323
|
return xJsonWr.write(spill);
|
324
|
}
|
325
|
if (_eventPtr) {
|
326
|
spill["daq_data"].append(_next_event);
|
327
|
}
|
328
|
}
|
329
|
|
330
|
// for the last spill, getNextEvent() goes false but spill buffer not empty
|
331
|
if (!finished) {
|
332
|
return xJsonWr.write(spill);
|
333
|
}
|
334
|
return "";
|
335
|
}
|
336
|
|
337
|
|
338
|
|