Skip to content

Commit df6e545

Browse files
authored
Rework RAO API to be more pythonic (#1126)
* Allow loading rao result from file for monitoring * Add glsk purpose * Wrap Crac and GLSK in python object * Put all parameters in the run method Signed-off-by: Bertrand Rix <[email protected]>
1 parent 3e98bdb commit df6e545

File tree

15 files changed

+458
-161
lines changed

15 files changed

+458
-161
lines changed

cpp/powsybl-cpp/powsybl-cpp.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2085,19 +2085,27 @@ JavaHandle getCrac(const JavaHandle& raoContext) {
20852085
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::getCrac, raoContext);
20862086
}
20872087

2088-
JavaHandle runRaoWithParameters(const JavaHandle& networkHandle, const JavaHandle& raoHandle, const RaoParameters& parameters, const std::string& raoProvider) {
2088+
void setLoopFlowGlsk(const JavaHandle& raoContext, const JavaHandle& glsk) {
2089+
pypowsybl::PowsyblCaller::get()->callJava(::setLoopFlowGlsk, raoContext, glsk);
2090+
}
2091+
2092+
void setMonitoringGlsk(const JavaHandle& raoContext, const JavaHandle& glsk) {
2093+
pypowsybl::PowsyblCaller::get()->callJava(::setMonitoringGlsk, raoContext, glsk);
2094+
}
2095+
2096+
JavaHandle runRaoWithParameters(const JavaHandle& networkHandle, const JavaHandle& cracHandle, const JavaHandle& raoHandle, const RaoParameters& parameters, const std::string& raoProvider) {
20892097
auto c_parameters = parameters.to_c_struct();
2090-
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runRao, networkHandle, raoHandle, c_parameters.get(), (char*) raoProvider.data());
2098+
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runRao, networkHandle, cracHandle, raoHandle, c_parameters.get(), (char*) raoProvider.data());
20912099
}
20922100

2093-
JavaHandle runVoltageMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider) {
2101+
JavaHandle runVoltageMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& cracHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider) {
20942102
auto c_loadflow_parameters = parameters.to_c_struct();
2095-
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runVoltageMonitoring, networkHandle, resultHandle, contextHandle, c_loadflow_parameters.get(), (char *) provider.data());
2103+
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runVoltageMonitoring, networkHandle, resultHandle, cracHandle, contextHandle, c_loadflow_parameters.get(), (char *) provider.data());
20962104
}
20972105

2098-
JavaHandle runAngleMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider) {
2106+
JavaHandle runAngleMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& cracHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider) {
20992107
auto c_loadflow_parameters = parameters.to_c_struct();
2100-
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runAngleMonitoring, networkHandle, resultHandle, contextHandle, c_loadflow_parameters.get(), (char *) provider.data());
2108+
return pypowsybl::PowsyblCaller::get()->callJava<JavaHandle>(::runAngleMonitoring, networkHandle, resultHandle, cracHandle, contextHandle, c_loadflow_parameters.get(), (char *) provider.data());
21012109
}
21022110

21032111

cpp/powsybl-cpp/powsybl-cpp.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,10 +1029,13 @@ SeriesArray* getCostResults(const JavaHandle& cracHandle, const JavaHandle& resu
10291029
std::vector<std::string> getVirtualCostNames(const JavaHandle& resultHandle);
10301030
SeriesArray* getVirtualCostsResults(const JavaHandle& cracHandle, const JavaHandle& resultHandle, const std::string& virtualCostName);
10311031

1032+
void setLoopFlowGlsk(const JavaHandle& raoContext, const JavaHandle& glsk);
1033+
void setMonitoringGlsk(const JavaHandle& raoContext, const JavaHandle& glsk);
1034+
10321035
JavaHandle createDefaultRaoParameters();
1033-
JavaHandle runRaoWithParameters(const JavaHandle& networkHandle, const JavaHandle& raoHandle, const RaoParameters& parameters, const std::string& raoProvider);
1034-
JavaHandle runVoltageMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider);
1035-
JavaHandle runAngleMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider);
1036+
JavaHandle runRaoWithParameters(const JavaHandle& networkHandle, const JavaHandle& cracHandle, const JavaHandle& raoHandle, const RaoParameters& parameters, const std::string& raoProvider);
1037+
JavaHandle runVoltageMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& cracHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider);
1038+
JavaHandle runAngleMonitoring(const JavaHandle& networkHandle, const JavaHandle& resultHandle, const JavaHandle& cracHandle, const JavaHandle& contextHandle, const LoadFlowParameters& parameters, const std::string& provider);
10361039

10371040
JavaHandle createGrid2opBackend(const JavaHandle& networkHandle, bool considerOpenBranchReactiveFlow, bool checkIsolatedAndDisconnectedInjections, int busesPerVoltageLevel, bool connectAllElementsToFirstBus);
10381041
void freeGrid2opBackend(const JavaHandle& backendHandle);

cpp/pypowsybl-cpp/bindings.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@ pypowsybl::JavaHandle loadNetworkFromBinaryBuffersPython(std::vector<py::buffer>
2626

2727
py::bytes saveNetworkToBinaryBufferPython(const pypowsybl::JavaHandle& network, const std::string& format, const std::map<std::string, std::string>& parameters, pypowsybl::JavaHandle* reportNode);
2828

29-
void setCracSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& crac);
30-
void setGlskSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& glsk);
29+
pypowsybl::JavaHandle loadCracSource(const pypowsybl::JavaHandle& networkHandle, const py::buffer& crac);
30+
pypowsybl::JavaHandle loadGlskSource(const py::buffer& glsk);
31+
pypowsybl::JavaHandle loadResultSource(const pypowsybl::JavaHandle& cracHandle, const py::buffer& result);
3132
pypowsybl::RaoParameters* loadRaoParametersFromBuffer(const py::buffer& parameters);
3233

3334
py::bytes saveRaoParametersToBinaryBuffer(const pypowsybl::RaoParameters& rao_parameters);
@@ -1272,12 +1273,15 @@ PYBIND11_MODULE(_pypowsybl, m) {
12721273

12731274
m.def("create_rao", &pypowsybl::createRao, "Create rao context");
12741275
m.def("run_rao", &pypowsybl::runRaoWithParameters, py::call_guard<py::gil_scoped_release>(), "Run a rao from buffered inputs",
1275-
py::arg("network"), py::arg("rao_context"), py::arg("parameters"), py::arg("rao_provider"));
1276-
m.def("set_crac_source", ::setCracSource, py::call_guard<py::gil_scoped_release>(), "Set crac source",
1277-
py::arg("network"), py::arg("rao_context"), py::arg("crac_source"));
1278-
m.def("set_glsk_source", ::setGlskSource, py::call_guard<py::gil_scoped_release>(), "Set glsk source",
1279-
py::arg("network"), py::arg("rao_context"), py::arg("glsk_source"));
1276+
py::arg("network"), py::arg("crac"), py::arg("rao_context"), py::arg("parameters"), py::arg("rao_provider"));
1277+
m.def("load_crac_source", ::loadCracSource, py::call_guard<py::gil_scoped_release>(), "Set crac source",
1278+
py::arg("network"), py::arg("crac_source"));
1279+
m.def("load_glsk_source", ::loadGlskSource, py::call_guard<py::gil_scoped_release>(), "Set glsk source", py::arg("glsk_source"));
12801280
m.def("get_crac", &pypowsybl::getCrac, "Get crac associated to the rao context", py::arg("rao_context"));
1281+
m.def("set_loopflow_glsk", &pypowsybl::setLoopFlowGlsk, "Set the glsk used for loop flow in rao run", py::arg("rao_context"), py::arg("glsk"));
1282+
m.def("set_monitoring_glsk", &pypowsybl::setMonitoringGlsk, "Set the glsk used for the rao angle monitoring", py::arg("rao_context"), py::arg("glsk"));
1283+
m.def("load_result_source", ::loadResultSource, py::call_guard<py::gil_scoped_release>(), "Load result source",
1284+
py::arg("crac"), py::arg("result_source"));
12811285
m.def("create_default_rao_parameters", &pypowsybl::createDefaultRaoParameters, "Create a default rao parameter");
12821286
m.def("load_rao_parameters", ::loadRaoParametersFromBuffer, "Load rao parameters from a buffer", py::arg("parameters_buffer"));
12831287
m.def("serialize_rao_parameters", ::saveRaoParametersToBinaryBuffer, "Serialize rao parameters to a buffer", py::arg("rao_parameters"));
@@ -1293,8 +1297,8 @@ PYBIND11_MODULE(_pypowsybl, m) {
12931297
m.def("get_cost_results", &pypowsybl::getCostResults, "Get rao cost results", py::arg("crac"), py::arg("rao_result"));
12941298
m.def("get_virtual_cost_names", &pypowsybl::getVirtualCostNames, "Get virtual cost names", py::arg("rao_result"));
12951299
m.def("get_virtual_cost_results", &pypowsybl::getVirtualCostsResults, "Get rao virtual cost results", py::arg("crac"), py::arg("rao_result"), py::arg("virtual_cost_name"));
1296-
m.def("run_voltage_monitoring", &pypowsybl::runVoltageMonitoring, py::call_guard<py::gil_scoped_release>(), "Run voltage monitoring", py::arg("network"), py::arg("result_handle"), py::arg("context_handle"), py::arg("load_flow_parameters"), py::arg("provider"));
1297-
m.def("run_angle_monitoring", &pypowsybl::runAngleMonitoring, py::call_guard<py::gil_scoped_release>(), "Run angle monitoring", py::arg("network"), py::arg("result_handle"), py::arg("context_handle"), py::arg("load_flow_parameters"), py::arg("provider"));
1300+
m.def("run_voltage_monitoring", &pypowsybl::runVoltageMonitoring, py::call_guard<py::gil_scoped_release>(), "Run voltage monitoring", py::arg("network"), py::arg("result_handle"), py::arg("crac_handle"), py::arg("context_handle"), py::arg("load_flow_parameters"), py::arg("provider"));
1301+
m.def("run_angle_monitoring", &pypowsybl::runAngleMonitoring, py::call_guard<py::gil_scoped_release>(), "Run angle monitoring", py::arg("network"), py::arg("result_handle"), py::arg("crac_handle"), py::arg("context_handle"), py::arg("load_flow_parameters"), py::arg("provider"));
12981302

12991303
py::enum_<Grid2opStringValueType>(m, "Grid2opStringValueType")
13001304
.value("VOLTAGE_LEVEL_NAME", Grid2opStringValueType::VOLTAGE_LEVEL_NAME)
@@ -1461,17 +1465,20 @@ py::bytes saveNetworkToBinaryBufferPython(const pypowsybl::JavaHandle& network,
14611465
return bytes;
14621466
}
14631467

1464-
void setCracSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& crac) {
1468+
pypowsybl::JavaHandle loadCracSource(const pypowsybl::JavaHandle& networkHandle, const py::buffer& crac) {
14651469
py::buffer_info cracInfo = crac.request();
1466-
pypowsybl::PowsyblCaller::get()->callJava<>(::setCracBufferedSource,
1467-
networkHandle, raoHandle, static_cast<char*>(cracInfo.ptr), cracInfo.size);
1470+
return pypowsybl::PowsyblCaller::get()->callJava<pypowsybl::JavaHandle>(::loadCracBufferedSource, networkHandle, static_cast<char*>(cracInfo.ptr), cracInfo.size);
14681471
}
14691472

1470-
void setGlskSource(const pypowsybl::JavaHandle& networkHandle, const pypowsybl::JavaHandle& raoHandle, const py::buffer& glsk) {
1473+
pypowsybl::JavaHandle loadGlskSource(const py::buffer& glsk) {
14711474
py::buffer_info glskInfo = glsk.request();
1472-
pypowsybl::PowsyblCaller::get()->callJava<>(::setGlskBufferedSource,
1473-
networkHandle, raoHandle,
1474-
static_cast<char*>(glskInfo.ptr), glskInfo.size);
1475+
return pypowsybl::PowsyblCaller::get()->callJava<pypowsybl::JavaHandle>(::loadGlskBufferedSource, static_cast<char*>(glskInfo.ptr), glskInfo.size);
1476+
}
1477+
1478+
pypowsybl::JavaHandle loadResultSource(const pypowsybl::JavaHandle& cracHandle, const py::buffer& result) {
1479+
py::buffer_info resultInfo = result.request();
1480+
return pypowsybl::PowsyblCaller::get()->callJava<pypowsybl::JavaHandle>(::loadResultFromBufferedSource,
1481+
cracHandle, static_cast<char*>(resultInfo.ptr), resultInfo.size);
14751482
}
14761483

14771484
py::bytes saveRaoResultsToBinaryBuffer(const pypowsybl::JavaHandle& raoResult, const pypowsybl::JavaHandle& crac) {
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
{
2+
"type" : "RAO_RESULT",
3+
"version" : "1.8",
4+
"info" : "Generated by Open RAO https://powsybl.readthedocs.io/projects/openrao",
5+
"computationStatus" : "default",
6+
"executionDetails" : "The RAO only went through first preventive",
7+
"costResults" : {
8+
"initial" : {
9+
"functionalCost" : -5.00,
10+
"virtualCost" : {
11+
"sensitivity-failure-cost" : 0.00
12+
}
13+
},
14+
"preventive" : {
15+
"functionalCost" : -5.00,
16+
"virtualCost" : {
17+
"sensitivity-failure-cost" : 0.00
18+
}
19+
},
20+
"outage" : {
21+
"functionalCost" : -5.00,
22+
"virtualCost" : {
23+
"sensitivity-failure-cost" : 0.00
24+
}
25+
},
26+
"auto" : {
27+
"functionalCost" : -5.00,
28+
"virtualCost" : {
29+
"sensitivity-failure-cost" : 0.00
30+
}
31+
},
32+
"curative" : {
33+
"functionalCost" : -5.00,
34+
"virtualCost" : {
35+
"sensitivity-failure-cost" : 0.00
36+
}
37+
}
38+
},
39+
"computationStatusMap" : [ ],
40+
"flowCnecResults" : [ {
41+
"flowCnecId" : "cnec1 - curative",
42+
"initial" : {
43+
"ampere" : {
44+
"margin" : 7.60,
45+
"side2" : {
46+
"flow" : 0.00
47+
}
48+
},
49+
"megawatt" : {
50+
"margin" : 5.00,
51+
"side2" : {
52+
"flow" : 0.00
53+
}
54+
}
55+
},
56+
"preventive" : {
57+
"ampere" : {
58+
"margin" : 7.60,
59+
"side2" : {
60+
"flow" : 0.00
61+
}
62+
},
63+
"megawatt" : {
64+
"margin" : 5.00,
65+
"side2" : {
66+
"flow" : 0.00
67+
}
68+
}
69+
},
70+
"auto" : {
71+
"ampere" : {
72+
"margin" : 7.60,
73+
"side2" : {
74+
"flow" : 0.00
75+
}
76+
},
77+
"megawatt" : {
78+
"margin" : 5.00,
79+
"side2" : {
80+
"flow" : 0.00
81+
}
82+
}
83+
},
84+
"curative" : {
85+
"ampere" : {
86+
"margin" : 7.60,
87+
"side2" : {
88+
"flow" : 0.00
89+
}
90+
},
91+
"megawatt" : {
92+
"margin" : 5.00,
93+
"side2" : {
94+
"flow" : 0.00
95+
}
96+
}
97+
}
98+
}, {
99+
"flowCnecId" : "cnec1 - preventive",
100+
"initial" : {
101+
"ampere" : {
102+
"margin" : 68.25,
103+
"side2" : {
104+
"flow" : 83.68
105+
}
106+
},
107+
"megawatt" : {
108+
"margin" : 49.99,
109+
"side2" : {
110+
"flow" : 50.01
111+
}
112+
}
113+
},
114+
"preventive" : {
115+
"ampere" : {
116+
"margin" : 68.25,
117+
"side2" : {
118+
"flow" : 83.68
119+
}
120+
},
121+
"megawatt" : {
122+
"margin" : 49.99,
123+
"side2" : {
124+
"flow" : 50.01
125+
}
126+
}
127+
}
128+
} ],
129+
"angleCnecResults" : [ ],
130+
"voltageCnecResults" : [ ],
131+
"networkActionResults" : [ ],
132+
"rangeActionResults" : [ ]
133+
}

docs/user_guide/rao.rst

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,24 +25,27 @@ Here is a code example of how to configure and run the RAO:
2525

2626
>>> import pypowsybl as pp
2727
>>> from pypowsybl.rao import Parameters as RaoParameters
28+
>>> from pypowsybl.rao import Crac
29+
>>> from pypowsybl.rao import Glsk as RaoGlsk
30+
>>> from pypowsybl.rao import RaoResult
2831
>>>
2932
>>> network = pp.network.load(str(DATA_DIR.joinpath("rao/rao_network.uct")))
30-
>>> parameters = RaoParameters()
31-
>>> parameters.load_from_file_source(str(DATA_DIR.joinpath("rao/rao_parameters.json")))
33+
>>> parameters = RaoParameters.from_file_source(str(DATA_DIR.joinpath("rao/rao_parameters.json")))
3234
>>> rao_runner = pp.rao.create_rao()
33-
>>> rao_runner.set_crac_file_source(network, str(DATA_DIR.joinpath("rao/rao_crac.json")))
34-
>>> rao_runner.set_glsk_file_source(network, str(DATA_DIR.joinpath("rao/rao_glsk.xml")))
35-
>>> rao_result = rao_runner.run(network, parameters)
35+
>>> crac = Crac.from_file_source(network, str(DATA_DIR.joinpath("rao/rao_crac.json")))
36+
>>> glsk = RaoGlsk.from_file_source(str(DATA_DIR.joinpath("rao/rao_glsk.xml")))
37+
>>> rao_result = rao_runner.run(crac=crac, network=network, parameters=parameters, loop_flow_glsk=glsk)
3638
>>> rao_result.status()
3739
<RaoComputationStatus.DEFAULT: 0>
3840

3941
Monitoring API
4042
--------------
4143

42-
Rao monitoring can run through the following API using an already produced rao result :
44+
Rao monitoring can run through the following API using a rao result already produced by a run, or loaded from file :
4345

44-
>>> result_with_voltage_monitoring = rao_runner.run_voltage_monitoring(network, rao_result)
45-
>>> result_with_angle_monitoring = rao_runner.run_angle_monitoring(network, rao_result)
46+
>>> result_with_voltage_monitoring = rao_runner.run_voltage_monitoring(crac, network, rao_result)
47+
>>> monitoring_glsk = RaoGlsk.from_file_source(str(DATA_DIR.joinpath("rao/GlskB45test.xml")))
48+
>>> result_with_angle_monitoring = rao_runner.run_angle_monitoring(crac, network, rao_result, monitoring_glsk=monitoring_glsk)
4649

4750
The returned rao result object are the original result enhanced with voltage or angle monitoring data.
4851

@@ -152,11 +155,12 @@ Cost for a given virtual cost name is returned as a pandas dataframe with cost v
152155
>>> sensi_cost.loc['curative', 'sensitivity-failure-cost']
153156
np.float64(0.0)
154157

155-
The 'RaoResult' object can also be serialized to json:
158+
The 'RaoResult' object can also be serialized to json and loaded from file:
156159

157160
.. doctest::
158161

159162
>>> rao_result.serialize(str(DATA_DIR.joinpath("rao/results.json")))
163+
>>> loaded_result = RaoResult.from_file_source(crac, str(DATA_DIR.joinpath("rao/results.json")))
160164

161165
Rao logs filter
162166
---------------
@@ -169,17 +173,16 @@ open rao, a RaoLogFilter is available :
169173
>>> import pypowsybl as pp
170174
>>> import logging
171175
>>> import sys
172-
>>> from pypowsybl.rao import (Parameters as RaoParameters, RaoLogFilter)
176+
>>> from pypowsybl.rao import (Parameters as RaoParameters, RaoLogFilter, Crac, Glsk as RaoGlsk)
173177
>>>
174178
>>> network = pp.network.load(str(DATA_DIR.joinpath("rao/rao_network.uct")))
175-
>>> parameters = RaoParameters()
176-
>>> parameters.load_from_file_source(str(DATA_DIR.joinpath("rao/rao_parameters.json")))
179+
>>> parameters = RaoParameters.from_file_source(str(DATA_DIR.joinpath("rao/rao_parameters.json")))
177180
>>> rao_runner = pp.rao.create_rao()
178-
>>> rao_runner.set_crac_file_source(network, str(DATA_DIR.joinpath("rao/rao_crac.json")))
179-
>>> rao_runner.set_glsk_file_source(network, str(DATA_DIR.joinpath("rao/rao_glsk.xml")))
181+
>>> crac = Crac.from_file_source(network, str(DATA_DIR.joinpath("rao/rao_crac.json")))
182+
>>> glsk = RaoGlsk.from_file_source(str(DATA_DIR.joinpath("rao/rao_glsk.xml")))
180183
>>>
181184
>>> logging.basicConfig(stream=sys.stdout) # Setup logging
182185
>>> logger = logging.getLogger('powsybl')
183186
>>> logger.setLevel(logging.ERROR)
184187
>>> logger.addFilter(RaoLogFilter())
185-
>>> rao_result = rao_runner.run(network, parameters)
188+
>>> rao_result = rao_runner.run(crac, network, parameters, loop_flow_glsk=glsk)

0 commit comments

Comments
 (0)