IcebergTPCRawDecoder_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 // Class: IcebergTPCRawDecoder
3 // Plugin Type: producer (art v2_10_03)
4 // File: IcebergTPCRawDecoder_module.cc
5 //
6 // Generated at Fri Mar 2 15:36:20 2018 by Thomas Junk using cetskelgen
7 // from cetlib version v3_02_00. Original code from Jingbo Wang for ProtoDUNE-SP
8 ////////////////////////////////////////////////////////////////////////
9 
17 #include "fhiclcpp/ParameterSet.h"
20 #include "art_root_io/TFileService.h"
22 #include <memory>
23 #include <cmath>
24 
25 // ROOT includes
26 #include "TH1.h"
27 #include "TStyle.h"
28 #include "TMath.h"
29 
30 // artdaq and dune-raw-data includes
34 #include "artdaq-core/Data/Fragment.hh"
35 #include "artdaq-core/Data/ContainerFragment.hh"
38 #include "dam/HeaderFragmentUnpack.hh"
39 #include "dam/DataFragmentUnpack.hh"
40 #include "dam/TpcFragmentUnpack.hh"
41 #include "dam/TpcStreamUnpack.hh"
42 #include "dam/access/WibFrame.hh"
43 #include "dam/access/Headers.hh"
44 #include "dam/access/TpcStream.hh"
45 #include "dam/access/TpcRanges.hh"
46 #include "dam/access/TpcToc.hh"
47 #include "dam/access/TpcPacket.hh"
48 #include "dam/RceFragmentUnpack.hh"
49 
50 // larsoft includes
53 #include "lardataobj/RawData/raw.h"
54 
55 // DUNE includes
57 
59 
60 public:
61  explicit IcebergTPCRawDecoder(fhicl::ParameterSet const & p);
66  void produce(art::Event & e) override;
67 
68 private:
69  typedef std::vector<raw::RawDigit> RawDigits;
70  typedef std::vector<raw::RDTimeStamp> RDTimeStamps;
74  typedef std::vector<raw::RDStatus> RDStatuses;
75 
76  // configuration parameters
77 
88  unsigned int _full_channel_count;
91  unsigned int _full_tick_count;
102 
112 
115 
116  //declare histogram data memebers
118  unsigned int duplicate_channels;
119  unsigned int error_counter;
120  unsigned int incorrect_ticks;
121  unsigned int rcechans;
122  unsigned int felixchans;
124  //TH1I * fIncorrectTickNumbersZoomed;
125  TH1I * fParticipRCE;
129  TH1I * fFragSizeRCE;
132 
133  // flags and state needed for the data integrity enforcement mechanisms
134 
135  unsigned int _tick_count_this_event; // for use in comparing tick counts for all channels
138  const unsigned int _duplicate_channel_checklist_size=15360;
142 
143  // internal methods
144 
145  bool _processRCE(art::Event &evt, RawDigits& raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm);
146  bool _processFELIX(art::Event &evt, RawDigits& raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm);
147  bool _process_RCE_AUX(const artdaq::Fragment& frag, RawDigits& raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm, uint32_t runNumber);
148  bool _process_FELIX_AUX(const artdaq::Fragment& frag, RawDigits& raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm, uint32_t runNumber);
149 
150  void computeMedianSigma(raw::RawDigit::ADCvector_t &v_adc, float &median, float &sigma);
151 
152  std::vector<int16_t> _buffer;
153 };
154 
155 
157  : EDProducer(p)
158 {
159  std::vector<int> emptyivec;
160  _rce_input_label = p.get<std::string>("RCERawDataLabel","daq");
161  _rce_input_container_instance = p.get<std::string>("RCERawDataContainerInstance","ContainerTPC");
162  _rce_input_noncontainer_instance = p.get<std::string>("RCERawDataNonContainerInstance","TPC");
163  _rce_fragment_type = p.get<int>("RCEFragmentType",2);
164  _drop_events_with_small_rce_frags = p.get<bool>("RCEDropEventsWithSmallFrags",false);
165  _drop_small_rce_frags = p.get<bool>("RCEDropSmallFrags",true);
166  _rce_frag_small_size = p.get<unsigned int>("RCESmallFragSize",10000);
167  _rce_drop_frags_with_badcsf = p.get<bool>("RCEDropFragsWithBadCSF",true);
168  _rce_hex_dump = p.get<bool>("RCEHexDump",false);
169  _rce_save_frags_to_files = p.get<bool>("RCESaveFragsToFiles",false);
170  _rce_check_buffer_size = p.get<bool>("RCECheckBufferSize",true);
171  _rce_buffer_size_checklimit = p.get<unsigned int>("RCEBufferSizeCheckLimit",10000000);
172 
173  _felix_input_label = p.get<std::string>("FELIXRawDataLabel");
174  _felix_input_container_instance = p.get<std::string>("FELIXRawDataContainerInstance","ContainerFELIX");
175  _felix_input_noncontainer_instance = p.get<std::string>("FELIXRawDataNonContainerInstance","FELIX");
176  _felix_fragment_type = p.get<int>("FELIXFragmentType",8);
177  _felix_drop_frags_with_badcsf = p.get<bool>("FELIXDropFragsWithBadCSF",true);
178  _felix_hex_dump = p.get<bool>("FELIXHexDump",false);
179  _felix_enforce_exact_crate_number = p.get<bool>("FELIXEnforceExactCrateNumber",false);
180  _felix_crate_number_to_check = p.get<int>("FELIXCrateNumberToCheck",6);
181  _drop_events_with_small_felix_frags = p.get<bool>("FELIXDropEventsWithSmallFrags",false);
182  _drop_small_felix_frags = p.get<bool>("FELIXDropSmallFrags",true);
183  _felix_frag_small_size = p.get<unsigned int>("FELIXSmallFragSize",10000);
184  _felix_check_buffer_size = p.get<bool>("FELIXCheckBufferSize",true);
185  _felix_buffer_size_checklimit = p.get<unsigned int>("FELIXBufferSizeCheckLimit",10000000);
186 
187  _output_label = p.get<std::string>("OutputDataLabel");
188 
189  _enforce_full_channel_count = p.get<bool>("EnforceFullChannelCount", false);
190  _full_channel_count = p.get<unsigned int>("FullChannelCount", 15360);
191  _enforce_same_tick_count = p.get<bool>("EnforceSameTickCount",false);
192  _enforce_full_tick_count = p.get<bool>("EnforceFullTickCount",false);
193  _full_tick_count = p.get<unsigned int>("FullTickCount",6000);
194  _enforce_error_free = p.get<bool>("EnforceErrorFree",false);
195  _enforce_no_duplicate_channels = p.get<bool>("EnforceNoDuplicateChannels", true);
196 
197  _compress_Huffman = p.get<bool>("CompressHuffman",false);
198  _print_coldata_convert_count = p.get<bool>("PrintColdataConvertCount",false);
199 
200  produces<RawDigits>( _output_label ); //the strings in <> are the typedefs defined above
201  produces<RDTimeStamps>( _output_label );
202  produces<RDTsAssocs>( _output_label );
203  produces<RDStatuses>( _output_label );
204 
205  //Initialize Histograms if the tag is present
206  //art::ServiceHandle<art::TFileService> fs;
207  _make_histograms = p.get<bool>("MakeHistograms",false);
208 
209  if (_make_histograms)
210  {
212 
213  //Number of channels with wrong number of tics plotted to have an adjusted log2 scale on x axis
214  fIncorrectTickNumbers = tFileService->make<TH1D>("fIncorrectTickNumbers","Channels with Unexpected Number of Ticks", 45, -0.5, 14.5);
215  fIncorrectTickNumbers->GetXaxis()->SetTitle("Channels with an Unexpected Number of Ticks");
216  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(2,"1");
217  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(8,"4");
218  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(14,"16");
219  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(23,"128");
220  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(32,"1024");
221  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(38,"4096");
222  fIncorrectTickNumbers->GetXaxis()->SetBinLabel(44, "16384");
223 
224  //same as fIncorrectTickNumbers but with a zoomed domain
225  //fIncorrectTickNumbersZoomed = tFileService->make<TH1I>("fIncorrectTickNumbersZoomed","Channels with Unexpected Number of Ticks", , 0.5, 100.5);
226  //fIncorrectTickNumbersZoomed->GetXaxis()->SetTitle("Channels with an Unexpected Number of Tics (log2)");
227 
228  //number of participating RCE channels per event
229  fParticipRCE = tFileService->make<TH1I>("fParticipRCE","Participating RCE channels", 130, 0.5, 15000.5); //expected value 128000
230  fParticipRCE->GetXaxis()->SetTitle("RCE channels");
231 
232  //number of participating FELIX channels per event
233  fParticipFELIX = tFileService->make<TH1I>("fParticipFELIX","Participating FELIX channels", 100, 0.5, 3000.5); //expected value 2560
234  fParticipFELIX->GetXaxis()->SetTitle("FELIX channels");
235 
236  //number of duplicated channels per event
237  fDuplicatesNumber = tFileService->make<TH1I>("fDuplicatesNumber", "Number of Duplucated Channels", 200, 0.5, 200.5);
238  fDuplicatesNumber->GetXaxis()->SetTitle("Number of Duplicates");
239  //gStyle->SetOptStat("nemro");
240 
241  //number of channels with error returns
242  fErrorsNumber = tFileService->make<TH1D>("fErrorsNumber", "Channels with Errors", 45, -0.5, 14.5);
243  fErrorsNumber->GetXaxis()->SetTitle("Number of channels with errors");
244  fErrorsNumber->GetXaxis()->SetBinLabel(2,"1");
245  fErrorsNumber->GetXaxis()->SetBinLabel(8,"4");
246  fErrorsNumber->GetXaxis()->SetBinLabel(14,"16");
247  fErrorsNumber->GetXaxis()->SetBinLabel(23,"128");
248  fErrorsNumber->GetXaxis()->SetBinLabel(32,"1024");
249  fErrorsNumber->GetXaxis()->SetBinLabel(38,"4096");
250  fErrorsNumber->GetXaxis()->SetBinLabel(44, "16384");
251 
252  //total fragment sizes
253  fFragSizeRCE = tFileService->make<TH1I>("fFragSizeRCE", "RCE Fragment Size", 100, 0.5, 288000000.5);
254  fFragSizeRCE->GetXaxis()->SetTitle("Size of RCE Fragments (bytes)");
255 
256  fFragSizeFELIX = tFileService->make<TH1I>("fFragSizeFELIX", "FELIX Fragment Size", 100, 0.5, 57600000.5);
257  fFragSizeFELIX->GetXaxis()->SetTitle("Size of FELIX Fragments (bytes)");
258 
259  fDeltaTimestamp = tFileService->make<TH1I>("fDeltaTimestamp", "Delta Timestamp Between Frames", 101, -0.5, 100.5);
260 
261  }
262 
263 }
264 
266 {
267  RawDigits raw_digits;
268  RDTimeStamps rd_timestamps;
269  RDTsAssocs rd_ts_assocs;
270 
271  RDPmkr rdpm(e,_output_label);
272  TSPmkr tspm(e,_output_label);
273 
274  error_counter = 0; //reset the errors to zero for each run
275  incorrect_ticks = 0;
276  duplicate_channels = 0;
277  rcechans = 0;
278  felixchans = 0;
279 
281  _discard_data = false; // true if we're going to drop the whole event's worth of data
282  _DiscardedCorruptData = false; // can be set to true if we drop some of the event's data
283  _KeptCorruptData = false; // true if we identify a corruption candidate but are skipping the test to drop it
284 
285  for (size_t i=0; i<_duplicate_channel_checklist_size; ++i) _duplicate_channel_checklist[i] = false;
286 
287  _processRCE(e,raw_digits,rd_timestamps,rd_ts_assocs,rdpm,tspm);
288  _processFELIX(e,raw_digits,rd_timestamps,rd_ts_assocs,rdpm,tspm);
289 
290  //Make the histograms for error checking. (other histograms are filled within the _process and _AUX functions)
291  if(_make_histograms)
292  {
293  fErrorsNumber->Fill(log2(error_counter));
296  fParticipFELIX->Fill(felixchans);
297  fParticipRCE->Fill(rcechans);
298  //fIncorrectTickNumbersZoomed->Fill(incorrect_ticks);
299  }
300 
301  if (_enforce_full_channel_count && raw_digits.size() != _full_channel_count)
302  {
303  MF_LOG_WARNING("IcebergTPCRawDecoder:") << "Wrong Total number of Channels " << raw_digits.size()
304  << " which is not " << _full_channel_count << ". Discarding Data";
305  _DiscardedCorruptData = true;
306  _discard_data = true;
307  }
308 
309  if (_discard_data)
310  {
311  RawDigits empty_raw_digits;
312  RDTimeStamps empty_rd_timestamps;
313  RDTsAssocs empty_rd_ts_assocs;
314  RDStatuses statuses;
315  statuses.emplace_back(true,false,1);
316  e.put(std::make_unique<decltype(empty_raw_digits)>(std::move(empty_raw_digits)),_output_label);
317  e.put(std::make_unique<decltype(empty_rd_timestamps)>(std::move(empty_rd_timestamps)),_output_label);
318  e.put(std::make_unique<decltype(empty_rd_ts_assocs)>(std::move(empty_rd_ts_assocs)),_output_label);
319  e.put(std::make_unique<decltype(statuses)>(std::move(statuses)),_output_label);
320  }
321  else
322  {
323  RDStatuses statuses;
324  unsigned int statword=0;
325  if (_DiscardedCorruptData) statword |= 1;
326  if (_KeptCorruptData) statword |= 2;
327  statuses.emplace_back(_DiscardedCorruptData,_KeptCorruptData,statword);
328  e.put(std::make_unique<decltype(raw_digits)>(std::move(raw_digits)),_output_label);
329  e.put(std::make_unique<decltype(rd_timestamps)>(std::move(rd_timestamps)),_output_label);
330  e.put(std::make_unique<decltype(rd_ts_assocs)>(std::move(rd_ts_assocs)),_output_label);
331  e.put(std::make_unique<decltype(statuses)>(std::move(statuses)),_output_label);
332  }
333 }
334 
335 bool IcebergTPCRawDecoder::_processRCE(art::Event &evt, RawDigits& raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm)
336 {
337  size_t n_rce_frags = 0;
339  auto cont_frags = evt.getHandle<artdaq::Fragments>(itag1);
340 
341  bool have_data=false;
342  bool have_data_nc=false;
343 
344  uint32_t runNumber = evt.run();
345 
346  if (cont_frags)
347  {
348  have_data = true;
349 
350  //size of RCE fragments into histogram
351  if(_make_histograms)
352  {
353  size_t rcebytes = 0;
354  for (auto const& cont : *cont_frags)
355  {
356  rcebytes = rcebytes + (cont.sizeBytes());
357  }
358  fFragSizeRCE->Fill(rcebytes);
359  }
360 
361  for (auto const& cont : *cont_frags)
362  {
363  //std::cout << "RCE container fragment size bytes: " << cont.sizeBytes() << std::endl;
364  bool process_flag = true;
365  if (cont.sizeBytes() < _rce_frag_small_size)
366  {
368  {
369  MF_LOG_WARNING("_process_RCE:") << " Small RCE fragment size: " << cont.sizeBytes() << " Discarding Event on request.";
370  _discard_data = true;
371  _DiscardedCorruptData = true;
372  evt.removeCachedProduct(cont_frags);
373  return false;
374  }
375  if ( _drop_small_rce_frags )
376  {
377  MF_LOG_WARNING("_process_RCE:") << " Small RCE fragment size: " << cont.sizeBytes() << " Discarding just this fragment on request.";
378  _DiscardedCorruptData = true;
379  process_flag = false;
380  }
381  _KeptCorruptData = true;
382  }
383  if (process_flag)
384  {
385  artdaq::ContainerFragment cont_frag(cont);
386  for (size_t ii = 0; ii < cont_frag.block_count(); ++ii)
387  {
388  if (_process_RCE_AUX(*cont_frag[ii], raw_digits, timestamps, tsassocs, rdpm, tspm, runNumber)) ++n_rce_frags;
389  }
390  }
391  }
392  evt.removeCachedProduct(cont_frags);
393  }
394 
395  //noncontainer frags
396 
398  auto frags = evt.getHandle<artdaq::Fragments>(itag2);
399 
400  if (frags)
401  {
402  have_data_nc = true;
403 
404  //size of RCE fragments into histogram
405  if(_make_histograms)
406  {
407  size_t rcebytes = 0;
408  for (auto const& frag: *frags)
409  {
410  rcebytes = rcebytes + (frag.sizeBytes());
411  }
412  fFragSizeRCE->Fill(rcebytes);
413  }
414 
415  for(auto const& frag: *frags)
416  {
417  bool process_flag = true;
418  if (frag.sizeBytes() < _rce_frag_small_size)
419  {
421  {
422  MF_LOG_WARNING("_process_RCE:") << " Small RCE fragment size: " << frag.sizeBytes() << " Discarding Event on request.";
423  _discard_data = true;
424  _DiscardedCorruptData = true;
425  evt.removeCachedProduct(frags);
426  return false;
427  }
428  if ( _drop_small_rce_frags )
429  {
430  MF_LOG_WARNING("_process_RCE:") << " Small RCE fragment size: " << frag.sizeBytes() << " Discarding just this fragment on request.";
431  _DiscardedCorruptData = true;
432  process_flag = false;
433  }
434  _KeptCorruptData = true;
435  }
436 
437  if (process_flag)
438  {
439  if (_process_RCE_AUX(frag, raw_digits, timestamps,tsassocs, rdpm, tspm, runNumber)) ++n_rce_frags;
440  }
441  }
442  evt.removeCachedProduct(frags);
443  }
444 
445  //MF_LOG_INFO("_processRCE")
446  //<< " Processed " << n_rce_frags
447  //<< " RCE Fragments, making "
448  //<< raw_digits.size()
449  //<< " RawDigits.";
450  return have_data || have_data_nc;
451 }
452 
453 // returns true if we want to add to the number of fragments processed. Separate flag used
454 // for data error conditions (_discard_data).
455 
457  const artdaq::Fragment& frag,
458  RawDigits& raw_digits,
459  RDTimeStamps &timestamps,
460  RDTsAssocs &tsassocs,
461  RDPmkr &rdpm,
462  TSPmkr &tspm,
463  uint32_t runNumber
464  )
465 {
466 
467  if (_rce_hex_dump)
468  {
469  std::ios oldState(nullptr);
470  oldState.copyfmt(std::cout);
471 
472  std::cout << "RCE Fragment: all numbers in hex " << std::hex
473  << " SequenceID = " << frag.sequenceID()
474  << " fragmentID = " << frag.fragmentID()
475  << " fragmentType = " << (unsigned)frag.type()
476  << " Timestamp = " << frag.timestamp() << std::endl;
477  std::cout << "Offset Data";
478  artdaq::Fragment fragloc(frag);
479  unsigned char *dbegin = reinterpret_cast<unsigned char *>(fragloc.dataAddress());
480  size_t dsize = fragloc.dataSizeBytes();
481  size_t offcounter=0;
482  for (size_t bcounter=0; bcounter<dsize;++bcounter)
483  {
484  if ( (offcounter % 8) == 0 )
485  {
486  std::cout << std::endl << std::hex << std::setfill('0') << std::setw(8) << offcounter << " ";
487  }
488  std::cout << std::hex << std::setfill('0') << std::setw(2) << (int) *dbegin << " ";
489  dbegin++;
490  offcounter++;
491  }
492  std::cout << std::endl;
493  std::cout.copyfmt(oldState);
494  }
495 
496  if(frag.type() != _rce_fragment_type)
497  {
498  MF_LOG_WARNING("_process_RCE_AUX:") << " RCE fragment type " << (int) frag.type() << " doesn't match expected value: " << _rce_fragment_type << " Discarding RCE fragment";
499  _DiscardedCorruptData = true;
500  return false;
501  }
502  //MF_LOG_INFO("_Process_RCE_AUX")
503  //<< " SequenceID = " << frag.sequenceID()
504  //<< " fragmentID = " << frag.fragmentID()
505  //<< " fragmentType = " << (unsigned)frag.type()
506  //<< " Timestamp = " << frag.timestamp();
508 
509  artdaq::Fragment cfragloc(frag);
510  size_t cdsize = cfragloc.dataSizeBytes();
511  const uint64_t* cdptr = (uint64_t const*) (cfragloc.dataBeginBytes() + 12); // see dune-raw-data/Overlays/RceFragment.cc
512  HeaderFragmentUnpack const cdheader(cdptr);
513  //bool isOkay = RceFragmentUnpack::isOkay(cdptr,cdsize+sizeof(cdheader));
514  if (cdsize>16) cdsize -= 16;
515  bool isOkay = RceFragmentUnpack::isOkay(cdptr,cdsize);
516  if (!isOkay)
517  {
518  MF_LOG_WARNING("_process_RCE_AUX:") << "RCE Fragment isOkay failed: " << cdsize << " Discarding this fragment";
519  error_counter++;
520  _DiscardedCorruptData = true;
521  return false;
522  }
523  DataFragmentUnpack df(cdptr);
524  //std::cout << "isTPpcNormal: " << df.isTpcNormal() << " isTpcDamaged: " << df.isTpcDamaged() << " isTpcEmpty: " << df.isTpcEmpty() << std::endl;
525 
526  dune::RceFragment rce(frag);
528  {
529  TString outfilename="rce";
530  outfilename += frag.sequenceID();
531  outfilename += "_";
532  outfilename += frag.fragmentID();
533  outfilename+=".fragment";
534  rce.save(outfilename.Data());
535  std::cout << "Saved an RCE fragment with " << rce.size() << " streams: " << outfilename << std::endl;
536  }
537 
538  uint32_t ch_counter = 0;
539  for (int i = 0; i < rce.size(); ++i)
540  {
541  auto const * rce_stream = rce.get_stream(i);
542  size_t n_ch = rce_stream->getNChannels();
543  size_t n_ticks = rce_stream->getNTicks();
544  auto const identifier = rce_stream->getIdentifier();
545  uint32_t crateNumber = identifier.getCrate();
546  uint32_t slotNumber = identifier.getSlot();
547  uint32_t fiberNumber = identifier.getFiber();
548 
549  //std::cout << "Processing an RCE Stream: " << crateNumber << " " << slotNumber << " " << fiberNumber << " " << n_ticks << " " << n_ch << std::endl;
550 
551  if (crateNumber == 0 || crateNumber > 6 || slotNumber > 4 || fiberNumber == 0 || fiberNumber > 4)
552  {
554  {
555  MF_LOG_WARNING("_process_RCE:") << "Bad crate, slot, fiber number, discarding fragment on request: "
556  << crateNumber << " " << slotNumber << " " << fiberNumber;
557  _DiscardedCorruptData = true;
558  return false;
559  }
560  _KeptCorruptData = true;
561  }
562 
563  // inverted ordering on back side, Run 2c (=Run 3)
564  // note Shekhar's FEMB number is fiber-1, and WIB is slot+1
565 
566  if (runNumber > 2572)
567  {
568  auto oldfiber = fiberNumber;
569  auto oldslot = slotNumber;
570 
571  if (oldslot == 0 && oldfiber == 4)
572  {
573  slotNumber = 1;
574  fiberNumber = 3;
575  }
576  if (oldslot == 1 && oldfiber == 4)
577  {
578  slotNumber = 0;
579  fiberNumber = 3;
580  }
581  if (oldslot == 1 && oldfiber == 3)
582  {
583  slotNumber = 0;
584  fiberNumber = 4;
585  }
586  if (oldslot == 0 && oldfiber == 3)
587  {
588  slotNumber = 1;
589  fiberNumber = 4;
590  }
591  }
592 
593  // two cable swaps on June 20, 2019, and go back to the original on Jan 22, 2020
594 
595  if (runNumber > 1530 && runNumber < 2572)
596  {
597  auto oldfiber = fiberNumber;
598  auto oldslot = slotNumber;
599 
600  // second swap, June 21, 2019 -- see Slack
601 
602  if (oldslot == 2 && oldfiber == 1)
603  {
604  slotNumber = 2;
605  fiberNumber = 3;
606  }
607  if (oldslot == 1 && oldfiber == 1)
608  {
609  slotNumber = 1;
610  fiberNumber = 3;
611  }
612  if (oldslot == 2 && oldfiber == 3)
613  {
614  slotNumber = 2;
615  fiberNumber = 1;
616  }
617  if (oldslot == 1 && oldfiber == 3)
618  {
619  slotNumber = 1;
620  fiberNumber = 1;
621  }
622 
623  oldfiber = fiberNumber;
624  oldslot = slotNumber;
625 
626  if (oldslot == 0 && oldfiber == 4)
627  {
628  slotNumber = 1;
629  fiberNumber = 3;
630  }
631  if (oldslot == 1 && oldfiber == 4)
632  {
633  slotNumber = 0;
634  fiberNumber = 3;
635  }
636  if (oldslot == 0 && oldfiber == 3)
637  {
638  slotNumber = 1;
639  fiberNumber = 4;
640  }
641  if (oldslot == 1 && oldfiber == 3)
642  {
643  slotNumber = 0;
644  fiberNumber = 4;
645  }
646  }
647 
648  // skip the fake TPC data
649 
650  if ( slotNumber == 1 && fiberNumber == 1 )
651  {
652  continue;
653  }
654 
655  if ( slotNumber == 2 && fiberNumber == 1 )
656  {
657  continue;
658  }
659 
660  //std::cout << " After cable swap : WIB: " << slotNumber+1 << " FEMB: " << fiberNumber-1 << std::endl;
661 
663  {
664  std::cout << "Printing coldata convert counts for slot: " << slotNumber << " fiber: " << fiberNumber << std::endl;
665  // from JJ's PdReaderTest.cc
666  using namespace pdd;
667  using namespace pdd::access;
668  //bool printed=false;
669  TpcStream const &stream = rce_stream->getStream ();
670  TpcToc toc (stream.getToc ());
671  TpcPacket pktRec (stream.getPacket ());
672  TpcPacketBody pktBdy (pktRec.getRecord ());
673  int npkts = toc.getNPacketDscs ();
674  for (int ipkt = 0; ipkt < npkts; ++ipkt)
675  {
676  TpcTocPacketDsc pktDsc (toc.getPacketDsc (ipkt));
677  unsigned int o64 = pktDsc.getOffset64 ();
678  unsigned int pktType = pktDsc.getType ();
679  unsigned nWibFrames = pktDsc.getNWibFrames ();
680  WibFrame const *wf = pktBdy.getWibFrames (pktType, o64);
681  for (unsigned iwf = 0; iwf < nWibFrames; ++iwf)
682  {
683  auto const &colddata = wf->getColdData ();
684  auto cvt0 = colddata[0].getConvertCount ();
685  //auto cvt1 = colddata[1].getConvertCount ();
686  int diff = (int) cvt0 - (int) iwf;
687  std::cout << "Packet: " << ipkt << " WIB frame: " << iwf << " RCE coldata convert count: " << cvt0 << " Difference: " << diff << std::endl;
688  //printed = true;
689  ++wf; // in case we were looping over WIB frames, but let's stop at the first
690  //break;
691  }
692  //if (printed) break;
693  }
694  }
695 
696 
697  if(_make_histograms)
698  {
699  //log the participating RCE channels
700  rcechans=rcechans+n_ch;
701  }
702 
703  if (n_ticks != _full_tick_count)
704  {
706  {
707  MF_LOG_WARNING("_process_RCE_AUX:") << "Nticks not the required value: " << n_ticks << " "
708  << _full_tick_count << " Discarding Data";
709  error_counter++;
710  incorrect_ticks++;
711  _discard_data = true;
712  _DiscardedCorruptData = true;
713  return false;
714  }
715  _KeptCorruptData = true;
716  }
717 
719  {
721  _tick_count_this_event = n_ticks;
722  }
723  else
724  {
725  if (n_ticks != _tick_count_this_event)
726  {
728  {
729  MF_LOG_WARNING("_process_RCE_AUX:") << "Nticks different for two channel streams: " << n_ticks
730  << " vs " << _tick_count_this_event << " Discarding Data";
731  error_counter++;
732  _discard_data = true;
733  _DiscardedCorruptData = true;
734  return false;
735  }
736  }
737  _KeptCorruptData = true;
738  }
739 
740 
741  //MF_LOG_INFO("_Process_RCE_AUX")
742  //<< "RceFragment timestamp: " << rce_stream->getTimeStamp()
743  //<< ", NChannels: " << n_ch
744  //<< ", NTicks: " << n_ticks;
745 
746  // TODO -- speed this up!! Remove one buffer copy
747 
748  size_t buffer_size = n_ch * n_ticks;
749 
750  if (buffer_size > _rce_buffer_size_checklimit)
751  {
753  {
754  MF_LOG_WARNING("_process_RCE_AUX:") << "n_ch*nticks too large: " << n_ch << " * " << n_ticks << " = " <<
755  buffer_size << " larger than: " << _rce_buffer_size_checklimit << ". Discarding this fragment";
756  _DiscardedCorruptData = true;
757  return false;
758  }
759  else
760  {
761  _KeptCorruptData = true;
762  }
763  }
764 
765  if (_buffer.capacity() < buffer_size)
766  {
767  // MF_LOG_INFO("_process_RCE_AUX")
768  //<< "Increase buffer size from " << _buffer.capacity()
769  //<< " to " << buffer_size;
770 
771  _buffer.reserve(buffer_size);
772  }
773 
774  int16_t* adcs = _buffer.data();
775  bool sgmcdretcode = rce_stream->getMultiChannelData(adcs);
776  if (!sgmcdretcode)
777  {
779  {
780  MF_LOG_WARNING("_process_RCE_AUX:") << "getMutliChannelData returns error flag: "
781  << " c:s:f:ich: " << crateNumber << " " << slotNumber << " " << fiberNumber << " Discarding Data";
782  error_counter++;
783  _DiscardedCorruptData = true;
784  return false;
785  }
786  _KeptCorruptData = true;
787  }
788 
789  //std::cout << "RCE raw decoder trj -- adjusted slot and fibers after run 1332: " << crateNumber << " " << slotNumber << " " << fiberNumber << std::endl;
790 
791 
793  for (size_t i_ch = 0; i_ch < n_ch; i_ch++)
794  {
795  // hardcode crate number 1 so we don't get warning messages
796  unsigned int offlineChannel = channelMap->GetOfflineNumberFromDetectorElements(1, slotNumber, fiberNumber, i_ch, dune::IcebergChannelMapService::kRCE);
797 
798  v_adc.clear();
799 
800  for (size_t i_tick = 0; i_tick < n_ticks; i_tick++)
801  {
802  v_adc.push_back(adcs[i_tick]);
803  }
804  adcs += n_ticks;
805 
806  ch_counter++;
807 
808  if (offlineChannel < _duplicate_channel_checklist_size)
809  {
810  if (_duplicate_channel_checklist[offlineChannel])
811  {
812  if(_make_histograms)
813  {
815  }
816 
818  {
819  MF_LOG_WARNING("_process_RCE_AUX:") << "Duplicate Channel: " << offlineChannel
820  << " c:s:f:ich: " << crateNumber << " " << slotNumber << " " << fiberNumber << " " << i_ch << " Discarding Data";
821  error_counter++;
822  _discard_data = true;
823  _DiscardedCorruptData = true;
824  return false;
825  }
826  _KeptCorruptData = true;
827  }
828  _duplicate_channel_checklist[offlineChannel] = true;
829  }
830 
831  float median=0;
832  float sigma=0;
833  computeMedianSigma(v_adc,median,sigma);
834 
835  /// FEMB 302 IS crate 3, slot 3, fiber 2
836 
837  auto uncompressed_nticks = v_adc.size(); // can be different from n_ticks due to padding of FEMB 302
838 
840  if (_compress_Huffman)
841  {
842  cflag = raw::kHuffman;
843  raw::Compress(v_adc,cflag);
844  }
845  // here n_ticks is the uncompressed size as required by the constructor
846  raw::RawDigit raw_digit(offlineChannel, uncompressed_nticks, v_adc, cflag);
847  raw_digit.SetPedestal(median,sigma);
848  raw_digits.push_back(raw_digit);
849 
850  raw::RDTimeStamp rdtimestamp(rce_stream->getTimeStamp(),offlineChannel);
851  timestamps.push_back(rdtimestamp);
852 
853  //associate the raw digit and the timestamp data products
854  auto const rawdigitptr = rdpm(raw_digits.size()-1);
855  auto const rdtimestampptr = tspm(timestamps.size()-1);
856  tsassocs.addSingle(rawdigitptr,rdtimestampptr);
857  }
858  }
859 
860  return true;
861 }
862 
863 
864 bool IcebergTPCRawDecoder::_processFELIX(art::Event &evt, RawDigits& raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm)
865 {
866 
867  // TODO Use MF_LOG_DEBUG
868  //MF_LOG_INFO("_processFELIX") << "-------------------- FELIX RawDecoder -------------------";
869 
870  unsigned int n_felix_frags = 0;
871 
873  auto cont_frags = evt.getHandle<artdaq::Fragments>(itag3);
874 
875  bool have_data = false;
876  bool have_data_nc = false;
877 
878  uint32_t runNumber = evt.run();
879 
880  if (cont_frags)
881  {
882  have_data = true;
883 
884  //size of felix fragments into histogram
885  if(_make_histograms)
886  {
887  size_t felixbytes = 0;
888  for (auto const& cont : *cont_frags)
889  {
890  felixbytes = felixbytes + (cont.sizeBytes());
891  }
892  fFragSizeFELIX->Fill(felixbytes);
893  }
894 
895  for (auto const& cont : *cont_frags)
896  {
897  bool process_flag = true;
898  if (cont.sizeBytes() < _felix_frag_small_size)
899  {
901  {
902  MF_LOG_WARNING("_process_FELIX:") << " Small FELIX fragment size: " << cont.sizeBytes() << " Discarding Event on request.";
903  _discard_data = true;
904  _DiscardedCorruptData = true;
905  evt.removeCachedProduct(cont_frags);
906  return false;
907  }
909  {
910  MF_LOG_WARNING("_process_FELIX:") << " Small FELIX fragment size: " << cont.sizeBytes() << " Discarding just this fragment on request.";
911  _DiscardedCorruptData = true;
912  process_flag = false;
913  }
914  _KeptCorruptData = true;
915  }
916  if (process_flag)
917  {
918  artdaq::ContainerFragment cont_frag(cont);
919  for (size_t ii = 0; ii < cont_frag.block_count(); ++ii)
920  {
921  if (_process_FELIX_AUX(*cont_frag[ii], raw_digits, timestamps, tsassocs, rdpm, tspm, runNumber)) ++n_felix_frags;
922  }
923  }
924  }
925  evt.removeCachedProduct(cont_frags);
926  }
927 
928  // noncontainer frags
929 
931  auto frags = evt.getHandle<artdaq::Fragments>(itag4);
932 
933  if (frags)
934  {
935 
936  if(_make_histograms)
937  {
938  size_t felixbytes = 0;
939  for (auto const& frag: *frags)
940  {
941  felixbytes = felixbytes + (frag.sizeBytes());
942  }
943  fFragSizeFELIX->Fill(felixbytes);
944  }
945 
946  for(auto const& frag: *frags)
947  {
948  bool process_flag = true;
949  if (frag.sizeBytes() < _felix_frag_small_size)
950  {
952  {
953  MF_LOG_WARNING("_process_FELIX:") << " Small FELIX fragment size: " << frag.sizeBytes() << " Discarding Event on request.";
954  _discard_data = true;
955  _DiscardedCorruptData = true;
956  evt.removeCachedProduct(frags);
957  return false;
958  }
960  {
961  MF_LOG_WARNING("_process_FELIX:") << " Small FELIX fragment size: " << frag.sizeBytes() << " Discarding just this fragment on request.";
962  _DiscardedCorruptData = true;
963  process_flag = false;
964  }
965  _KeptCorruptData = true;
966  }
967  if (process_flag)
968  {
969  if (_process_FELIX_AUX(frag, raw_digits,timestamps, tsassocs, rdpm, tspm, runNumber)) ++n_felix_frags;
970  }
971  }
972  evt.removeCachedProduct(frags);
973  }
974 
975 
976  //MF_LOG_INFO("_processFELIX")
977  //<< " Processed " << n_felix_frags
978  //<< " FELIX Fragments, total size of raw digits is now "
979  //<< raw_digits.size()
980  //<< " RawDigits.";
981 
982  return have_data || have_data_nc;
983 }
984 
985 bool IcebergTPCRawDecoder::_process_FELIX_AUX(const artdaq::Fragment& frag, RawDigits& raw_digits,
986  RDTimeStamps &timestamps,
987  RDTsAssocs &tsassocs,
988  RDPmkr &rdpm, TSPmkr &tspm,
989  uint32_t runNumber)
990 {
991 
992  //std::cout
993  //<< " SequenceID = " << frag.sequenceID()
994  //<< " fragmentID = " << frag.fragmentID()
995  //<< " fragmentType = " << (unsigned)frag.type()
996  //<< " Timestamp = " << frag.timestamp() << std::endl;
997 
998  if (_felix_hex_dump)
999  {
1000  std::ios oldState(nullptr);
1001  oldState.copyfmt(std::cout);
1002 
1003  std::cout << "FELIX Fragment: all numbers in hex " << std::hex
1004  << " SequenceID = " << frag.sequenceID()
1005  << " fragmentID = " << frag.fragmentID()
1006  << " fragmentType = " << (unsigned)frag.type()
1007  << " Timestamp = " << frag.timestamp() << std::endl;
1008  std::cout << "Offset Data";
1009  artdaq::Fragment fragloc(frag);
1010  unsigned char *dbegin = reinterpret_cast<unsigned char *>(fragloc.dataAddress());
1011  size_t dsize = fragloc.dataSizeBytes();
1012  size_t offcounter=0;
1013  for (size_t bcounter=0; bcounter<dsize;++bcounter)
1014  {
1015  if ( (offcounter % 8) == 0 )
1016  {
1017  std::cout << std::endl << std::hex << std::setfill('0') << std::setw(8) << offcounter << " ";
1018  }
1019  std::cout << std::hex << std::setfill('0') << std::setw(2) << (int) *dbegin << " ";
1020  dbegin++;
1021  offcounter++;
1022  }
1023  std::cout << std::endl;
1024  std::cout.copyfmt(oldState);
1025  }
1026 
1027  // check against _felix_fragment_type
1028  if(frag.type() != _felix_fragment_type)
1029  {
1030  _DiscardedCorruptData = true;
1031  MF_LOG_WARNING("_process_FELIX_AUX:") << " FELIX fragment type " << (int) frag.type() << " doesn't match expected value: " << _felix_fragment_type << " Discarding FELIX fragment";
1032  return false;
1033  }
1034  //if (frag.fragmentID() == 501)
1035  // {
1036  // std::cout << "Temporary hack: discarding fragment ID 501" << std::endl;
1037  // return false;
1038  // }
1039 
1041 
1042  //Load overlay class.
1043 
1044  bool is14 = _felix_input_noncontainer_instance == "FRAME14" || _felix_input_container_instance == "FRAME14";
1045  std::unique_ptr<dune::FelixFragment> felixptr;
1046  std::unique_ptr<dune::Frame14FragmentUnordered> frame14ptr;
1047  if (is14)
1048  {
1049  std::unique_ptr<dune::Frame14FragmentUnordered> ftmp(new dune::Frame14FragmentUnordered(frag));
1050  frame14ptr = std::move(ftmp);
1051  }
1052  else
1053  {
1054  std::unique_ptr<dune::FelixFragment> ftmp(new dune::FelixFragment(frag));
1055  felixptr = std::move(ftmp);
1056  }
1057 
1058  //Get detector element numbers from the fragment
1059 
1060  uint8_t crate = 0;
1061  uint8_t slot = 0;
1062  uint8_t fiber = 0;
1063 
1064  if (is14)
1065  {
1066  crate = frame14ptr->crate_no(0);
1067  slot = frame14ptr->slot_no(0);
1068  fiber = frame14ptr->fiber_no(0); // decode this one later
1069  int frame_version = frame14ptr->frame_version(0);
1070  //std::cout << "ICEBERG frame_version, crate, slot, fiber, fragID: " << frame_version << " "
1071  // << (int) crate << " " << (int) slot << " " << (int) fiber << " " << (int) frag.fragmentID() << std::endl;
1072  if (frame_version == 0)
1073  {
1074  std::cout << "ICEBERG frame_version = 0; skipping this fragment" << std::endl;
1075  return false;
1076  }
1077  fiber ++; // read in 0 to 1, go from 1 to 2
1078 
1079  // temporary hacks
1080  crate = 1;
1081  //int fragid = (int) frag.fragmentID();
1082  // if (fragid == 600)
1083  // {
1084  // slot = 0;
1085  // fiber = 1;
1086  // }
1087  // if (fragid == 601)
1088  // {
1089  // slot = 0;
1090  // fiber = 2;
1091  // }
1092  // if (fragid == 700)
1093  // {
1094  // slot = 2;
1095  // fiber = 1;
1096  // }
1097  // if (fragid == 701)
1098  // {
1099  // slot = 2;
1100  // fiber = 2;
1101  // }
1102  // if (fragid == 800)
1103  // {
1104  // slot = 1;
1105  // fiber = 1;
1106  // }
1107  // if (fragid == 801)
1108  // {
1109  // slot = 1;
1110  // fiber = 2;
1111  // }
1112 
1113  }
1114  else
1115  {
1116  crate = felixptr->crate_no(0);
1117  slot = felixptr->slot_no(0);
1118  fiber = felixptr->fiber_no(0); // decode this one later
1119  }
1120 
1121  if (crate == 0 || crate > 6 || slot > 4)
1122  {
1123  if (_felix_drop_frags_with_badcsf) // we'll check the fiber later
1124  {
1125  _DiscardedCorruptData = true;
1126  MF_LOG_WARNING("_process_FELIX_AUX:") << "Invalid crate or slot: c=" << (int) crate << " s=" << (int) slot << " discarding FELIX data.";
1127  return false;
1128  }
1129  _KeptCorruptData = true;
1130  }
1131  if ( _felix_crate_number_to_check > -1 && (int) crate != _felix_crate_number_to_check )
1132  {
1134  {
1135  _DiscardedCorruptData = true;
1136  MF_LOG_WARNING("_process_FELIX_AUX:") << "Crate c=" << (int) crate << " mismatches required crate: " << _felix_crate_number_to_check << " discarding FELIX data.";
1137  return false;
1138  }
1139  _KeptCorruptData = true;
1140  }
1141 
1143  {
1144  size_t first_coldata_convert_count = 0;
1145  if (is14)
1146  {
1147  first_coldata_convert_count = felixptr->coldata_convert_count(0,0);
1148  }
1149  else
1150  {
1151  first_coldata_convert_count = frame14ptr->total_frames();
1152  }
1153  std::cout << "FELIX Coldata convert count: " << (int) first_coldata_convert_count << std::endl;
1154  }
1155 
1156  //std::cout << "FELIX raw decoder crate, slot, fiber: " << (int) crate << " " << (int) slot << " " << (int) fiber << std::endl;
1157  // One frame contains 25 felix (20 ns-long) ticks. A "frame" is an offline tick
1158  unsigned n_frames = 0;
1159  if (is14)
1160  {
1161  n_frames = frame14ptr->total_frames();
1162  }
1163  else
1164  {
1165  n_frames = felixptr->total_frames();
1166  }
1167 
1168  //std::cout<<" Nframes = "<<n_frames<<std::endl;
1169  //_h_nframes->Fill(n_frames);
1170  const unsigned n_channels = dune::FelixFrame::num_ch_per_frame;// should be 256
1171 
1172  if (n_frames*n_channels > _felix_buffer_size_checklimit)
1173  {
1175  {
1176  MF_LOG_WARNING("_process_FELIX_AUX:") << "n_channels*n_frames too large: " << n_channels << " * " << n_frames << " = " <<
1177  n_frames*n_channels << " larger than: " << _felix_buffer_size_checklimit << ". Discarding this fragment";
1178  _DiscardedCorruptData = true;
1179  return false;
1180  }
1181  else
1182  {
1183  _KeptCorruptData = true;
1184  }
1185  }
1186 
1187  if(_make_histograms)
1188  {
1189  felixchans=felixchans+n_channels;
1190  }
1191 
1192  // this test does not yet exist for Frame14
1193 
1194  if (!is14)
1195  {
1196  for (unsigned int iframe=0; iframe<n_frames; ++iframe)
1197  {
1198  if ( felixptr->wib_errors(iframe) != 0)
1199  {
1200  if (_enforce_error_free )
1201  {
1202  _DiscardedCorruptData = true;
1203  MF_LOG_WARNING("_process_FELIX_AUX:") << "WIB Errors on frame: " << iframe << " : " << felixptr->wib_errors(iframe)
1204  << " Discarding Data";
1205  error_counter++;
1206  // drop just this fragment
1207  //_discard_data = true;
1208  return true;
1209  }
1210  _KeptCorruptData = true;
1211  }
1212  }
1213  }
1214 
1215  // check optimization of this -- size not reserved
1216 
1218  //v_adc.reserve(n_frames*n_channels);
1219  // Fill the adc vector.
1220 
1221  for(unsigned ch = 0; ch < n_channels; ++ch) {
1222  v_adc.clear();
1223  //std::cout<<"crate:slot:fiber = "<<crate<<", "<<slot<<", "<<fiber<<std::endl;
1224  std::vector<dune::adc_t> waveform( is14 ?
1225  frame14ptr->get_ADCs_by_channel(ch) :
1226  felixptr->get_ADCs_by_channel(ch) );
1227  for(unsigned int nframe=0;nframe<waveform.size();nframe++){
1228  // if(ch==0 && nframe<100) {
1229  // if(nframe==0) std::cout<<"Print the first 100 ADCs of Channel#1"<<std::endl;
1230  // std::cout<<waveform.at(nframe)<<" ";
1231  // if(nframe==99) std::cout<<std::endl;
1232  // }
1233  v_adc.push_back(waveform.at(nframe));
1234  }
1235 
1236  // handle 256 channels on two fibers -- use the channel map that assumes 128 chans per fiber (=FEMB)
1237 
1238  unsigned int fiberloc = 0;
1239  if (fiber == 1)
1240  {
1241  fiberloc = 1;
1242  }
1243  else if (fiber == 2)
1244  {
1245  fiberloc = 3;
1246  }
1247  else
1248  {
1249  MF_LOG_WARNING("_process_FELIX_AUX:") << " Fiber number " << (int) fiber << " is expected to be 1 or 2 -- revisit logic";
1250  fiberloc = 1;
1251  error_counter++;
1253  {
1254  MF_LOG_WARNING("_process_FELIX_AUX:") << " Dropping FELIX Data";
1255  return false;
1256  }
1257  }
1258 
1259  unsigned int chloc = ch;
1260  if (chloc > 127)
1261  {
1262  chloc -= 128;
1263  fiberloc++;
1264  }
1265  //unsigned int crateloc = crate;
1266 
1267  // conversion of Run 7 slot and fibers to Run 5
1268 
1269  if (runNumber > 9745)
1270  {
1271  auto slotloc3 = slot;
1272  auto fiberloc3 = fiberloc;
1273 
1274  // conversion map
1275  // run 7 slot, run 7 fiber, run 5 slot, run 5 fiber
1276  unsigned int sfmap[10][4] =
1277  {
1278  {4, 1, 0, 4},
1279  {3, 4, 1, 4},
1280  {3, 3, 2, 4},
1281  {3, 2, 0, 3},
1282  {3, 1, 1, 3},
1283  {0, 1, 0, 1},
1284  {0, 2, 2, 2},
1285  {0, 3, 1, 2},
1286  {0, 4, 0, 2},
1287  {1, 1, 2, 3}
1288  };
1289  bool found = false;
1290  for (size_t imap = 0; imap<10; ++imap)
1291  {
1292  if (slot == sfmap[imap][0] && fiberloc == sfmap[imap][1])
1293  {
1294  slotloc3 = sfmap[imap][2];
1295  fiberloc3 = sfmap[imap][3];
1296  found = true;
1297  break;
1298  }
1299  if (!found)
1300  {
1301  std::cout << "Slot, fiber not understood in mapping from Run 7 to Run 5: " << (int) slot << " " << (int) fiberloc << std::endl;
1302  slotloc3 = 0;
1303  fiberloc3 = 4;
1304  }
1305  }
1306  slot = slotloc3;
1307  fiberloc = fiberloc3;
1308  }
1309 
1310  // inverted ordering on back side, Run 2c (=Run 3)
1311  // note Shekhar's FEMB number is fiber-1, and WIB is slot+1
1312  // This goes up to run 5
1313 
1314  auto slotloc2 = slot;
1315  auto fiberloc2 = fiberloc;
1316 
1317  if (runNumber > 2572)
1318  {
1319 
1320  if (slot == 0 && fiberloc == 4)
1321  {
1322  slotloc2 = 1;
1323  fiberloc2 = 3;
1324  }
1325  if (slot == 1 && fiberloc == 4)
1326  {
1327  slotloc2 = 0;
1328  fiberloc2 = 3;
1329  }
1330  if (slot == 1 && fiberloc == 3)
1331  {
1332  slotloc2 = 0;
1333  fiberloc2 = 4;
1334  }
1335  if (slot == 0 && fiberloc == 3)
1336  {
1337  slotloc2 = 1;
1338  fiberloc2 = 4;
1339  }
1340  }
1341 
1342  // skip the fake TPC data
1343 
1344  if ( slotloc2 == 1 && fiberloc2 == 1 )
1345  {
1346  continue;
1347  }
1348 
1349  if ( slotloc2 == 2 && fiberloc2 == 1 )
1350  {
1351  continue;
1352  }
1353 
1354  // for iceberg, hardcode the crate number to suppress warnings
1355  unsigned int offlineChannel = channelMap->GetOfflineNumberFromDetectorElements(1, slotloc2, fiberloc2, chloc, dune::IcebergChannelMapService::kFELIX);
1356 
1357  //std::cout << "Calling channel map: " << (int) slotloc2 << " " << fiberloc2 << " " << chloc << " " << offlineChannel << std::endl;
1358 
1359  if ( v_adc.size() != _full_tick_count)
1360  {
1362  {
1363  MF_LOG_WARNING("_process_FELIX_AUX:") << "Nticks not the required value: " << v_adc.size() << " "
1364  << _full_tick_count << " Discarding Data";
1365  error_counter++;
1366  incorrect_ticks++;
1367  _discard_data = true;
1368  _DiscardedCorruptData = true;
1369  return true;
1370  }
1371  _KeptCorruptData = true;
1372  }
1373 
1375  {
1377  _tick_count_this_event = v_adc.size();
1378  }
1379  else
1380  {
1382  {
1383  if (v_adc.size() != _tick_count_this_event)
1384  {
1385  MF_LOG_WARNING("_process_FELIX_AUX:") << "Nticks different for two channel streams: " << v_adc.size()
1386  << " vs " << _tick_count_this_event << " Discarding Data";
1387  error_counter++;
1388  _discard_data = true;
1389  _DiscardedCorruptData = true;
1390  return true;
1391  }
1392  _KeptCorruptData = true;
1393  }
1394  }
1395 
1396  if (offlineChannel < _duplicate_channel_checklist_size)
1397  {
1398  if (_duplicate_channel_checklist[offlineChannel])
1399  {
1400  if(_make_histograms)
1401  {
1403  }
1405  {
1406  MF_LOG_WARNING("_process_FELIX_AUX:") << "Duplicate Channel: " << offlineChannel
1407  << " c:s:f:ich: " << (int) crate << " " << (int) slot << " " << (int) fiber << " " << (int) ch << " Discarding Data";
1408  error_counter++;
1409  _discard_data = true;
1410  _DiscardedCorruptData = true;
1411  return true;
1412  }
1413  _KeptCorruptData = true;
1414  }
1415  _duplicate_channel_checklist[offlineChannel] = true;
1416  }
1417 
1418  float median=0;
1419  float sigma=0;
1420  computeMedianSigma(v_adc,median,sigma);
1421 
1422  auto n_ticks = v_adc.size();
1424  if (_compress_Huffman)
1425  {
1426  cflag = raw::kHuffman;
1427  raw::Compress(v_adc,cflag);
1428  }
1429  // here n_ticks is the uncompressed size as required by the constructor
1430  raw::RawDigit raw_digit(offlineChannel, n_ticks, v_adc, cflag);
1431  raw_digit.SetPedestal(median,sigma);
1432  raw_digits.push_back(raw_digit);
1433 
1434  raw::RDTimeStamp rdtimestamp( is14 ? frame14ptr->timestamp() : felixptr->timestamp(),offlineChannel);
1435  timestamps.push_back(rdtimestamp);
1436 
1437  if (_make_histograms)
1438  {
1439  uint64_t last_timestamp = (is14 ? frame14ptr->timestamp(0) : felixptr->timestamp(0));
1440  for (size_t itick=1; itick<n_ticks; ++itick)
1441  {
1442  uint64_t timestamp = (is14 ? frame14ptr->timestamp(itick) : felixptr->timestamp(itick));
1443  uint64_t tdiff = 0;
1444  if (timestamp > last_timestamp)
1445  {
1446  tdiff = timestamp - last_timestamp;
1447  }
1448  else
1449  {
1450  tdiff = last_timestamp - timestamp;
1451  }
1452  fDeltaTimestamp->Fill(tdiff);
1453  last_timestamp = timestamp;
1454  }
1455  }
1456 
1457  //associate the raw digit and the timestamp data products
1458  auto const rawdigitptr = rdpm(raw_digits.size()-1);
1459  auto const rdtimestampptr = tspm(timestamps.size()-1);
1460  tsassocs.addSingle(rawdigitptr,rdtimestampptr);
1461  }
1462 
1463 
1464  return true;
1465 }
1466 
1467 
1468 // compute median and sigma. Sigma is half the distance between the upper and lower bounds of the
1469 // 68% region where 34% is above the median and 34% is below ("centered" on the median).
1470 
1472 {
1473  size_t asiz = v_adc.size();
1474  if (asiz == 0)
1475  {
1476  median = 0;
1477  sigma = 0;
1478  }
1479  else
1480  {
1481  // this is actually faster than the code below by about one second per event.
1482  // the RMS includes tails from bad samples and signals and may not be the best RMS calc.
1483 
1484  median = TMath::Median(asiz,v_adc.data());
1485  sigma = TMath::RMS(asiz,v_adc.data());
1486  }
1487 
1488  // std::cout << "sigma: " << sigma << std::endl;
1489 }
1490 
static constexpr size_t num_ch_per_frame
Definition: FelixFormat.hh:298
Huffman Encoding.
Definition: RawTypes.h:10
IcebergTPCRawDecoder & operator=(IcebergTPCRawDecoder const &)=delete
size_t total_frames() const
enum raw::_compress Compress_t
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
TpcStreamUnpack const * get_stream(int i) const
Definition: RceFragment.cc:48
uint8_t slot_no(const unsigned &frame_ID=0) const
uint8_t slot_no(const unsigned &frame_ID=0) const
uint8_t fiber_no(const unsigned &frame_ID=0) const
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::string string
Definition: nybbler.cc:12
uint8_t crate_no(const unsigned &frame_ID=0) const
bool _processRCE(art::Event &evt, RawDigits &raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm)
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
void computeMedianSigma(raw::RawDigit::ADCvector_t &v_adc, float &median, float &sigma)
std::vector< short > ADCvector_t
Type representing a (compressed) vector of ADC counts.
Definition: RawDigit.h:73
QTextStream & hex(QTextStream &s)
art::PtrMaker< raw::RawDigit > RDPmkr
int size() const
Definition: RceFragment.hh:25
no compression
Definition: RawTypes.h:9
const unsigned int _duplicate_channel_checklist_size
void produce(art::Event &e) override
bool _process_FELIX_AUX(const artdaq::Fragment &frag, RawDigits &raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm, uint32_t runNumber)
art::Assns< raw::RawDigit, raw::RDTimeStamp > RDTsAssocs
unsigned int GetOfflineNumberFromDetectorElements(unsigned int crate, unsigned int slot, unsigned int fiber, unsigned int fembchannel, FelixOrRCE frswitch)
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
struct dune::tde::crate crate
bool _processFELIX(art::Event &evt, RawDigits &raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm)
def move(depos, offset)
Definition: depos.py:107
T get(std::string const &key) const
Definition: ParameterSet.h:271
uint64_t timestamp(const unsigned &frame_ID=0) const
IcebergTPCRawDecoder(fhicl::ParameterSet const &p)
p
Definition: test.py:223
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
RunNumber_t run() const
Definition: DataViewImpl.cc:71
uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const
bool removeCachedProduct(Handle< PROD > &) const
Definition: DataViewImpl.h:927
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
void save(const std::string &filepath) const
Definition: RceFragment.cc:63
uint8_t fiber_no(const unsigned &frame_ID=0) const
adc_v get_ADCs_by_channel(const uint8_t channel_ID) const
uint8_t frame_version(const unsigned &frame_ID=0) const
uint16_t wib_errors(const unsigned &frame_ID=0) const
std::vector< raw::RDTimeStamp > RDTimeStamps
uint8_t crate_no(const unsigned &frame_ID=0) const
bool _process_RCE_AUX(const artdaq::Fragment &frag, RawDigits &raw_digits, RDTimeStamps &timestamps, RDTsAssocs &tsassocs, RDPmkr &rdpm, TSPmkr &tspm, uint32_t runNumber)
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
void addSingle(Ptr< left_t > const &left, Ptr< right_t > const &right, data_t const &data)
Definition: Assns.h:546
static double tdiff(const art::Timestamp &ts1, const art::Timestamp &ts2)
adc_v get_ADCs_by_channel(const uint8_t block_ID, const uint8_t channel_ID) const
void Compress(std::vector< short > &adc, raw::Compress_t compress)
Compresses a raw data buffer.
Definition: raw.cxx:19
def access(path, mode)
TCEvent evt
Definition: DataStructs.cxx:7
#define MF_LOG_WARNING(category)
std::vector< int16_t > _buffer
Q_EXPORT QTSManip setfill(int f)
Definition: qtextstream.h:337
std::vector< Fragment > Fragments
Definition: HDF5Utils.h:57
std::vector< raw::RawDigit > RawDigits
double median(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:26
std::vector< raw::RDStatus > RDStatuses
QTextStream & endl(QTextStream &s)
art::PtrMaker< raw::RDTimeStamp > TSPmkr
uint64_t timestamp(const unsigned &frame_ID=0) const