11 #include <dpsim-models/Logger.h>
12 #include <dpsim/DataLogger.h>
14 using namespace DPsim;
16 DataLogger::DataLogger(Bool enabled)
17 : mLogFile(), mEnabled(enabled), mDownsampling(1) {
18 mLogFile.setstate(std::ios_base::badbit);
21 DataLogger::DataLogger(String name, Bool enabled, UInt downsampling)
22 : mName(name), mEnabled(enabled), mDownsampling(downsampling) {
26 mFilename = CPS::Logger::logDir() +
"/" + name +
".csv";
28 if (mFilename.has_parent_path() && !fs::exists(mFilename.parent_path()))
29 fs::create_directory(mFilename.parent_path());
34 void DataLogger::open() {
36 std::ofstream(mFilename, std::ios_base::out | std::ios_base::trunc);
37 if (!mLogFile.is_open()) {
39 std::cerr <<
"Cannot open log file " << mFilename << std::endl;
44 void DataLogger::close() { mLogFile.close(); }
46 void DataLogger::setColumnNames(std::vector<String> names) {
47 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
48 mLogFile << std::right << std::setw(14) <<
"time";
49 for (
auto name : names) {
50 mLogFile <<
", " << std::right << std::setw(13) << name;
56 void DataLogger::logDataLine(Real time, Real data) {
60 mLogFile << std::scientific << std::right << std::setw(14) << time;
61 mLogFile <<
", " << std::right << std::setw(13) << data;
65 void DataLogger::logDataLine(Real time,
const Matrix &data) {
69 mLogFile << std::scientific << std::right << std::setw(14) << time;
70 for (Int i = 0; i < data.rows(); ++i) {
71 mLogFile <<
", " << std::right << std::setw(13) << data(i, 0);
76 void DataLogger::logDataLine(Real time,
const MatrixComp &data) {
79 mLogFile << std::scientific << std::right << std::setw(14) << time;
80 for (Int i = 0; i < data.rows(); ++i) {
81 mLogFile <<
", " << std::right << std::setw(13) << data(i, 0);
86 void DataLogger::logPhasorNodeValues(Real time,
const Matrix &data,
88 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
89 std::vector<String> names;
91 Int harmonicOffset = data.rows() / freqNum;
92 Int complexOffset = harmonicOffset / 2;
94 for (Int freq = 0; freq < freqNum; ++freq) {
95 for (Int node = 0; node < complexOffset; ++node) {
96 std::stringstream name;
97 name <<
"n" << std::setfill(
'0') << std::setw(5) << node <<
"f"
98 << std::setfill(
'0') << std::setw(2) << freq <<
".re";
99 names.push_back(name.str());
101 for (Int node = 0; node < complexOffset; ++node) {
102 std::stringstream name;
103 name <<
"n" << std::setfill(
'0') << std::setw(5) << node <<
"f"
104 << std::setfill(
'0') << std::setw(2) << freq <<
".im";
105 names.push_back(name.str());
108 setColumnNames(names);
110 logDataLine(time, data);
113 void DataLogger::logEMTNodeValues(Real time,
const Matrix &data) {
114 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
115 std::vector<String> names;
116 for (Int i = 0; i < data.rows(); ++i) {
117 std::stringstream name;
118 name <<
"node" << std::setfill(
'0') << std::setw(5) << i;
119 names.push_back(name.str());
121 setColumnNames(names);
123 logDataLine(time, data);
126 void DataLogger::log(Real time, Int timeStepCount) {
127 if (!mEnabled || !(timeStepCount % mDownsampling == 0))
130 if (mLogFile.tellp() == std::ofstream::pos_type(0)) {
131 mLogFile << std::right << std::setw(14) <<
"time";
132 for (
auto it : mAttributes)
133 mLogFile <<
", " << std::right << std::setw(13) << it.first;
137 mLogFile << std::scientific << std::right << std::setw(14) << time;
138 for (
auto it : mAttributes)
139 mLogFile <<
", " << std::right << std::setw(13) << it.second->toString();
143 void DataLogger::Step::execute(Real time, Int timeStepCount) {
144 mLogger.log(time, timeStepCount);
147 CPS::Task::Ptr DataLogger::getTask() {
148 return std::make_shared<DataLogger::Step>(*
this);
151 void DataLogger::logAttribute(
const std::vector<String> &name,
153 if (
auto attrMatrix =
155 if ((**attrMatrix).rows() == 1 && (**attrMatrix).cols() == 1) {
156 logAttribute(name[0], attrMatrix->deriveCoeff<CPS::Real>(0, 0));
157 }
else if ((**attrMatrix).cols() == 1) {
158 for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
159 logAttribute(name[k], attrMatrix->deriveCoeff<CPS::Real>(k, 0));
162 for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
163 for (UInt l = 0; l < (**attrMatrix).cols(); ++l) {
164 logAttribute(name[k * (**attrMatrix).cols() + l],
165 attrMatrix->deriveCoeff<CPS::Real>(k, l));
169 }
else if (
auto attrMatrix =
172 if ((**attrMatrix).rows() == 1 && (**attrMatrix).cols() == 1) {
173 logAttribute(name[0], attrMatrix->deriveCoeff<CPS::Complex>(0, 0));
174 }
else if ((**attrMatrix).cols() == 1) {
175 for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
176 logAttribute(name[k], attrMatrix->deriveCoeff<CPS::Complex>(k, 0));
179 for (UInt k = 0; k < (**attrMatrix).rows(); ++k) {
180 for (UInt l = 0; l < (**attrMatrix).cols(); ++l) {
181 logAttribute(name[k * (**attrMatrix).cols() + l],
182 attrMatrix->deriveCoeff<CPS::Complex>(k, l));
190 UInt rowsMax, UInt colsMax) {
193 mAttributes[name] = attrReal;
196 mAttributes[name +
".re"] = attrComp->deriveReal();
197 mAttributes[name +
".im"] = attrComp->deriveImag();
198 }
else if (
auto attrMatrix =
201 UInt rows =
static_cast<UInt
>((**attrMatrix).rows());
202 UInt cols =
static_cast<UInt
>((**attrMatrix).cols());
203 if (rowsMax == 0 || rowsMax > rows)
205 if (colsMax == 0 || colsMax > cols)
207 if (rows == 1 && cols == 1) {
208 mAttributes[name] = attrMatrix->deriveCoeff<Real>(0, 0);
209 }
else if (cols == 1) {
210 for (UInt k = 0; k < rowsMax; ++k) {
211 mAttributes[name +
"_" + std::to_string(k)] =
212 attrMatrix->deriveCoeff<Real>(k, 0);
215 for (UInt k = 0; k < rowsMax; ++k) {
216 for (UInt l = 0; l < colsMax; ++l) {
217 mAttributes[name +
"_" + std::to_string(k) +
"_" +
218 std::to_string(l)] = attrMatrix->deriveCoeff<Real>(k, l);
222 }
else if (
auto attrMatrix =
225 UInt rows =
static_cast<UInt
>((**attrMatrix).rows());
226 UInt cols =
static_cast<UInt
>((**attrMatrix).cols());
227 if (rowsMax == 0 || rowsMax > rows)
229 if (colsMax == 0 || colsMax > cols)
231 if (rows == 1 && cols == 1) {
232 mAttributes[name +
".re"] =
233 attrMatrix->deriveCoeff<Complex>(0, 0)->deriveReal();
234 mAttributes[name +
".im"] =
235 attrMatrix->deriveCoeff<Complex>(0, 0)->deriveImag();
236 }
else if (cols == 1) {
237 for (UInt k = 0; k < rowsMax; ++k) {
238 mAttributes[name +
"_" + std::to_string(k) +
".re"] =
239 attrMatrix->deriveCoeff<Complex>(k, 0)->deriveReal();
240 mAttributes[name +
"_" + std::to_string(k) +
".im"] =
241 attrMatrix->deriveCoeff<Complex>(k, 0)->deriveImag();
244 for (UInt k = 0; k < rowsMax; ++k) {
245 for (UInt l = 0; l < colsMax; ++l) {
246 mAttributes[name +
"_" + std::to_string(k) +
"_" + std::to_string(l) +
248 attrMatrix->deriveCoeff<Complex>(k, l)->deriveReal();
249 mAttributes[name +
"_" + std::to_string(k) +
"_" + std::to_string(l) +
251 attrMatrix->deriveCoeff<Complex>(k, l)->deriveImag();
256 mAttributes[name] = attr;