PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
SIOBlock.cc
Go to the documentation of this file.
1#include "podio/SIOBlock.h"
2
3#include <algorithm>
4#include <cstdlib>
5#include <dlfcn.h>
6#include <map>
7#include <sstream>
8#ifdef USE_BOOST_FILESYSTEM
9 #include <boost/filesystem.hpp>
10#else
11 #include <filesystem>
12#endif
13
14namespace podio {
16 sio::block("CollectionIDs", sio::version::encode_version(0, 3)) {
17 const auto table = store->getCollectionIDTable();
18 _names = table->names();
19 _ids = table->ids();
20 _types.reserve(_names.size());
21 _isSubsetColl.reserve(_names.size());
22 for (const int id : _ids) {
23 CollectionBase* tmp;
24 if (!store->get(id, tmp)) {
25 std::cerr
26 << "PODIO-ERROR cannot construct CollectionIDTableBlock because a collection is missing from the store (id: "
27 << id << ", name: " << table->name(id) << ")" << std::endl;
28 }
29
30 _types.push_back(tmp->getValueTypeName());
31 _isSubsetColl.push_back(tmp->isSubsetCollection());
32 }
33}
34
35void SIOCollectionIDTableBlock::read(sio::read_device& device, sio::version_type version) {
36 device.data(_names);
37 device.data(_ids);
38 device.data(_types);
39 if (version >= sio::version::encode_version(0, 2)) {
40 device.data(_isSubsetColl);
41 }
42}
43
44void SIOCollectionIDTableBlock::write(sio::write_device& device) {
45 device.data(_names);
46 device.data(_ids);
47
48 device.data(_types);
49 device.data(_isSubsetColl);
50}
51
52void writeGenericParameters(sio::write_device& device, const GenericParameters& params) {
53 writeMapLike(device, params.getIntMap());
54 writeMapLike(device, params.getFloatMap());
55 writeMapLike(device, params.getStringMap());
56 writeMapLike(device, params.getDoubleMap());
57}
58
59void readGenericParameters(sio::read_device& device, GenericParameters& params, sio::version_type version) {
60 readMapLike(device, params.getIntMap());
61 readMapLike(device, params.getFloatMap());
62 readMapLike(device, params.getStringMap());
63 if (version >= sio::version::encode_version(0, 2)) {
64 readMapLike(device, params.getDoubleMap());
65 }
66}
67
68void SIOEventMetaDataBlock::read(sio::read_device& device, sio::version_type version) {
69 readGenericParameters(device, *metadata, version);
70}
71
72void SIOEventMetaDataBlock::write(sio::write_device& device) {
74}
75
76void SIONumberedMetaDataBlock::read(sio::read_device& device, sio::version_type version) {
77 int size;
78 device.data(size);
79 while (size--) {
80 int id;
81 device.data(id);
82 GenericParameters params;
83 readGenericParameters(device, params, version);
84
85 data->emplace(id, std::move(params));
86 }
87}
88
89void SIONumberedMetaDataBlock::write(sio::write_device& device) {
90 device.data((int)data->size());
91 for (const auto& [id, params] : *data) {
92 device.data(id);
93 writeGenericParameters(device, params);
94 }
95}
96
97std::shared_ptr<SIOBlock> SIOBlockFactory::createBlock(const std::string& typeStr, const std::string& name,
98 const bool isSubsetColl) const {
99 const auto it = _map.find(typeStr);
100
101 if (it != _map.end()) {
102 auto blk = std::shared_ptr<SIOBlock>(it->second->create(name));
103 blk->createBuffers(isSubsetColl);
104 return blk;
105 } else {
106 return nullptr;
107 }
108}
109
110std::shared_ptr<SIOBlock> SIOBlockFactory::createBlock(const podio::CollectionBase* col,
111 const std::string& name) const {
112 const std::string typeStr = col->getValueTypeName();
113 const auto it = _map.find(typeStr);
114
115 if (it != _map.end()) {
116 auto blk = std::shared_ptr<SIOBlock>(it->second->create(name));
117 blk->setCollection(const_cast<podio::CollectionBase*>(col));
118 return blk;
119 } else {
120 return nullptr;
121 }
122}
123
124SIOBlockLibraryLoader::SIOBlockLibraryLoader() {
125 for (const auto& [lib, dir] : getLibNames()) {
126 const auto status = loadLib(lib);
127 switch (status) {
128 case LoadStatus::Success:
129 std::cerr << "Loaded SIOBlocks library \'" << lib << "\' (from " << dir << ")" << std::endl;
130 break;
131 case LoadStatus::AlreadyLoaded:
132 std::cerr << "SIOBlocks library \'" << lib << "\' already loaded. Not loading again from " << dir << std::endl;
133 break;
134 case LoadStatus::Error:
135 std::cerr << "ERROR while loading SIOBlocks library \'" << lib << "\' (from " << dir << ")" << std::endl;
136 break;
137 }
138 }
139}
140
141SIOBlockLibraryLoader::LoadStatus SIOBlockLibraryLoader::loadLib(const std::string& libname) {
142 if (_loadedLibs.find(libname) != _loadedLibs.end()) {
143 return LoadStatus::AlreadyLoaded;
144 }
145 void* libhandle = dlopen(libname.c_str(), RTLD_LAZY | RTLD_GLOBAL);
146 if (libhandle) {
147 _loadedLibs.insert({libname, libhandle});
148 return LoadStatus::Success;
149 }
150
151 return LoadStatus::Error;
152}
153
154std::vector<std::tuple<std::string, std::string>> SIOBlockLibraryLoader::getLibNames() {
155#ifdef USE_BOOST_FILESYSTEM
156 namespace fs = boost::filesystem;
157#else
158 namespace fs = std::filesystem;
159#endif
160 std::vector<std::tuple<std::string, std::string>> libs;
161
162 std::string dir;
163 const auto ldLibPath = std::getenv("LD_LIBRARY_PATH");
164 if (!ldLibPath) {
165 return libs;
166 }
167 std::istringstream stream(ldLibPath);
168 while (std::getline(stream, dir, ':')) {
169 if (not fs::exists(dir)) {
170 continue;
171 }
172
173 for (auto& lib : fs::directory_iterator(dir)) {
174 const auto filename = lib.path().filename().string();
175 if (filename.find("SioBlocks") != std::string::npos) {
176 libs.emplace_back(std::move(filename), dir);
177 }
178 }
179 }
180
181 return libs;
182}
183
184void SIOFileTOCRecord::addRecord(const std::string& name, PositionType startPos) {
185 auto it =
186 std::find_if(m_recordMap.begin(), m_recordMap.end(), [&name](const auto& entry) { return entry.first == name; });
187
188 if (it == m_recordMap.end()) {
189 m_recordMap.push_back({name, {startPos}});
190 } else {
191 it->second.push_back(startPos);
192 }
193}
194
195size_t SIOFileTOCRecord::getNRecords(const std::string& name) const {
196 const auto it = std::find_if(m_recordMap.cbegin(), m_recordMap.cend(),
197 [&name](const auto& entry) { return entry.first == name; });
198 if (it != m_recordMap.cend()) {
199 return it->second.size();
200 }
201 return 0;
202}
203
204SIOFileTOCRecord::PositionType SIOFileTOCRecord::getPosition(const std::string& name, unsigned iEntry) const {
205 const auto it = std::find_if(m_recordMap.cbegin(), m_recordMap.cend(),
206 [&name](const auto& keyVal) { return keyVal.first == name; });
207 if (it != m_recordMap.end()) {
208 if (iEntry < it->second.size()) {
209 return it->second[iEntry];
210 }
211 }
212
213 return 0;
214}
215
216std::vector<std::string_view> SIOFileTOCRecord::getRecordNames() const {
217 std::vector<std::string_view> cats;
218 cats.reserve(m_recordMap.size());
219 for (const auto& [cat, _] : m_recordMap) {
220 cats.emplace_back(cat);
221 }
222
223 return cats;
224}
225
226void SIOFileTOCRecordBlock::read(sio::read_device& device, sio::version_type) {
227 int size;
228 device.data(size);
229 while (size--) {
230 std::string name;
231 device.data(name);
232 std::vector<SIOFileTOCRecord::PositionType> positions;
233 device.data(positions);
234
235 record->m_recordMap.emplace_back(std::move(name), std::move(positions));
236 }
237}
238
239void SIOFileTOCRecordBlock::write(sio::write_device& device) {
240 device.data((int)record->m_recordMap.size());
241 for (const auto& [name, positions] : record->m_recordMap) {
242 device.data(name);
243 device.data(positions);
244 }
245}
246
247} // namespace podio
virtual std::string getValueTypeName() const =0
fully qualified type name of elements - with namespace
virtual bool isSubsetCollection() const =0
check if this collection is a subset collection
bool get(const std::string &name, const T *&collection)
access a collection by name. returns true if successful
Definition: EventStore.h:143
CollectionIDTable * getCollectionIDTable() const
Definition: EventStore.h:86
const StringMap & getStringMap() const
const IntMap & getIntMap() const
const FloatMap & getFloatMap() const
const DoubleMap & getDoubleMap() const
std::shared_ptr< SIOBlock > createBlock(const podio::CollectionBase *col, const std::string &name) const
Definition: SIOBlock.cc:110
void write(sio::write_device &device) override
Definition: SIOBlock.cc:44
void read(sio::read_device &device, sio::version_type version) override
Definition: SIOBlock.cc:35
void write(sio::write_device &device) override
Definition: SIOBlock.cc:72
void read(sio::read_device &device, sio::version_type version) override
Definition: SIOBlock.cc:68
podio::GenericParameters * metadata
Definition: SIOBlock.h:171
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
sio_helpers::position_type PositionType
Definition: SIOBlock.h:287
std::vector< std::string_view > getRecordNames() const
Definition: SIOBlock.cc:216
void addRecord(const std::string &name, PositionType startPos)
Definition: SIOBlock.cc:184
std::map< int, GenericParameters > * data
Definition: SIOBlock.h:214
void write(sio::write_device &device) override
Definition: SIOBlock.cc:89
void read(sio::read_device &device, sio::version_type version) override
Definition: SIOBlock.cc:76
void readGenericParameters(sio::read_device &device, GenericParameters &params, sio::version_type version)
Definition: SIOBlock.cc:59
void readMapLike(sio::read_device &device, MapLikeT &map)
Read anything that iterates like an std::map.
Definition: SIOBlock.h:43
void writeGenericParameters(sio::write_device &device, const GenericParameters &params)
Definition: SIOBlock.cc:52
void writeMapLike(sio::write_device &device, const MapLikeT &map)
Write anything that iterates like an std::map.
Definition: SIOBlock.h:33
void read(sio::read_device &device, sio::version_type version) override
Definition: SIOBlock.cc:226
void write(sio::write_device &device) override
Definition: SIOBlock.cc:239
SIOFileTOCRecord * record
Definition: SIOBlock.h:326