Warning, file /include/YODA/Writer.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006 #ifndef YODA_Writer_h
0007 #define YODA_Writer_h
0008
0009 #include "YODA/AnalysisObject.h"
0010 #include "YODA/Utils/Traits.h"
0011
0012 #include <YODA/Config/BuildConfig.h>
0013 #ifdef HAVE_HDF5
0014 #ifdef WITH_HIGHFIVE
0015 #include <YODA/highfive/H5File.hpp>
0016 #else
0017 #include <highfive/H5File.hpp>
0018 #define YODA_H5 HighFive
0019 #endif
0020 #endif
0021
0022 #include <type_traits>
0023 #include <fstream>
0024 #include <iostream>
0025
0026 namespace YODA {
0027
0028
0029 static bool enableH5compression = Utils::getEnvParam("YODA_HDF5_COMPRESSION", true);
0030
0031
0032 class Writer {
0033 public:
0034
0035
0036 virtual ~Writer() {}
0037
0038
0039
0040
0041
0042
0043 void write(const std::string& filename, const AnalysisObject& ao);
0044
0045
0046 void write(std::ostream& stream, const AnalysisObject& ao) {
0047 std::vector<const AnalysisObject*> vec{&ao};
0048 write(stream, vec);
0049 }
0050
0051
0052 template <typename T>
0053 typename std::enable_if_t<DerefableToAO<T>::value>
0054 write(std::ostream& stream, const T& ao) {
0055 write(stream, *ao);
0056 }
0057
0058
0059 template <typename T>
0060 typename std::enable_if_t<DerefableToAO<T>::value>
0061 write(const std::string& filename, const T& ao) {
0062 write(filename, *ao);
0063 }
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 #ifdef HAVE_HDF5
0078 void write(YODA_H5::File& file, const std::vector<const AnalysisObject*>& aos);
0079 #endif
0080
0081
0082
0083
0084
0085
0086
0087 void write(std::ostream& stream, const std::vector<const AnalysisObject*>& aos, int precision = -1);
0088
0089
0090
0091
0092
0093
0094 template <typename RANGE>
0095 typename std::enable_if_t<CIterable<RANGE>::value>
0096 write(std::ostream& stream, const RANGE& aos) {
0097 write(stream, std::begin(aos), std::end(aos));
0098 }
0099
0100
0101 template <typename RANGE>
0102 typename std::enable_if_t<CIterable<RANGE>::value>
0103 write(const std::string& filename, const RANGE& aos) {
0104 write(filename, std::begin(aos), std::end(aos));
0105 }
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117 template <typename AOITER>
0118 void write(std::ostream& stream, const AOITER& begin, const AOITER& end, int precision = -1) {
0119 std::vector<const AnalysisObject*> vec;
0120
0121 for (AOITER ipao = begin; ipao != end; ++ipao) vec.push_back(&(**ipao));
0122 write(stream, vec, precision);
0123 }
0124
0125
0126
0127
0128
0129
0130 template <typename AOITER>
0131 void write(const std::string& filename, const AOITER& begin, const AOITER& end) {
0132 std::vector<const AnalysisObject*> vec;
0133
0134 for (AOITER ipao = begin; ipao != end; ++ipao) vec.push_back(&(**ipao));
0135
0136 if (filename != "-") {
0137 try {
0138 const size_t lastdot = filename.find_last_of(".");
0139 std::string fmt = Utils::toLower(lastdot == std::string::npos ? filename : filename.substr(lastdot+1));
0140 const bool compress = (fmt == "gz") || (fmt == "h5" && enableH5compression);
0141 useCompression(compress);
0142 #ifdef HAVE_HDF5
0143
0144 if (Utils::startswith(fmt, "h5")) {
0145 try {
0146 YODA_H5::File h5(filename, YODA_H5::File::OpenOrCreate | YODA_H5::File::Truncate);
0147 write(h5, vec);
0148 } catch(...) {
0149 throw WriteError("Failed to open HDF5 file " + filename);
0150 }
0151 return;
0152 }
0153 #endif
0154
0155 std::ofstream stream;
0156 stream.exceptions(std::ofstream::failbit | std::ofstream::badbit);
0157 stream.open(filename.c_str());
0158 if (stream.fail())
0159 throw WriteError("Writing to filename " + filename + " failed");
0160 write(stream, vec);
0161 } catch (std::ofstream::failure& e) {
0162 throw WriteError("Writing to filename " + filename + " failed: " + e.what());
0163 }
0164 } else {
0165 try {
0166 write(std::cout, vec);
0167 } catch (std::runtime_error& e) {
0168 throw WriteError("Writing to stdout failed: " + std::string(e.what()));
0169 }
0170 }
0171
0172 }
0173
0174
0175
0176
0177 void setPrecision(int precision) {
0178 _precision = precision;
0179 }
0180
0181
0182 void setAOPrecision(const bool needsDP = false) {
0183 if (needsDP) _aoprecision = std::numeric_limits<double>::max_digits10;
0184 else if (_precision > 0) _aoprecision = _precision;
0185 else _aoprecision = 6;
0186 }
0187
0188
0189 void useCompression(const bool compress=true) {
0190 _compress = compress;
0191 }
0192
0193
0194 protected:
0195
0196
0197
0198
0199
0200 virtual void writeHead(std::ostream&) {}
0201
0202
0203 virtual void writeBody(std::ostream& stream, const AnalysisObject* ao);
0204
0205
0206 virtual void writeBody(std::ostream& stream, const AnalysisObject& ao);
0207
0208
0209
0210 template <typename T>
0211 typename std::enable_if_t<DerefableToAO<T>::value>
0212 writeBody(std::ostream& stream, const T& ao) { writeBody(stream, *ao); }
0213
0214
0215 virtual void writeFoot(std::ostream& stream) { stream << std::flush; }
0216
0217
0218
0219
0220
0221
0222
0223 virtual void writeAO(std::ostream& stream, const AnalysisObject& ao) = 0;
0224
0225 #ifdef HAVE_HDF5
0226 virtual void writeAOS(YODA_H5::File& file, const vector<const AnalysisObject*>& aos) = 0;
0227 #endif
0228
0229
0230
0231
0232
0233 int _precision, _aoprecision;
0234
0235
0236 bool _compress;
0237
0238 };
0239
0240
0241
0242 Writer& mkWriter(const std::string& format_name);
0243
0244
0245 }
0246
0247 #endif