AdcChannelData.h
Go to the documentation of this file.
1 // AdcChannelData.h
2 //
3 // David Adams
4 // June 2016
5 //
6 // Struct to hold the prepared time samples for a single TPC channel.
7 //
8 // Held in event info pointer:
9 // run - Run number
10 // subRun - Sub-run number
11 // event - Event number
12 // time - Unix time (sec)
13 // timerem - Time remainder (ns)
14 // trigger - Index indicating which trigger(s) fired.
15 // triggerClock - Time counter for the trigger
16 // triggerTick0 - Tick counter for the event
17 //
18 // Held in channel info pointer:
19 // channel - Offline channel number
20 // fembID - FEMB ID
21 // fembChannel - Channel number in FEMB (0, 1,..., 127).
22 // channelStatus - Channel status (0=ok, 1=bad, 2=noisy)
23 //
24 // Held directly:
25 // channelClock - Time counter for the channel data
26 // tick0 - Tick offset between triggerTick0 and first tick in raw/samples data.
27 // pedestal - Pedestal subtracted from the raw count
28 // pedestalRms - Pedestal RMS or sigma
29 //
30 // raw - Uncompressed array holding the raw ADC count for each tick
31 // samples - Array holding the prepared signal value for each tick
32 // binSamples - Array holding binned samples: binSamples[ibin][itick]
33 // sampleUnit - Unit for samples array (ADC counts, fC, ke, ...)
34 // sampleNoise - Noise level (e.g. RMS for samples)
35 // flags - Array holding the status flag for each tick
36 // signal - Array holding bools indicating which ticks have signals
37 // rois - Array of ROIs indicating ticks of interest (e.g. have signals)
38 // dftmags - Array of magnitudes for the DFT of the samples.
39 // dftphases - Array of phases for the DFT of the samples.
40 // metadata - Extra attributes
41 //
42 // digit - Corresponding raw digit
43 // wire - Corresponding wire
44 // digitIndex - Index for the digit in the event digit container
45 // wireIndex - Index for the wire in the event wire container
46 //
47 // views - Map of data views indexed by name.
48 // Each object implicitly has a self view with name "" holding only itself.
49 // viewParent - Pointer to the data object holding this as a view. Creator of the view
50 // object is responsible for filling this field.
51 //
52 // User can compare values against the defaults below to know if a value has been set.
53 // For arrays, check if the size in nonzero.
54 //
55 // There separate clocks for the trigger which corresponds to (time, timerem) and
56 // the TPC readout (channelClock). For protoDUNE, these run at 50 MHz.
57 //
58 // If filled, the DFT fields should have lengths (nsam+2)/2 for the magnitudes and
59 // (nsam+1)/2 for the phases with the first phase zero or pi.
60 //
61 // A data view is a vector of AdcChannelData objects providing an alternative
62 // representation of its parent.
63 // E.g. non-contiguous time samples, processing snapshot or alternative, ....
64 //
65 // A view path is a vector of names {vn0, vn1, ...} with string representation
66 // "vn0/vn1/..." that specifies the path to a collection of AdcChannelData objects
67 // at any depth in the view hiearchy.
68 // Example view access:
69 // string myview = "constituents/trun1000";
70 // AdcIndex nvie = mydata.viewCount(myview);
71 // for ( AdcIndex ivie=0; ivie<nvie; ++ivie ) {
72 // AdcChannelData* pdat = mydata.viewEntry(myview, ivie);
73 // cout << "T0 for view " << ivie " << ": " << pdata->tick0 << endl;
74 // }
75 
76 #ifndef AdcChannelData_H
77 #define AdcChannelData_H
78 
79 #include <string>
80 #include <vector>
81 #include <memory>
82 #include <map>
83 #include <iostream>
87 
88 namespace raw {
89  class RawDigit;
90 }
91 namespace recob {
92  class Wire;
93 }
94 
96 
97 public:
98 
99  using Name = std::string;
100  using NameVector = std::vector<Name>;
101  using FloatMap = std::map<Name, float>;
102  using View = std::vector<AdcChannelData>;
103  using ViewMap = std::map<Name, View>;
105  using EventInfoPtr = std::shared_ptr<const EventInfo>;
107  using ChannelInfoPtr = std::shared_ptr<const ChannelInfo>;
111 
112  static Index badIndex() { return EventInfo::badIndex(); }
113  static Index badLongIndex() { return EventInfo::badLongIndex(); }
114  static Index badChannel() { return EventInfo::badIndex(); }
115  static Index badSignal() { return -99999; }
116 
117  static const EventInfo& badEventInfo() {
118  return EventInfo::badEventInfo();
119  }
120 
121  static const ChannelInfo& badChannelInfo() {
122  return ChannelInfo::badChannelInfo();
123  }
124 
125  // ADC and derived data.
126  AdcLongIndex channelClock =0;
127  AdcInt tick0 = 0;
128  AdcSignal pedestal =badSignal();
129  AdcSignal pedestalRms =0.0;
134  AdcSignal sampleNoise =0.0;
141  AdcChannelData* viewParent =nullptr;
142 
143  // Connections to persistent data.
144  const raw::RawDigit* digit =nullptr;
145  const recob::Wire* wire =nullptr;
146  AdcIndex digitIndex =badIndex();
147  AdcIndex wireIndex =badIndex();
148 
149 private:
150 
153 
154  // Constituents and alternate views.
156 
157 public:
158 
159  // Set event info.
160  void setEventInfo(EventInfoPtr pevi) { m_peventInfo = pevi; }
161  void setEventInfo(const EventInfo* pevi) { m_peventInfo.reset(pevi); }
162  void setEventInfo(Index a_run, Index a_event, Index a_subRun =badIndex(),
163  time_t a_time =0, int a_timerem =0,
164  Index a_trigger =badIndex(), LongIndex a_triggerClock =badLongIndex()) {
165  setEventInfo(new EventInfo(a_run, a_event, a_subRun, a_time, a_timerem, a_trigger, a_triggerClock));
166  }
167 
168  // Return event info.
169  bool hasEventInfo() const { return bool(m_peventInfo); }
170  EventInfoPtr getEventInfoPtr() const { return m_peventInfo; }
171  const DuneEventInfo& getEventInfo() const {
172  return hasEventInfo() ? *m_peventInfo : badEventInfo();
173  }
174  AdcIndex run() const { return getEventInfo().run; }
175  AdcIndex subRun() const { return getEventInfo().subRun; }
176  AdcIndex event() const { return getEventInfo().event; }
177  time_t time() const { return getEventInfo().time; }
178  int timerem() const { return getEventInfo().timerem; }
179  AdcIndex trigger() const { return getEventInfo().trigger; }
180  AdcLongIndex triggerClock() const { return getEventInfo().triggerClock; }
181  AdcLongIndex triggerTick0() const { return getEventInfo().triggerTick0; }
182 
183  // Set channel info.
184  void setChannelInfo(ChannelInfoPtr pchi) { m_pchanInfo = pchi; }
185  void setChannelInfo(const ChannelInfo* pchi) { m_pchanInfo.reset(pchi); }
186  void setChannelInfo(Channel a_channel,
187  Index a_fembID =badIndex(),
188  Index a_fembChannel =badIndex(),
189  Index a_channelStatus =badIndex()) {
190  setChannelInfo(new ChannelInfo(a_channel, a_fembID, a_fembChannel, a_channelStatus));
191  }
192 
193  // Return channel info.
194  bool hasChannelInfo() const { return bool(m_pchanInfo); }
195  ChannelInfoPtr getChannelInfoPtr() const { return m_pchanInfo; }
197  return hasChannelInfo() ? *m_pchanInfo : badChannelInfo();
198  }
199  Channel channel() const { return getChannelInfo().channel; }
200  Index fembID() const { return getChannelInfo().fembID; }
201  Index fembChannel() const { return getChannelInfo().fembChannel; }
202  Index channelStatus() const { return getChannelInfo().channelStatus; }
203 
204  // Return the tick offset for the raw and samples data in this channel.
205  // This should allow us to align data from multiple channels and events.
207  AdcLongIndex tickoff = triggerTick0();
208  if ( tickoff == EventInfo::badLongIndex() ) tickoff = 0;
209  if ( tick0 < 0 ) return tickoff - AdcLongIndex(-tick0);
210  return tickoff + AdcLongIndex(tick0);
211  }
212 
213  // Copy ctor.
214  // Only copy event and channel data and not samples and
215  // derived data.
216  // Root dictionary (6.08/06) and AdcChannelDataMap (STL) require we keep copy.
218  channelClock = rhs.channelClock;
219  m_peventInfo = rhs.m_peventInfo;
220  m_pchanInfo = rhs.m_pchanInfo;
221  };
222 
223  // Delete assignment.
224  AdcChannelData& operator=(const AdcChannelData&) =delete;
225 
226  // Keel default ctor and move operations.
227  AdcChannelData() =default;
228  AdcChannelData(AdcChannelData&&) =default;
229  AdcChannelData& operator=(AdcChannelData&&) =default;
230 
231  // Check if a metadata field is defined.
232  bool hasMetadata(Name mname) const {
233  if ( mname.substr(0,3) == "../" ) {
234  if ( viewParent == nullptr ) return false;
235  return viewParent->hasMetadata(mname.substr(3));
236  }
237  return metadata.find(mname) != metadata.end();
238  }
239 
240  // Fetch metadata.
241  float getMetadata(Name mname, float def =0.0) const {
242  if ( mname.substr(0,3) == "../" ) {
243  if ( viewParent == nullptr ) return def;
244  return viewParent->getMetadata(mname.substr(3));
245  }
246  FloatMap::const_iterator imtd = metadata.find(mname);
247  if ( imtd == metadata.end() ) return def;
248  return imtd->second;
249  }
250 
251  // Set metadata.
252  void setMetadata(Name mname, float val) {
253  metadata[mname] = val;
254  }
255 
256  // Check if an attribute is defined.
257  bool hasAttribute(Name mname, float def =0.0) const {
258  if ( mname.substr(0,3) == "../" ) {
259  if ( viewParent == nullptr ) return false;
260  return viewParent->hasAttribute(mname.substr(3));
261  }
262  if ( mname == "run" ) return true;
263  if ( mname == "subRun" ) return true;
264  if ( mname == "event" ) return true;;
265  if ( mname == "trigger" ) return true;;
266  if ( mname == "triggerClock" ) return true;
267  if ( mname == "channelClock" ) return true;
268  if ( mname == "channelClockOffset" ) return true;
269  if ( mname == "channel" ) return true;
270  if ( mname == "fembID" ) return true;
271  if ( mname == "fembChannel" ) return true;
272  if ( mname == "pedestal" ) return true;
273  if ( mname == "pedestalRms" ) return true;
274  if ( mname == "sampleNoise" ) return true;
275  if ( mname == "digitIndex" ) return true;
276  if ( mname == "wireIndex" ) return true;
277  if ( mname == "raw" ) return true;
278  if ( mname == "samples" ) return true;
279  if ( mname == "flags" ) return true;
280  if ( mname == "signal" ) return true;
281  if ( mname == "rois" ) return true;
282  if ( mname == "dftmags" ) return true;
283  if ( mname == "dftphases" ) return true;
284  if ( mname == "digit" ) return true;
285  if ( mname == "wire" ) return true;
286  if ( mname == "metadata" ) return metadata.size();
287  return hasMetadata(mname);
288  }
289 
290  // Fetch any property including metadata.
291  float getAttribute(Name mname, float def =0.0) const {
292  if ( mname.substr(0,3) == "../" ) {
293  if ( viewParent == nullptr ) return def;
294  return viewParent->getAttribute(mname.substr(3));
295  }
296  // For basic types, return the value.
297  if ( mname == "run" ) return run();
298  if ( mname == "subRun" ) return subRun();
299  if ( mname == "event" ) return event();
300  if ( mname == "trigger" ) return trigger();
301  if ( mname == "triggerClock" ) return triggerClock(); // lose precision here
302  if ( mname == "channelClock" ) return channelClock; // lose precision here
303  if ( mname == "channelClockOffset" ) return channelClock - triggerClock();
304  if ( mname == "channel" ) return channel();
305  if ( mname == "fembID" ) return fembID();
306  if ( mname == "fembChannel" ) return fembChannel();
307  if ( mname == "pedestal" ) return pedestal;
308  if ( mname == "pedestalRms" ) return pedestalRms;
309  if ( mname == "sampleNoise" ) return sampleNoise;
310  if ( mname == "digitIndex" ) return digitIndex;
311  if ( mname == "wireIndex" ) return wireIndex;
312  // For vectors, return the size.
313  if ( mname == "raw" ) return raw.size();
314  if ( mname == "samples" ) return samples.size();
315  if ( mname == "flags" ) return flags.size();
316  if ( mname == "signal" ) return signal.size();
317  if ( mname == "rois" ) return rois.size();
318  if ( mname == "dftmags" ) return dftmags.size();
319  if ( mname == "dftphases" ) return dftphases.size();
320  // For pointer, return false for null.
321  if ( mname == "digit" ) return digit != nullptr;
322  if ( mname == "wire" ) return wire != nullptr;
323  if ( mname == "metadata" ) return metadata.size();
324  // Otherwise return the metatdata field.
325  return getMetadata(mname, def);
326  }
327 
328  // Clear the data.
329  void clear();
330 
331  // Fill rois from signal.
332  void roisFromSignal();
333 
334  // Return normalization specifier for the DFT held here.
335  // See RealDftNormalization.h
336  static AdcIndex dftNormalization() { return 22; }
337 
338  // Return the number of views.
339  // This does not include the self view.
340  size_t viewSize() const { return m_views.size(); }
341 
342  // Return the vector of available view names.
343  // This does not include the self view.
344  NameVector viewNames() const;
345 
346  // Return if a view or view path exists.
347  // This includes the self view.
348  bool hasView(Name vnam) const;
349 
350  // Read a view. Empty if undefined.
351  // This does not include the self view.
352  const View& view(Name vnam) const;
353 
354  // Obtain a mutable view. Entries may be added, removed or modified.
355  // View is added if not already existing.
356  View& updateView(Name vnam);
357 
358  // Return the number of entries for a specified view path.
359  // This includes the self view.
360  AdcIndex viewSize(Name vpnam) const;
361 
362  // Return the const channel data for an entry in a view path.
363  // This includes the self view.
364  // Returns null if the path does not exist or does not have the
365  // requested entry.
366  const AdcChannelData* viewEntry(Name vpnam, AdcIndex ient) const;
367 
368  // Return the mutable channel data for an entry in a view path.
369  // This includes the self view.
370  // Returns null if the path does not exist or does not have the
371  // requested entry.
372  AdcChannelData* mutableViewEntry(Name vpnam, AdcIndex ient);
373 
374 };
375 
376 //**********************************************************************
377 
378 typedef std::map<AdcChannel, AdcChannelData> AdcChannelDataMap;
379 
380 #ifdef __ROOTCLING__
381 #pragma link C++ class AdcChannelDataMap;
382 #endif
383 
384 //**********************************************************************
385 
386 inline void AdcChannelData::clear() {
387  channelClock = 0;
388  pedestal = badSignal();
389  pedestalRms = 0.0;
390  tick0 = 0;
391  raw.clear();
392  samples.clear();
393  sampleUnit = "";
394  sampleNoise = 0.0;
395  flags.clear();
396  signal.clear();
397  rois.clear();
398  dftmags.clear();
399  dftphases.clear();
400  digit = nullptr;
401  wire = nullptr;
402  dftmags.clear();
403  dftphases.clear();
404  digitIndex = badIndex();
405  wireIndex = badIndex();
406  metadata.clear();
407  m_peventInfo.reset();
408  m_pchanInfo.reset();
409 }
410 
411 //**********************************************************************
412 
414  rois.clear();
415  bool inRoi = false;
416  for ( unsigned int isig=0; isig<signal.size(); ++isig ) {
417  if ( inRoi ) {
418  AdcRoi& roi = rois.back();
419  if ( signal[isig] ) roi.second = isig;
420  else inRoi = false;
421  } else {
422  if ( signal[isig] ) {
423  rois.push_back(AdcRoi(isig, isig));
424  inRoi = true;
425  }
426  }
427  }
428 }
429 
430 //**********************************************************************
431 
433  NameVector vnams;
434  for ( ViewMap::value_type ivie : m_views ) {
435  vnams.push_back(ivie.first);
436  }
437  return vnams;
438 }
439 
440 //**********************************************************************
441 
442 bool AdcChannelData::hasView(Name vpnam) const {
443  if ( vpnam.size() == 0 ) return true;
444  Name::size_type ipos = vpnam.find("/");
445  if ( ipos == Name::npos ) return m_views.count(vpnam);
446  Name vnam = vpnam.substr(0, ipos);
447  if ( ! hasView(vnam) ) return false;
448  Name vsnam = vpnam.substr(ipos + 1);
449  for ( const AdcChannelData& acd : view(vnam) ) {
450  if ( acd.hasView(vsnam) ) return true;
451  }
452  return false;
453 }
454 
455 //**********************************************************************
456 
458  static const View empty;
459  ViewMap::const_iterator ivie = m_views.find(vnam);
460  if ( ivie == m_views.end() ) return empty;
461  return ivie->second;
462 }
463 
464 //**********************************************************************
465 
467  const Name myname = "AdcChannelData::updateView: ";
468  if ( vnam.size() == 0 ) {
469  std::cout << myname << "WARNING: View name may not be blank." << std::endl;
470  static View emptyView;
471  if ( emptyView.size() ) {
472  std::cout << myname << "ERROR: Empty view has been modified." << std::endl;
473  }
474  return emptyView;
475  }
476  return m_views[vnam];
477 }
478 
479 //**********************************************************************
480 
482  if ( vpnam.size() == 0 ) return 1;
483  Name::size_type ipos = vpnam.find("/");
484  if ( ipos == Name::npos ) return view(vpnam).size();
485  Name vnam = vpnam.substr(0, ipos);
486  Name vsnam = vpnam.substr(ipos + 1);
487  AdcIndex nvie = 0;
488  for ( const AdcChannelData& dat : view(vnam) ) nvie += dat.viewSize(vsnam);
489  return nvie;
490 }
491 
492 //**********************************************************************
493 
495  if ( vpnam.size() == 0 ) {
496  if ( ient == 0 ) return this;
497  else return nullptr;
498  }
499  Name::size_type ipos = vpnam.find("/");
500  if ( ipos == Name::npos ) {
501  const View& myview = view(vpnam);
502  if ( ient < myview.size() ) return &myview[ient];
503  return nullptr;
504  }
505  Name vnam = vpnam.substr(0, ipos);
506  Name vsnam = vpnam.substr(ipos + 1);
507  AdcIndex ientRem = ient;
508  for ( const AdcChannelData& dat : view(vnam) ) {
509  AdcIndex nvie = dat.viewSize(vsnam);
510  if ( ientRem < nvie ) return dat.viewEntry(vsnam, ientRem);
511  ientRem -= nvie;
512  }
513  return nullptr;
514 }
515 
516 //**********************************************************************
517 
519  if ( vpnam.size() == 0 ) {
520  if ( ient == 0 ) return this;
521  else return nullptr;
522  }
523  Name::size_type ipos = vpnam.find("/");
524  if ( ipos == Name::npos ) {
525  View& myview = updateView(vpnam);
526  if ( ient < myview.size() ) return &myview[ient];
527  return nullptr;
528  }
529  Name vnam = vpnam.substr(0, ipos);
530  Name vsnam = vpnam.substr(ipos + 1);
531  AdcIndex ientRem = ient;
532  for ( AdcChannelData& dat : updateView(vnam) ) {
533  AdcIndex nvie = dat.viewSize(vsnam);
534  if ( ientRem < nvie ) return dat.mutableViewEntry(vsnam, ientRem);
535  ientRem -= nvie;
536  }
537  return nullptr;
538 }
539 
540 //**********************************************************************
541 
542 #endif
void setEventInfo(const EventInfo *pevi)
ChannelInfoPtr getChannelInfoPtr() const
AdcSignalVectorVector binSamples
std::vector< AdcCount > AdcCountVector
Definition: AdcTypes.h:19
Index badIndex
const DuneEventInfo & getEventInfo() const
unsigned long int LongIndex
std::vector< AdcChannelData > View
Collection of charge vs time digitized from a single readout channel.
Definition: RawDigit.h:69
Reconstruction base classes.
AdcIndex subRun() const
std::string string
Definition: nybbler.cc:12
float AdcSignal
Definition: AdcTypes.h:21
AdcLongIndex triggerTick0() const
std::vector< AdcFlag > AdcFlagVector
Definition: AdcTypes.h:30
std::pair< AdcIndex, AdcIndex > AdcRoi
Definition: AdcTypes.h:54
intermediate_table::const_iterator const_iterator
Raw data description.
static AdcIndex dftNormalization()
AdcIndex trigger() const
ChannelInfoPtr m_pchanInfo
EventInfoPtr getEventInfoPtr() const
uint8_t channel
Definition: CRTFragment.hh:201
unsigned int Index
EventInfo::LongIndex LongIndex
std::shared_ptr< const EventInfo > EventInfoPtr
time_t time() const
float getAttribute(Name mname, float def=0.0) const
bool hasEventInfo() const
const DuneChannelInfo & getChannelInfo() const
EventInfoPtr m_peventInfo
static Index badSignal()
Index fembID() const
EventInfo::Index Index
std::map< Name, float > FloatMap
void setChannelInfo(ChannelInfoPtr pchi)
int AdcInt
Definition: AdcTypes.h:14
AdcRoiVector rois
NameVector viewNames() const
bool hasMetadata(Name mname) const
AdcLongIndex tickOffset() const
Index fembChannel() const
std::string Name
AdcChannelData(const AdcChannelData &rhs)
AdcIndex run() const
void setEventInfo(EventInfoPtr pevi)
void setChannelInfo(const ChannelInfo *pchi)
float getMetadata(Name mname, float def=0.0) const
std::vector< Name > NameVector
AdcIndex event() const
AdcSignalVector dftphases
AdcCountVector raw
unsigned int AdcIndex
Definition: AdcTypes.h:15
bool hasAttribute(Name mname, float def=0.0) const
ChannelInfo::Channel Channel
void setChannelInfo(Channel a_channel, Index a_fembID=badIndex(), Index a_fembChannel=badIndex(), Index a_channelStatus=badIndex())
std::vector< AdcRoi > AdcRoiVector
Definition: AdcTypes.h:55
Index channelStatus() const
const View & view(Name vnam) const
Channel channel() const
std::map< Name, View > ViewMap
unsigned long AdcLongIndex
Definition: AdcTypes.h:16
AdcFilterVector signal
std::vector< bool > AdcFilterVector
Definition: AdcTypes.h:27
void setEventInfo(Index a_run, Index a_event, Index a_subRun=badIndex(), time_t a_time=0, int a_timerem=0, Index a_trigger=badIndex(), LongIndex a_triggerClock=badLongIndex())
int timerem() const
AdcChannelData * mutableViewEntry(Name vpnam, AdcIndex ient)
std::vector< AdcSignalVector > AdcSignalVectorVector
Definition: AdcTypes.h:23
std::shared_ptr< const ChannelInfo > ChannelInfoPtr
const AdcChannelData * viewEntry(Name vpnam, AdcIndex ient) const
AdcLongIndex channelClock
bool hasChannelInfo() const
Class holding the regions of interest of signal from a channel.
Definition: Wire.h:118
std::vector< AdcSignal > AdcSignalVector
Definition: AdcTypes.h:22
View & updateView(Name vnam)
void setMetadata(Name mname, float val)
static const EventInfo & badEventInfo()
size_t viewSize() const
vector< vector< double > > clear
std::map< AdcChannel, AdcChannelData > AdcChannelDataMap
static Index badChannel()
static const ChannelInfo & badChannelInfo()
bool hasView(Name vnam) const
static Index badIndex()
int bool
Definition: qglobal.h:345
AdcSignalVector samples
AdcLongIndex triggerClock() const
AdcSignalVector dftmags
AdcChannel Channel
decltype(auto) constexpr empty(T &&obj)
ADL-aware version of std::empty.
Definition: StdUtils.h:97
QTextStream & endl(QTextStream &s)
static Index badLongIndex()
AdcFlagVector flags