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