DPsim
Loading...
Searching...
No Matches
DataLogger.cpp
1/* Copyright 2017-2021 Institute for Automation of Complex Power Systems,
2 * EONERC, RWTH Aachen University
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
7 *********************************************************************************/
8
9#include <iomanip>
10
11#include <dpsim-models/Logger.h>
12#include <dpsim/DataLogger.h>
13
14using namespace DPsim;
15
16DataLogger::DataLogger(Bool enabled)
17 : DataLoggerInterface(), mLogFile(), mEnabled(enabled), mDownsampling(1) {
18 mLogFile.setstate(std::ios_base::badbit);
19}
20
21DataLogger::DataLogger(String name, Bool enabled, UInt downsampling)
22 : DataLoggerInterface(), mName(name), mEnabled(enabled),
23 mDownsampling(downsampling) {
24 if (!mEnabled)
25 return;
26
27 mFilename = CPS::Logger::logDir() + "/" + name + ".csv";
28
29 if (mFilename.has_parent_path() && !fs::exists(mFilename.parent_path()))
30 fs::create_directory(mFilename.parent_path());
31}
32
33void DataLogger::start() {
34 if (!mEnabled)
35 return;
36
37 mLogFile =
38 std::ofstream(mFilename, std::ios_base::out | std::ios_base::trunc);
39 if (!mLogFile.is_open()) {
40 // TODO: replace by exception
41 std::cerr << "Cannot open log file " << mFilename << std::endl;
42 mEnabled = false;
43 }
44}
45
46void DataLogger::stop() { mLogFile.close(); }
47
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;
53 }
54 mLogFile << '\n';
55 }
56}
57
58void DataLogger::logDataLine(Real time, Real data) {
59 if (!mEnabled)
60 return;
61
62 mLogFile << std::scientific << std::right << std::setw(14) << time;
63 mLogFile << ", " << std::right << std::setw(13) << data;
64 mLogFile << '\n';
65}
66
67void DataLogger::logDataLine(Real time, const Matrix &data) {
68 if (!mEnabled)
69 return;
70
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);
74 }
75 mLogFile << '\n';
76}
77
78void DataLogger::logDataLine(Real time, const MatrixComp &data) {
79 if (!mEnabled)
80 return;
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);
84 }
85 mLogFile << '\n';
86}
87
88void DataLogger::logPhasorNodeValues(Real time, const Matrix &data,
89 Int freqNum) {
90 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
91 std::vector<String> names;
92
93 Int harmonicOffset = data.rows() / freqNum;
94 Int complexOffset = harmonicOffset / 2;
95
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());
102 }
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());
108 }
109 }
110 setColumnNames(names);
111 }
112 logDataLine(time, data);
113}
114
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());
122 }
123 setColumnNames(names);
124 }
125 logDataLine(time, data);
126}
127
128void DataLogger::log(Real time, Int timeStepCount) {
129 if (!mEnabled || !(timeStepCount % mDownsampling == 0))
130 return;
131
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;
136 mLogFile << '\n';
137 }
138
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();
142 mLogFile << '\n';
143}
144
145void DataLogger::Step::execute(Real time, Int timeStepCount) {
146 mLogger.log(time, timeStepCount);
147}
148
149CPS::Task::Ptr DataLogger::getTask() {
150 return std::make_shared<DataLogger::Step>(*this);
151}