1 #include "TRACE/tracemf.h"
2 #define TRACE_NAME "BinaryFileOutput"
4 #include "art/Framework/Core/ModuleMacros.h"
5 #include "art/Framework/Core/OutputModule.h"
6 #include "art/Framework/IO/FileStatsCollector.h"
7 #include "art/Framework/IO/PostCloseFileRenamer.h"
8 #include "art/Framework/Principal/EventPrincipal.h"
9 #include "art/Framework/Principal/Handle.h"
10 #include "art/Framework/Principal/RunPrincipal.h"
11 #include "art/Framework/Principal/SubRunPrincipal.h"
12 #include "art/Persistency/Common/GroupQueryResult.h"
13 #include "art/Persistency/Provenance/ModuleContext.h"
14 #include "canvas/Persistency/Common/WrappedTypeID.h"
15 #include "canvas/Persistency/Common/Wrapper.h"
16 #include "canvas/Utilities/DebugMacros.h"
17 #include "canvas/Utilities/Exception.h"
18 #include "fhiclcpp/ParameterSet.h"
20 #include "artdaq-core/Data/Fragment.hh"
21 #include "artdaq/DAQdata/Globals.hh"
38 using fhicl::ParameterSet;
65 void beginJob()
override;
67 void endJob()
override;
69 void write(EventPrincipal& )
override;
71 void writeRun(RunPrincipal& )
override{};
72 void writeSubRun(SubRunPrincipal& )
override{};
74 void initialize_FILE_();
76 void deinitialize_FILE_();
78 bool readParameterSet_(fhicl::ParameterSet
const& pset);
86 std::string name_ =
"BinaryFileOutput";
87 std::string file_name_ =
"/tmp/artdaqdemo.binary";
88 bool do_direct_ =
false;
90 std::unique_ptr<std::ofstream> file_ptr_ = {
nullptr};
91 art::FileStatsCollector fstats_;
95 : OutputModule(ps), fstats_{name_, processName()}
97 TLOG(TLVL_DEBUG + 32) <<
"Begin: BinaryFileOutput::BinaryFileOutput(ParameterSet const& ps)\n";
98 readParameterSet_(ps);
99 TLOG(TLVL_DEBUG + 32) <<
"End: BinaryFileOutput::BinaryFileOutput(ParameterSet const& ps)\n";
104 void art::BinaryFileOutput::beginJob()
106 TLOG(TLVL_DEBUG + 32) <<
"Begin: BinaryFileOutput::beginJob()\n";
108 TLOG(TLVL_DEBUG + 32) <<
"End: BinaryFileOutput::beginJob()\n";
111 void art::BinaryFileOutput::endJob()
113 TLOG(TLVL_DEBUG + 32) <<
"Begin: BinaryFileOutput::endJob()\n";
114 deinitialize_FILE_();
115 TLOG(TLVL_DEBUG + 32) <<
"End: BinaryFileOutput::endJob()\n";
118 void art::BinaryFileOutput::initialize_FILE_()
120 std::string file_name = PostCloseFileRenamer{fstats_}.applySubstitutions(file_name_);
123 fd_ = open(file_name.c_str(), O_WRONLY | O_CREAT | O_DIRECT, 0660);
124 TLOG(TLVL_DEBUG + 33) <<
"initialize_FILE_ fd_=" << fd_;
128 file_ptr_ = std::make_unique<std::ofstream>(file_name, std::ofstream::binary);
129 TLOG(TLVL_DEBUG + 33) <<
"BinaryFileOutput::initialize_FILE_ file_ptr_=" <<
static_cast<void*
>(file_ptr_.get()) <<
" errno=" << errno;
132 fstats_.recordFileOpen();
135 void art::BinaryFileOutput::deinitialize_FILE_()
144 file_ptr_.reset(
nullptr);
146 fstats_.recordFileClose();
149 bool art::BinaryFileOutput::readParameterSet_(fhicl::ParameterSet
const& pset)
151 TLOG(TLVL_DEBUG + 32) << name_ <<
"BinaryFileOutput::readParameterSet_ method called with "
152 <<
"ParameterSet = \"" << pset.to_string() <<
"\".";
156 file_name_ = pset.get<std::string>(
"fileName");
160 TLOG(TLVL_ERROR) << name_ <<
"The fileName parameter was not specified "
161 <<
"in the BinaryFileOutput initialization PSet: \"" << pset.to_string() <<
"\".";
164 do_direct_ = pset.get<
bool>(
"directIO",
false);
169 #define USE_STATIC_BUFFER 0
170 #if USE_STATIC_BUFFER == 1
171 static unsigned char static_buffer[0xa00000];
174 void art::BinaryFileOutput::write(EventPrincipal& ep)
176 using RawEvent = artdaq::Fragments;
177 using RawEvents = std::vector<RawEvent>;
178 using RawEventHandle = art::Handle<RawEvent>;
179 using RawEventHandles = std::vector<RawEventHandle>;
181 auto result_handles = std::vector<art::GroupQueryResult>();
182 auto const& wrapped = art::WrappedTypeID::make<RawEvent>();
183 ModuleContext
const mc{moduleDescription()};
184 ProcessTag
const processTag{
"", mc.moduleDescription().processName()};
186 result_handles = ep.getMany(mc, wrapped, art::MatchAllSelector{}, processTag);
188 for (
auto const& result_handle : result_handles)
190 auto const raw_event_handle = RawEventHandle(result_handle);
192 if (!raw_event_handle.isValid())
197 for (
auto const& fragment : *raw_event_handle)
199 auto sequence_id = fragment.sequenceID();
200 auto fragid_id = fragment.fragmentID();
201 TLOG(TLVL_DEBUG + 33) <<
"BinaryFileOutput::write seq=" << sequence_id <<
" frag=" << fragid_id <<
" "
202 <<
reinterpret_cast<const void*
>(fragment.headerBeginBytes()) <<
" bytes=0x" << std::hex
203 << fragment.sizeBytes() <<
" start";
206 ssize_t sts = ::write(fd_, reinterpret_cast<const char*>(fragment.headerBeginBytes()), fragment.sizeBytes());
207 TLOG(TLVL_DEBUG + 34) <<
"BinaryFileOutput::write seq=" << sequence_id <<
" frag=" << fragid_id <<
" done sts=" << sts
208 <<
" errno=" << errno;
212 #if USE_STATIC_BUFFER == 1
213 file_ptr_->write((
char*)static_buffer, fragment.sizeBytes());
215 file_ptr_->write(reinterpret_cast<const char*>(fragment.headerBeginBytes()), fragment.sizeBytes());
217 TLOG(TLVL_DEBUG + 34) <<
"BinaryFileOutput::write seq=" << sequence_id <<
" frag=" << fragid_id <<
" done errno=" << errno;
221 fstats_.recordEvent(ep.eventID());
~BinaryFileOutput() override
BinaryFileOutput Destructor.
BinaryFileOutput(ParameterSet const &ps)
BinaryFileOutput Constructor.
The BinaryFileOutput module streams art Events to a binary file, bypassing ROOT.