PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
SIOWriter.cc
Go to the documentation of this file.
1// podio specific includes
2#include "podio/SIOWriter.h"
4#include "podio/EventStore.h"
5#include "podio/SIOBlock.h"
6
7#include "sioUtils.h"
8
9// SIO specifc includes
10#include "sio/block.h"
11#include "sio/compression/zlib.h"
12
13namespace podio {
14
15SIOWriter::SIOWriter(const std::string& filename, EventStore* store) :
16 m_filename(filename),
17 m_store(store),
18 m_eventMetaData(std::make_shared<SIOEventMetaDataBlock>()),
19 m_runMetaData(std::make_shared<SIONumberedMetaDataBlock>("RunMetaData")),
20 m_collectionMetaData(std::make_shared<SIONumberedMetaDataBlock>("CollectionMetaData")) {
21
22 m_stream.open(filename, std::ios::binary);
23
24 if (not m_stream.is_open()) {
25 SIO_THROW(sio::error_code::not_open, "Couldn't open output stream '" + filename + "'");
26 }
27
28 // TODO: re-visit this once metadata handling is done in better defined way
29 m_eventMetaData->metadata = m_store->eventMetaDataPtr();
30
31 m_runMetaData->data = m_store->getRunMetaDataMap();
32 m_collectionMetaData->data = m_store->getColMetaDataMap();
33
34 auto& libLoader [[maybe_unused]] = SIOBlockLibraryLoader::instance();
35}
36
38 if (m_firstEvent) {
39 // Write the collectionIDs as a separate record at the beginning of the
40 // file. In this way they can easily be retrieved in the SIOReader without
41 // having to look for this specific record.
42 writeCollectionIDTable();
43 m_firstEvent = false;
44 }
45
46 auto blocks = createBlocks();
47 m_tocRecord.addRecord("event_record", sio_utils::writeRecord(blocks, "event_record", m_stream));
48}
49
50sio::block_list SIOWriter::createBlocks() const {
51 sio::block_list blocks;
52 blocks.emplace_back(m_eventMetaData);
53
54 for (const auto& name : m_collectionsToWrite) {
55 const podio::CollectionBase* col{nullptr};
56 m_store->get(name, col);
57 col->prepareForWrite();
58
59 blocks.emplace_back(podio::SIOBlockFactory::instance().createBlock(col, name));
60 }
61
62 return blocks;
63}
64
66 sio::block_list blocks{};
67 blocks.push_back(m_runMetaData);
68
69 m_tocRecord.addRecord(m_runMetaData->name(), sio_utils::writeRecord(blocks, m_runMetaData->name(), m_stream));
70
71 blocks.clear();
72 blocks.push_back(m_collectionMetaData);
73 m_tocRecord.addRecord(m_collectionMetaData->name(),
74 sio_utils::writeRecord(blocks, m_collectionMetaData->name(), m_stream));
75
76 blocks.clear();
77 auto tocRecordBlock = std::make_shared<SIOFileTOCRecordBlock>();
78 tocRecordBlock->record = &m_tocRecord;
79 blocks.push_back(tocRecordBlock);
80
81 const auto tocStartPos = sio_utils::writeRecord(blocks, sio_helpers::SIOTocRecordName, m_stream);
82 // Now that we know the position of the TOC Record, put this information
83 // into a final marker that can be identified and interpreted when reading
84 // again
85 uint64_t finalWords = (((uint64_t)sio_helpers::SIOTocMarker) << 32) | ((uint64_t)tocStartPos & 0xffffffff);
86 m_stream.write(reinterpret_cast<char*>(&finalWords), sizeof(finalWords));
87
88 m_stream.close();
89}
90
91void SIOWriter::registerForWrite(const std::string& name) {
92
93 const podio::CollectionBase* colB(nullptr);
94 m_store->get(name, colB);
95
96 if (!colB) {
97 throw std::runtime_error(std::string("no such collection to write: ") + name);
98 }
99 // Check if we can instantiate the blocks here so that we can skip the checks later
100 if (auto blk = podio::SIOBlockFactory::instance().createBlock(colB, name); !blk) {
101 const auto typName = colB->getValueTypeName();
102 throw std::runtime_error(std::string("could not create SIOBlock for type: ") + typName);
103 }
104
105 m_collectionsToWrite.push_back(name);
106}
107
108void SIOWriter::writeCollectionIDTable() {
109 sio::block_list blocks;
110 blocks.emplace_back(std::make_shared<SIOCollectionIDTableBlock>(m_store));
111 blocks.emplace_back(std::make_shared<SIOVersionBlock>(podio::version::build_version));
112
113 m_tocRecord.addRecord("file_metadata", sio_utils::writeRecord(blocks, "file_metadata", m_stream));
114}
115
116} // namespace podio
virtual std::string getValueTypeName() const =0
fully qualified type name of elements - with namespace
bool get(const std::string &name, const T *&collection)
access a collection by name. returns true if successful
Definition: EventStore.h:143
ColMDMap * getColMetaDataMap()
Definition: EventStore.h:104
GenericParameters * eventMetaDataPtr()
Definition: EventStore.h:107
RunMDMap * getRunMetaDataMap()
Definition: EventStore.h:101
static SIOBlockFactory & instance()
Definition: SIOBlock.h:236
static SIOBlockLibraryLoader & instance()
Definition: SIOBlock.h:263
void addRecord(const std::string &name, PositionType startPos)
Definition: SIOBlock.cc:184
SIOWriter(const std::string &filename, EventStore *store)
Definition: SIOWriter.cc:15
void registerForWrite(const std::string &name)
Definition: SIOWriter.cc:91
void writeEvent()
Definition: SIOWriter.cc:37
sio::ifstream::pos_type writeRecord(const sio::block_list &blocks, const std::string &recordName, sio::ofstream &stream, std::size_t initBufferSize=sio::mbyte, bool compress=true)
Write the passed record and return where it starts in the file.
Definition: sioUtils.h:82