yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.1.0
Reader.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of YODA -- Yet more Objects for Data Analysis
4// Copyright (C) 2008-2025 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_READER_H
7#define YODA_READER_H
8
11#include "YODA/Utils/Traits.h"
12
13#ifdef HAVE_HDF5
15#ifdef WITH_HIGHFIVE
16#include <YODA/highfive/H5File.hpp>
17#else
18#include <highfive/H5File.hpp>
19#define YODA_H5 HighFive
20#endif
21#endif
22
23#include <memory>
24#include <fstream>
25#include <iostream>
26#include <sstream>
27#include <type_traits>
28#include <unordered_map>
29#include <vector>
30
31namespace YODA {
32
33
35 class Reader {
36
37 public:
38
40 using TypeRegisterItr = typename std::unordered_map<std::string, std::unique_ptr<AOReaderBase>>::const_iterator;
41
43 virtual ~Reader() {
44 // This is technically leaking memory, but since this
45 // is a (static) singleton, there should be no issue.
46 // Cython relies on it for data-structure alignment, too.
47 for (auto& aor : _register) { aor.second.release(); }
48 }
49
50
53
60 template<typename CONT>
61 typename std::enable_if_t<YODA::Pushable<CONT,AnalysisObject*>::value>
62 read(std::istream& stream, CONT& aos, const std::string& match = "", const std::string& unmatch = "") {
63 // if CONT==std::vector<AnalysisObject*>, the compiler should select
64 // the virtual method below, since it prefers non-templated methods in the lookup
65 // otherwise we would enter a endless recursion. Check in case of problems.
66 std::vector<AnalysisObject*> v_aos;
67 read(stream, v_aos, match, unmatch);
68 for (const AnalysisObject* ao : v_aos) aos.push_back(ao);
69 }
70
76 virtual void read(std::istream& stream, std::vector<AnalysisObject*>& aos,
77 const std::string& match = "", const std::string& unmatch = "") = 0;
78
84 #ifdef HAVE_HDF5
85 virtual void read(const YODA_H5::File& file, std::vector<AnalysisObject*>& aos,
86 const std::string& match = "", const std::string& unmatch = "") = 0;
87 #endif
88
93 std::vector<AnalysisObject*> read(std::istream& stream, const std::string& match = "",
94 const std::string& unmatch = "") {
95 std::vector<AnalysisObject*> rtn;
96 read(stream, rtn, match, unmatch);
97 return rtn;
98 }
99
100
105 #ifdef HAVE_HDF5
106 std::vector<AnalysisObject*> read(const YODA_H5::File& file, const std::string& match = "",
107 const std::string& unmatch = "") {
108 std::vector<AnalysisObject*> rtn;
109 read(file, rtn, match, unmatch);
110 return rtn;
111 }
112 #endif
113
114
122 template<typename CONT>
123 typename std::enable_if_t<YODA::Pushable<CONT,AnalysisObject*>::value>
124 read(const std::string& filename, CONT& aos, const std::string& match = "", const std::string& unmatch = "") {
125 // if CONT==std::vector<AnalysisObject*>, the compiler should select
126 // the virtual method below, since it prefers non-templated methods in the lookup
127 // otherwise we would enter a endless recursion. Check in case of problems.
128 std::vector<AnalysisObject*> v_aos;
129 read(filename, v_aos, match, unmatch);
130 for (const AnalysisObject* ao : v_aos) aos.push_back(ao);
131 }
132
138 void read(const std::string& filename, std::vector<AnalysisObject*>& aos,
139 const std::string& match = "", const std::string& unmatch = "") {
140 if (filename != "-") {
141 try {
142 const size_t lastdot = filename.find_last_of(".");
143 std::string fmt = Utils::toLower(lastdot == std::string::npos ? filename : filename.substr(lastdot+1));
144 #ifdef HAVE_HDF5
145 // check if the requested format is H5
146 if (Utils::startswith(fmt, "h5")) {
147 try {
148 const YODA_H5::File h5(filename, YODA_H5::File::ReadOnly);
149 read(h5, aos, match, unmatch);
150 } catch (YODA::ReadError& e) {
151 throw ReadError("Reading from filename " + filename + " failed: " + e.what());
152 }
153 return;
154 }
155 #endif
156 std::ifstream instream;
157 instream.open(filename.c_str());
158 if (instream.fail())
159 throw ReadError("Reading from filename " + filename + " failed");
160 read(instream, aos, match, unmatch);
161 instream.close();
162 } catch (std::ifstream::failure& e) {
163 throw ReadError("Reading from filename " + filename + " failed: " + e.what());
164 }
165 } else {
166 try {
167 read(std::cin, aos, match, unmatch);
168 } catch (std::runtime_error& e) {
169 throw ReadError("Reading from stdin failed: " + std::string(e.what()));
170 }
171 }
172 }
173
178 std::vector<AnalysisObject*> read(const std::string& filename, const std::string& match = "",
179 const std::string& unmatch = "") {
180 std::vector<AnalysisObject*> rtn;
181 read(filename, rtn, match, unmatch);
182 return rtn;
183 }
184
186
189
191 template<typename T>
193 const string key = Utils::toUpper(T().type());
194 const TypeRegisterItr& res = _register.find(key);
195 if (res == _register.end()) _register[key] = std::make_unique<AOReader<T>>();
196 }
197
200 bool patternCheck(const std::string& path, const std::vector<std::regex>& patterns,
201 const std::vector<std::regex>& unpatterns) {
202 bool skip = false;
203 if (patterns.size()) {
204 skip = true;
205 for (const std::regex& re : patterns) {
206 if (std::regex_search(path, re)) { skip = false; break; }
207 }
208 }
209 if (!skip && unpatterns.size()) {
210 for (const std::regex& re : unpatterns) {
211 if (std::regex_search(path, re)) { skip = true; break; }
212 }
213 }
214 return !skip;
215 }
216
218
220 std::unordered_map<string, std::unique_ptr<AOReaderBase>> _register;
221
222 };
223
224
226 Reader& mkReader(const std::string& format_name);
227
228
229}
230
231#endif
AnalysisObject is the base class for histograms and scatters.
Error for file reading errors.
Definition Exceptions.h:72
Pure virtual base class for various output writers.
Definition Reader.h:35
std::enable_if_t< YODA::Pushable< CONT, AnalysisObject * >::value > read(const std::string &filename, CONT &aos, const std::string &match="", const std::string &unmatch="")
Read in a collection of objects objs from file filename.
Definition Reader.h:124
virtual void read(const YODA_H5::File &file, std::vector< AnalysisObject * > &aos, const std::string &match="", const std::string &unmatch="")=0
Read in a collection of objects objs from an HDF5 file.
void registerType()
AO type registration.
Definition Reader.h:192
virtual void read(std::istream &stream, std::vector< AnalysisObject * > &aos, const std::string &match="", const std::string &unmatch="")=0
Read in a collection of objects objs from output stream stream.
virtual ~Reader()
Virtual destructor.
Definition Reader.h:43
typename std::unordered_map< std::string, std::unique_ptr< AOReaderBase > >::const_iterator TypeRegisterItr
Convenience alias for AO Reader.
Definition Reader.h:40
std::vector< AnalysisObject * > read(const std::string &filename, const std::string &match="", const std::string &unmatch="")
Read in a collection of objects from output stream stream.
Definition Reader.h:178
std::vector< AnalysisObject * > read(const YODA_H5::File &file, const std::string &match="", const std::string &unmatch="")
Read in a collection of objects from an H5 file.
Definition Reader.h:106
std::enable_if_t< YODA::Pushable< CONT, AnalysisObject * >::value > read(std::istream &stream, CONT &aos, const std::string &match="", const std::string &unmatch="")
Read in a collection of objects objs from output stream stream.
Definition Reader.h:62
void read(const std::string &filename, std::vector< AnalysisObject * > &aos, const std::string &match="", const std::string &unmatch="")
Read in a collection of objects objs from file filename.
Definition Reader.h:138
bool patternCheck(const std::string &path, const std::vector< std::regex > &patterns, const std::vector< std::regex > &unpatterns)
Check if a string matches any of the given patterns, and that it doesn't match any unpatterns (for pa...
Definition Reader.h:200
std::vector< AnalysisObject * > read(std::istream &stream, const std::string &match="", const std::string &unmatch="")
Read in a collection of objects from output stream stream.
Definition Reader.h:93
Anonymous namespace to limit visibility.
Reader & mkReader(const std::string &format_name)
Factory function to make a reader object by format name or a filename.
Definition Reader.cc:19