00001 #ifndef artdaq_ArtModules_RootDAQOutFile_h
00002 #define artdaq_ArtModules_RootDAQOutFile_h
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "art/Framework/Core/Frameworkfwd.h"
00014 #include "art/Framework/Core/OutputModule.h"
00015 #include "art/Framework/IO/FileStatsCollector.h"
00016 #include "art/Framework/IO/Root/DropMetaData.h"
00017 #include "art/Framework/IO/Root/RootOutputClosingCriteria.h"
00018 #include "art/Framework/IO/Root/RootOutputTree.h"
00019 #include "artdaq/ArtModules/detail/DummyProductCache.h"
00020 #include "art/Framework/Principal/RangeSetsSupported.h"
00021 #if ART_HEX_VERSION >= 0x20703
00022 # include "art/Persistency/Provenance/Selections.h"
00023 # include "boost/filesystem.hpp"
00024 # include "cetlib/sqlite/Connection.h"
00025 #else
00026 # include "art/Persistency/Provenance/Selections.h"
00027 # include "boost/filesystem.hpp"
00028 #endif
00029 #include "canvas/Persistency/Provenance/BranchDescription.h"
00030 #include "canvas/Persistency/Provenance/BranchID.h"
00031 #include "canvas/Persistency/Provenance/BranchType.h"
00032 #include "canvas/Persistency/Provenance/FileIndex.h"
00033 #include "canvas/Persistency/Provenance/ParameterSetBlob.h"
00034 #include "canvas/Persistency/Provenance/ParameterSetMap.h"
00035 #include "canvas/Persistency/Provenance/ProductProvenance.h"
00036 #include "art/Persistency/RootDB/SQLite3Wrapper.h"
00037
00038 #include <array>
00039 #include <map>
00040 #include <memory>
00041 #include <string>
00042 #include <vector>
00043
00044 #include "TROOT.h"
00045
00046 class TFile;
00047 class TTree;
00048
00049 namespace art {
00050 class ResultsPrincipal;
00051 class RootDAQOutFile;
00052 class RootOutput;
00053 class RootOutputTree;
00054 class History;
00055 class FileBlock;
00056 class EventAuxiliary;
00057 class SubRunAuxiliary;
00058 class RunAuxiliary;
00059 class ResultsAuxiliary;
00060 }
00061
00062 class art::RootDAQOutFile {
00063 public:
00064
00065 enum class ClosureRequestMode { MaxEvents, MaxSize, Unset };
00066 using RootOutputTreePtrArray = std::array<std::unique_ptr<RootOutputTree>, NumBranchTypes>;
00067
00068 struct OutputItem {
00069
00070 BranchDescription const* branchDescription_ {nullptr};
00071 mutable void const* product_ {nullptr};
00072
00073 class Sorter {
00074 public:
00075
00076 explicit Sorter(TTree* tree);
00077 bool operator()(OutputItem const& lh, OutputItem const& rh) const;
00078
00079 private:
00080
00081
00082 std::map<std::string, int> treeMap_;
00083 };
00084
00085 ~OutputItem() = default;
00086
00087 explicit OutputItem(BranchDescription const* bd)
00088 : branchDescription_{bd}
00089 {}
00090
00091 BranchID branchID() const
00092 {
00093 return branchDescription_->branchID();
00094 }
00095
00096 std::string const& branchName() const
00097 {
00098 return branchDescription_->branchName();
00099 }
00100
00101 bool operator<(OutputItem const& rh) const
00102 {
00103 return *branchDescription_ < *rh.branchDescription_;
00104 }
00105
00106 };
00107
00108 using OutputItemList = std::vector<OutputItem>;
00109
00110 using OutputItemListArray = std::array<OutputItemList, NumBranchTypes>;
00111
00112 public:
00113
00114 explicit RootDAQOutFile(OutputModule*,
00115 std::string const& fileName,
00116 ClosingCriteria const& fileSwitchCriteria,
00117 int const compressionLevel,
00118 int64_t const saveMemoryObjectThreshold,
00119 int64_t const treeMaxVirtualSize,
00120 int const splitLevel,
00121 int const basketSize,
00122 DropMetaData dropMetaData,
00123 bool dropMetaDataForDroppedData,
00124 bool fastCloning);
00125
00126 #if ART_HEX_VERSION >= 0x20703
00127 void writeTTrees();
00128 #endif
00129 void writeOne(EventPrincipal const&);
00130 void writeSubRun(SubRunPrincipal const&);
00131 void writeRun(RunPrincipal const&);
00132 void writeFileFormatVersion();
00133 void writeFileIndex();
00134 void writeEventHistory();
00135 void writeProcessConfigurationRegistry();
00136 void writeProcessHistoryRegistry();
00137 void writeParameterSetRegistry();
00138 void writeProductDescriptionRegistry();
00139 void writeParentageRegistry();
00140 void writeBranchIDListRegistry();
00141 void writeProductDependencies();
00142 void writeFileCatalogMetadata(FileStatsCollector const& stats,
00143 FileCatalogMetadata::collection_type const&,
00144 FileCatalogMetadata::collection_type const&);
00145 void writeResults(ResultsPrincipal & resp);
00146 void setRunAuxiliaryRangeSetID(RangeSet const&);
00147 void setSubRunAuxiliaryRangeSetID(RangeSet const&);
00148 void finishEndFile();
00149 void beginInputFile(FileBlock const&, bool fastClone);
00150 void incrementInputFileNumber();
00151 void respondToCloseInputFile(FileBlock const&);
00152 bool requestsToCloseFile();
00153 void setFileStatus(OutputFileStatus const ofs) { status_ = ofs; }
00154
00155 void selectProducts(FileBlock const&);
00156
00157 std::string const& currentFileName() const { return file_; }
00158
00159 bool maxEventsPerFileReached(FileIndex::EntryNumber_t const maxEventsPerFile) const;
00160 bool maxSizeReached(unsigned const maxFileSize) const;
00161
00162 private:
00163
00164 void createDatabaseTables();
00165
00166 template <BranchType>
00167 void fillBranches(Principal const&,
00168 std::vector<ProductProvenance>*);
00169
00170 template <BranchType BT>
00171 std::enable_if_t<!detail::RangeSetsSupported<BT>::value, art::EDProduct const*>
00172 getProduct(OutputHandle const&,
00173 RangeSet const& productRS,
00174 std::string const& wrappedName);
00175
00176 template <BranchType BT>
00177 std::enable_if_t<detail::RangeSetsSupported<BT>::value, art::EDProduct const*>
00178 getProduct(OutputHandle const&,
00179 RangeSet const& productRS,
00180 std::string const& wrappedName);
00181
00182 private:
00183
00184 OutputModule const* om_;
00185 std::string file_;
00186 ClosingCriteria fileSwitchCriteria_;
00187 OutputFileStatus status_ {OutputFileStatus::Closed};
00188 int const compressionLevel_;
00189 int64_t const saveMemoryObjectThreshold_;
00190 int64_t const treeMaxVirtualSize_;
00191 int const splitLevel_;
00192 int const basketSize_;
00193 DropMetaData dropMetaData_;
00194 bool dropMetaDataForDroppedData_;
00195 bool fastCloning_;
00196 bool currentlyFastCloning_ {true};
00197 std::unique_ptr<TFile> filePtr_;
00198 FileIndex fileIndex_ {};
00199 FileProperties fp_ {};
00200 TTree* metaDataTree_ {nullptr};
00201 TTree* fileIndexTree_ {nullptr};
00202 TTree* parentageTree_ {nullptr};
00203 TTree* eventHistoryTree_ {nullptr};
00204 EventAuxiliary const* pEventAux_ {nullptr};
00205 SubRunAuxiliary const* pSubRunAux_ {nullptr};
00206 RunAuxiliary const* pRunAux_ {nullptr};
00207 ResultsAuxiliary const *pResultsAux_ {nullptr};
00208 ProductProvenances eventProductProvenanceVector_ {};
00209 ProductProvenances subRunProductProvenanceVector_ {};
00210 ProductProvenances runProductProvenanceVector_ {};
00211 ProductProvenances resultsProductProvenanceVector_ {};
00212 ProductProvenances* pEventProductProvenanceVector_ {&eventProductProvenanceVector_};
00213 ProductProvenances* pSubRunProductProvenanceVector_ {&subRunProductProvenanceVector_};
00214 ProductProvenances* pRunProductProvenanceVector_ {&runProductProvenanceVector_};
00215 ProductProvenances* pResultsProductProvenanceVector_ {&resultsProductProvenanceVector_};
00216 History const* pHistory_ {nullptr};
00217 RootOutputTreePtrArray treePointers_;
00218 bool dataTypeReported_ {false};
00219 std::set<BranchID> branchesWithStoredHistory_ {};
00220 # if ART_HEX_VERSION >= 0x20703
00221 cet::sqlite::Connection rootFileDB_;
00222 # else
00223 SQLite3Wrapper rootFileDB_;
00224 # endif
00225 OutputItemListArray selectedOutputItemList_ {{}};
00226 detail::DummyProductCache dummyProductCache_ {};
00227 unsigned subRunRSID_ {-1u};
00228 unsigned runRSID_ {-1u};
00229 std::chrono::steady_clock::time_point beginTime_ {std::chrono::steady_clock::now()};
00230 };
00231
00232
00233
00234
00235 #endif