7 #include "dpsim-models/Attribute.h"
10 #include <dpsim-models/Logger.h>
11 #include <dpsim/RealTimeDataLogger.h>
14 using namespace DPsim;
16 RealTimeDataLogger::RealTimeDataLogger(std::filesystem::path &filename,
size_t rowNumber)
17 :
DataLoggerInterface(), mFilename(filename), mRowNumber(rowNumber), mCurrentRow(0), mCurrentAttribute(0), mAttributeData() {}
19 RealTimeDataLogger::RealTimeDataLogger(std::filesystem::path &filename, Real finalTime, Real timeStep)
20 :
DataLoggerInterface(), mFilename(filename), mRowNumber((finalTime / timeStep + 0.5)), mCurrentRow(0), mCurrentAttribute(0), mAttributeData() {}
22 void RealTimeDataLogger::start() {
23 double mb_size =
static_cast<double>(mRowNumber) * (mAttributes.size() + 1) *
sizeof(Real);
24 auto log = CPS::Logger::get(
"RealTimeDataLogger", CPS::Logger::Level::off, CPS::Logger::Level::info);
25 log->info(
"Preallocating memory for real-time data logger: {} rows for {} attributes ({} MB)", mRowNumber, mAttributes.size(), mb_size / (1024 * 1024));
27 mAttributeData.resize(mRowNumber);
28 for (
auto &it : mAttributeData) {
30 it.resize(mAttributes.size() + 1);
34 void RealTimeDataLogger::stop() {
35 auto mLogFile = std::ofstream(mFilename, std::ios_base::out | std::ios_base::trunc);
36 if (!mLogFile.is_open()) {
37 throw std::runtime_error(
"Cannot open log file " + mFilename.string());
40 mLogFile << std::right << std::setw(14) <<
"time";
41 for (
auto it : mAttributes)
42 mLogFile <<
", " << std::right << std::setw(13) << it.first;
45 for (
auto row : mAttributeData) {
46 mLogFile << std::scientific << std::right << std::setw(14) << row[0];
47 for (
size_t i = 1; i < row.size(); ++i)
48 mLogFile <<
", " << std::right << std::setw(13) << row[i];
54 void RealTimeDataLogger::log(Real time, Int timeStepCount) {
55 mCurrentRow = timeStepCount;
56 if (timeStepCount < 0 ||
static_cast<size_t>(timeStepCount) >= mRowNumber) {
57 throw std::runtime_error(
"RealTimeDataLogger: timeStepCount out of bounds. Please verify the logger was initialized correctly.");
59 if (mAttributeData.size() != mRowNumber || mAttributeData[mCurrentRow].size() != mAttributes.size() + 1) {
60 throw std::runtime_error(
"RealTimeDataLogger: Attribute data size mismatch");
62 mAttributeData[mCurrentRow][0] = time;
63 mCurrentAttribute = 1;
65 for (
auto it : mAttributes) {
66 if (it.second->getType() ==
typeid(Real)) {
67 mAttributeData[mCurrentRow][mCurrentAttribute++] = **std::dynamic_pointer_cast<std::shared_ptr<CPS::Attribute<Real>>>(it.second.getPtr());
68 }
else if (it.second->getType() ==
typeid(Int)) {
69 mAttributeData[mCurrentRow][mCurrentAttribute++] = **std::dynamic_pointer_cast<std::shared_ptr<CPS::Attribute<Int>>>(it.second.getPtr());
74 void RealTimeDataLogger::Step::execute(Real time, Int timeStepCount) { mLogger.log(time, timeStepCount); }
76 CPS::Task::Ptr RealTimeDataLogger::getTask() {
return std::make_shared<RealTimeDataLogger::Step>(*
this); }