artdaq_demo  v3_06_01
NthEvent_transfer.cc
1 #include "artdaq-core/Data/Fragment.hh"
2 #include "artdaq-core/Utilities/ExceptionHandler.hh"
3 #include "artdaq/TransferPlugins/MakeTransferPlugin.hh"
4 #include "artdaq/TransferPlugins/TransferInterface.hh"
5 #include "cetlib/BasicPluginFactory.h"
6 
7 #include "fhiclcpp/ParameterSet.h"
8 #include "messagefacility/MessageLogger/MessageLogger.h"
9 
10 #include <boost/tokenizer.hpp>
11 
12 #include <sys/shm.h>
13 #include <iostream>
14 #include <limits>
15 #include <memory>
16 #include <sstream>
17 #include <string>
18 
22 namespace artdaq {
27 class NthEventTransfer : public TransferInterface
28 {
29 public:
37  NthEventTransfer( fhicl::ParameterSet const& ps, artdaq::TransferInterface::Role role );
38 
45  TransferInterface::CopyStatus transfer_fragment_min_blocking_mode( artdaq::Fragment const& fragment,
46  size_t send_timeout_usec ) override;
47 
53  TransferInterface::CopyStatus transfer_fragment_reliable_mode( artdaq::Fragment&& fragment ) override;
54 
61  int receiveFragment( artdaq::Fragment& fragment, size_t receiveTimeout ) override
62  {
63  // nth-event discarding is done at the send side. Pass receive calls through to underlying transfer
64  return physical_transfer_->receiveFragment( fragment, receiveTimeout );
65  }
66 
73  int receiveFragmentHeader( detail::RawFragmentHeader& header, size_t receiveTimeout ) override
74  {
75  return physical_transfer_->receiveFragmentHeader( header, receiveTimeout );
76  }
77 
84  int receiveFragmentData( RawDataType* destination, size_t wordCount ) override
85  {
86  return physical_transfer_->receiveFragmentData( destination, wordCount );
87  }
88 
93  int source_rank() const override { return physical_transfer_->source_rank(); }
94 
99  int destination_rank() const override { return physical_transfer_->destination_rank(); }
100 
105  bool isRunning() override { return physical_transfer_->isRunning(); }
106 
111  void flush_buffers() override { physical_transfer_->flush_buffers(); }
112 
113 private:
114  bool pass( const artdaq::Fragment& ) const;
115 
116  std::unique_ptr<TransferInterface> physical_transfer_;
117  size_t nth_;
118  size_t offset_;
119 };
120 
121 NthEventTransfer::NthEventTransfer( fhicl::ParameterSet const& pset, artdaq::TransferInterface::Role role )
122  : TransferInterface( pset, role ), nth_( pset.get<size_t>( "nth" ) ), offset_( pset.get<size_t>( "offset", 0 ) )
123 {
124  if ( pset.has_key( "source_rank" ) || pset.has_key( "destination_rank" ) )
125  {
126  throw cet::exception( "NthEvent" )
127  << "The parameters \"source_rank\" and \"destination_rank\" must be explicitly defined in the body of the "
128  "physical_transfer_plugin table, and not outside of it";
129  }
130 
131  if ( offset_ >= nth_ )
132  {
133  throw cet::exception( "NthEvent" )
134  << "Offset value of " << offset_ << " must not be larger than the modulus value of " << nth_;
135  }
136 
137  if ( nth_ == 0 )
138  {
139  mf::LogWarning( "NthEventTransfer" )
140  << "0 was passed as the nth parameter to NthEventTransfer. Will change to 1 (0 is undefined behavior)";
141  nth_ = 1;
142  }
143  // Instantiate the TransferInterface plugin used to effect transfers
144  physical_transfer_ = MakeTransferPlugin( pset, "physical_transfer_plugin", role );
145 }
146 
147 TransferInterface::CopyStatus NthEventTransfer::transfer_fragment_min_blocking_mode( artdaq::Fragment const& fragment,
148  size_t send_timeout_usec )
149 {
150  if ( !pass( fragment ) )
151  {
152  // Do not transfer but return success. Fragment is discarded
153  return TransferInterface::CopyStatus::kSuccess;
154  }
155 
156  // This is the nth Fragment, transfer
157  return physical_transfer_->transfer_fragment_min_blocking_mode( fragment, send_timeout_usec );
158 }
159 
160 TransferInterface::CopyStatus NthEventTransfer::transfer_fragment_reliable_mode( artdaq::Fragment&& fragment )
161 {
162  if ( !pass( fragment ) )
163  {
164  // Do not transfer but return success. Fragment is discarded
165  return TransferInterface::CopyStatus::kSuccess;
166  }
167 
168  // This is the nth Fragment, transfer
169  return physical_transfer_->transfer_fragment_reliable_mode( std::move( fragment ) );
170 }
171 
172 bool NthEventTransfer::pass( const artdaq::Fragment& fragment ) const
173 {
174  bool passed = false;
175 
176  if ( fragment.type() == artdaq::Fragment::DataFragmentType )
177  { passed = ( fragment.sequenceID() + nth_ - offset_ ) % nth_ == 0 ? true : false; }
178  else
179  {
180  passed = true;
181  }
182 
183  return passed;
184 }
185 } // namespace artdaq
186 
187 DEFINE_ARTDAQ_TRANSFER( artdaq::NthEventTransfer )
188 
189 // Local Variables:
190 // mode: c++
191 // 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 transfer_fragment_min_blocking_mode(artdaq::Fragment const &fragment, size_t send_timeout_usec) override
Transfer a Fragment to the destination. May not necessarily be reliable, but will not block longer th...
bool isRunning() override
Determine whether the TransferInterface plugin is able to send/receive data.
NthEventTransfer(fhicl::ParameterSet const &ps, artdaq::TransferInterface::Role role)
NthEventTransfer Constructor.
int destination_rank() const override
Get the destination rank from the physical transfer.
void flush_buffers() override
Flush any in-flight data. This should be used by the receiver after the receive loop has ended...
TransferInterface::CopyStatus transfer_fragment_reliable_mode(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.