1#ifndef PODIO_TESTS_READ_TEST_H
2#define PODIO_TESTS_READ_TEST_H
4#include "datamodel/ExampleClusterCollection.h"
5#include "datamodel/ExampleHitCollection.h"
6#include "datamodel/ExampleMCCollection.h"
7#include "datamodel/ExampleReferencingTypeCollection.h"
8#include "datamodel/ExampleWithARelationCollection.h"
9#include "datamodel/ExampleWithArrayCollection.h"
10#include "datamodel/ExampleWithComponentCollection.h"
11#include "datamodel/ExampleWithFixedWidthIntegersCollection.h"
12#include "datamodel/ExampleWithNamespace.h"
13#include "datamodel/ExampleWithOneRelationCollection.h"
14#include "datamodel/ExampleWithVectorMemberCollection.h"
20#include "podio/podioVersion.h"
32template <
typename FixedW
idthT>
34 if (actual != expected) {
35 std::stringstream msg{};
36 msg <<
"fixed width integer (" << type <<
") value is not as expected: " << actual <<
" vs " << expected;
37 throw std::runtime_error(msg.str());
42template <
typename StoreT>
43static constexpr bool isEventStore = std::is_same_v<podio::EventStore, StoreT>;
45template <
typename StoreT = podio::EventStore>
49 if constexpr (isEventStore<StoreT>) {
50 const auto& evtMD = store.getEventMetaData();
51 evtWeight = evtMD.template getValue<float>(
"UserEventWeight");
53 evtWeight = store.template getParameter<float>(
"UserEventWeight");
55 if (evtWeight != (
float)100. * eventNum) {
56 std::cout <<
" read UserEventWeight: " << evtWeight <<
" - expected : " << (float)100. * eventNum << std::endl;
57 throw std::runtime_error(
"Couldn't read event meta data parameters 'UserEventWeight'");
61 ss <<
" event_number_" << eventNum;
62 std::string evtName =
"";
63 if constexpr (isEventStore<StoreT>) {
64 const auto& evtMD = store.getEventMetaData();
65 evtName = evtMD.template getValue<std::string>(
"UserEventName");
67 evtName = store.template getParameter<std::string>(
"UserEventName");
70 if (evtName != ss.str()) {
71 std::cout <<
" read UserEventName: " << evtName <<
" - expected : " << ss.str() << std::endl;
72 throw std::runtime_error(
"Couldn't read event meta data parameters 'UserEventName'");
76 std::vector<int> someVectorData{};
77 if constexpr (isEventStore<StoreT>) {
78 const auto& evtMD = store.getEventMetaData();
79 someVectorData = evtMD.template getValue<std::vector<int>>(
"SomeVectorData");
81 someVectorData = store.template getParameter<std::vector<int>>(
"SomeVectorData");
83 if (someVectorData.size() != 4) {
84 throw std::runtime_error(
"Couldn't read event meta data parameters: 'SomeVectorData'");
86 for (
int i = 0; i < 4; ++i) {
87 if (someVectorData[i] != i + 1) {
88 throw std::runtime_error(
"Couldn't read event meta data parameters: 'SomeVectorData'");
93 if constexpr (!isEventStore<StoreT>) {
95 const auto doubleParams = store.template getParameter<std::vector<double>>(
"SomeVectorData");
96 if (doubleParams.size() != 2 || doubleParams[0] != eventNum * 1.1 || doubleParams[1] != eventNum * 2.2) {
97 throw std::runtime_error(
"Could not read event parameter: 'SomeDoubleValues' correctly");
105 store.template get<ExampleClusterCollection>(
"notthere");
106 }
catch (
const std::runtime_error& err) {
107 if (std::string(err.what()) !=
"No collection \'notthere\' is present in the EventStore") {
108 throw std::runtime_error(
"Trying to get non present collection \'notthere' should throw an exception");
113 auto& hits = store.template get<ExampleHitCollection>(
"hits");
114 if constexpr (isEventStore<StoreT>) {
115 const auto& colMD = store.getCollectionMetaData(hits.getID());
116 const auto& es = colMD.template getValue<std::string>(
"CellIDEncodingString");
117 if (es != std::string(
"system:8,barrel:3,layer:6,slice:5,x:-16,y:-16")) {
118 std::cout <<
" meta data from collection 'hits' with id = " << hits.getID()
119 <<
" read CellIDEncodingString: " << es <<
" - expected : system:8,barrel:3,layer:6,slice:5,x:-16,y:-16"
121 throw std::runtime_error(
"Couldn't read event meta data parameters 'CellIDEncodingString'");
129 auto& hitRefs = store.template get<ExampleHitCollection>(
"hitRefs");
130 if (hitRefs.size() != hits.size()) {
131 throw std::runtime_error(
"hit and subset hit collection do not have the same size");
133 if (!(hits[1] == hitRefs[0] && hits[0] == hitRefs[1])) {
134 throw std::runtime_error(
"hit subset collections do not have the expected contents");
138 auto& clusters = store.template get<ExampleClusterCollection>(
"clusters");
139 if (clusters.isValid()) {
140 auto cluster = clusters[0];
141 for (
auto i = cluster.Hits_begin(), end = cluster.Hits_end(); i != end; ++i) {
142 std::cout <<
" Referenced hit has an energy of " << i->energy() << std::endl;
145 throw std::runtime_error(
"Collection 'clusters' should be present");
152 auto& mcpRefs = store.template get<ExampleMCCollection>(
"mcParticleRefs");
153 if (!mcpRefs.isValid()) {
154 throw std::runtime_error(
"Collection 'mcParticleRefs' should be present");
159 for (
auto ref : mcpRefs) {
160 const auto daughters = ref.daughters();
161 if (!daughters.empty()) {
163 auto d [[maybe_unused]] = daughters[0];
166 const auto parents = ref.parents();
167 if (!parents.empty()) {
169 auto d [[maybe_unused]] = parents[0];
174 auto& mcps = store.template get<ExampleMCCollection>(
"mcparticles");
175 if (!mcps.isValid()) {
176 throw std::runtime_error(
"Collection 'mcparticles' should be present");
182 for (
auto p : mcps) {
183 std::cout <<
" particle " << p.getObjectID().index <<
" has daughters: ";
184 for (
auto it = p.daughters_begin(), end = p.daughters_end(); it != end; ++it) {
185 std::cout <<
" " << it->getObjectID().index;
187 std::cout <<
" and parents: ";
188 for (
auto it = p.parents_begin(), end = p.parents_end(); it != end; ++it) {
189 std::cout <<
" " << it->getObjectID().index;
191 std::cout << std::endl;
197 auto d0 = p.daughters(0);
198 auto d1 = p.daughters(1);
199 auto d2 = p.daughters(2);
200 auto d3 = p.daughters(3);
202 if (!(d0 == mcps[2])) {
203 throw std::runtime_error(
" error: 1. daughter of particle 0 is not particle 2 ");
205 if (!(d1 == mcps[3])) {
206 throw std::runtime_error(
" error: 2. daughter of particle 0 is not particle 3 ");
208 if (!(d2 == mcps[4])) {
209 throw std::runtime_error(
" error: 3. daughter of particle 0 is not particle 4 ");
211 if (!(d3 == mcps[5])) {
212 throw std::runtime_error(
" error: 4. daughter of particle 0 is not particle 5 ");
223 if (!(d0 == mcps[6])) {
224 throw std::runtime_error(
" error: 1. daughter of particle 3 is not particle 6 ");
226 if (!(d1 == mcps[7])) {
227 throw std::runtime_error(
" error: 2. daughter of particle 3 is not particle 7 ");
229 if (!(d2 == mcps[8])) {
230 throw std::runtime_error(
" error: 3. daughter of particle 3 is not particle 8 ");
232 if (!(d3 == mcps[9])) {
233 throw std::runtime_error(
" error: 4. daughter of particle 3 is not particle 9 ");
242 auto& mcpRefs = store.template get<ExampleMCCollection>(
"mcParticleRefs");
243 if (!mcpRefs.isValid()) {
244 throw std::runtime_error(
"Collection 'mcParticleRefs' should be present");
247 for (
auto pr : mcpRefs) {
248 if ((
unsigned)pr.getObjectID().collectionID == mcpRefs.getID()) {
249 throw std::runtime_error(
250 "objects of a reference collection should have a different collectionID than the reference collection");
254 auto& moreMCs = store.template get<ExampleMCCollection>(
"moreMCs");
257 if (mcps.size() != moreMCs.size()) {
258 throw std::runtime_error(
"'mcparticles' and 'moreMCs' should have the same size");
261 for (
size_t index = 0; index < mcps.size(); ++index) {
263 if (mcps[index].energy() != moreMCs[index].energy() ||
264 mcps[index].daughters().size() != moreMCs[index].daughters().size()) {
265 throw std::runtime_error(
"'mcparticles' and 'moreMCs' do not contain the same elements");
269 if (mcpRefs.size() != mcps.size()) {
270 throw std::runtime_error(
"'mcParticleRefs' collection has wrong size");
272 for (
size_t i = 0; i < mcpRefs.size(); ++i) {
274 if (!(mcpRefs[i] == mcps[2 * i + 1])) {
275 throw std::runtime_error(
"MCParticle reference does not point to the correct MCParticle");
278 const int index = (i - 5) * 2;
279 if (!(mcpRefs[i] == moreMCs[index])) {
280 throw std::runtime_error(
"MCParticle reference does not point to the correct MCParticle");
287 auto& refs = store.template get<ExampleReferencingTypeCollection>(
"refs");
288 if (refs.isValid()) {
290 for (
auto cluster : ref.Clusters()) {
291 for (
auto hit [[maybe_unused]] : cluster.Hits()) {
296 throw std::runtime_error(
"Collection 'refs' should be present");
299 auto& rels = store.template get<ExampleWithOneRelationCollection>(
"OneRelation");
300 if (rels.isValid()) {
303 throw std::runtime_error(
"Collection 'OneRelation' should be present");
307 auto& vecs = store.template get<ExampleWithVectorMemberCollection>(
"WithVectorMember");
308 if (vecs.isValid()) {
309 if (vecs.size() != 2) {
310 throw std::runtime_error(
"Collection 'WithVectorMember' should have two elements'");
313 for (
auto vec : vecs) {
314 if (vec.count().size() != 2) {
315 throw std::runtime_error(
316 "Element of 'WithVectorMember' collection should have two elements in its 'count' vector");
319 if (vecs[0].count(0) != eventNum || vecs[0].count(1) != eventNum + 10 || vecs[1].count(0) != eventNum + 1 ||
320 vecs[1].count(1) != eventNum + 11) {
321 throw std::runtime_error(
"Element values of the 'count' vector in an element of the 'WithVectorMember' "
322 "collection do not have the expected values");
325 for (
auto item : vecs) {
326 for (
auto c = item.count_begin(), end = item.count_end(); c != end; ++c) {
327 std::cout <<
" Counter value " << (*c) << std::endl;
331 throw std::runtime_error(
"Collection 'WithVectorMember' should be present");
334 auto& comps = store.template get<ExampleWithComponentCollection>(
"Component");
335 if (comps.isValid()) {
336 auto comp = comps[0];
337 int a [[maybe_unused]] = comp.component().data.x + comp.component().data.z;
340 auto& arrays = store.template get<ExampleWithArrayCollection>(
"arrays");
341 if (arrays.isValid() && arrays.size() != 0) {
342 auto array = arrays[0];
343 if (array.myArray(1) != eventNum) {
344 throw std::runtime_error(
"Array not properly set.");
346 if (array.arrayStruct().data.p.at(2) != 2 * eventNum) {
347 throw std::runtime_error(
"Array not properly set.");
349 if (array.structArray(0).x != eventNum) {
350 throw std::runtime_error(
"Array of struct not properly set.");
353 throw std::runtime_error(
"Collection 'arrays' should be present");
356 auto& nmspaces = store.template get<ex42::ExampleWithARelationCollection>(
"WithNamespaceRelation");
357 auto& copies = store.template get<ex42::ExampleWithARelationCollection>(
"WithNamespaceRelationCopy");
359 auto cpytest = ex42::ExampleWithARelationCollection{};
360 if (nmspaces.isValid() && copies.isValid()) {
361 for (
size_t j = 0; j < nmspaces.size(); j++) {
362 auto nmsp = nmspaces[j];
363 auto cpy = copies[j];
364 cpytest.push_back(nmsp.clone());
365 if (nmsp.ref().isAvailable()) {
366 if (nmsp.ref().component().x != cpy.ref().component().x ||
367 nmsp.ref().component().y != cpy.ref().component().y) {
368 throw std::runtime_error(
"Copied item has differing component in OneToOne referenced item.");
371 if (nmsp.ref().x() != cpy.ref().x()) {
372 throw std::runtime_error(
"Getting wrong values when using direct accessors for sub members.");
374 if (nmsp.number() != cpy.number()) {
375 throw std::runtime_error(
"Copied item has differing member.");
377 if (!(nmsp.ref().getObjectID() == cpy.ref().getObjectID())) {
378 throw std::runtime_error(
"Copied item has wrong OneToOne references.");
381 auto cpy_it = cpy.refs_begin();
382 for (
auto it = nmsp.refs_begin(); it != nmsp.refs_end(); ++it, ++cpy_it) {
383 if (it->component().x != cpy_it->component().x || it->component().y != cpy_it->component().y) {
384 throw std::runtime_error(
"Copied item has differing component in OneToMany referenced item.");
386 if (!(it->getObjectID() == cpy_it->getObjectID())) {
387 throw std::runtime_error(
"Copied item has wrong OneToMany references.");
392 throw std::runtime_error(
"Collection 'WithNamespaceRelation' and 'WithNamespaceRelationCopy' should be present");
396 const auto& fixedWidthInts = store.template get<ExampleWithFixedWidthIntegersCollection>(
"fixedWidthInts");
397 if (not fixedWidthInts.isValid() or fixedWidthInts.size() != 3) {
398 throw std::runtime_error(
"Collection \'fixedWidthInts\' should be present and have 3 elements");
401 auto maxValues = fixedWidthInts[0];
402 const auto& maxComps = maxValues.fixedWidthStruct();
410 auto minValues = fixedWidthInts[1];
411 const auto& minComps = minValues.fixedWidthStruct();
419 auto arbValues = fixedWidthInts[2];
420 const auto& arbComps = arbValues.fixedWidthStruct();
430 auto& usrInts = store.template get<podio::UserDataCollection<uint64_t>>(
"userInts");
432 if (usrInts.size() != (unsigned)eventNum + 1) {
433 throw std::runtime_error(
"Could not read all userInts properly (expected: " + std::to_string(eventNum + 1) +
434 ", actual: " + std::to_string(usrInts.size()) +
")");
437 auto& uivec = usrInts.vec();
439 for (
int iu : uivec) {
441 throw std::runtime_error(
"Couldn't read userInts properly");
446 for (
int iu : usrInts) {
448 throw std::runtime_error(
"Couldn't read userInts properly");
452 auto& usrDbl = store.template get<podio::UserDataCollection<double>>(
"userDoubles");
453 if (usrDbl.size() != 100) {
454 throw std::runtime_error(
455 "Could not read all userDoubles properly (expected: 100, actual: " + std::to_string(usrDbl.size()) +
")");
458 for (
double d : usrDbl) {
460 throw std::runtime_error(
"Couldn't read userDoubles properly");
468 store.setReader(&reader);
477 const auto correctIndex = [nEvents](
unsigned index) {
478 if (nEvents > 2000) {
479 return index % (nEvents / 2);
484 for (
unsigned i = 0; i < nEvents; ++i) {
487 std::cout <<
"reading event " << i << std::endl;
499 store.setReader(&reader);
virtual podio::version::Version currentFileVersion() const =0
Get the podio version with which the current file has been written.
virtual void endOfEvent()=0
Prepare the reader to read the next event.
virtual void goToEvent(unsigned iEvent)=0
virtual unsigned getEntries() const =0
get the number of events available from this reader
bool check_fixed_width_value(FixedWidthT actual, FixedWidthT expected, const std::string &type)
void run_read_test(podio::IReader &reader)
void run_read_test_event(podio::IReader &reader, unsigned event)
void processEvent(StoreT &store, int eventNum, podio::version::Version fileVersion)