Skip to content

Commit

Permalink
Fix handling of file switching for event meta data and unify tests (#133
Browse files Browse the repository at this point in the history
)

Make write / read tests reuse the same function

Significantly reduces code dupliation by having the write and
processEvent functions defined only once and re-used throughout all the
read and write tests.

Also increases test coverage in some places (e.g. MetaData have only
been partially covered until now) and reduces future maintenance costs.
  • Loading branch information
tmadlener authored Oct 6, 2020
1 parent 9c7fb4d commit 3b890f2
Show file tree
Hide file tree
Showing 7 changed files with 514 additions and 694 deletions.
3 changes: 3 additions & 0 deletions include/podio/ROOTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <string>
#include <vector>
#include <iostream>
#include <utility>

// forward declarations
class TClass;
Expand Down Expand Up @@ -76,6 +77,8 @@ class ROOTReader : public IReader {
std::map<int,GenericParameters>* readRunMetaData() override final ;

private:
std::pair<TTree*, unsigned> getLocalTreeAndEntry(const std::string& treename);

typedef std::pair<CollectionBase*, std::string> Input;
std::vector<Input> m_inputs;
std::map<std::string, std::pair<TClass*,TClass*> > m_storedClasses;
Expand Down
14 changes: 10 additions & 4 deletions src/ROOTReader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,29 @@

namespace podio {

std::pair<TTree*, unsigned> ROOTReader::getLocalTreeAndEntry(const std::string& treename) {
auto localEntry = m_chain->LoadTree(m_eventNumber);
auto* tree = static_cast<TTree*>(m_chain->GetFile()->Get(treename.c_str()));
return {tree, localEntry};
}

GenericParameters* ROOTReader::readEventMetaData(){
GenericParameters* emd = new GenericParameters() ;
auto evt_metadatatree = static_cast<TTree*>(m_chain->GetFile()->Get("evt_metadata"));
auto [evt_metadatatree, entry] = getLocalTreeAndEntry("evt_metadata");
evt_metadatatree->SetBranchAddress("evtMD",&emd);
evt_metadatatree->GetEntry(m_eventNumber);
evt_metadatatree->GetEntry(entry);
return emd ;
}
std::map<int,GenericParameters>* ROOTReader::readCollectionMetaData(){
auto* emd = new std::map<int,GenericParameters> ;
auto col_metadatatree = static_cast<TTree*>(m_chain->GetFile()->Get("col_metadata"));
auto [col_metadatatree, dummy] = getLocalTreeAndEntry("col_metadata");
col_metadatatree->SetBranchAddress("colMD",&emd);
col_metadatatree->GetEntry(0);
return emd ;
}
std::map<int,GenericParameters>* ROOTReader::readRunMetaData(){
auto* emd = new std::map<int,GenericParameters> ;
auto run_metadatatree = static_cast<TTree*>(m_chain->GetFile()->Get("run_metadata"));
auto [run_metadatatree, dummy] = getLocalTreeAndEntry("run_metadata");
run_metadatatree->SetBranchAddress("runMD",&emd);
run_metadatatree->GetEntry(0);
return emd ;
Expand Down
198 changes: 1 addition & 197 deletions tests/read-multiple.cpp
Original file line number Diff line number Diff line change
@@ -1,202 +1,6 @@
// STL
#include <vector>
#include <iostream>
#include <exception>
#include <cassert>

// podio specific includes
#include "podio/EventStore.h"
#include "read_test.h"
#include "podio/ROOTReader.h"

// test data model
#include "datamodel/ExampleHitCollection.h"
#include "datamodel/ExampleClusterCollection.h"
#include "datamodel/ExampleMCCollection.h"
#include "datamodel/ExampleReferencingTypeCollection.h"
#include "datamodel/ExampleWithOneRelationCollection.h"
#include "datamodel/ExampleWithVectorMemberCollection.h"
#include "datamodel/ExampleWithComponentCollection.h"
#include "datamodel/ExampleWithARelationCollection.h"
#include "datamodel/ExampleWithStringCollection.h"
#include "datamodel/ExampleWithNamespace.h"
#include "datamodel/ExampleWithArrayCollection.h"

/* example test program reading multiple files with one reader
*/


int glob = 0;


void processEvent(podio::EventStore& store, bool verboser, unsigned eventNum) {

auto& strings = store.get<ExampleWithStringCollection>("strings");
if(strings.isValid()){
auto string = strings[0];
if (string.theString() != "SomeString") {
throw std::runtime_error("Couldn't read string properly");
}
} else {
throw std::runtime_error("Collection 'strings' should be present.");
}

auto& clusters = store.get<ExampleClusterCollection>("clusters");
if(clusters.isValid()){
auto cluster = clusters[0];
for (auto i = cluster.Hits_begin(), end = cluster.Hits_end(); i!=end; ++i){
std::cout << " Referenced hit has an energy of " << i->energy() << std::endl;
glob++;
}
} else {
throw std::runtime_error("Collection 'clusters' should be present");
}


auto& mcps = store.get<ExampleMCCollection>("mcparticles");
if( mcps.isValid() ){
// check that we can retrieve the correct parent daughter relation
// set in write.cpp :

// particle 0 has particles 2,3,4 and 5 as daughters:
auto p = mcps[0] ;

//-------- print relations for debugging:
for( auto p : mcps ){
std::cout << " particle " << p.getObjectID().index << " has daughters: " ;
for(auto it = p.daughters_begin(), end = p.daughters_end() ; it!=end ; ++it ){
std::cout << " " << it->getObjectID().index ;
}
std::cout << " and parents: " ;
for(auto it = p.parents_begin(), end = p.parents_end() ; it!=end ; ++it ){
std::cout << " " << it->getObjectID().index ;
}
std::cout << std::endl ;
}

auto d0 = p.daughters(0) ;
auto d1 = p.daughters(1) ;
auto d2 = p.daughters(2) ;
auto d3 = p.daughters(3) ;

if( ! ( d0 == mcps[2] ) ) throw std::runtime_error(" error: 1. daughter of particle 0 is not particle 2 ");
if( ! ( d1 == mcps[3] ) ) throw std::runtime_error(" error: 2. daughter of particle 0 is not particle 3 ");
if( ! ( d2 == mcps[4] ) ) throw std::runtime_error(" error: 3. daughter of particle 0 is not particle 4 ");
if( ! ( d3 == mcps[5] ) ) throw std::runtime_error(" error: 4. daughter of particle 0 is not particle 5 ");


// particle 3 has particles 6,7,8 and 9 as daughters:
p = mcps[3] ;

d0 = p.daughters(0) ;
d1 = p.daughters(1) ;
d2 = p.daughters(2) ;
d3 = p.daughters(3) ;

if( ! ( d0 == mcps[6] ) ) throw std::runtime_error(" error: 1. daughter of particle 3 is not particle 6 ");
if( ! ( d1 == mcps[7] ) ) throw std::runtime_error(" error: 2. daughter of particle 3 is not particle 7 ");
if( ! ( d2 == mcps[8] ) ) throw std::runtime_error(" error: 3. daughter of particle 3 is not particle 8 ");
if( ! ( d3 == mcps[9] ) ) throw std::runtime_error(" error: 4. daughter of particle 3 is not particle 9 ");

} else {
throw std::runtime_error("Collection 'mcparticles' should be present");
}


//std::cout << "Fetching collection 'refs'" << std::endl;
auto& refs = store.get<ExampleReferencingTypeCollection>("refs");
if(refs.isValid()){
auto ref = refs[0];
for (auto j = ref.Clusters_begin(), end = ref.Clusters_end(); j!=end; ++j){
for (auto i = j->Hits_begin(), end = j->Hits_end(); i!=end; ++i){
//std::cout << " Referenced object has an energy of " << i->energy() << std::endl;
glob++;
}
}
} else {
throw std::runtime_error("Collection 'refs' should be present");
}
//std::cout << "Fetching collection 'OneRelation'" << std::endl;
auto& rels = store.get<ExampleWithOneRelationCollection>("OneRelation");
if(rels.isValid()) {
//std::cout << "Referenced object has an energy of " << (*rels)[0].cluster().energy() << std::endl;
glob++;
} else {
throw std::runtime_error("Collection 'OneRelation' should be present");
}

// std::cout << "Fetching collection 'WithVectorMember'" << std::endl;
auto& vecs = store.get<ExampleWithVectorMemberCollection>("WithVectorMember");
if(vecs.isValid()) {
// auto item = (*vecs)[0];
// std::cout << (*vecs).size() << std::endl;
// for (auto c = item.count_begin(), end = item.count_end(); c!=end; ++c){
// std::cout << " Counter value " << (*c) << std::endl;
// glob++;
// }
} else {
throw std::runtime_error("Collection 'WithVectorMember' should be present");
}

auto& comps = store.get<ExampleWithComponentCollection>("Component");
if (comps.isValid()) {
auto comp = comps[0];
int a = comp.component().data.x + comp.component().data.z;
}

auto& arrays = store.get<ExampleWithArrayCollection>("arrays");
if (arrays.isValid() && arrays.size() != 0) {
auto array = arrays[0];
if (array.myArray(1) != eventNum) {
throw std::runtime_error("Array not properly set.");
}
if (array.arrayStruct().data.p.at(2) != 2*eventNum) {
throw std::runtime_error("Array not properly set.");
}
if (array.structArray(0).x != eventNum) {
throw std::runtime_error("Array of struct not properly set.");
}
} else {
throw std::runtime_error("Collection 'arrays' should be present");
}

auto& nmspaces = store.get<ex42::ExampleWithARelationCollection>("WithNamespaceRelation");
auto& copies = store.get<ex42::ExampleWithARelationCollection>("WithNamespaceRelationCopy");
auto& cpytest = store.create<ex42::ExampleWithARelationCollection>("TestConstCopy");
if (nmspaces.isValid() && copies.isValid()) {
for (int j = 0; j < nmspaces.size(); j++) {
auto nmsp = nmspaces[j];
auto cpy = copies[j];
cpytest.push_back(nmsp.clone());
if (nmsp.ref().isAvailable()) {
if (nmsp.ref().data().x != cpy.ref().data().x || nmsp.ref().data().y != cpy.ref().data().y) {
throw std::runtime_error("Copied item has differing data in OneToOne referenced item.");
}
// check direct accessors of POD sub members
if (nmsp.ref().x() != cpy.ref().x()) {
throw std::runtime_error("Getting wrong values when using direct accessors for sub members.");
}
if (nmsp.number() != cpy.number()) {
throw std::runtime_error("Copied item has differing member.");
}
if (!(nmsp.ref().getObjectID() == cpy.ref().getObjectID())) {
throw std::runtime_error("Copied item has wrong OneToOne references.");
}
}
auto cpy_it = cpy.refs_begin();
for (auto it = nmsp.refs_begin(); it != nmsp.refs_end(); ++it, ++cpy_it) {
if (it->data().x != cpy_it->data().x || it->data().y != cpy_it->data().y) {
throw std::runtime_error("Copied item has differing data in OneToMany referenced item.");
}
if (!(it->getObjectID() == cpy_it->getObjectID())) {
throw std::runtime_error("Copied item has wrong OneToMany references.");
}
}
}
} else {
throw std::runtime_error("Collection 'WithNamespaceRelation' and 'WithNamespaceRelationCopy' should be present");
}
}

int main(){
auto reader = podio::ROOTReader();
auto store = podio::EventStore();
Expand Down
Loading

0 comments on commit 3b890f2

Please sign in to comment.