File indexing completed on 2025-04-19 09:13:42
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 #include <type_traits>
0012 #include <fstream>
0013 #include <iostream>
0014
0015 namespace YODA {
0016
0017
0018
0019 class Writer {
0020 public:
0021
0022
0023 virtual ~Writer() {}
0024
0025
0026
0027
0028
0029
0030 void write(const std::string& filename, const AnalysisObject& ao);
0031
0032
0033 void write(std::ostream& stream, const AnalysisObject& ao) {
0034
0035 std::vector<const AnalysisObject*> vec{&ao};
0036 write(stream, vec);
0037 }
0038
0039
0040 template <typename T>
0041 typename std::enable_if_t<DerefableToAO<T>::value>
0042 write(std::ostream& stream, const T& ao) {
0043 write(stream, *ao);
0044 }
0045
0046
0047 template <typename T>
0048 typename std::enable_if_t<DerefableToAO<T>::value>
0049 write(const std::string& filename, const T& ao) {
0050 write(filename, *ao);
0051 }
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 void write(std::ostream& stream, const std::vector<const AnalysisObject*>& aos);
0066
0067
0068
0069
0070
0071
0072 template <typename RANGE>
0073 typename std::enable_if_t<CIterable<RANGE>::value>
0074 write(std::ostream& stream, const RANGE& aos) {
0075 write(stream, std::begin(aos), std::end(aos));
0076 }
0077
0078
0079 template <typename RANGE>
0080 typename std::enable_if_t<CIterable<RANGE>::value>
0081 write(const std::string& filename, const RANGE& aos) {
0082 write(filename, std::begin(aos), std::end(aos));
0083 }
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095 template <typename AOITER>
0096 void write(std::ostream& stream, const AOITER& begin, const AOITER& end) {
0097 std::vector<const AnalysisObject*> vec;
0098
0099 for (AOITER ipao = begin; ipao != end; ++ipao) vec.push_back(&(**ipao));
0100 write(stream, vec);
0101 }
0102
0103
0104
0105
0106
0107
0108 template <typename AOITER>
0109 void write(const std::string& filename, const AOITER& begin, const AOITER& end) {
0110 std::vector<const AnalysisObject*> vec;
0111
0112 for (AOITER ipao = begin; ipao != end; ++ipao) vec.push_back(&(**ipao));
0113
0114 if (filename != "-") {
0115 try {
0116 const size_t lastdot = filename.find_last_of(".");
0117 std::string fmt = Utils::toLower(lastdot == std::string::npos ? filename : filename.substr(lastdot+1));
0118 const bool compress = (fmt == "gz");
0119 useCompression(compress);
0120
0121 std::ofstream stream;
0122 stream.exceptions(std::ofstream::failbit | std::ofstream::badbit);
0123 stream.open(filename.c_str());
0124 if (stream.fail())
0125 throw WriteError("Writing to filename " + filename + " failed");
0126 write(stream, vec);
0127 } catch (std::ofstream::failure& e) {
0128 throw WriteError("Writing to filename " + filename + " failed: " + e.what());
0129 }
0130 } else {
0131 try {
0132 write(std::cout, vec);
0133 } catch (std::runtime_error& e) {
0134 throw WriteError("Writing to stdout failed: " + std::string(e.what()));
0135 }
0136 }
0137
0138 }
0139
0140
0141
0142
0143 void setPrecision(int precision) {
0144 _precision = precision;
0145 }
0146
0147
0148 void setAOPrecision(const bool needsDP = false) {
0149 _aoprecision = needsDP? std::numeric_limits<double>::max_digits10 : _precision;
0150 }
0151
0152
0153 void useCompression(const bool compress=true) {
0154 _compress = compress;
0155 }
0156
0157
0158 protected:
0159
0160
0161
0162
0163
0164 virtual void writeHead(std::ostream&) {}
0165
0166
0167 virtual void writeBody(std::ostream& stream, const AnalysisObject* ao);
0168
0169
0170 virtual void writeBody(std::ostream& stream, const AnalysisObject& ao);
0171
0172
0173
0174 template <typename T>
0175 typename std::enable_if_t<DerefableToAO<T>::value>
0176 writeBody(std::ostream& stream, const T& ao) { writeBody(stream, *ao); }
0177
0178
0179 virtual void writeFoot(std::ostream& stream) { stream << std::flush; }
0180
0181
0182
0183
0184
0185
0186
0187 virtual void writeAO(std::ostream& stream, const AnalysisObject& ao) = 0;
0188
0189
0190
0191
0192
0193 int _precision, _aoprecision;
0194
0195
0196 bool _compress;
0197
0198 };
0199
0200
0201
0202 Writer& mkWriter(const std::string& format_name);
0203
0204
0205 }
0206
0207 #endif