yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.0
Writer.cc
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-2023 The YODA collaboration (see AUTHORS for details)
5//
6#include "YODA/WriterYODA.h"
7#include "YODA/WriterFLAT.h"
9
10#ifdef HAVE_LIBZ
11#define _XOPEN_SOURCE 700
12#include "zstr/zstr.hpp"
13#endif
14
15#include <iostream>
16#include <locale>
17#include <typeinfo>
18#include <sstream>
19#include <memory>
20using namespace std;
21
22namespace YODA {
23
24
25 Writer& mkWriter(const string& name) {
26 // Determine the format from the string (a file or file extension)
27 const size_t lastdot = name.find_last_of(".");
28 string fmt = Utils::toLower(lastdot == string::npos ? name : name.substr(lastdot+1));
29 const bool compress = (fmt == "gz");
30 //cout << "***" << compress << endl;
31 if (compress) {
32 #ifndef HAVE_LIBZ
33 throw UserError("YODA was compiled without zlib support: can't write " + name);
34 #endif
35 const size_t lastbutonedot = (lastdot == string::npos) ? string::npos : name.find_last_of(".", lastdot-1);
36 fmt = Utils::toLower(lastbutonedot == string::npos ? name : name.substr(lastbutonedot+1));
37 }
38 // Create the appropriate Writer
39 Writer* w = nullptr;
40 if (Utils::startswith(fmt, "yoda")) w = &WriterYODA::create();
41 if (Utils::startswith(fmt, "dat" )) w = &WriterFLAT::create();
42 if (Utils::startswith(fmt, "flat")) w = &WriterFLAT::create();
43 if (!w) throw UserError("Format cannot be identified from string '" + name + "'");
44 w->useCompression(compress);
45 return *w;
46 }
47
48
49 void Writer::write(const std::string& filename, const AnalysisObject& ao) {
50 std::vector<const AnalysisObject*> vec{&ao};
51 write(filename, vec);
52 }
53
54 // Canonical writer function, including compression handling
55 void Writer::write(ostream& stream, const vector<const AnalysisObject*>& aos) {
56 std::unique_ptr<std::ostream> zos;
57 std::ostream* os = &stream;
58
59 // Write numbers in the "C" locale
60 std::locale prev_locale = os->getloc();
61 os->imbue(std::locale::classic());
62
63 // Wrap the stream if needed
64 if (_compress) {
65 #ifdef HAVE_LIBZ
66 // Doesn't work to always create zstr wrapper: have to only create if compressing :-/
67 // zstr::ostream zstream(stream);
68 // ostream& os = _compress ? zstream : stream;
69 os = new zstr::ostream(stream);
70 zos.reset(os);
71 #else
72 throw UserError("YODA was compiled without zlib support: can't write to a compressed stream");
73 #endif
74 }
75
76 // Write the data components
78 writeHead(*os);
79 bool first = true;
80 for (const AnalysisObject* aoptr : aos) {
81 setAOPrecision( aoptr->annotation("WriterDoublePrecision", 0) );
82 try {
83 if (!first) *os << "\n"; //< blank line between items
84 writeBody(*os, aoptr);
85 first = false;
86 } catch (const LowStatsError& ex) {
88 std::cerr << "LowStatsError in writing AnalysisObject " << aoptr->title() << ":\n" << ex.what() << "\n";
89 }
90 }
91 writeFoot(*os);
92 *os << flush;
93
94 os->imbue(prev_locale);
95 }
96
97
98 void Writer::writeBody(ostream& stream, const AnalysisObject* ao) {
99 if (!ao) throw WriteError("Attempting to write a null AnalysisObject*");
100 writeBody(stream, *ao);
101 }
102
103 void Writer::writeBody(ostream& stream, const AnalysisObject& ao) {
104 try {
105 writeAO(stream, ao);
106 }
107 catch(...) {
108 ostringstream oss;
109 oss << "Unrecognised analysis object type " << ao.type() << " in Writer::write";
110 throw Exception(oss.str());
111 }
112 }
113
114
115}
AnalysisObject is the base class for histograms and scatters.
virtual std::string type() const
Get name of the analysis object type.
Generic unspecialised YODA runtime error.
Definition Exceptions.h:20
Errors relating to insufficient (effective) statistics.
Definition Exceptions.h:72
Error for problems introduced outside YODA, to put it nicely.
Definition Exceptions.h:100
Error for file writing errors.
Definition Exceptions.h:93
static Writer & create()
Singleton creation function.
Definition WriterFLAT.cc:17
static Writer & create()
Singleton creation function.
Definition WriterYODA.cc:21
Pure virtual base class for various output writers.
Definition Writer.h:19
virtual void writeHead(std::ostream &)
Write any opening boilerplate required by the format to stream.
Definition Writer.h:164
virtual void writeFoot(std::ostream &stream)
Write any closing boilerplate required by the format to stream.
Definition Writer.h:179
void useCompression(const bool compress=true)
Use libz compression?
Definition Writer.h:153
virtual void writeAO(std::ostream &stream, const AnalysisObject &ao)=0
virtual void writeBody(std::ostream &stream, const AnalysisObject *ao)
Write the body elements corresponding to AnalysisObject ao to stream.
Definition Writer.cc:98
void write(const std::string &filename, const AnalysisObject &ao)
Write out object ao to file filename.
Definition Writer.cc:49
void setAOPrecision(const bool needsDP=false)
Set precision of numerical quantities for current AO in this writer's output.
Definition Writer.h:148
Anonymous namespace to limit visibility.
Writer & mkWriter(const std::string &format_name)
Factory function to make a writer object by format name or a filename.
Definition Writer.cc:25