BeamlineUnpack.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////
2 /// \file BeamlineUnpack.cxx
3 /// \brief Methods to interface with the DAQ-formatted output file
4 /// for the beamline components of the test beam experiment.
5 /// \author Mike Wallbank (University of Cincinnati) <wallbank@fnal.gov>
6 /// \date November 2018
7 ////////////////////////////////////////////////////////////////////////////
8 
10 
12 
13 // -----------------------------------------------------------------------
14 artdaq::Fragments* daq2raw::getFragments(TBranch* br, unsigned entry) {
15  br->GetEntry(entry);
16  return reinterpret_cast<artdaq::Fragments*>(br->GetAddress());
17 }
18 
19 // -----------------------------------------------------------------------
20 void daq2raw::SpillWrapper::add(const artdaq::Fragment& frag) {
21 
22  if (nfragments_processed_ == 0) {
23  // Basically, it's the LAST of the fragments which is the
24  // largest if the spill couldn't be evenly split into four
25  // fragments, so that's why we add the "+1" padding to the
26  // buffer
27  size_t bufsize = (frag.dataSize() + 1) * sizeof(artdaq::RawDataType) * nfragments_ ;
28  buffer_.resize( bufsize );
29  }
30 
31  memcpy( &*buffer_.begin() + size_, frag.dataBeginBytes(), frag.dataSizeBytes() );
32 
33  // Bookkeeping
34  size_ += frag.dataSizeBytes();
36 
37 }
38 
39 // -----------------------------------------------------------------------
41 
42  art::ValidHandle<artdaq::Fragments> raw = evt.getValidHandle<artdaq::Fragments>(tag);
43  if (raw->size() != 1)
44  throw cet::exception("SpillWrapper") << "Error in SpillWrapper::add(): expected 1 artdaq fragment in event, found "
45  << raw->size() << std::endl;
46 
47  this->add((*raw)[0]);
48  return;
49 
50 }
51 
52 // -----------------------------------------------------------------------
53 daq2raw::BeamlineEvent::BeamlineEvent(unsigned int eventNum) {
54  fEventNumber = eventNum;
55  this->SetGoodEvent();
56 }
57 
58 // -----------------------------------------------------------------------
60 }
61 
62 // -----------------------------------------------------------------------
64  return fEventNumber;
65 }
66 
67 // -----------------------------------------------------------------------
69  fConfig = config;
70  return;
71 }
72 
73 // -----------------------------------------------------------------------
75  fTimestamp = timestamp;
76  return;
77 }
78 
79 // -----------------------------------------------------------------------
80 void daq2raw::BeamlineEvent::AddTDUTime(uint64_t tduTime) {
81  fTDUTime = tduTime;
82  return;
83 }
84 
85 // -----------------------------------------------------------------------
86 void daq2raw::BeamlineEvent::AddTrigger(std::vector<rawdata::RawBeamlineTrigger> trigger) {
87  fTrigger = trigger;
88  return;
89 }
90 
91 // -----------------------------------------------------------------------
92 void daq2raw::BeamlineEvent::AddToF(std::vector<rawdata::RawBeamlineDigit> tof) {
93  fToF = tof;
94  return;
95 }
96 
97 // -----------------------------------------------------------------------
98 void daq2raw::BeamlineEvent::AddWC(std::vector<rawdata::RawBeamlineWC> wc) {
99  fWC = wc;
100  return;
101 }
102 
103 // -----------------------------------------------------------------------
104 void daq2raw::BeamlineEvent::AddCherenkov(std::vector<rawdata::RawBeamlineDigit> cherenkov) {
105  fCherenkov = cherenkov;
106  return;
107 }
108 
109 // -----------------------------------------------------------------------
110 void daq2raw::BeamlineEvent::AddMuonStack(std::vector<rawdata::RawBeamlineDigit> muonstack) {
111  fMuonStack = muonstack;
112  return;
113 }
114 
115 // -----------------------------------------------------------------------
116 void daq2raw::BeamlineEvent::AddPaddleDigit(std::vector<rawdata::RawBeamlineDigit> paddle) {
117  fPaddleDigit = paddle;
118  return;
119 }
120 
121 // -----------------------------------------------------------------------
122 void daq2raw::BeamlineEvent::AddWCDigit(std::vector<rawdata::RawBeamlineDigit> wc) {
123  fWCDigit = wc;
124  return;
125 }
126 
127 // -----------------------------------------------------------------------
128 void daq2raw::BeamlineEvent::AddOtherDigit(std::vector<rawdata::RawBeamlineDigit> other) {
129  fOtherDigit = other;
130  return;
131 }
132 
133 // -----------------------------------------------------------------------
135  return fGoodEvent;
136 }
137 
138 // -----------------------------------------------------------------------
140  fGoodEvent = true;
141  return;
142 }
143 
144 // -----------------------------------------------------------------------
146  fGoodEvent = false;
147  return;
148 }
149 
150 // -----------------------------------------------------------------------
152  return fConfig;
153 }
154 
155 // -----------------------------------------------------------------------
157  return fTimestamp;
158 }
159 
160 // -----------------------------------------------------------------------
162  return fTDUTime;
163 }
164 
165 // -----------------------------------------------------------------------
166 std::vector<rawdata::RawBeamlineTrigger> daq2raw::BeamlineEvent::GetTrigger() const {
167  return fTrigger;
168 }
169 
170 // -----------------------------------------------------------------------
171 std::vector<rawdata::RawBeamlineDigit> daq2raw::BeamlineEvent::GetToF() const {
172  return fToF;
173 }
174 
175 // -----------------------------------------------------------------------
176 std::vector<rawdata::RawBeamlineWC> daq2raw::BeamlineEvent::GetWC() const {
177  return fWC;
178 }
179 
180 // -----------------------------------------------------------------------
181 std::vector<rawdata::RawBeamlineDigit> daq2raw::BeamlineEvent::GetCherenkov() const {
182  return fCherenkov;
183 }
184 
185 // -----------------------------------------------------------------------
186 std::vector<rawdata::RawBeamlineDigit> daq2raw::BeamlineEvent::GetMuonStack() const {
187  return fMuonStack;
188 }
189 
190 // -----------------------------------------------------------------------
191 std::vector<rawdata::RawBeamlineDigit> daq2raw::BeamlineEvent::GetPaddleDigit() const {
192  return fPaddleDigit;
193 }
194 
195 // -----------------------------------------------------------------------
196 std::vector<rawdata::RawBeamlineDigit> daq2raw::BeamlineEvent::GetWCDigit() const {
197  return fWCDigit;
198 }
199 
200 // -----------------------------------------------------------------------
201 std::vector<rawdata::RawBeamlineDigit> daq2raw::BeamlineEvent::GetOtherDigit() const {
202  return fOtherDigit;
203 }
204 
205 // -----------------------------------------------------------------------
207  fEventIt = -1;
208 }
209 
210 // -----------------------------------------------------------------------
212  fEventIt = -1;
213  for (size_t eventIt = 0; eventIt < numEvents; ++eventIt)
214  fEvents.emplace_back(new BeamlineEvent(eventIt));
215 }
216 
217 // -----------------------------------------------------------------------
219  for (std::vector<BeamlineEvent*>::iterator eventIt = fEvents.begin();
220  eventIt != fEvents.end(); ++eventIt) {
221  if (*eventIt)
222  delete *eventIt;
223  *eventIt = nullptr;
224  }
225 }
226 
227 // -----------------------------------------------------------------------
229  fEvents.push_back(event);
230  fEvents_TDUIndex[event->GetTDUTime()] = event;
231  return;
232 }
233 
234 // -----------------------------------------------------------------------
235 void daq2raw::BeamlineEvents::AddEvents(std::vector<BeamlineEvent*> events) {
236  fEvents.insert(fEvents.end(), events.begin(), events.end());
237  return;
238 }
239 
240 // -----------------------------------------------------------------------
242  fEvents.erase(std::remove_if(fEvents.begin(),
243  fEvents.end(),
244  [](const BeamlineEvent* e) { return !e->GoodEvent(); }),
245  fEvents.end());
246  return;
247 }
248 
249 // -----------------------------------------------------------------------
251  if (eventNum >= fEvents.size())
252  throw cet::exception("BeamlineUnpack")
253  << "Requested event " << eventNum << " does not exist" << std::endl;
254  return fEvents[eventNum];
255 }
256 
257 // -----------------------------------------------------------------------
258 daq2raw::BeamlineEvent* daq2raw::BeamlineEvents::FindEvent(unsigned long long nova_timestamp) {
259  if (fEvents_TDUIndex.count(nova_timestamp))
260  return fEvents_TDUIndex[nova_timestamp];
261  else
262  mf::LogWarning("BeamlineEvents::FindEvent")
263  << "Requested event with timestamp " << nova_timestamp << " does not exist" << std::endl;
264  return nullptr;
265 }
266 
267 // -----------------------------------------------------------------------
269  return fEvents.size();
270 }
271 
272 // -----------------------------------------------------------------------
273 std::vector<daq2raw::BeamlineEvent*> daq2raw::BeamlineEvents::GetEvents() const {
274  return fEvents;
275 }
276 
277 // -----------------------------------------------------------------------
279  ++fEventIt;
280  if (fEventIt >= fEvents.size())
281  throw cet::exception("BeamlineUnpack")
282  << "Next requested event (" << fEventIt << ") does not exist." << std::endl;
283  return fEvents.at(fEventIt);
284 }
285 
286 // -----------------------------------------------------------------------
288  return fEventIt+1 < fEvents.size();
289 }
290 
291 // -----------------------------------------------------------------------
293  fBeamlineEvents(nullptr) {
294  this->reconfigure(pset);
295 }
296 
297 // -----------------------------------------------------------------------
299  this->EndSpill();
300 }
301 
302 // -----------------------------------------------------------------------
304  fTriggerSource = pset.get<std::string>("TriggerSource", "Trigger");
305  fUnpackTrigger = pset.get<bool>("UnpackTrigger", true);
306  fUnpackDigitizer = pset.get<bool>("UnpackDigitizer", true);
307  fUnpackWireChamber = pset.get<bool>("UnpackWireChamber", true);
308  fUnpackTDU = pset.get<bool>("UnpackTDU", true);
309 
310  fChannelsPerTDC = pset.get<unsigned int>("ChannelsPerTDC", 64);
311  fTDCsPerWC = pset.get<unsigned int>("TDCsPerWC", 2);
312 
313  fTriggerLatency = pset.get<unsigned int>("TriggerLatency", 0);
314  fTDUOffset = pset.get<int> ("TDUOffset", 0);
315 }
316 
317 // -----------------------------------------------------------------------
318 std::vector<TriggerPattern::TriggerPattern_t>
319 daq2raw::BeamlineUnpack::CleanTriggers(const TriggerFragment& triggerFrag) {
320 
321  // filter triggers saved by the trigger
322  // board to remove any which occured directly
323  // after the previous one
324  std::vector<TriggerPattern::TriggerPattern_t> beamlineTriggers;
325 
326  uint32_t prevT = 0;
327  for (size_t trigIt = 0; trigIt < triggerFrag.triggerFragment.nEntries; ++trigIt) {
328 
329  TriggerPattern::TriggerPattern_t pattern =
330  triggerFrag.triggerFragment.patterns[trigIt];
331 
332  if (pattern.timeStamp - prevT > fTriggerLatency)
333  beamlineTriggers.push_back(pattern);
334 
335  prevT = pattern.timeStamp;
336 
337  }
338 
339  return beamlineTriggers;
340 
341 }
342 
343 // -----------------------------------------------------------------------
344 std::vector<TDUFragment*>
345 daq2raw::BeamlineUnpack::CleanTDU(const std::vector<TDUFragment*>& tduFrags) {
346 
347  // filter just beamline triggers from
348  // the TDU timestamps
349  std::vector<TDUFragment*> beamlineTDUs;
350 
351  // also remove duplicated timestamps
352  std::vector<uint64_t> prevTs;
353 
354  for (std::vector<TDUFragment*>::const_iterator tduFragIt = tduFrags.begin();
355  tduFragIt != tduFrags.end(); ++tduFragIt) {
356 
357  const TDUFragment::TDUFragment_t& tduFrag = (*tduFragIt)->tduFragment[0];
358 
359  if (tduFrag.type == 1 and
360  std::find(prevTs.begin(), prevTs.end(), tduFrag.timestamp) == prevTs.end()) {
361  beamlineTDUs.push_back(*tduFragIt);
362  prevTs.push_back(tduFrag.timestamp);
363  }
364 
365  }
366 
367  return beamlineTDUs;
368 
369 }
370 
371 // -----------------------------------------------------------------------
373  if (fBeamlineEvents)
374  delete fBeamlineEvents;
375  fBeamlineEvents = nullptr;
376 }
377 
378 // -----------------------------------------------------------------------
380  return fBeamlineEvents;
381 }
382 
383 // -----------------------------------------------------------------------
384 void daq2raw::BeamlineUnpack::Unpack(const LariatFragment* spillFrag,
385  const std::vector<TDUFragment*> tduFrags,
386  unsigned int run,
388 
389  // get trigger information
390  const TriggerFragment triggerFrag = spillFrag->triggerFragment;
391 
392  // get digits
393  const std::vector<V1742Fragment> v1742Frags = spillFrag->v1742Frags;
394 
395  // get wire chambers
396  TDCFragment tdcFrag;
397  if (fUnpackWireChamber and spillFrag->tdcFrags.size())
398  tdcFrag = spillFrag->tdcFrags[0];
399 
400  mf::LogVerbatim("BeamlineUnpack::Unpack")
401  << "There are " << triggerFrag.triggerFragment.nEntries << " triggers, "
402  << v1742Frags.size() << " digitizer triggers, "
403  << tdcFrag.tdcEvents.size() << " wire chamber triggers and "
404  << tduFrags.size() << " TDU timestamps." << std::endl;
405 
406  // clean up various fragments of data
407  std::vector<TriggerPattern::TriggerPattern_t> triggers_clean
408  = CleanTriggers(triggerFrag);
409  std::vector<TDUFragment*> tdu_clean = CleanTDU(tduFrags);
410 
411  mf::LogVerbatim("BeamlineUnpack::Unpack")
412  << "After cleaning, there are " << triggers_clean.size() << " triggers, "
413  << v1742Frags.size() << " digitizer triggers, "
414  << tdcFrag.tdcEvents.size() << " wire chamber triggers and "
415  << tdu_clean.size() << " TDU timestamps." << std::endl;
416 
417  // for testing and commissioning, we may have variable numbers of triggers
418  // in each component.
419  // deal with all possibilities
420  unsigned int numTriggers = 0;
421  if (fTriggerSource == "Trigger")
422  numTriggers = triggers_clean.size();
423  else if (fTriggerSource == "Digitizer")
424  numTriggers = v1742Frags.size();
425  else if (fTriggerSource == "WireChamber")
426  numTriggers = tdcFrag.tdcEvents.size();
427  else if (fTriggerSource == "TDU")
428  numTriggers = tdu_clean.size();
429 
430  // strictly enforce the correct number of fragments for each of the
431  // front-end data components we are trying to unpack
432  if ((fUnpackTrigger and triggers_clean.size() != numTriggers) or
433  (fUnpackDigitizer and v1742Frags.size() != numTriggers) or
434  (fUnpackWireChamber and tdcFrag.tdcEvents.size() != numTriggers) or
435  (fUnpackTDU and tdu_clean.size() != numTriggers))
436  throw cet::exception("BeamlineUnpack")
437  << "Inconsistent number of data fragments: "
438  << "Triggers: " << triggers_clean.size() << "; "
439  << "Digitizer: " << v1742Frags.size() << "; "
440  << "Wire Chambers: " << tdcFrag.tdcEvents.size() << "; "
441  << "TDU: " << tdu_clean.size() << "."
442  << std::endl;
443 
444  // make a new BeamlineEvents object to contain the information
445  fBeamlineEvents = new BeamlineEvents(numTriggers);
446 
447  // get the spill information
448  //LariatFragment::SpillTrailer spillFrag = frag->spillTrailer;
449 
450  // unpack everything
451  this->UnpackConfig(run);
452  if (fUnpackTrigger or fUnpackTDU)
453  this->UnpackTrigger(triggers_clean, tdu_clean, filename);
454  if (fUnpackDigitizer)
455  this->UnpackDigits(v1742Frags);
456  if (fUnpackWireChamber)
457  this->UnpackWC(tdcFrag);
458 
459  return;
460 
461 }
462 
463 // -----------------------------------------------------------------------
465 
467 
468  // beamline run
469  config.SetBeamlineRun(run);
470 
471  // magnetic field
472  float b_field = 0.;
473  try {
474  b_field = fMagneticField->MagneticField(run);
475  }
476  catch (cet::exception& e) {
477  e.what();
478  }
479  config.SetBField(b_field);
480 
481  for (unsigned int event = 0; event < fBeamlineEvents->NumEvents(); ++event)
482  fBeamlineEvents->FindEvent(event)->AddConfig(config);
483 
484  return;
485 
486 }
487 
488 // -----------------------------------------------------------------------
489 void daq2raw::BeamlineUnpack::UnpackTrigger(const std::vector<TriggerPattern::TriggerPattern_t>& beamlineTriggers,
490  const std::vector<TDUFragment*>& beamlineTDUs,
492 
493  // get number of triggers
494  unsigned int numTrigs = fUnpackTDU ?
495  beamlineTDUs.size() : beamlineTriggers.size();
496 
497  // get metadata, containing other information about the trigger
499  if (!filename.empty()) {
500  char* fullpathname = (char*)filename.c_str();
501  std::string relfilename = std::string(basename(fullpathname));
503  try {
504  metadata = ifdhp->getMetadata(relfilename);
505  }
506  catch (WebAPIException) {
507  metadata = "";
508  }
509  }
510 
511  // get trigger condition for this file
512  std::string trigger_condition = "";
513  std::istringstream metadataStream;
514  metadataStream.str(metadata);
515  while (metadataStream.good()) {
517  std::getline(metadataStream, line);
518  size_t pos = line.find(":");
519  if (pos != std::string::npos) {
520  key = line.substr(0, pos);
521  value = line.substr(pos+1);
522  if (key.find("Beamline.BeamlineTrigger") != std::string::npos) {
523  value.erase(std::remove(value.begin(), value.end(), ' '), value.end());
524  trigger_condition = value;
525  }
526  }
527  }
528 
529  // make new RawBeamlineTriggers
530  for (unsigned int triggerIt = 0; triggerIt < numTrigs; ++triggerIt) {
531 
532  // get timestamps
533  uint64_t timestamp =
534  fUnpackTrigger? static_cast<uint64_t>(beamlineTriggers[triggerIt].timeStamp) : 0;
535  long double timestamp_ns = timestamp * 10; //ns
536 
537  // get tdu timestamp
538  uint64_t tduTime = fUnpackTDU? (beamlineTDUs[triggerIt]->tduFragment.at(0).timestamp + fTDUOffset) : 0;
539 
540  // make trigger object
542  triggerIt);
543  trigger.SetTimestamp(timestamp_ns);
544  trigger.SetPattern(fUnpackTrigger? beamlineTriggers[triggerIt].inputPattern : 0);
545  trigger.SetTDUTime(tduTime);
546  trigger.SetTriggerCondition(trigger_condition);
547  std::vector<rawdata::RawBeamlineTrigger> triggers = {trigger};
548 
549  // add to event
550  fBeamlineEvents->FindEvent(triggerIt)->AddTrigger(triggers);
551  fBeamlineEvents->FindEvent(triggerIt)->AddTimestamp(timestamp_ns);
552  fBeamlineEvents->FindEvent(triggerIt)->AddTDUTime(tduTime);
553 
554  }
555 
556  return;
557 
558 }
559 
560 // -----------------------------------------------------------------------
561 void daq2raw::BeamlineUnpack::UnpackDigits(const std::vector<V1742Fragment>& frags) {
562 
563  // Look through all triggers
564  for (unsigned int v1742FragIt = 0; v1742FragIt < frags.size(); ++v1742FragIt) {
565 
566  const V1742Fragment& v1742Frag = frags[v1742FragIt];
567 
568  std::vector<rawdata::RawBeamlineDigit> cherenkovDigits, tofDigits,
569  muonStackDigits, paddleDigits, wcDigits, otherDigits;
570 
571  // Get all channels for this V1742 fragment
572  for (unsigned int waveform = 0; waveform < v1742Frag.waveForms.size(); ++waveform) {
573 
574  if (!fChannelMap->ActiveDigitChannel(waveform))
575  continue;
576 
577  uint64_t timestamp
578  = static_cast<uint64_t>(v1742Frag.triggerTimeStamps[static_cast<int>(waveform/8)]); // timestamps are saved per group
579  long double timestamp_ns = static_cast<long double>(timestamp) * 8.5; //ns
580 
582  digit.SetWaveform(v1742Frag.waveForms[waveform].data);
583  digit.SetTimestamp(timestamp_ns);
584 
585  switch (digit.ChannelID().System) {
587  cherenkovDigits.push_back(digit); break;
589  tofDigits.push_back(digit); break;
591  muonStackDigits.push_back(digit); break;
593  paddleDigits.push_back(digit); break;
595  wcDigits.push_back(digit); break;
597  otherDigits.push_back(digit); break;
598  default:
599  break;
600  }
601 
602  }
603 
604  fBeamlineEvents->FindEvent(v1742FragIt)->AddToF(tofDigits);
605  fBeamlineEvents->FindEvent(v1742FragIt)->AddCherenkov(cherenkovDigits);
606  fBeamlineEvents->FindEvent(v1742FragIt)->AddMuonStack(muonStackDigits);
607  fBeamlineEvents->FindEvent(v1742FragIt)->AddPaddleDigit(paddleDigits);
608  fBeamlineEvents->FindEvent(v1742FragIt)->AddWCDigit(wcDigits);
609  fBeamlineEvents->FindEvent(v1742FragIt)->AddOtherDigit(otherDigits);
610 
611  }
612 
613  return;
614 
615 }
616 
617 // -----------------------------------------------------------------------
618 void daq2raw::BeamlineUnpack::UnpackWC(const TDCFragment& frag) {
619 
620  // loop over events
621  unsigned int event = 0;
622  std::vector<std::vector<TDCFragment::TdcEventData> > tdcEvents = frag.tdcEvents;
623  for (std::vector<std::vector<TDCFragment::TdcEventData> >::const_iterator tdcEventIt = tdcEvents.begin();
624  tdcEventIt != tdcEvents.end(); ++tdcEventIt, ++event) {
625 
626  std::vector<rawdata::RawBeamlineWC> wcs(fGeometry->NumWCs());
627  for (unsigned int wc_num = 0; wc_num < wcs.size(); ++wc_num)
628  wcs[wc_num] = rawdata::RawBeamlineWC(fChannelMap->WCDetector(wc_num));
629 
630  // get the timestamp for this event
631  // Non-trivial!
632  // See https://cdcvs.fnal.gov/redmine/attachments/51083/TDC_Format_Description_B.pdf for a full description
633  // Each TDC header has a 'controller timestamp' (16 bit, 1.18 ns ticks) and 'tdc timestamp' (32 bit, 9.4 ns ticks)
634  // --> I _believe_ they should be the same for each TDC in the event (so enforce this)
635  // The bits 11..3 for the controller timestamp should be identical to bits 8..0 in the TDC timestamp
636  // In order to construct the full timestamp, need to concatenate the 3 lsbs from the controller timestamp
637  // to the TDC timestamp to make a 35 bit word. This is a timestamp in 1.18 ns ticks since the start of the spill
638  std::map<unsigned int, uint16_t> controllerTimestamps;
639  std::map<unsigned int, uint32_t> tdcTimestamps;
640 
641  // loop over TDCs in this event
642  for (std::vector<TDCFragment::TdcEventData>::const_iterator tdcIt = tdcEventIt->begin(); tdcIt != tdcEventIt->end(); ++tdcIt) {
643 
644  unsigned int tdcNumber = (int)tdcIt->tdcEventHeader.tdcNumber - 1;
645  unsigned int wcNumber = tdcNumber / fGeometry->NumWCs();
646  unsigned int tdc_on_wc = tdcNumber % fGeometry->NumWCs();
647  unsigned int tdc_on_plane = tdc_on_wc % fTDCsPerWC;
648  unsigned int plane_on_wc = tdc_on_wc / fTDCsPerWC;
649 
650  // timestamps
651  controllerTimestamps[tdcNumber] = tdcIt->tdcEventHeader.controllerTimeStamp;
652  tdcTimestamps[tdcNumber] = tdcIt->tdcEventHeader.tdcTimeStamp;
653 
654  // overflow register, one for each TDC so if any are set then the whole WC gets true
655  if (tdcIt->tdcEventHeader.eventStatus != 0)
657 
658  // loop over hits in this TDC
659  for (std::vector<TDCFragment::TdcHit>::const_iterator hitIt = tdcIt->tdcHits.begin(); hitIt != tdcIt->tdcHits.end(); ++hitIt) {
660  unsigned int channel_on_plane = (tdc_on_plane * fChannelsPerTDC) + (int)hitIt->channel;
661  rawdata::RawBeamlineWC::WCPulse pulse(channel_on_plane, hitIt->timeBin);
662  plane_on_wc ? wcs[wcNumber].AddYPulse(pulse) : wcs[wcNumber].AddXPulse(pulse);
663  }
664 
665  }
666 
667  // form total timestamp for event relative to start of spill
668  for (std::map<unsigned int, uint16_t>::const_iterator controllerTsIt = controllerTimestamps.begin();
669  controllerTsIt != controllerTimestamps.end(); ++controllerTsIt)
670  if (controllerTsIt->second != controllerTimestamps.begin()->second)
671  throw cet::exception("BeamlineUnpack::UnpackWC")
672  << "WC controller timestamps differ between TDC fragments." << std::endl;
673 
674  for (std::map<unsigned int, uint32_t>::const_iterator tdcTsIt = tdcTimestamps.begin();
675  tdcTsIt != tdcTimestamps.end(); ++tdcTsIt)
676  if (tdcTsIt->second != tdcTimestamps.begin()->second)
677  throw cet::exception("BeamlineUnpack::UnpackWC")
678  << "TDC timestamps differ between TDC fragments." << std::endl;
679 
680  uint32_t tdcTs = tdcTimestamps.begin()->second;
681  uint32_t controllerTs = controllerTimestamps.begin()->second;
682 
683  uint16_t tdcCommon = tdcTs & 0x1FFu;
684  uint16_t controllerCommon = (controllerTs & 0xFF8u) >> 3;
685  if (tdcCommon != controllerCommon)
686  throw cet::exception("BeamlineUnpack::UnpackWC")
687  << "Synchronization problem between MWPC controller and TDC timestamps." << std::endl
688  << "Bits 8..0 of TDC timestamp " << std::bitset<9>(tdcCommon) << "; "
689  << "bits 11..3 of controller timetamp " << std::bitset<9>(controllerCommon) << std::endl;
690 
691  uint64_t timestamp = static_cast<uint64_t>(((std::bitset<35>(tdcTimestamps.begin()->second) << 3) |
692  (std::bitset<35>(controllerTimestamps.begin()->second & 0x7))).to_ullong());
693  long double timestamp_ns = timestamp * 1.18; //ns
694  for (std::vector<rawdata::RawBeamlineWC>::iterator wcIt = wcs.begin(); wcIt != wcs.end(); ++wcIt)
695  wcIt->SetTimestamp(timestamp_ns);
696 
697  fBeamlineEvents->FindEvent(event)->AddWC(wcs);
698 
699  }
700 
701  return;
702 
703 }
void AddTimestamp(uint64_t timestamp)
DetectorID TrigDetector() const
Offline DetectorID for trigger.
void reconfigure(const fhicl::ParameterSet &pset)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
art::ServiceHandle< beamlinegeo::BeamlineGeometry > fGeometry
void SetBeamlineRun(unsigned int run)
Definition: RawBeamline.cxx:18
void AddOtherDigit(std::vector< rawdata::RawBeamlineDigit > other)
void AddToF(std::vector< rawdata::RawBeamlineDigit > tof)
BeamlineEvent * FindEvent(unsigned int event)
rawdata::RawBeamlineConfig GetConfig() const
void AddTrigger(std::vector< rawdata::RawBeamlineTrigger > trigger)
void AddWCDigit(std::vector< rawdata::RawBeamlineDigit > mwpc)
unsigned int NumWCs() const
Number of WCs in beamline.
const std::size_t nfragments_
std::vector< BeamlineEvent * > GetEvents() const
std::vector< rawdata::RawBeamlineTrigger > GetTrigger() const
std::vector< rawdata::RawBeamlineDigit > GetCherenkov() const
std::vector< rawdata::RawBeamlineWC > GetWC() const
std::vector< uint8_t > buffer_
unsigned int EventNumber() const
void Unpack(const LariatFragment *spillFrag, const std::vector< TDUFragment * > tduFrag, unsigned int run=0, std::string filename="")
::xsd::cxx::tree::exception< char > exception
Definition: Database.h:225
BeamlineEvent * GetNextEvent()
Definition: config.py:1
std::size_t nfragments_processed_
string filename
Definition: shutoffs.py:106
void AddEvents(std::vector< BeamlineEvent * > events)
artdaq::Fragments * getFragments(TBranch *br, unsigned entry)
void SetWaveform(std::vector< uint16_t > waveform)
uint64_t GetTDUTime() const
std::vector< rawdata::RawBeamlineDigit > GetToF() const
void AddWC(std::vector< rawdata::RawBeamlineWC > wc)
art::ServiceHandle< beamlineutil::BeamlineChannelMap > fChannelMap
const XML_Char int const XML_Char * value
Definition: expat.h:331
BeamlineEvents * fBeamlineEvents
T get(std::string const &key) const
Definition: ParameterSet.h:231
std::vector< rawdata::RawBeamlineDigit > GetWCDigit() const
uint64_t GetTimestamp() const
bool ActiveDigitChannel(unsigned int channel) const
Enquire whether this online digitizer channel is active.
void SetBField(float b_field)
Definition: RawBeamline.cxx:24
std::vector< TDUFragment * > CleanTDU(const std::vector< TDUFragment * > &tduFrags)
BeamlineEvent(unsigned int eventNum)
Definition: run.py:1
Methods to interface with the DAQ-formatted output file for the beamline components of the test beam ...
void UnpackTrigger(const std::vector< TriggerPattern::TriggerPattern_t > &beamlineTriggers, const std::vector< TDUFragment * > &beamlineTDUs, std::string filename="")
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
void AddMuonStack(std::vector< rawdata::RawBeamlineDigit > muonstack)
art::ServiceHandle< beamlineutil::BeamlineMagneticField > fMagneticField
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
void UnpackDigits(const std::vector< V1742Fragment > &frags)
void UnpackWC(const TDCFragment &frag)
std::vector< rawdata::RawBeamlineDigit > GetOtherDigit() const
BeamlineUnpack(const fhicl::ParameterSet &pset)
std::vector< rawdata::RawBeamlineDigit > GetMuonStack() const
float MagneticField(unsigned int beamline_run)
Return the magnetic field for a given beamline data run.
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
void AddConfig(rawdata::RawBeamlineConfig config)
Float_t e
Definition: plot.C:35
void add(const art::Event &evt, const art::InputTag &tag)
ChannelID DigitChannel(unsigned int channel) const
Offline ChannelID for this online digitizer channel.
void AddPaddleDigit(std::vector< rawdata::RawBeamlineDigit > paddle)
void AddTDUTime(uint64_t tduTime)
def entry(str)
Definition: HTMLTools.py:26
void AddCherenkov(std::vector< rawdata::RawBeamlineDigit > cherenkov)
BeamlineEvents * GetBeamlineEvents() const
void SetTimestamp(uint64_t timestamp)
Definition: RawBeamline.cxx:58
void events(int which)
Definition: Cana.C:52
void AddEvent(BeamlineEvent *event)
std::vector< rawdata::RawBeamlineDigit > GetPaddleDigit() const
std::vector< TriggerPattern::TriggerPattern_t > CleanTriggers(const TriggerFragment &triggerFrag)
unsigned int fChannelsPerTDC
unsigned int fTriggerLatency
unsigned int NumEvents() const
void UnpackConfig(unsigned int run)
DetectorID WCDetector(unsigned int detector) const
Offline DetectorID for this online WC detector.