PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
SIOFrameReader.cc
Go to the documentation of this file.
2#include "podio/SIOBlock.h"
3
4#include "sioUtils.h"
5
6#include <sio/api.h>
7#include <sio/definitions.h>
8
9#include <algorithm>
10#include <utility>
11
12namespace podio {
13
15 auto& libLoader [[maybe_unused]] = SIOBlockLibraryLoader::instance();
16}
17
18void SIOFrameReader::openFile(const std::string& filename) {
19 m_stream.open(filename, std::ios::binary);
20 if (!m_stream.is_open()) {
21 throw std::runtime_error("File " + filename + " couldn't be opened");
22 }
23
24 // NOTE: reading TOC record first because that jumps back to the start of the file!
25 readFileTOCRecord();
26 readPodioHeader();
27 readEDMDefinitions(); // Potentially could do this lazily
28}
29
30std::unique_ptr<SIOFrameData> SIOFrameReader::readNextEntry(const std::string& name) {
31 // Skip to where the next record of this name starts in the file, based on
32 // how many times we have already read this name
33 //
34 // NOTE: exploiting the fact that the operator[] of a map will create a
35 // default initialized entry for us if not present yet
36 const auto recordPos = m_tocRecord.getPosition(name, m_nameCtr[name]);
37 if (recordPos == 0) {
38 return nullptr;
39 }
40 m_stream.seekg(recordPos);
41
42 auto [tableBuffer, tableInfo] = sio_utils::readRecord(m_stream, false);
43 auto [dataBuffer, dataInfo] = sio_utils::readRecord(m_stream, false);
44
45 m_nameCtr[name]++;
46
47 return std::make_unique<SIOFrameData>(std::move(dataBuffer), dataInfo._uncompressed_length, std::move(tableBuffer),
48 tableInfo._uncompressed_length);
49}
50
51std::unique_ptr<SIOFrameData> SIOFrameReader::readEntry(const std::string& name, const unsigned entry) {
52 // NOTE: Will create or overwrite the entry counter
53 // All checks are done in the following function
54 m_nameCtr[name] = entry;
55 return readNextEntry(name);
56}
57
58std::vector<std::string_view> SIOFrameReader::getAvailableCategories() const {
59 // Filter the availalbe records from the TOC to remove records that are
60 // stored, but use reserved record names for podio meta data
61 auto recordNames = m_tocRecord.getRecordNames();
62 recordNames.erase(std::remove_if(recordNames.begin(), recordNames.end(),
63 [](const auto& elem) { return elem == sio_helpers::SIOEDMDefinitionName; }),
64 recordNames.end());
65 return recordNames;
66}
67
68unsigned SIOFrameReader::getEntries(const std::string& name) const {
69 return m_tocRecord.getNRecords(name);
70}
71
72bool SIOFrameReader::readFileTOCRecord() {
73 // Check if there is a dedicated marker at the end of the file that tells us
74 // where the TOC actually starts
75 m_stream.seekg(-sio_helpers::SIOTocInfoSize, std::ios_base::end);
76 uint64_t firstWords{0};
77 m_stream.read(reinterpret_cast<char*>(&firstWords), sizeof(firstWords));
78
79 const uint32_t marker = (firstWords >> 32) & 0xffffffff;
80 if (marker == sio_helpers::SIOTocMarker) {
81 const uint32_t position = firstWords & 0xffffffff;
82 m_stream.seekg(position);
83
84 const auto& [uncBuffer, _] = sio_utils::readRecord(m_stream);
85
86 sio::block_list blocks;
87 auto tocBlock = std::make_shared<SIOFileTOCRecordBlock>();
88 tocBlock->record = &m_tocRecord;
89 blocks.push_back(tocBlock);
90
91 sio::api::read_blocks(uncBuffer.span(), blocks);
92
93 m_stream.seekg(0);
94 return true;
95 }
96
97 m_stream.clear();
98 m_stream.seekg(0);
99 return false;
100}
101
102void SIOFrameReader::readPodioHeader() {
103 const auto& [buffer, _] = sio_utils::readRecord(m_stream, false, sizeof(podio::version::Version));
104
105 sio::block_list blocks;
106 blocks.emplace_back(std::make_shared<SIOVersionBlock>());
107 sio::api::read_blocks(buffer.span(), blocks);
108
109 m_fileVersion = static_cast<SIOVersionBlock*>(blocks[0].get())->version;
110}
111
112void SIOFrameReader::readEDMDefinitions() {
113 const auto recordPos = m_tocRecord.getPosition(sio_helpers::SIOEDMDefinitionName);
114 if (recordPos == 0) {
115 // No EDM definitions found
116 return;
117 }
118 m_stream.seekg(recordPos);
119
120 const auto& [buffer, _] = sio_utils::readRecord(m_stream);
121
122 sio::block_list blocks;
123 blocks.emplace_back(std::make_shared<podio::SIOMapBlock<std::string, std::string>>());
124 sio::api::read_blocks(buffer.span(), blocks);
125
126 auto datamodelDefs = static_cast<SIOMapBlock<std::string, std::string>*>(blocks[0].get());
127 m_datamodelHolder = DatamodelDefinitionHolder(std::move(datamodelDefs->mapData));
128}
129
130} // namespace podio
static SIOBlockLibraryLoader & instance()
Definition: SIOBlock.h:263
PositionType getPosition(const std::string &name, unsigned iEntry=0) const
Definition: SIOBlock.cc:204
size_t getNRecords(const std::string &name) const
Definition: SIOBlock.cc:195
std::vector< std::string_view > getRecordNames() const
Definition: SIOBlock.cc:216
unsigned getEntries(const std::string &name) const
Returns number of entries for the given name.
std::vector< std::string_view > getAvailableCategories() const
Get the names of all the availalable Frame categories in the current file(s)
void openFile(const std::string &filename)
std::unique_ptr< podio::SIOFrameData > readEntry(const std::string &name, const unsigned entry)
std::unique_ptr< podio::SIOFrameData > readNextEntry(const std::string &name)
std::pair< sio::buffer, sio::record_info > readRecord(sio::ifstream &stream, bool decompress=true, std::size_t initBufferSize=sio::mbyte)
Read the record into a buffer and potentially uncompress it.
Definition: sioUtils.h:18