SplitterInput_source.cc
Go to the documentation of this file.
1 // art
10 #include "art_root_io/TFileService.h"
20 
21 //Pedestal stuff...
27 #include "cetlib/getenv.h"
28 
29 // artdaq
30 #include "artdaq-core/Data/Fragment.hh"
31 #include "lbne-raw-data/Services/ChannelMap/ChannelMapService.h"
32 
33 // lardata
37 
38 // dune
39 #include "tpcFragmentToRawDigits.h"
40 #include "SSPReformatterAlgs.h"
41 #include "PennToOffline.h"
42 
43 // C++
44 #include <functional>
45 #include <memory>
46 #include <regex>
47 #include <string>
48 #include <vector>
49 #include <iostream>
50 
51 // ROOT
52 #include "TTree.h"
53 #include "TFile.h"
54 
55 using raw::RawDigit;
56 using raw::OpDetWaveform;
58 using std::vector;
59 using std::string;
60 
61 const int ArraySize = 500;
62 
63 // TODO:
64 // Handle cases of missing data products. What if SSP or Penn or RCE data are just not there?
65 // If SSP or Penn not there it is fine, but if no RCE then it won't know how when to stop making the event...
66 // Deal with ZS data -- currently this assumes non-ZS data
67 //===================================================================================================================
68 
69 namespace {
70 
71  struct LoadedWaveforms {
72 
73  LoadedWaveforms() : waveforms() {}
74  vector<OpDetWaveform> waveforms;
75 
76  void load( vector<OpDetWaveform> const & v, int fDebugLevel ) {
77  waveforms = v;
78  }
79 
80  // not really used
81  bool empty() const {
82  if (waveforms.size() == 0) return true;
83  return false;
84  }
85 
86  // Clear waveforms vector.
87  void clear(int fDebugLevel) {
88  if (fDebugLevel > 3) std::cout << "Clearing LoadedWaveforms." << std::endl;
89  waveforms.clear();
90  empty();
91  }
92 
93  std::vector<OpDetWaveform> TakeAll() {
94  return waveforms;
95  }
96 
97  void findinrange(std::vector<OpDetWaveform> &wbo,
98  lbne::TpcNanoSlice::Header::nova_timestamp_t first_timestamp,
99  lbne::TpcNanoSlice::Header::nova_timestamp_t last_timestamp,
100  lbne::TpcNanoSlice::Header::nova_timestamp_t event_timestamp,
101  double NovaTicksPerSSPTick,
102  int fDebugLevel) {
103  int hh = 0;
104  for (auto wf : waveforms) { // see if any waveforms have pieces inside this TPC boundary
105  lbne::TpcNanoSlice::Header::nova_timestamp_t WaveformTimestamp = wf.TimeStamp() * NovaTicksPerSSPTick;
106  if ( hh < 5 && fDebugLevel > 2) { // Just want to write out the first few waveforms
107  std::cout << "Looking at waveform number " << hh << ". It was on channel " << wf.ChannelNumber() << " at time " << WaveformTimestamp
108  << ". The times I passed were " << first_timestamp << " and " << last_timestamp
109  << std::endl;
110  }
111  if (WaveformTimestamp <= last_timestamp && WaveformTimestamp >= first_timestamp) {
112  lbne::TpcNanoSlice::Header::nova_timestamp_t NewNovaTime = WaveformTimestamp - event_timestamp;
113  double NewTime = NewNovaTime / NovaTicksPerSSPTick;
114  raw::OpDetWaveform odw( NewTime, wf.ChannelNumber(), wf.size() );
115  if (fDebugLevel > 3)
116  std::cout << "Pushing back waveform " << hh << " on channel " << odw.ChannelNumber() << " at time " << odw.TimeStamp() << " ("<< odw.TimeStamp()*NovaTicksPerSSPTick <<")" << std::endl;
117  for (size_t WaveSize = 0; WaveSize < wf.size(); ++WaveSize ) {
118  odw.emplace_back(wf[WaveSize]);
119  }
120  wbo.emplace_back(std::move(odw));
121  }
122  ++hh;
123  } // auto waveforms
124  if (fDebugLevel > 1) std::cout << "At the end of Waveform findinrange, wbo has size " << wbo.size() << std::endl;
125  } // findinrange
126 
127  //=======================================================================================
128  bool PhotonTrigger(lbne::TpcNanoSlice::Header::nova_timestamp_t this_timestamp, double fWaveformADCThreshold, int fWaveformADCsOverThreshold,
129  double fWaveformADCWidth, double NovaTicksPerSSPTick, int fDebugLevel, bool CheatTrigger ) { // Triggering on photon detectors
130  int HighADCWaveforms = 0;
131 
132  double SumWaveforms = 0;
133  int ADCs = 0;
134  int More1550 = 0;
135  int More1750 = 0;
136  int More2000 = 0;
137  double Lowest = 1e7;
138  double Biggest = 0;
139  for (auto wf : waveforms) { // see if any waveforms have pieces inside this TPC boundary
140  lbne::TpcNanoSlice::Header::nova_timestamp_t WaveformTimestamp = wf.TimeStamp() * NovaTicksPerSSPTick;
141  lbne::TpcNanoSlice::Header::nova_timestamp_t StartTimestamp = WaveformTimestamp - ( fWaveformADCWidth * NovaTicksPerSSPTick * 0.5);
142  lbne::TpcNanoSlice::Header::nova_timestamp_t EndTimestamp = WaveformTimestamp + ( fWaveformADCWidth * NovaTicksPerSSPTick * 0.5);
143  if (this_timestamp <= EndTimestamp && this_timestamp >= StartTimestamp) {
144  for (int ii=0;ii<(int)wf.size();++ii) {
145  if ((int)wf.Waveform()[ii] > fWaveformADCThreshold) {
146  ++HighADCWaveforms;
147 
148  SumWaveforms += (int)wf.Waveform()[ii];
149  if ( wf.Waveform()[ii] < Lowest ) Lowest = wf.Waveform()[ii];
150  if ( wf.Waveform()[ii] > Biggest) Biggest= wf.Waveform()[ii];
151  if ( wf.Waveform()[ii] > 1550 ) ++More1550;
152  if ( wf.Waveform()[ii] > 1750 ) ++More1750;
153  if ( wf.Waveform()[ii] > 2000 ) ++More2000;
154  ++ADCs;
155  } // If ADC count more than threshold (1550)
156  } // Loop over wf ADC's
157  } // If times match
158  } // Loop over waveforms
159  if (fDebugLevel > 3) {
160  std::cout << "Lowest " << Lowest << ", Biggest " << Biggest << ", Average " << SumWaveforms / ADCs
161  << ", Total " << ADCs << ", More1550 " << More1550 << ", More1750 " << More1750 << ", More2000 " << More2000
162  << std::endl;
163  }
164  if ( HighADCWaveforms > fWaveformADCsOverThreshold ) return true;
165  else return false;
166  } // Photon Trigger
167  }; // Loaded Waveforms
168 
169  //=============================== loaded OpHits ========================================================
170  struct LoadedOpHits {
171 
172  LoadedOpHits() : ophits() {}
173  vector<recob::OpHit> ophits;
174 
175  void load( vector<recob::OpHit> const & v, int fDebugLevel ) {
176  ophits = v;
177  }
178 
179  // not really used
180  bool empty() const {
181  if (ophits.size() == 0) return true;
182  return false;
183  }
184 
185  // Clear waveforms vector.
186  void clear(int fDebugLevel) {
187  if (fDebugLevel > 3) std::cout << "Clearing LoadedOphits." << std::endl;
188  ophits.clear();
189  empty();
190  }
191 
192  std::vector<recob::OpHit> TakeAll() {
193  return ophits;
194  }
195 
196  void findinrange(std::vector<recob::OpHit> &obo,
197  lbne::TpcNanoSlice::Header::nova_timestamp_t first_timestamp,
198  lbne::TpcNanoSlice::Header::nova_timestamp_t last_timestamp,
199  lbne::TpcNanoSlice::Header::nova_timestamp_t event_timestamp,
200  double NovaTicksPerSSPTick,
201  int fDebugLevel) {
202  int hh = 0;
203  for (auto wf : ophits) { // see if any ophits have pieces inside this TPC boundary
204  lbne::TpcNanoSlice::Header::nova_timestamp_t HitTimestamp = wf.PeakTime() * NovaTicksPerSSPTick;
205  if ( hh < 5 && fDebugLevel > 2) { // Just want to write out the first few ophits
206  std::cout << "Looking at waveform number " << hh << ". It was on channel " << wf.OpChannel() << " at time " << HitTimestamp
207  << ". The times I passed were " << first_timestamp << " and " << last_timestamp
208  << std::endl;
209  }
210  if (HitTimestamp <= last_timestamp && HitTimestamp >= first_timestamp) {
211  double NewTime = wf.PeakTime() - (event_timestamp/NovaTicksPerSSPTick);
212  double NewAbsTime = wf.PeakTimeAbs() - (event_timestamp/NovaTicksPerSSPTick);
213  recob::OpHit newHit( wf.OpChannel(), NewTime, NewAbsTime, wf.Frame(), wf.Width(), wf.Area(), wf.Amplitude(), wf.PE(), wf.FastToTotal() );
214  obo.emplace_back(std::move(newHit));
215 
216  if (fDebugLevel > 3)
217  std::cout << "Pushing back waveform " << hh << " on channel " << wf.OpChannel() << " at corrected time " << NewTime << "("<<HitTimestamp
218  << "). The times I passed were " << first_timestamp << " and " << last_timestamp << ", event_timestamp " << event_timestamp << std::endl;
219  }
220  ++hh;
221  } // auto ophits
222  if (fDebugLevel > 1) std::cout << "At the end of OpHit findinrange, obo has size " << obo.size() << std::endl;
223  } // findinrange
224 
225  //=======================================================================================
226  bool OpHitTrigger(lbne::TpcNanoSlice::Header::nova_timestamp_t this_timestamp, double fOpHitADCThreshold, int fOpHitADCsOverThreshold,
227  double fOpHitADCWidth, double NovaTicksPerSSPTick, int fDebugLevel ) { // Triggering on photon detectors
228  int hh = 0;
229  int HighADCHits = 0;
230  for (auto wf : ophits) { // see if any waveforms have pieces inside this TPC boundary
231  std::cout << "Looping through ophits, looking at element " << hh << ". It is channel " << wf.OpChannel() << " at time " << wf.PeakTime()
232  << ", it has Amplitude " << wf.Amplitude() << " and " << wf.PE() << " PE's." << std::endl;
233  ++hh;
234  if ( wf.Amplitude() > fOpHitADCThreshold ) ++HighADCHits;
235  } // Loop over waveforms
236  if ( HighADCHits > fOpHitADCsOverThreshold ) return true;
237  else return false;
238  } // Photon Trigger
239  }; // Loaded OpHits
240 
241  //=============================== loaded Digits ========================================================
242  struct LoadedDigits {
243 
244  LoadedDigits() : digits(), index(), firstTimestamp(0) {}
245 
246  vector<RawDigit> digits;
247  size_t index;
248  lbne::TpcNanoSlice::Header::nova_timestamp_t firstTimestamp; // timestamp of the first nanoslice in the digits vector
249 
250  void loadTimestamp(lbne::TpcNanoSlice::Header::nova_timestamp_t ts) {
251  firstTimestamp = ts;
252  }
253 
254  // Clear digits vector.
255  void clear(int fDebugLevel) {
256  if (fDebugLevel > 3) std::cout << "Clearing LoadedDigits." << std::endl;
257  digits.clear();
258  empty(fDebugLevel);
259  }
260 
261  unsigned int size() {
262  return digits.size();
263  }
264 
265  // copy rawdigits to LoadedDigits and uncompress if necessary.
266  void load( vector<RawDigit> const & v, int fDebugLevel ) {
267  if (v.size() == 0 || v.back().Compression() == raw::kNone) {
268  digits = v;
269  if (fDebugLevel > 1) std::cout << "RCE information is not compressed." << std::endl;
270  }
271  else {
272  if (fDebugLevel > 1) std::cout << "RCE information is compressed." << std::endl;
273  // make a new raw::RawDigit object for each compressed one
274  // to think about optimization -- two copies of the uncompressed raw digits here.
275  digits = std::vector<RawDigit>();
276  for (auto idigit = v.begin(); idigit != v.end(); ++idigit) {
277  std::vector<short> uncompressed;
278  int pedestal = (int)idigit->GetPedestal();
279  raw::Uncompress(idigit->ADCs(),
280  uncompressed,
281  pedestal,
282  idigit->Compression()
283  );
284  raw::RawDigit digit(idigit->Channel(),
285  idigit->Samples(),
286  uncompressed,
287  raw::kNone);
288  digit.SetPedestal( idigit->GetPedestal(), idigit->GetSigma() );
289  if (fDebugLevel > 3) std::cout << "Setting defualt pedestal values on channel " << digit.Channel() << " to " << digit.GetPedestal() << " and sigma " << digit.GetSigma() << std::endl;
290  digits.push_back(digit);
291  }
292  }
293  bool GoodDig = true;
294  for (unsigned int j=0; j<digits.size(); j=j+128) {
295  if ( digits[0].NADC() - digits[j].NADC() ) GoodDig = false;
296  if (fDebugLevel > 2)
297  std::cout << "digits[0] has " << digits[0].NADC() << " ADC's, whilst digits["<<j<<"] has " << digits[j].NADC() << " ADCs. Still a good digit? " << GoodDig << std::endl;
298  }
299  if (!GoodDig) {
300  if (fDebugLevel) std::cout << "Got a bad digit, so want to clear it...\n" << std::endl;
301  clear(fDebugLevel);
302  }
303 
304  index = 0ul;
305  } // load
306 
307  bool empty(int fDebugLevel) const {
308  if (digits.size() == 0) {
309  if (fDebugLevel > 3) std::cout << "digits.size is 0" << std::endl;
310  return true;
311  }
312  if (digits[0].Samples() == 0) {
313  if (fDebugLevel > 3) std::cout << "digits[0].samples is 0" << std::endl;
314  return true;
315  }
316  if (index >= digits[0].Samples()) {
317  if (fDebugLevel > 3) std::cout << "The index is more than the number of samples" << std::endl;
318  return true;
319  }
320  return false;
321  } // empty
322 
323  RawDigit::ADCvector_t next() {
324  ++index;
325  RawDigit::ADCvector_t digitsatindex;
326  for (size_t ichan=0; ichan<digits.size(); ichan++) {
327  digitsatindex.push_back(digits[ichan].ADC(index-1));
328  }
329  return digitsatindex;
330  }
331 
332  lbne::TpcNanoSlice::Header::nova_timestamp_t getTimeStampAtIndex(size_t index_local, double novatickspertpctick)
333  {
334  return firstTimestamp + index_local*novatickspertpctick;
335  }
336 
337  }; // loadedDigits
338  //=============================== loaded Counters ========================================================
339  struct LoadedCounters {
340 
341  LoadedCounters() : counters(), index() {}
342 
343  vector<ExternalTrigger> counters;
344  size_t index;
345 
346  void load( vector<ExternalTrigger> const & v, int fDebugLevel ) {
347 
348  if (v.size() == 0 )
349  counters = v;
350  else {
351  // make a new raw::ExternalTrigger object for each compressed one
352  // to think about optimization -- two copies of the uncompressed raw ExternalTrigger here.
353  counters = std::vector<ExternalTrigger>();
354  int ii = 0;
355  for (auto icounter = v.begin(); icounter != v.end(); ++icounter) {
356  std::vector<short> uncompressed;
357  raw::ExternalTrigger counter(icounter->GetTrigID(),
358  icounter->GetTrigTime() );
359  counters.push_back(counter);
360  ++ii;
361  }
362  }
363  index = 0ul;
364  } // load
365 
366  // not really used
367  bool empty() const {
368  if (counters.size() == 0) return true;
369  return false;
370  }
371 
372  lbne::TpcNanoSlice::Header::nova_timestamp_t ConvCounterTick(lbne::TpcNanoSlice::Header::nova_timestamp_t TrigTime, double novatickspercounttick) {
373  return TrigTime*novatickspercounttick;
374  }
375 
376  std::vector<ExternalTrigger> TakeAll() {
377  return counters;
378  }
379 
380  void clear(int fDebugLevel) {
381  if (fDebugLevel > 3) std::cout << "Clearing LoadedCounters." << std::endl;
382  counters.clear();
383  empty();
384  }
385 
386  void findinrange(std::vector<ExternalTrigger> &cbo,
387  lbne::TpcNanoSlice::Header::nova_timestamp_t first_timestamp,
388  lbne::TpcNanoSlice::Header::nova_timestamp_t last_timestamp,
389  lbne::TpcNanoSlice::Header::nova_timestamp_t event_timestamp,
390  unsigned int novatickspercounttick,
391  int fDebugLevel) {
392  int hh = 0;
393  for (auto count : counters) { // Loop through all the counters
394  lbne::TpcNanoSlice::Header::nova_timestamp_t TimeStamp = ConvCounterTick(count.GetTrigTime(), novatickspercounttick);
395  if ( hh < 5 && fDebugLevel > 2) { // Just want to look at first few counters.
396  std::cout << "Looking at muon counter " << hh << " It has ID " << count.GetTrigID() << " and time " << TimeStamp << "."
397  << " The times I passed were " << first_timestamp << " and " << last_timestamp << std::endl;
398  }
399  if (TimeStamp <= last_timestamp && TimeStamp >= first_timestamp) {
400  lbne::TpcNanoSlice::Header::nova_timestamp_t NewTime = TimeStamp - (event_timestamp/novatickspercounttick);
401  raw::ExternalTrigger ET(count.GetTrigID(), NewTime );
402  cbo.emplace_back(std::move(ET));
403  if (fDebugLevel > 3 )
404  std::cout << "Pushing back counter, channel " << ET.GetTrigID() << "(" << count.GetTrigID() << ") and corrected time " << ET.GetTrigTime() << " (" << count.GetTrigTime() << ")" << std::endl;
405 
406  } // If within range
407  ++hh;
408  } // auto waveforms
409  if (fDebugLevel > 1) std::cout << "At the end of Counter findinrange, cbo has size " << cbo.size() << std::endl;
410  } // findinrange
411 
412  //=======================================================================================
413  bool PTBTrigger(lbne::TpcNanoSlice::Header::nova_timestamp_t this_timestamp, double NovaTicksPerCountTick, double NovaTicksPerTPCTick, int fDebugLevel, std::vector<unsigned int> SpecialChan, bool CheatTrigger ) { // Triggering on muon counters
414  for ( auto count : counters ) {
415  for ( size_t ChanLoop = 0; ChanLoop < SpecialChan.size(); ++ChanLoop) {
416  if ( SpecialChan[ChanLoop] == count.GetTrigID() ) {
417  if (CheatTrigger) return true;
418  lbne::TpcNanoSlice::Header::nova_timestamp_t EffecTimeStamp = ConvCounterTick( count.GetTrigTime(), NovaTicksPerCountTick );
419  if ( EffecTimeStamp > this_timestamp
420  && EffecTimeStamp < (this_timestamp+NovaTicksPerTPCTick)
421  ) { // If timestamps match!
422  if (fDebugLevel)
423  std::cout << "Triggering on Counter " << count.GetTrigID() << ", " << EffecTimeStamp << ", TPC tick " << this_timestamp << std::endl;
424  return true;
425  } // If timestamps match
426  } // If a special TrigID
427  } // Loop through special counters.
428  } // Loop through counters
429  return false;
430  } // CounterTrigger
431 
432  }; // LoadedCounters
433 
434  //=============================== Monte Carlo Stuff ========================================================
435  struct MonteCarlo {
436  MonteCarlo() : MCParts() {} //, SimChans(), DetSimChans(), SimPhots() {}
437 
438  vector<simb::MCParticle> MCParts;
439  vector<sim::SimChannel> SimChans;
440  //vector<sim::AuxDetSimChannels> DetSimChans;
441  //vector<sim::SimPhotonsLits> SimPhots;
442 
443  void loadMCParts( vector<simb::MCParticle> const & v ) {
444  MCParts = v;
445  }
446 
447  void loadSimChans( vector<sim::SimChannel> const & b ) {
448  SimChans = b;
449  }
450 
451  vector<simb::MCParticle> TakeMCParts(lbne::TpcNanoSlice::Header::nova_timestamp_t event_timestamp, double fNanoSecondsPerNovaTick, int fDebugLevel) {
452  vector<simb::MCParticle> retParts;
453  int hh=0;
454  unsigned short TimeCorrec = ( event_timestamp / (2*fNanoSecondsPerNovaTick) ) - 1;
455  if (fDebugLevel > 2)
456  std::cout << "\n\nIn TakeMCParts....MCParts has size " << MCParts.size() << ", event timestamp is " << event_timestamp << " meaning the time correction is " << TimeCorrec << std::endl;
457 
458  for (auto part: MCParts) {
459  simb::MCParticle newPart = simb::MCParticle(part.TrackId(), part.PdgCode(), part.Process(), part.Mother(), part.Mass(), part.StatusCode());
460  newPart.SetGvtx( part.GetGvtx() );
461  newPart.SetEndProcess( part.EndProcess() );
462  newPart.SetPolarization ( part.Polarization() );
463  newPart.SetRescatter( part.Rescatter() );
464  newPart.SetWeight( part.Weight() );
465  for (size_t qq=0; qq < part.NumberTrajectoryPoints(); ++qq) {
466  const TLorentzVector pos = TLorentzVector( part.Vx(qq), part.Vy(qq), part.Vz(qq), part.T(qq) - TimeCorrec );
467  const TLorentzVector mom = TLorentzVector( part.Px(qq), part.Py(qq), part.Pz(qq), part.E(qq) );
468  newPart.AddTrajectoryPoint( pos, mom );
469  if (fDebugLevel > 4)
470  std::cout << "New Traj point...\nNew part is;"
471  << newPart.Vx(qq) << " " << newPart.Vy(qq) << " " << newPart.Vz(qq) << " " << newPart.T(qq) << " "
472  << newPart.Px(qq) << " " << newPart.Py(qq) << " " << newPart.Pz(qq) << " " << newPart.T(qq) << " " << newPart.P(qq) << " " << newPart.Pt(qq) << " " << newPart.E(qq)
473  << "\nOld part is;"
474  << part.Vx(qq) << " " << part.Vy(qq) << " " << part.Vz(qq) << " " << part.T(qq) << " "
475  << part.Px(qq) << " " << part.Py(qq) << " " << part.Pz(qq) << " " << part.T(qq) << " " << part.P(qq) << " " << part.Pt(qq) << " " << part.E(qq)
476  << std::endl;
477  }
478  for (int dd=0; dd<part.NumberDaughters(); ++dd)
479  newPart.AddDaughter(part.Daughter(dd));
480  retParts.emplace_back(newPart);
481  if (fDebugLevel > 3)
482  std::cout << "Made a new MCParticle"
483  << ", TrajPoints " << newPart.NumberTrajectoryPoints() << " " << part.NumberTrajectoryPoints()
484  << ", time " << newPart.T() << " " << part.T()
485  << ", TrackID " << newPart.TrackId() << " " << part.TrackId()
486  << ", Energy " << newPart.E() << " " << part.E()
487  << ", NDaughters " << newPart.NumberDaughters() << " " << part.NumberDaughters()
488  << std::endl;
489  //if ( newPart.T() - part.T() != 0 ) std::cout << "!!!!!!!!!!!!!!!!!NOT EQUAL TO 0!!!!!!!!!!!!!!!!!!!!!" << std::endl;
490  ++hh;
491  }
492  if (fDebugLevel > 1) std::cout << "At the end of TakeMCParts I am returning a vector of MCParticles with size " << retParts.size() << std::endl;
493  return retParts;
494  }
495 
496  vector<sim::SimChannel> TakeSimChans(lbne::TpcNanoSlice::Header::nova_timestamp_t event_timestamp, double fNovaTicksPerTPCTick, int fDebugLevel) {
497  vector<sim::SimChannel> retSimChans;
498  int qq = 0;
499  unsigned short TimeCorrec = ( event_timestamp / fNovaTicksPerTPCTick ) - 1;
500  if (fDebugLevel > 2)
501  std::cout << "\n\nIn TakeSimChans....SimChans has size " << MCParts.size() << ", event timestamp is " << event_timestamp << " meaning the time correction is " << TimeCorrec << std::endl;
502 
503  for (auto LoopSimChan: SimChans) {
504  sim::SimChannel newSimChan = sim::SimChannel( LoopSimChan.Channel() );
505  for (auto const& ideMap : LoopSimChan.TDCIDEMap()) {
506  unsigned short NewTime = ideMap.first - TimeCorrec;
507  for (auto const& ide : ideMap.second) {
508  double IDEPos[3] = { ide.x, ide.y, ide.z };
509  newSimChan.AddIonizationElectrons(ide.trackID, NewTime, ide.numElectrons, IDEPos, ide.energy );
510  }
511  //if ( NewTime - ideMap->first != 0 ) std::cout << "!!!!!!!!!!!!!!!!!NOT EQUAL TO 0!!!!!!!!!!!!!!!!!!!!!" << std::endl;
512  }
513  retSimChans.emplace_back(newSimChan);
514  if (fDebugLevel > 3)
515  std::cout << "Added a newSimChan with size " << newSimChan.TDCIDEMap().size() << ", " << LoopSimChan.TDCIDEMap().size()
516  << ". Channel " << newSimChan.Channel() << ", " << LoopSimChan.Channel()
517  << ". Charge on tdc(0) " << newSimChan.Charge(0) << ", " << LoopSimChan.Charge(0)
518  << ". Energy on tdc(0) " << newSimChan.Energy(0) << ", " << LoopSimChan.Energy(0)
519  << ". TrackIDEs(-10000,100000) " << newSimChan.TrackIDEs(0,100000).size() << " " << LoopSimChan.TrackIDEs(0,100000).size()
520  << std::endl;
521  ++qq;
522  }
523  if (fDebugLevel > 1) std::cout << "At the end of TakeSimChans I am returning a vector of SimChannels with size " << retSimChans.size() << std::endl;
524  return retSimChans;
525  }
526  }; // MonteCarlo
527  //===============================================================================================
528  // Retrieves branch name (a la art convention) where object resides
529  const char* getBranchName( art::InputTag const & tag, const string inputDataProduct ) {
530  std::ostringstream pat_s;
531  pat_s << inputDataProduct << "s"
532  << '_'
533  << tag.label()
534  << '_'
535  << tag.instance()
536  << '_'
537  << tag.process()
538  << ".obj";
539 
540  return pat_s.str().data();
541  }
542 
543  artdaq::Fragments*
544  getFragments( TBranch* br, unsigned entry ) {
545  br->GetEntry( entry );
546  return reinterpret_cast<artdaq::Fragments*>( br->GetAddress() );
547  }
548 
549  vector<raw::RawDigit>*
550  getRawDigits( TBranch* br, unsigned entry ) {
551  br->GetEntry( entry );
552  return reinterpret_cast<vector<raw::RawDigit>*>( br->GetAddress() );
553  }
554 
555  vector<raw::OpDetWaveform>*
556  getSSPWaveforms( TBranch* br, unsigned entry ) {
557  br->GetEntry( entry );
558  return reinterpret_cast<vector<raw::OpDetWaveform>*>( br->GetAddress() );
559  }
560 
561  vector<recob::OpHit>*
562  getOpHits( TBranch* br, unsigned entry ) {
563  br->GetEntry( entry );
564  return reinterpret_cast<vector<recob::OpHit>*>( br->GetAddress() );
565  }
566 
567  vector<raw::ExternalTrigger>*
568  getRawExternalTriggers( TBranch* br, unsigned entry ) {
569  br->GetEntry( entry );
570  return reinterpret_cast<vector<raw::ExternalTrigger>*>( br->GetAddress() );
571  }
572 
573  vector<simb::MCParticle>* getMCParticles(TBranch* br, unsigned entry) {
574  br->GetEntry( entry );
575  return reinterpret_cast<vector<simb::MCParticle>*>(br->GetAddress() );
576  }
577 
578  vector<simb::MCTruth>* getMCTruths(TBranch* br, unsigned entry) {
579  br->GetEntry( entry );
580  return reinterpret_cast<vector<simb::MCTruth>*>(br->GetAddress() );
581  }
582 
583  vector<sim::SimChannel>* getMCSimChans(TBranch* br, unsigned entry) {
584  br->GetEntry( entry );
585  return reinterpret_cast<vector<sim::SimChannel>*>(br->GetAddress() );
586  }
587 }
588 
589 //==========================================================================
590 namespace raw {
591  // Enable 'pset.get<raw::Compress_t>("compression")'
592  void decode (std::any const & a, Compress_t & result ){
593  unsigned tmp;
594  fhicl::detail::decode(a,tmp);
595  result = static_cast<Compress_t>(tmp);
596  }
597 }
598 //==========================================================================
599 
600 namespace DAQToOffline {
601  // The class Splitter is to be used as the template parameter for art::Source<T>. It understands how to read art's ROOT data files,
602  // to extract artdaq::Fragments from them, how to convert the artdaq::Fragments into vectors of raw::RawDigit objects, and
603  // finally how to re-combine those raw::RawDigit objects, raw::OpDetWaveform objects, and external trigger objects to present
604  // the user of the art::Source<Splitter> with a sequence of art::Events that have the desired event structure, different from
605  // the event structure of the data file(s) being read.
606 
607  class Splitter {
608  public:
611  art::SourceHelper const& sh);
612 
613  // See art/Framework/IO/Sources/Source.h for a description of each of the public member functions of Splitter.
614  bool readFile(string const& filename, art::FileBlock*& fb);
615 
616  bool readNext(art::RunPrincipal* const& inR,
617  art::SubRunPrincipal* const& inSR,
618  art::RunPrincipal*& outR,
619  art::SubRunPrincipal*& outSR,
620  art::EventPrincipal*& outE);
621 
622  void closeCurrentFile();
623 
624  private:
625 
626  using rawDigits_t = vector<RawDigit>;
627  using SSPWaveforms_t = vector<OpDetWaveform>;
628  using OpHits_t = vector<recob::OpHit>;
629  using PennCounters_t = vector<ExternalTrigger>;
630 
631  using MCPart_t = vector<simb::MCParticle>;
632  using MCTruth_t = vector<simb::MCTruth>;
633  using MCSimChan_t = vector<sim::SimChannel>;
634 
635  string sourceName_;
637  std::unique_ptr<TFile> file_;
655  string fPTBMapFile;
656  string fPTBMapDir;
658  TBranch* TPCinputBranch_;
660  TBranch* SSPinputBranch_;
666  TBranch* EventAuxBranch_;
667  LoadedDigits loadedDigits_;
668  LoadedWaveforms loadedWaveforms_;
669  LoadedOpHits loadedOpHits_;
670  LoadedCounters loadedCounters_;
671  MonteCarlo MonteCarlo_;
672  size_t nInputEvts_;
673  size_t EventIndex_;
685  std::vector<RawDigit::ADCvector_t> dbuf_;
692  unsigned short fTicksAccumulated;
693  unsigned int fChansPresent = 0;
694 
695  bool fTrigger = false;
696  bool fCheatPTBTrig = false;
697  bool fCheatSSPTrig = false;
698  size_t fLastTriggerIndex = 0;
699  size_t fLastEventIndex = 0;
700  size_t fLastEvent = 0;
701  int fDiffFromLastTrig = 0;
702  lbne::TpcNanoSlice::Header::nova_timestamp_t fLastTimeStamp = 0;
703  lbne::TpcNanoSlice::Header::nova_timestamp_t first_timestamp=0;
704  lbne::TpcNanoSlice::Header::nova_timestamp_t Event_timestamp=0;
705  lbne::TpcNanoSlice::Header::nova_timestamp_t last_timestamp=0;
706  lbne::TpcNanoSlice::Header::nova_timestamp_t this_timestamp=0;
707  lbne::TpcNanoSlice::Header::nova_timestamp_t prev_timestamp=0;
708 
709  std::map<uint64_t,size_t> EventTreeMap;
710 
711  TTree* fTree;
715  int GivenRunNum[ArraySize];
716  int GivenSubRunNum[ArraySize];
717  int GivenEventNum[ArraySize];
718  int TreeIndexStart[ArraySize];
719  int ChansAtStartOfEvent[ArraySize];
720  int ChansAtEndOfEvent[ArraySize];
721 
722  std::function<rawDigits_t(artdaq::Fragments const&,
723  std::vector<std::pair< std::pair<unsigned int,unsigned int>, lbne::TpcNanoSlice::Header::nova_timestamp_t > > &,
724  lbne::TpcNanoSlice::Header::nova_timestamp_t&,
726 
727  bool eventIsFull_(rawDigits_t const & v);
728 
729  bool loadEvents_( size_t &InputTree );
730  bool LoadPTBInformation( size_t LoadTree );
731  void LoadSSPInformation( size_t LoadTree );
732  void LoadRCEInformation( size_t LoadTree );
733 
734  void makeEventAndPutDigits_( art::EventPrincipal*& outE, art::Timestamp art_timestamp=0);
735 
736  void Reset();
737 
738  void CheckTimestamps(bool &JumpEvent, size_t &JumpNADC );
739 
740  bool NoRCEsCase(art::RunPrincipal*& outR, art::SubRunPrincipal*& outSR, art::EventPrincipal*& outE);
741 
742  void Triggering(std::map<int,int> &PrevChanADC, std::vector<short> ADCdigits, bool NewTree);
743 
744  void CheckTrigger();
745 
746  bool TicklerTrigger( std::map<int,int> &PrevChanADC, std::vector<short> ADCdigits );
747 
750 
765  std::vector<unsigned int> fWhichTrigger;
766  std::vector<unsigned int> fPTBTrigs;
783 
784  bool RCEsPresent = true;
785  int gSkippedOuputEvents = 0;
786  std::vector<std::pair<std::pair<unsigned int,unsigned int>, lbne::TpcNanoSlice::Header::nova_timestamp_t > > DigitsIndexList;
787 
788  std::map<uint16_t, std::map <size_t, std::pair<float,float> > > AllPedMap;
789  std::map<int,int> fPTBMap;
790  };
791 }
792 
793 //=======================================================================================
796  art::SourceHelper const& sh) :
797  sourceName_("SplitterInput"),
798  lastFileName_(ps.get<vector<string>>("fileNames",{}).back()),
799  file_(),
800  doneWithFiles_(false),
801  // TPCinputTag_("daq:TPC:DAQ"), // "moduleLabel:instance:processName"
802  TPCinputTag_ (ps.get<string>("TPCInputTag")),
803  SparseinputTag_ (ps.get<string>("SparseInputTag")),
804  SSPinputTag_ (ps.get<string>("SSPInputTag")),
805  OpHitinputTag_ (ps.get<string>("OpHitInputTag")),
806  PenninputTag_ (ps.get<string>("PennInputTag")),
807  MCPartinputTag_ (ps.get<string>("MCPartInputTag")),
808  MCTruthinputTag_ (ps.get<string>("MCTruthInputTag")),
809  MCSimChaninputTag_ (ps.get<string>("MCSimChanInputTag")),
810  TPCinputDataProduct_ (ps.get<string>("TPCInputDataProduct")),
811  SSPinputDataProduct_ (ps.get<string>("SSPInputDataProduct")),
812  OpHitinputDataProduct_(ps.get<string>("OpHitInputDataProduct")),
813  PenninputDataProduct_ (ps.get<string>("PennInputDataProduct")),
814  MCPartinputDataProduct_(ps.get<string>("MCPartInputDataProduct")),
815  MCTruthinputDataProduct_(ps.get<string>("MCTruthInputDataProduct")),
816  MCSimChaninputDataProduct_(ps.get<string>("MCSimChanInputDataProduct")),
817  sspReform (ps.get<fhicl::ParameterSet>("SSPReformatter")),
818  fPTBMapFile (ps.get<std::string>("PTBMapFile")),
819  fPTBMapDir (ps.get<std::string>("PTBMapDir")),
820  sh_(sh),
821  TPCinputBranch_(nullptr),
822  SSPinputBranch_(nullptr),
823  OpHitinputBranch_(nullptr),
824  PenninputBranch_(nullptr),
825  EventAuxBranch_(nullptr),
826  nInputEvts_(),
827  runNumber_(1), // Defaults
828  subRunNumber_(0),
829  eventNumber_(),
830  cachedRunNumber_(-1),
832  inputRunNumber_(1),
833  inputSubRunNumber_(1),
835  bufferedDigits_(),
836  dbuf_(),
837  wbuf_(),
838  hbuf_(),
839  cbuf_(),
842  std::placeholders::_1, // artdaq::Fragments
843  std::placeholders::_2, // std::vector< std::pair< std::pair<int,int>, lbne::TpcNanoSlice::Header::nova_timestamp_t > > DigitsIndexList
844  std::placeholders::_3, // lbne::TpcNanoSlice::Header::nova_timestamp_t& firstTimestamp
845  std::placeholders::_4, // the channel map
846  ps.get<bool>("UseRCEChanMap",true), // use the channel map
847  ps.get<bool>("debug",false),
848  ps.get<raw::Compress_t>("compression",raw::kNone),
849  ps.get<unsigned>("zeroThreshold",0) ) ),
850  fRequireRCE (ps.get<bool> ("RequireRCE")),
851  fRequireSSP (ps.get<bool> ("RequireSSP")),
852  fRequireOpHit (ps.get<bool> ("RequireOpHit")),
853  fRequirePTB (ps.get<bool> ("RequirePTB")),
854  fMonteCarlo (ps.get<bool> ("MonteCarlo")),
855  fPostTriggerTicks (ps.get<size_t>("PostTriggerTicks")),
856  fPreTriggerTicks (ps.get<size_t>("PreTriggerTicks")),
857  fNovaTicksPerTPCTick (ps.get<double>("NovaTicksPerTPCTick")),
858  fNovaTicksPerSSPTick (ps.get<double>("NovaTicksPerSSPTick")),
859  fNovaTicksPerCountTick (ps.get<double>("NovaTicksPerCountTick")),
860  fNanoSecondsPerNovaTick(ps.get<double>("NanoSecondsPerNovaTick")),
861  fDebugLevel (ps.get<int> ("DebugLevel")),
862  fTimeStampThreshold (ps.get<double>("TimeStampThreshold")),
863  fMCTrigLevel (ps.get<int> ("MCTrigLevel")),
864  fWhichTrigger (ps.get<std::vector<unsigned int> >("WhichTrigger")),
865  fPTBTrigs (ps.get<std::vector<unsigned int> >("PTBTrigs")),
866  fTrigSeparation (ps.get<int> ("TrigSeparation")),
867  fWaveformADCWidth (ps.get<double>("WaveformADCWidth")),
868  fWaveformADCThreshold (ps.get<double>("WaveformADCThreshold")),
869  fWaveformADCsOverThreshold(ps.get<double>("WaveformADCsOverThreshold")),
870  fOpHitADCWidth (ps.get<double>("OpHitADCWidth")),
871  fOpHitADCThreshold (ps.get<double>("OpHitADCThreshold")),
872  fOpHitADCsOverThreshold(ps.get<double>("OpHitADCsOverThreshold")),
873  fADCdiffThreshold (ps.get<int> ("ADCdiffThreshold")),
874  fADCsOverThreshold (ps.get<int> ("ADCsOverThreshold")),
875  fUsePedestalDefault (ps.get<bool> ("UsePedestalDefault")),
876  fUsePedestalFile (ps.get<bool> ("UsePedestalFile")),
877  fUsePedestalFileSearchPath(ps.get<bool> ("UsePedestalFileSearchPath",false)),
878  fPedestalFile (ps.get<std::string>("PedestalFile")),
879  fPedestalFileSearchPath(ps.get<std::string>("PedestalFileSearchPath", "")),
880  fSkipNInputEvents (ps.get<int> ("SkipNInputEvents")),
881  fSkipNOutputEvents (ps.get<int> ("SkipNOutputEvents"))
882 {
884  // Will use same instance names for the outgoing products as for the
885  // incoming ones.
886  prh.reconstitutes<rawDigits_t,art::InEvent>( sourceName_, TPCinputTag_.instance() );
888  prh.reconstitutes<OpHits_t,art::InEvent>( sourceName_, OpHitinputTag_.instance() );
890  // If looking at Monte Carlo, also want to copy the truth information to the split event.
891  if (fMonteCarlo) {
892  prh.reconstitutes<MCPart_t,art::InEvent>( sourceName_, MCPartinputTag_.instance() );
895  //prh.produces< art::Assns< simb::MCParticle, simb::MCTruth> >( MCPartinputTag_.instance() );
896  }
897  //std::cout << "Built TPC Channel Map" << std::endl;
899 }
900 
901 //=======================================================================================
903  //std::cout << "At the top of readFile" << std::endl;
904  // Get fragments branches
905  file_.reset( new TFile(filename.data()) );
906  TTree* evtree = reinterpret_cast<TTree*>(file_->Get(art::rootNames::eventTreeName().c_str()));
907 
908  TPCinputBranch_ = evtree->GetBranch( getBranchName(TPCinputTag_ , TPCinputDataProduct_ ) ); // get branch for TPC input tag
909  SparseinputBranch_ = evtree->GetBranch( getBranchName(SparseinputTag_, SSPinputDataProduct_ ) ); // get branch for Sparsified input tag
910  SSPinputBranch_ = evtree->GetBranch( getBranchName(SSPinputTag_ , SSPinputDataProduct_ ) ); // get branch for SSP input tag
911  OpHitinputBranch_ = evtree->GetBranch( getBranchName(OpHitinputTag_ , OpHitinputDataProduct_ ) ); // get branch for OpHit input tag
912  PenninputBranch_ = evtree->GetBranch( getBranchName(PenninputTag_ , PenninputDataProduct_ ) ); // get branch for Penn Board input tag
913 
914  MCPartinputBranch_ = evtree->GetBranch( getBranchName(MCPartinputTag_ , MCPartinputDataProduct_ ) ); // MCParticle input tag
915  MCTruthinputBranch_ = evtree->GetBranch( getBranchName(MCTruthinputTag_ , MCTruthinputDataProduct_ ) ); // MCTruth input tag
916  MCSimChaninputBranch_ = evtree->GetBranch( getBranchName(MCSimChaninputTag_, MCSimChaninputDataProduct_ ) ); // SimChannel input tag
917 
918  if (TPCinputBranch_) nInputEvts_ = static_cast<size_t>( TPCinputBranch_->GetEntries() );
919  size_t nevt_ssp = 0;
920  if (SparseinputBranch_)
921  nevt_ssp = static_cast<size_t>( SparseinputBranch_->GetEntries() );
922  if (nevt_ssp) {
924  if (fDebugLevel) std::cout << "There is data on the Sparsified branch, so using that." << std::endl;
925  }
926  if (!nevt_ssp)
927  if (SSPinputBranch_)
928  nevt_ssp = static_cast<size_t>( SSPinputBranch_->GetEntries() );
929  size_t nevt_penn = 0;
930  if (PenninputBranch_) nevt_penn = static_cast<size_t>( PenninputBranch_->GetEntries());
931 
932  if (nevt_ssp != nInputEvts_&& nevt_ssp) throw cet::exception("35-ton SplitterInput: Different numbers of RCE and SSP input events in file");
933  if (nevt_penn != nInputEvts_&& nevt_penn) throw cet::exception("35-ton SplitterInput: Different numbers of RCE and Penn input events in file");
934  EventIndex_ = 0ul;
935 
936  EventAuxBranch_ = evtree->GetBranch( "EventAuxiliary" );
937  pevaux_ = &evAux_;
938  EventAuxBranch_->SetAddress(&pevaux_);
939 
940  // ------------ Make my sorted event branch --------------------
941  EventTreeMap.clear();
942  art::RunNumber_t TreeRunNumber; uint16_t IntRunNumber;
943  art::SubRunNumber_t TreeSubRunNumber; uint16_t IntSubRunNumber;
944  art::EventNumber_t TreeEventNumber; uint32_t IntEventNumber;
945  uint64_t CombinedInt;
946 
947  std::cout << "\nfDebugLevel is " << fDebugLevel << ", PedestalDefault is " << fUsePedestalDefault << " fUsePedestalFile is " << fUsePedestalFile << std::endl;
948 
949  art::RunNumber_t PrevRunNumber = -1;
950  for (size_t Tree=1; Tree < nInputEvts_; ++Tree) {
951  EventAuxBranch_->GetEntry(Tree); TreeRunNumber = evAux_.run(); //Get the run number
952  IntRunNumber = (int)TreeRunNumber; TreeSubRunNumber = evAux_.subRun(); IntSubRunNumber = (int)TreeSubRunNumber; //Get the subrun number
953  TreeEventNumber = evAux_.event(); IntEventNumber = (int)TreeEventNumber; //Get the event number
954  CombinedInt = (uint64_t) IntRunNumber << 16 | IntSubRunNumber << 16 | IntEventNumber; // Combine them as a 64 bit int.
955  if (fDebugLevel > 4 )
956  std::cout << "Looking at Tree " << Tree << ", RunNumber " << IntRunNumber << ", SubRunNumber " << IntSubRunNumber << ", EventNumber " << IntEventNumber << ", CrazyNumber " << CombinedInt << std::endl;
957  EventTreeMap[CombinedInt] = Tree; // Add that to a tree - use the fact that this will sort them by Run, Subrun, Event.
958 
959  art::RunNumber_t ThisNumber = evAux_.run();;
960  if (ThisNumber != PrevRunNumber ) {
961  if ( evAux_.isRealData() ) { // If real data subtract pedestal conditions
962  dune::DetPedestalDUNE pedestals("dune35t");
963  pedestals.SetDetName("dune35t");
965  if ( fUsePedestalFile ) {
966  std::string fullname;
968  if( fPedestalFileSearchPath != "" ){
969  std::cout << "SplitterStitcher: fPedestalFileSearchPath: " << fPedestalFileSearchPath << " fPedestalFile: " << fPedestalFile << std::endl;
971  if(fPedestalFile != "" ) sp.find_file(fPedestalFile, fullname);
972  else fullname = cet::getenv(fPedestalFileSearchPath);
973  }//fPedestalFileSearchPath != ""
974  else{
975  std::cout << "SplitterStitcher: fPedestalFileSearchPath: " << fPedestalFileSearchPath << " fPedestalFile: " << fPedestalFile << std::endl;
976  fullname = fPedestalFile;
977  }
978  }//fUsePedestalFileSearchPath
979  else fullname = fPedestalFile;
980 
981  std::cout << "SplitterStitcher: Setting CSVFileName to " << fullname << std::endl;
982  pedestals.SetCSVFileName(fullname);
983  } else {
984  pedestals.SetUseDB(true);
985  }
986  pedestals.Update(ThisNumber);
987  for (size_t ichan=0;ichan<2048;ichan++) {
988  AllPedMap[ThisNumber][ichan].first = pedestals.PedMean(ichan);
989  AllPedMap[ThisNumber][ichan].second = pedestals.PedMeanErr(ichan);
990  if (fDebugLevel > 2) {
991  std::cout << "AllPedMap["<<ThisNumber<<"]["<<ichan<<"] has mean " << pedestals.PedMean(ichan) << " (" << AllPedMap[ThisNumber][ichan].first << ")"
992  << "and error " << pedestals.PedMeanErr(ichan) << " (" << AllPedMap[ThisNumber][ichan].second << "). " << std::endl;
993  }
994  }
995  PrevRunNumber = ThisNumber;
996  }
997  }
998  }
999 
1000  // New fileblock
1001  fb = new art::FileBlock(art::FileFormatVersion(),filename);
1002  if ( fb == nullptr ) {
1004  << "Unable to open file " << filename << ".\n";
1005  }
1006 
1008  fTree = tfs->make<TTree>("EventInfo","Split event information");
1009  fTree->Branch("AttemptedEvents",&AttemptedEvents,"AttemptedEvents/I");
1010  fTree->Branch("VoidedEvents" ,&VoidedEvents ,"VoidedEvents/I" );
1011  fTree->Branch("GoodEvents" ,&GoodEvents ,"GoodEvents/I" );
1012  fTree->Branch("GivenRunNum" ,&GivenRunNum ,"GivenRunNum[AttemptedEvents]/I" );
1013  fTree->Branch("GivenSubRunNum" ,&GivenSubRunNum ,"GivenSubRunNum[AttemptedEvents]/I" );
1014  fTree->Branch("GivenEventNum" ,&GivenEventNum ,"GivenEventNum[AttemptedEvents]/I" );
1015  fTree->Branch("TreeIndexStart" ,&TreeIndexStart ,"TreeIndexStart[AttemptedEvents]/I" );
1016  fTree->Branch("ChansAtStartOfEvent",&ChansAtStartOfEvent,"ChansAtStartOfEvent[AttemptedEvents]/I");
1017  fTree->Branch("ChansAtEndOfEvent" ,&ChansAtEndOfEvent ,"ChansAtEndOfEvent[AttemptedEvents]/I" );
1018 
1020  for (size_t q=0; q<ArraySize; ++q)
1022 
1023  return true;
1024 }
1025 
1026 //=======================================================================================
1028  art::SubRunPrincipal* const& inSR,
1029  art::RunPrincipal* & outR,
1030  art::SubRunPrincipal* & outSR,
1031  art::EventPrincipal* & outE) {
1032  //std::cout << "At the start of readNext..." << std::endl;
1033  if (!fRequireRCE) {
1034  std::cout << "Entering NoRCEsCase" << std::endl;
1035  bool Return = NoRCEsCase(outR, outSR, outE);
1036  std::cout << "Left NoRCEsCase" << std::endl;
1037  return Return;
1038  }
1039 
1040  if ( doneWithFiles_ ) {
1041  return false;
1042  }
1044  size_t FirstDigIndex;
1045  size_t FirstDigEventIndex;
1046  size_t FirstDigEvent;
1047  bool first_tick = true; // The earliest time in this new split event, so want to calculate time of this for use with first_timestamp variable only!
1048  bool NewTree;
1049  bool JumpEvent = false;
1050  size_t JumpNADC = 0;
1051 
1052  std::map<int,int> PrevChanADC;
1053  if (fDebugLevel > 3 ) {
1054  std::cout << "\nAt the top of readNext....what do I increment here? " << fTicksAccumulated << " " << ticksPerEvent_ << " " << loadedDigits_.empty(fDebugLevel)
1055  << " " << wbuf_.size() << " " << cbuf_.size() << " " << hbuf_.size() << std::endl;
1056  }
1057  while ( fTicksAccumulated < ticksPerEvent_ ) {
1059  NewTree = false;
1060  prev_timestamp = this_timestamp; // set prev_timestamp to old timestamp
1061 
1062  // ************* Check if loadedDigits is empty... ************************
1063  while (loadedDigits_.empty(fDebugLevel)) {
1064  if (fDebugLevel > 3 ) std::cout << "\nLoaded digits is empty..." << std::endl;
1065  if ( fTrigger ) { // Want to load wbuf with end of last event, before loading new data.
1069  if (fDebugLevel > 2 ) {
1070  std::cout << "Loaded digits was empty, will be refilled..."
1071  << "\nwbuf_ has size " << wbuf_.size() << " at " << first_timestamp << " " << last_timestamp << " " << fNovaTicksPerSSPTick
1072  << "\nhbuf_ has size " << hbuf_.size() << " at " << first_timestamp << " " << last_timestamp << " " << fNovaTicksPerSSPTick
1073  << "\ncbuf_ has size " << cbuf_.size() << " at " << first_timestamp << " " << last_timestamp << " " << fNovaTicksPerCountTick
1074  << std::endl;
1075  }
1076  }
1077  bool rc = loadEvents_(EventIndex_);
1078  //std::cout << "Loaded a new event..." << EventIndex_ << " " << loadedDigits_.empty(fDebugLevel) << " " << loadedWaveforms_.empty()
1079  // << " " << loadedCounters_.empty() << " " << loadedOpHits_.empty() << " " << RCEsPresent << std::endl;
1080  if (!RCEsPresent && (!loadedWaveforms_.empty() || !loadedOpHits_.empty())) {
1081  if (fDebugLevel) std::cout << "\nThe RCEs aren't present, so switching to the don't require RCEs case...." << std::endl;
1082  bool Return = NoRCEsCase(outR, outSR, outE);
1083  return Return;
1084  } // RCEsPresent
1085  if (fDebugLevel > 2) std::cout << "There are a total of " << loadedDigits_.digits[0].NADC() << " ADC's " << std::endl;
1086  if (!rc) {
1087  doneWithFiles_ = (file_->GetName() == lastFileName_);
1088  //std::cout << "Loaded the final file..." << std::endl;
1089  return false;
1090  }
1091  NewTree = true;
1092  first_tick = true; // Just loaded in new event, so want to reset first_timestamp...doesn't effect previous loaded event.
1093  first_timestamp=0, last_timestamp=0; // Want to reset the timestamps.
1094  // ******* Check that the time stamps lead on from one another!! ***********
1095  if ( loadedDigits_.digits.size() != 0 && loadedDigits_.digits[0].NADC() ) {
1096  if (fTrigger ) {
1097  if (loadedDigits_.size() != fChansPresent) {
1098  if (fDebugLevel)
1099  std::cout << "\nThere are inconsistent numbers of digits between this millislice and the previous millislice: "
1100  << loadedDigits_.size() << " not " << fChansPresent << ". This means data is corrupted. Voiding this trigger."
1101  << std::endl;
1108  ++AttemptedEvents;
1109  ++VoidedEvents;
1110  Reset();
1111  } else {
1112  CheckTimestamps( JumpEvent, JumpNADC ); // Check that the time stamps lead on from one another!!
1113  } // If triggered and good digit consistency, check timestamps.
1114  } // If triggered check digit consistency, and timestamps
1115  } // If digits has size
1116  } // loadedDigits_.empty()
1117 
1118  if (NewTree) {
1119  if (JumpEvent) {
1120  loadedDigits_.index = fPreTriggerTicks - JumpNADC;
1121  JumpEvent = false;
1122  JumpNADC = 0;
1123  }
1124  if (fDebugLevel) std::cout << "\nLooking at EventIndex " << EventIndex_-1 << ", index " << loadedDigits_.index << std::endl;
1125  }
1126 
1127  std::vector<short> nextdigits = loadedDigits_.next();
1128  // Check if I am straddling over a readout boundary within this microslice....
1129  if (DigitsIndexList.size() > 1) {
1130  for (unsigned int IndexListLoop = 1; IndexListLoop<DigitsIndexList.size(); ++IndexListLoop ) {
1131  if (loadedDigits_.index-1 == DigitsIndexList[IndexListLoop].first.first) {
1132  if (fDebugLevel) std::cout << "\nI am looking at loadedDigitsIndex " << loadedDigits_.index << ". This is the index where the jump occurs so I want to reset stuff." << std::endl;
1133  Reset();
1134  NewTree = true;
1135  lbne::TpcNanoSlice::Header::nova_timestamp_t NewStamp = DigitsIndexList[IndexListLoop].second - (DigitsIndexList[IndexListLoop].first.first*fNovaTicksPerTPCTick);
1136  loadedDigits_.loadTimestamp(NewStamp);
1137  if (fDebugLevel) std::cout << "I have reset the event... and loaded a new timestamp " << NewStamp << " as opposed to " << DigitsIndexList[IndexListLoop].second << std::endl;
1138  }
1139  }
1140  }
1141  // Get the timestamp for this index.
1142  this_timestamp = loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick);
1143  if (fTrigger && fDebugLevel > 4) {
1144  std::cout << "Index " << loadedDigits_.index << " " << fTicksAccumulated << " " << prev_timestamp << " " << this_timestamp << std::endl;
1145  }
1146  // ******* See if can trigger on this tick...only want to do this if haven't already triggered. We also don't want two triggers too close together!... *****************
1148  Triggering (PrevChanADC, nextdigits, NewTree);
1149  } // if TickAccumulated == 0
1150 
1151  // ******* What do we want to do for every tick we have triggered on? *****************
1152  if ( fTrigger ) {
1153  if (fTicksAccumulated == 0 ) { // Have only just triggered!
1154  FirstDigIndex = loadedDigits_.index;
1155  FirstDigEventIndex = EventIndex_ - 1;
1156  FirstDigEvent = inputEventNumber_;
1158  fChansPresent = nextdigits.size();
1159  if (fDebugLevel) {
1160  std::cout << "\nThe trigger is good so triggering on, EventIndex " << fLastEventIndex << " corresponding to event " << fLastEvent
1161  << ", loadedDigits_.index() " << fLastTriggerIndex << ", with timestamp " << fLastTimeStamp << ", there are " << fChansPresent << " digits in this event."
1162  << "\nThe first tick in this event is in EventIndex " << FirstDigEventIndex << ", event " << FirstDigEvent << ", loadedDigits index " << loadedDigits_.index
1163  << ". It has timestamp " << this_timestamp
1164  << std::endl;
1165  }
1166  }
1167  if (first_tick) { // First tick in split event and/or first tick in newly loaded event.
1169  first_tick = false;
1170  }
1172 
1173  // ************* Now want to load the RCE information into dbuf_ ************************
1174  if (dbuf_.size() == 0) {
1175  RawDigit::ADCvector_t emptyvector;
1176  for (size_t ichan=0;ichan<nextdigits.size();ichan++) dbuf_.push_back(emptyvector);
1177  }
1178  for (size_t ichan=0;ichan<nextdigits.size();ichan++) {
1179  dbuf_[ichan].push_back(nextdigits[ichan]);
1180  }
1181  fTicksAccumulated ++;
1182  } // If triggered on this tick!
1183  // ************* Now Done for this tick ************************
1184 
1185  // If I want to skip N Output events, I want to delete the event now that I have made it...
1187  if (fDebugLevel) std::cout << "I have skipped " << gSkippedOuputEvents << " events of a desired " << fSkipNOutputEvents << ". I am now voiding another...\n" << std::endl;
1189  Reset();
1190  }
1191  } // while ticks accumulated < ticksperEvent
1192 
1193  if (fDebugLevel > 1)
1194  std::cout << "\nGot enough ticks now start building the events...Start/End time for Waveforms/Counters are " << first_timestamp << " " << last_timestamp << std::endl;
1195  // ************* Fill wbuf_ with the SSP information within time range ************************
1196  if (fDebugLevel > 1)
1197  std::cout << "Loading the Waveforms...wbuf_ has size " << wbuf_.size() << " " << fNovaTicksPerSSPTick << std::endl;
1199  if (fDebugLevel > 1)
1200  std::cout << "wbuf_ now has size " << wbuf_.size() << std::endl;
1201 
1202  // ************* Fill hbuf_ with the OpHit information within time range ************************
1203  if (fDebugLevel > 1)
1204  std::cout << "Loading the Waveforms...hbuf_ has size " << hbuf_.size() << " " << fNovaTicksPerSSPTick << std::endl;
1206  if (fDebugLevel > 1)
1207  std::cout << "hbuf_ now has size " << hbuf_.size() << std::endl;
1208 
1209  // ************* Fill cbuf_ with the PTB information within time range ************************
1210  if (fDebugLevel > 1)
1211  std::cout << "Loading the Counters! cbuf size " << cbuf_.size() << " counterticks " << fNovaTicksPerCountTick << std::endl;
1213  if (fDebugLevel > 1)
1214  std::cout << "Now cbuf has size " << cbuf_.size() << std::endl;
1215 
1216  // ******** Now Build the event *********
1220  if ( runNumber_ != cachedRunNumber_ ) {
1221  outR = sh_.makeRunPrincipal(runNumber_,this_art_event_timestamp);
1223  eventNumber_ = 0ul;
1224  }
1226  outSR = sh_.makeSubRunPrincipal(runNumber_,subRunNumber_,this_art_event_timestamp);
1228  eventNumber_ = 0ul;
1229  }
1230 
1231  // ************* Now fill dbuf_ with TPC information collected ************************
1232  if (fDebugLevel > 1) std::cout << "Just about to fill d " << fTicksAccumulated << " " << dbuf_.size() << std::endl;
1233  for (size_t ichan=0;ichan<dbuf_.size();ichan++) {
1234  RawDigit d(loadedDigits_.digits[ichan].Channel(), fTicksAccumulated, dbuf_[ichan] //,loadedDigits_.digits[ichan].Compression()
1235  );
1236  if (evAux_.isRealData() ) { //If looking at real data!
1237  d.SetPedestal(AllPedMap[runNumber_][loadedDigits_.digits[ichan].Channel()].first,
1238  AllPedMap[runNumber_][loadedDigits_.digits[ichan].Channel()].second );
1239  if (fDebugLevel > 3) {
1240  std::cout << "digit[0] corresponding to channel " << d.Channel() << " ("<<ichan<<") has ADC value " << d.ADC(0)
1241  << ", pedestal "<<d.GetPedestal()<<" ["<<AllPedMap[runNumber_][loadedDigits_.digits[ichan].Channel()].first <<"],"
1242  << " and sigma "<<d.GetSigma() <<" ["<<AllPedMap[runNumber_][loadedDigits_.digits[ichan].Channel()].second<<"]."
1243  << std::endl;
1244  }
1245  } else { //If looking at Truth
1246  d.SetPedestal(loadedDigits_.digits[ichan].GetPedestal(),
1247  loadedDigits_.digits[ichan].GetSigma() );
1248  if (fDebugLevel > 3)
1249  std::cout << "Looking at Monte Carlo, so using pedestals loaded from event, channel " << ichan
1250  << ", pedestal " << d.GetPedestal() << " ("<<loadedDigits_.digits[ichan].GetPedestal()<<")"
1251  << ", sigma " << d.GetSigma() << " ("<<loadedDigits_.digits[ichan].GetSigma()<<")." << std::endl;
1252  }
1253  bufferedDigits_.emplace_back(d);
1254  }
1255 
1256  // If looking at Monte Carlo, now want to add the Truth stuff
1257  if (fMonteCarlo) {
1259  if (fDebugLevel) std::cout << "Have now returned from TakeMCParts, it has size " << mcbuf_.size() << std::endl;
1261  if (fDebugLevel) std::cout << "Have now returned from TakeMCSimChans, it has size " << simchanbuf_.size() << std::endl;
1262  }
1263 
1264  // Create event using the time from the data.
1265  makeEventAndPutDigits_( outE, this_art_event_timestamp);
1266 
1267  // ******** Reset loadedDigits_.index and TreeIndex_ to where the trigger was *********
1268  if (fDebugLevel) {
1269  std::cout << "The event triggered on Event Index " << fLastEventIndex << ", event " << fLastEvent << ", tick " << fLastTriggerIndex << ".\n"
1270  << "It went from EventIndex " << FirstDigEventIndex << ", event " << FirstDigEvent << ", tick " << FirstDigIndex
1271  << " to Tree index " << EventIndex_-1 << ", event " << inputEventNumber_ << ", tick " << loadedDigits_.index << ".\n"
1272  << "I want to reset the tick value for sure, but do I need to reload the digits because EventIndex is different?" << std::endl;
1273  }
1274  if ( EventIndex_-1 != fLastEventIndex ) {
1275  if (fDebugLevel) std::cout << "Yes I do! Changing EventIndex_ to fLastEventIndex...Also want to clear loadedDigits." << std::endl;
1277  loadedDigits_.index = 0;
1278  loadedDigits_.clear(fDebugLevel);
1280  } else {
1281  if (fDebugLevel) std::cout << "No, I'm still looking at the same tree!\n" << std::endl;
1282  }
1285 
1286  return true;
1287 } // read next
1288 
1289 //=======================================================================================
1291  file_.reset(nullptr);
1292  fTree->Fill();
1293 }
1294 
1295 //=======================================================================================
1296 bool DAQToOffline::Splitter::eventIsFull_( vector<RawDigit> const & v ) {
1297  return v.size() == ticksPerEvent_;
1298 }
1299 
1300 //=======================================================================================
1301 bool DAQToOffline::Splitter::loadEvents_( size_t &LoadEventIndex ) {
1302  //std::cout << "At the start of loadEvents..." << std::endl;
1303  if ( LoadEventIndex != nInputEvts_ ) {
1304  if ( !loadedDigits_.empty(fDebugLevel) && fRequireRCE ) return false;
1305 
1306  // I want to look through my map to find correct tree for this event, whilst ensuring I skip the neccessary number of events....
1307  bool GoodTree = false;
1308  size_t LoadTree = 0;
1309  while (!GoodTree) {
1310  int LookingAtIndex = 0;
1311  for (std::map<uint64_t,size_t>::iterator it=EventTreeMap.begin(); it!=EventTreeMap.end(); ++it ) {
1312  ++LookingAtIndex;
1313  if ( LookingAtIndex == (int)LoadEventIndex ) {
1314  // Is this index high enough?
1315  if (LookingAtIndex > fSkipNInputEvents ) {
1316  LoadTree = it->second;
1317  GoodTree = true;
1318  }
1319  break;
1320  }
1321  } // For Loop
1322  if (fDebugLevel > 2)
1323  std::cout << "Looking for event " << LoadEventIndex << ", it was found at TreeIndex " << LookingAtIndex << " but I want to skip " << fSkipNInputEvents << ". Do I load this tree? " << GoodTree << std::endl;
1324  if (!GoodTree) ++LoadEventIndex;
1325  } // While Loop
1326  // I want to look through my map to find correct tree for this event!
1327 
1328  EventAuxBranch_->GetEntry(LoadTree);
1333  if (fDebugLevel > 1)
1334  std::cout << "\nLoading event " << inputEventNumber_ << " at EventIndex " << LoadEventIndex << " on TreeIndex " << LoadTree << std::endl;
1335 
1336  bool PTBTrigPresent = false;
1337  if (fRequirePTB) {
1338  PTBTrigPresent= LoadPTBInformation( LoadTree );
1339  }
1340 
1341  if ( fWhichTrigger.size() == 1 && fWhichTrigger[0] == 3 ) { // If looking for only looking for triggers from the PTB
1342  if ( PTBTrigPresent || fTrigger ) { // Only load RCEs and SSPs if a trigger is present.
1343  if (fRequireSSP) LoadSSPInformation( LoadTree );
1344  if (fRequireRCE) LoadRCEInformation( LoadTree );
1345  } else { // If no PTB trigger is present make sure to clear Digits and Waveforms.
1349  }
1350  } else { // If either not looking for PTB triggers at all, or looking for additional triggers too, then always load RCE/SSP.
1351  if (fRequireSSP) LoadSSPInformation( LoadTree );
1352  if (fRequireRCE) LoadRCEInformation( LoadTree );
1353  }
1354  // If Looking at MonteCarlo, also want to load in some other stuff....
1355  if (fMonteCarlo) {
1356  auto *particles = getMCParticles(MCPartinputBranch_, LoadTree);
1357  MonteCarlo_.loadMCParts(*particles);
1358  auto *truths = getMCTruths(MCTruthinputBranch_, LoadTree);
1359  mctruth_ = *truths;
1360  auto *simchans = getMCSimChans(MCSimChaninputBranch_, LoadTree);
1361  MonteCarlo_.loadSimChans(*simchans);
1362  }
1363 
1364  LoadEventIndex++;
1365  return true;
1366  }
1367  else return false;
1368 } // load digits
1369 //=======================================================================================
1371  bool TrigPresent = false;
1372  if (PenninputDataProduct_.find("Fragment") != std::string::npos) {
1373  auto* PennFragments = getFragments ( PenninputBranch_, LoadTree );
1374  lbne::PennMicroSlice::Payload_Timestamp *FirstPTBTimestamp = nullptr;
1375  std::vector<raw::ExternalTrigger> counters = DAQToOffline::PennFragmentToExternalTrigger( *PennFragments, fPTBMap, FirstPTBTimestamp );
1376  loadedCounters_.load( counters, fDebugLevel );
1377  if (fDebugLevel > 1) std::cout << "Counters has size " << counters.size() << std::endl;
1378 
1379  for (size_t CountLoop = 0; CountLoop < counters.size(); ++CountLoop) {
1380  if (fDebugLevel > 3 )
1381  std::cout << "Looking at counters[" << CountLoop << "] has CounterID " << counters[CountLoop].GetTrigID() << " and Timestamp " << counters[CountLoop].GetTrigTime() << std::endl;
1382  for (size_t PTB = 0; PTB < fPTBTrigs.size(); ++PTB) {
1383  if ( counters[CountLoop].GetTrigID() == fPTBTrigs[PTB] ) {
1384  if (fDebugLevel) std::cout << "\nThere is a trigger on channel " << counters[CountLoop].GetTrigID() << " at time " << counters[CountLoop].GetTrigTime() << " in event " << inputEventNumber_ << std::endl;
1385  TrigPresent = true;
1386  }
1387  }
1388  }
1389  } else {
1390  auto *counters = getRawExternalTriggers(PenninputBranch_, LoadTree );
1391  loadedCounters_.load( *counters, fDebugLevel );
1392  if (fDebugLevel > 1) {
1393  std::cout << "Counters has size" << counters->size() << std::endl;
1394  }
1395 
1396  for (auto count: *counters) {
1397  if (fDebugLevel > 3 )
1398  std::cout << "Looking at a counter which has CounterID " << count.GetTrigID() << " and Timestamp " << count.GetTrigTime() << std::endl;
1399  for (size_t PTB = 0; PTB < fPTBTrigs.size(); ++PTB) {
1400  if ( count.GetTrigID() == fPTBTrigs[PTB] ) {
1401  if (fDebugLevel) std::cout << "Looking at event " << inputEventNumber_ << ", there is a trigger here on channel " << count.GetTrigID() << std::endl;
1402  TrigPresent = true;
1403  }
1404  }
1405  }
1406  }
1407  return TrigPresent;
1408 }
1409 //=======================================================================================
1411  if (SSPinputDataProduct_.find("Fragment") != std::string::npos) {
1412  auto* SSPfragments = getFragments( SSPinputBranch_, LoadTree );
1413  std::vector<raw::OpDetWaveform> waveforms;
1414  std::vector<recob::OpHit> hits;
1415  sspReform.SSPFragmentToWaveformsAndHits(*SSPfragments, waveforms, hits);
1416  if (fDebugLevel > 3 ) {
1417  for ( size_t WaveLoop=0; WaveLoop < waveforms.size(); ++WaveLoop ) {
1418  int64_t SSPTime = waveforms[WaveLoop].TimeStamp()*fNovaTicksPerSSPTick;
1419  std::cout << "Looking at waveform[" << WaveLoop << "] it has channel number " << waveforms[WaveLoop].ChannelNumber()
1420  << " and timestamp " << SSPTime << ", and size " << waveforms[WaveLoop].size() << std::endl;
1421  }
1422  for ( size_t HitLoop=0; HitLoop < hits.size(); ++HitLoop ) {
1423  int64_t OpHitTime = hits[HitLoop].PeakTime()*fNovaTicksPerSSPTick;
1424  std::cout << "Looking at waveform[" << HitLoop << "] it is on channel number " << hits[HitLoop].OpChannel() << " at timestamp " << OpHitTime << std::endl;
1425  }
1426  }
1427 
1428  if (fDebugLevel > 1)
1429  std::cout << "Loaded waveforms has size " << waveforms.size() << ", and OpHits has size " << hits.size() << std::endl;
1430  if (waveforms.size() && hits.size()) std::cout << "\n They Both have non-zero size!!!!\n\n\n" << std::endl;
1431  loadedWaveforms_.load( waveforms, fDebugLevel );
1432  loadedOpHits_.load ( hits , fDebugLevel );
1433  }
1434  else {
1435  auto* waveforms = getSSPWaveforms(SSPinputBranch_, LoadTree );
1436  if (fDebugLevel > 1) std::cout << "Loaded waveforms has size " << waveforms->size() << std::endl;
1437  loadedWaveforms_.load( *waveforms, fDebugLevel );
1438  if ( evAux_.isRealData() ) {
1439  auto* hits = getOpHits(OpHitinputBranch_, LoadTree );
1440  if (fDebugLevel > 1) std::cout << "Loaded OpHits has size " << hits->size() << std::endl;
1441  loadedOpHits_.load( *hits, fDebugLevel );
1442  } else {
1443  std::vector<recob::OpHit> hits;
1444  hits.clear();
1445  loadedOpHits_.load( hits, fDebugLevel );
1446  }
1447  }
1448  return;
1449 }
1450 //=======================================================================================
1452  if (TPCinputDataProduct_.find("Fragment") != std::string::npos) {
1453  //RCEsPresent = true;
1454  lbne::TpcNanoSlice::Header::nova_timestamp_t firstTimestamp = 0;
1455  auto* fragments = getFragments( TPCinputBranch_, LoadTree );
1457  rawDigits_t const digits = fragmentsToDigits_( *fragments, DigitsIndexList, firstTimestamp, TPCChannelMap );
1458  if (!digits.size() && EventIndex_ == 0) {
1459  RCEsPresent = false;
1460  fRequireRCE = false;
1461  }
1462  loadedDigits_.load( digits, fDebugLevel );
1463  loadedDigits_.loadTimestamp( firstTimestamp );
1464  if (fDebugLevel > 1) std::cout << "Loaded RCE information with timestamp " << firstTimestamp << std::endl;
1465  }
1466  else {
1467  auto* digits = getRawDigits(TPCinputBranch_, LoadTree );
1468  loadedDigits_.load( *digits, fDebugLevel);
1469  loadedDigits_.loadTimestamp(0); // MC timestamp is zero (? assume?)
1470  if (fDebugLevel > 1) std::cout << "Loaded MC RCE's with timestamp 0" << std::endl;
1471  }
1472 }
1473 //=======================================================================================
1475  // just keep incrementing the event number as we split along
1476  ++eventNumber_;
1477 
1478  for (size_t TrigSize = 0; TrigSize < fWhichTrigger.size(); ++TrigSize) {
1479  if ( fWhichTrigger[TrigSize] == 0 && fDebugLevel) {
1480  std::cout << "\n\n\nI hope you know that you are triggering on a random number of ticks and not any sort of data! Check that fwhichTrigger is set correctly.\n\n\n" << std::endl;
1481  }
1482  }
1483  std::cout << "\nMaking an event with RunNumber " << runNumber_ << ", subRunNumber " << subRunNumber_ << ", EventNumber " << eventNumber_ << " and art_timestamp " << art_timestamp.value() << std::endl;
1484 
1486  art::put_product_in_principal( std::make_unique<rawDigits_t>(bufferedDigits_),
1487  *outE,
1488  sourceName_,
1489  TPCinputTag_.instance() );
1490  art::put_product_in_principal( std::make_unique<SSPWaveforms_t>(wbuf_),
1491  *outE,
1492  sourceName_,
1493  SSPinputTag_.instance() );
1494  art::put_product_in_principal( std::make_unique<OpHits_t>(hbuf_),
1495  *outE,
1496  sourceName_,
1498  art::put_product_in_principal( std::make_unique<PennCounters_t>(cbuf_),
1499  *outE,
1500  sourceName_,
1501  PenninputTag_.instance() );
1502 
1503  if (fMonteCarlo) {
1504  art::put_product_in_principal( std::make_unique<MCPart_t>(mcbuf_),
1505  *outE,
1506  sourceName_,
1508  art::put_product_in_principal( std::make_unique<MCTruth_t>(mctruth_),
1509  *outE,
1510  sourceName_,
1512  art::put_product_in_principal( std::make_unique<MCSimChan_t>(simchanbuf_),
1513  *outE,
1514  sourceName_,
1516  //std::unique_ptr< art::Assns< simb::MCParticle, simb::MCTruth> > assn( new art::Assns<simb::MCParticle, simb::MCTruth> );
1517  //util::CreateAssn(*this, eventNumber_, mcbuf_, mctruth_, *assn);
1518  //art::put_product_in_principal( std::make_unique_ptr<art::Assns< simb::MCParticle, simb::MCTruth> >(assn),
1519  // *outE,
1520  // sourceName_,
1521  // MCPartinputTag_.instance() );
1522  }
1529  ++AttemptedEvents;
1530  ++GoodEvents;
1531 
1532  mf::LogDebug("SplitterFunc") << "Producing event: " << outE->eventID() << " with " << bufferedDigits_.size() << " RCE digits and " <<
1533  wbuf_.size() << " SSP waveforms, " << hbuf_.size() << " OpHits and " << cbuf_.size() << " External Triggers (muon counters)";
1534  Reset();
1535 }
1536 //=======================================================================================
1538  bufferedDigits_.clear();
1539  for (size_t ichan=0;ichan<dbuf_.size();ichan++) { dbuf_[ichan].clear(); }
1540  dbuf_.clear();
1541  wbuf_.clear();
1542  hbuf_.clear();
1543  cbuf_.clear();
1544  Event_timestamp = 0;
1545  fTicksAccumulated = 0; // No longer have any RCE data...
1546  fTrigger = false; // Need to re-decide where to trigger
1547  fDiffFromLastTrig = 0; // Reset trigger counter.
1548  fChansPresent = 0;
1549  if (fDebugLevel > 1) std::cout << "Resetting everything (dbuf, cbuf, wbuf, hbuf, Trigger, etc)" << std::endl;
1550 }
1551 //=======================================================================================
1552 void DAQToOffline::Splitter::CheckTimestamps(bool &JumpEvent, size_t &JumpNADC ) {
1553  int StampDiff = loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick) - prev_timestamp;
1554  if (fDebugLevel) std::cout << "\n" << StampDiff << " = " << loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick) << " - " << prev_timestamp << std::endl;
1555  if ( fabs(StampDiff) > fTimeStampThreshold ) { // Timestamps of old and new file too far apart. So want to clear all previously loaded event.
1556  if (fDebugLevel) std::cout << "\nThe absolute gap between timestamps is " << fabs(StampDiff) << " which is more than the threshold " << fTimeStampThreshold << std::endl;
1557  bool fixed = false;
1558  if ( StampDiff < 0 ) { // got overlapping timestamps.
1559  if (fDebugLevel) std::cout << "Stamp diff is negative...need to figure out how to try and fix..." << std::endl;
1560  //fixed = true;
1561  } else {
1562  if (fDebugLevel) std::cout << "Stamp diff is positive...need to figure out how to try and fix..." << std::endl;
1563  //fixed=true;
1564  }
1565  if (!fixed) {
1566  if (fDebugLevel) std::cout << "\nCan't reconcile the timestamps, so voiding this trigger :( \n" << std::endl;
1567  Reset();
1569  if (fPreTriggerTicks > loadedDigits_.digits[0].NADC() ) {
1570  JumpEvent = true;
1571  JumpNADC = loadedDigits_.digits[0].NADC();
1572  }
1574  this_timestamp = loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick);
1575  fLastTriggerIndex = 0;
1576  } else {
1577  if (fDebugLevel) std::cout << "\nRectified the timestamps, carry on building event :D\n" << std::endl;
1578  }
1579  } else {
1580  if (fDebugLevel) std::cout << "\nTimestamps lead on from each other, carry on :)" << std::endl;
1581  }
1582 } // Check Timestamps
1583 //=======================================================================================
1585  fCheatPTBTrig = fCheatSSPTrig = true; // Want to 'cheat' SSP and PTB trigs in this case. Cheat means look over whole event time, not a small range of ticks.
1586  while (!fTrigger) {
1587  bool NewTree = false;
1588  // Whilst LoadedWaveforms and LoadedCounters are empty, load a new event...
1589  while (!NewTree) {
1590  if( loadedWaveforms_.empty() && loadedOpHits_.empty() ) {
1591  bool rc = loadEvents_(EventIndex_);
1592  if (!rc) {
1593  doneWithFiles_ = (file_->GetName() == lastFileName_);
1594  return false;
1595  }
1596  } else NewTree = true;
1597  } // while not NewTree ( Waveforms and OpHits are empty )
1598  std::map<int,int> PrevChanADC;
1599  std::vector<short> ADCdigits;
1600  Triggering(PrevChanADC, ADCdigits, NewTree);
1601  }
1602  wbuf_ = loadedWaveforms_.TakeAll();
1603  hbuf_ = loadedOpHits_.TakeAll();
1604  cbuf_ = loadedCounters_.TakeAll();
1605  if (fDebugLevel) std::cout << "After looking at EventIndex_ " << EventIndex_-1 << ", event " << inputEventNumber_ << " wbuf, hbuf cbuf have sizes " << wbuf_.size() << ", " << hbuf_.size() << ", " << cbuf_.size() << std::endl;
1606 
1607  // ******** Now Build the event *********
1610  //art::Timestamp ts; // LBNE should decide how to initialize this -- use first_timestamp converted into an art::Timestamp
1611  //FIXME - This is a first attempt at interpreting the novatimestamp from the tpc data to create an art event timestamp
1612  if (cbuf_.size()) {
1613  Event_timestamp = cbuf_[0].GetTrigTime();
1614  if (wbuf_.size() && wbuf_[0].TimeStamp() < Event_timestamp) Event_timestamp = wbuf_[0].TimeStamp();
1615  if (hbuf_.size() && hbuf_[0].PeakTime() < Event_timestamp) Event_timestamp = hbuf_[0].PeakTime();
1616  } else {
1617  if (wbuf_.size()) {
1618  Event_timestamp = wbuf_[0].TimeStamp();
1619  if (hbuf_.size() && hbuf_[0].PeakTime() < Event_timestamp) Event_timestamp = hbuf_[0].PeakTime();
1620  } else Event_timestamp = hbuf_[0].PeakTime();
1621  }
1622 
1624  if ( runNumber_ != cachedRunNumber_ ) {
1625  outR = sh_.makeRunPrincipal(runNumber_,this_art_event_timestamp);
1627  eventNumber_ = 0ul;
1628  }
1630  outSR = sh_.makeSubRunPrincipal(runNumber_,subRunNumber_,this_art_event_timestamp);
1632  eventNumber_ = 0ul;
1633  }
1634  //inputEventTime_ is the art::Timestamp() of the online art::Event() used to create the offline art::Event()
1635  makeEventAndPutDigits_( outE, this_art_event_timestamp );
1636  Reset();
1638  loadedOpHits_.clear(fDebugLevel);
1640  return true;
1641 }
1642 //=======================================================================================
1644  size_t TempEventIndex = EventIndex_ -1;
1645  art::EventNumber_t TempEventNumber = inputEventNumber_;
1646  size_t TempTriggerIndex = loadedDigits_.index;
1647  lbne::TpcNanoSlice::Header::nova_timestamp_t TempTimeStamp = this_timestamp;
1648  size_t TempNADCs = loadedDigits_.digits[0].NADC();
1649 
1650  if (fDebugLevel) std::cout << "\nTrying to Trigger on timestamp " << this_timestamp << std::endl;
1651 
1652  //******** Now to sort out the prebuffer!!! ***********
1653  int BufferResidual = loadedDigits_.index - fPreTriggerTicks;
1654  if ( BufferResidual > 0 ) {
1655  if (fDebugLevel) {
1656  std::cout << "I have enough previous digits in this event for the prebuffer (" << BufferResidual << " = " << loadedDigits_.index << " - " << fPreTriggerTicks
1657  << ")! Moving loadedDigits_.index to " << BufferResidual << std::endl;
1658  }
1659  loadedDigits_.index = BufferResidual;
1660  }
1661  else { // Don't have enough ticks in the event for the prebuffer :( so need to load previous events!
1662  BufferResidual = -BufferResidual;
1663  lbne::TpcNanoSlice::Header::nova_timestamp_t TrigEvStart = loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick);
1664  if (fDebugLevel) {
1665  std::cout << "I don't have enough previous digits :(, I need an extra " << BufferResidual << " ticks from previous events. TrigEvStart = " << TrigEvStart
1666  << ". I'm going to have to load the previous event to try and find these ticks..."
1667  << std::endl;
1668  }
1669  // ASSUMPTION! Only worth loading the previous event, as won't want more than one readout of pretrigger window.
1670  if (EventIndex_ < 3) {
1671  std::cout << "No previous event to load, so can't get a good event. Voiding the trigger." << std::endl;
1672  } else {
1673  loadedDigits_.index = 0; // Clear loadedDigits
1674  loadedDigits_.clear(fDebugLevel); // Clear loadedDigits
1677  this_timestamp = loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick);
1678  if ( BufferResidual - (int)loadedDigits_.digits[0].NADC() < 0 ) {
1679  loadedDigits_.index = loadedDigits_.digits[0].NADC() - BufferResidual;
1680  if (fDebugLevel)
1681  std::cout << "I have satisfied the pretrigger conditions, on the previous EventIndex " << EventIndex_-1 << " corresponding to event " << inputEventNumber_ << ". It has " << loadedDigits_.digits[0].NADC()
1682  << " ADCs, so switching the index to " << loadedDigits_.index << std::endl;
1683  } else { // ^ If enough ticks in previous event to satisfy pre-trigger ^
1684  if (fDebugLevel)
1685  std::cout << "I can't satisfy the pretrigger conditions, on the previous event. So loading old event :(" << std::endl;
1686  loadedDigits_.index = 0; // Clear loadedDigits
1687  loadedDigits_.clear(fDebugLevel); // Clear loadedDigits
1688  EventIndex_ = TempEventIndex;
1690  loadedDigits_.index = TempTriggerIndex;
1691  fTrigger = false;
1692  std::cout << "Have I reloaded everything properly?"
1693  << "\nEventIndex " << TempEventIndex << ", Event " << TempEventNumber << ", Index " << TempTriggerIndex << ", NADCs " << TempNADCs
1694  << "\nEventIndex " << EventIndex_-1 << ", Event " << inputEventNumber_ << ", Index " << loadedDigits_.index << ", NADCs " << loadedDigits_.digits[0].NADC()
1695  << std::endl;
1696  } // ^ If NOT enough ticks in previous event to satisfy pre-trigger ^
1697  } // If can load previous event
1698  } // If need to load previous event for pre-trigger
1699  this_timestamp = loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick); // Set this_timestamp to whatever it now is....
1700 
1701  if ( fTrigger ) { // If trigger is still good!
1702  fLastTriggerIndex = TempTriggerIndex;
1703  fLastEventIndex = TempEventIndex;
1704  fLastEvent = TempEventNumber;
1705  fLastTimeStamp = TempTimeStamp;
1706  }
1707  else {
1708  loadedDigits_.index = TempTriggerIndex + BufferResidual; // Jump to where the trigger was plus buffer residual
1709  if (fDebugLevel) {
1710  std::cout << "Trigger isn't good so I'm going back to where I triggered..."
1711  << "Attempted trigger was in EventIndex " << TempEventIndex << ", event " << TempEventNumber << " at index " << TempTriggerIndex
1712  << " at timestamp " << TempTimeStamp << ", it had " << TempNADCs << " ADCs."
1713  << "\nI'm now at event " << inputEventNumber_ << " index " << loadedDigits_.index
1714  << " and timestamp " << loadedDigits_.getTimeStampAtIndex(loadedDigits_.index, fNovaTicksPerTPCTick)
1715  << " and " << loadedDigits_.digits[0].NADC() << " ADCs, loadedDigits empty? " << loadedDigits_.empty(fDebugLevel) << "\n"
1716  << std::endl;
1717  }
1718  }
1719 }
1720 //===================================================================================================================================
1721 void DAQToOffline::Splitter::Triggering(std::map<int,int> &PrevChanADC, std::vector<short> ADCdigits, bool NewTree) {
1722  if ( EventIndex_-1 != fLastEventIndex ) fLastTimeStamp = 0; // No longer looking at same treeIndex as previous trigger, so reset lastTimeStamp
1723 
1724  for (size_t TrigSize = 0; TrigSize < fWhichTrigger.size(); ++TrigSize) {
1725  // Trigger on Monte Carlo whichTrigger == 0
1726  if ( fWhichTrigger[TrigSize] == 0 ) {
1727  if ( fDiffFromLastTrig > fMCTrigLevel ) fTrigger = true;
1728  }
1729  // Trigger on new files
1730  else if ( fWhichTrigger[TrigSize] == 1 && NewTree ) {
1731  fTrigger = true;
1732  }
1733  // Trigger on Photon Detectors
1734  else if ( fWhichTrigger[TrigSize] == 2 ) {
1736  }
1737  // Trigger using the user defined PTB Trigger vector
1738  else if ( fWhichTrigger[TrigSize] == 3 ) {
1740  }
1741  // Trigger on "Tickler" / TPC information
1742  else if ( fWhichTrigger[TrigSize] == 4 ) {
1743  fTrigger = TicklerTrigger( PrevChanADC, ADCdigits);
1744  }
1745 
1747  if (fTrigger) break;
1748  }
1749 }
1750 //===================================================================================================================================
1751 bool DAQToOffline::Splitter::TicklerTrigger( std::map<int,int> &PrevChanADC, std::vector<short> ADCdigits ) {
1752  int HitsOverThreshold = 0;
1753  if (PrevChanADC.size() != 0) {
1754  for (unsigned int achan=0; achan<ADCdigits.size(); ++achan)
1755  if ( fabs( ADCdigits[achan] - PrevChanADC[achan] ) > fADCdiffThreshold ) {
1756  ++HitsOverThreshold;
1757  if (fDebugLevel > 3) {
1758  std::cout << "Looking at index " << loadedDigits_.index << " channel " << achan << "..." << ADCdigits[achan] << " - "
1759  << PrevChanADC[achan] << " = " << fabs( ADCdigits[achan] - PrevChanADC[achan] ) << " > " << fADCdiffThreshold
1760  << std::endl;
1761  }
1762  }
1763  if ( HitsOverThreshold != 0 )
1764  if (fDebugLevel > 2) std::cout << " after looking through all the channels ("<<ADCdigits.size()<<") I had " << HitsOverThreshold << " ticks with diff more than " << fADCdiffThreshold << std::endl;
1765  if ( HitsOverThreshold > fADCsOverThreshold ) {
1766  if (fDebugLevel > 2) std::cout << "Looking at index " << loadedDigits_.index << ", which had " << HitsOverThreshold << " hits over diff threshold. Trigger threshold is " << fADCsOverThreshold << std::endl;
1767  return true;
1768  }
1769  } // if PrevChanADC not empty.
1770  for (unsigned int bchan=0; bchan<ADCdigits.size(); ++bchan)
1771  PrevChanADC[bchan] = ADCdigits[bchan];
1772  return false;
1773 }
1774 //===================================================================================================================================
1776 //===================================================================================================================================
double E(const int i=0) const
Definition: MCParticle.h:232
void Triggering(std::map< int, int > &PrevChanADC, std::vector< short > ADCdigits, bool NewTree)
SubRunNumber_t subRun() const noexcept
lbne::TpcNanoSlice::Header::nova_timestamp_t last_timestamp
intermediate_table::iterator iterator
EventID const & eventID() const
Definition: Principal.cc:1121
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:217
std::pair< lbne::PennMicroSlice::Payload_Header::short_nova_timestamp_t, std::bitset< TypeSizes::TriggerWordSize > > PTBTrigger
Definition: PennToOffline.h:43
void AddDaughter(const int trackID)
Definition: MCParticle.h:264
void SSPFragmentToWaveformsAndHits(artdaq::Fragments const &rawFragments, std::vector< raw::OpDetWaveform > &opDetWaveformVector, std::vector< recob::OpHit > &opHitVector)
enum raw::_compress Compress_t
QList< Entry > entry
double Py(const int i=0) const
Definition: MCParticle.h:230
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
Energy deposited on a readout channel by simulated tracks.
Definition: SimChannel.h:140
void AddTrajectoryPoint(TLorentzVector const &position, TLorentzVector const &momentum)
Definition: MCParticle.h:256
static QCString result
void SetUseDefaults(bool f)
art::SubRunNumber_t inputSubRunNumber_
Channel_t ChannelNumber() const
Definition: OpDetWaveform.h:69
static const double ps
Definition: Units.h:103
bool loadEvents_(size_t &InputTree)
std::string string
Definition: nybbler.cc:12
bool readFile(string const &filename, art::FileBlock *&fb)
double Energy(TDC_t tdc) const
Returns the total energy on this channel in the specified TDC [MeV].
Definition: SimChannel.cxx:154
EventNumber_t event() const noexcept
std::unique_ptr< TFile > file_
void LoadRCEInformation(size_t LoadTree)
void BuildPTBChannelMap(std::string MapDir, std::string MapFile, std::map< int, int > &channelMap)
double Px(const int i=0) const
Definition: MCParticle.h:229
art::SubRunNumber_t subRunNumber_
struct vector vector
SubRunPrincipal * makeSubRunPrincipal(SubRunAuxiliary const &subRunAux) const
vector< sim::SimChannel > MCSimChan_t
vector< simb::MCParticle > MCPart_t
std::string const & instance() const noexcept
Definition: InputTag.cc:82
Definition of basic raw digits.
unsigned short uint16_t
Definition: stdint.h:125
vector< ExternalTrigger > PennCounters_t
art::SourceHelper const & sh_
art::EventAuxiliary evAux_
Raw data description.
art::EventNumber_t inputEventNumber_
art::SubRunNumber_t cachedSubRunNumber_
Particle class.
string filename
Definition: train.py:213
no compression
Definition: RawTypes.h:9
std::string const & process() const noexcept
Definition: InputTag.cc:88
std::vector< unsigned int > fPTBTrigs
std::map< uint64_t, size_t > EventTreeMap
int NumberDaughters() const
Definition: MCParticle.h:216
constexpr TimeValue_t value() const
Definition: Timestamp.h:23
bool NoRCEsCase(art::RunPrincipal *&outR, art::SubRunPrincipal *&outSR, art::EventPrincipal *&outE)
RunPrincipal * makeRunPrincipal(RunAuxiliary const &runAux) const
Definition: SourceHelper.cc:94
art::EventNumber_t eventNumber_
void decode(std::any const &, std::string &)
int TrackId() const
Definition: MCParticle.h:209
std::vector< raw::RawDigit > tpcFragmentToRawDigits(artdaq::Fragments const &rawFragments, std::vector< std::pair< std::pair< unsigned int, unsigned int >, lbne::TpcNanoSlice::Header::nova_timestamp_t > > &DigitsIndexList, lbne::TpcNanoSlice::Header::nova_timestamp_t &firstTimestamp, art::ServiceHandle< lbne::ChannelMapService > const &channelMap, bool useChannelMap, bool debug, raw::Compress_t compression, unsigned int zeroThreshold)
lbne::TpcNanoSlice::Header::nova_timestamp_t Event_timestamp
void readFile(string fileName, string &content)
Definition: test_suite.cc:18
EventAuxiliary::ExperimentType experimentType() const noexcept
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
RunNumber_t run() const noexcept
std::string const & label() const noexcept
Definition: InputTag.cc:76
SSPReformatterAlgs sspReform
art::EventAuxiliary * pevaux_
double Pt(const int i=0) const
Definition: MCParticle.h:235
vector< RawDigit > rawDigits_t
virtual float PedMean(raw::ChannelID_t ch) const
Retrieve pedestal information.
void LoadSSPInformation(size_t LoadTree)
void SetPolarization(const TVector3 &p)
Definition: MCParticle.h:265
void decode(std::any const &a, Compress_t &result)
auto counter(T begin, T end)
Returns an object to iterate values from begin to end in a range-for loop.
Definition: counter.h:285
void SetCSVFileName(std::string fname)
std::vector< std::pair< std::pair< unsigned int, unsigned int >, lbne::TpcNanoSlice::Header::nova_timestamp_t > > DigitsIndexList
unsigned int uint32_t
Definition: stdint.h:126
double Charge(TDC_t tdc) const
Returns the total number of ionization electrons on this channel in the specified TDC...
Definition: SimChannel.cxx:132
void makeEventAndPutDigits_(art::EventPrincipal *&outE, art::Timestamp art_timestamp=0)
lbne::TpcNanoSlice::Header::nova_timestamp_t first_timestamp
art::Timestamp make_art_timestamp_from_nova_timestamp(lbne::TpcNanoSlice::Header::nova_timestamp_t this_nova_timestamp)
std::string getenv(std::string const &name)
Definition: getenv.cc:15
def move(depos, offset)
Definition: depos.py:107
double P(const int i=0) const
Definition: MCParticle.h:233
size_t size
Definition: lodepng.cpp:55
std::vector< sim::TrackIDE > TrackIDEs(TDC_t startTDC, TDC_t endTDC) const
Returns energies collected for each track within a time interval.
Definition: SimChannel.cxx:244
double T(const int i=0) const
Definition: MCParticle.h:223
unsigned __int64 uint64_t
Definition: stdint.h:136
IDNumber_t< Level::SubRun > SubRunNumber_t
Definition: IDNumber.h:119
lbne::TpcNanoSlice::Header::nova_timestamp_t fLastTimeStamp
string tmp
Definition: languages.py:63
art::RunNumber_t inputRunNumber_
vector< recob::OpHit > OpHits_t
void SetWeight(double wt)
Definition: MCParticle.h:267
void SetEndProcess(std::string s)
Definition: MCParticle.cxx:105
std::vector< raw::RawDigit > rawDigits_t
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition: pointer.h:1124
void AddIonizationElectrons(TrackID_t trackID, TDC_t tdc, double numberElectrons, double const *xyz, double energy)
Add ionization electrons and energy to this channel.
Definition: SimChannel.cxx:52
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
raw::ChannelID_t Channel() const
Returns the readout channel this object describes.
Definition: SimChannel.h:329
lbne::TpcNanoSlice::Header::nova_timestamp_t this_timestamp
std::map< uint16_t, std::map< size_t, std::pair< float, float > > > AllPedMap
double Vx(const int i=0) const
Definition: MCParticle.h:220
bool readNext(art::RunPrincipal *const &inR, art::SubRunPrincipal *const &inSR, art::RunPrincipal *&outR, art::SubRunPrincipal *&outSR, art::EventPrincipal *&outE)
const int ArraySize
void SetGvtx(double *v)
Definition: MCParticle.cxx:120
Utility object to perform functions of association.
std::enable_if_t<!detail::range_sets_supported(P::branch_type)> put_product_in_principal(std::unique_ptr< T > &&product, P &principal, std::string const &module_label, std::string const &instance_name={})
void SetPedestal(float ped, float sigma=1.)
Set pedestal and its RMS (the latter is 0 by default)
Definition: RawDigit.cxx:68
MaybeLogger_< ELseverityLevel::ELsev_success, false > LogDebug
signed __int64 int64_t
Definition: stdint.h:135
bool eventIsFull_(rawDigits_t const &v)
void CheckTimestamps(bool &JumpEvent, size_t &JumpNADC)
double Pz(const int i=0) const
Definition: MCParticle.h:231
object containing MC truth information necessary for making RawDigits and doing back tracking ...
IDNumber_t< Level::Event > EventNumber_t
Definition: IDNumber.h:118
std::string find_file(std::string const &filename) const
Definition: search_path.cc:94
Interface for experiment-specific channel quality info provider.
lbne::TpcNanoSlice::Header::nova_timestamp_t prev_timestamp
double Vz(const int i=0) const
Definition: MCParticle.h:222
bool LoadPTBInformation(size_t LoadTree)
Splitter(fhicl::ParameterSet const &ps, art::ProductRegistryHelper &prh, art::SourceHelper const &sh)
static bool * b
Definition: config.cpp:1043
TDCIDEs_t const & TDCIDEMap() const
Returns all the deposited energy information as stored.
Definition: SimChannel.h:328
std::string const & eventTreeName()
Definition: rootNames.cc:67
vector< vector< double > > clear
EventPrincipal * makeEventPrincipal(EventAuxiliary const &eventAux, std::unique_ptr< History > &&history) const
art::RunNumber_t cachedRunNumber_
vector< simb::MCTruth > MCTruth_t
std::map< int, int > fPTBMap
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
Interface for experiment-specific service for channel quality info.
void Uncompress(const std::vector< short > &adc, std::vector< short > &uncompressed, raw::Compress_t compress)
Uncompresses a raw data buffer.
Definition: raw.cxx:755
std::vector< raw::ExternalTrigger > PennFragmentToExternalTrigger(artdaq::Fragments const &Fragments, std::map< int, int > &channelMap, lbne::PennMicroSlice::Payload_Timestamp *&FirstPTBTimestamp)
void SetRescatter(int code)
Definition: MCParticle.h:266
#define DEFINE_ART_INPUT_SOURCE(klass)
void function(int client, int *resource, int parblock, int *test, int p)
std::vector< RawDigit::ADCvector_t > dbuf_
bool isRealData() const noexcept
bool TicklerTrigger(std::map< int, int > &PrevChanADC, std::vector< short > ADCdigits)
std::vector< unsigned int > fWhichTrigger
virtual float PedMeanErr(raw::ChannelID_t ch) const
double Vy(const int i=0) const
Definition: MCParticle.h:221
bool Update(uint64_t ts)
Timestamp const & time() const noexcept
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
std::function< rawDigits_t(artdaq::Fragments const &, std::vector< std::pair< std::pair< unsigned int, unsigned int >, lbne::TpcNanoSlice::Header::nova_timestamp_t > > &, lbne::TpcNanoSlice::Header::nova_timestamp_t &, art::ServiceHandle< lbne::ChannelMapService > const &)> fragmentsToDigits_
vector< OpDetWaveform > SSPWaveforms_t
QTextStream & endl(QTextStream &s)
void SetDetName(std::string detName)
def load(filename, jpath="depos")
Definition: depos.py:34
IDNumber_t< Level::Run > RunNumber_t
Definition: IDNumber.h:120