PGM JSON Converter
The PGM JSON Converter, converts to and from the native power-grid-model JSON data format, but with the addition of
handling extra info; information about the components, stored in the json data, but not used for the calculations.
This json format makes it convenient to evaluate the grid data in perspective of input to power-grid-model.
More details about the JSON format are mentioned in power_grid_model.utils
and an example of it is in Make Test
Dataset in power-grid-model repository.
1. Load the JSON data
Define source and destination paths:
source_file = "data/tiny-net/input.json"
destination_file = "data/tiny-net/sym_output.json"
For debugging purposes, let’s check the JSON input:
from pathlib import Path
from IPython.display import display, Markdown
with Path(source_file).open() as json_file:
display(Markdown(f"<pre style='max-height: 160px; overflow: scroll; white-space: pre'>{json_file.read()}</pre>"))
{ "node": [ {"id": 1, "u_rated": 10500.0, "name": "First Node"}, {"id": 2, "u_rated": 10500.0, "name": "Second Node"}, {"id": 3, "u_rated": 10500.0, "name": "Third Node"} ], "line": [ {"id": 4, "from_node": 1, "to_node": 2, "from_status": 1, "to_status": 1, "r1": 0.11, "x1": 0.12, "c1": 4.1380285203892784e-05, "tan1": 0.1076923076923077, "i_n": 510.0}, {"id": 5, "from_node": 2, "to_node": 3, "from_status": 1, "to_status": 1, "r1": 0.15, "x1": 0.16, "c1": 5.411268065124442e-05, "tan1": 0.10588235294117646, "i_n": 520.0} ], "source": [ {"id": 6, "node": 1, "status": 1, "u_ref": 1.01047619047619, "sk": 200000000.0} ], "sym_load": [ {"id": 7, "node": 2, "status": 1, "type": 4}, {"id": 8, "node": 3, "status": 1, "type": 4} ], "sym_voltage_sensor": [ {"id": 101, "measured_object": 1, "u_sigma": 105.0, "u_measured": 10751.072595758282, "u_angle_measured": -0.013054638926306409}, {"id": 201, "measured_object": 2, "u_sigma": 105.0, "u_measured": 10752.698591183394, "u_angle_measured": -0.01763734945972652}, {"id": 301, "measured_object": 3, "u_sigma": 100.0, "u_measured": 10748.320749959701, "u_angle_measured": -0.02018233075947404} ], "sym_power_sensor": [ {"id": 401, "measured_object": 4, "measured_terminal_type": 0, "power_sigma": 37916.0, "p_measured": 2412359.2976399013, "q_measured": -3024028.886598367}, {"id": 402, "measured_object": 4, "measured_terminal_type": 1, "power_sigma": 1000000000000000.0, "p_measured": -2000000.0, "q_measured": 1000000.0}, {"id": 501, "measured_object": 5, "measured_terminal_type": 0, "power_sigma": 20878.0, "p_measured": 1230426.390004009, "q_measured": -1742195.1033582848}, {"id": 502, "measured_object": 5, "measured_terminal_type": 1, "power_sigma": 10435.0, "p_measured": -1019999.9999999485, "q_measured": -219999.99999999927}, {"id": 601, "measured_object": 6, "measured_terminal_type": 2, "power_sigma": 38009.0, "p_measured": 2412359.297639887, "q_measured": -3024028.8865982923}, {"id": 701, "measured_object": 7, "measured_terminal_type": 4, "power_sigma": 10316.0, "p_measured": 1010000.0, "q_measured": 210000.0}, {"id": 801, "measured_object": 8, "measured_terminal_type": 4, "power_sigma": 10435.0, "p_measured": 1020000.0, "q_measured": 220000.0} ] }
Instantiate the converter, optionally with source and destination file paths.
Then use load_input_data()
to load the data and convert it to power-grid-model data.
Additional information is stored in extra_info
.
%%capture cap --no-stderr
from power_grid_model_io.converters import PgmJsonConverter
converter = PgmJsonConverter(source_file=source_file, destination_file=destination_file)
input_data, extra_info = converter.load_input_data()
Let’s investigate the data we have converted, for one of the components: nodes
import pandas as pd
# The node data is stored as a numpy structured array in input_data["node"]
display(input_data["node"])
# We can use pandas to display the data in a convenient tabular format
display(pd.DataFrame(input_data["node"]))
# Notice that the node names were not stored in the numpy array, as we don't need them for the calculations
display({i: extra_info[i] for i in input_data["node"]["id"]})
array([(1, 10500.), (2, 10500.), (3, 10500.)],
dtype={'names': ['id', 'u_rated'], 'formats': ['<i4', '<f8'], 'offsets': [0, 8], 'itemsize': 16, 'aligned': True})
id | u_rated | |
---|---|---|
0 | 1 | 10500.0 |
1 | 2 | 10500.0 |
2 | 3 | 10500.0 |
{1: {'name': 'First Node'},
2: {'name': 'Second Node'},
3: {'name': 'Third Node'}}
2. Run the calculation
Run powerflow calculation with the input_data
and show the results for nodes
.
from power_grid_model import PowerGridModel
pgm = PowerGridModel(input_data=input_data)
output_data = pgm.calculate_state_estimation()
display(pd.DataFrame(output_data["node"]))
id | energized | u_pu | u | u_angle | |
---|---|---|---|---|---|
0 | 1 | 1 | 1.023912 | 10751.072596 | -0.013055 |
1 | 2 | 1 | 1.024067 | 10752.698591 | -0.017637 |
2 | 3 | 1 | 1.023650 | 10748.320750 | -0.020182 |
3. Save the data as a JSON file
The data can be stored in a json file, using the same converter instance as we used to load the input data. The file will be saved in the destination_file
path supplied in the constructor, or a custom data_store (file, api endpint, database, etc) can be provided here.
converter.save(data=output_data, extra_info=extra_info)
Again, for debugging purposes, let’s check the JSON output. Notice that the node names are added to the nodes data.
from pathlib import Path
from IPython.display import display, Markdown
with Path(destination_file).open() as json_file:
display(Markdown(f"<pre style='max-height: 160px; overflow: scroll; white-space: pre'>{json_file.read()}</pre>"))
{ "line": [ {"id": 4, "energized": 1, "loading": 0.4073282784816704, "p_from": 2412359.29761995, "q_from": -3024028.8865554463, "i_from": 207.7374220256519, "s_from": 3868362.455553408, "p_to": -2240426.3899862496, "q_to": 1532195.103337908, "i_to": 145.73743890160117, "s_to": 2714246.1648935755}, {"id": 5, "energized": 1, "loading": 0.22023469237854879, "p_from": 1230426.3899934771, "q_from": -1742195.1033335815, "i_from": 114.52204003684537, "s_from": 2132883.7003624667, "p_to": -1019999.9999924893, "q_to": -219999.99999526862, "i_to": 56.04963781959543, "s_to": 1043455.7968513072} ], "node": [ {"id": 1, "energized": 1, "u_pu": 1.0239116757788667, "u": 10751.0725956781, "u_angle": -0.013054638926272096, "name": "First Node"}, {"id": 2, "energized": 1, "u_pu": 1.0240665324860059, "u": 10752.698591103062, "u_angle": -0.017637349459711085, "name": "Second Node"}, {"id": 3, "energized": 1, "u_pu": 1.0236495952266011, "u": 10748.320749879313, "u_angle": -0.020182330759471272, "name": "Third Node"} ], "source": [ {"id": 6, "energized": 1, "p": 2412359.29761995, "q": -3024028.8865554463, "i": 207.73742202565188, "s": 3868362.455553408, "pf": 0.6236125299367373} ], "sym_load": [ {"id": 7, "energized": 1, "p": 1009999.9999928857, "q": 209999.99999549665, "i": 55.39027580879406, "s": 1031600.6979368217, "pf": 0.9790609894049733}, {"id": 8, "energized": 1, "p": 1019999.9999924893, "q": 219999.99999526862, "i": 56.04963781959543, "s": 1043455.7968513072, "pf": 0.9775210440829433} ], "sym_power_sensor": [ {"id": 401, "energized": 1, "p_residual": 1.9951151841723913e-05, "q_residual": -4.292033395358885e-05}, {"id": 402, "energized": 1, "p_residual": 240426.38998624976, "q_residual": -532195.1033379079}, {"id": 501, "energized": 1, "p_residual": 1.0532019700804085e-05, "q_residual": -2.4703350476329433e-05}, {"id": 502, "energized": 1, "p_residual": -7.459144413246577e-06, "q_residual": -4.730660307927792e-06}, {"id": 601, "energized": 1, "p_residual": 1.993694098700871e-05, "q_residual": -4.284572696633404e-05}, {"id": 701, "energized": 1, "p_residual": 7.114309141798003e-06, "q_residual": 4.503342143635791e-06}, {"id": 801, "energized": 1, "p_residual": 7.510658761589184e-06, "q_residual": 4.731381952893798e-06} ], "sym_voltage_sensor": [ {"id": 101, "energized": 1, "u_residual": 8.017919661540418e-08, "u_angle_residual": -3.431456507829722e-14}, {"id": 201, "energized": 1, "u_residual": 8.033307352661723e-08, "u_angle_residual": -1.543556948924163e-14}, {"id": 301, "energized": 1, "u_residual": 8.038902876705833e-08, "u_angle_residual": -2.7651492207070305e-15} ] }
Summary
%%capture cap --no-stderr
from power_grid_model import PowerGridModel
from power_grid_model_io.converters import PgmJsonConverter
source_file = "data/tiny-net/input.json"
destination_file = "data/tiny-net/sym_output.json"
converter = PgmJsonConverter(source_file=source_file, destination_file=destination_file)
input_data, extra_info = converter.load_input_data()
pgm = PowerGridModel(input_data=input_data)
output_data = pgm.calculate_state_estimation()
converter.save(data=output_data, extra_info=extra_info)