Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ on:

jobs:
ref:
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v3
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

python_requires='>=3.8,<3.12',
install_requires=[
'numpy>1.21', 'pandas', 'scipy', 'dill', 'matplotlib',
'numpy>1.21', 'pandas>=1.0', 'scipy', 'dill', 'matplotlib',
'pyomo>=6', 'gurobipy',
'gridx-egret @ git+https://github.com/shrivats-pu/Egret.git'
],
Expand Down
29 changes: 29 additions & 0 deletions vatic/compat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
"""Compatibility utilities for different dependency versions."""

import pandas as pd


def hourly_resample(df_or_series):
"""Resample to hourly frequency with backward compatibility.

pandas 2.2+ requires lowercase frequency aliases ('h'),
while older versions use uppercase ('H').
"""
try:
return df_or_series.resample('h')
except ValueError:
return df_or_series.resample('H')


def hourly_freq():
"""Return the hourly frequency string compatible with installed pandas.

pandas 2.2+ requires lowercase frequency aliases ('h'),
while older versions use uppercase ('H').
"""
try:
# Test if lowercase works
pd.date_range(start='2020-01-01', periods=1, freq='h')
return 'h'
except ValueError:
return 'H'
14 changes: 8 additions & 6 deletions vatic/data/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import pandas as pd
from datetime import datetime

from vatic.compat import hourly_resample

import os
_ROOT = os.path.abspath(os.path.dirname(__file__))

Expand Down Expand Up @@ -566,8 +568,8 @@ def load_by_bus(self,
load_fcsts = self.get_forecasts('Load', start_date, end_date)

if load_actls is None:
load_actls = self.get_actuals(
'Load', start_date, end_date).resample('H').mean()
load_actls = hourly_resample(
self.get_actuals('Load', start_date, end_date)).mean()

site_dfs = dict()
for zone, zone_df in self.bus_df.groupby('Area'):
Expand Down Expand Up @@ -628,8 +630,8 @@ def create_timeseries(

for asset_type in self.timeseries_cohorts:
gen_fcsts = self.get_forecasts(asset_type, start_date, end_date)
gen_actls = self.get_actuals(
asset_type, start_date, end_date).resample('H').mean()
gen_actls = hourly_resample(
self.get_actuals(asset_type, start_date, end_date)).mean()

gen_fcsts.columns = pd.MultiIndex.from_tuples(
[('fcst', asset_name) for asset_name in gen_fcsts.columns])
Expand Down Expand Up @@ -714,8 +716,8 @@ def create_scenario_timeseries(
gen_df = pd.concat([gen_df, gen_scens], axis=1)

for asset_type in self.no_scenario_renews:
new_actuals = self.get_actuals(
asset_type, start_date, end_date).resample('H').mean()
new_actuals = hourly_resample(
self.get_actuals(asset_type, start_date, end_date)).mean()

for asset_name, asset_actuals in new_actuals.iteritems():
gen_df['actl', asset_name] = asset_actuals
Expand Down
2 changes: 1 addition & 1 deletion vatic/data_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -665,7 +665,7 @@ def _get_model_for_date(self,
# we can just copy the final value of the first day
else:
day_data['MaxNondispatchablePower'].update({
(gen, i): float(gen_data[gen][-1]) for i in range(25, 49)})
(gen, i): float(gen_data[gen].iloc[-1]) for i in range(25, 49)})

# for dispatchable renewables, minimum output is always zero
for gen in self.template['DispatchRenewables']:
Expand Down
9 changes: 5 additions & 4 deletions vatic/stats_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

from .model_data import VaticModelData
from .time_manager import VaticTime
from .compat import hourly_freq

import matplotlib.pyplot as plt
import seaborn as sns
Expand Down Expand Up @@ -386,17 +387,17 @@ def save_output(self, sim_runtime=None) -> dict[str, pd.DataFrame]:
tgen_gby = report_dfs['thermal_detail'].groupby('Generator')

# get the final output for each generator
final_dispatch = tgen_gby.apply(lambda x: round(x['Dispatch'][-1], 2))
final_dispatch = tgen_gby.apply(lambda x: round(x['Dispatch'].iloc[-1], 2))

# get the final on/off state for each generator
final_bool = tgen_gby.apply(
lambda x: (x['Unit State'][-1] * 2 - 1))
lambda x: (x['Unit State'].iloc[-1] * 2 - 1))

# find how long it has been since each generator was in a state not
# matching its final state, combine this info with final on/off
last_conds = tgen_gby.apply(
lambda x: (x['Unit State']
!= x['Unit State'][-1])[::-1].argmax()
!= x['Unit State'].iloc[-1])[::-1].argmax()
) * final_bool

# for generators which were on or off for the entire simulation
Expand Down Expand Up @@ -603,7 +604,7 @@ def generate_commitment_heatmaps(self) -> None:
t.strftime('%m/%d\n%-I%p') if i % 6 == 0 else ""
for i, t in enumerate(pd.date_range(start=ruc_time.when,
periods=commits.shape[1],
freq='H'))
freq=hourly_freq()))
]

ylbls = [
Expand Down
Loading