PODIO v00-16-03
An Event-Data-Model Toolkit for High Energy Physics Experiments
Loading...
Searching...
No Matches
relation_range.cpp File Reference
#include "datamodel/ExampleMCCollection.h"
#include "datamodel/MutableExampleReferencingType.h"
#include "datamodel/MutableExampleWithVectorMember.h"
#include "podio/EventStore.h"
#include "podio/ROOTReader.h"
#include "podio/ROOTWriter.h"
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

Go to the source code of this file.

Macros

#define LOCATION()
 
#define ASSERT_CONDITION(condition, message)
 
#define ASSERT_EQUAL(left, right, message)
 

Functions

void fillExampleMCCollection (ExampleMCCollection &collection)
 
void doTestExampleMC (ExampleMCCollection const &collection)
 
void testExampleMC ()
 
void testExampleWithVectorMember ()
 
void testExampleReferencingType ()
 
void testWithIO ()
 
int main (int, char **)
 

Macro Definition Documentation

◆ ASSERT_CONDITION

#define ASSERT_CONDITION (   condition,
  message 
)
Value:
{ \
if (!(condition)) { \
throw std::runtime_error(LOCATION() + std::string(": ") + message); \
} \
}
#define LOCATION()

Definition at line 18 of file relation_range.cpp.

◆ ASSERT_EQUAL

#define ASSERT_EQUAL (   left,
  right,
  message 
)
Value:
{ \
std::stringstream msg; \
msg << message << " | expected: " << right << " - actual: " << left; \
ASSERT_CONDITION(left == right, msg.str()) \
}

Definition at line 25 of file relation_range.cpp.

◆ LOCATION

#define LOCATION ( )
Value:
std::string(__FILE__) + std::string(":") + std::to_string(__LINE__) + std::string(" in ") + \
std::string(__PRETTY_FUNCTION__)

Definition at line 14 of file relation_range.cpp.

Function Documentation

◆ doTestExampleMC()

void doTestExampleMC ( ExampleMCCollection const &  collection)

Definition at line 60 of file relation_range.cpp.

60 {
61 // Empty
62 ASSERT_CONDITION(collection[7].daughters().empty() && collection[7].parents().empty(),
63 "RelationRange of empty collection is not empty");
64 // Equivalent but potentially quicker way of checking an empty collection
65 ASSERT_CONDITION(collection[7].daughters().empty() && collection[7].parents().empty(),
66 "RelationRange of empty collection is not empty");
67
68 // alternatively check if a loop is entered
69 for (const auto& p [[maybe_unused]] : collection[7].daughters()) {
70 throw std::runtime_error("Range based for loop entered on a supposedly empty range");
71 }
72
73 ASSERT_EQUAL(collection[0].daughters().size(), 3, "Range has wrong size");
74 // check daughter relations are OK
75 std::vector<int> expectedPDG = {1, 5, 4};
76 int index = 0;
77 for (const auto& p : collection[0].daughters()) {
78 ASSERT_EQUAL(p.PDG(), expectedPDG[index], "ExampleMC daughters range points to wrong particle (by PDG)");
79 index++;
80 }
81
82 // Check indexed access
83 const auto daughters = collection[0].daughters();
84 for (size_t i = 0; i < expectedPDG.size(); ++i) {
85 const auto daughter = daughters[i];
86 ASSERT_EQUAL(daughter.PDG(), expectedPDG[i], "ExampleMC daughter points to the wrong particle (by PDG)");
87 }
88
89 // mothers and daughters
90 ASSERT_EQUAL(collection[2].daughters().size(), 2, "Range has wrong size");
91 ASSERT_EQUAL(collection[2].parents().size(), 2, "Range has wrong size");
92
93 expectedPDG = {1, 9};
94 index = 0;
95 for (const auto& p : collection[2].daughters()) {
96 ASSERT_EQUAL(p.PDG(), expectedPDG[index], "ExampleMC daughters range points to wrong particle (by PDG)");
97 index++;
98 }
99 expectedPDG = {8, 6};
100 index = 0;
101 for (const auto& p : collection[2].parents()) {
102 ASSERT_EQUAL(p.PDG(), expectedPDG[index], "ExampleMC parents range points to wrong particle (by PDG)");
103 index++;
104 }
105
106 // Indexed access with range check
107 const auto parents = collection[2].parents();
108 for (size_t i = 0; i < expectedPDG.size(); ++i) {
109 const auto parent = parents.at(i);
110 ASSERT_EQUAL(parent.PDG(), expectedPDG[i], "ExampleMC parents points to the wrong particle (by PDG)");
111 }
112
113 try {
114 const auto parent [[maybe_unused]] = parents.at(3);
115 throw std::runtime_error("Trying to access out of bounds in a RelationRange::at should throw");
116 } catch (const std::out_of_range& err) {
117 ASSERT_EQUAL(err.what(), std::string("index out of bounds for RelationRange"),
118 "Access out of bounds throws wrong exception");
119 }
120
121 // realistic case
122 auto mcp6 = collection[6];
123 ASSERT_EQUAL(mcp6.daughters().size(), 1, "Wrong number of daughters");
124 auto parent = mcp6.parents(0);
125 ASSERT_EQUAL(parent.daughters().size(), 1, "Wrong number of daughters");
126
127 for (const auto& p : mcp6.parents()) {
128 // loop will only run once as per the above assertion
129 ASSERT_EQUAL(p, parent, "parent-daughter relation is not as expected");
130 }
131 for (const auto& p : parent.daughters()) {
132 // loop will only run once as per the above assertion
133 ASSERT_EQUAL(p, mcp6, "daughter-parent relation is not as expected");
134 }
135}
#define ASSERT_CONDITION(condition, message)
#define ASSERT_EQUAL(left, right, message)

Referenced by testExampleMC(), and testWithIO().

◆ fillExampleMCCollection()

void fillExampleMCCollection ( ExampleMCCollection &  collection)

Definition at line 32 of file relation_range.cpp.

32 {
33 for (int i = 0; i < 10; ++i) {
34 MutableExampleMC mcp;
35 mcp.PDG(i);
36 collection.push_back(mcp);
37 }
38
39 // only daughters
40 auto mcp = collection[0];
41 mcp.adddaughters(collection[1]);
42 mcp.adddaughters(collection[5]);
43 mcp.adddaughters(collection[4]);
44
45 // daughters and parents
46 mcp = collection[2];
47 mcp.adddaughters(collection[1]);
48 mcp.adddaughters(collection[9]);
49 mcp.addparents(collection[8]);
50 mcp.addparents(collection[6]);
51
52 // realistic case with possibly cyclical references
53 mcp = collection[6];
54 mcp.adddaughters(collection[2]);
55 mcp.addparents(collection[3]);
56 collection[3].adddaughters(collection[6]);
57}

Referenced by testExampleMC(), and testWithIO().

◆ main()

int main ( int  ,
char **   
)

Definition at line 215 of file relation_range.cpp.

215 {
216 try {
220 testWithIO();
221 } catch (std::runtime_error const& ex) {
222 std::cerr << ex.what() << std::endl;
223 return 1;
224 }
225
226 return 0;
227}
void testWithIO()
void testExampleReferencingType()
void testExampleMC()
void testExampleWithVectorMember()

◆ testExampleMC()

void testExampleMC ( )

Definition at line 137 of file relation_range.cpp.

137 {
138 ExampleMCCollection mcps;
140 doTestExampleMC(mcps);
141}
void doTestExampleMC(ExampleMCCollection const &collection)
void fillExampleMCCollection(ExampleMCCollection &collection)

Referenced by main().

◆ testExampleReferencingType()

void testExampleReferencingType ( )

Definition at line 159 of file relation_range.cpp.

159 {
160 MutableExampleReferencingType ex;
161 ExampleReferencingType ex1;
162 ExampleReferencingType ex2;
163
164 ex.addRefs(ex1);
165 ex.addRefs(ex2);
166
167 ASSERT_EQUAL(ex.Refs().size(), 2, "Wrong number of references");
168
169 int index = 0;
170 for (const auto& e : ex.Refs()) {
171 if (index == 0) {
172 ASSERT_EQUAL(e, ex1, "First element of range is not as expected");
173 } else {
174 ASSERT_EQUAL(e, ex2, "Second element of range is not as expected");
175 }
176
177 index++;
178 }
179
180 ASSERT_CONDITION(!ex.Refs().empty(), "Relation range of element with relations should not be empty");
181 ASSERT_CONDITION(ex1.Refs().empty(), "Relation range of element with no relations should be empty");
182}

Referenced by main().

◆ testExampleWithVectorMember()

void testExampleWithVectorMember ( )

Definition at line 143 of file relation_range.cpp.

143 {
144 MutableExampleWithVectorMember ex;
145 ex.addcount(1);
146 ex.addcount(2);
147 ex.addcount(10);
148
149 ASSERT_EQUAL(ex.count().size(), 3, "vector member range has wrong size");
150
151 std::vector<int> expected = {1, 2, 10};
152 int index = 0;
153 for (const int c : ex.count()) {
154 ASSERT_EQUAL(c, expected[index], "wrong content in range-based for loop");
155 index++;
156 }
157}

Referenced by main().

◆ testWithIO()

void testWithIO ( )

Definition at line 184 of file relation_range.cpp.

184 {
185 podio::EventStore store;
186 podio::ROOTWriter writer("relation_range_io_test.root", &store);
187
188 auto& collection = store.create<ExampleMCCollection>("mcparticles");
189 writer.registerForWrite("mcparticles");
190
191 for (int i = 0; i < 10; ++i) {
192 fillExampleMCCollection(collection);
193 doTestExampleMC(collection);
194 writer.writeEvent();
195 store.clearCollections();
196 }
197 writer.finish();
198
199 podio::EventStore readStore;
200 podio::ROOTReader reader;
201 reader.openFile("relation_range_io_test.root");
202 readStore.setReader(&reader);
203
204 for (int i = 0; i < 10; ++i) {
205 auto& readColl = readStore.get<ExampleMCCollection>("mcparticles");
206 ASSERT_CONDITION(readColl.isValid(), "Collection 'mcparticles' should be present");
207 ASSERT_EQUAL(readColl.size(), 10, "'mcparticles' should have 10 entries");
208
209 doTestExampleMC(readColl);
210 readStore.clear();
211 reader.endOfEvent();
212 }
213}
bool get(const std::string &name, const T *&collection)
access a collection by name. returns true if successful
Definition: EventStore.h:143
void clear()
clears itself; deletes collections (use at end of event processing)
Definition: EventStore.cc:126
void clearCollections()
empties collections.
Definition: EventStore.cc:119
T & create(const std::string &name)
create a new collection
Definition: EventStore.h:133
void setReader(IReader *reader)
set the reader
Definition: EventStore.cc:149
void openFile(const std::string &filename) override
Definition: ROOTReader.cc:140
void endOfEvent() override
Preparing to read next event.
Definition: ROOTReader.cc:212

Referenced by main().