Skip to content
Snippets Groups Projects
Commit a43c815b authored by Christoph von Oy's avatar Christoph von Oy
Browse files

Refactored handling of profiles with AggregatedDynamic dynamics

parent 9669a708
Branches
No related tags found
No related merge requests found
......@@ -1048,10 +1048,10 @@ class AggregatedDynamic(Dynamic):
np.full(number_of_time_steps_per_period, step_length, dtype=int)
)
root_dynamic = self.dynamic_tree.root()
self.shape_ = sum(len(period) for period in periods)
self.state_shape_ = sum(len(period) + 1 for period in periods)
self.period_dynamics = []
self.n_p = []
running_index = 0
self.offsets_ = []
for i, period in enumerate(periods):
index = 0
period_indices = [0]
......@@ -1066,8 +1066,12 @@ class AggregatedDynamic(Dynamic):
self.n_p.append(
sum(1 for period_index in period_order if period_index == i)
)
self.offsets_.append((running_index, running_index + len(period)))
running_index += len(period)
self.period_order = period_order
self.n = len(period_order)
self.shape_ = running_index
self.state_shape_ = running_index + len(periods)
# sanity check 5: all elements in period order are valid period indices (above n_p[i] is the number of times that period index i appears in period order -> sum(n_p) == len(period_order))
if sum(n_p for n_p in self.n_p) != len(period_order):
......@@ -1075,6 +1079,12 @@ class AggregatedDynamic(Dynamic):
"All elements in period order have to be valid period indices!"
)
def number_of_periods(self) -> int:
return len(self.period_dynamics)
def offsets(self, period_index) -> Tuple[int]:
return self.offsets_[period_index]
def number_of_steps(self) -> int:
return self.dynamic.number_of_steps()
......@@ -1129,7 +1139,7 @@ class PeriodDynamic(Dynamic):
def resample(
values, dynamic: Dynamic, target_dynamic: Dynamic
): # values: type hinting Union[np-array, dict[int, np-array]], type hinting Union[np-array, dict[int, np-array]]
): # values: type hinting a np-array, type hinting a np-array
if dynamic == target_dynamic:
return values
elif isinstance(dynamic, TreeDynamic) and isinstance(target_dynamic, TreeDynamic):
......@@ -1168,7 +1178,8 @@ def resample_aggregation_down(
raise ValueError(
f"The period dynamic has to be part of the aggregated dynamic!"
)
return values[target_dynamic.period_index]
offset = dynamic.offsets(target_dynamic.period_index)
return values[offset[0] : offset[1]]
def resample_variable(variable, dynamic: Dynamic, target_dynamic: Dynamic):
......@@ -1196,9 +1207,7 @@ def resample_variable_tree(variable, dynamic: TreeDynamic, target_dynamic: TreeD
class Profile:
def __init__(
self, values, dynamic: Dynamic
): # values: type hinting Union[np-array, dict[int, np-array]]
def __init__(self, values, dynamic: Dynamic): # values: type hinting np-array
self.values = values
self.dynamic = dynamic
......@@ -1217,18 +1226,20 @@ class Profile:
}
elif isinstance(dynamic, AggregatedDynamic):
df = pd.read_csv(path, index_col=[0, 1])
profiles = {column: dict() for column in df.columns}
for period_index in df.index.levels[0]:
if (
len(df.loc[period_index])
!= dynamic.period_dynamics[period_index].number_of_steps()
if len(df.index.levels[0]) != dynamic.number_of_periods():
raise ValueError(
f"The number of periods in the csv file and the number of periods in the dynamic have the be the same!"
)
if any(
len(df.loc[period_index]) != period_dynamic.number_of_steps()
for period_index, period_dynamic in enumerate(dynamic.period_dynamics)
):
raise ValueError(
f"The number of rows in the csv file for a period and the number of steps in the period dynamic have to be the same!"
f"The number of rows in the csv file for a period and the number of segments in that period have the be the same!"
)
for column in df.columns:
profiles[column][period_index] = df.loc[period_index][column].values
return {column: Profile(profiles[column], dynamic) for column in df.columns}
return {
column: Profile(df[column].values, dynamic) for column in df.columns
}
else:
raise ValueError(f"Invalid dynamic type {type(dynamic)}!")
......
......@@ -152,9 +152,9 @@ class EntityResult:
self.u_result = np.empty(n_u_vars, dtype=float)
self.i_result = np.empty((n_i_vars, dynamic.number_of_steps()), dtype=float)
self.i_result = np.empty((n_i_vars, dynamic.shape()), dtype=float)
self.i_prime_result = np.empty((n_i_prime_vars, dynamic.number_of_steps() + 1), dtype=float)
self.i_prime_result = np.empty((n_i_prime_vars, dynamic.state_shape()), dtype=float)
self.dynamic = dynamic
......
......@@ -325,7 +325,7 @@ class Topology:
for name in objectives:
scaled_expression = 0.0
one_time_expression = 0.0
for period_index in range(len(block.dynamic.period_dynamics)):
for period_index in range(block.dynamic.number_of_periods()):
(
period_scaled_expression,
period_one_time_expression,
......@@ -559,7 +559,7 @@ class Topology:
elif isinstance(block.dynamic, (AggregatedDynamic)):
self._results[key].extract_result(block)
for period_index in range(len(block.dynamic.period_dynamics)):
for period_index in range(block.dynamic.number_of_periods()):
period_block = block.blocks[str(period_index)]
self._results[key].sub_results[period_index].extract_result(
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment