artdaq_demo  v3_01_00
NthEvent_transfer.cc
1 #include "artdaq/TransferPlugins/TransferInterface.hh"
2 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh"
3 #include "artdaq-core/Data/Fragment.hh"
4 #include "artdaq-core/Utilities/ExceptionHandler.hh"
5 #include "cetlib/BasicPluginFactory.h"
6 
7 #include "messagefacility/MessageLogger/MessageLogger.h"
8 #include "fhiclcpp/ParameterSet.h"
9 
10 #include <boost/tokenizer.hpp>
11 
12 #include <sys/shm.h>
13 #include <memory>
14 #include <iostream>
15 #include <string>
16 #include <limits>
17 #include <sstream>
18 
22 namespace artdaq
23 {
28  class NthEventTransfer : public TransferInterface
29  {
30  public:
38  NthEventTransfer(fhicl::ParameterSet const& ps, artdaq::TransferInterface::Role role);
39 
46  TransferInterface::CopyStatus
47  copyFragment(artdaq::Fragment& fragment, size_t send_timeout_usec) override;
48 
55  TransferInterface::CopyStatus
56  moveFragment(artdaq::Fragment&& fragment) override;
57 
64  int receiveFragment(artdaq::Fragment& fragment,
65  size_t receiveTimeout) override
66  {
67  // nth-event discarding is done at the send side. Pass receive calls through to underlying transfer
68  return physical_transfer_->receiveFragment(fragment, receiveTimeout);
69  }
70 
77  int receiveFragmentHeader(detail::RawFragmentHeader& header, size_t receiveTimeout) override
78  {
79  return physical_transfer_->receiveFragmentHeader(header, receiveTimeout);
80  }
81 
88  int receiveFragmentData(RawDataType* destination, size_t wordCount) override
89  {
90  return physical_transfer_->receiveFragmentData(destination, wordCount);
91  }
92 
97  int source_rank() const override { return physical_transfer_->source_rank(); }
98 
103  int destination_rank() const override { return physical_transfer_->destination_rank(); }
104 
105 
106  private:
107 
108  bool pass(const artdaq::Fragment&) const;
109 
110  std::unique_ptr<TransferInterface> physical_transfer_;
111  size_t nth_;
112  size_t offset_;
113  };
114 
115  NthEventTransfer::NthEventTransfer(fhicl::ParameterSet const& pset, artdaq::TransferInterface::Role role) :
116  TransferInterface(pset, role)
117  , nth_(pset.get<size_t>("nth")),
118  offset_(pset.get<size_t>("offset", 0))
119  {
120  if (pset.has_key("source_rank") || pset.has_key("destination_rank")) {
121  throw cet::exception("NthEvent") << "The parameters \"source_rank\" and \"destination_rank\" must be explicitly defined in the body of the physical_transfer_plugin table, and not outside of it";
122  }
123 
124 
125  if (offset_ >= nth_) {
126  throw cet::exception("NthEvent") << "Offset value of " << offset_ <<
127  " must not be larger than the modulus value of " << nth_;
128  }
129 
130  if (nth_ == 0)
131  {
132  mf::LogWarning("NthEventTransfer") << "0 was passed as the nth parameter to NthEventTransfer. Will change to 1 (0 is undefined behavior)";
133  nth_ = 1;
134  }
135  // Instantiate the TransferInterface plugin used to effect transfers
136  physical_transfer_ = MakeTransferPlugin(pset, "physical_transfer_plugin", role);
137  }
138 
139 
140  TransferInterface::CopyStatus
141  NthEventTransfer::copyFragment(artdaq::Fragment& fragment,
142  size_t send_timeout_usec)
143  {
144 
145  if (!pass(fragment))
146  {
147  // Do not transfer but return success. Fragment is discarded
148  return TransferInterface::CopyStatus::kSuccess;
149  }
150 
151  // This is the nth Fragment, transfer
152  return physical_transfer_->copyFragment(fragment, send_timeout_usec);
153  }
154 
155  TransferInterface::CopyStatus
156  NthEventTransfer::moveFragment(artdaq::Fragment&& fragment)
157  {
158  if (!pass(fragment))
159  {
160  // Do not transfer but return success. Fragment is discarded
161  return TransferInterface::CopyStatus::kSuccess;
162  }
163 
164  // This is the nth Fragment, transfer
165  return physical_transfer_->moveFragment(std::move(fragment));
166  }
167 
168  bool
169  NthEventTransfer::pass(const artdaq::Fragment& fragment) const
170  {
171  bool passed = false;
172 
173  if (fragment.type() == artdaq::Fragment::DataFragmentType) {
174  passed = (fragment.sequenceID() + nth_ - offset_) % nth_ == 0 ? true : false;
175  }
176  else {
177  passed = true;
178  }
179 
180  return passed;
181  }
182 }
183 
184 DEFINE_ARTDAQ_TRANSFER(artdaq::NthEventTransfer)
185 
186 // Local Variables:
187 // mode: c++
188 // End:
Demonstration TransferInterface plugin showing how to discard events Intended for use in the transfer...
int receiveFragment(artdaq::Fragment &fragment, size_t receiveTimeout) override
Receive a fragment from the transfer plugin.
int receiveFragmentHeader(detail::RawFragmentHeader &header, size_t receiveTimeout) override
Receive a Fragment Header from the transport mechanism.
TransferInterface::CopyStatus copyFragment(artdaq::Fragment &fragment, size_t send_timeout_usec) override
Copy a fragment, using the non-reliable channel.
NthEventTransfer(fhicl::ParameterSet const &ps, artdaq::TransferInterface::Role role)
NthEventTransfer Constructor.
int destination_rank() const override
Get the destination rank from the physical transfer.
TransferInterface::CopyStatus moveFragment(artdaq::Fragment &&fragment) override
Copy a fragment, using the reliable channel. moveFragment assumes ownership of the fragment...
int receiveFragmentData(RawDataType *destination, size_t wordCount) override
Receive the body of a Fragment to the given destination pointer.
int source_rank() const override
Get the source rank from the physical transfer.