9 #include <dpsim-models/CSVReader.h>
13 MatrixRow CSVReader::csv2Eigen(
const String &path) {
14 std::ifstream inputFile;
17 std::vector<double> values;
19 while (std::getline(inputFile, line)) {
20 std::stringstream lineStream(line);
22 while (std::getline(lineStream, cell,
',')) {
23 values.push_back(std::stod(cell));
27 UInt columns = values.size() / rows;
28 return Eigen::Map<const MatrixRow>(values.data(), rows, columns);
31 void CSVRow::readNextRow(std::istream &str) {
33 std::getline(str, line);
35 std::stringstream lineStream(line);
39 while (std::getline(lineStream >> std::ws, cell,
',')) {
40 m_data.push_back(cell);
43 if (!lineStream && cell.empty()) {
49 int CSVRow::size()
const {
return m_data.size(); }
53 m_row.readNextRow(*m_str);
68 while (time_step != 0) {
70 m_row.readNextRow(*m_str);
80 CSVReaderIterator::CSVReaderIterator(std::istream &str)
81 : m_str(str.good() ? &str : NULL) {
85 CSVReaderIterator::CSVReaderIterator() : m_str(NULL) {}
87 CSVReader::CSVReader(CPS::String name, std::list<fs::path> paths,
88 CPS::Logger::Level logLevel) {
89 mSLog = Logger::get(name +
"_csvReader", logLevel);
91 for (
auto file : paths) {
92 if (file.string().find(
".csv") != std::string::npos) {
93 mFileList.push_back(file);
94 std::cout <<
"add " << file << std::endl;
99 CSVReader::CSVReader(CPS::String name, CPS::String path,
100 CPS::Logger::Level logLevel) {
101 mSLog = Logger::get(name +
"_csvReader", logLevel);
104 for (
const auto &entry : fs::directory_iterator(path)) {
105 mFileList.push_back(entry.path());
109 CSVReader::CSVReader(CPS::String name, CPS::String path,
110 std::map<String, String> &assignList,
111 CPS::Logger::Level logLevel)
114 mAssignPattern = assignList;
117 CSVReader::CSVReader(CPS::String name, std::list<fs::path> paths,
118 std::map<String, String> &assignList,
119 CPS::Logger::Level logLevel)
121 mAssignPattern = assignList;
124 CPS::Real CSVReader::time_format_convert(
const CPS::String &time) {
127 if (sscanf(time.c_str(),
"%d:%d:%d", &hh, &mm, &ss) >= 2) {
128 secs = hh * 3600 + mm * 60 + ss;
133 std::vector<PQData> CSVReader::readLoadProfileDP(fs::path file, Real start_time,
134 Real time_step, Real end_time,
136 CSVReader::DataFormat format) {
138 std::vector<PQData> load_profileDP;
139 std::ifstream csvfile(file);
143 if (mSkipFirstRow && !std::isdigit((*row_).get(0)[0])) {
151 Real presentTime = 0;
153 if ((start_time < 0) | (Int(presentTime) + 1 > Int(start_time)))
164 pq.p = std::stod((*row_).get(1)) * 1000 * scale_factor;
165 pq.q = std::stod((*row_).get(2)) * 1000 * scale_factor;
166 load_profileDP.push_back(pq);
167 if (end_time > 0 && presentTime > end_time)
174 presentTime = Int(presentTime) + 1;
176 std::cout <<
"CSV loaded." << std::endl;
177 return load_profileDP;
361 Real time_step, Real end_time,
362 CSVReader::DataFormat format) {
365 std::ifstream csvfile(file);
366 bool need_that_conversion = (format == DataFormat::HHMMSS) ?
true :
false;
367 bool data_with_weighting_factor =
false;
372 if (mSkipFirstRow && !std::isdigit((*loop).get(0)[0])) {
384 CPS::Real nextTime = (need_that_conversion)
386 : std::stod((*nextRow).get(0));
387 if ((*nextRow).size() == 2) {
388 data_with_weighting_factor =
true;
390 if ((start_time < 0) | (nextTime >= Int(start_time))) {
398 CPS::Real currentTime = (need_that_conversion)
400 : std::stod((*loop).get(0));
401 if (data_with_weighting_factor) {
402 Real wf = std::stod((*loop).get(1));
403 load_profile.weightingFactors.insert(
404 std::pair<Real, Real>(currentTime, wf));
408 pq.p = std::stod((*loop).get(1)) * 1000;
409 pq.q = std::stod((*loop).get(2)) * 1000;
410 load_profile.pqData.insert(std::pair<Real, PQData>(currentTime, pq));
413 if (end_time > 0 && currentTime > end_time)
416 std::vector<CPS::Real> times;
417 for (CPS::Real x_ = start_time; x_ <= end_time; x_ += time_step) {
421 for (
auto x : times) {
422 if (load_profile.pqData.find(x) == load_profile.pqData.end()) {
423 if (data_with_weighting_factor) {
425 load_profile.weightingFactors.insert(std::pair<Real, Real>(x, y));
428 load_profile.pqData.insert(std::pair<Real, PQData>(x, y));
437 std::vector<Real> CSVReader::readPQData(fs::path file, Real start_time,
438 Real time_step, Real end_time,
439 CSVReader::DataFormat format) {
441 std::vector<Real> p_data;
442 std::ifstream csvfile(file);
446 if (mSkipFirstRow && !std::isdigit((*row_).get(0)[0])) {
454 Real presentTime = 0;
456 if ((start_time < 0) | (Int(presentTime) + 1 > Int(start_time)))
465 p_data.push_back(std::stod((*row_).get(0)) * 1000);
466 if (end_time > 0 && presentTime > end_time)
473 presentTime = Int(presentTime) + 1;
475 std::cout <<
"CSV loaded." << std::endl;
480 Real time_step, Real end_time,
482 CSVReader::DataFormat format) {
485 case CSVReader::Mode::AUTO: {
487 if (std::shared_ptr<CPS::SP::Ph1::Load> load =
488 std::dynamic_pointer_cast<CPS::SP::Ph1::Load>(obj)) {
489 SPDLOG_LOGGER_INFO(mSLog,
490 "Comparing csv file names with load mRIDs ...");
491 String load_name = load->name();
492 for (
auto file : mFileList) {
493 String file_name = file.filename().string();
495 for (
auto &c : load_name)
497 for (
auto &c : file_name)
500 load_name.erase(remove_if(load_name.begin(), load_name.end(),
501 [](
char c) { return !isalnum(c); }),
503 file_name.erase(remove_if(file_name.begin(), file_name.end(),
504 [](
char c) { return !isalnum(c); }),
506 if (std::string(file_name.begin(), file_name.end() - 3)
507 .compare(load_name) == 0) {
510 load->use_profile =
true;
511 SPDLOG_LOGGER_INFO(mSLog,
"Assigned {} to {}",
512 file.filename().string(), load->name());
519 case CSVReader::Mode::MANUAL: {
520 Int LP_assigned_counter = 0;
521 Int LP_not_assigned_counter = 0;
522 SPDLOG_LOGGER_INFO(mSLog,
523 "Assigning load profiles with user defined pattern ...");
525 if (std::shared_ptr<CPS::SP::Ph1::Load> load =
526 std::dynamic_pointer_cast<CPS::SP::Ph1::Load>(obj)) {
527 std::map<String, String>::iterator file =
528 mAssignPattern.find(load->name());
529 if (file == mAssignPattern.end()) {
530 std::cout << load->name() <<
" has no profile given." << std::endl;
531 SPDLOG_LOGGER_INFO(mSLog,
"{} has no profile given.", load->name());
532 LP_not_assigned_counter++;
537 time_step, end_time);
538 load->use_profile =
true;
539 std::cout <<
" Assigned " << file->second <<
" to " << load->name()
541 SPDLOG_LOGGER_INFO(mSLog,
"Assigned {}.csv to {}", file->second,
543 LP_assigned_counter++;
546 SPDLOG_LOGGER_INFO(mSLog,
547 "Assigned profiles for {} loads, {} not assigned.",
548 LP_assigned_counter, LP_not_assigned_counter);
552 throw std::invalid_argument(
"Load profile assign mode error");
560 std::map<Real, PQData>::const_iterator entry = pqData.upper_bound(x);
563 if (entry == pqData.end()) {
564 return (--entry)->second;
566 if (entry == pqData.begin()) {
567 return entry->second;
569 std::map<Real, PQData>::const_iterator prev = entry;
572 const CPS::Real delta = (x - prev->first) / (entry->first - prev->first);
574 y.p = delta * entry->second.p + (1 - delta) * prev->second.p;
575 y.q = delta * entry->second.q + (1 - delta) * prev->second.q;
582 std::map<Real, Real>::const_iterator entry = weightingFactors.upper_bound(x);
585 if (entry == weightingFactors.end()) {
586 return (--entry)->second;
588 if (entry == weightingFactors.begin()) {
589 return entry->second;
591 std::map<Real, Real>::const_iterator prev = entry;
594 const CPS::Real delta = (x - prev->first) / (entry->first - prev->first);
596 y = delta * entry->second + (1 - delta) * prev->second;
reads load profiles (csv files only) and assign them to the corresponding load object
PowerProfile readLoadProfile(fs::path file, Real start_time=-1, Real time_step=1, Real end_time=-1, CSVReader::DataFormat format=CSVReader::DataFormat::SECONDS)
PQData interpol_linear(std::map< Real, PQData > &data_PQ, Real x)
interpolation for PQ data points
void assignLoadProfile(SystemTopology &sys, Real start_time=-1, Real time_step=1, Real end_time=-1, CSVReader::Mode mode=CSVReader::Mode::AUTO, CSVReader::DataFormat format=CSVReader::DataFormat::SECONDS)
assign load profile to corresponding load object
Real time_format_convert(const String &time)
IdentifiedObject::List mComponents
List of network components.