Skip to content

Commit

Permalink
multiple changes in the clustering and MTS procedures
Browse files Browse the repository at this point in the history
  • Loading branch information
squoilin committed Apr 4, 2020
1 parent 1f17555 commit 8f4b2b6
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 113 deletions.
27 changes: 11 additions & 16 deletions dispaset/preprocessing/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ def build_single_run(config, profiles=None):
HeatDemand = UnitBasedTable(plants_heat,'HeatDemand',config,fallbacks=['Unit'],default=0)
CostHeatSlack = UnitBasedTable(plants_heat,'CostHeatSlack',config,fallbacks=['Unit','Zone'],default=config['default']['CostHeatSlack'])
Temperatures = NodeBasedTable('Temperatures',config)

# Update reservoir levels with newly computed ones from the mid-term scheduling
if profiles is not None:
for key in profiles.columns:
if key not in ReservoirLevels.columns:
logging.error('The reservoir profile "' + key + '" provided by the MTS is not found in the ReservoirLevels table')
print(ReservoirLevels.columns)
else:
ReservoirLevels[key].update(profiles[key])
logging.info('The reservoir profile "' + key + '" provided by the MTS is used as target reservoir level')


# data checks:
check_AvailabilityFactors(plants,AF)
Expand Down Expand Up @@ -316,22 +327,6 @@ def build_single_run(config, profiles=None):
for key in ['ReservoirLevels']:
finalTS[key] = merge_series(plants, finalTS[key], mapping, tablename=key, method='StorageWeightedAverage')

# Update reservoir levels with newly computed ones from the mid-term scheduling
if profiles is not None:
if config['HydroScheduling'] == 'Zonal' and config['SimulationType'] == 'Standard':
logging.critical("SimulationType: 'Standard' and HydroScheduling: 'Zonal' not supported! Please"
" choose different input options")
sys.exit(1)
if all(profiles.columns.isin(finalTS['ReservoirLevels'].columns)):
finalTS['ReservoirLevels'].update(profiles)
logging.info('New reservoir levels from Mid-term scheduling are now imposed instead of historic values')
else:
for key in profiles.columns:
if key not in finalTS['ReservoirLevels'].columns:
logging.critical('The reservoir profile "' + key + '" provided by the MTS is not found in the ReservoirLevels table')
print(ReservoirLevels.columns)
sys.exit(1)

# Check that all times series data is available with the specified data time step:
for key in FuelPrices:
check_df(FuelPrices[key], StartDate=config['idx'][0], StopDate=config['idx'][-1], name=key)
Expand Down
2 changes: 1 addition & 1 deletion dispaset/preprocessing/data_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ def read_truefalse(sheet, rowstart, colstart, rowstop, colstop, colapart=1):
The list of strings associated with a True value is returned
"""
out = []
for i in range(rowstart, rowstop):
for i in range(rowstart, rowstop+1):
if sheet.cell_value(i, colstart + colapart) == 1:
out.append(sheet.cell_value(i, colstart))
return out
Expand Down
130 changes: 70 additions & 60 deletions dispaset/preprocessing/preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
import sys

import pandas as pd
import numpy as np

from .build import build_single_run

from ..solve import solve_GAMS
from ..misc.gdx_handler import gdx_to_dataframe, gdx_to_list
from ..postprocessing.data_handler import GAMSstatus
from .utils import pd_timestep

try:
Expand Down Expand Up @@ -54,6 +56,18 @@ def build_simulation(config, mts_plot=None, MTSTimeStep=None):
SimData = build_single_run(config, new_profiles)
return SimData

def _check_results(results):
'''
Function that checks the gams status in the results
'''
if "model" in results['status']:
errors = results['status'][(results['status']['model'] != 1) & (results['status']['model'] != 8)]
if len(errors) > 0:
logging.critical('Some simulation errors were encountered when running the regional MTS. Some results could not be computed, for example at time ' + str(errors.index[0]) + ', with the error message: "' + GAMSstatus('model', errors['model'].iloc[0]) + '"')
for i in errors.index:
errors.loc[i,'Error Message'] = GAMSstatus('model',errors['model'][i])
sys.exit(1)
return True

def mid_term_scheduling(config, TimeStep=None, mts_plot=None):
"""
Expand Down Expand Up @@ -92,12 +106,15 @@ def mid_term_scheduling(config, TimeStep=None, mts_plot=None):

if config['mts_zones'] is None:
temp_config['mts_zones'] = config['zones']
logging.info('Simulation with all zones selected')
logging.info('MTS Simulation with all zones selected')
else:
temp_config['zones'] = config['mts_zones']

# remove look ahead:
temp_config['LookAhead'] = 0

# use a LP formulation
temp_config['SimulationType'] = 'LP clustered'

# Adjust time step:
if TimeStep is not None:
Expand All @@ -118,65 +135,76 @@ def mid_term_scheduling(config, TimeStep=None, mts_plot=None):

# Checking which type of hydro scheduling simulation is specified in the config file:
if config['HydroScheduling'] == 'Zonal':
if config['SimulationType'] == 'Standard':
logging.critical("SimulationType: 'Standard' and HydroScheduling: 'Zonal' not supported! Please"
" choose different input options")
sys.exit(1)
else:
no_of_zones = len(config['mts_zones'])
temp_results = {}
for i, c in enumerate(config['mts_zones']):
logging.info('(Currently simulating Zone): ' + str(i + 1) + ' out of ' + str(no_of_zones))
temp_config['zones'] = [c] # Override zone that needs to be simulated
_ = build_single_run(temp_config) # Create temporary SimData
r = solve_GAMS(sim_folder=temp_config['SimulationDirectory'],
gams_folder=temp_config['GAMS_folder'],
gams_file=gams_file,
result_file=resultfile)
temp_results[c] = gdx_to_dataframe(
gdx_to_list(config['GAMS_folder'], config['SimulationDirectory'] + '/' + resultfile, varname='all',
verbose=True), fixindex=True, verbose=True)
profiles = pd.DataFrame(index=idx)
for c in config['mts_zones']:
if 'OutputStorageLevel' not in temp_results[c]:
logging.critical('Storage levels in zone ' + c + ' were not computed, please check that storage units '
'are present in the ' + c + ' power plant database! If not, unselect ' + c +
' form the zones in the MTS module')
sys.exit(0)
elif len(temp_results[c]['OutputStorageLevel']) > len(idx):
logging.critical('The number of time steps in the mid-term simulation results (' + str(
len(temp_results[c]['OutputStorageLevel'])) +
') does not match the length of the index (' + str(len(idx)) + ')')
sys.exit(0)
elif len(temp_results[c]['OutputStorageLevel']) < len(idx):
for u in temp_results[c]['OutputStorageLevel']:
profiles[u] = temp_results[c]['OutputStorageLevel'][u].reindex(range(1, len(idx) + 1)).fillna(0).values
else:
for u in temp_results[c]['OutputStorageLevel']:
profiles[u] = temp_results[c]['OutputStorageLevel'][u].values
no_of_zones = len(config['mts_zones'])
temp_results = {}
profiles = pd.DataFrame(index=idx)
for i, c in enumerate(config['mts_zones']):
logging.info('(Currently simulating Zone): ' + str(i + 1) + ' out of ' + str(no_of_zones))
temp_config['zones'] = [c] # Override zone that needs to be simulated
SimData = build_single_run(temp_config) # Create temporary SimData
units = SimData['units']
r = solve_GAMS(sim_folder=temp_config['SimulationDirectory'],
gams_folder=temp_config['GAMS_folder'],
gams_file=gams_file,
result_file=resultfile)
temp_results[c] = gdx_to_dataframe(
gdx_to_list(config['GAMS_folder'], config['SimulationDirectory'] + '/' + resultfile, varname='all',
verbose=True), fixindex=True, verbose=True)
_check_results(temp_results[c])
if 'OutputStorageLevel' not in temp_results[c]:
logging.critical('Storage levels in zone ' + c + ' were not computed, please check that storage units '
'are present in the ' + c + ' power plant database! If not, unselect ' + c +
' form the zones in the MTS module')
sys.exit(0)
elif len(temp_results[c]['OutputStorageLevel']) > len(idx):
logging.critical('The number of time steps in the mid-term simulation results (' + str(
len(temp_results[c]['OutputStorageLevel'])) +
') does not match the length of the index (' + str(len(idx)) + ')')
sys.exit(0)
elif len(temp_results[c]['OutputStorageLevel']) < len(idx):
temp_results[c]['OutputStorageLevel'] = temp_results[c]['OutputStorageLevel'].reindex(range(1, len(idx) + 1)).fillna(0).values
for u in temp_results[c]['OutputStorageLevel']:
if u not in units.index:
logging.critical('Unit "' + u + '" is reported in the reservoir levels of the result file but does not appear in the units table')
sys.exit(1)
for u_old in units.loc[u,'FormerUnits']:
profiles[u_old] = temp_results[c]['OutputStorageLevel'][u].values

# Solving reservoir levels for all regions simultaneously
elif config['HydroScheduling'] == 'Regional':
_ = build_single_run(temp_config) # Create temporary SimData
SimData = build_single_run(temp_config) # Create temporary SimData
units = SimData['units']
r = solve_GAMS(sim_folder=temp_config['SimulationDirectory'],
gams_folder=temp_config['GAMS_folder'],
gams_file=gams_file,
result_file=resultfile)
gams_folder=temp_config['GAMS_folder'],
gams_file=gams_file,
result_file=resultfile)
temp_results = gdx_to_dataframe(
gdx_to_list(config['GAMS_folder'], config['SimulationDirectory'] + '/' + resultfile, varname='all',
verbose=True), fixindex=True, verbose=True)
_check_results(temp_results)
if 'OutputStorageLevel' not in temp_results:
logging.critical('Storage levels in the selected region were not computed, please check that storage units '
'are present in the power plant database! If not, unselect zones with no storage units '
'form the zones in the MTS module')
sys.exit(0)
elif len(temp_results['OutputStorageLevel']) < len(idx):
if len(temp_results['OutputStorageLevel']) < len(idx):
profiles = temp_results['OutputStorageLevel'].reindex(range(1, len(idx) + 1)).fillna(0).set_index(idx)
else:
profiles = temp_results['OutputStorageLevel'].set_index(idx)
# Updating the profiles table with the original unit names:
for u in profiles:
if u not in units.index:
logging.critical('Unit "' + u + '" is reported in the reservoir levels of the result file but does not appear in the units table')
sys.exit(1)
for u_old in units.loc[u,'FormerUnits']:
profiles[u_old] = profiles[u]
profiles.drop(u,axis=1,inplace=True)
else:
logging.error('HydroScheduling parameter should be either "Regional" or "Zonal" (case sensitive). ')
sys.exit()

# replace all 1.000000e+300 values by nan since they correspond to undefined in GAMS:
profiles[profiles>=1E300] = np.nan

if mts_plot:
profiles.plot()
Expand All @@ -187,21 +215,3 @@ def mid_term_scheduling(config, TimeStep=None, mts_plot=None):
pickle.dump(profiles, open("temp_profiles.p", "wb"))
return profiles


def get_temp_sim_results(config, gams_dir=None):
"""
This function reads the simulation environment folder once it has been solved and loads
the input variables together with the results.
:param config: Read config file
:param gams_dir: Path to GAMS directory
:returns results: Two dictionaries with all the outputs
"""

resultfile = config['SimulationDirectory'] + '/Results_simple.gdx'
results = gdx_to_dataframe(gdx_to_list(gams_dir, resultfile, varname='all', verbose=True), fixindex=True,
verbose=True)
results['OutputStorageLevel'] = results['OutputStorageLevel'].reindex(
list(range(results['OutputStorageLevel'].index.min(),
results['OutputStorageLevel'].index.max() + 1)), fill_value=0)
return results

0 comments on commit 8f4b2b6

Please sign in to comment.