37 std::ifstream file(filename);
38 if (!file.is_open()) {
39 LOG_ERROR(
"Cannot open input file: {}", filename);
43 LOG_DEBUG(
"Reading IEEE Common Data Format: {}", filename);
50 std::vector<int> busID;
51 std::vector<std::string> busName;
52 std::vector<int> busType;
53 std::vector<double> V, delta, Pl, Ql, Pg, Qg, Qgmax, Qgmin, Gs, Bs;
55 std::vector<int> fromBus, toBus;
56 std::vector<double> R, X, G, B, tap;
58 std::map<std::string, std::string> busTypes;
64 std::map<std::string, int> busIndex;
66 while (std::getline(file, line)) {
67 std::string firstToken = strip(line.substr(0, 4));
69 if (line.find(
"BUS DATA") != std::string::npos) { section =
"bus";
LOG_DEBUG(
"Parsing BUS DATA section ...");
continue; }
70 if (line.find(
"BRANCH DATA") != std::string::npos) { section =
"branch";
LOG_DEBUG(
"Parsing BRANCH DATA section ...");
continue; }
71 if (line.find(
"-999") != std::string::npos) { section =
"";
continue; }
73 if (section ==
"bus" && !firstToken.empty() && std::all_of(firstToken.begin(), firstToken.end(), ::isdigit)) {
75 std::string
id = strip(line.substr(0, 4));
76 busIndex[id] = busCount;
77 busID.push_back(busCount);
78 busName.push_back(strip(line.substr(4, 11)));
79 std::string typeStr = strip(line.substr(24, 2));
80 busType.push_back(std::stoi(busTypes[typeStr]));
82 double vmag = std::stod(strip(line.substr(27, 6)));
83 V.push_back(vmag > 0.0 ? vmag : 1.0);
85 Pl.push_back(std::stod(strip(line.substr(40, 9))) / 100.0);
86 Ql.push_back(std::stod(strip(line.substr(49, 10))) / 100.0);
87 Pg.push_back(std::stod(strip(line.substr(59, 8))) / 100.0);
88 Qg.push_back(std::stod(strip(line.substr(67, 8))) / 100.0);
89 Qgmax.push_back(std::stod(strip(line.substr(90, 8))) / 100.0);
90 Qgmin.push_back(std::stod(strip(line.substr(98, 8))) / 100.0);
91 Gs.push_back(std::stod(strip(line.substr(106, 8))));
92 Bs.push_back(std::stod(strip(line.substr(114, 8))));
95 if (section ==
"branch" && !firstToken.empty() && std::all_of(firstToken.begin(), firstToken.end(), ::isdigit)) {
97 std::string from = strip(line.substr(0, 4));
98 std::string to = strip(line.substr(5, 4));
99 fromBus.push_back(busIndex[from]);
100 toBus.push_back(busIndex[to]);
101 R.push_back(std::stod(strip(line.substr(19, 10))));
102 X.push_back(std::stod(strip(line.substr(29, 10))));
104 B.push_back(std::stod(strip(line.substr(40, 10))));
105 std::string aStr = strip(line.substr(76, 6));
106 double aVal = aStr.empty() ? 0.0 : std::stod(aStr);
107 tap.push_back(aVal == 0.0 ? 1.0 : aVal);
111 int nBus = busID.size();
112 busData.
ID = Eigen::Map<Eigen::VectorXi>(busID.data(), nBus);
113 busData.
Type = Eigen::Map<Eigen::VectorXi>(busType.data(), nBus);
114 busData.
V = Eigen::Map<Eigen::VectorXd>(V.data(), nBus);
115 busData.
delta = Eigen::Map<Eigen::VectorXd>(delta.data(), nBus);
116 busData.
Pg = Eigen::Map<Eigen::VectorXd>(Pg.data(), nBus);
117 busData.
Qg = Eigen::Map<Eigen::VectorXd>(Qg.data(), nBus);
118 busData.
Pl = Eigen::Map<Eigen::VectorXd>(Pl.data(), nBus);
119 busData.
Ql = Eigen::Map<Eigen::VectorXd>(Ql.data(), nBus);
120 busData.
Qgmax = Eigen::Map<Eigen::VectorXd>(Qgmax.data(), nBus);
121 busData.
Qgmin = Eigen::Map<Eigen::VectorXd>(Qgmin.data(), nBus);
122 busData.
Gs = Eigen::Map<Eigen::VectorXd>(Gs.data(), nBus);
123 busData.
Bs = Eigen::Map<Eigen::VectorXd>(Bs.data(), nBus);
126 int nBranch = fromBus.size();
127 branchData.
From = Eigen::Map<Eigen::VectorXi>(fromBus.data(), nBranch);
128 branchData.
To = Eigen::Map<Eigen::VectorXi>(toBus.data(), nBranch);
129 branchData.
R = Eigen::Map<Eigen::VectorXd>(R.data(), nBranch);
130 branchData.
X = Eigen::Map<Eigen::VectorXd>(X.data(), nBranch);
131 branchData.
G = Eigen::Map<Eigen::VectorXd>(G.data(), nBranch);
132 branchData.
B = Eigen::Map<Eigen::VectorXd>(B.data(), nBranch);
135 LOG_DEBUG(
"IEEE CDF parsing complete: {} bus cards, {} branch cards", nBus, nBranch);