Bug Summary

File:libraries/DAQ/JEventSource_EVIO.cc
Location:line 4572, column 67
Description:Dereference of null pointer

Annotated Source Code

1// $Id$
2// $HeadURL$
3//
4// File: JEventSource_EVIO.cc
5// Created: Tue Aug 7 15:22:29 EDT 2012
6// Creator: davidl (on Darwin harriet.jlab.org 11.4.0 i386)
7//
8
9// See comments in JEventSource_EVIO.h for overview description
10
11#include <unistd.h>
12#include <stdint.h>
13
14#include <string>
15#include <cmath>
16#include <iomanip>
17using namespace std;
18
19
20// This flag allows us to switch back and forth from using HDEVIO and
21// the CODA-supplied EVIO
22#define USE_HDEVIO1 1
23
24//#define ENABLE_UPSAMPLING
25
26#ifdef HAVE_EVIO1
27
28#if USE_HDEVIO1 == 0
29#include <evioFileChannel.hxx>
30#endif
31
32extern "C" uint32_t *swap_int32_t(uint32_t *data, unsigned int length, uint32_t *dest);
33#endif // HAVE_EVIO
34
35#ifdef HAVE_ET
36//#include <evioETChannel.hxx>
37#include <et.h>
38#endif // HAVE_ET
39
40#include "JEventSourceGenerator_EVIO.h"
41//#include "JFactoryGenerator_DAQ.h"
42#include "JEventSource_EVIO.h"
43
44using namespace jana;
45
46#include <DANA/DStatusBits.h>
47#include <TTAB/DTranslationTable.h>
48#include <TTAB/DTranslationTable_factory.h>
49#include <DAQ/Df125EmulatorAlgorithm_factory.h>
50#include <DAQ/Df250EmulatorAlgorithm_factory.h>
51
52#define _DBG_DAQ(A)cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<":"<<
52<<" 0x"<<hex<<A<<" cntrl:0x"<<
(A&0xF0000000)<<dec<<" slot:"<<((A>>
22)&0x1F)<<endl
cerr<<__FILE__"libraries/DAQ/JEventSource_EVIO.cc"<<":"<<__LINE__52<<" 0x"<<hex<<A<<" cntrl:0x"<<(A&0xF0000000)<<dec<<" slot:"<<((A>>22)&0x1F)<<endl
53
54// Make us a plugin
55#include <JANA/JApplication.h>
56//extern "C"{
57// void InitPlugin(JApplication *app){
58// InitJANAPlugin(app);
59// app->AddEventSourceGenerator(new JEventSourceGenerator_EVIO());
60// app->AddFactoryGenerator(new JFactoryGenerator_DAQ());
61// }
62//} // "C"
63
64// if we don't find a run number in the file, then it's nice to let the user know
65static bool WARN_USER_RUN_FILENAME = false;
66
67set<uint32_t> ROCIDS_TO_PARSE;
68
69//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
70// If EVIO support is not available, define dummy methods
71#ifndef HAVE_EVIO1
72JEventSource_EVIO::JEventSource_EVIO(const char* source_name):JEventSource(source_name){
73 cerr << endl;
74 cerr << "You are trying to use code requiring EVIO when support" << endl;
75 cerr << "for EVIO was not built into this binary. Set your" << endl;
76 cerr << "EVIOROOT *and* your ETROOT environment variables to" << endl;
77 cerr << "point to your EVIO installation and recompile." << endl;
78 cerr << endl;
79 exit(-1);
80}
81 JEventSource_EVIO::~JEventSource_EVIO(){}
82jerror_t JEventSource_EVIO::GetEvent(jana::JEvent &event){return NOERROR;}
83 void JEventSource_EVIO::FreeEvent(jana::JEvent &event){}
84jerror_t JEventSource_EVIO::GetObjects(jana::JEvent &event, jana::JFactory_base *factory){return NOERROR;}
85jerror_t JEventSource_EVIO::ReadEVIOEvent(uint32_t* &buf){return NOERROR;}
86//:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
87
88#else // HAVE_EVIO
89
90//----------------
91// Constructor
92//----------------
93JEventSource_EVIO::JEventSource_EVIO(const char* source_name):JEventSource(source_name)
94{
95 // Initialize connection objects and flags to NULL
96 et_connected = false;
97 //chan = NULL;
98 hdevio = NULL__null;
99 source_type = kNoSource;
100 quit_on_next_ET_timeout = false;
101
102 // Initialize dedicated JStreamLog used for debugging messages
103 evioout.SetTag("--- EVIO ---: ");
104 evioout.SetTimestampFlag();
105 evioout.SetThreadstampFlag();
106
107 // Define base set of status bits
108 if(japp) DStatusBits::SetStatusBitDescriptions(japp);
109
110 // Get configuration parameters
111 AUTODETECT_MODULE_TYPES = true;
112 DUMP_MODULE_MAP = false;
113 MAKE_DOM_TREE = true;
114 PARSE_EVIO_EVENTS = true;
115 PARSE_F250 = true;
116 PARSE_F125 = true;
117 PARSE_F1TDC = true;
118 PARSE_CAEN1290TDC = true;
119 PARSE_CONFIG = true;
120 PARSE_BOR = true;
121 PARSE_EPICS = true;
122 PARSE_EVENTTAG = true;
123 PARSE_TRIGGER = true;
124 BUFFER_SIZE = 20000000; // in bytes
125 ET_STATION_NEVENTS = 10;
126 ET_STATION_CREATE_BLOCKING = false;
127 ET_DEBUG_WORDS_TO_DUMP = 0;
128 LOOP_FOREVER = false;
129 VERBOSE = 0;
130 TIMEOUT = 2.0;
131 MODTYPE_MAP_FILENAME = "modtype.map";
132 ENABLE_DISENTANGLING = true;
133
134 F125_EMULATION_MODE = kEmulationAuto;
135 F250_EMULATION_MODE = kEmulationAuto;
136
137 USER_RUN_NUMBER = 0;
138 F125PULSE_NUMBER_FILTER = 1000;
139 F250PULSE_NUMBER_FILTER = 1000;
140
141 if(gPARMS){
142 // JANA doesn't know about EmulationModeType so we use temporary variables
143 uint32_t f250_emulation_mode = F250_EMULATION_MODE;
144 uint32_t f125_emulation_mode = F125_EMULATION_MODE;
145
146 gPARMS->SetDefaultParameter("EVIO:AUTODETECT_MODULE_TYPES", AUTODETECT_MODULE_TYPES, "Try and guess the module type tag,num values for which there is no module map entry.");
147 gPARMS->SetDefaultParameter("EVIO:DUMP_MODULE_MAP", DUMP_MODULE_MAP, "Write module map used to file when source is destroyed. n.b. If more than one input file is used, the map file will be overwritten!");
148 gPARMS->SetDefaultParameter("EVIO:MAKE_DOM_TREE", MAKE_DOM_TREE, "Set this to 0 to disable generation of EVIO DOM Tree and parsing of event. (for benchmarking/debugging)");
149 gPARMS->SetDefaultParameter("EVIO:PARSE_EVIO_EVENTS", PARSE_EVIO_EVENTS, "Set this to 0 to disable parsing of event but still make the DOM tree, so long as MAKE_DOM_TREE isn't set to 0. (for benchmarking/debugging)");
150 gPARMS->SetDefaultParameter("EVIO:PARSE_F250", PARSE_F250, "Set this to 0 to disable parsing of data from F250 ADC modules (for benchmarking/debugging)");
151 gPARMS->SetDefaultParameter("EVIO:PARSE_F125", PARSE_F125, "Set this to 0 to disable parsing of data from F125 ADC modules (for benchmarking/debugging)");
152 gPARMS->SetDefaultParameter("EVIO:PARSE_F1TDC", PARSE_F1TDC, "Set this to 0 to disable parsing of data from F1TDC modules (for benchmarking/debugging)");
153 gPARMS->SetDefaultParameter("EVIO:PARSE_CAEN1290TDC", PARSE_CAEN1290TDC, "Set this to 0 to disable parsing of data from CAEN 1290 TDC modules (for benchmarking/debugging)");
154 gPARMS->SetDefaultParameter("EVIO:PARSE_CONFIG", PARSE_CONFIG, "Set this to 0 to disable parsing of ROC configuration data in the data stream (for benchmarking/debugging)");
155 gPARMS->SetDefaultParameter("EVIO:PARSE_BOR", PARSE_BOR, "Set this to 0 to disable parsing of BOR events from the data stream (for benchmarking/debugging)");
156 gPARMS->SetDefaultParameter("EVIO:PARSE_EPICS", PARSE_EPICS, "Set this to 0 to disable parsing of EPICS events from the data stream (for benchmarking/debugging)");
157 gPARMS->SetDefaultParameter("EVIO:PARSE_EVENTTAG", PARSE_EVENTTAG, "Set this to 0 to disable parsing of event tag data in the data stream (for benchmarking/debugging)");
158 gPARMS->SetDefaultParameter("EVIO:PARSE_TRIGGER", PARSE_TRIGGER, "Set this to 0 to disable parsing of the built trigger bank from CODA (for benchmarking/debugging)");
159
160 gPARMS->SetDefaultParameter("EVIO:BUFFER_SIZE", BUFFER_SIZE, "Size in bytes to allocate for holding a single EVIO event.");
161 gPARMS->SetDefaultParameter("EVIO:ET_STATION_NEVENTS", ET_STATION_NEVENTS, "Number of events to use if we have to create the ET station. Ignored if station already exists.");
162 gPARMS->SetDefaultParameter("EVIO:ET_STATION_CREATE_BLOCKING", ET_STATION_CREATE_BLOCKING, "Set this to 0 to create station in non-blocking mode (default is to create it in blocking mode). Ignored if station already exists.");
163 gPARMS->SetDefaultParameter("EVIO:ET_DEBUG_WORDS_TO_DUMP", ET_DEBUG_WORDS_TO_DUMP, "Number of words to dump to screen from ET buffer (useful for debugging only).");
164 gPARMS->SetDefaultParameter("EVIO:LOOP_FOREVER", LOOP_FOREVER, "If reading from EVIO file, keep re-opening file and re-reading events forever (only useful for debugging) If reading from ET, this is ignored.");
165 gPARMS->SetDefaultParameter("EVIO:VERBOSE", VERBOSE, "Set verbosity level for processing and debugging statements while parsing. 0=no debugging messages. 10=all messages");
166 gPARMS->SetDefaultParameter("ET:TIMEOUT", TIMEOUT, "Set the timeout in seconds for each attempt at reading from ET system (repeated attempts will still be made indefinitely until program quits or the quit_on_et_timeout flag is set.");
167 gPARMS->SetDefaultParameter("EVIO:MODTYPE_MAP_FILENAME", MODTYPE_MAP_FILENAME, "Optional module type conversion map for use with files generated with the non-standard module types");
168 gPARMS->SetDefaultParameter("EVIO:ENABLE_DISENTANGLING", ENABLE_DISENTANGLING, "Enable/disable disentangling of multi-block events. Enabled by default. Set to 0 to disable.");
169
170 gPARMS->SetDefaultParameter("EVIO:F250_EMULATION_MODE", f250_emulation_mode, "Set f250 emulation mode. 0=no emulation, 1=always, 2=auto. Default is 2 (auto).");
171 gPARMS->SetDefaultParameter("EVIO:F125_EMULATION_MODE", f125_emulation_mode, "Set f125 emulation mode. 0=no emulation, 1=always, 2=auto. Default is 2 (auto).");
172
173 gPARMS->SetDefaultParameter("EVIO:RUN_NUMBER", USER_RUN_NUMBER, "User-supplied run number. Override run number from other sources with this.(will be ignored if set to zero)");
174 gPARMS->SetDefaultParameter("EVIO:F125PULSE_NUMBER_FILTER", F125PULSE_NUMBER_FILTER, "Ignore data for DF125XXX objects with a pulse number equal or greater than this.");
175 gPARMS->SetDefaultParameter("EVIO:F250PULSE_NUMBER_FILTER", F250PULSE_NUMBER_FILTER, "Ignore data for DF250XXX objects with a pulse number equal or greater than this.");
176
177 F250_EMULATION_MODE = (EmulationModeType)f250_emulation_mode;
178 F125_EMULATION_MODE = (EmulationModeType)f125_emulation_mode;
179 }
180
181 // Try to open the file.
182 try {
183
184 if(VERBOSE>0) evioout << "Attempting to open \""<<this->source_name<<"\" as EVIO file..." <<endl;
185
186#if USE_HDEVIO1
187 //---------- HDEVIO ------------
188 hdevio = new HDEVIO(this->source_name);
189 if( ! hdevio->is_open ) throw std::exception(); // throw exception if unable to open
190#else // USE_HDEVIO
191 //-------- CODA EVIO -----------
192 jerr << "You are attempting to use the CODA Channels library for reading" << endl;
193 jerr << "and EVIO file and this mechanism has been disabled from in the" << endl;
194 jerr << "DAQ library. Contact davidl@jlab.org if you need this to be" << endl;
195 jerr << "reinstated." << endl;
196 quit(0);
197 //chan = new evioFileChannel(this->source_name, "r", BUFFER_SIZE);
198 //chan->open(); // open the file. Throws exception if not successful
199
200#endif // USE_HDEVIO
201
202 source_type = kFileSource;
203
204 } catch (std::exception &e) {
205
206#ifdef HAVE_ET
207 // Could not open file. Check if name starts with "ET:"
208 //chan = NULL;
209 if(this->source_name.substr(0,3) == "ET:"){
210 if(VERBOSE>0) evioout << "Attempting to open \""<<this->source_name<<"\" as ET (network) source..." <<endl;
211 ConnectToET(source_name);
212 }
213
214 if(!et_connected) throw JException("Failed to open ET system: " + this->source_name);
215
216 // open the channel. Throws exception if not successful
217 // chan->open(); // evioETchannel no longer used
218 source_type = kETSource;
219
220#else // HAVE_ET
221
222 // No ET and the file didn't work so re-throw the exception
223 if(this->source_name.substr(0,3) == "ET:"){
224 cerr << endl;
225 cerr << "=== ERROR: ET source specified and this was compiled without ===" << endl;
226 cerr << "=== ET support. You need to install ET and set your ===" << endl;
227 cerr << "=== ETROOT environment variable appropriately before ===" << endl;
228 cerr << "=== recompiling. ===" << endl;
229 cerr << endl;
230 }
231 throw e;
232
233#endif // HAVE_ET
234 }
235 if(VERBOSE>0) evioout << "Success opening event source \"" << this->source_name << "\"!" <<endl;
236
237
238 // Create list of data types this event source can provide
239 // (must match what is returned by JObject::className() )
240 // n.b. there is an ugly hack down in GetObjects that will
241 // probably also need a line added for each data type added
242 // here.
243 event_source_data_types.insert("Df250Config");
244 event_source_data_types.insert("Df250PulseIntegral");
245 event_source_data_types.insert("Df250StreamingRawData");
246 event_source_data_types.insert("Df250WindowSum");
247 event_source_data_types.insert("Df250PulseRawData");
248 event_source_data_types.insert("Df250TriggerTime");
249 event_source_data_types.insert("Df250PulseTime");
250 event_source_data_types.insert("Df250PulsePedestal");
251 event_source_data_types.insert("Df250WindowRawData");
252 event_source_data_types.insert("Df125Config");
253 event_source_data_types.insert("Df125PulseIntegral");
254 event_source_data_types.insert("Df125TriggerTime");
255 event_source_data_types.insert("Df125PulseTime");
256 event_source_data_types.insert("Df125PulsePedestal");
257 event_source_data_types.insert("Df125WindowRawData");
258 event_source_data_types.insert("Df125CDCPulse");
259 event_source_data_types.insert("Df125FDCPulse");
260 event_source_data_types.insert("DF1TDCConfig");
261 event_source_data_types.insert("DF1TDCHit");
262 event_source_data_types.insert("DF1TDCTriggerTime");
263 event_source_data_types.insert("DCAEN1290TDCConfig");
264 event_source_data_types.insert("DCAEN1290TDCHit");
265 event_source_data_types.insert("DCODAEventInfo");
266 event_source_data_types.insert("DCODAROCInfo");
267 event_source_data_types.insert("DTSscalers");
268 event_source_data_types.insert("DEPICSvalue");
269 event_source_data_types.insert("DEventTag");
270 event_source_data_types.insert("DL1Info");
271
272 // Read in optional module type translation map if it exists
273 ReadOptionalModuleTypeTranslation();
274
275 last_run_number = 0;
276 filename_run_number = 0;
277 current_event_count = 0;
278
279 // Try extracting the run number from the filename. (This is
280 // only used if the run number is not found in the EVIO data.)
281 size_t pos2 = this->source_name.find_last_of('_');
282 if(pos2 != string::npos){
283 size_t pos1 = this->source_name.find_last_of('_', pos2-1);
284 if(pos1 != string::npos){
285 pos1++;
286 string runstr = this->source_name.substr(pos1, pos2-pos1);
287 if(runstr.length()>0) filename_run_number = atoi(runstr.c_str());
288 }
289 }
290
291 pthread_mutex_init(&evio_buffer_pool_mutex, NULL__null);
292 pthread_mutex_init(&stored_events_mutex, NULL__null);
293 pthread_mutex_init(&current_event_count_mutex, NULL__null);
294 pthread_rwlock_init(&BOR_lock, NULL__null);
295}
296
297//----------------
298// Destructor
299//----------------
300JEventSource_EVIO::~JEventSource_EVIO()
301{
302 // close event source here
303// if(chan){
304// if(VERBOSE>0) evioout << "Closing event source \"" << this->source_name << "\"" <<endl;
305// chan->close();
306// delete chan;
307// }
308
309#ifdef HAVE_ET
310 if(et_connected){
311 if(VERBOSE>0) evioout << "Closing ET connection \"" << this->source_name << "\"" <<endl;
312 et_close(sys_id);
313 et_connected = false;
314 }
315#endif
316
317 if(hdevio){
318 if(VERBOSE>0) evioout << "Closing hdevio event source \"" << this->source_name << "\"" <<endl;
319 hdevio->PrintStats();
320 delete hdevio;
321 }
322
323 // Release memory used for the event buffer pool
324 while(!evio_buffer_pool.empty()){
325 free(evio_buffer_pool.front());
326 evio_buffer_pool.pop_front();
327 }
328
329 // Delete any BOR config objects
330 for(uint32_t i=0; i<BORobjs.size(); i++) delete BORobjs[i];
331 BORobjs.clear();
332
333 // Optionally dump the module map
334 if(DUMP_MODULE_MAP)DumpModuleMap();
335}
336
337//---------------------------------
338// ReadOptionalModuleTypeTranslation
339//---------------------------------
340void JEventSource_EVIO::ReadOptionalModuleTypeTranslation(void)
341{
342 // Some data may be taken with bad ROLs or drivers that
343 // write module type values that are non-standard. This
344 // allows the user to specify a simple text file that
345 // can be read in to translate the types found in the
346 // file to another type so that they can be properly parsed.
347 ifstream ifs(MODTYPE_MAP_FILENAME.c_str());
348 if(!ifs.is_open()) return;
349
350 cout << "Opened JLab module type translation map: " << endl;
351 cout << " " << MODTYPE_MAP_FILENAME << endl;
352 while(ifs.good()){
353 char line[256];
354 ifs.getline(line, 256);
355 if(ifs.gcount() < 1) break;
356 if(line[0] == '#') continue;
357
358 stringstream ss(line);
359 uint32_t from=10000, to=10000;
360 ss >> from >> to; // from=evio to=TT
361 if( to==10000 ){
362 if( from!=10000){
363 cout << "unable to convert line:" << endl;
364 cout << " " << line;
365 }
366 }else{
367 modtype_translate[(MODULE_TYPE)from] = (MODULE_TYPE)to;
368 }
369 }
370 ifs.close();
371
372 cout << " Read " << modtype_translate.size() << " entries" << endl;
373 map<MODULE_TYPE,MODULE_TYPE>::iterator iter;
374 for(iter=modtype_translate.begin(); iter != modtype_translate.end(); iter++){
375 cout << " type " << iter->first << " -> type " << iter->second << endl;
376 }
377}
378
379//----------------
380// ConnectToET
381//----------------
382void JEventSource_EVIO::ConnectToET(const char* source_name)
383{
384#ifdef HAVE_ET
385
386 /// Format for ET source strings is:
387 ///
388 /// ET:session:station:host:port
389 ///
390 /// The session is used to form the filename of the ET
391 /// system. For example, if an session of "eb" is specified,
392 /// then a file named "/tmp/et_sys_eb" is assumed to be
393 /// what should be opened. If no session is specified (or
394 /// an empty session name) then "none" is used as the session.
395 ///
396 /// If the station name specified does not exist, it will
397 /// be created. If it does exist, the existing station will
398 /// be used. If no station is specified, then the station
399 /// name "DANA" will be used. Any station created will be
400 /// set to "blocking" *unless* the configuration paramter
401 /// EVIO:ET_STATION_CREATE_BLOCKING is set to "0"
402 /// in which case it will be set to non-blocking.
403 ///
404 /// If the host is specified, then an attempt will be made
405 /// to open that system. If it is not specified, then
406 /// it will attempt to open an ET system on the local machine.
407 ///
408 /// If port is specified, it is used as the TCP port number
409 /// on the remote host to attach to. If the host is not
410 /// specified (i.e. by having two colons and therefore
411 /// an empty string) then the port is ignored. If the
412 /// port is omitted or specified as "0", then the default
413 /// port is used.
414 ///
415
416 // Split source name into session, station, etc...
417 vector<string> fields;
418 string str = source_name;
419 size_t startpos=0, endpos=0;
420 while((endpos = str.find(":", startpos)) != str.npos){
421 size_t len = endpos-startpos;
422 fields.push_back(len==0 ? "":str.substr(startpos, len));
423 startpos = endpos+1;
424 }
425 if(startpos<str.length()) fields.push_back(str.substr(startpos, str.npos));
426
427 string session = fields.size()>1 ? fields[1]:"";
428 string station = fields.size()>2 ? fields[2]:"";
429 string host = fields.size()>3 ? fields[3]:"localhost";
430 int port = fields.size()>4 ? atoi(fields[4].c_str()):ET_SERVER_PORT;
431
432 if(session == "") session = "none";
433 if(station == "") station = "DANA";
434 if(host == "") host = "localhost";
435 string fname = session.at(0)=='/' ? session:(string("/tmp/et_sys_") + session);
436
437 // Report to user what we're doing
438 jout << " Opening ET system:" << endl;
439 if(session!=fname) jout << " session: " << session << endl;
440 jout << " station: " << station << endl;
441 jout << " system file: " << fname << endl;
442 jout << " host: " << host << endl;
443 if(port !=0) jout << " port: " << port << endl;
444
445 // connect to the ET system
446 et_openconfig openconfig;
447 et_open_config_init(&openconfig);
448 if(host != ""){
449 if(host.find("239.")==0){
450 cout<<__FILE__"libraries/DAQ/JEventSource_EVIO.cc"<<":"<<__LINE__450<<" Configuring input ET for multicast" << endl;
451 et_open_config_setcast(openconfig, ET_MULTICAST);
452 et_open_config_addmulticast(openconfig, host.c_str());
453 et_open_config_sethost(openconfig, ET_HOST_ANYWHERE);
454 et_open_config_setport(openconfig, port);
455 struct timespec tspec={5,5};
456 et_open_config_settimeout(openconfig, tspec);
457 et_open_config_setwait(openconfig, ET_OPEN_WAIT);
458 }else{
459 cout<<__FILE__"libraries/DAQ/JEventSource_EVIO.cc"<<":"<<__LINE__459<<" Configuring input ET for direct connection" << endl;
460 et_open_config_setcast(openconfig, ET_DIRECT);
461 et_open_config_setmode(openconfig, ET_HOST_AS_LOCAL); // ET_HOST_AS_LOCAL or ET_HOST_AS_REMOTE
462 et_open_config_sethost(openconfig, host.c_str());
463 et_open_config_setport(openconfig, ET_BROADCAST_PORT);
464 if(port != 0)et_open_config_setserverport(openconfig, port);
465 }
466 }
467 int err = et_open(&sys_id,fname.c_str(),openconfig);
468 if(err != ET_OK){
469 cerr << __FILE__"libraries/DAQ/JEventSource_EVIO.cc"<<":"<<__LINE__469<<" Problem opening ET system"<<endl;
470 cerr << et_perror(err);
471 return;
472 }
473
474 // create station config in case no station exists
475 et_statconfig et_station_config;
476 et_station_config_init(&et_station_config);
477 et_station_config_setblock(et_station_config, ET_STATION_CREATE_BLOCKING ? ET_STATION_BLOCKING:ET_STATION_NONBLOCKING);
478 et_station_config_setselect(et_station_config,ET_STATION_SELECT_ALL);
479 et_station_config_setuser(et_station_config,ET_STATION_USER_MULTI);
480 et_station_config_setrestore(et_station_config,ET_STATION_RESTORE_OUT);
481 et_station_config_setcue(et_station_config,ET_STATION_NEVENTS);
482 et_station_config_setprescale(et_station_config,1);
483 cout<<"ET station configured\n";
484
485 // create station if not already created
486 int status=et_station_create(sys_id,&sta_id,station.c_str(),et_station_config);
487 if((status!=ET_OK)&&(status!=ET_ERROR_EXISTS)) {
488 et_close(sys_id);
489 cerr << "Unable to create station " << station << endl;
490 cerr << et_perror(status);
491
492 // Check that the number of events in the ET system is not
493 // less than the number of events we specified for the station CUE.
494 int Nevents = 0;
495 et_system_getnumevents(sys_id, &Nevents);
496 if(Nevents <= ET_STATION_NEVENTS){
497 jerr << "NOTE: The number of events specified for the station cue is equal to" << endl;
498 jerr << "or greater than the number of events in the entire ET system:" << endl;
499 jerr << endl;
500 jerr << " " << ET_STATION_NEVENTS << " >= " << Nevents << endl;
501 jerr << endl;
502 jerr << "Try re-running with: " << endl;
503 jerr << endl;
504 jerr << " -PEVIO:ET_STATION_NEVENTS=" << (Nevents+1)/2 << endl;
505 jerr << endl;
506 }
507 return;
508 }
509 if(status==ET_ERROR_EXISTS){
510 jout << " Using existing ET station " << station << endl;
511 }else{
512 jout << " ET station " << station << " created\n";
513 }
514
515 // Attach to the ET station
516 status=et_station_attach(sys_id,sta_id,&att_id);
517 if(status!=ET_OK) {
518 et_close(sys_id);
519 jerr << "Unable to attach to station " << station << endl;
520 return;
521 }
522
523 jout << "...now connected to ET system: " << fname
524 << ", station: " << station << " (station id=" << sta_id << ", attach id=" << att_id <<")" << endl;
525
526 et_connected = true;
527 // chan = new evioETChannel(sys_id, att_id);
528
529 // Make sure the size of event buffers we will allocate are at least as big
530 // as the event size used in the ET system
531 size_t eventsize;
532 et_system_geteventsize(sys_id, &eventsize);
533 if((uint32_t)eventsize > BUFFER_SIZE){
534 jout<<" Events in ET system are larger than currently set buffer size:"<<endl;
535 jout<<" "<<eventsize<<" > "<<BUFFER_SIZE<<endl;
536 jout<<" Setting BUFFER_SIZE to "<<eventsize<<endl;
537 BUFFER_SIZE = (uint32_t)eventsize;
538 }else{
539 jout<<" ET system event size:"<<eventsize<<" JEventSource_EVIO.BUFFER_SIZE:"<<BUFFER_SIZE<<endl;
540 }
541
542#else
543 jerr << endl;
544 jerr << "You are attempting to connect to an ET system using a binary that" <<endl;
545 jerr << "was compiled without ET support. Please reconfigure and recompile" <<endl;
546 jerr << "To get ET support." << endl;
547 jerr << endl;
548 throw exception();
549#endif // HAVE_ET
550}
551
552//----------------
553// Cleanup
554//----------------
555void JEventSource_EVIO::Cleanup(void)
556{
557 /// This is called internally by the JEventSource_EVIO class
558 /// once all events have been read in. Its purpose is to
559 /// free the hidden memory in all of the container class
560 /// members of the JEventSource_EVIO class. This is needed
561 /// for jobs that process a lot of input files and therefore
562 /// create a lot JEventSource_EVIO objects. JANA does not delete
563 /// these objects until the end of the job so this tends to
564 /// act like a memory leak. The data used can be substantial
565 /// (nearly 1GB per JEventSource_EVIO object).
566 if(hdevio) delete hdevio;
567 hdevio = NULL__null;
568 //if(chan) delete chan;
569 //chan = NULL;
570#ifdef HAVE_ET
571 if(et_connected) et_close(sys_id);
572 et_connected = false;
573#endif // HAVE_ET
574
575 module_type.clear();
576 modtype_translate.clear();
577
578 for(uint32_t i=0; i<hit_objs.size(); i++) hit_objs[i].resize(0);
579 hit_objs.resize(0);
580
581 while(!stored_events.empty()){
582 delete stored_events.front();
583 stored_events.pop();
584 }
585 while(!evio_buffer_pool.empty()) {
586 delete evio_buffer_pool.back();
587 evio_buffer_pool.pop_back();
588 }
589 while(!event_source_data_types.empty()){
590 event_source_data_types.erase(event_source_data_types.begin());
591 }
592}
593
594//----------------
595// GetEvent
596//----------------
597jerror_t JEventSource_EVIO::GetEvent(JEvent &event)
598{
599 if(VERBOSE>1) evioout << "GetEvent called for &event = " << hex << &event << dec << endl;
600
601 // If we couldn't even open the source, then there's nothing to do
602 bool no_source = true;
603#if USE_HDEVIO1
604 if(source_type==kFileSource && hdevio->is_open) no_source = false;
605#endif
606 if(source_type==kETSource && et_connected) no_source = false;
607 if(no_source)throw JException(string("Unable to open EVIO channel for \"") + source_name + "\"");
608
609
610 // This may not be a long term solution, but here goes:
611 // We need to write single events out in EVIO format, possibly
612 // with new information attached. The easiest way to do this
613 // is to keep the DOM tree when the event is read in and modify
614 // it if needed before writing it out. The complication comes
615 // in that entangled events will not have a dedicated DOM tree
616 // for every event. This is only an issue if disentangling is
617 // not done upstream. How this is handled now is that the DOM
618 // tree pointer is copied into the ObjList object for the first
619 // physics event found in the DAQ event. The DOM tree is freed
620 // in FreeEvent (if the pointer is non-NULL). Note that for
621 // single event blocks (i.e. already disentangled events) the
622 // stored_events list will always be empty so "evt" is always
623 // set.
624
625 // Check for event stored from parsing a previously read in
626 // DAQ event
627 ObjList *objs_ptr = NULL__null;
628 pthread_mutex_lock(&stored_events_mutex);
629 if(!stored_events.empty()){
630 objs_ptr = stored_events.front();
631 stored_events.pop();
632
633 // If this is a stored event then it almost certainly
634 // came from a multi-event block of physics events.
635 // Set the physics event status bit.
636 event.SetStatusBit(kSTATUS_PHYSICS_EVENT);
637 }
638 pthread_mutex_unlock(&stored_events_mutex);
639
640 // If no events are currently stored in the buffer, then
641 // read in another event block.
642 if(objs_ptr == NULL__null){
643 uint32_t *buff = NULL__null; // ReadEVIOEvent will allocate memory from pool for this
644 double t1 = GetTime();
645 jerror_t err = ReadEVIOEvent(buff);
646 double t2 = GetTime();
647 if(err != NOERROR) return err;
648 if(buff == NULL__null) return MEMORY_ALLOCATION_ERROR;
649 uint32_t buff_size = ((*buff) + 1)*4; // first word in EVIO buffer is total bank size in words
650
651 objs_ptr = new ObjList();
652 objs_ptr->time_evio_read = t2 - t1;
653 objs_ptr->eviobuff = buff;
654 objs_ptr->eviobuff_size = buff_size;
655 objs_ptr->run_number = FindRunNumber(buff);
656 objs_ptr->event_number = FindEventNumber(buff);
657
658 // Increment counter that keeps track of how many events
659 // are currently being processed.
660 pthread_mutex_lock(&current_event_count_mutex);
661 current_event_count++;
662 pthread_mutex_unlock(&current_event_count_mutex);
663 }
664
665 // Store a pointer to the ObjList object for this event in the
666 // JEvent as the Reference value. Parsing will be done later
667 // in GetObjects() -> ParseEvents() using the eviobuff pointer.
668 event.SetJEventSource(this);
669 event.SetEventNumber((uint64_t)objs_ptr->event_number);
670 event.SetRunNumber(objs_ptr->run_number);
671 event.SetRef(objs_ptr);
672 event.SetStatusBit(kSTATUS_EVIO);
673 if( source_type == kFileSource ) event.SetStatusBit(kSTATUS_FROM_FILE);
674 if( source_type == kETSource ) event.SetStatusBit(kSTATUS_FROM_ET);
675 if(objs_ptr)
676 if(objs_ptr->eviobuff) FindEventType(objs_ptr->eviobuff, event);
677
678 // EPICS and BOR events are barrier events
679 if(event.GetStatusBit(kSTATUS_EPICS_EVENT) || event.GetStatusBit(kSTATUS_BOR_EVENT) ){
680 event.SetSequential();
681 }
682
683 Nevents_read++;
684
685 return NOERROR;
686}
687
688//----------------
689// FreeEvent
690//----------------
691void JEventSource_EVIO::FreeEvent(JEvent &event)
692{
693 if(VERBOSE>1) evioout << "FreeEvent called for event: " << event.GetEventNumber() << endl;
694
695 ObjList *objs_ptr = (ObjList*)event.GetRef();
696 if(objs_ptr){
697
698 // If a DAQ event was read in but GetObjects never called
699 // then the buffer will never have been parsed. Since the
700 // DAQ event could hold multiple Physics events, we parse
701 // it now to ensure all physics events are presented by
702 // the event source. The ParseEvents call will copy the
703 // first event's parameters into our objs_ptr object, but
704 // any additional ones will be placed in stored_events.
705 if(!objs_ptr->eviobuff_parsed) ParseEvents(objs_ptr);
706
707 if(objs_ptr->own_objects){
708
709 for(unsigned int i=0; i<objs_ptr->hit_objs.size(); i++){
710 delete objs_ptr->hit_objs[i];
711 }
712
713 for(unsigned int i=0; i<objs_ptr->config_objs.size(); i++){
714 delete objs_ptr->config_objs[i];
715 }
716
717 for(unsigned int i=0; i<objs_ptr->misc_objs.size(); i++){
718 delete objs_ptr->misc_objs[i];
719 }
720 }
721
722 if(objs_ptr->DOMTree != NULL__null) delete objs_ptr->DOMTree;
723 if(objs_ptr->eviobuff){
724
725 // If we have not already stopped reading events from
726 // the source then return this buffer to the pool. Otherwise,
727 // delete the buffer.
728 if(hdevio){
729 // Return EVIO buffer to pool for recycling
730 pthread_mutex_lock(&evio_buffer_pool_mutex);
731 evio_buffer_pool.push_front(objs_ptr->eviobuff);
732 pthread_mutex_unlock(&evio_buffer_pool_mutex);
733 }else{
734 free(objs_ptr->eviobuff);
735 }
736 }
737
738 delete objs_ptr;
739
740 // Decrement counter that keeps track of how many events
741 // are currently being processed.
742 pthread_mutex_lock(&current_event_count_mutex);
743 current_event_count--;
744 bool last_event = (hdevio==NULL__null) && (current_event_count==0);
745 pthread_mutex_unlock(&current_event_count_mutex);
746
747 // If we are the last event, then clean up as much memory as
748 // possible.
749 if(last_event) Cleanup();
750 }
751}
752
753//----------------
754// ParseEvents
755//----------------
756jerror_t JEventSource_EVIO::ParseEvents(ObjList *objs_ptr)
757{
758 /// This is the high-level entry point for parsing the
759 /// DAQ event in order to create one or more Physics
760 /// events. It will be called from either GetObjects
761 /// or FreeEvent, the latter being done only if needed
762 /// to ensure the event does eventually get parsed.
763 /// The grunt work of actually parsing the data starts
764 /// in ParseEVIOEvent().
765 ///
766 /// This method is here so that the DOM Tree creation
767 /// and data parsing can be deferred from the EventBuffer
768 /// thread (of which there is only one) to an event
769 /// processor thread (or which there may be many). Since
770 /// the DOM tree creating and data parsing represent the
771 /// larger time cost of getting the event into memory,
772 /// a siginificant performance increase can be gained
773 /// using this slightly more complicated method.
774
775 if(VERBOSE>2) evioout << " Entering ParseEvents() with objs_ptr=" << hex << objs_ptr << dec << endl;
776
777 // Double check that we're not re-parsing an event
778 if(objs_ptr->eviobuff_parsed){
779 jerr << " DAQ event already parsed!! Bug in code. Contact davidl@jlab.org" << endl;
780 return UNKNOWN_ERROR;
781 }
782
783 // Bomb-proof against getting a NULL buffer
784 uint32_t *buff = objs_ptr->eviobuff;
785 if(buff == NULL__null){
786 jerr << " Bad buffer pointer passed to JEventSource_EVIO::ParseEvent()!!" << endl;
787 return RESOURCE_UNAVAILABLE;
788 }
789
790 // This container will be used to hold all of the individual
791 // Physics (L1 triggered) events for this DAQ event. This includes
792 // both dientangling multi-event blocks and separating multi-event
793 // ET events.
794 list<ObjList*> full_events;
795
796 // Setup up iptr and iend to point to the start of the first event
797 // and the word just after the end of the last event respectively.
798 // Initialize them for the case of reading from a file and not a
799 // CODA-produced ET event
800 uint32_t *iptr = &buff[0];
801 uint32_t *iend = &buff[buff[0]+1]; // EVIO length word is exclusive so +1
802
803 // If the "event" was read from ET, then it may (and likely
804 // will) contain several DAQ events. (Each DAQ event may itself
805 // contain many L1 trigger events.) In addition, the ET event
806 // will have a Network Transport Header (NTH) that must be skipped
807 // but only if read from CODA. Events put into the ET system
808 // by other means will not include the NTH. To decide whether
809 // there is an NTH, we look at the magic word and the header length.
810 // Note that byteswapping should already have occured.
811 if(source_type==kETSource && buff[7]==0xc0da0100 && buff[2]==8){
812 // This buffer read from ET. Redefine iptr and iend
813 iptr = &buff[8];
814 iend = &buff[buff[0]]; // EVIO length word in NTH is inclusive so don't add 1
815 }
816
817 if(VERBOSE>5) evioout << " Looping event stack with " << *iptr << " words" << endl;
818
819 // Loop over events in buffer until entire buffer is parsed.
820 // When reading from a file, this loop should only get executed once.
821 int Nevents_in_stack=0;
822 while(iptr < iend){
823
824 double time_dom_tree = 0;
825 double time_evio_parse = 0;
826
827 // Make a evioDOMTree for this DAQ event
828 evioDOMTree *evt = NULL__null;
829 if(MAKE_DOM_TREE){
830 try{
831 double tstart = GetTime();
832 evt = new evioDOMTree(iptr);
833 time_dom_tree = GetTime() - tstart;
834 }catch(evioException &e){
835 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<835<<" "
<< "Problem creating EVIO DOM Tree!!" << endl;
836 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<836<<" "
<< e.what() << endl;
837 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<837<<" "
<< "Binary dump of first 160 words follows:" << endl;
838 DumpBinary(iptr, iend, 160);
839 exit(-1);
840 }
841 }
842
843 if(evt){
844 // Parse event, making other ObjList objects
845 list<ObjList*> my_full_events;
846 //bool skipped_parsing = true;
847 if(PARSE_EVIO_EVENTS){
848 try{
849 double tstart = GetTime();
850 ParseEVIOEvent(evt, my_full_events);
851 time_evio_parse = GetTime() - tstart;
852 }catch(JException &jexception){
853 jerr << "Exception thrown from ParseEVIOEvent!" << endl;
854 jerr << jexception.toString() << endl;
855 }
856 }
857
858 // Append physics events found for this DAQ event to the list of all physics events
859 if(!my_full_events.empty()) {
860 my_full_events.front()->DOMTree = evt; // keep DOMTree pointer with first event from this DAQ event
861 my_full_events.front()->time_dom_tree = time_dom_tree;
862 my_full_events.front()->time_evio_parse = time_evio_parse;
863 full_events.insert( full_events.end(), my_full_events.begin(), my_full_events.end() );
864 }else{
865 delete evt;
866 }
867 }else{
868 // No DOM tree made for this buffer. Insert an empty event into
869 // the list so we can keep track of the number of events seen
870 // even when DOMTree creation is turned off.
871 ObjList *objs = new ObjList;
872 full_events.push_back(objs);
873 }
874
875 // Advance pointer to next event in buffer
876 iptr += iptr[0]+1;
877 Nevents_in_stack++; // number of events processed in this buffer (for debugging)
878 }
879
880 if(VERBOSE>5) evioout << " Loop finished. " << full_events.size() << " events total found (" << Nevents_in_stack << " events in stack)" << endl;
881
882 // At this point, we have parsed the DAQ event and extracted all physics
883 // events into the full_events list. In the case of a prestart or go event
884 // read from an EVIO file, the full_events list may actually be empty at
885 // this point. For these cases, we need to add an empty event for the
886 // current thread to "process".
887 bool empty_event = full_events.empty();
888 if(empty_event) full_events.push_back(new ObjList());
889
890 // Whether we actually parsed the events or not, we mark them as being
891 // parsed since it is really just used as a flag to tell whether this
892 // method should be called or not.
893 list<ObjList*>::iterator iter = full_events.begin();
894 for( ; iter != full_events.end(); iter++ ) (*iter)->eviobuff_parsed = true;
895
896 // Copy the first event's objects obtained from parsing into this event's ObjList
897 ObjList *objs = full_events.front();
898 full_events.pop_front();
899 //objs_ptr->run_number = empty_event ? objs_ptr->run_number:objs->run_number;
900 objs_ptr->own_objects = objs->own_objects;
901 objs_ptr->hit_objs = objs->hit_objs;
902 objs_ptr->config_objs = objs->config_objs;
903 objs_ptr->misc_objs = objs->misc_objs;
904 objs_ptr->eviobuff_parsed = objs->eviobuff_parsed;
905 objs_ptr->time_dom_tree = objs->time_dom_tree;
906 objs_ptr->time_evio_parse = objs->time_evio_parse;
907 //objs_ptr->eviobuff = objs->eviobuff; // Don't copy this! (it causes memory leak)
908 //objs_ptr->eviobuff_size = objs->eviobuff_size;
909 objs_ptr->DOMTree = objs->DOMTree;
910 delete objs;
911
912 // Config objects come from banks that are created when a block
913 // of events is read out. Thus, a single set of config. objects
914 // will be created when parsing a multi-event block. Here, we duplicate
915 // all config objects for the first event for every other event in the
916 // block. To make this a little more compact and maintainable, we use a
917 // #define. This allows us to write the class type once and guarantee
918 // that it shows up the same in all places. For example, using
919 // CloneConfigObject(Df125Config) will expand to something like:
920 //
921 // if(confobj->className() == string("Df125Config")){
922 // c = new Df125Config(confobj->rocid,confobj->slot_mask);
923 // *((Df125Config*)c) = *((Df125Config*)confobj);
924 // }
925#define CloneConfigObject(T){ if(confobj->className() == string("T")){ c = new T(confobj
->rocid,confobj->slot_mask); *((T*)c) = *((T*)confobj);
} }
{ if(confobj->className() == string(#T)){ c = new T(confobj->rocid,confobj->slot_mask); *((T*)c) = *((T*)confobj);} }
926 list<ObjList*>::iterator feiter = full_events.begin();
927 for(; feiter!=full_events.end(); feiter++){
928 ObjList *objs = *feiter;
929 for(uint32_t j=0; j<objs_ptr->config_objs.size(); j++){
930 DDAQConfig *confobj = objs_ptr->config_objs[j];
931 DDAQConfig *c = NULL__null;
932 CloneConfigObject(Df250Config){ if(confobj->className() == string("Df250Config")){ c = new
Df250Config(confobj->rocid,confobj->slot_mask); *((Df250Config
*)c) = *((Df250Config*)confobj);} }
;
933 CloneConfigObject(Df125Config){ if(confobj->className() == string("Df125Config")){ c = new
Df125Config(confobj->rocid,confobj->slot_mask); *((Df125Config
*)c) = *((Df125Config*)confobj);} }
;
934 CloneConfigObject(DF1TDCConfig){ if(confobj->className() == string("DF1TDCConfig")){ c = new
DF1TDCConfig(confobj->rocid,confobj->slot_mask); *((DF1TDCConfig
*)c) = *((DF1TDCConfig*)confobj);} }
;
935 CloneConfigObject(DCAEN1290TDCConfig){ if(confobj->className() == string("DCAEN1290TDCConfig"))
{ c = new DCAEN1290TDCConfig(confobj->rocid,confobj->slot_mask
); *((DCAEN1290TDCConfig*)c) = *((DCAEN1290TDCConfig*)confobj
);} }
;
936 if(c)objs->config_objs.push_back(c);
937 }
938 }
939
940 // Copy remaining events into the stored_events container
941 pthread_mutex_lock(&stored_events_mutex);
942 while(!full_events.empty()){
943 objs = full_events.front();
944 full_events.pop_front();
945 stored_events.push(objs);
946
947 // Copy run number from first event
948 objs->run_number = objs_ptr->run_number;
949 }
950 pthread_mutex_unlock(&stored_events_mutex);
951
952 if(VERBOSE>2) evioout << " Leaving ParseEvents()" << endl;
953
954 return NOERROR;
955}
956
957//----------------
958// GetPoolBuffer
959//----------------
960uint32_t* JEventSource_EVIO::GetPoolBuffer(void)
961{
962 // Get buffer from pool or allocate new one if needed
963 uint32_t *buff = NULL__null;
964 pthread_mutex_lock(&evio_buffer_pool_mutex);
965 if(evio_buffer_pool.empty()){
966 // Allocate new block of memory
967 if(VERBOSE>5) evioout << " evio_buffer_pool empty. Allocating new buffer of size: " << BUFFER_SIZE << " bytes" << endl;
968 buff = (uint32_t*)malloc(BUFFER_SIZE);
969 }else{
970 if(VERBOSE>5) evioout << " evio_buffer_pool not empty(size=" << evio_buffer_pool.size() << "). using buffer from pool" << endl;
971 buff = evio_buffer_pool.front();
972 evio_buffer_pool.pop_front();
973 }
974 pthread_mutex_unlock(&evio_buffer_pool_mutex);
975
976 return buff;
977}
978
979//----------------
980// ReadEVIOEvent
981//----------------
982jerror_t JEventSource_EVIO::ReadEVIOEvent(uint32_t* &buff)
983{
984 /// This method will read an event from the source (file or ET system)
985 /// copying the data into "buff". No parsing of the data is done at
986 /// this level except that if the event comes from ET and needs to be
987 /// byte-swapped, the byte swapping is done during the copy.
988 ///
989 /// This is called from the GetEvent method and therefore run in
990 /// the event reader thread. Events read from ET may contain several DAQ
991 /// events in a single buffer (and each of those may contain several
992 /// physics events if read in multi-event blocks). Separating the multiple
993 /// DAQ events is left to the ParseEvents method which gets called later
994 /// from the event processing threads to improve efficiency.
995
996 if(VERBOSE>1) evioout << " ReadEVIOEvent() called with &buff=" << hex << &buff << dec << endl;
997
998 try{
999 if(source_type==kFileSource){
1000 if(VERBOSE>3) evioout << " attempting read from EVIO file source ..." << endl;
1001
1002#if USE_HDEVIO1
1003
1004 bool done = false;
1005 buff = GetPoolBuffer(); // Get (or allocate) a new buffer from the pool
1006 uint32_t buff_size = BUFFER_SIZE;
1007 while(!done){
1008 if(hdevio->read(buff, buff_size)){
1009 done = true;
1010 }else{
1011 string mess = hdevio->err_mess.str();
1012
1013 switch(hdevio->err_code){
1014 case HDEVIO::HDEVIO_OK:
1015 done = true;
1016 break;
1017 case HDEVIO::HDEVIO_USER_BUFFER_TOO_SMALL:
1018 if(VERBOSE>0) evioout << "EVIO buffer too small (" << buff_size << " bytes) . Reallocating to " << hdevio->last_event_len<< endl;
1019 if(buff) delete[] buff;
1020 buff_size = hdevio->last_event_len;
1021 buff = new uint32_t[buff_size];
1022 continue;
1023 break;
1024 case HDEVIO::HDEVIO_EVENT_BIGGER_THAN_BLOCK:
1025 case HDEVIO::HDEVIO_BANK_TRUNCATED:
1026 case HDEVIO::HDEVIO_UNKNOWN_BANK_TYPE:
1027 if(VERBOSE>0) cout << endl << mess << endl;
1028 continue;
1029 break;
1030 case HDEVIO::HDEVIO_EOF:
1031 if(hdevio) delete hdevio;
1032 hdevio = NULL__null;
1033 if(LOOP_FOREVER && Nevents_read>=1){
1034 cout << "LOOP_FOREVER: reopening " << this->source_name <<endl;
1035 hdevio = new HDEVIO(this->source_name);
1036 if( hdevio->is_open ) continue;
1037 }
1038 return NO_MORE_EVENTS_IN_SOURCE;
1039 break;
1040 default:
1041 cout << endl << "err_code=" << hdevio->err_code << endl;
1042 cout << endl << mess << endl;
1043 if(hdevio) delete hdevio;
1044 hdevio = NULL__null;
1045 return NO_MORE_EVENTS_IN_SOURCE;
1046 break;
1047 }
1048 }
1049 } // while(!done)
1050
1051#else
1052 // ( removed old evio library code )
1053#endif // USE_HDEVIO
1054
1055 }else if(source_type==kETSource){
1056
1057#ifdef HAVE_ET
1058
1059 if(VERBOSE>3) evioout << " attempting read from EVIO ET source ..." << endl;
1060
1061
1062 // Loop until we get an event or are told to stop
1063 struct timespec timeout;
1064 timeout.tv_sec = (unsigned int)floor(TIMEOUT); // set ET timeout
1065 timeout.tv_nsec = (unsigned int)floor(1.0E9*(TIMEOUT-(float)timeout.tv_sec));
1066 et_event *pe=NULL__null;
1067 while(! japp->GetQuittingStatus() ){
1068 int err = et_event_get(sys_id, att_id, &pe, ET_TIMED , &timeout);
1069
1070 if( err == ET_OK && pe!=NULL__null) break; // got an event. break out of while loop
1071
1072 if( err == ET_OK && pe==NULL__null){
1073 evioout << " !!! ET returned no error, but event pointer is NULL!!!" << endl;
1074 return NO_MORE_EVENTS_IN_SOURCE;
1075 }
1076
1077 if( err==ET_ERROR_TIMEOUT ){
1078 if(quit_on_next_ET_timeout)return NO_MORE_EVENTS_IN_SOURCE;
1079 }else if( err!=ET_OK){
1080 evioout << " Error reading from ET. This probably means the ET" << endl;
1081 evioout << "system has gone away (possibly due to run ending or" << endl;
1082 evioout << "DAQ crashing). At any rate, we are quitting now as this" << endl;
1083 evioout << "error is currently unrecoverable." << endl;
1084 return NO_MORE_EVENTS_IN_SOURCE;
1085 }
1086
1087 usleep(10);
1088 }
1089
1090 if(japp->GetQuittingStatus() && pe==NULL__null) return NO_MORE_EVENTS_IN_SOURCE;
1091
1092 // Get pointer to event buffer in the ET-owned memory
1093 uint32_t *et_buff=NULL__null;
1094 et_event_getdata(pe, (void**)&et_buff);
1095 if(et_buff == NULL__null){
1096 jerr << " Got event from ET, but pointer to data is NULL!" << endl;
1097 return NO_MORE_EVENTS_IN_SOURCE;
1098 }
1099
1100 // If user specified to dump words from ET event, do it right away
1101 if(ET_DEBUG_WORDS_TO_DUMP) DumpBinary(et_buff, &et_buff[ET_DEBUG_WORDS_TO_DUMP], ET_DEBUG_WORDS_TO_DUMP, NULL__null);
1102
1103 // A single ET event may have multiple EVIO blocks in it
1104 // Each block may have several EVIO events in it.
1105 //
1106 // (note that "block" here is not the same as the CODA
1107 // "block number". That one determines the number of
1108 // entangled events within the EVIO event and is dealt
1109 // with later while parsing the EVIO event itself.)
1110 //
1111 // We need to loop over EVIO blocks in this ET event
1112 // and then loop over EVIO events within the block.
1113
1114 // Get total size of ET event
1115 size_t et_len=0;
1116 size_t et_idx=0;
1117 et_event_getlength(pe, &et_len);
1118 if(VERBOSE>3)evioout << " ET event length: " << et_len << " (=" << et_len/4 << " words)"<<endl;
1119
1120 // Loop over EVIO blocks in ET event
1121 vector<uint32_t*> buffs;
1122 while(et_idx < et_len/4){
1123
1124 // Pointer to start of EVIO block header
1125 if(VERBOSE>3)evioout << " Looking for EVIO block header at et_idx=" << et_idx << endl;
1126 uint32_t *evio_block = &et_buff[et_idx];
1127
1128 // Check byte order of event by looking at magic #
1129 bool swap_needed = false;
1130 uint32_t magic = evio_block[7];
1131 switch(magic){
1132 case 0xc0da0100: swap_needed = false; break;
1133 case 0x0001dac0: swap_needed = true; break;
1134 default:
1135 evioout << "EVIO magic word not present!" << endl;
1136 return NO_MORE_EVENTS_IN_SOURCE;
1137 }
1138 uint32_t len = evio_block[0];
1139 if(swap_needed) len = EVIO_SWAP32(len)( (((len) >> 24) & 0x000000FF) | (((len) >> 8
) & 0x0000FF00) | (((len) << 8) & 0x00FF0000) |
(((len) << 24) & 0xFF000000) )
;
1140 if(VERBOSE>3){
1141 evioout << "Swapping is " << (swap_needed ? "":"not ") << "needed" << endl;
1142 evioout << " Num. words in EVIO buffer: "<<len<<endl;
1143 }
1144
1145 bool is_last_evio_block = (evio_block[5]>>(9+8))&0x1;
1146 if(VERBOSE>3)evioout << " Is last EVIO block?: " << is_last_evio_block << endl;
1147
1148 // Loop over all evio events in ET event
1149 uint32_t idx = 8; // point to first EVIO event
1150 while(idx<len){
1151
1152 // Size of events in bytes
1153 uint32_t mylen = swap_needed ? EVIO_SWAP32(evio_block[idx])( (((evio_block[idx]) >> 24) & 0x000000FF) | (((evio_block
[idx]) >> 8) & 0x0000FF00) | (((evio_block[idx]) <<
8) & 0x00FF0000) | (((evio_block[idx]) << 24) &
0xFF000000) )
:evio_block[idx];
1154 uint32_t bufsize_bytes = (mylen+1)*sizeof(uint32_t); // +1 is for buffer length word
1155 if(bufsize_bytes > BUFFER_SIZE){
1156 jerr<<" ET event larger than our BUFFER_SIZE!!!"<<endl;
1157 jerr<<" " << bufsize_bytes << " > " << BUFFER_SIZE << endl;
1158 jerr<<" Will stop reading from this source now. Try restarting"<<endl;
1159 jerr<<" with -PEVIO:BUFFER_SIZE=X where X is greater than "<<bufsize_bytes<<endl;
1160 if(VERBOSE>3){
1161 evioout << "First few words in case you are trying to debug:" << endl;
1162 for(unsigned int j=0; j<3; j++){
1163 char str[512];
1164 for(unsigned int i=0; i<5; i++){
1165 sprintf(str, " %08x", evio_block[i+j*5]);
1166 evioout << str;
1167 }
1168 evioout << endl;
1169 }
1170 }
1171 return NO_MORE_EVENTS_IN_SOURCE;
1172 }
1173
1174 // Check that EVIO event length doesn't claim to
1175 // extend past ET buffer.
1176 if( (idx+mylen) > len ){
1177 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<1177<<" "
<< "Bad word count while swapping events in ET event stack!" << endl;
1178 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<1178<<" "
<< "idx="<<idx<<" mylen="<<mylen<<" len="<<len<<endl;
1179 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<1179<<" "
<< "This indicates a problem either with the DAQ system"<<endl;
1180 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<1180<<" "
<< "or this parser code! Contact davidl@jlab.org x5567 " <<endl;
1181 break;
1182 }
1183
1184 // Get new buffer for this EVIO event
1185 buff = GetPoolBuffer();
1186
1187 // Copy event into "buff", byte swapping if needed.
1188 // If no swapping is needed, we just copy it all over
1189 // in one go.
1190 if(!swap_needed){
1191 memcpy(buff, &evio_block[idx], bufsize_bytes);
1192 }else{
1193 swap_int32_t(&evio_block[idx], mylen+1, buff);
1194 }
1195
1196 // Update pointer to next EVIO event in stack (if any)
1197 idx += mylen+1;
1198 buffs.push_back(buff);
1199 }
1200
1201 // bump index to next EVIO block
1202 et_idx += idx;
1203 if(VERBOSE>3)evioout << " EVIO events found so far: " << buffs.size() << endl;
1204 if(is_last_evio_block){
1205 if(VERBOSE>3) evioout << " Block flagged as last in ET event. Ignoring last " << (et_len/4 - et_idx) << " words" <<endl;
1206 break;
1207 }
1208 }
1209
1210 // Put ET event back since we're done with it
1211 et_event_put(sys_id, att_id, pe);
1212
1213 if(VERBOSE>3) evioout << " Found " << buffs.size() << " events in the ET event stack." << endl;
1214
1215 // The first EVIO event should be returned via "buff".
1216 buff = buffs.empty() ? NULL__null:buffs[0];
1217
1218 // Additional EVIO events need to be placed in
1219 // the "stored_events" deque so they can be
1220 // used in subsequent calls to GetEvent()
1221 pthread_mutex_lock(&stored_events_mutex);
1222 for(uint32_t i=1; i<buffs.size(); i++){
1223 ObjList *objs = new ObjList();
1224 objs->eviobuff = buffs[i];
1225 objs->eviobuff_size = BUFFER_SIZE;
1226 objs->run_number = FindRunNumber(buffs[i]);
1227 objs->event_number = FindEventNumber(buffs[i]);
1228 stored_events.push(objs);
1229 }
1230 pthread_mutex_unlock(&stored_events_mutex);
1231
1232#else // HAVE_ET
1233
1234 japp->Quit();
1235 evioout << "Attempting to read from ET system using binary that" << endl;
1236 evioout << "does not have ET support built in! Try recompiling" << endl;
1237 evioout << "programs/Utilities/plugins/DAQ with ETROOT defined" << endl;
1238 evioout << "and pointing to an ET installation." << endl;
1239
1240#endif //HAVE_ET
1241
1242 }
1243 } catch (evioException &e) {
1244 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<1244<<" "
<<e.what()<<endl;
1245 if(e.type == S_EVFILE_TRUNC0x40730001){
1246 jerr << "-- Event buffer truncated --" <<endl;
1247 jerr << "---- this could be because the events are too large " << endl;
1248 jerr << "---- for the buffer provided (" << BUFFER_SIZE << " bytes)" <<endl;
1249 jerr << "---- you can try giving a larger buffer size by setting" << endl;
1250 jerr << "---- the EVIO:BUFFER_SIZE configuration parameter by " << endl;
1251 jerr << "---- adding this argument to your command line:" << endl;
1252 jerr << "---- -PEVIO:BUFFER_SIZE=X (where X is in bytes)" << endl;
1253 }
1254 }
1255
1256 if(VERBOSE>2) evioout << " Leaving ReadEVIOEvent()" << endl;
1257
1258 return NOERROR;
1259}
1260
1261//----------------
1262// GetObjects
1263//----------------
1264jerror_t JEventSource_EVIO::GetObjects(JEvent &event, JFactory_base *factory)
1265{
1266 if(VERBOSE>2) evioout << " GetObjects() called for &event = " << hex << &event << dec << endl;
1267
1268 // This will get called when the first object of the event is
1269 // requested (regardless of the type of object). Instead of
1270 // pulling out objects only of the type requested, we instead
1271 // take the data for all objects and copy them into the respective
1272 // factories. Subsequent requests for objects for this same
1273 // event will get them from the factories. Thus, this should
1274 // only get called once per event.
1275 // O.K. that is not actually true. If objects of a type we don't
1276 // supply are requested, then the corresponding factory's evnt_called
1277 // flag will not have been set and it will come here first to see
1278 // if the source can supply those objects. In those cases, we should
1279 // just return OBJECT_NOT_AVAILABLE so it can revert to the factory
1280 // algorithm. We use the "own_objects" flag here to test if we have
1281 // already copied the low-level objects to the factories and so
1282 // should return right away.
1283 ObjList *objs_ptr = (ObjList*)event.GetRef();
1284 if(!objs_ptr)return RESOURCE_UNAVAILABLE;
1285 if(!objs_ptr->own_objects) return OBJECT_NOT_AVAILABLE; // if objects were already copied ...
1286
1287 // If any translation tables exist, we will use them at the end of this
1288 // method. However, the TTab plugin has an option to specify parsing of
1289 // only certain detector systems. It does this by copying values into
1290 // this JEventSource_EVIO object via the AddROCIDtoParseList method
1291 // while in the brun method. The brun method won't get called until
1292 // we ask for the DTranslationTable objects, thus, we must ask for them
1293 // here, prior to calling ParseEvents.
1294 // Note that we have to use the GetFromFactory() method here since
1295 // if we just use Get() or GetSingle(), it will call us (the event
1296 // source) again in an infinite loop!
1297 // Also note that we use static_cast here instead of dynamic_cast
1298 // since the latter requires that the type_info structure for
1299 // the DTranslationTable_factory be present. It is not in this
1300 // plugin (it is in the TTab plugin). Thus, with dynamic_cast there
1301 // is an unresolved symbol error if the TTab plugin is not also
1302 // present. (Make sense?)
1303 vector<const DTranslationTable*> translationTables;
1304 JEventLoop *loop = event.GetJEventLoop();
1305 DTranslationTable_factory *ttfac = static_cast<DTranslationTable_factory*>(loop->GetFactory("DTranslationTable"));
1306 if(ttfac) ttfac->Get(translationTables);
1307
1308 // We use a deferred parsing scheme for efficiency. If the event
1309 // is not flagged as having already been parsed, then parse it
1310 // now, creating objects for one or more events. The first event's
1311 // parameters will be copied into our ObjList object and any additional
1312 // ones stored in the stored_events queue.
1313 if(!objs_ptr->eviobuff_parsed) ParseEvents(objs_ptr);
1314
1315 // Get name of class which is actually being requested by caller
1316 string dataClassName = (factory==NULL__null ? "N/A":factory->GetDataClassName());
1317
1318 // Make list of data(hit) types we have. Keep list of
1319 // pointers to hit objects of each type
1320 map<string, vector<JObject*> > hit_objs_by_type;
1321 vector<DDAQAddress*> &hit_objs = objs_ptr->hit_objs;
1322 for(unsigned int i=0; i<hit_objs.size(); i++){
1323 JObject *hit_obj = hit_objs[i];
1324 hit_objs_by_type[hit_obj->className()].push_back(hit_obj);
1325 }
1326
1327 // Make list of config objects of each type
1328 map<string, vector<JObject*> > config_objs_by_type;
1329 vector<DDAQConfig*> &config_objs = objs_ptr->config_objs;
1330 for(unsigned int i=0; i<config_objs.size(); i++){
1331 JObject *config_obj = config_objs[i];
1332 config_objs_by_type[config_obj->className()].push_back(config_obj);
1333 }
1334
1335 // Make list of misc objects of each type
1336 map<string, vector<JObject*> > misc_objs_by_type;
1337 vector<JObject*> &misc_objs = objs_ptr->misc_objs;
1338 for(unsigned int i=0; i<misc_objs.size(); i++){
1339 JObject *jobj = misc_objs[i];
1340 misc_objs_by_type[jobj->className()].push_back(jobj);
1341 }
1342
1343 // Associate any DDAQConfig objects with hit objects to which they should apply.
1344 // If the objects are emulated, we will add this association later.
1345 for(unsigned int j=0; j<config_objs.size(); j++){
1346 DDAQConfig *config = config_objs[j];
1347 for(unsigned int i=0; i<hit_objs.size(); i++){
1348 DDAQAddress *hit = hit_objs[i];
1349 if(hit->rocid != config->rocid) continue;
1350 if( (1<<hit->slot) & config->slot_mask){
1351 hit->AddAssociatedObject(config);
1352 }
1353 }
1354 }
1355
1356 // Copy pointers to BOR objects
1357 CopyBOR(loop, hit_objs_by_type);
1358
1359 // In order for the janadot plugin to properly display the callgraph, we need to
1360 // make entries for each of the object types that we generated from data in the file.
1361 // Actually, we need to do it for all of the data objects we supply, but if any objects
1362 // are emulated (e.g. Df250PulseIntegral) they need to be added differently so the correct
1363 // dependence is shown. The first step is to add entries for all of the hit objects we
1364 // actually did find in the file. Do that here.
1365 map<string, vector<JObject*> >::iterator hoiter;
1366 for(hoiter=hit_objs_by_type.begin(); hoiter!=hit_objs_by_type.end(); hoiter++){
1367 AddSourceObjectsToCallStack(loop, hoiter->first);
1368 }
1369
1370 // Get references to various objects
1371 vector<JObject*> &f250_wrd_objs = hit_objs_by_type["Df250WindowRawData"];
1372 vector<JObject*> &f250_pt_objs = hit_objs_by_type["Df250PulseTime"];
1373 vector<JObject*> &f250_pp_objs = hit_objs_by_type["Df250PulsePedestal"];
1374 vector<JObject*> &f250_pi_objs = hit_objs_by_type["Df250PulseIntegral"];
1375
1376 vector<JObject*> &f125_wrd_objs = hit_objs_by_type["Df125WindowRawData"];
1377 vector<JObject*> &f125_pt_objs = hit_objs_by_type["Df125PulseTime"];
1378 vector<JObject*> &f125_pp_objs = hit_objs_by_type["Df125PulsePedestal"];
1379 vector<JObject*> &f125_pi_objs = hit_objs_by_type["Df125PulseIntegral"];
1380 vector<JObject*> &f125_cp_objs = hit_objs_by_type["Df125CDCPulse"];
1381 vector<JObject*> &f125_fp_objs = hit_objs_by_type["Df125FDCPulse"];
1382
1383 // Firmware Emulation
1384
1385 if( F250_EMULATION_MODE != kEmulationNone ){
1386 EmulateDf250Firmware(event, f250_wrd_objs, f250_pt_objs, f250_pp_objs, f250_pi_objs);
1387 }
1388 // Repeat for f125
1389 if( F125_EMULATION_MODE != kEmulationNone ){
1390 EmulateDf125Firmware(event, f125_wrd_objs, f125_cp_objs, f125_fp_objs);
1391 }
1392
1393 // Make PulseTime, PulsePedstal, and PulseIntegral objects associated objects of one another
1394 vector<Df250PulseIntegral*> f250_ppi_objs;
1395 vector<Df250PulseTime*> f250_ppt_objs;
1396 vector<Df250PulsePedestal*> f250_ppp_objs;
1397 CopyContainerElementsWithCast(f250_pi_objs, f250_ppi_objs);
1398 CopyContainerElementsWithCast(f250_pt_objs, f250_ppt_objs);
1399 CopyContainerElementsWithCast(f250_pp_objs, f250_ppp_objs);
1400 LinkAssociationsWithPulseNumber(f250_ppt_objs, f250_ppi_objs);
1401 LinkAssociationsWithPulseNumber(f250_ppp_objs, f250_ppi_objs);
1402 LinkAssociationsWithPulseNumber(f250_ppp_objs, f250_ppt_objs);
1403
1404 vector<Df125WindowRawData*> f125_pwrd_objs;
1405 vector<Df125PulseIntegral*> f125_ppi_objs;
1406 vector<Df125PulseTime*> f125_ppt_objs;
1407 vector<Df125PulsePedestal*> f125_ppp_objs;
1408 vector<Df125CDCPulse*> f125_pcp_objs;
1409 vector<Df125FDCPulse*> f125_pfp_objs;
1410 CopyContainerElementsWithCast(f125_wrd_objs, f125_pwrd_objs);
1411 CopyContainerElementsWithCast(f125_pi_objs, f125_ppi_objs);
1412 CopyContainerElementsWithCast(f125_pt_objs, f125_ppt_objs);
1413 CopyContainerElementsWithCast(f125_pp_objs, f125_ppp_objs);
1414 CopyContainerElementsWithCast(f125_cp_objs, f125_pcp_objs);
1415 CopyContainerElementsWithCast(f125_fp_objs, f125_pfp_objs);
1416 LinkAssociationsWithPulseNumber(f125_ppt_objs, f125_ppi_objs);
1417 LinkAssociationsWithPulseNumber(f125_ppp_objs, f125_ppi_objs);
1418 LinkAssociationsWithPulseNumber(f125_ppp_objs, f125_ppt_objs);
1419 LinkAssociations(f125_pcp_objs, f125_pwrd_objs);
1420 LinkAssociations(f125_pfp_objs, f125_pwrd_objs);
1421
1422 // Add data objects to call stack for the classes we can provide, but for which
1423 // there are no objects for this event. Again, this is so janadot will display things
1424 // properly.
1425 set<string>::iterator siter;
1426 for(siter=event_source_data_types.begin(); siter!=event_source_data_types.end(); siter++){
1427 if(hit_objs_by_type.find(*siter) == hit_objs_by_type.end()){
1428 AddSourceObjectsToCallStack(loop, *siter);
1429 }
1430 }
1431
1432 // The f125 firmware used for the 2014 and Spring 2015 commissioning
1433 // data was hardwired to report pedestals that were an average of
1434 // 4 samples. Since only the average was reported, the number of
1435 // samples used for this data was always "1". For the firmware
1436 // implemented in late 2015, configuration parameters were introduced
1437 // to allow a different number of samples to be used for the pedestal
1438 // and a different divisor as well. Here, we need to replace the
1439 // nsamples field of the PulsePedestal objects (which should be set to
1440 // a default value of "1") with values determined by the config.
1441 // parameters. We use the value NPED which should be calculated in
1442 // the coda_config code on the ROCs when the data was taken.
1443 vector<JObject*> &vpp125 = hit_objs_by_type["Df125PulsePedestal"];
1444 for(unsigned int i=0; i<vpp125.size(); i++){
1445 Df125PulsePedestal *pp = (Df125PulsePedestal*)vpp125[i];
1446 if(!pp->emulated){
1447 const Df125Config*conf = NULL__null;
1448 pp->GetSingle(conf);
1449 if(conf!=NULL__null){
1450 if(conf->NPED != 0xFFFF){
1451 pp->nsamples = conf->NPED;
1452 }
1453 }
1454 }
1455 }
1456
1457 // Initially, the F250, F125 firmware does not include the
1458 // pedestal measurement in the pulse integral data
1459 // (it is an add-on Pulse Pedestal word) We want the
1460 // pedestal field of the Df250PulseIntegral objects
1461 // to contain the measured pedestals in both cases.
1462 // Check all Df250PulseIntegral objects for an associated
1463 // Df250PulsePedestal object. If it has one, copy the
1464 // pedestal from it into the Df250PulseIntegral.
1465 vector<JObject*> &vpi250 = hit_objs_by_type["Df250PulseIntegral"];
1466 for(unsigned int i=0; i<vpi250.size(); i++){
1467
1468 Df250PulseIntegral *pi = (Df250PulseIntegral*)vpi250[i];
1469 const Df250Config*conf = NULL__null;
1470 const Df250PulsePedestal*pp = NULL__null;
1471 pi->GetSingle(conf);
1472 pi->GetSingle(pp);
1473
1474 // If a Df250PulsePedestal object is associated with this
1475 // then copy its pedestal into the pedestal member of this
1476 // pulse integral object. Furthermore, if the pedestal is
1477 // *not* emulated and we have a configuration parameter from
1478 // the datastream for the number of samples the pedestal
1479 // represents, then copy this into the nsamples_pedestal.
1480 if(pp){
1481 pi->pedestal = pp->pedestal;
1482 if(!pp->emulated){
1483 if(conf!=NULL__null){
1484 if(conf->NPED != 0xFFFF){
1485 pi->nsamples_pedestal = conf->NPED;
1486 }
1487 }
1488 }
1489 }
1490
1491 // If this pulse integral is *not* emulated AND there is
1492 // a configuration object from the data stream associated,
1493 // then copy the number of samples for the integral from it.
1494 if(!pi->emulated){
1495 if(conf){
1496 pi->nsamples_integral = conf->NSA_NSB;
1497 }
1498 }
1499 }
1500 vector<JObject*> &vpi125 = hit_objs_by_type["Df125PulseIntegral"];
1501 for(unsigned int i=0; i<vpi125.size(); i++){
1502
1503 Df125PulseIntegral *pi = (Df125PulseIntegral*)vpi125[i];
1504 const Df125Config*conf = NULL__null;
1505 const Df125PulsePedestal*pp = NULL__null;
1506 pi->GetSingle(conf);
1507 pi->GetSingle(pp);
1508
1509 // If a Df125PulsePedestal object is associated with this
1510 // then copy its pedestal into the pedestal member of this
1511 // pulse integral object. Furthermore, if the pedestal is
1512 // *not* emulated then copy the number of pedestal samples.
1513 // (n.b. the value of nsamples should have been set based
1514 // on the configuration parameter in a separate loop over
1515 // Df125PulsePedestal objects above.)
1516 if(pp){
1517 pi->pedestal = pp->pedestal;
1518 if(!pp->emulated) pi->nsamples_pedestal = pp->nsamples;
1519 }
1520
1521 // If this pulse integral is *not* emulated AND there is
1522 // a configuration object from the data stream associated,
1523 // then copy the number of samples for the integral from it.
1524 if(!pi->emulated){
1525 if(conf){
1526 pi->nsamples_integral = conf->NSA_NSB;
1527 }
1528 }
1529 }
1530 vector<JObject*> &vcdcp125 = hit_objs_by_type["Df125CDCPulse"];
1531 for(unsigned int i=0; i<vcdcp125.size(); i++){
1532
1533 Df125CDCPulse *cdcp = (Df125CDCPulse*)vcdcp125[i];
1534 const Df125Config*conf = NULL__null;
1535 cdcp->GetSingle(conf);
1536
1537 // If this CDCpulse is *not* emulated AND there is
1538 // a configuration object from the data stream associated,
1539 // then copy the number of samples for the integral from it.
1540 if(!cdcp->emulated){
1541 if(conf){
1542 //cdcp->nsamples_integral = conf->NSA_NSB;
1543 int TC = (int)cdcp->le_time/10+1;
1544 //int PG = conf->PG; does not yet work
1545 int PG = 4;
1546 int END = ( (TC-PG+conf->IE) > (conf->NW - 20) ) ? (conf->NW - 20) : (TC-PG + conf->IE) ;
1547 int nsamp = END - (TC-PG);
1548 if (nsamp>0){
1549 cdcp->nsamples_integral = nsamp;
1550 } else {
1551 cdcp->nsamples_integral = 1;
1552 }
1553 }
1554 }
1555 }
1556
1557 vector<JObject*> &vfdcp125 = hit_objs_by_type["Df125FDCPulse"];
1558 for(unsigned int i=0; i<vfdcp125.size(); i++){
1559
1560 Df125FDCPulse *fdcp = (Df125FDCPulse*)vfdcp125[i];
1561 const Df125Config*conf = NULL__null;
1562 fdcp->GetSingle(conf);
1563
1564 // If this FDCpulse is *not* emulated AND there is
1565 // a configuration object from the data stream associated,
1566 // then copy the number of samples for the integral from it.
1567 if(!fdcp->emulated){
1568 if(conf){
1569 //fdcp->nsamples_integral = conf->NSA_NSB;
1570 int TC = (int)fdcp->le_time/10+1;
1571 //int PG = conf->PG; does not yet work
1572 int PG = 4;
1573 int END = ( (TC-PG+conf->IE) > (conf->NW - 20) ) ? (conf->NW - 20) : (TC-PG + conf->IE) ;
1574 int nsamp = END - (TC-PG);
1575 if (nsamp>0){
1576 fdcp->nsamples_integral = nsamp;
1577 } else {
1578 fdcp->nsamples_integral = 1;
1579 }
1580 }
1581 }
1582 }
1583
1584 // Loop over types of config objects, copying to appropriate factory
1585 map<string, vector<JObject*> >::iterator config_iter = config_objs_by_type.begin();
1586 for(; config_iter!=config_objs_by_type.end(); config_iter++){
1587 JFactory_base *fac = loop->GetFactory(config_iter->first, "", false); // false= don't allow default tag replacement
1588 if(fac) fac->CopyTo(config_iter->second);
1589 }
1590
1591 // Loop over types of hit objects, copying to appropriate factory
1592 map<string, vector<JObject*> >::iterator iter = hit_objs_by_type.begin();
1593 for(; iter!=hit_objs_by_type.end(); iter++){
1594 JFactory_base *fac = loop->GetFactory(iter->first, "", false); // false= don't allow default tag replacement
1595 fac->CopyTo(iter->second);
1596 }
1597
1598 // Loop over types of misc objects, copying to appropriate factory
1599 map<string, vector<JObject*> >::iterator misc_iter = misc_objs_by_type.begin();
1600 for(; misc_iter!=misc_objs_by_type.end(); misc_iter++){
1601 JFactory_base *fac = loop->GetFactory(misc_iter->first, "", false); // false= don't allow default tag replacement
1602 fac->CopyTo(misc_iter->second);
1603 }
1604 objs_ptr->own_objects = false;
1605
1606 // Copy pointers to BOR objects
1607 //CopyBOR(loop, hit_objs_by_type);
1608
1609 // Returning OBJECT_NOT_AVAILABLE tells JANA that this source cannot
1610 // provide the type of object requested and it should try and generate
1611 // it via a factory algorithm. Returning NOERROR on the other hand
1612 // tells JANA that we can provide this type of object and any that
1613 // are present have already been copied into the appropriate factory.
1614 jerror_t err = OBJECT_NOT_AVAILABLE;
1615 if(strlen(factory->Tag()) == 0){ // We do not supply any tagged factory data here
1616 if(event_source_data_types.find(dataClassName) != event_source_data_types.end()) err = NOERROR;
1617 }
1618
1619 // If it turns out there are no objects of one of the types we supply
1620 // then the CopyTo method for that factory never gets called and subsequent
1621 // requests for that object type will end up calling this method again.
1622 // (For the case when this is done from the ApplyTranslationTable call
1623 // below, it results in an infinite loop!). To prevent this, we need to
1624 // mark all factories of the data types we supply as having had their
1625 // evnt method called.
1626 set<string>::iterator dtiter = event_source_data_types.begin();
1627 for(; dtiter!=event_source_data_types.end(); dtiter++){
1628 JFactory_base *fac = loop->GetFactory(*dtiter);
1629 if(fac) {
1630 // The DAQ_WRD2PI plugin wants to generate some objects from
1631 // the waveform data, overiding anything found in the file.
1632 // It this case, the factory's use_factory flag is set and
1633 // we should NOT mark the factory as having it's event method
1634 // called. Furthermore, we should delete any objects in the
1635 // factory.
1636 // Now, another complication is that the only way to check
1637 // the use_factory flag is to have a pointer to the JFactory
1638 // not the JFactory_base. This means we have to check the data
1639 // type of the factory and make the appropriate cast
1640 string dataClassName = fac->GetDataClassName();
1641 int checkSourceFirst = 1;
1642 if( dataClassName == "Df250Config") checkSourceFirst = ((JFactory<Df250Config >*)fac)->GetCheckSourceFirst();
1643 else if(dataClassName == "Df250PulseIntegral") checkSourceFirst = ((JFactory<Df250PulseIntegral >*)fac)->GetCheckSourceFirst();
1644 else if(dataClassName == "Df250StreamingRawData") checkSourceFirst = ((JFactory<Df250StreamingRawData>*)fac)->GetCheckSourceFirst();
1645 else if(dataClassName == "Df250WindowSum") checkSourceFirst = ((JFactory<Df250WindowSum >*)fac)->GetCheckSourceFirst();
1646 else if(dataClassName == "Df250PulseRawData") checkSourceFirst = ((JFactory<Df250PulseRawData >*)fac)->GetCheckSourceFirst();
1647 else if(dataClassName == "Df250TriggerTime") checkSourceFirst = ((JFactory<Df250TriggerTime >*)fac)->GetCheckSourceFirst();
1648 else if(dataClassName == "Df250PulseTime") checkSourceFirst = ((JFactory<Df250PulseTime >*)fac)->GetCheckSourceFirst();
1649 else if(dataClassName == "Df250PulsePedestal") checkSourceFirst = ((JFactory<Df250PulsePedestal >*)fac)->GetCheckSourceFirst();
1650 else if(dataClassName == "Df250WindowRawData") checkSourceFirst = ((JFactory<Df250WindowRawData >*)fac)->GetCheckSourceFirst();
1651 else if(dataClassName == "Df125Config") checkSourceFirst = ((JFactory<Df125Config >*)fac)->GetCheckSourceFirst();
1652 else if(dataClassName == "Df125PulseIntegral") checkSourceFirst = ((JFactory<Df125PulseIntegral >*)fac)->GetCheckSourceFirst();
1653 else if(dataClassName == "Df125TriggerTime") checkSourceFirst = ((JFactory<Df125TriggerTime >*)fac)->GetCheckSourceFirst();
1654 else if(dataClassName == "Df125PulseTime") checkSourceFirst = ((JFactory<Df125PulseTime >*)fac)->GetCheckSourceFirst();
1655 else if(dataClassName == "Df125PulsePedestal") checkSourceFirst = ((JFactory<Df125PulsePedestal >*)fac)->GetCheckSourceFirst();
1656 else if(dataClassName == "Df125WindowRawData") checkSourceFirst = ((JFactory<Df125WindowRawData >*)fac)->GetCheckSourceFirst();
1657 else if(dataClassName == "Df125CDCPulse") checkSourceFirst = ((JFactory<Df125CDCPulse >*)fac)->GetCheckSourceFirst();
1658 else if(dataClassName == "Df125FDCPulse") checkSourceFirst = ((JFactory<Df125FDCPulse >*)fac)->GetCheckSourceFirst();
1659 else if(dataClassName == "DF1TDCConfig") checkSourceFirst = ((JFactory<DF1TDCConfig >*)fac)->GetCheckSourceFirst();
1660 else if(dataClassName == "DF1TDCHit") checkSourceFirst = ((JFactory<DF1TDCHit >*)fac)->GetCheckSourceFirst();
1661 else if(dataClassName == "DF1TDCTriggerTime") checkSourceFirst = ((JFactory<DF1TDCTriggerTime >*)fac)->GetCheckSourceFirst();
1662 else if(dataClassName == "DCAEN1290TDCConfig") checkSourceFirst = ((JFactory<DCAEN1290TDCConfig >*)fac)->GetCheckSourceFirst();
1663 else if(dataClassName == "DCAEN1290TDCHit") checkSourceFirst = ((JFactory<DCAEN1290TDCHit >*)fac)->GetCheckSourceFirst();
1664 else if(dataClassName == "DCODAEventInfo") checkSourceFirst = ((JFactory<DCODAEventInfo >*)fac)->GetCheckSourceFirst();
1665 else if(dataClassName == "DCODAROCInfo") checkSourceFirst = ((JFactory<DCODAROCInfo >*)fac)->GetCheckSourceFirst();
1666 else if(dataClassName == "DTSscalers") checkSourceFirst = ((JFactory<DTSscalers >*)fac)->GetCheckSourceFirst();
1667 else if(dataClassName == "Df250BORConfig") checkSourceFirst = ((JFactory<Df250BORConfig >*)fac)->GetCheckSourceFirst();
1668 else if(dataClassName == "Df125BORConfig") checkSourceFirst = ((JFactory<Df125BORConfig >*)fac)->GetCheckSourceFirst();
1669 else if(dataClassName == "DF1TDCBORConfig") checkSourceFirst = ((JFactory<DF1TDCBORConfig >*)fac)->GetCheckSourceFirst();
1670 else if(dataClassName == "DCAEN1290TDCBORConfig") checkSourceFirst = ((JFactory<DCAEN1290TDCBORConfig>*)fac)->GetCheckSourceFirst();
1671
1672 if(checkSourceFirst) {
1673 fac->Set_evnt_called();
1674 }else{
1675 // Factory wants to generate these so delete any read
1676 // from source.
1677 fac->Reset();
1678 }
1679 }
1680 }
1681
1682 // If a translation table object is available, use it to create
1683 // detector hits from the low-level DAQ objects we just created.
1684 for(unsigned int i=0; i<translationTables.size(); i++){
1685 translationTables[i]->ApplyTranslationTable(loop);
1686 if(translationTables[i]->IsSuppliedType(dataClassName))
1687 if(strlen(factory->Tag()) == 0)err = NOERROR; // Don't allow tagged factories from Translation table
1688 }
1689
1690 if(VERBOSE>2) evioout << " Leaving GetObjects()" << endl;
1691
1692 return err;
1693}
1694
1695//----------------
1696// CopyBOR
1697//----------------
1698void JEventSource_EVIO::CopyBOR(JEventLoop *loop, map<string, vector<JObject*> > &hit_objs_by_type)
1699{
1700 /// Copy pointers to BOR (Beginning Of Run) objects into the
1701 /// appropriate factories for this event. The objects are flagged
1702 /// so that the factories won't delete them and the objects
1703 /// may be reused on subsequent events.
1704
1705 pthread_rwlock_rdlock(&BOR_lock);
1706
1707 // Make list of BOR objects of each type
1708 map<string, vector<JObject*> > bor_objs_by_type;
1709 for(unsigned int i=0; i<BORobjs.size(); i++){
1710 JObject *jobj = BORobjs[i];
1711 bor_objs_by_type[jobj->className()].push_back(jobj);
1712 }
1713
1714 // Loop over types of BOR objects, copying to appropriate factory
1715 map<string, vector<JObject*> >::iterator iter = bor_objs_by_type.begin();
1716 for(; iter!=bor_objs_by_type.end(); iter++){
1717 const string &bor_obj_name = iter->first;
1718 vector<JObject*> &bors = iter->second;
1719 JFactory_base *fac = loop->GetFactory(bor_obj_name, "", false); // false= don't allow default tag replacement
1720 if(fac){
1721 fac->CopyTo(bors);
1722 fac->SetFactoryFlag(JFactory_base::NOT_OBJECT_OWNER);
1723 }
1724
1725 // Associate with hit objects from this type of module
1726 if(bor_obj_name == "Df250BORConfig"){
1727 LinkAssociationsModuleOnlyWithCast<Df250BORConfig,Df250PulseIntegral>(bors, hit_objs_by_type["Df250PulseIntegral"]);
1728 LinkAssociationsModuleOnlyWithCast<Df250BORConfig,Df250PulsePedestal>(bors, hit_objs_by_type["Df250PulsePedestal"]);
1729 LinkAssociationsModuleOnlyWithCast<Df250BORConfig,Df250PulseTime>(bors, hit_objs_by_type["Df250PulseTime"]);
1730 LinkAssociationsModuleOnlyWithCast<Df250BORConfig,Df250WindowRawData>(bors, hit_objs_by_type["Df250WindowRawData"]);
1731 }
1732 if(bor_obj_name == "Df125BORConfig"){
1733 LinkAssociationsModuleOnlyWithCast<Df125BORConfig,Df125CDCPulse>(bors, hit_objs_by_type["Df125CDCPulse"]);
1734 LinkAssociationsModuleOnlyWithCast<Df125BORConfig,Df125FDCPulse>(bors, hit_objs_by_type["Df125FDCPulse"]);
1735 LinkAssociationsModuleOnlyWithCast<Df125BORConfig,Df125PulseIntegral>(bors, hit_objs_by_type["Df125PulseIntegral"]);
1736 LinkAssociationsModuleOnlyWithCast<Df125BORConfig,Df125PulsePedestal>(bors, hit_objs_by_type["Df125PulsePedestal"]);
1737 LinkAssociationsModuleOnlyWithCast<Df125BORConfig,Df125PulseTime>(bors, hit_objs_by_type["Df125PulseTime"]);
1738 LinkAssociationsModuleOnlyWithCast<Df125BORConfig,Df125WindowRawData>(bors, hit_objs_by_type["Df125WindowRawData"]);
1739 }
1740 if(bor_obj_name == "DF1TDCBORConfig"){
1741 LinkAssociationsModuleOnlyWithCast<DF1TDCBORConfig,Df250PulseIntegral>(bors, hit_objs_by_type["DF1TDCHit"]);
1742 }
1743 if(bor_obj_name == "DCAEN1290TDCBORConfig"){
1744 LinkAssociationsModuleOnlyWithCast<DCAEN1290TDCBORConfig,Df250PulseIntegral>(bors, hit_objs_by_type["DCAEN1290TDCHit"]);
1745 }
1746 }
1747
1748 pthread_rwlock_unlock(&BOR_lock);
1749}
1750
1751//----------------
1752// AddSourceObjectsToCallStack
1753//----------------
1754void JEventSource_EVIO::AddSourceObjectsToCallStack(JEventLoop *loop, string className)
1755{
1756 /// This is used to give information to JANA regarding the origin of objects
1757 /// that *should* come from the source. We add them in explicitly because
1758 /// the file may not have any, but factories may ask for them. We want those
1759 /// links to indicate that the "0" objects in the factory came from the source
1760 /// so that janadot draws these objects correctly.
1761
1762 JEventLoop::call_stack_t cs;
1763 cs.caller_name = "<ignore>"; // tells janadot this object wasn't actually requested by anybody
1764 cs.caller_tag = "";
1765 cs.callee_name = className;
1766 cs.callee_tag = "";
1767 cs.start_time = 0.0;
1768 cs.end_time = 0.0;
1769 cs.data_source = JEventLoop::DATA_FROM_SOURCE;
1770 loop->AddToCallStack(cs);
1771}
1772
1773//----------------
1774// AddEmulatedObjectsToCallStack
1775//----------------
1776void JEventSource_EVIO::AddEmulatedObjectsToCallStack(JEventLoop *loop, string caller, string callee)
1777{
1778 /// This is used to give information to JANA regarding the relationship and
1779 /// origin of some of these data objects. This is really just needed so that
1780 /// the janadot program can be used to produce the correct callgraph. Because
1781 /// of how this plugin works, JANA can't record the correct call stack (at
1782 /// least not easily!) Therefore, we have to give it a little help here.
1783
1784 JEventLoop::call_stack_t cs;
1785 cs.caller_name = caller;
1786 cs.callee_name = callee;
1787 cs.data_source = JEventLoop::DATA_FROM_SOURCE;
1788 loop->AddToCallStack(cs);
1789 cs.callee_name = cs.caller_name;
1790 cs.caller_name = "<ignore>";
1791 cs.data_source = JEventLoop::DATA_FROM_FACTORY;
1792 loop->AddToCallStack(cs);
1793}
1794
1795//----------------
1796// EmulateDf250Firmware
1797//----------------
1798void JEventSource_EVIO::EmulateDf250Firmware(JEvent &event, vector<JObject*> &wrd_objs, vector<JObject*> &pt_objs, vector<JObject*> &pp_objs, vector<JObject*> &pi_objs)
1799{
1800 // Cant emulate without the raw data
1801 if(wrd_objs.size() == 0) return;
1802 if(VERBOSE>3) evioout << " Entering EmulateDf250Firmware ..." <<endl;
1803
1804 vector <const Df250EmulatorAlgorithm*> f250Emulator_const;
1805 Df250EmulatorAlgorithm *f250Emulator = NULL__null;
1806 JEventLoop *loop = event.GetJEventLoop();
1807 Df250EmulatorAlgorithm_factory *f250EmFac = static_cast<Df250EmulatorAlgorithm_factory*>(loop->GetFactory("Df250EmulatorAlgorithm"));
1808 if (f250EmFac) {
1809 f250EmFac->Get(f250Emulator_const);
1810 // Drop const
1811 if (f250Emulator_const.size() != 0) f250Emulator = const_cast<Df250EmulatorAlgorithm*>(f250Emulator_const[0]);
1812 }
1813
1814 if(VERBOSE>3) evioout << " Looping over raw data ..." <<endl;
1815 // Loop over all window raw data objects
1816 for(unsigned int i=0; i<wrd_objs.size(); i++){
1817 const Df250WindowRawData *f250WindowRawData = (Df250WindowRawData*)wrd_objs[i];
1818 Df250PulseTime *f250PulseTime = NULL__null;
1819 Df250PulsePedestal *f250PulsePedestal = NULL__null;
1820 Df250PulseIntegral *f250PulseIntegral = NULL__null;
1821
1822 // When raw data exists, we will always do the emulation
1823 // Grab the existing Pulse data
1824 // This will grab the first pulse. This will need to be adapted later for multiple hits.
1825 for(uint32_t j=0; j<pt_objs.size(); j++){
1826 Df250PulseTime *pt = (Df250PulseTime*)pt_objs[j];
1827 if(pt->rocid == f250WindowRawData->rocid){
1828 if(pt->slot == f250WindowRawData->slot){
1829 if(pt->channel == f250WindowRawData->channel){
1830 f250PulseTime = pt;
1831 f250PulseTime->AddAssociatedObject(f250WindowRawData);
1832 if(pt->emulated){
1833 jerr << "Emulating channel that already has emulated objects!" << endl;
1834 jerr << "This likely means there is a bug in JEventSource_EVIO.cc" <<endl;
1835 jerr << "PulseTime: rocid="<<pt->rocid<<" slot="<<pt->slot<<" channel="<<pt->channel<<endl;
1836 jerr << "please report error to davidl@jlab.org" << endl;
1837 exit(-1);
1838 }
1839 break;
1840 }
1841 }
1842 }
1843 }
1844
1845 // Ditto for pulse pedestal objects
1846 for(uint32_t j=0; j<pp_objs.size(); j++){
1847 Df250PulsePedestal *pp = (Df250PulsePedestal*)pp_objs[j];
1848 if(pp->rocid == f250WindowRawData->rocid){
1849 if(pp->slot == f250WindowRawData->slot){
1850 if(pp->channel == f250WindowRawData->channel){
1851 f250PulsePedestal = pp;
1852 f250PulsePedestal->AddAssociatedObject(f250WindowRawData);
1853 if(pp->emulated){
1854 jerr << "Emulating channel that already has emulated objects!" << endl;
1855 jerr << "This likely means there is a bug in JEventSource_EVIO.cc" <<endl;
1856 jerr << "PulsePedestal: rocid="<<pp->rocid<<" slot="<<pp->slot<<" channel="<<pp->channel<<endl;
1857 jerr << "please report error to davidl@jlab.org" << endl;
1858 exit(-1);
1859 }
1860 break;
1861 }
1862 }
1863 }
1864 }
1865
1866 // Ditto for pulse integral objects
1867 for(uint32_t j=0; j<pi_objs.size(); j++){
1868 Df250PulseIntegral *pi = (Df250PulseIntegral*)pi_objs[j];
1869 if(pi->rocid == f250WindowRawData->rocid){
1870 if(pi->slot == f250WindowRawData->slot){
1871 if(pi->channel == f250WindowRawData->channel){
1872 f250PulseIntegral = pi;
1873 f250PulseIntegral->AddAssociatedObject(f250WindowRawData);
1874 if(pi->emulated){
1875 jerr << "Emulating channel that already has emulated objects!" << endl;
1876 jerr << "This likely means there is a bug in JEventSource_EVIO.cc" <<endl;
1877 jerr << "PulseIntegral: rocid="<<pi->rocid<<" slot="<<pi->slot<<" channel="<<pi->channel<<endl;
1878 jerr << "please report error to davidl@jlab.org" << endl;
1879 exit(-1);
1880 }
1881 break;
1882 }
1883 }
1884 }
1885 }
1886
1887 // create new Df250PulseTime object if one does not exist
1888 if(f250PulseTime == NULL__null){
1889 f250PulseTime = new Df250PulseTime;
1890 f250PulseTime->rocid =f250WindowRawData->rocid;
1891 f250PulseTime->slot = f250WindowRawData->slot;
1892 f250PulseTime->channel = f250WindowRawData->channel;
1893 f250PulseTime->itrigger = f250WindowRawData->itrigger;
1894 f250PulseTime->pulse_number = 0;
1895 f250PulseTime->emulated = true;
1896 f250PulseTime->AddAssociatedObject(f250WindowRawData);
1897 pt_objs.push_back(f250PulseTime);
1898 }
1899
1900 // create new Df250PulsePedestal object if one does not exist
1901 if(f250PulsePedestal == NULL__null){
1902 f250PulsePedestal = new Df250PulsePedestal;
1903 f250PulsePedestal->rocid =f250WindowRawData->rocid;
1904 f250PulsePedestal->slot = f250WindowRawData->slot;
1905 f250PulsePedestal->channel = f250WindowRawData->channel;
1906 f250PulsePedestal->itrigger = f250WindowRawData->itrigger;
1907 f250PulsePedestal->pulse_number = 0;
1908 f250PulsePedestal->emulated = true;
1909 f250PulsePedestal->AddAssociatedObject(f250WindowRawData);
1910 pp_objs.push_back(f250PulsePedestal);
1911 }
1912
1913 // create new Df250PulseIntegral object if one does not exist
1914 if(f250PulseIntegral == NULL__null){
1915 f250PulseIntegral = new Df250PulseIntegral;
1916 f250PulseIntegral->rocid =f250WindowRawData->rocid;
1917 f250PulseIntegral->slot = f250WindowRawData->slot;
1918 f250PulseIntegral->channel = f250WindowRawData->channel;
1919 f250PulseIntegral->itrigger = f250WindowRawData->itrigger;
1920 f250PulseIntegral->pulse_number = 0;
1921 f250PulseIntegral->emulated = true;
1922 f250PulseIntegral->AddAssociatedObject(f250WindowRawData);
1923 pi_objs.push_back(f250PulseIntegral);
1924 }
1925
1926 // Flag all objects as emulated and their values will be replaced with emulated quantities
1927 if (F250_EMULATION_MODE == kEmulationAlways){
1928 f250PulseTime->emulated = 1;
1929 f250PulsePedestal->emulated = 1;
1930 f250PulseIntegral->emulated = 1;
1931 }
1932
1933 // Emulate firmware
1934 if(VERBOSE>3) evioout << " Calling EmulateFirmware ..." << endl;
1935 f250Emulator->EmulateFirmware(f250WindowRawData, f250PulseTime, f250PulsePedestal, f250PulseIntegral);
1936 }
1937
1938 // PulseTime, PulsePedestal, PulseIntegral objects are associated to one another in GetObjects
1939 if(VERBOSE>3) evioout << " Leaving EmulateDf250Firmware" <<endl;
1940}
1941
1942//----------------
1943// EmulateDf125Firmware
1944//----------------
1945void JEventSource_EVIO::EmulateDf125Firmware( JEvent &event, vector<JObject*> &wrd_objs, vector<JObject*> &cp_objs, vector<JObject*> &fp_objs)
1946{
1947 /// This code implements an upsampling technique developed by Naomi Jarvis at
1948 /// CMU. This was not implemented in the firmware for the 2014-2015 commissioning
1949 /// run, but was implemented for later runs.
1950 ///
1951 /// Removed f250 style emulation of f125 firmware. Keep in mind if for some reason old
1952 /// mode 8 data is processed, it will return the new style words with 1/10
1953 /// sample resolution. It is doubtful anyone will be using these in the future so nbd. 3/18/2016 MS
1954
1955 if(wrd_objs.size() == 0) return; // Can't do anything without the raw data
1956 if(VERBOSE>3) evioout << " Entering EmulateDf125Firmware ..." <<endl;
1957
1958 vector <const Df125EmulatorAlgorithm*> f125Emulator_const;
1959 Df125EmulatorAlgorithm *f125Emulator = NULL__null;
1960 JEventLoop *loop = event.GetJEventLoop();
1961 Df125EmulatorAlgorithm_factory *f125EmFac = static_cast<Df125EmulatorAlgorithm_factory*>(loop->GetFactory("Df125EmulatorAlgorithm"));
1962 if (f125EmFac) {
1963 f125EmFac->Get(f125Emulator_const);
1964 // Drop const
1965 if (f125Emulator_const.size() != 0) f125Emulator = const_cast<Df125EmulatorAlgorithm*>(f125Emulator_const[0]);
1966 }
1967
1968 // Loop over all window raw data objects
1969 for(unsigned int i=0; i<wrd_objs.size(); i++){
1970 const Df125WindowRawData *f125WindowRawData = (Df125WindowRawData*)wrd_objs[i];
1971 Df125CDCPulse *f125CDCPulse = NULL__null;
1972 Df125FDCPulse *f125FDCPulse = NULL__null;
1973
1974 //search for existing CDCPulse
1975 for(uint32_t j=0; j<cp_objs.size(); j++){
1976 Df125CDCPulse *cp = (Df125CDCPulse*)cp_objs[j];
1977 if(cp->rocid == f125WindowRawData->rocid){
1978 if(cp->slot == f125WindowRawData->slot){
1979 if(cp->channel == f125WindowRawData->channel){
1980 f125CDCPulse = cp;
1981 f125CDCPulse->AddAssociatedObject(f125WindowRawData);
1982 break;
1983 }
1984 }
1985 }
1986 }
1987
1988 // search for existing FDCPulse
1989 for(uint32_t j=0; j<fp_objs.size(); j++){
1990 Df125FDCPulse *fp = (Df125FDCPulse*)fp_objs[j];
1991 if(fp->rocid == f125WindowRawData->rocid){
1992 if(fp->slot == f125WindowRawData->slot){
1993 if(fp->channel == f125WindowRawData->channel){
1994 f125FDCPulse = fp;
1995 f125FDCPulse->AddAssociatedObject(f125WindowRawData);
1996 break;
1997 }
1998 }
1999 }
2000 }
2001
2002 // If the the pulse objects do not exist, create new ones to go with our raw data
2003 // This should rarely happen since CDC_long and FDC_long have the raw data
2004 // along with the calculated quantities in a pulse word. Pure raw mode would be the only time
2005 // when this would not be the case. Since this is so infrequently used (if ever),
2006 // the ROCID check for CDC/FDC determination is hard coded...
2007 // ROCID CDC: 25-28
2008 // ROCID FDC Cathode: 52,53,55-62
2009
2010 if(f125CDCPulse == NULL__null && ( f125WindowRawData->rocid < 30 ) ){
2011 f125CDCPulse = new Df125CDCPulse;
2012 f125CDCPulse->rocid = f125WindowRawData->rocid;
2013 f125CDCPulse->slot = f125WindowRawData->slot;
2014 f125CDCPulse->channel = f125WindowRawData->channel;
2015 f125CDCPulse->emulated = true;
2016 f125CDCPulse->AddAssociatedObject(f125WindowRawData);
2017 cp_objs.push_back(f125CDCPulse);
2018 }
2019
2020 else if(f125FDCPulse == NULL__null && ( f125WindowRawData->rocid > 30 ) ){
2021 f125FDCPulse = new Df125FDCPulse;
2022 f125FDCPulse->rocid = f125WindowRawData->rocid;
2023 f125FDCPulse->slot = f125WindowRawData->slot;
2024 f125FDCPulse->channel = f125WindowRawData->channel;
2025 f125FDCPulse->emulated = true;
2026 f125FDCPulse->AddAssociatedObject(f125WindowRawData);
2027 cp_objs.push_back(f125FDCPulse);
2028 }
2029
2030 // Flag all objects as emulated and their values will be replaced with emulated quantities
2031 if (F125_EMULATION_MODE == kEmulationAlways){
2032 if(f125CDCPulse!=NULL__null) f125CDCPulse->emulated = 1;
2033 if(f125FDCPulse!=NULL__null) f125FDCPulse->emulated = 1;
2034 }
2035
2036 // Perform the emulation
2037 f125Emulator->EmulateFirmware(f125WindowRawData, f125CDCPulse, f125FDCPulse);
2038 }
2039
2040 if(VERBOSE>3) evioout << " Leaving EmulateDf125Firmware" <<endl;
2041}
2042
2043//----------------
2044// GetRunNumber
2045//----------------
2046int32_t JEventSource_EVIO::GetRunNumber(evioDOMTree *evt)
2047{
2048 // Note: This is currently not used. Preference is
2049 // now given to the run number found in FindRunNumber
2050 // which is called from GetEvent. This makes things
2051 // a little simpler and ensures the run number originally
2052 // presented to the processor/factory does not change.
2053 // 2/15/2016 DL
2054
2055 // This is called during event parsing to get the
2056 // run number for the event.
2057 // Look through event to try and extract the run number.
2058 // We do this by looking for all uint64_t nodes. Then
2059 // check for a parent with one of the magic values for
2060 // the tag indicating it has run number information.
2061 if(USER_RUN_NUMBER>0) return USER_RUN_NUMBER;
2062 if(!evt) return last_run_number;
2063
2064 evioDOMNodeListP bankList = evt->getNodeList(typeIs<uint64_t>());
2065 evioDOMNodeList::iterator iter = bankList->begin();
2066 const uint64_t *run_number_and_type = NULL__null;
2067 for(; iter!=bankList->end(); iter++){
2068 evioDOMNodeP bankPtr = *iter;
2069 evioDOMNodeP physics_event_built_trigger_bank = bankPtr->getParent();
2070 if(physics_event_built_trigger_bank == NULL__null) continue;
2071 uint32_t tag = physics_event_built_trigger_bank->tag;
2072 const vector<uint64_t> *vec;
2073 switch(tag){
2074 case 0xFF22:
2075 case 0xFF23:
2076 case 0xFF26:
2077 case 0xFF27:
2078 vec = bankPtr->getVector<uint64_t>();
2079 if(!vec) continue;
2080 if(vec->size()<1) continue;
2081 run_number_and_type = &((*vec)[vec->size()-1]);
2082 break;
2083 }
2084 if(run_number_and_type != NULL__null) break;
2085 }
2086
2087 if(run_number_and_type != NULL__null) last_run_number = (*run_number_and_type)>>32;
2088
2089 return last_run_number;
2090}
2091
2092//----------------
2093// FindRunNumber
2094//----------------
2095int32_t JEventSource_EVIO::FindRunNumber(uint32_t *iptr)
2096{
2097 /// This is called from GetEvent() to quickly look for the run number
2098 /// at the time the event is read in so it can be passed into
2099 /// JEvent. It is what will be used for accessing the CCDB.
2100 /// from this event. If a bank containing the run number is found,
2101 /// use it to provide the run number. Otherwise, return whatever run
2102 /// number we were able to extract from the file name.
2103
2104 if(VERBOSE>1) evioout << " .. Searching for run number ..." <<endl;
2105 if(USER_RUN_NUMBER>0){
2106 if(VERBOSE>1) evioout << " returning user-supplied run number: " << USER_RUN_NUMBER << endl;
2107 return last_run_number=USER_RUN_NUMBER;
2108 }
2109
2110 // Assume first word is number of words in bank
2111 uint32_t *iend = &iptr[*iptr - 1];
2112 if(*iptr > 2048) iend = &iptr[2048];
2113 bool has_timestamps = false;
2114 while(iptr<iend){
2115 iptr++;
2116
2117 // EPICS event
2118 if( (*iptr & 0xff000f) == 0x600001){
2119 if(VERBOSE>2) evioout << " Found EPICS header. Looking for HD:coda:daq:run_number ..." << endl;
2120 const char *cptr = (const char*)&iptr[1];
2121 const char *cend = (const char*)iend;
2122 const char *needle = "HD:coda:daq:run_number=";
2123 while(cptr<cend){
2124 if(VERBOSE>4) evioout << " \""<<cptr<<"\"" << endl;
2125 if(!strncmp(cptr, needle, strlen(needle))){
2126 if(VERBOSE>2) evioout << " Found it!" << endl;
2127 return last_run_number = atoi(&cptr[strlen(needle)]);
2128 }
2129 cptr+=4; // should only start on 4-byte boundary!
2130 }
2131 }
2132
2133 // BOR event
2134 if( (*iptr & 0xffffffff) == 0x00700E01){
2135 // OK, this looks like a BOR event which does not include the
2136 // run number. In this case, we have a couple of options:
2137 //
2138 // 1. If we are reading from a file then look further into
2139 // the file to see if we can find another event with the
2140 // run number in it.
2141 //
2142 // 2. Return the run number found from the filename.
2143 //
2144 if(source_type==kFileSource){
2145 int32_t run_number = EpicQuestForRunNumber();
2146 if(run_number != 0){
2147 if(VERBOSE>1) evioout << " Found run number " << run_number << " from Epic Quest." <<endl;
2148 return last_run_number = run_number;
2149 }
2150 }
2151 break; // return filename_run_number with warning message
2152 }
2153
2154 // PHYSICS event
2155 switch((*iptr)>>16){
2156 case 0xFF10:
2157 case 0xFF11:
2158 case 0xFF20:
2159 case 0xFF21:
2160 case 0xFF24:
2161 case 0xFF25:
2162 case 0xFF30:
2163 // These Trigger Bank Tag values have no run number info in them
2164 if(VERBOSE>2) evioout << " ... Trigger bank tag (0x" << hex << ((*iptr)>>16) << dec << ") does not contain run number" <<endl;
2165 if(!WARN_USER_RUN_FILENAME) {
2166 jout << "WARNING: setting run number " << filename_run_number << " based on file name" << endl;
2167 WARN_USER_RUN_FILENAME = true;
2168 }
2169 return last_run_number = filename_run_number;
2170 case 0xFF23:
2171 case 0xFF27:
2172 has_timestamps = true;
2173 case 0xFF22:
2174 case 0xFF26:
2175 if(VERBOSE>2) evioout << " ... Trigger bank tag (0x" << hex << ((*iptr)>>16) << dec << ") does contain run number" <<endl;
2176 // Nrocs = (*iptr) & 0x0F;
2177 break;
2178 default:
2179 continue;
2180 }
2181 iptr++;
2182 if( ((*iptr)&0x00FF0000) != 0x000A0000) { iptr--; continue; }
2183 uint32_t M = iptr[-3] & 0x000000FF; // Number of events from Physics Event header
2184 if(VERBOSE>2) evioout << " ... Trigger bank " << (has_timestamps ? "does":"doesn't") << " have timestamps. Nevents in block M=" << M <<endl;
2185 iptr++;
2186 uint64_t *iptr64 = (uint64_t*)iptr;
2187
2188 uint64_t event_num = *iptr64;
2189 if(source_type==kETSource) event_num = ((*iptr64)>>32) | ((*iptr64)<<32);
2190 if(VERBOSE>3) evioout << " .... Event num: " << event_num <<endl;
2191 iptr64++;
2192 if(has_timestamps) iptr64 = &iptr64[M]; // advance past timestamps
2193
2194 // I'm not sure I fully understand this, but if we read from
2195 // ET, then the run number is in the low 32 bits of *iptr64.
2196 // If we are reading from a file, it is in the high 32 bits.
2197 // No byte swapping is needed (it has already been done, though
2198 // perhaps incorrectly). We handle this here by checking if
2199 // this is an ET source or not.
2200 uint64_t run64 = (*iptr64)>>32;
2201 if(source_type==kETSource){
2202 run64 = (*iptr64)&0xffffffff;
2203 }
2204 int32_t run = (int32_t)run64;
2205 if(VERBOSE>1) evioout << " .. Found run number: " << run <<endl;
2206
2207 return last_run_number = run;
2208 }
2209
2210 // if we're not sure what else to do, try a more comprehensive search
2211 if(source_type==kFileSource){
2212 int32_t run_number = EpicQuestForRunNumber();
2213 if(run_number != 0){
2214 if(VERBOSE>1) evioout << " Found run number " << run_number << " from Epic Quest." <<endl;
2215 return last_run_number = run_number;
2216 }
2217 }
2218
2219 if(!WARN_USER_RUN_FILENAME) {
2220 jout << "WARNING: setting run number " << filename_run_number << " based on file name" << endl;
2221 WARN_USER_RUN_FILENAME = true;
2222 }
2223
2224 return last_run_number = filename_run_number;
2225}
2226
2227//----------------
2228// EpicQuestForRunNumber
2229//----------------
2230int32_t JEventSource_EVIO::EpicQuestForRunNumber(void)
2231{
2232 /// This is called when an event is encountered that does
2233 /// not have a run number in it. (e.g. a BOR event encountered
2234 /// in FindRunNumber() ). This is a last hope of finding the
2235 /// run number in the file by looking for other events that
2236 /// may contain it. Specifically, EPICS or PHYSICS events.
2237 /// This only works if it is a file source so that it can open
2238 /// the file and read in past the first event.
2239 ///
2240 /// Note that this is extremely inefficient so should not be
2241 /// called very often. As a precaution, this will look to see
2242 /// if last_run_number is not set to 0 first and will just
2243 /// return it if it is. Only if it is not will the epic quest
2244 /// commence.
2245
2246 if(source_type!=kFileSource) return 0;
2247 if(last_run_number != 0) return last_run_number;
2248
2249 uint32_t buff_len = 4000000;
2250 uint32_t *buff = new uint32_t[buff_len];
2251 HDEVIO *hdevio = new HDEVIO(source_name);
2252 while(hdevio->read(buff, buff_len)){
2253
2254 // Assume first word is number of words in bank
2255 uint32_t *iptr = buff;
2256 uint32_t *iend = &iptr[*iptr - 1];
2257 if(*iptr > 2048) iend = &iptr[2048];
2258 bool has_timestamps = false;
2259 while(iptr<iend){
2260 iptr++;
2261
2262 // EPICS event
2263 if( (*iptr & 0xff000f) == 0x600001){
2264 if(VERBOSE>2) evioout << " Found EPICS header. Looking for HD:coda:daq:run_number ..." << endl;
2265 const char *cptr = (const char*)&iptr[1];
2266 const char *cend = (const char*)iend;
2267 const char *needle = "HD:coda:daq:run_number=";
2268 while(cptr<cend){
2269 if(VERBOSE>4) evioout << " \""<<cptr<<"\"" << endl;
2270 if(!strncmp(cptr, needle, strlen(needle))){
2271 if(VERBOSE>2) evioout << " Found it!" << endl;
2272 int32_t run_number = atoi(&cptr[strlen(needle)]);
2273 if(hdevio) delete hdevio;
2274 if(buff) delete[] buff;
2275 return run_number;
2276 }
2277 cptr+=4; // should only start on 4-byte boundary!
2278 }
2279 }
2280
2281 // BOR event
2282 if( (*iptr & 0xffffffff) == 0x00700E01) continue;
2283
2284 // PHYSICS event
2285 bool not_in_this_buffer = false;
2286 switch((*iptr)>>16){
2287 case 0xFF10:
2288 case 0xFF11:
2289 case 0xFF20:
2290 case 0xFF21:
2291 case 0xFF24:
2292 case 0xFF25:
2293 case 0xFF30:
2294 not_in_this_buffer = true;
2295 break;
2296 case 0xFF23:
2297 case 0xFF27:
2298 has_timestamps = true;
2299 case 0xFF22:
2300 case 0xFF26:
2301 break;
2302 default:
2303 continue;
2304 }
2305
2306 if(not_in_this_buffer) break; // go to next EVIO buffer
2307
2308 iptr++;
2309 if( ((*iptr)&0x00FF0000) != 0x000A0000) { iptr--; continue; }
2310 uint32_t M = iptr[-3] & 0x000000FF; // Number of events from Physics Event header
2311 if(VERBOSE>2) evioout << " ...(epic quest) Trigger bank " << (has_timestamps ? "does":"doesn't") << " have timestamps. Nevents in block M=" << M <<endl;
2312 iptr++;
2313 uint64_t *iptr64 = (uint64_t*)iptr;
2314
2315 uint64_t event_num = *iptr64;
2316 if(source_type==kETSource) event_num = ((*iptr64)>>32) | ((*iptr64)<<32);
2317 if(VERBOSE>3) evioout << " ....(epic quest) Event num: " << event_num <<endl;
2318 iptr64++;
2319 if(has_timestamps) iptr64 = &iptr64[M]; // advance past timestamps
2320
2321 // I'm not sure I fully understand this, but if we read from
2322 // ET, then the run number is in the low 32 bits of *iptr64.
2323 // If we are reading from a file, it is in the high 32 bits.
2324 // No byte swapping is needed (it has already been done, though
2325 // perhaps incorrectly). We handle this here by checking if
2326 // this is an ET source or not.
2327 uint64_t run64 = (*iptr64)>>32;
2328 if(source_type==kETSource){
2329 run64 = (*iptr64)&0xffffffff;
2330 }
2331 int32_t run = (int32_t)run64;
2332 if(VERBOSE>1) evioout << " .. (epic quest) Found run number: " << run <<endl;
2333
2334 if(hdevio) delete hdevio;
2335 if(buff) delete[] buff;
2336 return run;
2337
2338 } // while(iptr<iend)
2339
2340 if(hdevio->Nevents > 500) break;
2341 } // while(hdevio->read(buff, buff_len))
2342
2343 if(hdevio) delete hdevio;
2344 if(buff) delete[] buff;
2345
2346 return 0;
2347}
2348
2349//----------------
2350// FindEventNumber
2351//----------------
2352uint64_t JEventSource_EVIO::FindEventNumber(uint32_t *iptr)
2353{
2354 /// This is called from GetEvent() to quickly look for the event number
2355 /// at the time the event is read in so it can be passed into JEvent.
2356 /// (See comments for FindRunNumber above.)
2357 if(VERBOSE>1) evioout << " .. Searching for event number ..." <<endl;
2358
2359 if(*iptr < 6){
2360 if(VERBOSE>1) evioout << " Word count(="<<*iptr<<")<6. Returning Nevents_read+1(=" << Nevents_read+1 << ") as event number" <<endl;
2361 return Nevents_read+1;
2362 }
2363
2364 // Check header of Trigger bank
2365 uint32_t mask = 0xFF202000;
2366 if( (iptr[3]&mask) != mask ){
2367 if(VERBOSE>1){
2368 evioout << " iptr[3]=" << hex << iptr[3] << " does not look like trigger bank tag (" << (iptr[3]&mask) << " != " << mask << ")" << dec <<endl;
2369 evioout << " Returning Nevents_read+1(=" << Nevents_read+1 << ") as event number" <<endl;
2370 }
2371 return Nevents_read+1;
2372 }
2373
2374 uint64_t loevent_num = iptr[5];
2375 uint64_t hievent_num = iptr[6];
2376 if(source_type==kETSource) {
2377 loevent_num = iptr[6];
2378 hievent_num = iptr[5];
2379 }
2380 uint64_t event_num = loevent_num + (hievent_num<<32);
2381 if(VERBOSE>1) evioout << " .. Found event number: " << event_num <<endl;
2382
2383 return event_num;
2384}
2385
2386//----------------
2387// FindEventType
2388//----------------
2389void JEventSource_EVIO::FindEventType(uint32_t *iptr, JEvent &event)
2390{
2391 /// This is called from GetEvent to quickly determine the type of
2392 /// event this is (Physics, EPICS, SYNC, BOR, ...)
2393 uint32_t head = iptr[1];
2394 if( (head & 0xff000f) == 0x600001){
2395 event.SetStatusBit(kSTATUS_EPICS_EVENT);
2396 }else if( (head & 0xffffffff) == 0x00700E01){
2397 event.SetStatusBit(kSTATUS_BOR_EVENT);
2398 }else if( (head & 0xffffff00) == 0xff501000){
2399 event.SetStatusBit(kSTATUS_PHYSICS_EVENT);
2400 }else if( (head & 0xffffff00) == 0xff701000){
2401 event.SetStatusBit(kSTATUS_PHYSICS_EVENT);
2402 }else if( (head & 0xfff000ff) == 0xffd00000){
2403 event.SetStatusBit(kSTATUS_CONTROL_EVENT);
2404 if( (head>>16) == 0xffd0 ) event.SetStatusBit(kSTATUS_SYNC_EVENT);
2405 }else{
2406 DumpBinary(iptr, &iptr[16]);
2407 }
2408}
2409
2410//----------------
2411// MergeObjLists
2412//----------------
2413void JEventSource_EVIO::MergeObjLists(list<ObjList*> &events1, list<ObjList*> &events2)
2414{
2415 if(VERBOSE>5) evioout << " Entering MergeObjLists(). "
2416 << " &events1=" << hex << &events1 << dec << "(" << events1.size() << " events) "
2417 << " &events2=" << hex << &events2 << dec << "(" << events2.size() << " events) " << endl;
2418
2419 /// Merge the events referenced in events2 into the events1 list.
2420 ///
2421 /// This will append the object lists for each type of data object
2422 /// stored in events2 onto the appropriate list in events1. It does this
2423 /// event-by-event. The idea being that each entry in the queue represents a
2424 /// partial list of the objects for the event. The two queues are most likely
2425 /// filled from different EVIO banks orginiating from different ROCs.
2426 ///
2427 /// Before the merging is done, it is checked that both lists either have the
2428 /// same number of events, or one list is empty. One list is allowed to be
2429 /// empty since it is possible it was "filled" from a bank that contains no
2430 /// data at all which may not neccessarily be an error. If both queues have
2431 /// at least one event, but they do not contain an equal number of events,
2432 /// then an exception is thrown.
2433 ///
2434 /// The contents of event2 will be erased before returning. Ownership of all
2435 /// ObjList objects pointed to by event2 upon entry should be considered
2436 /// owned by event1 upon return.
2437
2438 // Allow a list of 1 event with only config objects in test below
2439 bool justconfig = false;
2440 if(events1.size()==1){
2441 ObjList *objs1 = events1.front();
2442 justconfig = objs1->hit_objs.size()==0 && objs1->misc_objs.size()==0 && objs1->config_objs.size()!=0;
2443 }else if(events2.size()==1){
2444 ObjList *objs2 = events2.front();
2445 justconfig = objs2->hit_objs.size()==0 && objs2->misc_objs.size()==0 && objs2->config_objs.size()!=0;
2446 }
2447
2448 // Check number of events and throw exception if appropriate
2449 unsigned int Nevents1 = events1.size();
2450 unsigned int Nevents2 = events2.size();
2451 if(Nevents1>0 && Nevents2>0 && !justconfig){
2452 if(Nevents1 != Nevents2){
2453 evioout << "Mismatch of number of events passed to MergeObjLists. Throwing exception." << endl;
2454 evioout << "Nevents1="<<Nevents1<<" Nevents2="<<Nevents2<<endl;
2455 throw JException("Number of events in JEventSource_EVIO::MergeObjLists do not match!");
2456 }
2457 }
2458
2459 // Handle cases when one or both lists are empty
2460 if(Nevents1==0 && Nevents2==0)return;
2461 if(Nevents1==0){
2462 events1 = events2;
2463 events2.clear(); // clear queue
2464 return;
2465 }
2466 if(Nevents2==0)return;
2467
2468 // If we get here it means both events1 and events2 have events
2469 list<ObjList*>::iterator iter = events1.begin();
2470 for(; iter!=events1.end(); iter++){
2471 if(events2.empty()) break; // in case one has just config objects in a single event
2472 ObjList *objs1 = *iter;
2473 ObjList *objs2 = events2.front();
2474 events2.pop_front();
2475
2476 objs1->hit_objs.insert(objs1->hit_objs.end(), objs2->hit_objs.begin(), objs2->hit_objs.end());
2477 objs1->config_objs.insert(objs1->config_objs.end(), objs2->config_objs.begin(), objs2->config_objs.end());
2478 objs1->misc_objs.insert(objs1->misc_objs.end(), objs2->misc_objs.begin(), objs2->misc_objs.end());
2479
2480 // Delete the objs2 container
2481 delete objs2;
2482 }
2483
2484 // Clear out any references to objects in event2 (this should be redundant)
2485 events2.clear(); // clear queue
2486
2487 if(VERBOSE>5) evioout << " Leaving MergeObjLists(). &events1=" << hex << &events1 << " &events2=" << &events2 << dec << endl;
2488}
2489
2490//----------------
2491// ParseEVIOEvent
2492//----------------
2493void JEventSource_EVIO::ParseEVIOEvent(evioDOMTree *evt, list<ObjList*> &full_events)
2494{
2495 if(VERBOSE>5) evioout << " Entering ParseEVIOEvent() with evt=" << hex << evt << dec << endl;
2496
2497 if(!evt)throw RESOURCE_UNAVAILABLE;
2498
2499 // Since each bank contains parts of many events, have them fill in
2500 // the "tmp_events" list and then merge those into the "full_events".
2501 // It is done this way so each bank can grow tmp_events to the appropriate
2502 // size to hold the number of events it discovers in the bank. A check
2503 // can then be made that this is consistent with the number of event
2504 // fragments found in the other banks.
2505 //list<ObjList*> full_events;
2506 list<ObjList*> tmp_events;
2507
2508 // The Physics Event bank is the outermost bank of the event and
2509 // it is a bank of banks. One of those banks is the
2510 // "Built Trigger Bank" which is a bank of segments. The others
2511 // are the "Data Bank" banks which in turn contain the
2512 // "Data Block Bank" banks which hold the actual data. For the
2513 // mc2coda generated data files (and presumably the real data)
2514 // these Data Block Banks are banks of ints. More specifically,
2515 // uint32_t.
2516 //
2517 // The "Physics Event's Built Trigger Bank" is a bank of segments.
2518 // This contains 3 segments, one each of type uint64, uint16, and
2519 // unit32. The first two are "common data" which contains information
2520 // common to all rocs. The last (uint32) has information specific to each
2521 // event and for each ROC.
2522 //
2523 // For now, we skip parseing the Built Trigger Bank and just
2524 // look for Data Block Banks. We do this by getting a list of
2525 // all uint32_t banks in the enitries DOM Tree (at all levels
2526 // of the heirachy) and checking the parent banks for depth
2527 // and additional info.
2528
2529 // Loop over list of all EVIO banks at all levels of the tree and parse
2530 // them, creating data objects and adding them to the overall list.
2531 evioDOMNodeListP bankList = evt->getNodeList();
2532 evioDOMNodeList::iterator iter = bankList->begin();
2533 if(VERBOSE>7) evioout << " Looping over " << bankList->size() << " banks in EVIO event" << endl;
2534 for(int ibank=1; iter!=bankList->end(); iter++, ibank++){ // ibank only used for debugging messages
2535
2536 if(VERBOSE>7) evioout << " -------- bank " << ibank << "/" << bankList->size() << " --------" << endl;
2537
2538 // The data banks we want should have exactly two parents:
2539 // - Data Bank bank <-- parent
2540 // - Physics Event bank <-- grandparent
2541 //
2542 // other types of events may be inserted in the datastream though so we
2543 // check for those first.
2544
2545 // BOR event
2546 // BOR events will have an outermost
2547 // bank with tag=0x70 and num=1. If this is the outermost bank of
2548 // a BOR event, then parse it. If it is a inner BOR bank then ignore it.
2549 evioDOMNodeP outermostBankPtr = *iter;
2550 while(outermostBankPtr->getParent()) outermostBankPtr = outermostBankPtr->getParent();
2551 if(outermostBankPtr->tag==0x70 && outermostBankPtr->num==1){
2552 // This is a BOR bank
2553 if(VERBOSE>9) evioout << " bank is part of BOR event ... " << endl;
2554 if(outermostBankPtr == *iter){
2555 if(VERBOSE>9) evioout << " bank is outermost EVIO bank. Parsing BOR event ..." << endl;
2556 ParseBORevent(outermostBankPtr);
2557 }else{
2558 if(VERBOSE>9) evioout << " bank is not outermost EVIO bankin BOR event skipping ..." << endl;
2559 }
2560 continue; // no further processing of this bank is needed
2561 }
2562
2563 // EPICS event
2564 evioDOMNodeP bankPtr = *iter;
2565 evioDOMNodeP data_bank = bankPtr->getParent();
2566 if( data_bank==NULL__null ) {
2567
2568 if(VERBOSE>9) evioout << " bank has no parent. Checking if it's an EPICS event ... " << endl;
2569 if(bankPtr->tag==96 && bankPtr->num==1){
2570 // This looks like an EPICS event. Hand it over to EPICS parser
2571 ParseEPICSevent(bankPtr, full_events);
2572 }else{
2573 if(VERBOSE>9) evioout << " Not an EPICS event bank. skipping ... " << endl;
2574 }
2575
2576 continue;
2577 }
2578
2579 // Trigger Bank
2580 evioDOMNodeP physics_event_bank = data_bank->getParent();
2581
2582 // TS scalers for SYNC events. Currently us phys event tag
2583 // Don't use the parent tag in the future, to be checked
2584 if((physics_event_bank != NULL__null) && (bankPtr != NULL__null)){
2585 if( (physics_event_bank->tag == 0xff70) && (bankPtr->tag == 0xEE02)){
2586 const vector<uint32_t> *vec = bankPtr->getVector<uint32_t>();
2587 if(vec->size() < 102){
2588 evioout << " TS record for SYNC event is inconsistent. Don't parse " << endl;
2589 } else {
2590 ParseTSSync(bankPtr, full_events);
2591 // MergeObjLists(full_events, tmp_events);
2592 }
2593 }
2594 }
2595
2596
2597 if( physics_event_bank==NULL__null ){
2598 if(VERBOSE>6) evioout << " bank has no grandparent. Checking if this is a trigger bank ... " << endl;
2599
2600 // Check if this is a CODA Reserved Bank Tag. If it is, then
2601 // this probably is part of the built trigger bank and not
2602 // the ROC data we're looking to parse here.
2603 if((bankPtr->tag & 0xFF00) == 0xFF00){
2604 if(VERBOSE>6) evioout << " Bank tag="<<hex<<data_bank->tag<<dec<<" is in reserved CODA range and has correct lineage. Assuming it's a built trigger bank."<< endl;
2605 ParseBuiltTriggerBank(bankPtr, tmp_events);
2606 if(VERBOSE>5) evioout << " Merging objects in ParseEVIOEvent" << endl;
2607 MergeObjLists(full_events, tmp_events);
2608
2609 // Check if this is a DEventTag bank
2610 }else if(bankPtr->tag == 0x0056){
2611 const vector<uint32_t> *vec = bankPtr->getVector<uint32_t>();
2612 if(vec){
2613 const uint32_t *iptr = &(*vec)[0];
2614 const uint32_t *iend = &(*vec)[vec->size()];
2615 ParseEventTag(iptr, iend, tmp_events);
2616 if(VERBOSE>5) evioout << " Merging DEventTag objects in ParseEVIOEvent" << endl;
2617 MergeObjLists(full_events, tmp_events);
2618 }
2619 }
2620
2621 continue; // if this wasn't a trigger bank, then it has the wrong lineage to be a data bank
2622 }
2623 if( physics_event_bank->getParent() != NULL__null ){
2624 if(VERBOSE>9) evioout << " bank DOES have great-grandparent. skipping ... " << endl;
2625 continue; // physics event bank should have no parent!
2626 }
2627 if(VERBOSE>9){
2628 evioout << " Physics Event Bank: tag=" << hex << physics_event_bank->tag << " num=" << (int)physics_event_bank->num << dec << endl;
2629 evioout << " Data Bank: tag=" << hex << data_bank->tag << " num=" << (int)data_bank->num << dec << endl;
2630 }
2631
2632 if(VERBOSE>9) evioout << " bank lineage check OK. Continuing with parsing ... " << endl;
2633
2634 // Extract ROC id (crate number) from bank's parent
2635 uint32_t rocid = data_bank->tag & 0x0FFF;
2636
2637 // Get data from bank in the form of a vector of uint32_t
2638 const vector<uint32_t> *vec = bankPtr->getVector<uint32_t>();
2639 if(!vec){
2640 if(VERBOSE>6) evioout << " bank is not uint32_t. Skipping..." << endl;
2641 continue;
2642 }
2643 const uint32_t *iptr = &(*vec)[0];
2644 const uint32_t *iend = &(*vec)[vec->size()];
2645 if(VERBOSE>6) evioout << " uint32_t bank has " << vec->size() << " words" << endl;
2646
2647 // If there are rocid's specified that we wish to parse, make sure this one
2648 // is in the list. Otherwise, skip it.
2649 if(!ROCIDS_TO_PARSE.empty()){
2650 if(VERBOSE>4) evioout << " Skipping parsing of rocid="<<rocid<<" due to it being in ROCIDS_TO_PARSE set." << endl;
2651 if(ROCIDS_TO_PARSE.find(rocid) == ROCIDS_TO_PARSE.end()) continue;
2652 }
2653
2654 // Check if this is a CODA Reserved Bank Tag.
2655 if((data_bank->tag & 0xFF00) == 0xFF00){
2656 if(VERBOSE>6) evioout << " Data Bank tag="<<hex<<data_bank->tag<<dec<<" is in reserved CODA range. This is probably not ROC data"<< endl;
2657 continue;
2658 }
2659
2660 // Check if this is a TS Bank.
2661 if(bankPtr->tag == 0xEE02){
2662 if(VERBOSE>4) evioout << " TS bank tag="<<hex<<bankPtr->tag<<dec<< endl;
2663 ParseTSBank(rocid, iptr, iend, full_events);
2664 continue;
2665 }
2666
2667 // Check if this is a f250 Pedestal Bank.
2668 if(bankPtr->tag == 0xEE05){
2669 if(VERBOSE>6) evioout << " SYNC event - f250 pedestals not currently handled"<< endl;
2670 continue;
2671 }
2672
2673 // The number of events in block is stored in lower 8 bits
2674 // of header word (aka the "num") of Data Bank. This should
2675 // be at least 1.
2676 uint32_t NumEvents = data_bank->num & 0xFF;
2677 if( NumEvents<1 ){
2678 if(VERBOSE>9) evioout << " bank has less than 1 event (Data Bank num or \"M\" = 0) skipping ... " << endl;
2679 continue;
2680 }
2681
2682 // At this point iptr and iend indicate the data that came
2683 // from the ROC itself (all CODA headers have been stripped
2684 // away). Here, we need to decide what type of data this
2685 // bank contains. All JLab modules have a common block
2686 // header format and so are handled in a common way. Other
2687 // modules (e.g. CAEN) will have to appear in their own
2688 // EVIO bank and should be identified by their own det_id
2689 // value in the Data Block Bank.
2690 //
2691 // Current, preliminary thinking includes writing the type
2692 // of data into the 12-bit detector id contained in the
2693 // Data Block Bank of the DAQ group's "Event Building EVIO
2694 // Scheme". (This is the lower 12 bits of the "tag"). We
2695 // use this to decide if it is JLab module data or somehting
2696 // else.
2697 uint32_t det_id = bankPtr->tag & 0x0FFF;
2698 // Call appropriate parsing method
2699 bool bank_parsed = true; // will be set to false if default case is entered
2700 switch(det_id){
2701 case 0:
2702 case 1:
2703 case 3:
2704 case 6: // flash 250 module, MMD 2014/2/4
2705 case 16: // flash 125 module (CDC), DL 2014/6/19
2706 case 26: // F1 TDC module (BCAL), MMD 2014-07-31
2707 ParseJLabModuleData(rocid, iptr, iend, tmp_events);
2708 break;
2709
2710 case 20:
2711 ParseCAEN1190(rocid, iptr, iend, tmp_events);
2712 break;
2713
2714 case 0x55:
2715 ParseModuleConfiguration(rocid, iptr, iend, tmp_events);
2716 break;
2717
2718 case 5:
2719 // Beni's original CDC ROL used for the stand-alone CDC DAQ
2720 // had the following for the TS readout list (used in the TI):
2721 // *dma_dabufp++ = 0xcebaf111;
2722 // *dma_dabufp++ = tsGetIntCount();
2723 // *dma_dabufp++ = 0xdead;
2724 // *dma_dabufp++ = 0xcebaf222;
2725 // We skip this here, but put in the case so that we avoid errors
2726 break;
2727
2728
2729 default:
2730 jerr<<"Unknown module type ("<<det_id<<") encountered for tag="<<bankPtr->tag<<" num="<< (int)bankPtr->num << endl;
2731 bank_parsed = false;
2732 if(VERBOSE>5){
2733 cerr << endl;
2734 cout << "----- First few words to help with debugging -----" << endl;
2735 cout.flush(); cerr.flush();
2736 int i=0;
2737 for(const uint32_t *iiptr = iptr; iiptr<iend; iiptr++, i++){
2738 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2738<<" "
<< "0x" << hex << *iiptr << dec << endl;
2739 if(i>=8) break;
2740 }
2741
2742 }
2743 }
2744
2745 // Merge this bank's partial events into the full events
2746 if(bank_parsed){
2747 if(VERBOSE>5) evioout << " Merging objects in ParseEVIOEvent" << endl;
2748 MergeObjLists(full_events, tmp_events);
2749 }
2750 }
2751
2752 // The following disabled in preference for keeping the
2753 // run number found by FindRunNumber called from
2754 // GetEvent() 2/15/2016
2755
2756 // // Set the run number for all events
2757 // uint32_t run_number = GetRunNumber(evt);
2758 // list<ObjList*>::iterator evt_iter = full_events.begin();
2759 // for(; evt_iter!=full_events.end(); evt_iter++){
2760 // ObjList *objs = *evt_iter;
2761 // objs->run_number = run_number;
2762 // }
2763
2764 if(VERBOSE>5) evioout << " Leaving ParseEVIOEvent()" << endl;
2765}
2766
2767//----------------
2768// ParseBuiltTriggerBank
2769//----------------
2770void JEventSource_EVIO::ParseBuiltTriggerBank(evioDOMNodeP trigbank, list<ObjList*> &events)
2771{
2772 if(!PARSE_TRIGGER) return;
2773
2774 if(VERBOSE>5) evioout << " Entering ParseBuiltTriggerBank()" << endl;
2775
2776 uint32_t Mevents = 1; // number of events in block (will be overwritten below)
2777 uint32_t Nrocs = (uint32_t)trigbank->num; // number of rocs providing data in this bank
2778 evioDOMNodeP physics_event_bank = trigbank->getParent();
2779 if(physics_event_bank) Mevents = (uint32_t)physics_event_bank->num;
2780
2781 if(VERBOSE>6) evioout << " Mevents=" << Mevents << " Nrocs=" << Nrocs << endl;
2782
2783 // Some values to fill in while parsing the banks that will be used later to create objects
2784 vector<uint64_t> avg_timestamps;
2785 uint32_t run_number = 0;
2786 uint32_t run_type = 0;
2787 uint64_t first_event_num = 1;
2788 vector<uint16_t> event_types;
2789 map<uint32_t, vector<DCODAROCInfo*> > rocinfos; // key=event (from 0 to Mevents-1)
2790 //vector<map<uint32_t, DCODAROCInfo*> > rocinfos; // key=rocid
2791
2792 // Loop over children of built trigger bank
2793 evioDOMNodeListP bankList = trigbank->getChildren();
2794 evioDOMNodeList::iterator iter = bankList->begin();
2795 for(int ibank=1; iter!=bankList->end(); iter++, ibank++){
2796
2797 if(VERBOSE>7) evioout << " Looking for data in child banks ..." << endl;
2798
2799 evioDOMNodeP bankPtr = *iter;
2800
2801 // The "Physics Event's Built Trigger Bank" is a bank of segments that
2802 // may contain banks of 3 data types: uint64_t, uint32_t, and uint16_t
2803 // The uint64_t contains the first event number, average timestamps, and
2804 // run number & types. The uint16_t contains the event type(s). The
2805 // uint32_t contains the optional ROC specific meta data starting with
2806 // the specific timestamp for each event. All of these have some options
2807 // on exactly what info is contained in the bank. The first check here is
2808 // on the data type the bank contains. At most, one of the following pointers
2809 // should be non-zero.
2810 vector<uint64_t> *vec64 = bankPtr->getVector<uint64_t>();
2811 vector<uint32_t> *vec32 = bankPtr->getVector<uint32_t>();
2812 vector<uint16_t> *vec16 = bankPtr->getVector<uint16_t>();
2813
2814 // unit64_t = common data (1st part)
2815 if(vec64){
2816
2817 if(VERBOSE>9) evioout << " found uint64_t data" << endl;
2818
2819 // In addition to the first event number (1st word) there are three
2820 // additional pieces of information that may be present:
2821 // t = average timestamp
2822 // r = run number and type
2823 // d = run specific data
2824 //
2825 // The last one ("d") comes in the form of multiple uint32_t banks
2826 // so is not included in vec64. The other two have their presence
2827 // signaled by bit 0(=t) and bit 1(=r) in the trigbank tag. (We can
2828 // also deduce this from the bank length.)
2829
2830 if(vec64->size() == 0) continue; // need debug message here!
2831
2832 first_event_num = (*vec64)[0];
2833
2834 // Hi and lo 32bit words in 64bit numbers seem to be
2835 // switched for events read from ET, but not read from
2836 // file. Not sure if this is in the swapping routine
2837 if(source_type==kETSource) first_event_num = (first_event_num>>32) | (first_event_num<<32);
2838
2839 uint32_t Ntimestamps = vec64->size()-1;
2840 if(Ntimestamps==0) continue; // no more words of interest
2841 if(trigbank->tag & 0x2) Ntimestamps--; // subtract 1 for run number/type word if present
2842 for(uint32_t i=0; i<Ntimestamps; i++) avg_timestamps.push_back((*vec64)[i+1]);
2843
2844 // run number and run type
2845 if(trigbank->tag & 0x02){
2846 run_number = (*vec64)[vec64->size()-1] >> 32;
2847 run_type = (*vec64)[vec64->size()-1] & 0xFFFFFFFF;
2848 }
2849 }
2850
2851 // uint16_t = common data (2nd part)
2852 if(vec16){
2853
2854 if(VERBOSE>9) evioout << " found uint16_t data" << endl;
2855
2856 for(uint32_t i=0; i<Mevents; i++){
2857 if(i>=vec16->size()) break;
2858 event_types.push_back((*vec16)[i]);
2859 }
2860 }
2861
2862 // uint32_t = inidivdual ROC timestamps and misc. roc-specfic data
2863 if(vec32){
2864
2865 if(VERBOSE>9) evioout << " found uint32_t data" << endl;
2866
2867 // Get pointer to DCODAROCInfo object for this rocid/event, instantiating it if necessary
2868 uint32_t rocid = (uint32_t)bankPtr->tag;
2869 uint32_t Nwords_per_event = vec32->size()/Mevents;
2870 if(vec32->size() != Mevents*Nwords_per_event){
2871 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2871<<" "
<< "Number of ROC data words in Trigger Bank inconsistent with header" << endl;
2872 exit(-1);
2873 }
2874
2875 uint32_t *iptr = &(*vec32)[0];
2876 for(uint32_t ievent=0; ievent<Mevents; ievent++){
2877
2878 DCODAROCInfo *codarocinfo = new DCODAROCInfo;
2879 codarocinfo->rocid = rocid;
2880
2881 uint64_t ts_low = *iptr++;
2882 uint64_t ts_high = *iptr++;
2883 codarocinfo->timestamp = (ts_high<<32) + ts_low;
2884 for(uint32_t i=2; i<Nwords_per_event; i++) codarocinfo->misc.push_back(*iptr++);
2885
2886 if(VERBOSE>7) evioout << " Adding DCODAROCInfo for rocid="<<rocid<< " with timestamp " << codarocinfo->timestamp << endl;
2887 rocinfos[ievent].push_back(codarocinfo);
2888 }
2889 }
2890 }
2891
2892 // Check that we have agreement on the number of events this data represents
2893 bool Nevent_mismatch = false;
2894 if(!avg_timestamps.empty()) Nevent_mismatch |= (avg_timestamps.size() != Mevents);
2895 if(!event_types.empty() ) Nevent_mismatch |= (event_types.size() != Mevents);
2896 if(!rocinfos.empty() ) Nevent_mismatch |= (rocinfos.size() != Mevents);
2897 if(Nevent_mismatch){
2898 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2898<<" "
<<"Mismatch in number of events in Trigger Bank!"<<endl;
2899 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2899<<" "
<<" Mevents="<<Mevents<<endl;
2900 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2900<<" "
<<" avg_timestamps.size()="<<avg_timestamps.size()<<endl;
2901 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2901<<" "
<<" event_types.size()="<<event_types.size()<<endl;
2902 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2902<<" "
<<" rocinfos.size()="<<rocinfos.size()<<endl;
2903 exit(-1);
2904 }
2905
2906 // Copy all objects into events
2907 for(uint32_t i=0; i<Mevents; i++){
2908 while(events.size()<=i){
2909 if(!ENABLE_DISENTANGLING && !events.empty()) break;
2910 events.push_back(new ObjList);
2911 }
2912 ObjList *objs = events.back();
2913
2914 DCODAEventInfo *codaeventinfo = new DCODAEventInfo;
2915 codaeventinfo->run_number = run_number;
2916 codaeventinfo->run_type = run_type;
2917 codaeventinfo->event_number = first_event_num + i;
2918 codaeventinfo->event_type = event_types.empty() ? 0:event_types[i];
2919 codaeventinfo->avg_timestamp = avg_timestamps.empty() ? 0:avg_timestamps[i];
2920 objs->misc_objs.push_back(codaeventinfo);
2921 objs->event_number = codaeventinfo->event_number;
2922
2923 vector<DCODAROCInfo*> &codarocinfos = rocinfos[i];
2924 for(uint32_t i=0; i<codarocinfos.size(); i++) objs->misc_objs.push_back(codarocinfos[i]);
2925 }
2926
2927 if(VERBOSE>6) evioout << " Found "<<events.size()<<" events in Built Trigger Bank"<< endl;
2928 if(VERBOSE>5) evioout << " Leaving ParseBuiltTriggerBank()" << endl;
2929}
2930
2931//----------------
2932// ParseModuleConfiguration
2933//----------------
2934void JEventSource_EVIO::ParseModuleConfiguration(int32_t rocid, const uint32_t* &iptr, const uint32_t *iend, list<ObjList*> &events)
2935{
2936 if(!PARSE_CONFIG){ iptr = iend; return; }
2937
2938 if(VERBOSE>5) evioout << " Entering ParseModuleConfiguration() (events.size()="<<events.size()<<")" << endl;
2939
2940 /// Parse a bank of module configuration data. These are configuration values
2941 /// programmed into the module at the beginning of the run that may be needed
2942 /// in the offline. For example, the number of samples to sum in a FADC pulse
2943 /// integral.
2944 ///
2945 /// The bank has one or more sections, each describing parameters applicable
2946 /// to a number of modules as indicated by a 24bit slot mask.
2947 ///
2948 /// This bank should appear only once per DAQ event which, if in multi-event
2949 /// block mode, may have multiple L1 events. The parameters here will apply
2950 /// to all L1 events in the block. This method will put the config objects
2951 /// in the first event of "events", creating it if needed. The config objects
2952 /// are duplicated for all other events in the block later, after all event
2953 /// parsing is finished and the total number of events is known.
2954 /// (See the end of ParseEvents() .)
2955
2956 while(iptr < iend){
2957 uint32_t slot_mask = (*iptr) & 0xFFFFFF;
2958 uint32_t Nvals = ((*iptr) >> 24) & 0xFF;
2959 iptr++;
2960
2961 Df250Config *f250config = NULL__null;
2962 Df125Config *f125config = NULL__null;
2963 DF1TDCConfig *f1tdcconfig = NULL__null;
2964 DCAEN1290TDCConfig *caen1290tdcconfig = NULL__null;
2965
2966 // Loop over all parameters in this section
2967 for(uint32_t i=0; i< Nvals; i++){
2968 if( iptr >= iend){
2969 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2969<<" "
<< "DAQ Configuration bank corrupt! slot_mask=0x" << hex << slot_mask << dec << " Nvals="<< Nvals << endl;
2970 exit(-1);
2971 }
2972
2973 daq_param_type ptype = (daq_param_type)((*iptr)>>16);
2974 uint16_t val = (*iptr) & 0xFFFF;
2975
2976 if(VERBOSE>6) evioout << " DAQ parameter of type: 0x" << hex << ptype << dec << " found with value: " << val << endl;
2977
2978 // Create config object of correct type if needed and copy
2979 // parameter value into it.
2980 switch(ptype>>8){
2981
2982 // f250
2983 case 0x05:
2984 if( !f250config ) f250config = new Df250Config(rocid, slot_mask);
2985 switch(ptype){
2986 case kPARAM250_NSA : f250config->NSA = val; break;
2987 case kPARAM250_NSB : f250config->NSB = val; break;
2988 case kPARAM250_NSA_NSB : f250config->NSA_NSB = val; break;
2989 case kPARAM250_NPED : f250config->NPED = val; break;
2990 default: _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<2990<<" "
<< "UNKNOWN DAQ Config Parameter type: 0x" << hex << ptype << dec << endl;
2991 }
2992 break;
2993
2994 // f125
2995 case 0x0F:
2996 if( !f125config ) f125config = new Df125Config(rocid, slot_mask);
2997 switch(ptype){
2998 case kPARAM125_NSA : f125config->NSA = val; break;
2999 case kPARAM125_NSB : f125config->NSB = val; break;
3000 case kPARAM125_NSA_NSB : f125config->NSA_NSB = val; break;
3001 case kPARAM125_NPED : f125config->NPED = val; break;
3002 case kPARAM125_WINWIDTH : f125config->WINWIDTH = val; break;
3003 case kPARAM125_PL : f125config->PL = val; break;
3004 case kPARAM125_NW : f125config->NW = val; break;
3005 case kPARAM125_NPK : f125config->NPK = val; break;
3006 case kPARAM125_P1 : f125config->P1 = val; break;
3007 case kPARAM125_P2 : f125config->P2 = val; break;
3008 case kPARAM125_PG : f125config->PG = val; break;
3009 case kPARAM125_IE : f125config->IE = val; break;
3010 case kPARAM125_H : f125config->H = val; break;
3011 case kPARAM125_TH : f125config->TH = val; break;
3012 case kPARAM125_TL : f125config->TL = val; break;
3013 case kPARAM125_IBIT : f125config->IBIT = val; break;
3014 case kPARAM125_ABIT : f125config->ABIT = val; break;
3015 case kPARAM125_PBIT : f125config->PBIT = val; break;
3016 default: _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3016<<" "
<< "UNKNOWN DAQ Config Parameter type: 0x" << hex << ptype << dec << endl;
3017 }
3018 break;
3019
3020 // F1TDC
3021 case 0x06:
3022 if( !f1tdcconfig ) f1tdcconfig = new DF1TDCConfig(rocid, slot_mask);
3023 switch(ptype){
3024 case kPARAMF1_REFCNT : f1tdcconfig->REFCNT = val; break;
3025 case kPARAMF1_TRIGWIN : f1tdcconfig->TRIGWIN = val; break;
3026 case kPARAMF1_TRIGLAT : f1tdcconfig->TRIGLAT = val; break;
3027 case kPARAMF1_HSDIV : f1tdcconfig->HSDIV = val; break;
3028 case kPARAMF1_BINSIZE : f1tdcconfig->BINSIZE = val; break;
3029 case kPARAMF1_REFCLKDIV : f1tdcconfig->REFCLKDIV = val; break;
3030 default: _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3030<<" "
<< "UNKNOWN DAQ Config Parameter type: 0x" << hex << ptype << dec << endl;
3031 }
3032 break;
3033
3034 // caen1290
3035 case 0x10:
3036 if( !caen1290tdcconfig ) caen1290tdcconfig = new DCAEN1290TDCConfig(rocid, slot_mask);
3037 switch(ptype){
3038 case kPARAMCAEN1290_WINWIDTH : caen1290tdcconfig->WINWIDTH = val; break;
3039 case kPARAMCAEN1290_WINOFFSET : caen1290tdcconfig->WINOFFSET = val; break;
3040 default: _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3040<<" "
<< "UNKNOWN DAQ Config Parameter type: 0x" << hex << ptype << dec << endl;
3041 }
3042 break;
3043
3044 default:
3045 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3045<<" "
<< "Unknown module type: 0x" << hex << (ptype>>8) << endl;
3046 exit(-1);
3047 }
3048
3049#if 0
3050 // Create config object of correct type if needed. (Only one type
3051 // should be created per section!)
3052 switch(ptype>>8){
3053 case 0x05: if(!f250config ) f250config = new Df250Config(rocid, slot_mask); break;
3054 case 0x0F: if(!f125config ) f125config = new Df125Config(rocid, slot_mask); break;
3055 case 0x06: if(!f1tdcconfig ) f1tdcconfig = new DF1TDCConfig(rocid, slot_mask); break;
3056 case 0x10: if(!caen1290tdcconfig) caen1290tdcconfig = new DCAEN1290TDCConfig(rocid, slot_mask); break;
3057 default:
3058 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3058<<" "
<< "Unknown module type: 0x" << hex << (ptype>>8) << endl;
3059 exit(-1);
3060 }
3061
3062 // Copy parameter into config. object
3063 switch(ptype){
3064 case kPARAM250_NSA : f250config->NSA = val; break;
3065 case kPARAM250_NSB : f250config->NSB = val; break;
3066 case kPARAM250_NSA_NSB : f250config->NSA_NSB = val; break;
3067 case kPARAM250_NPED : f250config->NPED = val; break;
3068
3069 case kPARAM125_NSA : f125config->NSA = val; break;
3070 case kPARAM125_NSB : f125config->NSB = val; break;
3071 case kPARAM125_NSA_NSB : f125config->NSA_NSB = val; break;
3072 case kPARAM125_NPED : f125config->NPED = val; break;
3073 case kPARAM125_WINWIDTH : f125config->WINWIDTH = val; break;
3074 case kPARAM125_PL : f125config->PL = val; break;
3075 case kPARAM125_NW : f125config->NW = val; break;
3076 case kPARAM125_NPK : f125config->NPK = val; break;
3077 case kPARAM125_P1 : f125config->P1 = val; break;
3078 case kPARAM125_P2 : f125config->P2 = val; break;
3079 case kPARAM125_PG : f125config->PG = val; break;
3080 case kPARAM125_IE : f125config->IE = val; break;
3081 case kPARAM125_H : f125config->H = val; break;
3082 case kPARAM125_TH : f125config->TH = val; break;
3083 case kPARAM125_TL : f125config->TL = val; break;
3084 case kPARAM125_IBIT : f125config->IBIT = val; break;
3085 case kPARAM125_ABIT : f125config->ABIT = val; break;
3086 case kPARAM125_PBIT : f125config->PBIT = val; break;
3087
3088 case kPARAMF1_REFCNT : f1tdcconfig->REFCNT = val; break;
3089 case kPARAMF1_TRIGWIN : f1tdcconfig->TRIGWIN = val; break;
3090 case kPARAMF1_TRIGLAT : f1tdcconfig->TRIGLAT = val; break;
3091 case kPARAMF1_HSDIV : f1tdcconfig->HSDIV = val; break;
3092 case kPARAMF1_BINSIZE : f1tdcconfig->BINSIZE = val; break;
3093 case kPARAMF1_REFCLKDIV : f1tdcconfig->REFCLKDIV = val; break;
3094
3095 case kPARAMCAEN1290_WINWIDTH : caen1290tdcconfig->WINWIDTH = val; break;
3096 case kPARAMCAEN1290_WINOFFSET : caen1290tdcconfig->WINOFFSET = val; break;
3097
3098 default:
3099 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3099<<" "
<< "UNKNOWN DAQ Config Parameter type: 0x" << hex << ptype << dec << endl;
3100 }
3101#endif
3102
3103 iptr++;
3104 }
3105
3106 // If we get here it means we didn't exit in the switch(ptype>>16) statement above
3107 // so there is at least one DDAQConfig object we need to store. Get pointer to
3108 // first event's ObjList, creating it if needed.
3109 if(events.empty()) events.push_back(new ObjList());
3110 ObjList *objs = *(events.begin());
3111
3112 if(f250config ) objs->config_objs.push_back(f250config );
3113 if(f125config ) objs->config_objs.push_back(f125config );
3114 if(f1tdcconfig ) objs->config_objs.push_back(f1tdcconfig );
3115 if(caen1290tdcconfig) objs->config_objs.push_back(caen1290tdcconfig);
3116 }
3117
3118 if(VERBOSE>5) evioout << " Leaving ParseModuleConfiguration()" << endl;
3119}
3120
3121//----------------
3122// ParseEventTag
3123//----------------
3124void JEventSource_EVIO::ParseEventTag(const uint32_t* &iptr, const uint32_t *iend, list<ObjList*> &events)
3125{
3126 if(!PARSE_EVENTTAG){ iptr = iend; return; }
3127
3128 if(VERBOSE>5) evioout << " Entering ParseEventTag() (events.size()="<<events.size()<<")" << endl;
3129
3130 // Make sure there is one event in the event container
3131 // and get pointer to it.
3132 if(events.empty()) events.push_back(new ObjList());
3133 ObjList *objs = *(events.begin());
3134
3135
3136 DEventTag *etag = new DEventTag;
3137
3138 // event_status
3139 uint64_t lo = *iptr++;
3140 uint64_t hi = *iptr++;
3141 etag->event_status = (hi<<32) + lo;
3142
3143 // L3_status
3144 lo = *iptr++;
3145 hi = *iptr++;
3146 etag->L3_status = (hi<<32) + lo;
3147
3148 // L3_decision
3149 etag->L3_decision = (DL3Trigger::L3_decision_t)*iptr++;
3150
3151 // L3_algorithm
3152 etag->L3_algorithm = *iptr++;
3153
3154 objs->misc_objs.push_back(etag);
3155
3156
3157 if(VERBOSE>5) evioout << " Leaving ParseEventTag()" << endl;
3158}
3159
3160//----------------
3161// ParseJLabModuleData
3162//----------------
3163void JEventSource_EVIO::ParseJLabModuleData(int32_t rocid, const uint32_t* &iptr, const uint32_t *iend, list<ObjList*> &events)
3164{
3165 if(VERBOSE>5) evioout << " Entering ParseJLabModuleData()" << endl;
3166
3167 /// Parse a bank of data coming from one or more JLab modules.
3168 /// The data are assumed to follow the standard JLab format for
3169 /// block headers. If multiple modules are read out in a single
3170 /// chain block transfer, then the data will all be placed in
3171 /// a single EVIO bank and this will loop over the modules.
3172 while(iptr < iend){
3173
3174 if(VERBOSE>9) evioout << "Parsing word: " << hex << *iptr << dec << endl;
3175
3176 // This was observed in some CDC data. Not sure where it came from ...
3177 if(*iptr == 0xF800FAFA){
3178 if(VERBOSE>9) evioout << " 0xf800fafa is a known extra word. Skipping it ..." << endl;
3179 iptr++;
3180 continue;
3181 }
3182
3183 // Get module type from next word (bits 18-21)
3184 uint32_t mod_id = ((*iptr) >> 18) & 0x000F;
3185
3186 // The enum defined in DModuleType.h MUST be kept in alignment
3187 // with the DAQ group's definitions for modules types!
3188 MODULE_TYPE type = (MODULE_TYPE)mod_id;
3189 if(VERBOSE>5) evioout << " Encountered module type: " << type << " (=" << DModuleType::GetModule(type).GetName() << ")" << endl;
3190
3191 if(modtype_translate.find(type) != modtype_translate.end()){
3192 type = modtype_translate[type];
3193 if(VERBOSE>5) evioout << " switched module type to: " << type << " (=" << DModuleType::GetModule(type).GetName() << ")" << endl;
3194 }
3195
3196 // Parse buffer depending on module type
3197 // (Note that each of the ParseXXX routines called below will
3198 // update the "iptr" variable to point to the next word
3199 // after the block it parsed.)
3200 list<ObjList*> tmp_events;
3201 const uint32_t *istart=iptr; // just for UNKNOWN case below
3202 bool module_parsed = true;
3203 switch(type){
3204 case DModuleType::FADC250:
3205 Parsef250Bank(rocid, iptr, iend, tmp_events);
3206 break;
3207
3208 case DModuleType::FADC125:
3209 Parsef125Bank(rocid, iptr, iend, tmp_events);
3210 break;
3211
3212 case DModuleType::F1TDC32:
3213 ParseF1TDCBank(rocid, iptr, iend, tmp_events);
3214 break;
3215
3216 case DModuleType::F1TDC48:
3217 ParseF1TDCBank(rocid, iptr, iend, tmp_events);
3218 break;
3219
3220 case DModuleType::JLAB_TS:
3221 //ParseTSBank(rocid, iptr, iend, tmp_events); // This is not used
3222 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<3222<<" "
<< "What the ? ! This data type isn't supposed to be here!!" << endl;
3223 break;
3224
3225 case DModuleType::TID:
3226 ParseTIBank(rocid, iptr, iend, tmp_events);
3227 break;
3228
3229 case DModuleType::UNKNOWN:
3230 default:
3231 jerr<<"Unknown module type ("<<mod_id<<") iptr=0x" << hex << iptr << dec << endl;
3232
3233 while(iptr<iend && ((*iptr) & 0xF8000000) != 0x88000000) iptr++; // Skip to JLab block trailer
3234 iptr++; // advance past JLab block trailer
3235 while(iptr<iend && *iptr == 0xF8000000) iptr++; // skip filler words after block trailer
3236 module_parsed = false;
3237 jerr<<"...skipping to 0x" << hex << iptr << dec << " (discarding " << (((uint64_t)iptr-(uint64_t)istart)/4) << " words)" << endl;
3238 break;
3239 }
3240
3241 if(VERBOSE>9) evioout << "Finished parsing (last word: " << hex << iptr[-1] << dec << ")" << endl;
3242
3243 if(module_parsed){
3244 if(VERBOSE>5) evioout << " Merging objects in ParseJLabModuleData" << endl;
3245 MergeObjLists(events, tmp_events);
3246 }
3247 }
3248
3249 if(VERBOSE>5) evioout << " Leaving ParseJLabModuleData()" << endl;
3250}
3251
3252//----------------
3253// Parsef250Bank
3254//----------------
3255void JEventSource_EVIO::Parsef250Bank(int32_t rocid, const uint32_t* &iptr, const uint32_t *iend, list<ObjList*> &events)
3256{
3257 /// Parse data from a single FADC250 module.
3258
3259 if(!PARSE_F250){ iptr = iend; return; }
3260
3261 // This will get updated to point to a newly allocated object when an
3262 // event header is encountered. The existing value (if non-NULL) is
3263 // added to the events queue first though so all events are kept.
3264 ObjList *objs = NULL__null;
3265
3266 // From the Block Header
3267 uint32_t slot=0;
3268 //uint32_t Nblock_events;
3269 //uint32_t iblock;
3270
3271 // From the Block Trailer
3272 //uint32_t slot_trailer;
3273 //uint32_t Nwords_in_block;
3274
3275 // From Event header
3276 //uint32_t slot_event_header;
3277 uint32_t itrigger = -1;
3278 uint32_t last_itrigger = -2;
3279
3280 // Loop over data words
3281 for(; iptr<iend; iptr++){
3282
3283 // Skip all non-data-type-defining words at this
3284 // level. When we do encounter one, the appropriate
3285 // case block below should handle parsing all of
3286 // the data continuation words and advance the iptr.
3287 if(((*iptr>>31) & 0x1) == 0)continue;
3288
3289 // Variables used inside of switch, but cannot be declared inside
3290 uint64_t t = 0L;
3291 uint32_t channel = 0;
3292 uint32_t sum = 0;
3293 uint32_t pulse_number = 0;
3294 uint32_t quality_factor = 0;
3295 uint32_t pulse_time = 0;
3296 uint32_t pedestal = 0;
3297 uint32_t pulse_peak = 0;
3298 uint32_t nsamples_integral = 0;
3299 uint32_t nsamples_pedestal = 0;
3300 bool overflow = false;
3301
3302 bool found_block_trailer = false;
3303 uint32_t data_type = (*iptr>>27) & 0x0F;
3304 switch(data_type){
3305 case 0: // Block Header
3306 slot = (*iptr>>22) & 0x1F;
3307 if(VERBOSE>7) evioout << " FADC250 Block Header: slot="<<slot<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3308 //iblock= (*iptr>>8) & 0x03FF;
3309 //Nblock_events= (*iptr>>0) & 0xFF;
3310 break;
3311 case 1: // Block Trailer
3312 //slot_trailer = (*iptr>>22) & 0x1F;
3313 //Nwords_in_block = (*iptr>>0) & 0x3FFFFF;
3314 if(VERBOSE>7) evioout << " FADC250 Block Trailer"<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3315 found_block_trailer = true;
3316 break;
3317 case 2: // Event Header
3318 //slot_event_header = (*iptr>>22) & 0x1F;
3319 itrigger = (*iptr>>0) & 0x3FFFFF;
3320 if(VERBOSE>7) evioout << " FADC250 Event Header: itrigger="<<itrigger<<" (objs=0x"<<hex<<objs<<dec<<", last_itrigger="<<last_itrigger<<", rocid="<<rocid<<", slot="<<slot<<")" <<" ("<<hex<<*iptr<<dec<<")" <<endl;
3321 if( (itrigger!=last_itrigger) || (objs==NULL__null) ){
3322 if(ENABLE_DISENTANGLING){
3323 if(objs){
3324 events.push_back(objs);
3325 objs = NULL__null;
3326 }
3327 }
3328 if(!objs) objs = new ObjList;
3329 last_itrigger = itrigger;
3330 }
3331 break;
3332 case 3: // Trigger Time
3333 t = ((*iptr)&0xFFFFFF)<<0;
3334 if(VERBOSE>7) evioout << " FADC250 Trigger Time: t="<<t<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3335 iptr++;
3336 if(((*iptr>>31) & 0x1) == 0){
3337 t += ((*iptr)&0xFFFFFF)<<24; // from word on the street: second trigger time word is optional!!??
3338 if(VERBOSE>7) evioout << " Trigger time high word="<<(((*iptr)&0xFFFFFF))<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3339 }else{
3340 iptr--;
3341 }
3342 if(objs) objs->hit_objs.push_back(new Df250TriggerTime(rocid, slot, itrigger, t));
3343 break;
3344 case 4: // Window Raw Data
3345 // iptr passed by reference and so will be updated automatically
3346 if(VERBOSE>7) evioout << " FADC250 Window Raw Data"<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3347 MakeDf250WindowRawData(objs, rocid, slot, itrigger, iptr);
3348 break;
3349 case 5: // Window Sum
3350 channel = (*iptr>>23) & 0x0F;
3351 sum = (*iptr>>0) & 0x3FFFFF;
3352 overflow = (*iptr>>22) & 0x1;
3353 if(VERBOSE>7) evioout << " FADC250 Window Sum"<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3354 if(objs) objs->hit_objs.push_back(new Df250WindowSum(rocid, slot, channel, itrigger, sum, overflow));
3355 break;
3356 case 6: // Pulse Raw Data
3357 // iptr passed by reference and so will be updated automatically
3358 if(VERBOSE>7) evioout << " FADC250 Pulse Raw Data"<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3359 MakeDf250PulseRawData(objs, rocid, slot, itrigger, iptr);
3360 break;
3361 case 7: // Pulse Integral
3362 channel = (*iptr>>23) & 0x0F;
3363 pulse_number = (*iptr>>21) & 0x03;
3364 quality_factor = (*iptr>>19) & 0x03;
3365 sum = (*iptr>>0) & 0x7FFFF;
3366 nsamples_integral = 0; // must be overwritten later in GetObjects with value from Df125Config value
3367 nsamples_pedestal = 1; // The firmware returns an already divided pedestal
3368 pedestal = 0; // This will be replaced by the one from Df250PulsePedestal in GetObjects
3369 if(VERBOSE>7) evioout << " FADC250 Pulse Integral: chan="<<channel<<" pulse_number="<<pulse_number<<" sum="<<sum<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3370 if( (objs!=NULL__null) && (pulse_number<F250PULSE_NUMBER_FILTER) ) {
3371 objs->hit_objs.push_back(new Df250PulseIntegral(rocid, slot, channel, itrigger, pulse_number,
3372 quality_factor, sum, pedestal, nsamples_integral, nsamples_pedestal));
3373 }
3374 break;
3375 case 8: // Pulse Time
3376 channel = (*iptr>>23) & 0x0F;
3377 pulse_number = (*iptr>>21) & 0x03;
3378 quality_factor = (*iptr>>19) & 0x03;
3379 pulse_time = (*iptr>>0) & 0x7FFFF;
3380 if(VERBOSE>7) evioout << " FADC250 Pulse Time: chan="<<channel<<" pulse_number="<<pulse_number<<" pulse_time="<<pulse_time<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3381 if( (objs!=NULL__null) && (pulse_number<F250PULSE_NUMBER_FILTER) ) {
3382 objs->hit_objs.push_back(new Df250PulseTime(rocid, slot, channel, itrigger, pulse_number, quality_factor, pulse_time));
3383 }
3384 break;
3385 case 9: // Streaming Raw Data
3386 // This is marked "reserved for future implementation" in the current manual (v2).
3387 // As such, we don't try handling it here just yet.
3388 if(VERBOSE>7) evioout << " FADC250 Streaming Raw Data (unsupported)"<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3389 break;
3390 case 10: // Pulse Pedestal
3391 channel = (*iptr>>23) & 0x0F;
3392 pulse_number = (*iptr>>21) & 0x03;
3393 pedestal = (*iptr>>12) & 0x1FF;
3394 pulse_peak = (*iptr>>0) & 0xFFF;
3395 if(VERBOSE>7) evioout << " FADC250 Pulse Pedestal chan="<<channel<<" pulse_number="<<pulse_number<<" pedestal="<<pedestal<<" pulse_peak="<<pulse_peak<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3396 if( (objs!=NULL__null) && (pulse_number<F250PULSE_NUMBER_FILTER) ) {
3397 objs->hit_objs.push_back(new Df250PulsePedestal(rocid, slot, channel, itrigger, pulse_number, pedestal, pulse_peak));
3398 }
3399 break;
3400 case 13: // Event Trailer
3401 // This is marked "suppressed for normal readout – debug mode only" in the
3402 // current manual (v2). It does not contain any data so the most we could do here
3403 // is return early. I'm hesitant to do that though since it would mean
3404 // different behavior for debug mode data as regular data.
3405 case 14: // Data not valid (empty module)
3406 case 15: // Filler (non-data) word
3407 if(VERBOSE>7) evioout << " FADC250 Event Trailer, Data not Valid, or Filler word ("<<data_type<<")"<<" ("<<hex<<*iptr<<dec<<")"<<endl;
3408 break;
3409 }
3410
3411 // Once we find a block trailer, assume that is it for this module.
3412 if(found_block_trailer){
3413 iptr++; // iptr is still pointing to block trailer. Jump to next word.
3414 break;
3415 }
3416 }
3417
3418 // Chop off filler words
3419 for(; iptr<iend; iptr++){
3420 if(((*iptr)&0xf8000000) != 0xf8000000) break;
3421 }
3422
3423 // Add last event in block to list
3424 if(objs)events.push_back(objs);
3425
3426 // Here, we make object associations to link PulseIntegral, PulseTime, PulseRawData, etc
3427 // objects to each other so it is easier to get to these downstream without having to
3428 // make nested loops. This is the most efficient place to do it since the ObjList objects
3429 // in "event" contain only the objects from this EVIO block (i.e. at most one crate's
3430 // worth.)
3431 list<ObjList*>::iterator iter = events.begin();
3432 for(; iter!=events.end(); iter++){
3433
3434 // Sort list of objects into type-specific lists
3435 vector<DDAQAddress*> &hit_objs = (*iter)->hit_objs;
3436 vector<Df250TriggerTime*> vtrigt;
3437 vector<Df250WindowRawData*> vwrd;
3438 vector<Df250WindowSum*> vws;
3439 vector<Df250PulseRawData*> vprd;
3440 vector<Df250PulseIntegral*> vpi;
3441 vector<Df250PulseTime*> vpt;
3442 vector<Df250PulsePedestal*> vpp;
3443 for(unsigned int i=0; i<hit_objs.size(); i++){
3444 AddIfAppropriate(hit_objs[i], vtrigt);
3445 AddIfAppropriate(hit_objs[i], vwrd);
3446 AddIfAppropriate(hit_objs[i], vws);
3447 AddIfAppropriate(hit_objs[i], vprd);
3448 AddIfAppropriate(hit_objs[i], vpi);
3449 AddIfAppropriate(hit_objs[i], vpt);
3450 AddIfAppropriate(hit_objs[i], vpp);
3451 }
3452
3453 // Connect Df250PulseIntegral, Df250PulseTime, and
3454 // Df250PulsePedestal with Df250PulseRawData
3455 // (n.b. the associations between pi, pt, and pp are
3456 // done in GetObjects where emulated objects are
3457 // also available.)
3458 LinkAssociationsWithPulseNumber(vprd, vpi);
3459 LinkAssociationsWithPulseNumber(vprd, vpt);
3460 LinkAssociationsWithPulseNumber(vprd, vpp);
3461
3462 // Connect Df250WindowSum and Df250WindowRawData
3463 LinkAssociations(vwrd, vws);
3464
3465 // Connect Df250TriggerTime to everything
3466 LinkAssociationsModuleOnly(vtrigt, vwrd);
3467 LinkAssociationsModuleOnly(vtrigt, vws);
3468 LinkAssociationsModuleOnly(vtrigt, vprd);
3469 LinkAssociationsModuleOnly(vtrigt, vpi);
3470 LinkAssociationsModuleOnly(vtrigt, vpt);
3471 LinkAssociationsModuleOnly(vtrigt, vpp);
3472 }
3473}
3474
3475//----------------
3476// MakeDf250WindowRawData
3477//----------------
3478void JEventSource_EVIO::MakeDf250WindowRawData(ObjList *objs, uint32_t rocid, uint32_t slot, uint32_t itrigger, const uint32_t* &iptr)
3479{
3480 uint32_t channel = (*iptr>>23) & 0x0F;
3481 uint32_t window_width = (*iptr>>0) & 0x0FFF;
3482
3483 Df250WindowRawData *wrd = new Df250WindowRawData(rocid, slot, channel, itrigger);
3484
3485 for(uint32_t isample=0; isample<window_width; isample +=2){
3486
3487 // Advance to next word
3488 iptr++;
3489
3490 // Make sure this is a data continuation word, if not, stop here
3491 if(((*iptr>>31) & 0x1) != 0x0){
3492 iptr--; // calling method expects us to point to last word in block
3493 break;
3494 }
3495
3496 bool invalid_1 = (*iptr>>29) & 0x1;
3497 bool invalid_2 = (*iptr>>13) & 0x1;
3498 uint16_t sample_1 = 0;
3499 uint16_t sample_2 = 0;
3500 if(!invalid_1)sample_1 = (*iptr>>16) & 0x1FFF;
3501 if(!invalid_2)sample_2 = (*iptr>>0) & 0x1FFF;
3502
3503 // Sample 1
3504 wrd->samples.push_back(sample_1);
3505 wrd->invalid_samples |= invalid_1;
3506 wrd->overflow |= (sample_1>>12) & 0x1;
3507
3508 if((isample+2) == window_width && invalid_2)break; // skip last sample if flagged as invalid
3509
3510 // Sample 2
3511 wrd->samples.push_back(sample_2);
3512 wrd->invalid_samples |= invalid_2;
3513 wrd->overflow |= (sample_2>>12) & 0x1;
3514 }
3515
3516 // Due to how the calling function works, the value of "objs" passed to us may be NULL.
3517 // This will happen if a Window Raw Data block is encountered before an event header.
3518 // For these cases, we still want to try parsing the data so that the iptr is updated
3519 // but don't have an event to assign it to. If "objs" is non-NULL, add this object to
3520 // the list. Otherwise, delete it now.
3521 if(objs){
3522 objs->hit_objs.push_back(wrd);
3523 }else{
3524 delete wrd;
3525 }
3526}
3527
3528//----------------
3529// MakeDf250PulseRawData
3530//----------------
3531void JEventSource_EVIO::MakeDf250PulseRawData(ObjList *objs, uint32_t rocid, uint32_t slot, uint32_t itrigger, const uint32_t* &iptr)
3532{
3533 const uint32_t *istart = iptr;
3534 uint32_t channel = (*iptr>>23) & 0x0F;
3535 uint32_t pulse_number = (*iptr>>21) & 0x0003;
3536 uint32_t first_sample_number = (*iptr>>0) & 0x03FF;
3537
3538 if(VERBOSE>9) evioout << " DF250PulseRawData: iptr=0x" << hex << iptr << dec << " channel=" << channel << " pulse_number=" << pulse_number << " first_sample=" << first_sample_number << endl;
3539
3540 Df250PulseRawData *prd = new Df250PulseRawData(rocid, slot, channel, itrigger, pulse_number, first_sample_number);
3541
3542 // This loop needs to break when it hits a non-continuation word
3543 for(uint32_t isample=0; isample<1000; isample +=2){
3544
3545 // Advance to next word
3546 iptr++;
3547
3548 // Make sure this is a data continuation word, if not, stop here
3549 if(((*iptr>>31) & 0x1) != 0x0)break;
3550
3551 bool invalid_1 = (*iptr>>29) & 0x1;
3552 bool invalid_2 = (*iptr>>13) & 0x1;
3553 uint16_t sample_1 = 0;
3554 uint16_t sample_2 = 0;
3555 if(!invalid_1)sample_1 = (*iptr>>16) & 0x1FFF;
3556 if(!invalid_2)sample_2 = (*iptr>>0) & 0x1FFF;
3557
3558 // Sample 1
3559 prd->samples.push_back(sample_1);
3560 prd->invalid_samples |= invalid_1;
3561 prd->overflow |= (sample_1>>12) & 0x1;
3562
3563 bool last_word = (iptr[1]>>31) & 0x1;
3564 if(last_word && invalid_2)break; // skip last sample if flagged as invalid
3565
3566 // Sample 2
3567 prd->samples.push_back(sample_2);
3568 prd->invalid_samples |= invalid_2;
3569 prd->overflow |= (sample_2>>12) & 0x1;
3570 }
3571
3572 if(VERBOSE>9) evioout << " number of samples: " << prd->samples.size() << " words processed: " << iptr-istart << endl;
3573
3574 // When should get here because the loop above stopped when it found
3575 // a data defining word (bit 31=1). The method calling this one will
3576 // assume iptr is pointing to the last word of this block and it will
3577 // advance to the first word of the next block. We need to back up one
3578 // word so that it is pointing to the last word of this block.
3579 iptr--;
3580
3581 // Due to how the calling function works, the value of "objs" passed to us may be NULL.
3582 // This will happen if a Window Raw Data block is encountered before an event header.
3583 // For these cases, we still want to try parsing the data so that the iptr is updated
3584 // but don't have an event to assign it to. If "objs" is non-NULL, add this object to
3585 // the list. Otherwise, delete it now.
3586 if(objs){
3587 objs->hit_objs.push_back(prd);
3588 }else{
3589 delete prd;
3590 }
3591}
3592
3593//----------------
3594// Parsef125Bank
3595//----------------
3596void JEventSource_EVIO::Parsef125Bank(int32_t rocid, const uint32_t* &iptr, const uint32_t* iend, list<ObjList*> &events)
3597{
3598 /// Parse data from a single FADC125 module.
3599 /// This is currently written assuming that the Pulse Integral, Pulse Time, and Pulse Pedestal
3600 /// data formats follow what is in the file:
3601 /// https://halldweb1.jlab.org/wiki/index.php/File:FADC125_dataformat_250_modes.docx
3602
3603 if(!PARSE_F125){ iptr = iend; return; }
3604
3605 if(VERBOSE>6) evioout << " Entering Parsef125Bank for rocid=" << rocid << "..."<<endl;
3606
3607 // This will get updated to point to a newly allocated object when an
3608 // event header is encountered. The existing value (if non-NULL) is
3609 // added to the events queue first though so all events are kept.
3610 ObjList *objs = NULL__null;
3611
3612 // From the Block Header
3613 uint32_t slot=0;
3614 //uint32_t Nblock_events;
3615 //uint32_t iblock;
3616
3617 // From the Block Trailer
3618 //uint32_t slot_trailer;
3619 //uint32_t Nwords_in_block;
3620
3621 // From Event header
3622 //uint32_t slot_event_header;
3623 uint32_t itrigger = -1;
3624 uint32_t last_itrigger = -2;
3625 uint32_t last_pulse_time_channel=0;
3626 uint32_t last_slot = -1;
3627 uint32_t last_channel = -1;
3628
3629 // Loop over data words
3630 for(; iptr<iend; iptr++){
3631
3632 // Skip all non-data-type-defining words at this
3633 // level. When we do encounter one, the appropriate
3634 // case block below should handle parsing all of
3635 // the data continuation words and advance the iptr.
3636 if(((*iptr>>31) & 0x1) == 0)continue;
3637
3638 // Variables used inside of switch, but cannot be declared inside
3639 uint64_t t = 0L;
3640 uint32_t channel = 0;
3641 uint32_t sum = 0;
3642 uint32_t pulse_number = 0;
3643 uint32_t pulse_time = 0;
3644 uint32_t quality_factor = 0;
3645 uint32_t overflow_count = 0;
3646 uint32_t pedestal = 0;
3647 uint32_t pulse_peak = 0;
3648 uint32_t peak_time = 0;
3649 uint32_t nsamples_integral = 0;
3650 uint32_t nsamples_pedestal = 0;
3651 uint32_t word1=0;
3652 uint32_t word2=0;
3653
3654 bool found_block_trailer = false;
3655 uint32_t data_type = (*iptr>>27) & 0x0F;
3656 switch(data_type){
3657 case 0: // Block Header
3658 slot = (*iptr>>22) & 0x1F;
3659 if(VERBOSE>7) evioout << " FADC125 Block Header: slot="<<slot<<endl;
3660 //iblock= (*iptr>>8) & 0x03FF;
3661 //Nblock_events= (*iptr>>0) & 0xFF;
3662 break;
3663 case 1: // Block Trailer
3664 //slot_trailer = (*iptr>>22) & 0x1F;
3665 //Nwords_in_block = (*iptr>>0) & 0x3FFFFF;
3666 found_block_trailer = true;
3667 break;
3668 case 2: // Event Header
3669 //slot_event_header = (*iptr>>22) & 0x1F;
3670 itrigger = (*iptr>>0) & 0x3FFFFFF;
3671 if(VERBOSE>7) evioout << " FADC125 Event Header: itrigger="<<itrigger<<" (objs=0x"<<hex<<objs<<dec<<", last_itrigger="<<last_itrigger<<", rocid="<<rocid<<", slot="<<slot<<")" <<endl;
3672 if( (itrigger!=last_itrigger) || (objs==NULL__null) ){
3673 if(ENABLE_DISENTANGLING){
3674 if(objs){
3675 events.push_back(objs);
3676 objs = NULL__null;
3677 }
3678 }
3679 if(!objs) objs = new ObjList;
3680 last_itrigger = itrigger;
3681 }
3682 break;
3683 case 3: // Trigger Time
3684 t = ((*iptr)&0xFFFFFF)<<0;
3685 iptr++;
3686 if(((*iptr>>31) & 0x1) == 0){
3687 t += ((*iptr)&0xFFFFFF)<<24; // from word on the street: second trigger time word is optional!!??
3688 }else{
3689 iptr--;
3690 }
3691 if(VERBOSE>7) evioout << " FADC125 Trigger Time (t="<<t<<")"<<endl;
3692 if(objs) objs->hit_objs.push_back(new Df125TriggerTime(rocid, slot, itrigger, t));
3693 break;
3694 case 4: // Window Raw Data
3695 // iptr passed by reference and so will be updated automatically
3696 if(VERBOSE>7) evioout << " FADC125 Window Raw Data"<<endl;
3697 MakeDf125WindowRawData(objs, rocid, slot, itrigger, iptr);
3698 break;
3699
3700 case 5: // CDC pulse data (new) (GlueX-doc-2274-v8)
3701
3702 // Word 1:
3703 word1 = *iptr;
3704 channel = (*iptr>>20) & 0x7F;
3705 pulse_number = (*iptr>>15) & 0x1F;
3706 pulse_time = (*iptr>>4 ) & 0x7FF;
3707 quality_factor = (*iptr>>3 ) & 0x1; //time QF bit
3708 overflow_count = (*iptr>>0 ) & 0x7;
3709 if(VERBOSE>8) evioout << " FADC125 CDC Pulse Data word1: " << hex << (*iptr) << dec << endl;
3710 if(VERBOSE>7) evioout << " FADC125 CDC Pulse Data (chan="<<channel<<" pulse="<<pulse_number<<" time="<<pulse_time<<" QF="<<quality_factor<<" OC="<<overflow_count<<")"<<endl;
3711
3712 // Word 2:
3713 ++iptr;
3714 if(iptr>=iend){
3715 jerr << " Truncated f125 CDC hit (block ends before continuation word!)" << endl;
3716 continue;
3717 }
3718 if( ((*iptr>>31) & 0x1) != 0 ){
3719 jerr << " Truncated f125 CDC hit (missing continuation word!)" << endl;
3720 continue;
3721 }
3722 word2 = *iptr;
3723 pedestal = (*iptr>>23) & 0xFF;
3724 sum = (*iptr>>9 ) & 0x3FFF;
3725 pulse_peak = (*iptr>>0 ) & 0x1FF;
3726 if(VERBOSE>8) evioout << " FADC125 CDC Pulse Data word2: " << hex << (*iptr) << dec << endl;
3727 if(VERBOSE>7) evioout << " FADC125 CDC Pulse Data (pedestal="<<pedestal<<" sum="<<sum<<" peak="<<pulse_peak<<")"<<endl;
3728
3729 // Create hit objects
3730 nsamples_integral = 0; // must be overwritten later in GetObjects with value from Df125Config value
3731 nsamples_pedestal = 1; // The firmware pedestal divided by 2^PBIT where PBIT is a config. parameter
3732
3733 if( (objs!=NULL__null) && (pulse_number<F125PULSE_NUMBER_FILTER) ) {
3734 // n.b. This is were we might apply a check on whether we are
3735 // only producing emulated objects. If so, then we shouldn't
3736 // create the Df125CDCPulse. At this point in time though,
3737 // there are 3 config. parameters that control this because
3738 // the original firmware produced 3 separate data types as
3739 // opposed to the new firmware that puts the same infomation
3740 // into a single data type. The emulation framework is also
3741 // being revamped.
3742 objs->hit_objs.push_back( new Df125CDCPulse(rocid, slot, channel, itrigger
3743 , pulse_number // NPK
3744 , pulse_time // le_time
3745 , quality_factor // time_quality_bit
3746 , overflow_count // overflow_count
3747 , pedestal // pedestal
3748 , sum // integral
3749 , pulse_peak // first_max_amp
3750 , word1 // word1
3751 , word2 // word2
3752 , nsamples_pedestal // nsamples_pedestal
3753 , nsamples_integral // nsamples_integral
3754 , false) // emulated
3755 );
3756 }
3757
3758 // n.b. We don't record last_slot, last_channel, etc... here since those
3759 // are only used by data types corresponding to older firmware that did
3760 // not write out data type 5.
3761 break;
3762
3763 case 6: // FDC pulse data-integral (new) (GlueX-doc-2274-v8)
3764
3765 // Word 1:
3766 word1 = *iptr;
3767 channel = (*iptr>>20) & 0x7F;
3768 pulse_number = (*iptr>>15) & 0x1F;
3769 pulse_time = (*iptr>>4 ) & 0x7FF;
3770 quality_factor = (*iptr>>3 ) & 0x1; //time QF bit
3771 overflow_count = (*iptr>>0 ) & 0x7;
3772 if(VERBOSE>8) evioout << " FADC125 FDC Pulse Data(integral) word1: " << hex << (*iptr) << dec << endl;
3773 if(VERBOSE>7) evioout << " FADC125 FDC Pulse Data (chan="<<channel<<" pulse="<<pulse_number<<" time="<<pulse_time<<" QF="<<quality_factor<<" OC="<<overflow_count<<")"<<endl;
3774
3775 // Word 2:
3776 ++iptr;
3777 if(iptr>=iend){
3778 jerr << " Truncated f125 FDC hit (block ends before continuation word!)" << endl;
3779 continue;
3780 }
3781 if( ((*iptr>>31) & 0x1) != 0 ){
3782 jerr << " Truncated f125 FDC hit (missing continuation word!)" << endl;
3783 continue;
3784 }
3785 word2 = *iptr;
3786 pulse_peak = 0;
3787 sum = (*iptr>>19) & 0xFFF;
3788 peak_time = (*iptr>>11) & 0xFF;
3789 pedestal = (*iptr>>0 ) & 0x7FF;
3790 if(VERBOSE>8) evioout << " FADC125 FDC Pulse Data(integral) word2: " << hex << (*iptr) << dec << endl;
3791 if(VERBOSE>7) evioout << " FADC125 FDC Pulse Data (integral="<<sum<<" time="<<peak_time<<" pedestal="<<pedestal<<")"<<endl;
3792
3793 // Create hit objects
3794 nsamples_integral = 0; // must be overwritten later in GetObjects with value from Df125Config value
3795 nsamples_pedestal = 1; // The firmware pedestal divided by 2^PBIT where PBIT is a config. parameter
3796
3797 if( (objs!=NULL__null) && (pulse_number<F125PULSE_NUMBER_FILTER) ) {
3798 // n.b. This is were we might apply a check on whether we are
3799 // only producing emulated objects. If so, then we shouldn't
3800 // create the Df125FDCPulse. At this point in time though,
3801 // there are 3 config. parameters that control this because
3802 // the original firmware produced 3 separate data types as
3803 // opposed to the new firmware that puts the same infomation
3804 // into a single data type. The emulation framework is also
3805 // being revamped.
3806 objs->hit_objs.push_back( new Df125FDCPulse(rocid, slot, channel, itrigger
3807 , pulse_number // NPK
3808 , pulse_time // le_time
3809 , quality_factor // time_quality_bit
3810 , overflow_count // overflow_count
3811 , pedestal // pedestal
3812 , sum // integral
3813 , pulse_peak // peak_amp
3814 , peak_time // peak_time
3815 , word1 // word1
3816 , word2 // word2
3817 , nsamples_pedestal // nsamples_pedestal
3818 , nsamples_integral // nsamples_integral
3819 , false) // emulated
3820 );
3821 }
3822
3823 // n.b. We don't record last_slot, last_channel, etc... here since those
3824 // are only used by data types corresponding to older firmware that did
3825 // not write out data type 6.
3826 break;
3827
3828 case 7: // Pulse Integral
3829 if(VERBOSE>7) evioout << " FADC125 Pulse Integral"<<endl;
3830 channel = (*iptr>>20) & 0x7F;
3831 sum = (*iptr>>0) & 0xFFFFF;
3832 nsamples_integral = 0; // must be overwritten later in GetObjects with value from Df125Config value
3833 nsamples_pedestal = 1; // The firmware returns an already divided pedestal
3834 pedestal = 0; // This will be replaced by the one from Df250PulsePedestal in GetObjects
3835 if (last_slot == slot && last_channel == channel) pulse_number = 1;
3836 last_slot = slot;
3837 last_channel = channel;
3838 if( (objs!=NULL__null) && (pulse_number<F125PULSE_NUMBER_FILTER) ) {
3839 objs->hit_objs.push_back(new Df125PulseIntegral(rocid, slot, channel, itrigger, pulse_number,
3840 quality_factor, sum, pedestal, nsamples_integral, nsamples_pedestal));
3841 }
3842 break;
3843 case 8: // Pulse Time
3844 if(VERBOSE>7) evioout << " FADC125 Pulse Time"<<endl;
3845 channel = (*iptr>>20) & 0x7F;
3846 pulse_number = (*iptr>>18) & 0x03;
3847 pulse_time = (*iptr>>0) & 0xFFFF;
3848 if( (objs!=NULL__null) && (pulse_number<F125PULSE_NUMBER_FILTER) ) {
3849 objs->hit_objs.push_back(new Df125PulseTime(rocid, slot, channel, itrigger, pulse_number, quality_factor, pulse_time));
3850 }
3851 last_pulse_time_channel = channel;
3852 break;
3853
3854 case 9: // FDC pulse data-peak (new) (GlueX-doc-2274-v8)
3855
3856 // Word 1:
3857 word1 = *iptr;
3858 channel = (*iptr>>20) & 0x7F;
3859 pulse_number = (*iptr>>15) & 0x1F;
3860 pulse_time = (*iptr>>4 ) & 0x7FF;
3861 quality_factor = (*iptr>>3 ) & 0x1; //time QF bit
3862 overflow_count = (*iptr>>0 ) & 0x7;
3863 if(VERBOSE>8) evioout << " FADC125 FDC Pulse Data(peak) word1: " << hex << (*iptr) << dec << endl;
3864 if(VERBOSE>7) evioout << " FADC125 FDC Pulse Data (chan="<<channel<<" pulse="<<pulse_number<<" time="<<pulse_time<<" QF="<<quality_factor<<" OC="<<overflow_count<<")"<<endl;
3865
3866 // Word 2:
3867 ++iptr;
3868 if(iptr>=iend){
3869 jerr << " Truncated f125 FDC hit (block ends before continuation word!)" << endl;
3870 continue;
3871 }
3872 if( ((*iptr>>31) & 0x1) != 0 ){
3873 jerr << " Truncated f125 FDC hit (missing continuation word!)" << endl;
3874 continue;
3875 }
3876 word2 = *iptr;
3877 pulse_peak = (*iptr>>19) & 0xFFF;
3878 sum = 0;
3879 peak_time = (*iptr>>11) & 0xFF;
3880 pedestal = (*iptr>>0 ) & 0x7FF;
3881 if(VERBOSE>8) evioout << " FADC125 FDC Pulse Data(peak) word2: " << hex << (*iptr) << dec << endl;
3882 if(VERBOSE>7) evioout << " FADC125 FDC Pulse Data (integral="<<sum<<" time="<<peak_time<<" pedestal="<<pedestal<<")"<<endl;
3883
3884 // Create hit objects
3885 nsamples_integral = 0; // must be overwritten later in GetObjects with value from Df125Config value
3886 nsamples_pedestal = 1; // The firmware pedestal divided by 2^PBIT where PBIT is a config. parameter
3887
3888 if( (objs!=NULL__null) && (pulse_number<F125PULSE_NUMBER_FILTER) ) {
3889 // n.b. This is were we might apply a check on whether we are
3890 // only producing emulated objects. If so, then we shouldn't
3891 // create the Df125FDCPulse. At this point in time though,
3892 // there are 3 config. parameters that control this because
3893 // the original firmware produced 3 separate data types as
3894 // opposed to the new firmware that puts the same infomation
3895 // into a single data type. The emulation framework is also
3896 // being revamped.
3897 objs->hit_objs.push_back( new Df125FDCPulse(rocid, slot, channel, itrigger
3898 , pulse_number // NPK
3899 , pulse_time // le_time
3900 , quality_factor // time_quality_bit
3901 , overflow_count // overflow_count
3902 , pedestal // pedestal
3903 , sum // integral
3904 , pulse_peak // peak_amp
3905 , peak_time // peak_time
3906 , word1 // word1
3907 , word2 // word2
3908 , nsamples_pedestal // nsamples_pedestal
3909 , nsamples_integral // nsamples_integral
3910 , false) // emulated
3911 );
3912 }
3913
3914 // n.b. We don't record last_slot, last_channel, etc... here since those
3915 // are only used by data types corresponding to older firmware that did
3916 // not write out data type 6.
3917 break;
3918
3919 case 10: // Pulse Pedestal (consistent with Beni's hand-edited version of Cody's document)
3920 if(VERBOSE>7) evioout << " FADC125 Pulse Pedestal"<<endl;
3921 //channel = (*iptr>>20) & 0x7F;
3922 channel = last_pulse_time_channel; // not enough bits to hold channel number so rely on proximity to Pulse Time in data stream (see "FADC125 dataformat 250 modes.docx")
3923 pulse_number = (*iptr>>21) & 0x03;
3924 pedestal = (*iptr>>12) & 0x1FF;
3925 pulse_peak = (*iptr>>0) & 0xFFF;
3926 nsamples_pedestal = 1; // The firmware returns an already divided pedestal
3927 if( (objs!=NULL__null) && (pulse_number<F125PULSE_NUMBER_FILTER) ) {
3928 objs->hit_objs.push_back(new Df125PulsePedestal(rocid, slot, channel, itrigger, pulse_number, pedestal, pulse_peak, nsamples_pedestal));
3929 }
3930 break;
3931
3932 case 13: // Event Trailer
3933 case 14: // Data not valid (empty module)
3934 case 15: // Filler (non-data) word
3935 if(VERBOSE>7) evioout << " FADC125 ignored data type: " << data_type <<endl;
3936 break;
3937 }
3938
3939 // Once we find a block trailer, assume that is it for this module.
3940 if(found_block_trailer){
3941 iptr++; // iptr is still pointing to block trailer. Jump to next word.
3942 break;
3943 }
3944 }
3945
3946 // Chop off filler words
3947 for(; iptr<iend; iptr++){
3948 if(((*iptr)&0xf8000000) != 0xf8000000) break;
3949 }
3950
3951 // Add last event in block to list
3952 if(objs)events.push_back(objs);
3953
3954 // Here, we make object associations to link PulseIntegral, PulseTime, PulseRawData, etc
3955 // objects to each other so it is easier to get to these downstream without having to
3956 // make nested loops. This is the most efficient place to do it since the ObjList objects
3957 // in "event" contain only the objects from this EVIO block (i.e. at most one crate's
3958 // worth.)
3959 list<ObjList*>::iterator iter = events.begin();
3960 for(; iter!=events.end(); iter++){
3961
3962 // Sort list of objects into type-specific lists
3963 vector<DDAQAddress*> &hit_objs = (*iter)->hit_objs;
3964 vector<Df125TriggerTime*> vtrigt;
3965 vector<Df125WindowRawData*> vwrd;
3966 vector<Df125PulseRawData*> vprd;
3967 vector<Df125PulseIntegral*> vpi;
3968 vector<Df125PulseTime*> vpt;
3969 vector<Df125PulsePedestal*> vpp;
3970 for(unsigned int i=0; i<hit_objs.size(); i++){
3971 AddIfAppropriate(hit_objs[i], vtrigt);
3972 AddIfAppropriate(hit_objs[i], vwrd);
3973 AddIfAppropriate(hit_objs[i], vprd);
3974 AddIfAppropriate(hit_objs[i], vpi);
3975 AddIfAppropriate(hit_objs[i], vpt);
3976 AddIfAppropriate(hit_objs[i], vpp);
3977 }
3978
3979 // Connect Df125PulseIntegral with Df125PulseTime
3980 LinkAssociationsWithPulseNumber(vprd, vpi);
3981 LinkAssociationsWithPulseNumber(vprd, vpt);
3982 LinkAssociationsWithPulseNumber(vprd, vpp);
3983 LinkAssociationsWithPulseNumber(vpi, vpt);
3984 LinkAssociationsWithPulseNumber(vpi, vpp);
3985 LinkAssociationsWithPulseNumber(vpt, vpp);
3986
3987 // Connect Df125TriggerTime to everything
3988 LinkAssociationsModuleOnly(vtrigt, vwrd);
3989 LinkAssociationsModuleOnly(vtrigt, vprd);
3990 LinkAssociationsModuleOnly(vtrigt, vpi);
3991 LinkAssociationsModuleOnly(vtrigt, vpt);
3992 LinkAssociationsModuleOnly(vtrigt, vpp);
3993 }
3994
3995 if(VERBOSE>6) evioout << " Leaving Parsef125Bank"<<endl;
3996}
3997
3998//----------------
3999// MakeDf125WindowRawData
4000//----------------
4001void JEventSource_EVIO::MakeDf125WindowRawData(ObjList *objs, uint32_t rocid, uint32_t slot, uint32_t itrigger, const uint32_t* &iptr)
4002{
4003 uint32_t channel = (*iptr>>20) & 0x7F;
4004 uint32_t window_width = (*iptr>>0) & 0x0FFF;
4005
4006 Df125WindowRawData *wrd = new Df125WindowRawData(rocid, slot, channel, itrigger);
4007
4008 for(uint32_t isample=0; isample<window_width; isample +=2){
4009
4010 // Advance to next word
4011 iptr++;
4012
4013 // Make sure this is a data continuation word, if not, stop here
4014 if(((*iptr>>31) & 0x1) != 0x0)break;
4015
4016 bool invalid_1 = (*iptr>>29) & 0x1;
4017 bool invalid_2 = (*iptr>>13) & 0x1;
4018 uint16_t sample_1 = 0;
4019 uint16_t sample_2 = 0;
4020 if(!invalid_1)sample_1 = (*iptr>>16) & 0x1FFF;
4021 if(!invalid_2)sample_2 = (*iptr>>0) & 0x1FFF;
4022
4023 // Sample 1
4024 wrd->samples.push_back(sample_1);
4025 wrd->invalid_samples |= invalid_1;
4026 wrd->overflow |= (sample_1>>12) & 0x1;
4027
4028 if((isample+2) == window_width && invalid_2)break; // skip last sample if flagged as invalid
4029
4030 // Sample 2
4031 wrd->samples.push_back(sample_2);
4032 wrd->invalid_samples |= invalid_2;
4033 wrd->overflow |= (sample_2>>12) & 0x1;
4034 }
4035
4036 if(VERBOSE>7) evioout << " FADC125 - " << wrd->samples.size() << " samples" << endl;
4037
4038 // Due to how the calling function works, the value of "objs" passed to us may be NULL.
4039 // This will happen if a Window Raw Data block is encountered before an event header.
4040 // For these cases, we still want to try parsing the data so that the iptr is updated
4041 // but don't have an event to assign it to. If "objs" is non-NULL, add this object to
4042 // the list. Otherwise, delete it now.
4043 if(objs){
4044 objs->hit_objs.push_back(wrd);
4045 }else{
4046 delete wrd;
4047 }
4048}
4049
4050//----------------
4051// MakeDf125PulseRawData
4052//----------------
4053void JEventSource_EVIO::MakeDf125PulseRawData(ObjList *objs, uint32_t rocid, uint32_t slot, uint32_t itrigger, const uint32_t* &iptr)
4054{
4055 uint32_t channel = (*iptr>>23) & 0x0F;
4056 uint32_t pulse_number = (*iptr>>21) & 0x000F;
4057 uint32_t first_sample_number = (*iptr>>0) & 0x03FF;
4058
4059 Df125PulseRawData *prd = new Df125PulseRawData(rocid, slot, channel, itrigger, pulse_number, first_sample_number);
4060
4061 // This loop needs to break when it hits a non-continuation word
4062 for(uint32_t isample=0; isample<1000; isample +=2){
4063
4064 // Advance to next word
4065 iptr++;
4066
4067 // Make sure this is a data continuation word, if not, stop here
4068 if(((*iptr>>31) & 0x1) != 0x0)break;
4069
4070 bool invalid_1 = (*iptr>>29) & 0x1;
4071 bool invalid_2 = (*iptr>>13) & 0x1;
4072 uint16_t sample_1 = 0;
4073 uint16_t sample_2 = 0;
4074 if(!invalid_1)sample_1 = (*iptr>>16) & 0x1FFF;
4075 if(!invalid_2)sample_2 = (*iptr>>0) & 0x1FFF;
4076
4077 // Sample 1
4078 prd->samples.push_back(sample_1);
4079 prd->invalid_samples |= invalid_1;
4080 prd->overflow |= (sample_1>>12) & 0x1;
4081
4082 bool last_word = (iptr[1]>>31) & 0x1;
4083 if(last_word && invalid_2)break; // skip last sample if flagged as invalid
4084
4085 // Sample 2
4086 prd->samples.push_back(sample_2);
4087 prd->invalid_samples |= invalid_2;
4088 prd->overflow |= (sample_2>>12) & 0x1;
4089 }
4090
4091
4092 // Due to how the calling function works, the value of "objs" passed to us may be NULL.
4093 // This will happen if a Window Raw Data block is encountered before an event header.
4094 // For these cases, we still want to try parsing the data so that the iptr is updated
4095 // but don't have an event to assign it to. If "objs" is non-NULL, add this object to
4096 // the list. Otherwise, delete it now.
4097 if(objs){
4098 objs->hit_objs.push_back(prd);
4099 }else{
4100 delete prd;
4101 }
4102}
4103
4104//----------------
4105// ParseF1TDCBank
4106//----------------
4107void JEventSource_EVIO::ParseF1TDCBank(int32_t rocid, const uint32_t* &iptr, const uint32_t* iend, list<ObjList*> &events)
4108{
4109 /// Parse data from a single F1TDCv2 (32 ch) or F1TDCv3 (48 ch) module.
4110 /// This code is based on the document F1TDC_V2_V3_4_29_14.pdf obtained from:
4111 /// https://coda.jlab.org/wiki/index.php/JLab_Module_Manuals
4112
4113 if(!PARSE_F1TDC){ iptr = iend; return; }
4114
4115 if(VERBOSE>6) evioout << " Entering ParseF1TDCBank (rocid=" << rocid << ")" << endl;
4116
4117 const uint32_t *istart = iptr;
4118
4119 // Some early data had a marker word at just before the actual F1 data
4120 if(*iptr == 0xf1daffff) iptr++;
4121
4122 // Block header word
4123 // Double check that block header is set
4124 if( ((*iptr) & 0xF8000000) != 0x80000000 ){
4125 throw JException("F1TDC Block header corrupt! (high 5 bits not set to 0x80000000!)");
4126 }
4127
4128 uint32_t slot_block_header = (*iptr)>>22 & 0x001F;
4129 uint32_t block_num = (*iptr)>> 8 & 0x03FF;
4130 uint32_t Nevents_block_header = (*iptr)>> 0 & 0x00FF;
4131 int modtype = (*iptr)>>18 & 0x000F; // should match a DModuleType::type_id_t
4132 if(VERBOSE>5) evioout << " F1 Block Header: slot=" << slot_block_header << " block_num=" << block_num << " Nevents=" << Nevents_block_header << endl;
4133
4134 // Advance to next word
4135 iptr++;
4136
4137 // Loop over events
4138 ObjList *objs = NULL__null;
4139 while(iptr<iend){
4140
4141 // Event header
4142 // Double check that event header is set
4143 if( ((*iptr) & 0xF8000000) != 0x90000000 ){
4144 if(VERBOSE>10){
4145 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4145<<" "
<<"Corrupt F1TDC Event header! Data dump follows (\"*\" indicates bad header word):" <<endl;
4146 DumpBinary(istart, iend, 0, iptr);
4147 }
4148 throw JException("F1TDC Event header corrupt! (high 5 bits not set to 0x90000000!)");
4149 }
4150
4151 uint32_t slot_event_header = (*iptr)>>22 & 0x00000001F;
4152 uint32_t itrigger = (*iptr)>>0 & 0x0003FFFFF;
4153 if(VERBOSE>5) evioout << " F1 Event Header: slot=" << slot_block_header << " itrigger=" << itrigger << endl;
4154
4155 // Make sure slot number from event header matches block header
4156 if(slot_event_header != slot_block_header){
4157 char str[256];
4158 sprintf(str, "F1TDC slot from event header(%d) doesn't match block header(%d)", slot_event_header, slot_block_header);
4159 throw JException(str);
4160 }
4161
4162 // Advance to timestamp word
4163 iptr++;
4164 if(iptr>=iend) throw JException("F1TDC data corrupt! Block truncated before timestamp word!");
4165
4166 // The most recent documentation says that the first time stamp
4167 // word holds the low 24 bits and the second the high 16 bits. According to Dave A.,
4168 // the second word is optional.
4169 uint32_t trig_time = ((*iptr)&0xFFFFFF);
4170 if(VERBOSE>6) evioout << " F1 Trigger time: low 24 bits=" << trig_time << endl;
4171 iptr++;
4172 if(iptr>=iend) throw JException("F1TDC data corrupt! Block truncated before trailer word!");
4173 if(((*iptr>>31) & 0x1) == 0){
4174 trig_time += ((*iptr)&0xFFFF)<<24; // from word on the street: second trigger time word is optional!!??
4175 if(VERBOSE>6) evioout << " F1 Trigger time: high 16 bits=" << ((*iptr)&0xFFFF) << " total trig_time=" << trig_time << endl;
4176 }else{
4177 iptr--; // second time word not present, back up pointer
4178 }
4179
4180 // Create a new object list (i.e. new event)
4181 if(objs!=NULL__null && ENABLE_DISENTANGLING){
4182 events.push_back(objs);
4183 objs = NULL__null;
4184 }
4185 if(!objs) objs = new ObjList;
4186
4187 if(objs) objs->hit_objs.push_back(new DF1TDCTriggerTime(rocid, slot_block_header, itrigger, trig_time));
4188
4189 // Advance past last timestamp word to first data word (or rather, F1 chip header)
4190 iptr++;
4191
4192 // Loop over F1 data words
4193 uint32_t chip_f1header=0, chan_on_chip_f1header=0, itrigger_f1header=0, trig_time_f1header=0;
4194 while( iptr<iend && ((*iptr)>>31)==0x1 ){
4195
4196 bool done = false;
4197
4198 uint32_t chip, chan_on_chip, time;
4199 uint32_t channel;
4200 DF1TDCHit *hit=NULL__null;
4201 switch( (*iptr) & 0xF8000000 ){
4202 case 0xC0000000: // F1 Header
4203 chip_f1header = ((*iptr)>> 3) & 0x07;
4204 chan_on_chip_f1header = ((*iptr)>> 0) & 0x07; // this is always 7 in real data!
4205 itrigger_f1header = ((*iptr)>>16) & 0x3F;
4206 trig_time_f1header = ((*iptr)>> 7) & 0x1FF;
4207 if(VERBOSE>5) evioout << " Found F1 header: chip=" << chip_f1header << " chan=" << chan_on_chip_f1header << " itrig=" << itrigger_f1header << " trig_time=" << trig_time_f1header << endl;
4208 //if( itrigger_f1header != (itrigger & 0x3F)) throw JException("Trigger number in F1 header word does not match Event header word!");
4209 break;
4210 case 0xB8000000: // F1 Data
4211 chip = (*iptr>>19) & 0x07;
4212 chan_on_chip = (*iptr>>16) & 0x07;
4213 time = (*iptr>> 0) & 0xFFFF;
4214 if(VERBOSE>5) evioout << " Found F1 data : chip=" << chip << " chan=" << chan_on_chip << " time=" << time << " (header: chip=" << chip_f1header << ")" << endl;
4215 //if(chip!=chip_f1header) throw JException("F1 chip number in data does not match header!");
4216 channel = F1TDC_channel(chip, chan_on_chip, modtype);
4217 hit = new DF1TDCHit(rocid, slot_block_header, channel, itrigger, trig_time_f1header, time, *iptr, MODULE_TYPE(modtype));
4218 if(objs)objs->hit_objs.push_back(hit);
4219 break;
4220 case 0xF8000000: // Filler word
4221 if(VERBOSE>7) evioout << " Found F1 filler word" << endl;
4222 break;
4223 case 0x80000000: // JLab block header (handled in outer loop)
4224 case 0x88000000: // JLab block trailer (handled in outer loop)
4225 case 0x90000000: // JLab event header (handled in outer loop)
4226 case 0x98000000: // Trigger time (handled in outer loop)
4227 case 0xF0000000: // module has no valid data available for read out (how to handle this?)
4228 if(VERBOSE>5) evioout << " Found F1 break word: 0x" << hex << *iptr << dec << endl;
4229 done = true;
4230 break;
4231 default:
4232 cerr<<endl;
4233 cout.flush(); cerr.flush();
4234 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4234<<" "
<<"Unknown data word in F1TDC block. Dumping for debugging:" << endl;
4235 for(const uint32_t *iiptr = istart; iiptr<iend; iiptr++){
4236 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4236<<" "
<<"0x"<<hex<<*iiptr<<dec;
4237 if(iiptr == iptr)cerr<<" <----";
4238 switch( (*iiptr) & 0xF8000000 ){
4239 case 0x80000000: cerr << " F1 Block Header"; break;
4240 case 0x90000000: cerr << " F1 Event Header"; break;
4241 case 0x98000000: cerr << " F1 Trigger time"; break;
4242 case 0xC0000000: cerr << " F1 Header"; break;
4243 case 0xB8000000: cerr << " F1 Data"; break;
4244 case 0x88000000: cerr << " F1 Block Trailer"; break;
4245 case 0xF8000000: cerr << " Filler word"; break;
4246 case 0xF0000000: cerr << " <module has no valid data>"; break;
4247 default: break;
4248 }
4249 cerr<<endl;
4250 if(iiptr > (iptr+4)) break;
4251 }
4252
4253 throw JException("Unexpected word type in F1TDC block!");
4254 }
4255
4256 if(done)break;
4257
4258 // Advance to next data word
4259 iptr++;
4260
4261 } // end loop over data words in this event
4262
4263 // If the current word is a JLab block trailer, then we are done
4264 if( ((*iptr) & 0xF8000000) == 0x88000000) break;
4265
4266 } // end loop over events
4267
4268 // Add hits for last event to list of events.
4269 if(objs)events.push_back(objs);
4270
4271 if( ((*iptr) & 0xF8000000) != 0x88000000 ){
4272 throw JException("F1TDC Block Trailer corrupt! (high 5 bits not set to 0x88000000!)");
4273 }
4274
4275 // Advance past JLab block trailer
4276 iptr++;
4277
4278 // Skip filler words
4279 while(iptr<iend && (*iptr&0xF8000000)==0xF8000000)iptr++;
4280
4281 // Double check that we found all of the events we were supposed to
4282 if(!ENABLE_DISENTANGLING) Nevents_block_header=1;
4283 if(events.size() != Nevents_block_header){
4284 stringstream ss;
4285 ss << "F1TDC missing events in block! (found "<< events.size() <<" but should have found "<<Nevents_block_header<<")";
4286 DumpBinary(istart, iend, 128);
4287 throw JException(ss.str());
4288 }
4289
4290 if(VERBOSE>6) evioout << " Leaving ParseF1TDCBank (rocid=" << rocid << ")" << endl;
4291
4292}
4293
4294//----------------
4295// F1TDC_channel
4296//----------------
4297uint32_t JEventSource_EVIO::F1TDC_channel(uint32_t chip, uint32_t chan_on_chip, int modtype)
4298{
4299 /// Convert a F1TDC chip number and channel on the chip to the
4300 /// front panel channel number. This is based on "Input Channel Mapping"
4301 /// section at the very bottom of the document F1TDC_V2_V3_4_29_14.pdf
4302
4303 uint32_t channel_map[8] = {0, 0, 1, 1, 2, 2, 3, 3};
4304 switch(modtype){
4305 case DModuleType::F1TDC32:
4306 return (4 * chip) + channel_map[ chan_on_chip&0x7 ];
4307 case DModuleType::F1TDC48:
4308 return (chip <<3) | chan_on_chip;
4309 default:
4310 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4310<<" "
<< "Calling F1TDC_channel for module type: " << DModuleType::GetName((DModuleType::type_id_t)modtype) << endl;
4311 throw JException("F1TDC_channel called for non-F1TDC module type");
4312 }
4313 return 1000000; // (should never get here)
4314}
4315
4316//----------------
4317// ParseTSBank
4318//----------------
4319void JEventSource_EVIO::ParseTSBank(int32_t rocid, const uint32_t* &iptr, const uint32_t* iend, list<ObjList*> &events)
4320{
4321 /// Parse data written to the TS roc data during sync events.
4322 /// This is written by the ts_scalers routine in the conf_utils.c
4323 /// file and called from ts_list.c
4324
4325 uint32_t Nwords = ((uint64_t)iend - (uint64_t)iptr)/sizeof(uint32_t);
4326 uint32_t Nwords_expected = (6+32+16+32+16);
4327 if(Nwords != Nwords_expected){
4328 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4328<<" "
<< "TS bank size does not match expected!!" << endl;
4329 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4329<<" "
<< "Found " << Nwords << " words. Expected " << Nwords_expected << endl;
4330
4331 }else{
4332 DTSscalers *s = new DTSscalers;
4333 s->nsync_event = *iptr++;
4334 s->int_count = *iptr++;
4335 s->live_time = *iptr++;
4336 s->busy_time = *iptr++;
4337 s->inst_livetime = *iptr++;
4338 s->time = *iptr++;
4339 for(uint32_t i=0; i<32; i++) s->gtp_scalers[i] = *iptr++;
4340 for(uint32_t i=0; i<16; i++) s->fp_scalers[i] = *iptr++;
4341 for(uint32_t i=0; i<32; i++) s->gtp_rate[i] = *iptr++;
4342 for(uint32_t i=0; i<16; i++) s->fp_rate[i] = *iptr++;
4343
4344 if(events.empty()) events.push_back(new ObjList);
4345 ObjList *objs = *(events.begin());
4346 objs->misc_objs.push_back(s);
4347 }
4348
4349 iptr = iend;
4350}
4351
4352//----------------
4353// ParseTIBank
4354//----------------
4355void JEventSource_EVIO::ParseTIBank(int32_t rocid, const uint32_t* &iptr, const uint32_t* iend, list<ObjList*> &events)
4356{
4357 while(iptr<iend && ((*iptr) & 0xF8000000) != 0x88000000) iptr++; // Skip to JLab block trailer
4358 iptr++; // advance past JLab block trailer
4359 while(iptr<iend && *iptr == 0xF8000000) iptr++; // skip filler words after block trailer
4360 //iptr = iend;
4361}
4362
4363//----------------
4364// ParseCAEN1190
4365//----------------
4366void JEventSource_EVIO::ParseCAEN1190(int32_t rocid, const uint32_t* &iptr, const uint32_t *iend, list<ObjList*> &events)
4367{
4368 /// Parse data from a CAEN 1190 or 1290 module
4369 /// (See ppg. 72-74 of V1290_REV15.pdf manual)
4370
4371 if(!PARSE_CAEN1290TDC){ iptr = iend; return; }
4372
4373 uint32_t slot = 0;
4374 uint32_t event_count = 0;
4375 uint32_t word_count = 0;
4376 uint32_t trigger_time_tag = 0;
4377 uint32_t tdc_num = 0;
4378 uint32_t event_id = 0;
4379 uint32_t bunch_id = 0;
4380
4381 // We need to accomodate multi-event blocks where
4382 // events are entangled (i.e. hits from event 1
4383 // are mixed inbetween those of event 2,3,4,
4384 // etc... With CAEN modules, we only know which
4385 // event a hit came from by looking at the event_id
4386 // in the TDC header. This value is only 12 bits
4387 // and could roll over within an event block. This
4388 // means we need to keep track of the order we
4389 // encounter them in so it is maintained in the
4390 // "events" container. The event_id order is kept
4391 // in the "event_id_order" vector.
4392 map<uint32_t, vector<DCAEN1290TDCHit*> > hits_by_event_id;
4393 vector<uint32_t> event_id_order;
4394
4395 while(iptr<iend){
4396
4397 // This word appears to be appended to the data.
4398 // Probably in the ROL. Ignore it if found.
4399 if(*iptr == 0xd00dd00d) {
4400 if(VERBOSE>7) evioout << " CAEN skipping 0xd00dd00d word" << endl;
4401 iptr++;
4402 continue;
4403 }
4404
4405 uint32_t type = (*iptr) >> 27;
4406 uint32_t edge = 0; // 1=trailing, 0=leading
4407 uint32_t channel = 0;
4408 uint32_t tdc = 0;
4409 uint32_t error_flags = 0;
4410 DCAEN1290TDCHit *caen1290tdchit = NULL__null;
4411 map<uint32_t, ObjList*>::iterator iter;
4412 switch(type){
4413 case 0b01000: // Global Header
4414 slot = (*iptr) & 0x1f;
4415 event_count = ((*iptr)>>5) & 0xffffff;
4416 if(VERBOSE>7) evioout << " CAEN TDC Global Header (slot=" << slot << " , event count=" << event_count << ")" << endl;
4417 break;
4418 case 0b10000: // Global Trailer
4419 slot = (*iptr) & 0x1f;
4420 word_count = ((*iptr)>>5) & 0x7ffff;
4421 if(VERBOSE>7) evioout << " CAEN TDC Global Trailer (slot=" << slot << " , word count=" << word_count << ")" << endl;
4422 slot = event_count = word_count = trigger_time_tag = tdc_num = event_id = bunch_id = 0;
4423 break;
4424 case 0b10001: // Global Trigger Time Tag
4425 trigger_time_tag = ((*iptr)>>5) & 0x7ffffff;
4426 if(VERBOSE>7) evioout << " CAEN TDC Global Trigger Time Tag (tag=" << trigger_time_tag << ")" << endl;
4427 break;
4428 case 0b00001: // TDC Header
4429 tdc_num = ((*iptr)>>24) & 0x03;
4430 event_id = ((*iptr)>>12) & 0x0fff;
4431 bunch_id = (*iptr) & 0x0fff;
4432 if( find(event_id_order.begin(), event_id_order.end(), event_id) == event_id_order.end()){
4433 event_id_order.push_back(event_id);
4434 }
4435 if(VERBOSE>7) evioout << " CAEN TDC TDC Header (tdc=" << tdc_num <<" , event id=" << event_id <<" , bunch id=" << bunch_id << ")" << endl;
4436 break;
4437 case 0b00000: // TDC Measurement
4438 edge = ((*iptr)>>26) & 0x01;
4439 channel = ((*iptr)>>21) & 0x1f;
4440 tdc = ((*iptr)>>0) & 0x1fffff;
4441 if(VERBOSE>7) evioout << " CAEN TDC TDC Measurement (" << (edge ? "trailing":"leading") << " , channel=" << channel << " , tdc=" << tdc << ")" << endl;
4442
4443 // Create DCAEN1290TDCHit object
4444 caen1290tdchit = new DCAEN1290TDCHit(rocid, slot, channel, 0, edge, tdc_num, event_id, bunch_id, tdc);
4445 hits_by_event_id[event_id].push_back(caen1290tdchit);
4446 break;
4447 case 0b00100: // TDC Error
4448 error_flags = (*iptr) & 0x7fff;
4449 if(VERBOSE>7) evioout << " CAEN TDC TDC Error (err flags=0x" << hex << error_flags << dec << ")" << endl;
4450 break;
4451 case 0b00011: // TDC Trailer
4452 tdc_num = ((*iptr)>>24) & 0x03;
4453 event_id = ((*iptr)>>12) & 0x0fff;
4454 word_count = ((*iptr)>>0) & 0x0fff;
4455 if(VERBOSE>7) evioout << " CAEN TDC TDC Trailer (tdc=" << tdc_num <<" , event id=" << event_id <<" , word count=" << word_count << ")" << endl;
4456 tdc_num = event_id = bunch_id = 0;
4457 break;
4458 case 0b11000: // Filler Word
4459 if(VERBOSE>7) evioout << " CAEN TDC Filler Word" << endl;
4460 break;
4461 default:
4462 evioout << "Unknown datatype: 0x" << hex << type << " full word: "<< *iptr << dec << endl;
4463 }
4464
4465 iptr++;
4466 }
4467
4468 // If disentagling is disabled, then lump all hits into single event
4469 if( (!ENABLE_DISENTANGLING) && (event_id_order.size()>1) ){
4470 if(VERBOSE>2) evioout << " Disentangling disabled. Merging all hits into single event" << endl;
4471 vector<DCAEN1290TDCHit*> &hits1 = hits_by_event_id[event_id_order[0]];
4472 for(uint32_t i=1; i<event_id_order.size(); i++){
4473 vector<DCAEN1290TDCHit*> &hits2 = hits_by_event_id[event_id_order[i]];
4474 hits1.insert(hits1.end(), hits2.begin(), hits2.end()); // copy hits into first event
4475 hits_by_event_id.erase(event_id_order[i]); // remove hits list for this event_id
4476 }
4477 }
4478
4479 // Add hits for each event to the events container, creating ObjList's as needed
4480 for(uint32_t i=0; i<event_id_order.size(); i++){
4481
4482 // Make sure there are enough event containers to hold this event
4483 while(events.size() <= i) events.push_back(new ObjList);
4484 list<ObjList*>::iterator it = events.begin();
4485 advance(it, i);
4486 ObjList *objs = *it;
4487
4488 vector<DCAEN1290TDCHit*> &hits = hits_by_event_id[event_id_order[i]];
4489 objs->hit_objs.insert(objs->hit_objs.end(), hits.begin(), hits.end());
4490
4491 if(VERBOSE>7) evioout << " Added " << hits.size() << " hits with event_id=" << event_id_order[i] << " to event " << i << endl;
4492 }
4493
4494}
4495
4496//----------------
4497// ParseBORevent
4498//----------------
4499void JEventSource_EVIO::ParseBORevent(evioDOMNodeP bankPtr)
4500{
4501 if(!PARSE_BOR) return;
1
Taking false branch
4502
4503 // This really shouldn't be needed
4504 pthread_rwlock_wrlock(&BOR_lock);
4505
4506 // Delete any existing BOR config objects. BOR events should
4507 // be flagged as sequential (or barrier) events so all threads
4508 // that were using these should be done with them now.
4509 for(uint32_t i=0; i<BORobjs.size(); i++) delete BORobjs[i];
2
Loop condition is false. Execution continues on line 4510
4510 BORobjs.clear();
4511
4512 evioDOMNodeListP bankList = bankPtr->getChildren();
4513 evioDOMNodeList::iterator iter = bankList->begin();
4514 if(VERBOSE>7) evioout << " Looping over " << bankList->size() << " banks in BOR event" << endl;
3
Taking false branch
4515 for(int ibank=1; iter!=bankList->end(); iter++, ibank++){ // ibank only used for debugging messages
4
Loop condition is true. Entering loop body
6
Loop condition is true. Entering loop body
8
Loop condition is true. Entering loop body
10
Loop condition is true. Entering loop body
4516 evioDOMNodeP childBank = *iter;
4517
4518 if(childBank->tag==0x71){
5
Taking false branch
7
Taking false branch
9
Taking false branch
11
Taking true branch
4519 // uint32_t rocid = childBank->num;
4520 evioDOMNodeListP bankList = childBank->getChildren();
4521 evioDOMNodeList::iterator iter = bankList->begin();
4522 for(; iter!=bankList->end(); iter++){
12
Loop condition is true. Entering loop body
16
Loop condition is true. Entering loop body
20
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
4523 evioDOMNodeP dataBank = *iter;
4524 // uint32_t slot = dataBank->tag>>5;
4525 uint32_t modType = dataBank->tag&0x1f;
4526
4527 const vector<uint32_t> *vec = dataBank->getVector<uint32_t>();
4528
4529 const uint32_t *src = &(*vec)[0];
4530 uint32_t *dest = NULL__null;
4531 uint32_t sizeof_dest = 0;
4532
4533 Df250BORConfig *f250conf = NULL__null;
4534 Df125BORConfig *f125conf = NULL__null;
4535 DF1TDCBORConfig *F1TDCconf = NULL__null;
4536 DCAEN1290TDCBORConfig *caen1190conf = NULL__null;
4537
4538 switch(modType){
13
'Default' branch taken. Execution continues on line 4569
17
'Default' branch taken. Execution continues on line 4569
21
'Default' branch taken. Execution continues on line 4569
25
'Default' branch taken. Execution continues on line 4569
4539 case DModuleType::FADC250: // f250
4540 f250conf = new Df250BORConfig;
4541 dest = (uint32_t*)&f250conf->rocid;
4542 sizeof_dest = sizeof(f250config);
4543 break;
4544 case DModuleType::FADC125: // f125
4545 f125conf = new Df125BORConfig;
4546 dest = (uint32_t*)&f125conf->rocid;
4547 sizeof_dest = sizeof(f125config);
4548 break;
4549
4550 case DModuleType::F1TDC32: // F1TDCv2
4551 case DModuleType::F1TDC48: // F1TDCv3
4552 F1TDCconf = new DF1TDCBORConfig;
4553 dest = (uint32_t*)&F1TDCconf->rocid;
4554 sizeof_dest = sizeof(F1TDCconfig);
4555 break;
4556
4557 case DModuleType::CAEN1190: // CAEN 1190 TDC
4558 case DModuleType::CAEN1290: // CAEN 1290 TDC
4559 caen1190conf = new DCAEN1290TDCBORConfig;
4560 dest = (uint32_t*)&caen1190conf->rocid;
4561 sizeof_dest = sizeof(caen1190config);
4562 break;
4563 }
4564
4565 // Check that the bank size and data structure size match.
4566 // If they do, then copy the data and add the object to
4567 // the event. If not, then delete the object and print
4568 // a warning message.
4569 if( vec->size() == (sizeof_dest/sizeof(uint32_t)) ){
14
Taking false branch
18
Taking false branch
22
Taking false branch
26
Taking true branch
4570
4571 // Copy bank data, assuming format is the same
4572 for(uint32_t i=0; i<vec->size(); i++) *dest++ = *src++;
27
Loop condition is true. Entering loop body
28
Dereference of null pointer
4573
4574 // Store object for use in this and subsequent events
4575 if(f250conf) BORobjs.push_back(f250conf);
4576 if(f125conf) BORobjs.push_back(f125conf);
4577 if(F1TDCconf) BORobjs.push_back(F1TDCconf);
4578 if(caen1190conf) BORobjs.push_back(caen1190conf);
4579
4580 }else if(sizeof_dest>0){
15
Taking false branch
19
Taking false branch
23
Taking false branch
4581 if(f250conf) delete f250conf;
4582 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4582<<" "
<< "BOR bank size does not match structure! " << vec->size() <<" != " << (sizeof_dest/sizeof(uint32_t)) << endl;
4583 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4583<<" "
<< "sizeof(f250config)="<<sizeof(f250config)<<endl;
4584 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4584<<" "
<< "sizeof(f125config)="<<sizeof(f125config)<<endl;
4585 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4585<<" "
<< "sizeof(F1TDCconfig)="<<sizeof(F1TDCconfig)<<endl;
4586 _DBG_std::cerr<<"libraries/DAQ/JEventSource_EVIO.cc"<<
":"<<4586<<" "
<< "sizeof(caen1190config)="<<sizeof(caen1190config)<<endl;
4587 }
4588 }
4589 }
4590 }
4591
4592 pthread_rwlock_unlock(&BOR_lock);
4593
4594}
4595
4596
4597//----------------
4598// ParseTSSyncevent
4599//----------------
4600void JEventSource_EVIO::ParseTSSync(evioDOMNodeP bankPtr, list<ObjList*> &events)
4601{
4602
4603 DL1Info *trig_info = new DL1Info;
4604
4605 // cout << " INSIDE ParseTSSync " << endl;
4606
4607 if((bankPtr->tag & 0xFFFF) == 0xEE02){
4608 const vector<uint32_t> *vec = bankPtr->getVector<uint32_t>();
4609
4610 trig_info->nsync = (*vec)[0];
4611 trig_info->trig_number = (*vec)[1];
4612 trig_info->live_time = (*vec)[2];
4613 trig_info->busy_time = (*vec)[3];
4614 trig_info->live_inst = (*vec)[4];
4615 trig_info->unix_time = (*vec)[5];
4616
4617
4618
4619 // GTP scalers
4620 for(uint32_t ii = 6; ii < 38; ii++){
4621 trig_info->gtp_sc.push_back((*vec)[ii]);
4622 }
4623
4624 // FP scalers
4625 for(uint32_t ii = 38; ii < 54; ii++){
4626 trig_info->fp_sc.push_back((*vec)[ii]);
4627 }
4628
4629 // GTP rate
4630 for(uint32_t ii = 54; ii < 86; ii++){
4631 trig_info->gtp_rate.push_back((*vec)[ii]);
4632 }
4633
4634 // FP rate
4635 for(uint32_t ii = 86; ii < 102; ii++){
4636 trig_info->fp_rate.push_back((*vec)[ii]);
4637 }
4638 }
4639
4640
4641 if(events.empty()){
4642 events.push_back(new ObjList());
4643 // cout << " TSSync: Empty event " << endl;
4644 }
4645
4646 ObjList *objs = *(events.begin());
4647
4648 objs->misc_objs.push_back(trig_info);
4649
4650
4651}
4652
4653
4654//----------------
4655// ParseEPICSevent
4656//----------------
4657void JEventSource_EVIO::ParseEPICSevent(evioDOMNodeP bankPtr, list<ObjList*> &events)
4658{
4659 if(!PARSE_EPICS) return;
4660
4661 time_t timestamp=0;
4662
4663 ObjList *objs = NULL__null;
4664
4665 evioDOMNodeListP bankList = bankPtr->getChildren();
4666 evioDOMNodeList::iterator iter = bankList->begin();
4667 if(VERBOSE>7) evioout << " Looping over " << bankList->size() << " banks in EPICS event" << endl;
4668 for(int ibank=1; iter!=bankList->end(); iter++, ibank++){ // ibank only used for debugging messages
4669 evioDOMNodeP childBank = *iter;
4670
4671 if(childBank->tag == 97){
4672 // timestamp bank
4673 const vector<uint32_t> *vec = childBank->getVector<uint32_t>();
4674 if(vec) {
4675 timestamp = (time_t)(*vec)[0];
4676 if(VERBOSE>7) evioout << " timestamp: " << ctime(&timestamp);
4677 }
4678 }else if(childBank->tag==98){
4679 const vector<uint8_t> *vec = childBank->getVector<uint8_t>();
4680 if(vec){
4681 string nameval = (const char*)&((*vec)[0]);
4682 DEPICSvalue *epicsval = new DEPICSvalue(timestamp, nameval);
4683 if(VERBOSE>7) evioout << " " << nameval << endl;
4684
4685 if(!objs){
4686 if(events.empty()) events.push_back(new ObjList);
4687 objs = *(events.begin());
4688 }
4689 objs->misc_objs.push_back(epicsval);
4690 }
4691 }
4692 }
4693}
4694
4695//----------------
4696// DumpBinary
4697//----------------
4698void JEventSource_EVIO::DumpBinary(const uint32_t *iptr, const uint32_t *iend, uint32_t MaxWords, const uint32_t *imark)
4699{
4700 /// This is used for debugging. It will print to the screen the words
4701 /// starting at the address given by iptr and ending just before iend
4702 /// or for MaxWords words, whichever comes first. If iend is NULL,
4703 /// then MaxWords will be printed. If MaxWords is zero then it is ignored
4704 /// and only iend is checked. If both iend==NULL and MaxWords==0, then
4705 /// only the word at iptr is printed.
4706
4707 cout << "Dumping binary: istart=" << hex << iptr << " iend=" << iend << " MaxWords=" << dec << MaxWords << endl;
4708
4709 if(iend==NULL__null && MaxWords==0) MaxWords=1;
4710 if(MaxWords==0) MaxWords = (uint32_t)0xffffffff;
4711
4712 uint32_t Nwords=0;
4713 while(iptr!=iend && Nwords<MaxWords){
4714
4715 // line1 is hex and line2 is decimal
4716 stringstream line1, line2;
4717
4718 // print words in columns 8 words wide. First part is
4719 // reserved for word number
4720 uint32_t Ncols = 8;
4721 line1 << setw(5) << Nwords;
4722 line2 << string(5, ' ');
4723
4724 // Loop over columns
4725 for(uint32_t i=0; i<Ncols; i++, iptr++, Nwords++){
4726
4727 if(iptr == iend) break;
4728 if(Nwords>=MaxWords) break;
4729
4730 stringstream iptr_hex;
4731 iptr_hex << hex << "0x" << *iptr;
4732
4733 string mark = (iptr==imark ? "*":" ");
4734
4735 line1 << setw(12) << iptr_hex.str() << mark;
4736 line2 << setw(12) << *iptr << mark;
4737 }
4738
4739 cout << line1.str() << endl;
4740 cout << line2.str() << endl;
4741 cout << endl;
4742 }
4743}
4744
4745#endif // HAVE_EVIO
4746
4747#if 0
4748//----------------
4749// GuessModuleType
4750//----------------
4751MODULE_TYPE JEventSource_EVIO::GuessModuleType(const uint32_t* istart, const uint32_t* iend, evioDOMNodeP bankPtr)
4752{
4753 /// Try parsing through the information in the given data buffer
4754 /// to determine which type of module produced the data.
4755
4756 if(IsFADC250(istart, iend)) return DModuleType::FADC250;
4757 if(IsF125ADC(istart, iend)) return DModuleType::F125ADC;
4758 if(IsF1TDC(istart, iend)) return DModuleType::F1TDC;
4759 if(IsTS(istart, iend)) return DModuleType::JLAB_TS;
4760 if(IsTI(istart, iend)) return DModuleType::JLAB_TID;
4761
4762
4763 // Couldn't figure it out...
4764 return DModuleType::UNKNOWN;
4765}
4766
4767//----------------
4768// IsFADC250
4769//----------------
4770bool JEventSource_EVIO::IsFADC250(const uint32_t *istart, const uint32_t *iend)
4771{
4772 //---- Check for f250
4773 // This will check if the first word appears to be a block header.
4774 // If so, it loops over all words looking for a block trailer.
4775 // If the slot number in the block trailer matches that in the
4776 // block header AND the number of words in the block matches that
4777 // specified in the block trailer, then it is assumed to be a f250.
4778 if(((*istart>>31) & 0x1) == 1){
4779 uint32_t data_type = (*istart>>27) & 0x0F;
4780 if(data_type == 0){ // Block Header
4781 uint32_t slot_header = (*istart>>22) & 0x1F;
4782 uint32_t Nwords = 1;
4783 for(const uint32_t *iptr=istart; iptr<iend; iptr++, Nwords++){
4784 if(((*iptr>>31) & 0x1) == 1){
4785 uint32_t data_type = (*iptr>>27) & 0x0F;
4786 if(data_type == 1){ // Block Trailer
4787 uint32_t slot_trailer = (*iptr>>22) & 0x1F;
4788 uint32_t Nwords_trailer = (*iptr>>0) & 0x3FFFFF;
4789
4790 if( slot_header == slot_trailer && Nwords == Nwords_trailer ){
4791 return true;
4792 }else{
4793 return false;
4794 }
4795 }
4796 }
4797 }
4798 }
4799 }
4800
4801 // either first word was not a block header or no block trailer was found
4802 return false;
4803}
4804
4805//----------------
4806// IsF1TDC
4807//----------------
4808bool JEventSource_EVIO::IsF1TDC(const uint32_t *istart, const uint32_t *iend)
4809{
4810 //---- Check for F1TDC
4811 // This will check for consistency in the slot numbers for all words
4812 // in the buffer. The slot number of data words are checked against
4813 // the slot number of the most recently encountered header word.
4814 uint32_t slot_header = 1000;
4815 uint32_t slot_trailer = 1000;
4816
4817 const uint32_t *iptr=istart;
4818
4819 // skip first word which appears to be ROL marker for F1TDC data
4820 if(*istart == 0xf1daffff)iptr++
4821
4822 // There is no distinction between header and trailer
4823 // words other than the order that they appear. We keep
4824 // track by flipping this value
4825 bool looking_for_header = true;
4826
4827 // Keep track of the number of valid blocks of F1TDC data we find
4828 // (i.e. ones where the header and trailer words were found
4829 int Nvalid = 0;
4830
4831 for(; iptr<iend; iptr++){
4832
4833 // ROL end of data marker (only in test setup data)
4834 if(*iptr == 0xda0000ff)break;
4835
4836 uint32_t slot = (*iptr>>27) & 0x1F;
4837
4838 // if slot is 0 or 30, we are supposed to ignore the data.
4839 if(slot == 30 || slot ==0)continue;
4840
4841 if(((*iptr>>23) & 0x1) == 0){
4842 // header/trailer word
4843 if(looking_for_header){
4844 slot_header = slot;
4845 looking_for_header = false;
4846 }else{
4847 slot_trailer = slot;
4848 if(slot_trailer != slot_header)return false;
4849 looking_for_header = true;
4850 Nvalid++;
4851 }
4852 }else{
4853 // data word
4854
4855 // if we encounter a data word when we are expecting
4856 // a header word, then the current word is not from
4857 // an F1TDC. However, if we did find at least one valid
4858 // block at the begining, of the buffer, claim the buffer
4859 // points to F1TDC data. We check for as many valid F1TDC
4860 // blocks as possible to help ensure that is what the data
4861 // is.
4862 if(looking_for_header)return Nvalid>0;
4863
4864 // If the slot number does not match, then this is
4865 // not valid F1TDC data
4866 if(slot != slot_header)return false;
4867 }
4868 }
4869
4870 return Nvalid>0;
4871}
4872
4873//----------------
4874// DumpModuleMap
4875//----------------
4876void JEventSource_EVIO::DumpModuleMap(void)
4877{
4878 // Open output file
4879 string fname = "module_map.txt";
4880 ofstream ofs(fname.c_str());
4881 if(!ofs.is_open()){
4882 jerr<<"Unable to open file \""<<fname<<"\" for writing!"<<endl;
4883 return;
4884 }
4885
4886 jout<<"Writing module map to file \""<<fname<<"\""<<endl;
4887
4888 // Write header
4889 time_t now = time(NULL__null);
4890 ofs<<"# Autogenerated module map"<<endl;
4891 ofs<<"# Created: "<<ctime(&now);
4892 ofs<<"#"<<endl;
4893
4894 // Write known module types in header
4895 vector<DModuleType> modules;
4896 DModuleType::GetModuleList(modules);
4897 ofs<<"# Known module types:"<<endl;
4898 ofs<<"# ----------------------"<<endl;
4899 for(unsigned int i=0; i<modules.size(); i++){
4900 string name = modules[i].GetName();
4901 string space(12-name.size(), ' ');
4902 ofs << "# " << name << space << " - " << modules[i].GetDescription() <<endl;
4903 }
4904 ofs<<"#"<<endl;
4905 ofs<<"#"<<endl;
4906
4907 // Write module map
4908 ofs<<"# Format is:"<<endl;
4909 ofs<<"# tag num type"<<endl;
4910 ofs<<"#"<<endl;
4911
4912 map<tagNum, MODULE_TYPE>::iterator iter = module_type.begin();
4913 for(; iter!=module_type.end(); iter++){
4914
4915 tagNum tag_num = iter->first;
4916 MODULE_TYPE type = iter->second;
4917 ofs<<tag_num.first<<" "<<(int)tag_num.second<<" "<<DModuleType::GetName(type)<<endl;
4918 }
4919 ofs<<endl;
4920
4921 // Close output file
4922 ofs.close();
4923}
4924#endif