Skip to content

Commit

Permalink
Enable selective reading in Reader interface
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadlener committed Jan 6, 2025
1 parent 37859c7 commit a585ae1
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 30 deletions.
38 changes: 24 additions & 14 deletions include/podio/Reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ class Reader {
struct ReaderConcept {
virtual ~ReaderConcept() = default;

virtual podio::Frame readNextFrame(const std::string& name) = 0;
virtual podio::Frame readFrame(const std::string& name, size_t index) = 0;
virtual podio::Frame readNextFrame(const std::string& name, const std::vector<std::string>&) = 0;
virtual podio::Frame readFrame(const std::string& name, size_t index, const std::vector<std::string>&) = 0;
virtual size_t getEntries(const std::string& name) const = 0;
virtual podio::version::Version currentFileVersion() const = 0;
virtual std::optional<podio::version::Version> currentFileVersion(const std::string& name) const = 0;
Expand All @@ -44,16 +44,17 @@ class Reader {

~ReaderModel() = default;

podio::Frame readNextFrame(const std::string& name) override {
auto maybeFrame = m_reader->readNextEntry(name);
podio::Frame readNextFrame(const std::string& name, const std::vector<std::string>& collsToRead) override {
auto maybeFrame = m_reader->readNextEntry(name, collsToRead);
if (maybeFrame) {
return maybeFrame;
}
throw std::runtime_error("Failed reading category " + name + " (reading beyond bounds?)");
}

podio::Frame readFrame(const std::string& name, size_t index) override {
auto maybeFrame = m_reader->readEntry(name, index);
podio::Frame readFrame(const std::string& name, size_t index,
const std::vector<std::string>& collsToRead) override {
auto maybeFrame = m_reader->readEntry(name, index, collsToRead);
if (maybeFrame) {
return maybeFrame;
}
Expand Down Expand Up @@ -105,46 +106,55 @@ class Reader {
/// Read the next frame of a given category
///
/// @param name The category name for which to read the next frame
/// @param collsToRead (optional) the collection names that should be read. If
/// not provided (or empty) all collections will be read
///
/// @returns A fully constructed Frame with the contents read from file
///
/// @throws std::invalid_argument in case the category is not available or in
/// case no more entries are available
podio::Frame readNextFrame(const std::string& name) {
return m_self->readNextFrame(name);
podio::Frame readNextFrame(const std::string& name, const std::vector<std::string>& collsToRead = {}) {
return m_self->readNextFrame(name, collsToRead);
}

/// Read the next frame of the "events" category
///
/// @param collsToRead (optional) the collection names that should be read. If
/// not provided (or empty) all collections will be read
///
/// @returns A fully constructed Frame with the contents read from file
///
/// @throws std::invalid_argument in case no (more) events are available
podio::Frame readNextEvent() {
return readNextFrame(podio::Category::Event);
podio::Frame readNextEvent(const std::vector<std::string>& collsToRead = {}) {
return readNextFrame(podio::Category::Event, collsToRead);
}

/// Read a specific frame for a given category
///
/// @param name The category name for which to read the next entry
/// @param index The entry number to read
/// @param collsToRead (optional) the collection names that should be read. If
/// not provided (or empty) all collections will be read
///
/// @returns A fully constructed Frame with the contents read from file
///
/// @throws std::invalid_argument in case the category is not available or in
/// case the specified entry is not available
podio::Frame readFrame(const std::string& name, size_t index) {
return m_self->readFrame(name, index);
podio::Frame readFrame(const std::string& name, size_t index, const std::vector<std::string>& collsToRead = {}) {
return m_self->readFrame(name, index, collsToRead);
}

/// Read a specific frame of the "events" category
///
/// @param index The event number to read
/// @param collsToRead (optional) the collection names that should be read. If
/// not provided (or empty) all collections will be read
///
/// @returns A fully constructed Frame with the contents read from file
///
/// @throws std::invalid_argument in case the desired event is not available
podio::Frame readEvent(size_t index) {
return readFrame(podio::Category::Event, index);
podio::Frame readEvent(size_t index, const std::vector<std::string>& collsToRead = {}) {
return readFrame(podio::Category::Event, index, collsToRead);
}

/// Get the number of entries for the given name
Expand Down
25 changes: 19 additions & 6 deletions tests/read_frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "interface_extension_model/TestInterfaceLinkCollection.h"

#include "podio/Frame.h"
#include "podio/Reader.h"

#include <iostream>

Expand Down Expand Up @@ -274,14 +275,17 @@ int read_frames(const std::string& filename, bool assertBuildVersion = true) {
return 0;
}

// /// Check that reading only a subset of collections works as expected
template <typename ReaderT>
int test_read_frame_limited(const std::string& inputFile) {
auto reader = ReaderT();
reader.openFile(inputFile);
int test_read_frame_limited(ReaderT& reader) {
const std::vector<std::string> collsToRead = {"mcparticles", "clusters"};

const auto event = podio::Frame(reader.readNextEntry("events", collsToRead));
const auto event = [&]() {
if constexpr (std::is_same_v<ReaderT, podio::Reader>) {
return podio::Frame(reader.readFrame("events", 1, collsToRead));
} else {
return podio::Frame(reader.readEntry("events", 1, collsToRead));
}
}();

const auto& availColls = event.getAvailableCollections();

Expand Down Expand Up @@ -313,7 +317,7 @@ int test_read_frame_limited(const std::string& inputFile) {
return 1;
}

const auto& clusters = event.get<ExampleClusterCollection>("clusters");
const auto& clusters = event.template get<ExampleClusterCollection>("clusters");
const auto clu0 = clusters[0];
const auto hits = clu0.Hits();
if (hits.size() != 1 || hits[0].isAvailable()) {
Expand All @@ -324,4 +328,13 @@ int test_read_frame_limited(const std::string& inputFile) {
return 0;
}

/// Check that reading only a subset of collections works as expected
template <typename ReaderT>
int test_read_frame_limited(const std::string& inputFile) {
auto reader = ReaderT();
reader.openFile(inputFile);

return test_read_frame_limited(reader);
}

#endif // PODIO_TESTS_READ_FRAME_H
10 changes: 4 additions & 6 deletions tests/root_io/read_interface_root.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#include "read_frame.h"
#include "read_interface.h"

int main(int, char**) {
#include "podio/Reader.h"

int main(int, char**) {
auto reader = podio::makeReader("example_frame_interface.root");
if (read_frames(reader)) {
return 1;
}

return 0;
return read_frames(reader) + test_read_frame_limited(reader);
}
6 changes: 2 additions & 4 deletions tests/sio_io/read_interface_sio.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
#include "read_frame.h"
#include "read_interface.h"

int main(int, char**) {

auto readerSIO = podio::makeReader("example_frame_sio_interface.sio");
if (read_frames(readerSIO)) {
return 1;
}
return read_frames(readerSIO) + test_read_frame_limited(readerSIO);

return 0;
}

0 comments on commit a585ae1

Please sign in to comment.