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