1 #include "art/Framework/Core/ModuleMacros.h"
2 #include "art/Framework/Core/OutputModule.h"
3 #include "art/Framework/Principal/EventPrincipal.h"
4 #include "art/Framework/Principal/RunPrincipal.h"
5 #include "art/Framework/Principal/SubRunPrincipal.h"
6 #include "art/Framework/Principal/Handle.h"
7 #include "art/Persistency/Common/GroupQueryResult.h"
8 #include "art/Framework/IO/FileStatsCollector.h"
9 #include "art/Framework/IO/PostCloseFileRenamer.h"
10 #include "canvas/Utilities/DebugMacros.h"
11 #include "canvas/Utilities/Exception.h"
12 #include "fhiclcpp/ParameterSet.h"
14 #include "artdaq-core/Data/Fragment.hh"
15 #include "artdaq/DAQdata/Globals.hh"
17 #define TRACE_NAME "BinaryFileOutput"
35 using fhicl::ParameterSet;
62 void beginJob()
override;
64 void endJob()
override;
66 void write(EventPrincipal&)
override;
68 void writeRun(RunPrincipal&)
override {};
69 void writeSubRun(SubRunPrincipal&)
override {};
71 void initialize_FILE_();
73 void deinitialize_FILE_();
75 bool readParameterSet_(fhicl::ParameterSet
const& pset);
78 std::string name_ =
"BinaryFileOutput";
79 std::string file_name_ =
"/tmp/artdaqdemo.binary";
80 bool do_direct_ =
false;
82 std::unique_ptr<std::ofstream> file_ptr_ = {
nullptr};
83 art::FileStatsCollector fstats_;
89 , fstats_{ name_, processName() }
91 FDEBUG(1) <<
"Begin: BinaryFileOutput::BinaryFileOutput(ParameterSet const& ps)\n";
92 readParameterSet_(ps);
93 FDEBUG(1) <<
"End: BinaryFileOutput::BinaryFileOutput(ParameterSet const& ps)\n";
99 FDEBUG(1) <<
"Begin/End: BinaryFileOutput::~BinaryFileOutput()\n";
103 art::BinaryFileOutput::
106 FDEBUG(1) <<
"Begin: BinaryFileOutput::beginJob()\n";
108 FDEBUG(1) <<
"End: BinaryFileOutput::beginJob()\n";
112 art::BinaryFileOutput::
115 FDEBUG(1) <<
"Begin: BinaryFileOutput::endJob()\n";
116 deinitialize_FILE_();
117 FDEBUG(1) <<
"End: BinaryFileOutput::endJob()\n";
122 art::BinaryFileOutput::
125 std::string file_name = PostCloseFileRenamer{ fstats_ }.applySubstitutions(file_name_);
128 fd_ = open(file_name.c_str(), O_WRONLY | O_CREAT | O_DIRECT, 0660);
129 TLOG_ARB(4,
"BinaryFileOutput") <<
"initialize_FILE_ fd_=" << fd_ << TLOG_ENDL;
133 file_ptr_ = std::make_unique<std::ofstream>(file_name, std::ofstream::binary);
134 TRACE(4,
"BinaryFileOutput::initialize_FILE_ file_ptr_=%p errno=%d", (
void*)file_ptr_.get(), errno);
137 fstats_.recordFileOpen();
141 art::BinaryFileOutput::
150 file_ptr_.reset(
nullptr);
151 fstats_.recordFileClose();
155 art::BinaryFileOutput::
156 readParameterSet_(fhicl::ParameterSet
const& pset)
158 TLOG_DEBUG(name_) <<
"BinaryFileOutput::readParameterSet_ method called with "
159 <<
"ParameterSet = \"" << pset.to_string()
160 <<
"\"." << TLOG_ENDL;
164 file_name_ = pset.get<std::string>(
"fileName");
169 <<
"The fileName parameter was not specified "
170 <<
"in the BinaryFileOutput initialization PSet: \""
171 << pset.to_string() <<
"\"." << TLOG_ENDL;
174 do_direct_ = pset.get<
bool>(
"directIO",
false);
179 #define USE_STATIC_BUFFER 0
180 #if USE_STATIC_BUFFER == 1
181 static unsigned char static_buffer[0xa00000];
185 art::BinaryFileOutput::
186 write(EventPrincipal& ep)
188 using RawEvent = artdaq::Fragments;
189 using RawEvents = std::vector<RawEvent>;
190 using RawEventHandle = art::Handle<RawEvent>;
191 using RawEventHandles = std::vector<RawEventHandle>;
193 auto result_handles = std::vector<art::GroupQueryResult>();
194 ep.getManyByType(art::TypeID(
typeid(RawEvent)), result_handles);
196 for (
auto const& result_handle : result_handles)
198 auto const raw_event_handle = RawEventHandle(result_handle);
200 if (!raw_event_handle.isValid())
203 for (
auto const& fragment : *raw_event_handle)
205 auto sequence_id = fragment.sequenceID();
206 auto fragid_id = fragment.fragmentID();
207 TRACE(4,
"BinaryFileOutput::write seq=%lu frag=%i %p bytes=0x%lx start"
208 , sequence_id, fragid_id, fragment.headerBeginBytes(), fragment.sizeBytes());
211 ssize_t sts = ::write(fd_, reinterpret_cast<const char*>(fragment.headerBeginBytes()), fragment.sizeBytes());
212 TRACE(5,
"BinaryFileOutput::write seq=%lu frag=%i done sts=%ld errno=%d"
213 , sequence_id, fragid_id, sts, errno);
217 # if USE_STATIC_BUFFER == 1
218 file_ptr_->write((
char*)static_buffer, fragment.sizeBytes());
220 file_ptr_->write(reinterpret_cast<const char*>(fragment.headerBeginBytes()), fragment.sizeBytes());
222 TRACE(5,
"BinaryFileOutput::write seq=%lu frag=%i done errno=%d"
223 , sequence_id, fragid_id, errno);
227 fstats_.recordEvent(ep.id());
virtual ~BinaryFileOutput()
BinaryFileOutput Destructor.
BinaryFileOutput(ParameterSet const &ps)
BinaryFileOutput Constructor.
The BinaryFileOutput module streams art Events to a binary file, bypassing ROOT.