Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Periodic value deserialization #124

Merged
merged 19 commits into from
Oct 16, 2023
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
3 changes: 2 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ def read(*names, **kwargs):
install_requires=[
"datapackage==1.5.1",
"tableschema==1.7.4", # newer versions (v1.8.0 and up) fail!
"oemof.solph==0.5.1",
# "oemof.solph>=0.5.1",
"oemof.solph==0.5.2dev0",
"pandas>=0.22",
"paramiko",
"toml",
Expand Down
131 changes: 110 additions & 21 deletions src/oemof/tabular/datapackage/reading.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,66 @@ def find(n, d):
for flow in (typemap.get(FLOW_TYPE, HSN),)
}

period_data = {}
if package.get_resource("periods"):
df_periods = pd.DataFrame.from_dict(
package.get_resource("periods").read(keyed=True)
)
period_data["timeincrement"] = df_periods["timeincrement"].values
period_data["timeindex"] = pd.DatetimeIndex(df_periods["timeindex"])
period_data["periods"] = [
pd.DatetimeIndex(df["timeindex"])
for period, df in df_periods.groupby("periods")
]
period_data["periods"] = [
pd.DatetimeIndex(i.values, freq=i.inferred_freq, name="timeindex")
for i in period_data["periods"]
]
period_data["years"] = period_data["timeindex"].year.unique().values

def create_periodic_values(values, periods_index):
"""
Create periodic values from given values and period_data.
The values are repeated for each period for the whole length e.g.
8760 values for hourly data in one period.

Parameters
----------
values : list
List of values to be repeated.
periods_index : list
List containing periods datetimeindex.

Returns
-------
list
List of periodic values.
"""
# check if length of list equals number of periods
if len(values) != len(periods_index):
raise ValueError(
"Length of values does not equal number of periods."
)

# create timeseries with periodic values
periodic_values = pd.concat(
[
pd.Series(repeat(values[i], len(period)), index=period)
for i, period in enumerate(periods_index)
]
)

return periodic_values.tolist()

def create_yearly_values(values, years):
results = pd.Series()
for i in range(len(years) - 1):
diff = years[i + 1] - years[i]
period_results = pd.Series(repeat(values[i], diff))
results = pd.concat([results, period_results])
results = pd.concat([results, pd.Series(values[-1])])
return results.tolist()

facades = {}
for r in package.resources:
if all(
Expand Down Expand Up @@ -405,6 +465,51 @@ def find(n, d):
for f, v in facade.items():
if isinstance(v, Decimal):
facade[f] = float(v)
# check if multi-period and value is list
if period_data and isinstance(v, list):
# check if length of list equals number of periods
if len(v) == len(period_data["periods"]):
if f in ["capacity_costs"]:
# special period parameters don't need to be
# converted into timeseries
facade[f] = [
float(vv)
if isinstance(vv, Decimal)
else vv
for vv in v
]
continue
elif f in ["fixed_costs"]:
# special period parameter need to be
# converted into timeseries with value for each
# year
facade[f] = create_yearly_values(
v, period_data["years"]
)
msg = (
f"\nThe parameter '{f}' of a "
f"'{facade['type']}' facade is converted "
"into a yearly list. This might not be "
"possible for every parameter and lead to "
"ambiguous error messages.\nPlease be "
"aware, when using this feature!"
)
warnings.warn(msg, UserWarning)

else:
# create timeseries with periodic values
facade[f] = create_periodic_values(
v, period_data["periods"]
)
msg = (
f"\nThe parameter '{f}' of a "
f"'{facade['type']}' facade is converted "
"into a periodic timeseries. This might "
"not be possible for every parameter and "
"lead to ambiguous error messages.\nPlease"
" be aware, when using this feature!"
)
warnings.warn(msg, UserWarning)
read_facade(
facade,
facades,
Expand Down Expand Up @@ -442,28 +547,12 @@ def find(n, d):
# if no temporal provided as resource, take the first timeindex
# from dict
else:
# look for periods resource and if present, take as periods from it
# look for periods resource and if present, take periods from it
if package.get_resource("periods"):
df_periods = pd.DataFrame.from_dict(
package.get_resource("periods").read(keyed=True)
)
timeincrement = df_periods["increment"].values
timeindex = pd.DatetimeIndex(df_periods["timeindex"])
periods = [
pd.DatetimeIndex(df["timeindex"])
for period, df in df_periods.groupby("periods")
]
periods = [
pd.DatetimeIndex(
i.values, freq=i.inferred_freq, name="timeindex"
)
for i in periods
]

es = cls(
timeindex=timeindex,
timeincrement=timeincrement,
periods=periods,
timeindex=period_data["timeindex"],
timeincrement=period_data["timeincrement"],
periods=period_data["periods"],
infer_last_interval=False,
)

Expand All @@ -483,7 +572,7 @@ def find(n, d):
timeindex = pd.date_range(
start=pd.to_datetime("today"), periods=1, freq="H"
)
es = cls()
es = cls(timeindex=timeindex)

es.add(
*chain(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
timeindex,periods, increment
timeindex,periods, timeincrement
2011-01-01T00:00:00Z,0,1
2011-01-01T01:00:00Z,0,1
2011-01-01T02:00:00Z,0,1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@
"format": "default"
},
{
"name": "increment",
"name": "timeincrement",
"type": "integer",
"format": "default"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
timeindex,periods, increment
timeindex,periods, timeincrement
2015-01-01T00:00:00Z,0,1
2015-01-01T01:00:00Z,0,1
2015-01-01T02:00:00Z,0,1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,7 @@
"format": "default"
},
{
"name": "increment",
"name": "timeincrement",
"type": "integer",
"format": "default"
}
Expand Down
Loading