11#include " artdaq-core-mu2e/Overlays/FragmentType.hh"
22#include " artdaq-core-mu2e/Overlays/CFO_Packets/CFO_Event.h"
33
4+ #include " artdaq-core/Data/MetadataFragment.hh"
45#include " artdaq/DAQdata/Globals.hh"
56#include " artdaq/Generators/GeneratorMacros.hh"
67
@@ -43,6 +44,9 @@ class CFOZmqReceiver : public artdaq::CommandableFragmentGenerator
4344 uint64_t event_mode_bitmask_;
4445 std::atomic<bool > receive_thread_running_{false };
4546 std::unique_ptr<boost::thread> receiver_thread_;
47+ uint8_t daq_mode_word_value_{0 };
48+ uint64_t predictive_subrun_offset_{0 };
49+ uint32_t current_subrun_number_{1 };
4650};
4751} // namespace mu2e
4852
@@ -52,6 +56,7 @@ mu2e::CFOZmqReceiver::CFOZmqReceiver(fhicl::ParameterSet const& ps)
5256 , socket_(context_, zmq::socket_type::sub)
5357 , zmq_address_(ps.get<std::string>(" zmqAddress" , " inproc://default" ))
5458 , event_mode_bitmask_(ps.get<uint64_t >(" eventModeBitmask" , 0xFFFFFFFFFFFFFFFF ))
59+ , predictive_subrun_offset_(ps.get<uint64_t >(" predictiveSubrunOffset" , 0 ))
5560{
5661 socket_.set (zmq::sockopt::rcvtimeo, 1000 ); // 1 second timeout
5762}
@@ -145,16 +150,31 @@ void mu2e::CFOZmqReceiver::receiveCFOData_()
145150
146151 auto cfoEvent = CFOLib::CFO_Event (data_msg.data ());
147152 uint64_t eventMode = cfoEvent.GetEventRecord ().event_mode ;
153+ uint8_t daqModeWord = static_cast <uint8_t >(eventMode & 0xFF'0000'0000 >> 32 );
148154 auto timestamp = cfoEvent.GetEventWindowTag ().GetEventWindowTag (true );
149155 if ((eventMode & event_mode_bitmask_) == 0 )
150156 {
157+ if (daqModeWord != daq_mode_word_value_)
158+ {
159+ TLOG (TLVL_DEBUG + 25 ) << " Received CFO event " << timestamp << " with DAQ mode word " << std::hex << daqModeWord << " != " << daq_mode_word_value_ << " , checking for subrun transition" ;
160+ std::bitset<8 > daqModeBits (daqModeWord);
161+ daq_mode_word_value_ = daqModeWord;
162+ if (daqModeBits.test (2 ))
163+ {
164+ current_subrun_number_++;
165+ // Sequence in EndOfSubrunFragment is the _last_ timestamp of the subrun, thus subtracting one to make the next subrun start at timestamp + predictive_subrun_offset_
166+ auto endOfSubrunFrag = artdaq::MetadataFragment::CreateEndOfSubrunFragment (my_rank, timestamp + predictive_subrun_offset_ - 1 , current_subrun_number_, 0 );
167+
168+ std::lock_guard<std::mutex> lock (frag_mutex_);
169+ frags_.push_back (std::move (endOfSubrunFrag));
170+ }
171+ continue ;
172+ }
151173 TLOG (TLVL_DEBUG + 25 ) << " Received CFO event " << timestamp << " with mode " << std::hex << eventMode << std::dec << " , skipping due to bitmask" ;
152174 continue ;
153175 }
154- else
155- {
156- TLOG (TLVL_DEBUG + 24 ) << " Received CFO event " << timestamp << " with mode " << std::hex << eventMode << std::dec << " , processing" ;
157- }
176+
177+ TLOG (TLVL_DEBUG + 24 ) << " Received CFO event " << timestamp << " with mode " << std::hex << eventMode << std::dec << " , processing" ;
158178
159179 // Process the received data and create an artdaq Fragment
160180 auto frag = std::make_unique<artdaq::Fragment>(static_cast <artdaq::Fragment::sequence_id_t >(timestamp),
0 commit comments