artdaq_core  v1_07_01
 All Classes Namespaces Functions
RawEvent.hh
1 #ifndef artdaq_core_Data_RawEvent_hh
2 #define artdaq_core_Data_RawEvent_hh
3 
4 #include "artdaq-core/Data/dictionarycontrol.hh"
5 #include "artdaq-core/Data/Fragments.hh"
6 
7 #include "cetlib/exception.h"
8 
9 #include <iosfwd>
10 #include <memory>
11 #include <algorithm>
12 
13 namespace artdaq {
14 
15  // RawEvent is the artdaq view of a generic event, containing a
16  // header and zero or more Fragments.
17 
18  // RawEventHeader is the artdaq generic event header. It contains
19  // the information necessary for routing of raw events inside the
20  // artdaq code, but is not intended for use by any experiment.
21 
22  namespace detail { struct RawEventHeader; }
23 
25  typedef uint32_t run_id_t; // Fragments don't know about runs
26  typedef uint32_t subrun_id_t; // Fragments don't know about subruns
27  typedef Fragment::sequence_id_t sequence_id_t;
28 
29  run_id_t run_id; // RawDataType run_id;
30  subrun_id_t subrun_id; // RawDataType subrun_id;
31  sequence_id_t sequence_id; // RawDataType sequence_id;
32  bool is_complete;
33 
34  RawEventHeader(run_id_t run,
35  subrun_id_t subrun,
36  sequence_id_t event) :
37  run_id(run),
38  subrun_id(subrun),
39  sequence_id(event),
40  is_complete(false)
41  { }
42 
43  };
44 
45  // RawEvent should be a class, not a struct; it should be enforcing
46  // invariants (the contained Fragments should all have the correct
47  // event id).
48 
49  class RawEvent {
50  public:
51  typedef detail::RawEventHeader::run_id_t run_id_t;
52  typedef detail::RawEventHeader::subrun_id_t subrun_id_t;
53  typedef detail::RawEventHeader::sequence_id_t sequence_id_t;
54 
55  RawEvent(run_id_t run, subrun_id_t subrun, sequence_id_t event);
56 
57  // Insert the given (pointer to a) Fragment into this
58  // RawEvent. This takes ownership of the Fragment referenced by
59  // the FragmentPtr, unless an exception is thrown.
60 #if HIDE_FROM_ROOT
61  void insertFragment(FragmentPtr && pfrag);
62 
63  // Mark the event as complete
64  void markComplete();
65 
66  // Return the number of fragments this RawEvent contains.
67  size_t numFragments() const;
68 
69  // Return the sum of the word counts of all fragments in this RawEvent.
70  size_t wordCount() const;
71 
72  // Accessors for header information
73  run_id_t runID() const;
74  subrun_id_t subrunID() const;
75  sequence_id_t sequenceID() const;
76  bool isComplete() const;
77 
78  // Print summary information about this RawEvent to the given stream.
79  void print(std::ostream & os) const;
80 
81  // Release all the Fragments from this RawEvent, returning them to
82  // the caller through a unique_ptr that manages a vector into which
83  // the Fragments have been moved.
84  std::unique_ptr<std::vector<Fragment>> releaseProduct();
85 
86  // Fills in a list of unique fragment types from this event
87  void fragmentTypes(std::vector<Fragment::type_t>& type_list);
88 
89  // Release the Fragments from this RawEvent with the specified
90  // fragment type, returning them to the caller through a unique_ptr
91  // that manages a vector into which the Fragments have been moved.
92  // PLEASE NOTE that releaseProduct and releaseProduct(type_t) can not
93  // both be used on the same RawEvent since each one gives up
94  // ownership of the fragments within the event.
95  std::unique_ptr<std::vector<Fragment>> releaseProduct(Fragment::type_t);
96 
97 #endif
98 
99  private:
100  detail::RawEventHeader header_;
101  FragmentPtrs fragments_;
102  };
103 
104  typedef std::shared_ptr<RawEvent> RawEvent_ptr;
105 
106  inline
107  RawEvent::RawEvent(run_id_t run, subrun_id_t subrun, sequence_id_t event) :
108  header_(run, subrun, event),
109  fragments_()
110  { }
111 
112 #if HIDE_FROM_ROOT
113  inline
114  void RawEvent::insertFragment(FragmentPtr && pfrag)
115  {
116  if (pfrag == nullptr) {
117  throw cet::exception("LogicError")
118  << "Attempt to insert a null FragmentPtr into a RawEvent detected.\n";
119  }
120  fragments_.emplace_back(std::move(pfrag));
121  }
122 
123  inline void RawEvent::markComplete() { header_.is_complete = true; }
124 
125  inline
126  size_t RawEvent::numFragments() const
127  {
128  return fragments_.size();
129  }
130 
131  inline
132  size_t RawEvent::wordCount() const
133  {
134  size_t sum = 0;
135  for (auto const & frag : fragments_) { sum += frag->size(); }
136  return sum;
137  }
138 
139  inline RawEvent::run_id_t RawEvent::runID() const { return header_.run_id; }
140  inline RawEvent::subrun_id_t RawEvent::subrunID() const { return header_.subrun_id; }
141  inline RawEvent::sequence_id_t RawEvent::sequenceID() const { return header_.sequence_id; }
142  inline bool RawEvent::isComplete() const { return header_.is_complete; }
143 
144  inline
145  std::unique_ptr<std::vector<Fragment>> RawEvent::releaseProduct()
146  {
147  std::unique_ptr<std::vector<Fragment>> result(new std::vector<Fragment>);
148  result->reserve(fragments_.size());
149  // 03/08/2016 ELF: Moving to range-for for STL compatibility
150  //for (size_t i = 0, sz = fragments_.size(); i < sz; ++i) {
151  for (auto & i : fragments_) {
152  result->emplace_back(std::move(*i));
153  }
154  // It seems more hygenic to clear fragments_ rather than to leave
155  // it full of unique_ptrs to Fragments that have been plundered by
156  // the move.
157  fragments_.clear();
158  return result;
159  }
160 
161  inline
162  void RawEvent::fragmentTypes(std::vector<Fragment::type_t>& type_list)
163  {
164  // 03/08/2016 ELF: Moving to range-for for STL compatibility
165  //for (size_t i = 0, sz = fragments_.size(); i < sz; ++i) {
166  for (auto& i : fragments_) {
167  Fragment::type_t fragType = i->type(); // fragments_[i]->type();
168  if (std::find(type_list.begin(), type_list.end(), fragType) == type_list.end()) {
169  type_list.push_back(fragType);
170  }
171  }
172  //std::sort(type_list.begin(), type_list.end());
173  //std::unique(type_list.begin(), type_list.end());
174  }
175 
176  inline
177  std::unique_ptr<std::vector<Fragment>>
178  RawEvent::releaseProduct(Fragment::type_t fragment_type)
179  {
180  std::unique_ptr<std::vector<Fragment>> result(new std::vector<Fragment>);
181  FragmentPtrs::iterator iter = fragments_.begin();
182  do {
183  if ((*iter)->type() == fragment_type) {
184  result->push_back(std::move(*(*iter)));
185  iter = fragments_.erase(iter);
186  }
187  else {
188  ++iter;
189  }
190  } while (iter != fragments_.end());
191  return result;
192  }
193 
194  inline
195  std::ostream & operator<<(std::ostream & os, RawEvent const & ev)
196  {
197  ev.print(os);
198  return os;
199  }
200 
201 #endif
202 }
203 
204 #endif /* artdaq_core_Data_RawEvent_hh */