$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 00002 00003 #define TRACE_NAME "BinaryFileOutput" 00004 00005 #include "art/Framework/Core/ModuleMacros.h" 00006 #include "art/Framework/Core/OutputModule.h" 00007 #include "art/Framework/Principal/EventPrincipal.h" 00008 #include "art/Framework/Principal/RunPrincipal.h" 00009 #include "art/Framework/Principal/SubRunPrincipal.h" 00010 #include "art/Framework/Principal/Handle.h" 00011 #include "art/Persistency/Common/GroupQueryResult.h" 00012 #include "art/Framework/IO/FileStatsCollector.h" 00013 #include "art/Framework/IO/PostCloseFileRenamer.h" 00014 #include "canvas/Utilities/DebugMacros.h" 00015 #include "canvas/Utilities/Exception.h" 00016 #include "fhiclcpp/ParameterSet.h" 00017 00018 #include "artdaq-core/Data/Fragment.hh" 00019 #include "artdaq/DAQdata/Globals.hh" 00020 00021 #include <iomanip> 00022 #include <iostream> 00023 #include <fstream> 00024 #include <sstream> 00025 #include <string> 00026 #include <vector> 00027 #include <memory> 00028 #include <unistd.h> 00029 #include <stdio.h> 00030 00031 namespace art 00032 { 00033 class BinaryFileOutput; 00034 } 00035 00036 using art::BinaryFileOutput; 00037 using fhicl::ParameterSet; 00038 00042 class art::BinaryFileOutput final: public OutputModule 00043 { 00044 public: 00056 explicit BinaryFileOutput(ParameterSet const& ps); 00057 00061 virtual ~BinaryFileOutput(); 00062 00063 private: 00064 void beginJob() override; 00065 00066 void endJob() override; 00067 00068 void write(EventPrincipal&) override; 00069 00070 void writeRun(RunPrincipal&) override {}; 00071 void writeSubRun(SubRunPrincipal&) override {}; 00072 00073 void initialize_FILE_(); 00074 00075 void deinitialize_FILE_(); 00076 00077 bool readParameterSet_(fhicl::ParameterSet const& pset); 00078 00079 private: 00080 std::string name_ = "BinaryFileOutput"; 00081 std::string file_name_ = "/tmp/artdaqdemo.binary"; 00082 bool do_direct_ = false; 00083 int fd_ = -1; // Used for direct IO 00084 std::unique_ptr<std::ofstream> file_ptr_ = {nullptr}; 00085 art::FileStatsCollector fstats_; 00086 }; 00087 00088 art::BinaryFileOutput:: 00089 BinaryFileOutput(ParameterSet const& ps) 00090 : OutputModule(ps) 00091 , fstats_{ name_, processName() } 00092 { 00093 TLOG(TLVL_DEBUG) << "Begin: BinaryFileOutput::BinaryFileOutput(ParameterSet const& ps)\n"; 00094 readParameterSet_(ps); 00095 TLOG(TLVL_DEBUG) << "End: BinaryFileOutput::BinaryFileOutput(ParameterSet const& ps)\n"; 00096 } 00097 00098 art::BinaryFileOutput:: 00099 ~BinaryFileOutput() 00100 { 00101 TLOG(TLVL_DEBUG) << "Begin/End: BinaryFileOutput::~BinaryFileOutput()\n"; 00102 } 00103 00104 void 00105 art::BinaryFileOutput:: 00106 beginJob() 00107 { 00108 TLOG(TLVL_DEBUG) << "Begin: BinaryFileOutput::beginJob()\n"; 00109 initialize_FILE_(); 00110 TLOG(TLVL_DEBUG) << "End: BinaryFileOutput::beginJob()\n"; 00111 } 00112 00113 void 00114 art::BinaryFileOutput:: 00115 endJob() 00116 { 00117 TLOG(TLVL_DEBUG) << "Begin: BinaryFileOutput::endJob()\n"; 00118 deinitialize_FILE_(); 00119 TLOG(TLVL_DEBUG) << "End: BinaryFileOutput::endJob()\n"; 00120 } 00121 00122 00123 void 00124 art::BinaryFileOutput:: 00125 initialize_FILE_() 00126 { 00127 std::string file_name = PostCloseFileRenamer{ fstats_ }.applySubstitutions(file_name_); 00128 if (do_direct_) 00129 { 00130 fd_ = open(file_name.c_str(), O_WRONLY | O_CREAT | O_DIRECT, 0660); 00131 TLOG(TLVL_TRACE) << "initialize_FILE_ fd_=" << fd_; 00132 } 00133 else 00134 { 00135 file_ptr_ = std::make_unique<std::ofstream>(file_name, std::ofstream::binary); 00136 TLOG(TLVL_TRACE) << "BinaryFileOutput::initialize_FILE_ file_ptr_=" << (void*)file_ptr_.get() << " errno=" << errno; 00137 //file_ptr_->rdbuf()->pubsetbuf(0, 0); 00138 } 00139 fstats_.recordFileOpen(); 00140 } 00141 00142 void 00143 art::BinaryFileOutput:: 00144 deinitialize_FILE_() 00145 { 00146 if (do_direct_) 00147 { 00148 close(fd_); 00149 fd_ = -1; 00150 } 00151 else 00152 file_ptr_.reset(nullptr); 00153 fstats_.recordFileClose(); 00154 } 00155 00156 bool 00157 art::BinaryFileOutput:: 00158 readParameterSet_(fhicl::ParameterSet const& pset) 00159 { 00160 TLOG(TLVL_DEBUG) << name_ << "BinaryFileOutput::readParameterSet_ method called with " 00161 << "ParameterSet = \"" << pset.to_string() 00162 << "\"."; 00163 // determine the data sending parameters 00164 try 00165 { 00166 file_name_ = pset.get<std::string>("fileName"); 00167 } 00168 catch (...) 00169 { 00170 TLOG(TLVL_ERROR) << name_ 00171 << "The fileName parameter was not specified " 00172 << "in the BinaryFileOutput initialization PSet: \"" 00173 << pset.to_string() << "\"."; 00174 return false; 00175 } 00176 do_direct_ = pset.get<bool>("directIO", false); 00177 // determine the data sending parameters 00178 return true; 00179 } 00180 00181 #define USE_STATIC_BUFFER 0 00182 #if USE_STATIC_BUFFER == 1 00183 static unsigned char static_buffer[0xa00000]; 00184 #endif 00185 00186 void 00187 art::BinaryFileOutput:: 00188 write(EventPrincipal& ep) 00189 { 00190 using RawEvent = artdaq::Fragments; 00191 using RawEvents = std::vector<RawEvent>; 00192 using RawEventHandle = art::Handle<RawEvent>; 00193 using RawEventHandles = std::vector<RawEventHandle>; 00194 00195 auto result_handles = std::vector<art::GroupQueryResult>(); 00196 auto const& wrapped = art::WrappedTypeID::make<RawEvent>(); 00197 result_handles = ep.getMany(wrapped, art::MatchAllSelector{}); 00198 00199 for (auto const& result_handle : result_handles) 00200 { 00201 auto const raw_event_handle = RawEventHandle(result_handle); 00202 00203 if (!raw_event_handle.isValid()) 00204 continue; 00205 00206 for (auto const& fragment : *raw_event_handle) 00207 { 00208 auto sequence_id = fragment.sequenceID(); 00209 auto fragid_id = fragment.fragmentID(); 00210 TLOG(TLVL_TRACE) << "BinaryFileOutput::write seq=" << sequence_id 00211 << " frag=" << fragid_id << " " << reinterpret_cast<const void*>(fragment.headerBeginBytes()) 00212 << " bytes=0x" << std::hex << fragment.sizeBytes() << " start"; 00213 if (do_direct_) 00214 { 00215 ssize_t sts = ::write(fd_, reinterpret_cast<const char*>(fragment.headerBeginBytes()), fragment.sizeBytes()); 00216 TLOG(5) << "BinaryFileOutput::write seq=" << sequence_id << " frag=" << fragid_id << " done sts=" << sts << " errno=" << errno; 00217 } 00218 else 00219 { 00220 # if USE_STATIC_BUFFER == 1 00221 file_ptr_->write((char*)static_buffer, fragment.sizeBytes()); 00222 # else 00223 file_ptr_->write(reinterpret_cast<const char*>(fragment.headerBeginBytes()), fragment.sizeBytes()); 00224 # endif 00225 TLOG(5) << "BinaryFileOutput::write seq=" << sequence_id << " frag=" << fragid_id << " done errno=" << errno; 00226 } 00227 } 00228 } 00229 fstats_.recordEvent(ep.id()); 00230 return; 00231 } 00232 00233 DEFINE_ART_MODULE(art::BinaryFileOutput)