Aufgrund einer Wartung wird GitLab am 26.10. zwischen 8:00 und 9:00 Uhr kurzzeitig nicht zur Verfügung stehen. / Due to maintenance, GitLab will be temporarily unavailable on 26.10. between 8:00 and 9:00 am.

CSVReader.h 5.74 KB
Newer Older
1
2
/* Copyright 2017-2020 Institute for Automation of Complex Power Systems,
 *                     EONERC, RWTH Aachen University
Markus Mirz's avatar
Markus Mirz committed
3
 *
4
5
6
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
Markus Mirz's avatar
Markus Mirz committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 *********************************************************************************/

#pragma once

#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <experimental/filesystem>
#include <cps/Logger.h>
#include <cps/SystemTopology.h>
#include <cps/SP/SP_Ph1_Load.h>
#include <cps/DP/DP_Ph1_PQLoadCS.h>
#include <cps/DP/DP_Ph1_AvVoltageSourceInverterDQ.h>
#include <cps/SP/SP_Ph1_AvVoltageSourceInverterDQ.h>

namespace CPS {
	/// reads load profiles (csv files only) and assign them to the corresponding load object
	class CSVReader {
	private:
		/// Logger
		Logger::Log mSLog;
		/// path of load profile files (csv file)
		String mPath;
		/// list of load profile files with path
		std::list<std::experimental::filesystem::path> mFileList;
		/// assign pattern, used when the MANUAL mode is selected
		std::map <String, String> mAssignPattern;
37
38
		/// Skip first row if it has no digits at beginning
		Bool mSkipFirstRow = true;
Markus Mirz's avatar
Markus Mirz committed
39
40
41
42
43
44
45
46
47
48
49
50
51
52

	public:
		/// set load profile assigning pattern. AUTO for assigning load profile name (csv file name) to load object with the same name (mName)
		/// MANUAL for providing an assign pattern manually. see power flow example: CIM/CIGRE_MV_PowerFlowTest_LoadProfiles.cpp
		enum class Mode { AUTO, MANUAL };

		/*
		 Time Stamp Format.
         HHMMSS:  Hours : Minutes : Seconds, it be casted to the corresponding SECONDS.
         SECONDS: profiles recorded with total seconds.
         PVGEN: format comply with https://www.fein-aachen.org/projects/PVgenerator/
		*/
		enum class DataFormat { HHMMSS, SECONDS, HOURS, MINUTES };

53
		///
Markus Mirz's avatar
Markus Mirz committed
54
		CSVReader(String name, std::list<std::experimental::filesystem::path> path, Logger::Level logLevel);
55
		///
Markus Mirz's avatar
Markus Mirz committed
56
		CSVReader(String name, String path, Logger::Level logLevel);
57
		///
Markus Mirz's avatar
Markus Mirz committed
58
		CSVReader(String name, std::list<std::experimental::filesystem::path> path, std::map<String, String>& assignList, Logger::Level logLevel);
59
		///
Markus Mirz's avatar
Markus Mirz committed
60
61
62
63
64
		CSVReader(String name, String path, std::map<String, String>& assignList, Logger::Level logLevel);

		///	convert HH:MM:SS format timestamp into total seconds.
		///	e.g.: 00 : 01 : 00 -- > 60.
		Real time_format_convert(const String& time);
65
66
		/// Skip first row if it has no digits at beginning
		void doSkipFirstRow(Bool value = true) { mSkipFirstRow = value; }
67
68
		///
		MatrixRow csv2Eigen(const std::string& path);
Markus Mirz's avatar
Markus Mirz committed
69
70
71
72
73
74
75
76
77
78

		std::vector<PQData> readLoadProfileDP(std::experimental::filesystem::path file,
			Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
			CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);

		// void assignLoadProfilePF(std::vector<std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ>>& loads,
		// 	Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
		// 	CSVReader::Mode mode = CSVReader::Mode::AUTO,
		// 	CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);

79
80
81
82
		// void assignLoadProfileSP(std::vector<std::shared_ptr<CPS::SP::Ph1::AvVoltageSourceInverterDQ>>& loads,
		// 	Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
		// 	CSVReader::Mode mode = CSVReader::Mode::AUTO,
		// 	CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);
Markus Mirz's avatar
Markus Mirz committed
83
84
85
86
87
88
89
90

		void assignLoadProfileDP(std::vector<std::shared_ptr<CPS::DP::Ph1::AvVoltageSourceInverterDQ>>& loads,
			Real start_time = -1, Real time_step = 1, Real end_time = -1, Real scale_factor= 1,
			CSVReader::Mode mode = CSVReader::Mode::AUTO,
			CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);

		/// TODO : deprecate in the future
		/// read in load profile with time stamp format specified
91
		PowerProfile readLoadProfile(std::experimental::filesystem::path file,
Markus Mirz's avatar
Markus Mirz committed
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
			Real start_time = -1, Real time_step = 1, Real end_time = -1,
			CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);
		///
		std::vector<Real> readPQData (std::experimental::filesystem::path file,
			Real start_time = -1, Real time_step = 1, Real end_time = -1,
			CSVReader::DataFormat format = CSVReader::DataFormat::SECONDS);
		/// assign load profile to corresponding load object
		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);
		///
		void assignPVGeneration(SystemTopology& sys,
			Real start_time = -1, Real time_step = 1, Real end_time = -1,
			CSVReader::Mode mode = CSVReader::Mode::AUTO);

		/// interpolation for PQ data points
		PQData interpol_linear(std::map<Real, PQData>& data_PQ, Real x);

		/// interpolation for weighting factor data points
		Real interpol_linear(std::map<Real, Real>& data_wf, Real x);
	};


	// #### csv reader section
	class CSVRow {
	public:
		///
		String const& get(std::size_t index) const { return m_data[index]; }
		///
		Int size() const;
		///
		void readNextRow(std::istream& str);
	private:
		///
		std::vector<String> m_data;
	};

	class CSVReaderIterator {
	public:
		CSVReaderIterator(std::istream& str);
		CSVReaderIterator();

		CSVReaderIterator& next();
		CSVReaderIterator next(Int);
		CSVReaderIterator& step(Int time_step);
		CSVRow const& operator*() const { return m_row; };
		Bool operator==(CSVReaderIterator const& rhs) {
			return ((this == & rhs) || ((this->m_str == NULL) && (rhs.m_str == NULL)));
		}
		Bool operator!=(CSVReaderIterator const&rhs) {
			return !((*this) == rhs);
		}
	private:
		std::istream* m_str;
		CSVRow m_row;
	};
}