Hall-D Software  alpha
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DMapEVIOWords.cc
Go to the documentation of this file.
1 // $Id:$
2 //
3 // File: DMapEVIOWords.cc
4 // Created: Sat May 28 19:22:47 EDT 2016
5 // Creator: davidl (on Linux gluon104.jlab.org 2.6.32-358.23.2.el6.x86_64)
6 //
7 
8 #include <stdint.h>
9 #include <vector>
10 
11 #include "DMapEVIOWords.h"
12 #include <JANA/JApplication.h>
13 #include <JANA/JFactory.h>
14 #include <JANA/JEventLoop.h>
15 
16 using namespace std;
17 using namespace jana;
18 
19 #include <DANA/DApplication.h>
20 #include <TTAB/DTranslationTable.h>
21 
22 #include <TDirectory.h>
23 #include <TH2.h>
24 #include <TH1.h>
25 #include <TProfile.h>
26 #include <TProfile2D.h>
27 #include <TROOT.h>
28 
29 extern uint32_t BLOCK_SIZE;
30 
31 // root hist pointers
32 static TProfile *daq_hits_per_event;
33 static TProfile *daq_words_per_event;
34 static TH1D *daq_event_size;
35 static TH1D *daq_block_size; // Adds together BLOCK_SIZE EVIO events (n.b. evio events could already be blocks!)
36 static TH1D *daq_event_tdiff;
37 static TH1D *daq_words_by_type;
38 //static bool ttab_labels_set = false;
39 
40 
41 
42 //------------------
43 // DMapEVIOWords (Constructor)
44 //------------------
46 {
47  max_history_buff_size = 400;
48 
49  char daq_block_size_title[256];
50  sprintf(daq_block_size_title, "Block size (%d EVIO events) in kB", BLOCK_SIZE);
51 
52  daq_hits_per_event = new TProfile("daq_hits_per_event", "Hits/event vs. rocid", 100, 0.5, 100.5);
53  daq_words_per_event = new TProfile("daq_words_per_event", "words/event vs. rocid", 100, 0.5, 100.5);
54  daq_event_size = new TH1D("daq_event_size", "Event size in kB", 10000, 0.0, 1.0E3);
55  daq_block_size = new TH1D("daq_block_size", daq_block_size_title, 1000, 0.0, 1.0E3);
56  daq_event_tdiff = new TH1D("daq_event_tdiff", "Time between events", 10000, 0.0, 1.0E1);
57  daq_words_by_type = new TH1D("daq_words_by_type", "Number of words in EVIO file by type", kNEVIOWordTypes, 0, (double)kNEVIOWordTypes);
58 
59  daq_words_per_event->GetXaxis()->SetBinLabel(1 ,"Trigger Bank");
60  daq_words_per_event->GetXaxis()->SetBinLabel(99 ,"Residual");
61  AddROCIDLabels();
62 
63  daq_event_size->SetXTitle("Total event size (kB)");
64  daq_event_tdiff->SetXTitle("#deltat between events (ms)");
65 
66  // Making sure all labels have at least a single space avoids ROOT bugs when interacting with canvas
67  for(int ibin=1; ibin<=kNEVIOWordTypes; ibin++) daq_words_by_type->GetXaxis()->SetBinLabel(ibin, " ");
68 
69  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kUnknown, "unknown");
70  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kEVIOHeader, "EVIO len. & header");
71  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kEVIOEventNumber, "Event Number Word");
72  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kEVIOTimestamp, "Timestamp");
73 
74  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kBORData, "BOR record");
75 
76  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250BlockHeader, "f250 Block Header");
77  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250BlockTrailer, "f250 Block Trailer");
78  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250EventHeader, "f250 Event Header");
79  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250TriggerTime, "f250 Trigger Time");
80  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250WindowRawData, "f250 Window Raw Data");
81  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250WindowSum, "f250 Window Sum");
82  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250PulseRawData, "f250 Pulse Raw Data");
83  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250PulseData, "f250 Pulse Data");
84  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250PulseIntegral, "f250 Pulse Integral");
85  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250PulseTime, "f250 Pulse Time");
86  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250PulsePedestal, "f250 Pulse Pedestal");
87  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250EventTrailer, "f250 Event Trailer");
88  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250DataNotValid, "f250 Data Not Valid");
89  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250Filler, "f250 Filler Word");
90  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf250Unknown, "f250 Unknown");
91 
92  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125BlockHeader, "f125 Block Header");
93  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125BlockTrailer, "f125 Block Trailer");
94  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125EventHeader, "f125 Event Header");
95  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125TriggerTime, "f125 Trigger Time");
96  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125WindowRawData, "f125 Window Raw Data");
97  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125CDCPulse, "f125 CDC Pulse");
98  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125FDCPulse6, "f125 FDC Pulse (integral)");
99  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125FDCPulse9, "f125 FDC Pulse (peak)");
100  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125PulseIntegral, "f125 Pulse Integral");
101  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125PulseTime, "f125 Pulse Time");
102  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125PulsePedestal, "f125 Pulse Pedestal");
103  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125EventTrailer, "f125 Event Trailer");
104  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125DataNotValid, "f125 Data Not Valid");
105  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125Filler, "f125 Filler Word");
106  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kf125Unknown, "f125 Unknown");
107 
108  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2BlockHeader, "F1v2 Block Header");
109  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2BLockTrailer, "F1v2 Block Trailer");
110  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2EventHeader, "F1v2 Event Header");
111  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2TriggerTime, "F1v2 Trigger Time");
112  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2ChipHeader, "F1v2 Chip Header");
113  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2Data, "F1v2 Data");
114  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2Filler, "F1v2 Filler");
115  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2BreakWord, "F1v2 Break Word");
116  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v2Unknown, "F1v2 Unknown");
117 
118  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3BlockHeader, "F1v3 Block Header");
119  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3BLockTrailer, "F1v3 Block Trailer");
120  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3EventHeader, "F1v3 Event Header");
121  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3TriggerTime, "F1v3 Trigger Time");
122  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3ChipHeader, "F1v3 Chip Header");
123  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3Data, "F1v3 Data");
124  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3Filler, "F1v3 Filler");
125  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3BreakWord, "F1v3 Break Word");
126  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF1v3Unknown, "F1v3 Unknown");
127 
128  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190GlobalHeader, "CAEN1190 GLobal Header");
129  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190GlobalTrailer, "CAEN1190 Global Trailer");
130  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190GlobalTriggerTime, "CAEN1190 Trigger Time");
131  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190TDCHeader, "CAEN1190 TDC Header");
132  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190TDCData, "CAEN1190 TDC Data");
133  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190TDCError, "CAEN1190 TDC Error");
134  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190TDCTrailer, "CAEN1190 TDC Trailer");
135  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190Filler, "CAEN1190 Filler");
136  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kCAEN1190Unknown, "CAEN1190 Unknown");
137 
138  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kConfig, "DAQ Config");
139  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kConfigf250, "DAQ Config f250");
140  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kConfigf125, "DAQ Config f125");
141  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kConfigF1, "DAQ Config F1");
142  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kConfigCAEN1190, "DAQ Config CAEN1190");
143 
144  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kEPICSheader, "EPICS header");
145  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kEPICSdata, "EPICS data");
146 
147  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kTSsync, "TS sync event data");
148 
149  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kF800FAFA, "0xf800fafa");
150  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kD00DD00D, "0xd00dd00d");
151 
152  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kTotWords, "Total words in all events");
153  daq_words_by_type->GetXaxis()->SetBinLabel(1 + kNevents, "Number of events");
154 
155 }
156 
157 //------------------
158 // ~DMapEVIOWords (Destructor)
159 //------------------
161 {
162 
163 }
164 
165 //------------------
166 // AddROCIDLabels
167 //------------------
169 {
170  /// This is called just once to set the x-axis labels
171  /// of histograms whose x-axis is the rocid so that we
172  /// can label them by detector.
173 
174  DApplication dapp(0, NULL);
175  JEventLoop loop(&dapp);
176  DTranslationTable ttab(&loop);
177 
178  // Loop over all rocid values
179  for(uint32_t rocid=2; rocid<99; rocid++){
180  // We don't actually know what slot/channel combos are defined
181  // for this so we loop until we find one.
182  bool found_chan = false;
183  daq_hits_per_event->GetXaxis()->SetBinLabel(rocid, "");
184  daq_words_per_event->GetXaxis()->SetBinLabel(rocid, "");
185  for(uint32_t slot=2; slot<24; slot++){
186  for(uint32_t channel=0; channel<3; channel++){
187  try{
188  DTranslationTable::csc_t csc = {rocid, slot, channel};
189  const DTranslationTable::DChannelInfo &chinfo = ttab.GetDetectorIndex(csc);
190  daq_hits_per_event->GetXaxis()->SetBinLabel(rocid, ttab.DetectorName(chinfo.det_sys).c_str());
191  daq_words_per_event->GetXaxis()->SetBinLabel(rocid, ttab.DetectorName(chinfo.det_sys).c_str());
192  found_chan = true;
193  break;
194  }catch(JException &e){
195  // Do nothing
196  }
197  }
198  if(found_chan) break;
199  }
200  }
201 }
202 
203 
204 //------------------
205 // ParseEvent
206 //------------------
207 void DMapEVIOWords::ParseEvent(uint32_t *buff)
208 {
209  uint32_t *istart = buff;
210  uint32_t evio_buffwords = buff[0]+1;
211  uint32_t evio_buffsize = evio_buffwords*sizeof(uint32_t);
212  uint32_t *iend = &istart[evio_buffwords];
213 
214  if( istart==NULL ) return;
215  if( (evio_buffwords>=10) && (istart[7]==0xc0da0100) ){
216  // NTH is first 8 words so skip them
217  istart= &istart[8];
218  evio_buffsize -= 8*sizeof(uint32_t);
219  evio_buffwords -= 8;
220  }
221 
222  // Check if this is BOR data
223  if( evio_buffwords >= 4 ){
224  if( (istart[1]&0xFFFF00FF) == 0x00700001 ){
225 
226  // FILL HISTOGRAMS
227  // Since we are filling histograms local to this plugin, it will not interfere with other ROOT operations: can use plugin-wide ROOT fill lock
228  daq_words_by_type->Fill(kBORData, istart[0]);
229  daq_words_by_type->Fill(kTotWords, istart[0]);
230  return; // no further parsing needed
231  }
232  }
233 
234  // Check if this is EPICS data
235  if( evio_buffwords >= 4 ){
236  if( ((istart[1]>>16)&0xFF) == 0x60 ){
237 
238  daq_words_by_type->Fill(kEPICSheader, 2.0); // EVIO bank length and header word
239  daq_words_by_type->Fill(kTotWords, istart[0]);
240 
241  // Loop over daughter banks
242  uint32_t *iptr = &istart[2];
243  while( iptr < iend ){
244 
245  uint32_t bank_len = (*iptr)&0xFFFF;
246  uint32_t tag = ((*iptr)>>24)&0xFF;
247  iptr++;
248 
249  if(tag == 0x61){
250  // timestamp bank (count as header)
251  daq_words_by_type->Fill(kEPICSheader, bank_len+1);
252  }else if(tag == 0x62){
253  // EPICS data value
254  daq_words_by_type->Fill(kEPICSdata, bank_len+1);
255  }else{
256  // Unknown tag
257  }
258 
259  iptr = &iptr[bank_len];
260  }
261 
262  return; // no further parsing needed
263  }
264  }
265 
266  if( evio_buffwords < 4 ){
267  cout << "Too few words in event (" << evio_buffwords << ") skipping..." << endl;
268  return;
269  }
270 
271  // Physics event length
272  uint32_t physics_event_len = istart[0];
273  if( (istart[1] & 0xFF001000) != 0xFF001000 ) return; // not a physics event
274  if( physics_event_len+1 > evio_buffwords ){
275  cout << "Too many words in physics event: " << physics_event_len+1 << " > " << evio_buffwords << endl;
276  return;
277  }
278 
279  // Trigger bank event length
280  uint32_t trigger_bank_len = istart[2];
281  if( (istart[3] & 0xFF202000) != 0xFF202000 ) return; // not a trigger bank
282  if( trigger_bank_len+2 > evio_buffwords ){
283  cout << "Too many words in trigger bank " << trigger_bank_len << " > " << evio_buffwords-2 << endl;
284  return;
285  }
286 
287  // Time difference between events
288  // since events may be out of order due to L3, we
289  // keep track of up to 400 timestamps and only make
290  // entries once we have accumulated that many.
291  // (probably better to look for adjacent event numbers
292  // but that will take a littel refactoring.)
293  uint64_t tlo = istart[2+5];
294  uint64_t thi = istart[2+6];
295  uint64_t timestamp = (thi<<32) + (tlo<<0);
296  ts_history.insert(timestamp);
297  if( ts_history.size() > max_history_buff_size ){
298  auto it1 = ts_history.begin();
299  auto it2 = it1;
300  uint64_t t1 = *(it1);
301  uint64_t t2 = *(++it2);
302  ts_history.erase(it1, it2);
303  double tdiff_ns = (double)(t2 - t1)*4.0;
304  double tdiff_ms = tdiff_ns/1.0E6;
305  daq_event_tdiff->Fill(tdiff_ms);
306  }
307 
308  // Allocate memory to hold stats data
309  uint32_t Nwords[100]; // total data words for each ROC (includes event length words)
310  uint32_t word_stats[kNEVIOWordTypes]; // obtained from parsing event
311  for(uint32_t rocid=0; rocid<100; rocid++) Nwords[rocid] = 0;
312  for(uint32_t i=0; i<kNEVIOWordTypes; i++) word_stats[i] = 0;
313 
314  word_stats[kNevents] += istart[1]&0xFF;
315  word_stats[kTotWords] += evio_buffwords;
316 
317  word_stats[kEVIOHeader] += 4; // physics event and built trigger bank length and header words
318 
319  // Loop over data banks
320  uint32_t *iptr = &istart[3+trigger_bank_len];
321  while(iptr < iend){
322 
323  uint32_t len = *iptr;
324  uint32_t rocid = (iptr[1]>>16) & 0XFF;
325 
326  if(rocid<100) Nwords[rocid] += len+1;
327 
328  word_stats[kEVIOHeader] += 2; // ROC data bank length and header words
329 
330  uint32_t *imyend = &iptr[len+1];
331  if(imyend > iend) imyend = iend;
332 
333  uint64_t Nwords = ((uint64_t)imyend - (uint64_t)iptr)/sizeof(uint32_t);
334  if(Nwords<2){
335  static int Nwarnings = 0;
336  if(Nwarnings<10){
337  cout << "Nwords<2 (?)" << endl;
338  cout << " evio_buffwords = " << evio_buffwords << endl;
339  cout << " physics_event_len = " << physics_event_len << endl;
340  cout << " trigger_bank_len = " << trigger_bank_len << endl;
341  if(++Nwarnings == 10) cout << "Last warning!" << endl;
342  }
343  break;
344  }
345 
346  DataWordStats(iptr, imyend, word_stats);
347 
348  iptr = imyend;
349  }
350 
351  // Updated unknown words counter
352  uint32_t Nwords_added = TotWordCount(word_stats);
353  word_stats[kUnknown] += evio_buffwords - Nwords_added;
354 
355  // FILL HISTOGRAMS
356  // Since we are filling histograms local to this plugin, it will not interfere with other ROOT operations: can use plugin-wide ROOT fill lock
357 
358 
359  // Fill event size histos
360  double physics_event_len_kB = (double)((physics_event_len+1)*sizeof(uint32_t))/1024.0;
361  daq_event_size->Fill(physics_event_len_kB);
362  static int Nin_block = 1;
363  static double block_size = 0;
364  block_size += physics_event_len_kB;
365  Nin_block++;
366  if( (Nin_block%BLOCK_SIZE) == 0 ){
367  daq_block_size->Fill(block_size);
368  block_size = 0.0;
369  Nin_block = 0;
370  }
371 
372  uint32_t TotalWords = 0;
373  for(uint32_t rocid=0; rocid<100; rocid++){
374  daq_words_per_event->Fill(rocid, Nwords[rocid]);
375  TotalWords += Nwords[rocid];
376  }
377 
378  daq_words_per_event->Fill(1, trigger_bank_len+1);
379  daq_words_per_event->Fill(99, physics_event_len - trigger_bank_len - TotalWords);
380 
381  for(uint32_t i=0; i<kNEVIOWordTypes; i++){
382  daq_words_by_type->Fill(i, (double)word_stats[i]);
383  }
384 
385 }
386 
387 //------------------
388 // TotWordCount
389 //------------------
390 uint32_t DMapEVIOWords::TotWordCount(uint32_t *word_stats)
391 {
392  uint32_t N=0;
393  for(uint32_t i=kUnknown; i<kTotWords; i++) N += word_stats[i];
394  return N;
395 }
396 
397 //------------------
398 // DataWordStats
399 //------------------
400 void DMapEVIOWords::DataWordStats(uint32_t *iptr, uint32_t *iend, uint32_t *word_stats)
401 {
402  // Upon entry, the iptr will point to the start of the "Physics Event's Data Bank".
403  // It will loop over all sub-banks, tallying the word count as it goes up to
404  // but not including iend.
405 
406  iptr++; // advance past length word
407  uint32_t rocid = (*iptr++)>>16 & 0x0FFF;
408  while(iptr < iend){
409  uint32_t data_block_bank_len = *iptr++;
410  uint32_t *iendbank = &iptr[data_block_bank_len];
411  uint32_t det_id = ((*iptr) >> 16) & 0x0FFF;
412 
413  if(iendbank > iend) iendbank = iend;
414 
415  word_stats[kEVIOHeader] += 2; // data block bank length and header words
416 
417  iptr++; // advance to first raw data word
418 
419  // Not sure where this comes from, but it needs to be skipped if present
420  while( (*iptr==0xF800FAFA) && (iptr<iend) ){
421  word_stats[kF800FAFA]++;
422  iptr++;
423  }
424 
425  switch(det_id){
426  case 0:
427  case 1:
428  case 3:
429  case 6: // flash 250 module, MMD 2014/2/4
430  case 16: // flash 125 module (CDC), DL 2014/6/19
431  case 26: // F1 TDC module (BCAL), MMD 2014-07-31
432  ParseJLabModuleData(rocid, iptr, iendbank, word_stats);
433  break;
434 
435  case 20:
436  ParseCAEN1190(rocid, iptr, iendbank, word_stats);
437  break;
438 
439  case 0x55:
440  ParseModuleConfiguration(rocid, iptr, iendbank, word_stats);
441  break;
442 
443  case 0xE02:
444  ParseTSscalerBank(iptr, iendbank, word_stats);
445  break;
446 
447  default:
448  break;
449  }
450 
451  iptr = iendbank;
452  }
453 
454 
455 }
456 
457 //------------------
458 // ParseJLabModuleData
459 //------------------
460 void DMapEVIOWords::ParseJLabModuleData(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
461 {
462  while(iptr < iend){
463  if(*iptr != 0xf800fafa) break;
464  word_stats[kF800FAFA]++;
465  iptr++;
466  }
467 
468  uint32_t mod_id = ((*iptr) >> 18) & 0x000F;
469  switch(mod_id){
470  case DModuleType::FADC250: Parsef250Bank(rocid, iptr, iend, word_stats); break;
471  case DModuleType::FADC125: Parsef125Bank(rocid, iptr, iend, word_stats); break;
472  case DModuleType::F1TDC32: ParseF1v2TDCBank(rocid, iptr, iend, word_stats); break;
473  case DModuleType::F1TDC48: ParseF1v3TDCBank(rocid, iptr, iend, word_stats); break;
474  //case DModuleType::JLAB_TS: ParseTSBank(rocid, iptr, iend, word_stats); break;
475  //case DModuleType::TID: ParseTIBank(rocid, iptr, iend, word_stats); break;
476  }
477 }
478 
479 //------------------
480 // Parsef250Bank
481 //------------------
482 void DMapEVIOWords::Parsef250Bank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
483 {
484  while(iptr<iend){
485 
486  if(((*iptr>>31) & 0x1) == 0) { word_stats[kf250Unknown]++ ; iptr++; continue;}
487 
488  uint32_t window_width;
489  uint32_t window_words;
490  uint32_t data_type = (*iptr>>27) & 0x0F;
491  switch(data_type){
492  case 0: word_stats[kf250BlockHeader]++; iptr++; break;
493  case 1: word_stats[kf250BlockTrailer]++; iptr++; break;
494  case 2: word_stats[kf250EventHeader]++; iptr++; break;
495  case 3: // Trigger time
496  word_stats[kf250TriggerTime]++;
497  iptr++;
498  if(((*iptr>>31) & 0x1) == 0){ word_stats[kf250TriggerTime]++; iptr++; }
499  break;
500  case 4: // Window Raw Data
501  window_width = (*iptr>>0) & 0x0FFF;
502  window_words = 1 + ((window_width+1)/2); // 1 is for header word + 2 sample per word
503  word_stats[kf250WindowRawData] += window_words;
504  iptr = &iptr[window_words];
505  break;
506  case 7: word_stats[kf250PulseIntegral]++; iptr++; break;
507  case 8: word_stats[kf250PulseTime]++; iptr++; break;
508  case 9: word_stats[kf250PulseData]++; iptr++;
509  while( ((*iptr>>31) & 0x1) == 0 ){
510  word_stats[kf250PulseData]++; iptr++;
511  if(iptr == iend) break;
512  }
513  break;
514  case 10: word_stats[kf250PulsePedestal]++; iptr++; break;
515  case 13: word_stats[kf250EventTrailer]++; iptr++; break;
516  case 14: word_stats[kf250DataNotValid]++; iptr++; break;
517  case 15: word_stats[kf250Filler]++; iptr++; break;
518 
519  default: word_stats[kf250Unknown]++; iptr++; break;
520  }
521  }
522 }
523 
524 //------------------
525 // Parsef125Bank
526 //------------------
527 void DMapEVIOWords::Parsef125Bank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
528 {
529  while(iptr<iend){
530 
531  if(((*iptr>>31) & 0x1) == 0) { word_stats[kf125Unknown]++ ; iptr++; continue;}
532 
533  uint32_t window_width;
534  uint32_t window_words;
535  uint32_t data_type = (*iptr>>27) & 0x0F;
536  switch(data_type){
537  case 0: word_stats[kf125BlockHeader]++; iptr++; break;
538  case 1: word_stats[kf125BlockTrailer]++; iptr++; break;
539  case 2: word_stats[kf125EventHeader]++; iptr++; break;
540  case 3: // Trigger time
541  word_stats[kf125TriggerTime]++;
542  iptr++;
543  if(((*iptr>>31) & 0x1) == 0){ word_stats[kf125TriggerTime]++; iptr++; }
544  break;
545  case 4: // Window Raw Data
546  window_width = (*iptr>>0) & 0x0FFF;
547  window_words = 1 + ((window_width+1)/2); // 1 is for header word + 2 sample per word
548  word_stats[kf125WindowRawData] += window_words;
549  iptr = &iptr[window_words];
550  break;
551  case 5: word_stats[kf125CDCPulse]++;
552  iptr++;
553  if(((*iptr>>31) & 0x1) == 0){ word_stats[kf125CDCPulse]++; iptr++; }
554  break;
555  case 6: word_stats[kf125FDCPulse6]++;
556  iptr++;
557  if(((*iptr>>31) & 0x1) == 0){ word_stats[kf125FDCPulse6]++; iptr++; }
558  break;
559  case 7: word_stats[kf125PulseIntegral]++; iptr++; break;
560  case 8: word_stats[kf125PulseTime]++; iptr++; break;
561  case 9: word_stats[kf125FDCPulse9]++;
562  iptr++;
563  if(((*iptr>>31) & 0x1) == 0){ word_stats[kf125FDCPulse9]++; iptr++; }
564  break;
565  case 10: word_stats[kf125PulsePedestal]++; iptr++; break;
566  case 13: word_stats[kf125EventTrailer]++; iptr++; break;
567  case 14: word_stats[kf125DataNotValid]++; iptr++; break;
568  case 15: word_stats[kf125Filler]++; iptr++; break;
569 
570  default: word_stats[kf125Unknown]++; iptr++; break;
571  }
572  }
573 }
574 
575 //------------------
576 // ParseF1v2TDCBank
577 //------------------
578 void DMapEVIOWords::ParseF1v2TDCBank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
579 {
580  while(iptr<iend){
581  switch( (*iptr++) & 0xF8000000 ){
582  case 0xC0000000: word_stats[kF1v2ChipHeader]++; break;
583  case 0xB8000000: word_stats[kF1v2Data]++; break;
584  case 0xF8000000: word_stats[kF1v2Filler]++; break;
585  case 0x80000000: word_stats[kF1v2BlockHeader]++; break;
586  case 0x88000000: word_stats[kF1v2BLockTrailer]++; break;
587  case 0x90000000: word_stats[kF1v2EventHeader]++; break;
588  case 0x98000000: word_stats[kF1v2TriggerTime]++; break;
589  case 0xF0000000: word_stats[kF1v2BreakWord]++; break;
590  default: word_stats[kF1v2Unknown]++; break;
591  }
592  }
593 }
594 
595 //------------------
596 // ParseF1v3TDCBank
597 //------------------
598 void DMapEVIOWords::ParseF1v3TDCBank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
599 {
600  while(iptr<iend){
601  switch( (*iptr++) & 0xF8000000 ){
602  case 0xC0000000: word_stats[kF1v3ChipHeader]++; break;
603  case 0xB8000000: word_stats[kF1v3Data]++; break;
604  case 0xF8000000: word_stats[kF1v3Filler]++; break;
605  case 0x80000000: word_stats[kF1v3BlockHeader]++; break;
606  case 0x88000000: word_stats[kF1v3BLockTrailer]++; break;
607  case 0x90000000: word_stats[kF1v3EventHeader]++; break;
608  case 0x98000000: word_stats[kF1v3TriggerTime]++; break;
609  case 0xF0000000: word_stats[kF1v3BreakWord]++; break;
610  default: word_stats[kF1v3Unknown]++; break;
611  }
612  }
613 }
614 
615 //------------------
616 // ParseCAEN1190
617 //------------------
618 void DMapEVIOWords::ParseCAEN1190(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
619 {
620  while(iptr<iend){
621 
622  // This word appears to be appended to the data.
623  // Probably in the ROL. Ignore it if found.
624  if(*iptr == 0xd00dd00d) {
625  word_stats[kD00DD00D]++;
626  iptr++;
627  continue;
628  }
629 
630  uint32_t type = (*iptr++) >> 27;
631  switch(type){
632  case 0b01000: word_stats[kCAEN1190GlobalHeader]++; break;
633  case 0b10000: word_stats[kCAEN1190GlobalTrailer]++; break;
634  case 0b10001: word_stats[kCAEN1190GlobalTriggerTime]++; break;
635  case 0b00001: word_stats[kCAEN1190TDCHeader]++; break;
636  case 0b00000: word_stats[kCAEN1190TDCData]++; break;
637  case 0b00100: word_stats[kCAEN1190TDCError]++; break;
638  case 0b00011: word_stats[kCAEN1190TDCTrailer]++; break;
639  case 0b11000: word_stats[kCAEN1190Filler]++; break;
640  default: word_stats[kCAEN1190Unknown]++; break;
641  }
642  }
643 }
644 
645 //------------------
646 // ParseModuleConfiguration
647 //------------------
648 void DMapEVIOWords::ParseModuleConfiguration(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
649 {
650  while(iptr < iend){
651 
652  word_stats[kConfig]++; // Count headers as generic
653  uint32_t Nvals = ((*iptr++) >> 24) & 0xFF;
654 
655  // Loop over all parameters in this section
656  for(uint32_t i=0; i< Nvals; i++){
657 
658  switch((*iptr++)>>24){
659  case 0x05: word_stats[kConfigf250]++; break;
660  case 0x0F: word_stats[kConfigf125]++; break;
661  case 0x06: word_stats[kConfigF1]++; break;
662  case 0x10: word_stats[kConfigCAEN1190]++; break;
663  default: word_stats[kConfig]++; break;
664  }
665  }
666  }
667 }
668 
669 //------------------
670 // ParseTSscalerBank
671 //------------------
672 void DMapEVIOWords::ParseTSscalerBank(uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
673 {
674  word_stats[kTSsync] += (uint32_t)( (uint64_t)iend - (uint64_t)iptr)/sizeof(uint32_t) ;
675 
676  iptr = iend;
677 }
DApplication * dapp
static double E1[100]
uint32_t BLOCK_SIZE
Definition: hdevio_scan.cc:37
void ParseCAEN1190(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
sprintf(text,"Post KinFit Cut")
void DataWordStats(uint32_t *iptr, uint32_t *iend, uint32_t *word_stats)
static TH1D * daq_block_size
static TH1D * daq_event_size
void ParseTSscalerBank(uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
void AddROCIDLabels(void)
void ParseJLabModuleData(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
static double E3[100]
TEllipse * e
void Parsef250Bank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
const DChannelInfo & GetDetectorIndex(const csc_t &in_daq_index) const
uint32_t TotWordCount(uint32_t *word_stats)
static TProfile * daq_words_per_event
void Parsef125Bank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
TLatex * t1
void ParseF1v3TDCBank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
static TH1D * daq_event_tdiff
void ParseModuleConfiguration(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
void ParseF1v2TDCBank(uint32_t rocid, uint32_t *&iptr, uint32_t *iend, uint32_t *word_stats)
static const size_t block_size
Definition: src/md5.cpp:54
void ParseEvent(uint32_t *buff)
static string DetectorName(Detector_t type)
static TProfile * daq_hits_per_event