61 std::ifstream file(filename);
62 if (!file.is_open()) {
63 LOG_ERROR(
"Cannot open input file: {}", filename);
67 LOG_DEBUG(
"Reading PSS/E Raw Format: {}", filename);
71 std::getline(file, line);
77 if (hdr.size() >= 2) sbase = std::stod(hdr[1]);
78 if (hdr.size() >= 3) version = std::stoi(hdr[2]);
80 LOG_DEBUG(
"PSS/E RAW format version {} detected (SBASE = {:.2f} MVA)", version, sbase);
82 if (version != 32 && version != 33) {
83 LOG_WARN(
"PSS/E version {} is not explicitly supported. Attempting to parse as v{}.",
84 version, (version >= 33 ? 33 : 32));
88 std::string title1, title2;
89 std::getline(file, title1);
90 std::getline(file, title2);
91 LOG_DEBUG(
"PSS/E case: {}", strip(title1));
96 std::vector<int> busID;
97 std::vector<std::string> busName;
98 std::vector<int> busType;
99 std::vector<double> V, delta_vec;
101 std::map<int, int> busIndex;
104 while (std::getline(file, line)) {
108 if (f.size() < 9)
continue;
111 int origID = std::stoi(f[0]);
112 busIndex[origID] = busCount;
114 busID.push_back(busCount);
115 busName.push_back(stripQuotes(f[1]));
117 int ide = std::stoi(f[3]);
120 case 3: type = 1;
break;
121 case 2: type = 2;
break;
122 default: type = 3;
break;
124 busType.push_back(type);
126 double vmag = std::stod(f[7]);
127 V.push_back(vmag > 0.0 ? vmag : 1.0);
128 delta_vec.push_back(0.0);
135 std::vector<double> Pl(nBus, 0.0), Ql(nBus, 0.0);
136 std::vector<double> Pg(nBus, 0.0), Qg(nBus, 0.0);
137 std::vector<double> Qgmax(nBus, 0.0), Qgmin(nBus, 0.0);
138 std::vector<double> Gs(nBus, 0.0), Bs(nBus, 0.0);
142 while (std::getline(file, line)) {
146 if (f.size() < 8)
continue;
148 int origBus = std::stoi(f[0]);
149 int status = std::stoi(f[2]);
150 if (status == 0)
continue;
152 int idx = busIndex[origBus] - 1;
153 Pl[idx] += std::stod(f[5]) / sbase;
154 Ql[idx] += std::stod(f[6]) / sbase;
158 while (std::getline(file, line)) {
162 if (f.size() < 4)
continue;
164 int origBus = std::stoi(f[0]);
165 int status = std::stoi(f[1]);
166 if (status == 0)
continue;
168 int idx = busIndex[origBus] - 1;
169 Gs[idx] += std::stod(f[2]) / sbase;
170 Bs[idx] += std::stod(f[3]) / sbase;
175 while (std::getline(file, line)) {
179 if (f.size() < 10)
continue;
181 int origBus = std::stoi(f[0]);
182 int idx = busIndex[origBus] - 1;
184 Pg[idx] += std::stod(f[2]) / sbase;
185 Qg[idx] += std::stod(f[3]) / sbase;
186 Qgmax[idx] += std::stod(f[4]) / sbase;
187 Qgmin[idx] += std::stod(f[5]) / sbase;
190 double vs = std::stod(f[6]);
191 if (busType[idx] == 1 || busType[idx] == 2) {
198 std::vector<int> fromBus, toBus;
199 std::vector<double> R_vec, X_vec, G_vec, B_vec, tap_vec;
201 while (std::getline(file, line)) {
205 if (f.size() < 6)
continue;
207 int from = std::stoi(f[0]);
208 int to = std::abs(std::stoi(f[1]));
210 fromBus.push_back(busIndex[from]);
211 toBus.push_back(busIndex[to]);
212 R_vec.push_back(std::stod(f[3]));
213 X_vec.push_back(std::stod(f[4]));
214 G_vec.push_back(0.0);
215 B_vec.push_back(std::stod(f[5]));
216 tap_vec.push_back(1.0);
226 while (std::getline(file, line)) {
230 if (f1.size() < 5)
continue;
232 int I = std::stoi(f1[0]);
233 int J = std::stoi(f1[1]);
234 int K = std::stoi(f1[2]);
236 int cz = (f1.size() >= 6) ? std::stoi(f1[5]) : 1;
239 std::getline(file, line);
242 double r12 = (f2.size() >= 1) ? std::stod(f2[0]) : 0.0;
243 double x12 = (f2.size() >= 2) ? std::stod(f2[1]) : 0.0;
244 double sbase12 = (f2.size() >= 3) ? std::stod(f2[2]) : sbase;
247 if (cz == 2 && sbase12 > 0.0) {
248 r12 *= sbase / sbase12;
249 x12 *= sbase / sbase12;
253 std::getline(file, line);
255 double windv1 = (f3.size() >= 1) ? std::stod(f3[0]) : 1.0;
258 std::getline(file, line);
262 std::getline(file, line);
263 LOG_WARN(
"3-winding transformer ({}-{}-{}) encountered, skipping.", I, J, K);
267 fromBus.push_back(busIndex[I]);
268 toBus.push_back(busIndex[J]);
269 R_vec.push_back(r12);
270 X_vec.push_back(x12);
271 G_vec.push_back(0.0);
272 B_vec.push_back(0.0);
273 double tapVal = (windv1 == 0.0) ? 1.0 : windv1;
274 tap_vec.push_back(tapVal);
277 busData.
ID = Eigen::Map<Eigen::VectorXi>(busID.data(), nBus);
278 busData.
Type = Eigen::Map<Eigen::VectorXi>(busType.data(), nBus);
279 busData.
V = Eigen::Map<Eigen::VectorXd>(V.data(), nBus);
280 busData.
delta = Eigen::Map<Eigen::VectorXd>(delta_vec.data(), nBus);
281 busData.
Pg = Eigen::Map<Eigen::VectorXd>(Pg.data(), nBus);
282 busData.
Qg = Eigen::Map<Eigen::VectorXd>(Qg.data(), nBus);
283 busData.
Pl = Eigen::Map<Eigen::VectorXd>(Pl.data(), nBus);
284 busData.
Ql = Eigen::Map<Eigen::VectorXd>(Ql.data(), nBus);
285 busData.
Qgmax = Eigen::Map<Eigen::VectorXd>(Qgmax.data(), nBus);
286 busData.
Qgmin = Eigen::Map<Eigen::VectorXd>(Qgmin.data(), nBus);
287 busData.
Gs = Eigen::Map<Eigen::VectorXd>(Gs.data(), nBus);
288 busData.
Bs = Eigen::Map<Eigen::VectorXd>(Bs.data(), nBus);
291 int nBranch =
static_cast<int>(fromBus.size());
292 branchData.
From = Eigen::Map<Eigen::VectorXi>(fromBus.data(), nBranch);
293 branchData.
To = Eigen::Map<Eigen::VectorXi>(toBus.data(), nBranch);
294 branchData.
R = Eigen::Map<Eigen::VectorXd>(R_vec.data(), nBranch);
295 branchData.
X = Eigen::Map<Eigen::VectorXd>(X_vec.data(), nBranch);
296 branchData.
G = Eigen::Map<Eigen::VectorXd>(G_vec.data(), nBranch);
297 branchData.
B = Eigen::Map<Eigen::VectorXd>(B_vec.data(), nBranch);
300 LOG_DEBUG(
"PSS/E v{} file parsed: {} buses, {} branches (incl. transformers)",
301 version, nBus, nBranch);