Source code for prepshot.output_data

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""This module contains functions to save solving results of models.
"""

import logging
import argparse

import numpy as np
import xarray as xr
import pandas as pd

from prepshot.logs import timer
from prepshot.utils import cartesian_product


[docs]def create_data_array( data : dict, dims : list, unit : str, model : object ) -> xr.DataArray: """Create a xarray DataArray with specified data, dimensions, coordinates and units. Parameters ---------- data : dict The data to be included in the DataArray. dims : list The list of dimentions of the data. unit : str The unit of the data. model : object The model object. Returns ------- xr.DataArray A DataArray with the specified data, dimensions, coordinates and units. """ coords = {dim:getattr(model, dim) for dim in dims} index_tuple = cartesian_product(*coords.values()) if len(dims) == 1: index_tuple = [i[0] for i in index_tuple] data_values = data.map(model.get_value) data = np.array( [data_values[tuple_] for tuple_ in index_tuple] ).reshape([len(coord) for coord in coords.values()]) return xr.DataArray(data=data, dims=dims, coords=coords, attrs={'unit': unit})
[docs]@timer def extract_results_non_hydro(model : object) -> xr.Dataset: """Extracts results for non-hydro models. Parameters ---------- model : object Model object sloved already. Returns ------- xr.Dataset A Dataset containing DataArrays for each attribute of the model. """ model.zone1 = model.zone model.zone2 = model.zone data_vars = {} data_vars['trans_export'] = create_data_array( model.trans_export, ['hour', 'month', 'year', 'zone1', 'zone2'], 'TWh', model) data_vars['gen'] = create_data_array( model.gen, ['hour', 'month', 'year', 'zone', 'tech'], 'TWh', model) data_vars['install'] = create_data_array( model.cap_existing, ['year', 'zone', 'tech'], 'MW', model ) data_vars['carbon'] = create_data_array( model.carbon, ['year'], 'Ton', model ) data_vars['charge'] = create_data_array( model.charge, ['hour', 'month', 'year', 'zone', 'tech'], 'MWh', model ) data_vars['cost_var_breakdown'] = create_data_array( model.cost_var_tech_breakdown, ['year', 'zone', 'tech'], 'dollar', model ) data_vars['cost_fix_breakdown'] = create_data_array( model.cost_fix_tech_breakdown, ['year', 'zone', 'tech'], 'dollar', model ) data_vars['cost_newtech_breakdown'] = create_data_array( model.cost_newtech_breakdown, ['year', 'zone', 'tech'], 'dollar', model ) data_vars['cost_newline_breakdown'] = create_data_array( model.cost_newline_breakdown, ['year', 'zone1', 'zone2'], 'dollar', model ) data_vars['carbon_breakdown'] = create_data_array( model.carbon_breakdown, ['year', 'zone', 'tech'], 'Ton', model) data_vars['cost_var'] = xr.DataArray(model.get_value(model.cost_var)) data_vars['cost_fix'] = xr.DataArray(model.get_value(model.cost_fix)) data_vars['cost_newtech'] = xr.DataArray( data=model.get_value(model.cost_newtech) ) data_vars['cost_newline'] = xr.DataArray( data=model.get_value(model.cost_newline) ) data_vars['income'] = xr.DataArray( data=model.get_value(model.income) ) data_vars['cost'] = xr.DataArray( data = model.get_value(model.cost) ) return xr.Dataset(data_vars)
[docs]@timer def extract_results_hydro(model : object) -> xr.Dataset: """Extracts results for hydro models. Parameters ---------- model : object Model solved already. Returns ------- xr.Dataset A Dataset containing DataArrays for each attribute of the model. """ ds = extract_results_non_hydro(model) data_vars = {} data_vars['genflow'] = create_data_array( model.genflow, ['station', 'hour', 'month', 'year'], 'm**3s**-1', model ) data_vars['spillflow'] = create_data_array( model.spillflow, ['station', 'hour', 'month', 'year'], 'm**3s**-1', model ) return ds.assign(data_vars)
[docs]@timer def save_to_excel( ds : xr.Dataset, output_filename : str ) -> None: """Save the results to an Excel file. Parameters ---------- ds : xr.Dataset Dataset containing the results. output_filename : str The name of the output file. """ # pylint: disable=abstract-class-instantiated with pd.ExcelWriter( f'{output_filename}.xlsx', engine='xlsxwriter' ) as writer: for key in ds.data_vars: if len(ds[key].shape) == 0: df = pd.DataFrame([ds[key].values.max()], columns=[key]) else: df = ds[key].to_dataframe() df.to_excel(writer, sheet_name=key, merge_cells=False)
[docs]def save_result(model : object) -> None: """Extracts results from the provided model. Parameters ---------- model : object The model object to extract results from and save. """ isinflow = model.params['isinflow'] args = model.params['command_line_args'] output_filename = model.params['output_filename'] output_filename = update_output_filename(output_filename, args) if isinflow: ds = extract_results_hydro(model) else: ds = extract_results_non_hydro(model) ds.to_netcdf(f'{output_filename}.nc') logging.info( "Results are written to %s.nc", output_filename ) save_to_excel(ds, output_filename) logging.info("Results are written to separate excel files")
[docs]def update_output_filename( output_filename : str, args : argparse.Namespace ) -> str: """Update the output filename based on the arguments. Parameters ---------- output_filename : str The name of the output file. args : argparse.Namespace Arguments parsed by argparse. Returns ------- str The updated output filename. """ output_filename = output_filename + '_'.join( f'{key}_{value}' for key, value in vars(args).items() if value is not None ) return output_filename