File measurementssaverstd.h
File List > code_source > cosmolattice > include > CosmoInterface > measurements > measurementsIO > std > measurementssaverstd.h
Go to the documentation of this file
#ifndef COSMOINTERFACE_MEASUREMENTS_STD_MEASUREMENTSSAVERSTD_H
#define COSMOINTERFACE_MEASUREMENTS_STD_MEASUREMENTSSAVERSTD_H
/* This file is part of CosmoLattice, available at www.cosmolattice.net .
Copyright Daniel G. Figueroa, Adrien Florio, Francisco Torrenti and Wessel Valkenburg.
Released under the MIT license, see LICENSE.md. */
// File info: Main contributor(s): Daniel G. Figueroa, Adrien Florio, Francisco Torrenti, Year: 2019
#include "TempLat/util/conditionaloutput/outputstream.h"
#include <filesystem>
#include <sstream>
#include <iomanip>
#include "TempLat/lattice/field/field.h"
#include "CosmoInterface/measurements/measurementsIO/filesmanager.h"
namespace TempLat
{
template <typename T> class MeasurementsSaverStd
{
public:
// Put public methods here. These should change very little over time.
template <size_t NDim>
MeasurementsSaverStd(FilesManager<NDim> &fm, std::string fn, bool amIRoot, bool appendMode,
const std::vector<std::string> &headers = {})
: mMode(!appendMode ? std::ios_base::out : std::ios_base::app),
outputAv(makeOutputStream(fm.getWorkingDir() + fm.getTag() + "average_" + fn + ".txt", amIRoot, appendMode,
fm.getOverwriteMode())),
stream(std::make_shared<std::stringstream>()), headerStream(std::make_shared<std::stringstream>()),
headerSaved(false)
{
if (!appendMode && fm.getPrintHeaders())
for (auto &str : headers)
addHeader(str);
else
headerSaved = true;
}
template <size_t NDim>
MeasurementsSaverStd(FilesManager<NDim> &fm, const Field<T, NDim> &fld, bool amIRoot, bool appendMode,
const std::vector<std::string> &headers = {})
: mMode(!appendMode ? std::ios_base::out : std::ios_base::app), stream(std::make_shared<std::stringstream>()),
headerStream(std::make_shared<std::stringstream>()), headerSaved(false)
{
auto name = fm.getCurredName(fld, true);
outputAv = makeOutputStream(name + ".txt", amIRoot, appendMode, fm.getOverwriteMode());
if (!appendMode && fm.getPrintHeaders())
for (auto &str : headers)
addHeader(str);
else
headerSaved = true;
}
virtual ~MeasurementsSaverStd() = default;
void addAverage(const T &r) {
if constexpr (std::floating_point<T> && (sizeof(T) == sizeof(float))) (*stream) << std::setprecision(8);
else (*stream) << std::setprecision(15);
(*stream) << " " << r;
// (*stream) << std::setprecision(15) << " " << r;
}
void addHeader(const std::string &str) { (*headerStream) << " " << str; }
void save()
{
if (!headerSaved) {
(*outputAv) << "#" << StringTrimmer::ltrimmed(headerStream->str()) << "\n";
headerSaved = true;
}
(*outputAv) << StringTrimmer::ltrimmed(stream->str()) << "\n";
stream->str("");
outputAv->flush();
}
private:
/* Put all member variables and private methods here. These may change arbitrarily. */
std::shared_ptr<OutputStream<T>> makeOutputStream(const std::string &fname, bool amIRoot, bool appendMode,
bool overwriteMode)
{
if (!appendMode && std::filesystem::exists(fname) && amIRoot) {
if (overwriteMode) {
std::filesystem::remove(fname);
} else {
throw(FileAlreadyExistsError(
"Refusing to overwrite existing output file \"" + fname +
"\". Set 'appendToFiles = true' to append, or 'overwriteFiles = true' to delete."));
}
}
return std::make_shared<OutputStream<T>>(fname, amIRoot, mMode);
}
std::ios_base::openmode mMode;
std::shared_ptr<OutputStream<T>> outputAv;
std::shared_ptr<std::stringstream> stream;
std::shared_ptr<std::stringstream> headerStream;
bool headerSaved;
};
} // namespace TempLat
#endif