11#include <dpsim-models/Logger.h>
12#include <dpsim/DataLogger.h>
16DataLogger::DataLogger(Bool enabled)
18 mLogFile.setstate(std::ios_base::badbit);
21DataLogger::DataLogger(String name, Bool enabled, UInt downsampling)
23 mDownsampling(downsampling) {
27 mFilename = CPS::Logger::logDir() +
"/" + name +
".csv";
29 if (mFilename.has_parent_path() && !fs::exists(mFilename.parent_path()))
30 fs::create_directory(mFilename.parent_path());
33void DataLogger::start() {
38 std::ofstream(mFilename, std::ios_base::out | std::ios_base::trunc);
39 if (!mLogFile.is_open()) {
41 std::cerr <<
"Cannot open log file " << mFilename << std::endl;
46void DataLogger::stop() { mLogFile.close(); }
48void DataLogger::setColumnNames(std::vector<String> names) {
49 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
50 mLogFile << std::right << std::setw(14) <<
"time";
51 for (
auto name : names) {
52 mLogFile <<
", " << std::right << std::setw(13) << name;
58void DataLogger::logDataLine(Real time, Real data) {
62 mLogFile << std::scientific << std::right << std::setw(14) << time;
63 mLogFile <<
", " << std::right << std::setw(13) << data;
67void DataLogger::logDataLine(Real time,
const Matrix &data) {
71 mLogFile << std::scientific << std::right << std::setw(14) << time;
72 for (Int i = 0; i < data.rows(); ++i) {
73 mLogFile <<
", " << std::right << std::setw(13) << data(i, 0);
78void DataLogger::logDataLine(Real time,
const MatrixComp &data) {
81 mLogFile << std::scientific << std::right << std::setw(14) << time;
82 for (Int i = 0; i < data.rows(); ++i) {
83 mLogFile <<
", " << std::right << std::setw(13) << data(i, 0);
88void DataLogger::logPhasorNodeValues(Real time,
const Matrix &data,
90 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
91 std::vector<String> names;
93 Int harmonicOffset = data.rows() / freqNum;
94 Int complexOffset = harmonicOffset / 2;
96 for (Int freq = 0; freq < freqNum; ++freq) {
97 for (Int node = 0; node < complexOffset; ++node) {
98 std::stringstream name;
99 name <<
"n" << std::setfill(
'0') << std::setw(5) << node <<
"f"
100 << std::setfill(
'0') << std::setw(2) << freq <<
".re";
101 names.push_back(name.str());
103 for (Int node = 0; node < complexOffset; ++node) {
104 std::stringstream name;
105 name <<
"n" << std::setfill(
'0') << std::setw(5) << node <<
"f"
106 << std::setfill(
'0') << std::setw(2) << freq <<
".im";
107 names.push_back(name.str());
110 setColumnNames(names);
112 logDataLine(time, data);
115void DataLogger::logEMTNodeValues(Real time,
const Matrix &data) {
116 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
117 std::vector<String> names;
118 for (Int i = 0; i < data.rows(); ++i) {
119 std::stringstream name;
120 name <<
"node" << std::setfill(
'0') << std::setw(5) << i;
121 names.push_back(name.str());
123 setColumnNames(names);
125 logDataLine(time, data);
128void DataLogger::log(Real time, Int timeStepCount) {
129 if (!mEnabled || !(timeStepCount % mDownsampling == 0))
132 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
133 mLogFile << std::right << std::setw(14) <<
"time";
134 for (
auto it : mAttributes)
135 mLogFile <<
", " << std::right << std::setw(13) << it.first;
139 mLogFile << std::scientific << std::right << std::setw(14) << time;
140 for (
auto it : mAttributes)
141 mLogFile <<
", " << std::right << std::setw(13) << it.second->toString();
145void DataLogger::Step::execute(Real time, Int timeStepCount) {
146 mLogger.log(time, timeStepCount);
149CPS::Task::Ptr DataLogger::getTask() {
150 return std::make_shared<DataLogger::Step>(*
this);