Skip to content

Commit

Permalink
5.1.28
Browse files Browse the repository at this point in the history
  • Loading branch information
SanPen committed Sep 13, 2024
1 parent e765631 commit de3f7c6
Show file tree
Hide file tree
Showing 21 changed files with 488 additions and 132 deletions.
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -959,6 +959,45 @@ Br2 117.102446 66.761871 0.0 0.0 66.761871
Br3 38.591163 22.775597 0.0 0.0 22.775597
```

### Export the results

A simple function is available to export the results of a driver.

```python
import GridCalEngine.api as gce

fname = os.path.join("data", "grids", "IEEE39_1W.gridcal")
grid = gce.open_file(fname)

# create the driver
pf_driver = gce.PowerFlowTimeSeriesDriver(grid=grid,
options=gce.PowerFlowOptions(),
time_indices=grid.get_all_time_indices())
# run
pf_driver.run()

# Save the driver results in a zip file with CSV files inside
gce.export_drivers(drivers_list=[pf_driver], file_name="IEEE39_1W_results.zip")
```

You could save many drivers in the same zip file passing then into the list `drivers_list`.

Also there is a function to save from the results objects themselves:

```python
import GridCalEngine.api as gce

fname = os.path.join("data", "grids", "IEEE39_1W.gridcal")
grid = gce.open_file(fname)

# run with the API shortcut functions
pf_results = gce.power_flow(grid)
pf_ts_results = gce.power_flow_ts(grid)

# Save the driver results in a zip file with CSV files inside
gce.export_results(results_list=[pf_results, pf_ts_results], file_name="IEEE39_1W_results.zip")
```

## Contact

- Join the [Discord GridCal channel](https://discord.com/invite/dzxctaNbvu) for a friendly chat, or quick question.
Expand Down
4 changes: 2 additions & 2 deletions src/GridCal/Gui/Main/SubClasses/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ def export_all(self):
:return:
"""

available_results = self.get_available_results()
available_results = self.get_available_drivers()

if len(available_results) > 0:

Expand All @@ -851,7 +851,7 @@ def export_all(self):

self.stuff_running_now.append('export_all')
self.export_all_thread_object = exprtdrv.ExportAllThread(circuit=self.circuit,
simulations_list=available_results,
drivers_list=available_results,
file_name=filename)

self.export_all_thread_object.progress_signal.connect(self.ui.progressBar.setValue)
Expand Down
4 changes: 2 additions & 2 deletions src/GridCal/Gui/Main/SubClasses/simulations.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ def get_simulations(self) -> List[DRIVER_OBJECTS]:

return all_threads

def get_available_results(self):
def get_available_drivers(self) -> List[DRIVER_OBJECTS]:
"""
Get a list of all the available results' objects
:return: list[object]
Expand Down Expand Up @@ -539,7 +539,7 @@ def update_available_results(self) -> None:
# clear results lists
self.ui.results_treeView.setModel(None)

available_results = self.get_available_results()
available_results = self.get_available_drivers()
max_steps = 0
d = dict()
lst = list()
Expand Down
2 changes: 1 addition & 1 deletion src/GridCal/Gui/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def get_pointer_lambda(self, gui_instance):
- func(self) is then what I wanted to lambda in the first place
"""
func = self.function_ptr
return lambda e, func=func: func(gui_instance) # This is not an error, it is correct
return lambda e=True, func=func: func(gui_instance) # This is not an error, it is correct

def to_dict(self) -> Dict[str, str]:
"""
Expand Down
89 changes: 26 additions & 63 deletions src/GridCal/Session/export_results_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,97 +14,57 @@
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import os
from io import StringIO
import zipfile
from PySide6.QtCore import QThread, Signal

from typing import List
from PySide6.QtCore import QThread, Signal
from GridCalEngine.IO.gridcal.results_export import export_drivers
from GridCalEngine.Devices.multi_circuit import MultiCircuit
from GridCalEngine.Simulations.types import DRIVER_OBJECTS
from GridCalEngine.basic_structures import Logger


class ExportAllThread(QThread):
"""
ExportAllThread
"""
progress_signal = Signal(float)
progress_text = Signal(str)
done_signal = Signal()

def __init__(self, circuit, simulations_list, file_name):
def __init__(self, circuit: MultiCircuit, drivers_list: List[DRIVER_OBJECTS], file_name: str):
"""
Constructor
:param simulations_list: list of GridCal simulation drivers
:param circuit: Grid circuit
:param drivers_list: list of GridCal simulation drivers
:param file_name: name of the file where to save (.zip)
"""
QThread.__init__(self)

self.circuit = circuit
self.circuit: MultiCircuit = circuit

self.simulations_list = simulations_list
self.drivers_list: List[DRIVER_OBJECTS] = drivers_list

self.file_name = file_name
self.file_name: str = file_name

self.valid = False
self.valid: bool = False

self.logger = Logger()

self.error_msg = ''
self.error_msg: str = ""

self.__cancel__ = False

def run(self):
def run(self) -> None:
"""
run the file save procedure
"""

# try:
path, fname = os.path.split(self.file_name)

self.progress_text.emit('Flushing ' + fname + ' into ' + fname + '...')

self.logger = Logger()

# names_dict = {DeviceType.BusDevice: self.circuit.get_bus_names(),
# DeviceType.BranchDevice: self.circuit.get_branch_names(),
# DeviceType.BusDevice.LoadDevice: self.circuit.get_load_names(),
# DeviceType.BusDevice.GeneratorDevice: self.circuit.get_controlled_generator_names(),
# DeviceType.BusDevice.BatteryDevice: self.circuit.get_battery_names()}

# open zip file for writing
try:
with zipfile.ZipFile(self.file_name, 'w', zipfile.ZIP_DEFLATED) as myzip:

n = len(self.simulations_list)

for k, driver in enumerate(self.simulations_list):

self.progress_signal.emit((k + 1) / n * 100.0)

if isinstance(driver.results.available_results, dict):
available_res = [e for tpe, lst in driver.results.available_results.items() for e in lst]
else:
available_res = driver.results.available_results

for available_result in available_res:

# ge the result type definition
result_name, device_type = available_result.value

self.progress_text.emit('flushing ' + driver.results.name + ' ' + result_name)

# save the DataFrame to the buffer
mdl = driver.results.mdl(result_type=available_result)

if mdl is not None:
with StringIO() as buffer:
filename = driver.results.name + ' ' + result_name + '.csv'
try:
mdl.save_to_csv(buffer)
myzip.writestr(filename, buffer.getvalue())
except ValueError:
self.logger.add_error('Value error', filename)
else:
self.logger.add_info('No results for ' + driver.results.name + ' - ' + result_name)

except PermissionError:
self.logger.add('Permission error.\nDo you have the file open?')
export_drivers(drivers_list=self.drivers_list,
file_name=self.file_name,
text_func=self.progress_text.emit,
progress_func=self.progress_signal.emit,
logger=self.logger)

self.valid = True

Expand All @@ -114,4 +74,7 @@ def run(self):
self.done_signal.emit()

def cancel(self):
self.__cancel__ = True
"""
Cancel progress
"""
self.__cancel__ = True
2 changes: 1 addition & 1 deletion src/GridCal/__version__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
_current_year_ = datetime.datetime.now().year

# do not forget to keep a three-number version!!!
__GridCal_VERSION__ = "5.1.27"
__GridCal_VERSION__ = "5.1.28"

url = 'https://github.com/SanPen/GridCal'

Expand Down
13 changes: 8 additions & 5 deletions src/GridCalEngine/Devices/Branches/overhead_line_type.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class WireInTower:
Wire -> Tower association
"""

def __init__(self, wire: Wire, xpos=0, ypos=0, phase=1):
def __init__(self, wire: Wire, xpos: float = 0.0, ypos: float = 0.0, phase: int = 1):
"""
Wire in a tower
:param wire: Wire instance
Expand Down Expand Up @@ -132,12 +132,15 @@ def __init__(self, name='Tower', idtag: str | None = None):
self.register(key='Imax', units='kA', tpe=float, definition='Current rating of the tower', old_names=['rating'])
self.register(key='Vnom', units='kV', tpe=float, definition='Voltage rating of the line')

def add_wire(self, w: WireInTower):
def add_wire_relationship(self, wire: Wire, xpos: float = 0.0, ypos: float = 0.0, phase: int = 1):
"""
:param w:
:return:
Wire in a tower
:param wire: Wire instance
:param xpos: x position in m
:param ypos: y position in m
:param phase: 0->Neutral, 1->A, 2->B, 3->C
"""
w = WireInTower(wire=wire, xpos=xpos, ypos=ypos, phase=phase)
self.wires_in_tower.append(w)

def z_series(self):
Expand Down
6 changes: 3 additions & 3 deletions src/GridCalEngine/Devices/Branches/wire.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ def __init__(self, name='', idtag: Union[str, None] = None,
self.GMR = gmr
self.max_current = max_current

self.register(key='R', units='Ohm/km', tpe=float, definition='resistance of the conductor')
self.register(key='X', units='Ohm/km', tpe=float, definition='reactance of the conductor')
self.register(key='GMR', units='m', tpe=float, definition='Geometric Mean Radius of the conductor')
self.register(key='R', units='Ohm/km', tpe=float, definition='resistance of the conductor', old_names=['r'])
self.register(key='X', units='Ohm/km', tpe=float, definition='reactance of the conductor', old_names=['x'])
self.register(key='GMR', units='m', tpe=float, definition='Geometric Mean Radius of the conductor', old_names=['gmr'])
self.register(key='max_current', units='kA', tpe=float, definition='Maximum current of the conductor')
self.register(key='stranding', tpe=str, definition='Stranding of wire')
self.register(key='material', tpe=str, definition='Material of wire')
Expand Down
9 changes: 8 additions & 1 deletion src/GridCalEngine/IO/__init__.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@


from GridCalEngine.IO.cim import cgmesProfile, CIMImport, CIMExport

from GridCalEngine.IO.dgs.dgs_parser import dgs_to_circuit

from GridCalEngine.IO.others.dpx_parser import load_dpx
from GridCalEngine.IO.others.ipa_parser import load_iPA

from GridCalEngine.IO.gridcal.json_parser import save_json_file_v3, parse_json_data_v3
from GridCalEngine.IO.gridcal.excel_interface import interpret_excel_v3, interprete_excel_v2
from GridCalEngine.IO.gridcal.results_export import export_drivers, export_results

from GridCalEngine.IO.matpower.matpower_parser import parse_matpower_file, get_matpower_case_data

from GridCalEngine.IO.raw.raw_parser_legacy import PSSeParser
from GridCalEngine.IO.gridcal.excel_interface import interpret_excel_v3, interprete_excel_v2

from GridCalEngine.IO.file_handler import FileOpen, FileSave, FileSavingOptions
37 changes: 24 additions & 13 deletions src/GridCalEngine/IO/gridcal/excel_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,23 +547,35 @@ def set_object_attributes(obj_, attr_list, values):

# Add the overhead_line_types ##################################################################################
if 'overhead_line_types' in data.keys():
lst = data['overhead_line_types']
df = data['overhead_line_types']
if data['overhead_line_types'].values.shape[0] > 0:
for tower_name in lst['tower_name'].unique():
tower = dev.OverheadLineType()
vals = lst[lst['tower_name'] == tower_name].values
for tower_name in df['tower_name'].unique():
obj = dev.OverheadLineType()
dft = df[df['tower_name'] == tower_name]
vals = dft.values

wire_prop = df.columns.values[len(obj.registered_properties):]

# set the tower values
set_object_attributes(tower, tower.registered_properties.keys(), vals[0, :])
set_object_attributes(obj, obj.registered_properties.keys(), vals[0, :])

# add the wires
for i in range(vals.shape[0]):
wire = dev.Wire()
set_object_attributes(wire, tower.get_wire_properties(), vals[i, len(tower.registered_properties):])
tower.add_wire(wire)
if len(wire_prop) == 7:
for i in range(vals.shape[0]):
# ['wire_name' 'xpos' 'ypos' 'phase' 'r' 'x' 'gmr']
name = dft['wire_name'].values[i]
gmr = dft['gmr'].values[i]
r = dft['r'].values[i]
x = dft['x'].values[i]
xpos = dft['xpos'].values[i]
ypos = dft['ypos'].values[i]
phase = dft['phase'].values[i]

wire = dev.Wire(name=name, gmr=gmr, r=r, x=x)
obj.add_wire_relationship(wire=wire, xpos=xpos, ypos=ypos, phase=phase)

circuit.add_overhead_line(tower)
branch_types[str(tower)] = tower
circuit.add_overhead_line(obj)
branch_types[str(obj)] = obj
else:
pass
else:
Expand Down Expand Up @@ -1022,8 +1034,7 @@ def set_object_attributes(obj_, attr_list, values):
phase = dft['phase'].values[i]

wire = dev.Wire(name=name, gmr=gmr, r=r, x=x)
w = dev.WireInTower(wire=wire, xpos=xpos, ypos=ypos, phase=phase)
obj.add_wire(w)
obj.add_wire_relationship(wire=wire, xpos=xpos, ypos=ypos, phase=phase)

circuit.add_overhead_line(obj)
branch_types[str(obj)] = obj
Expand Down
4 changes: 1 addition & 3 deletions src/GridCalEngine/IO/gridcal/pack_unpack.py
Original file line number Diff line number Diff line change
Expand Up @@ -1436,9 +1436,7 @@ def parse_gridcal_data(data: Dict[str, Union[str, float, pd.DataFrame, Dict[str,
xpos = df['xpos'].values[i]
ypos = df['ypos'].values[i]
phase = df['phase'].values[i]

w = dev.WireInTower(wire=wire, xpos=xpos, ypos=ypos, phase=phase)
tower.add_wire(w)
tower.add_wire_relationship(wire=wire, xpos=xpos, ypos=ypos, phase=phase)

# create diagrams --------------------------------------------------------------------------------------------------
if text_func is not None:
Expand Down
Loading

0 comments on commit de3f7c6

Please sign in to comment.