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/RootDAQOutput/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
00065 class art::RootDAQOutFile {
00066 public:
00067
00071 enum class ClosureRequestMode { MaxEvents, MaxSize, Unset };
00072 using RootOutputTreePtrArray = std::array<std::unique_ptr<RootOutputTree>, NumBranchTypes>;
00073
00074 struct OutputItem {
00075
00076 BranchDescription const* branchDescription_ {nullptr};
00077 mutable void const* product_ {nullptr};
00078
00079 class Sorter {
00080 public:
00081
00082 explicit Sorter(TTree* tree);
00083 bool operator()(OutputItem const& lh, OutputItem const& rh) const;
00084
00085 private:
00086
00087
00088 std::map<std::string, int> treeMap_;
00089 };
00090
00091 ~OutputItem() = default;
00092
00093 explicit OutputItem(BranchDescription const* bd)
00094 : branchDescription_{bd}
00095 {}
00096
00097 BranchID branchID() const
00098 {
00099 return branchDescription_->branchID();
00100 }
00101
00102 std::string const& branchName() const
00103 {
00104 return branchDescription_->branchName();
00105 }
00106
00107 bool operator<(OutputItem const& rh) const
00108 {
00109 return *branchDescription_ < *rh.branchDescription_;
00110 }
00111
00112 };
00113
00114 using OutputItemList = std::vector<OutputItem>;
00115
00116 using OutputItemListArray = std::array<OutputItemList, NumBranchTypes>;
00117
00118 public:
00119
00120 explicit RootDAQOutFile(OutputModule*,
00121 std::string const& fileName,
00122 ClosingCriteria const& fileSwitchCriteria,
00123 int const compressionLevel,
00124 int64_t const saveMemoryObjectThreshold,
00125 int64_t const treeMaxVirtualSize,
00126 int const splitLevel,
00127 int const basketSize,
00128 DropMetaData dropMetaData,
00129 bool dropMetaDataForDroppedData,
00130 bool fastCloning);
00131
00132 #if ART_HEX_VERSION >= 0x20703
00133 void writeTTrees();
00134 #endif
00135 void writeOne(EventPrincipal const&);
00136 void writeSubRun(SubRunPrincipal const&);
00137 void writeRun(RunPrincipal const&);
00138 void writeFileFormatVersion();
00139 void writeFileIndex();
00140 void writeEventHistory();
00141 void writeProcessConfigurationRegistry();
00142 void writeProcessHistoryRegistry();
00143 void writeParameterSetRegistry();
00144 void writeProductDescriptionRegistry();
00145 void writeParentageRegistry();
00146 void writeBranchIDListRegistry();
00147 void writeProductDependencies();
00148 void writeFileCatalogMetadata(FileStatsCollector const& stats,
00149 FileCatalogMetadata::collection_type const&,
00150 FileCatalogMetadata::collection_type const&);
00151 void writeResults(ResultsPrincipal & resp);
00152 void setRunAuxiliaryRangeSetID(RangeSet const&);
00153 void setSubRunAuxiliaryRangeSetID(RangeSet const&);
00154 void finishEndFile();
00155 void beginInputFile(FileBlock const&, bool fastClone);
00156 void incrementInputFileNumber();
00157 void respondToCloseInputFile(FileBlock const&);
00158 bool requestsToCloseFile();
00159 void setFileStatus(OutputFileStatus const ofs) { status_ = ofs; }
00160
00161 void selectProducts(FileBlock const&);
00162
00163 std::string const& currentFileName() const { return file_; }
00164
00165 bool maxEventsPerFileReached(FileIndex::EntryNumber_t const maxEventsPerFile) const;
00166 bool maxSizeReached(unsigned const maxFileSize) const;
00167
00168 private:
00169
00170 void createDatabaseTables();
00171
00172 template <BranchType>
00173 void fillBranches(Principal const&,
00174 std::vector<ProductProvenance>*);
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 template <BranchType BT>
00183 std::enable_if_t<detail::RangeSetsSupported<BT>::value, art::EDProduct const*>
00184 getProduct(OutputHandle const&,
00185 RangeSet const& productRS,
00186 std::string const& wrappedName);
00187
00188 private:
00189
00190 OutputModule const* om_;
00191 std::string file_;
00192 ClosingCriteria fileSwitchCriteria_;
00193 OutputFileStatus status_ {OutputFileStatus::Closed};
00194 int const compressionLevel_;
00195 int64_t const saveMemoryObjectThreshold_;
00196 int64_t const treeMaxVirtualSize_;
00197 int const splitLevel_;
00198 int const basketSize_;
00199 DropMetaData dropMetaData_;
00200 bool dropMetaDataForDroppedData_;
00201 bool fastCloning_;
00202 bool currentlyFastCloning_ {true};
00203 std::unique_ptr<TFile> filePtr_;
00204 FileIndex fileIndex_ {};
00205 FileProperties fp_ {};
00206 TTree* metaDataTree_ {nullptr};
00207 TTree* fileIndexTree_ {nullptr};
00208 TTree* parentageTree_ {nullptr};
00209 TTree* eventHistoryTree_ {nullptr};
00210 EventAuxiliary const* pEventAux_ {nullptr};
00211 SubRunAuxiliary const* pSubRunAux_ {nullptr};
00212 RunAuxiliary const* pRunAux_ {nullptr};
00213 ResultsAuxiliary const *pResultsAux_ {nullptr};
00214 ProductProvenances eventProductProvenanceVector_ {};
00215 ProductProvenances subRunProductProvenanceVector_ {};
00216 ProductProvenances runProductProvenanceVector_ {};
00217 ProductProvenances resultsProductProvenanceVector_ {};
00218 ProductProvenances* pEventProductProvenanceVector_ {&eventProductProvenanceVector_};
00219 ProductProvenances* pSubRunProductProvenanceVector_ {&subRunProductProvenanceVector_};
00220 ProductProvenances* pRunProductProvenanceVector_ {&runProductProvenanceVector_};
00221 ProductProvenances* pResultsProductProvenanceVector_ {&resultsProductProvenanceVector_};
00222 History const* pHistory_ {nullptr};
00223 RootOutputTreePtrArray treePointers_;
00224 bool dataTypeReported_ {false};
00225 std::set<BranchID> branchesWithStoredHistory_ {};
00226 # if ART_HEX_VERSION >= 0x20703
00227 cet::sqlite::Connection rootFileDB_;
00228 # else
00229 SQLite3Wrapper rootFileDB_;
00230 # endif
00231 OutputItemListArray selectedOutputItemList_ {{}};
00232 detail::DummyProductCache dummyProductCache_ {};
00233 unsigned subRunRSID_ {-1u};
00234 unsigned runRSID_ {-1u};
00235 std::chrono::steady_clock::time_point beginTime_ {std::chrono::steady_clock::now()};
00236 };
00237
00238
00239
00240
00241 #endif