artdaq_core  v1_07_08
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
ContainerFragmentLoader.hh
1 #ifndef artdaq_core_Data_ContainerFragmentLoader_hh
2 #define artdaq_core_Data_ContainerFragmentLoader_hh
3 
5 // ContainerFragmentLoader
6 //
7 // This class gives write access to a ContainerFragment. It should be
8 // used when multiple fragments are generated by one BoardReader for a
9 // single event.
10 //
12 
13 #include "artdaq-core/Data/Fragment.hh"
14 #include "artdaq-core/Data/ContainerFragment.hh"
15 #include "tracemf.h"
16 
17 #include <iostream>
18 
19 namespace artdaq
20 {
21  class ContainerFragmentLoader;
22 }
23 
24 
29 {
30 public:
31 
32 
38  explicit ContainerFragmentLoader(Fragment& f);
39 
40  // ReSharper disable once CppMemberFunctionMayBeConst
46  {
47  assert(artdaq_Fragment_.hasMetadata());
48  return reinterpret_cast<Metadata *>(&*artdaq_Fragment_.metadataAddress());
49  }
50 
56  {
57  metadata()->fragment_type = type;
58  }
59 
68  void set_missing_data(bool isDataMissing)
69  {
70  metadata()->missing_data = isDataMissing;
71  }
72 
78  void addFragment(artdaq::Fragment& frag);
79 
84  void addFragment(artdaq::FragmentPtr& frag);
85 
91 
92 private:
93  // Note that this non-const reference hides the const reference in the base class
94  artdaq::Fragment& artdaq_Fragment_;
95 
96  static size_t words_to_frag_words_(size_t nWords);
97 
98  void addSpace_(size_t bytes);
99 
100  uint8_t* dataBegin_() { return reinterpret_cast<uint8_t*>(&*artdaq_Fragment_.dataBegin()); }
101  void* dataEnd_() { return reinterpret_cast<void*>(dataBegin_() + lastFragmentIndex()); }
102 };
103 
106  , artdaq_Fragment_(f)
107 {
109  Metadata m;
110  m.block_count = 0;
112  m.missing_data = false;
113  for (int ii = 0; ii < CONTAINER_FRAGMENT_COUNT_MAX; ++ii)
114  {
115  m.index[ii] = 0;
116  }
117  artdaq_Fragment_.setMetadata<Metadata>(m);
118 
119  if (artdaq_Fragment_.size() !=
121  words_to_frag_words_(Metadata::size_words))
122  {
123  std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
124  std::cerr << "Expected size: " << artdaq::detail::RawFragmentHeader::num_words() +
125  words_to_frag_words_(Metadata::size_words) << std::endl;
126 
127  throw cet::exception("ContainerFragmentLoader: Raw artdaq::Fragment object size suggests it does not consist of its own header + the ContainerFragment::Metadata object");
128  }
129 }
130 
131 inline size_t artdaq::ContainerFragmentLoader::words_to_frag_words_(size_t nWords)
132 {
133  size_t mod = nWords % words_per_frag_word_();
134  return mod ?
135  nWords / words_per_frag_word_() + 1 :
136  nWords / words_per_frag_word_();
137 }
138 
139 inline void artdaq::ContainerFragmentLoader::addSpace_(size_t bytes)
140 {
141  auto currSize = sizeof(artdaq::Fragment::value_type) * artdaq_Fragment_.dataSize(); // Resize takes into account header and metadata size
142  artdaq_Fragment_.resizeBytes(bytes + currSize);
143  TRACE(4, "ContainerFragmentLoader::addSpace_: dataEnd_ is now at %p", dataEnd_());
144 }
145 
147 {
148  TRACE(4, "ContainerFragmentLoader::addFragment: Adding Fragment with payload size %llu to Container", (unsigned long long)frag.dataSizeBytes());
149  if (metadata()->fragment_type == Fragment::EmptyFragmentType) metadata()->fragment_type = frag.type();
150  else if (frag.type() != metadata()->fragment_type)
151  {
152  throw cet::exception("ContainerFragmentLoader::addFragment: Trying to add a fragment of different type than what's already been added!");
153  }
154  TRACE(4, "ContainerFragmentLoader::addFragment: Payload Size is %llu, lastFragmentIndex is %llu, and frag.size is %llu", (unsigned long long)artdaq_Fragment_.dataSizeBytes(), (unsigned long long)lastFragmentIndex(), (unsigned long long)frag.sizeBytes());
155  if (artdaq_Fragment_.dataSizeBytes() < lastFragmentIndex() + frag.sizeBytes())
156  {
157  addSpace_(frag.sizeBytes());
158  }
159  frag.setSequenceID(artdaq_Fragment_.sequenceID());
160  TRACE(4, "ContainerFragmentLoader::addFragment, copying %llu bytes from %p to %p", (long long unsigned int)frag.sizeBytes(), (void*)frag.headerAddress(), dataEnd_());
161  memcpy(dataEnd_(), frag.headerAddress(), frag.sizeBytes());
162  metadata()->index[block_count()] = lastFragmentIndex() + frag.sizeBytes();
163  metadata()->block_count++;
164 }
165 
167 {
168  addFragment(*frag);
169 }
170 
172 {
173  for (auto& frag : frags)
174  {
175  addFragment((*frag));
176  }
177 }
178 
179 #endif /* artdaq_core_Data_ContainerFragmentLoader_hh */
std::unique_ptr< Fragment > FragmentPtr
A std::unique_ptr to a Fragment object.
Definition: Fragment.hh:50
static size_t const size_words
Size of the Metadata object.
The artdaq::ContainerFragment class represents a Fragment which contains other Fragments.
std::size_t dataSizeBytes() const
Return the number of bytes in the data payload. This does not include the number of bytes in the head...
Definition: Fragment.hh:346
void setSequenceID(sequence_id_t sequence_id)
Sets the Sequence ID of the Fragment.
Definition: Fragment.hh:844
void setSystemType(type_t stype)
Sets the type of the Fragment, checking that it is a valid system type.
Definition: Fragment.hh:837
std::size_t size() const
Gets the size of the Fragment, from the Fragment header.
Definition: Fragment.hh:788
void set_fragment_type(Fragment::type_t type)
Sets the type of Fragment which this ContainerFragment should contain.
A Read-Write version of the ContainerFragment, used for filling ContainerFragment objects with other ...
static constexpr type_t EmptyFragmentType
Copy EmptyFragmentType from RawFragmentHeader.
Definition: Fragment.hh:151
std::size_t sizeBytes() const
Size of vals_ vector ( header + (optional) metadata + payload) in bytes.
Definition: Fragment.hh:331
static constexpr std::size_t num_words()
Returns the number of RawDataType words present in the header.
detail::RawFragmentHeader::type_t type_t
typedef for type_t from RawFragmentHeader
Definition: Fragment.hh:133
static const int CONTAINER_FRAGMENT_COUNT_MAX
The maximum capacity of the ContainerFragment (in fragments)
count_t fragment_type
The Fragment::type_t of stored Fragment objects.
size_t lastFragmentIndex() const
Returns the offset of the last Fragment in the ContainerFragment.
Metadata * metadata()
Get the ContainerFragment metadata (includes information about the location of Fragment objects withi...
void addFragment(artdaq::Fragment &frag)
Add a Fragment to the ContainerFragment by reference.
count_t block_count
The number of Fragment objects stored in the ContainerFragment.
iterator dataBegin()
Return an iterator to the beginning of the data payload (after header and metadata) ...
Definition: Fragment.hh:1008
QuickVec< RawDataType >::value_type value_type
Alias value_type type from QuickVec&lt;RawDataType&gt;
Definition: Fragment.hh:180
Contains the information necessary for retrieving Fragment objects from the ContainerFragment.
count_t missing_data
Flag if the ContainerFragment knows that it is missing data.
static constexpr type_t ContainerFragmentType
Copy ContainerFragmentType from RawFragmentHeader.
Definition: Fragment.hh:152
ContainerFragmentLoader(Fragment &f)
Constructs the ContainerFragmentLoader.
void setMetadata(const T &md)
Set the metadata in the Fragment to the contents of the specified structure. This throws an exception...
Definition: Fragment.hh:919
type_t type() const
Type of the Fragment, from the Fragment header.
Definition: Fragment.hh:802
RawDataType * metadataAddress()
Get the address of the metadata. For internal use only, use metadata() instead.
Definition: Fragment.hh:1092
size_t index[CONTAINER_FRAGMENT_COUNT_MAX]
Offset of each Fragment within the ContainerFragment.
std::list< FragmentPtr > FragmentPtrs
A std::list of FragmentPtrs.
Definition: Fragment.hh:55
bool hasMetadata() const
Test whether this Fragment has metadata.
Definition: Fragment.hh:885
A Fragment contains the data from one piece of the DAQ system for one event The artdaq::Fragment is t...
Definition: Fragment.hh:81
void set_missing_data(bool isDataMissing)
Sets the missing_data flag.
void addFragments(artdaq::FragmentPtrs &frags)
Add a collection of Fragment objects to the ContainerFragment.
RawDataType * headerAddress()
Gets the address of the header.
Definition: Fragment.hh:1104