Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
# Separately find the loc_techs(_carriers) dimension and all other dimensions
loc_tech_dim = [i for i in data_var.dims if 'loc_tech' in i]
if not loc_tech_dim:
loc_tech_dim = [i for i in data_var.dims if 'loc_carrier' in i]
if not loc_tech_dim:
if return_as == 'Series':
return data_var.to_series()
elif return_as in ['DataArray', 'MultiIndex DataArray']:
return data_var
else:
raise ValueError('`return_as` must be `DataArray`, `Series`, or '
'`MultiIndex DataArray`, but `{}` given'.format(return_as))
elif len(loc_tech_dim) > 1:
e = exceptions.ModelError
raise e("Cannot split loc_techs or loc_tech_carriers dimension "
"for DataArray {}".format(data_var.name))
loc_tech_dim = loc_tech_dim[0]
# xr.Datarray -> pd.Series allows for string operations
data_var_idx = data_var[loc_tech_dim].to_index()
index_list = data_var_idx.str.split('::').tolist()
# carrier_prod, carrier_con, and carrier_export will return an index_list
# of size 3, all others will be an index list of size 2
possible_names = ['loc', 'tech', 'carrier']
names = [i + 's' for i in possible_names if i in loc_tech_dim]
data_var_midx = pd.MultiIndex.from_tuples(index_list, names=names)
# Replace the Datarray loc_tech_dim with this new MultiIndex
# Generate the set of all files we want to read from file
flattened_config = model_run.locations.as_dict_flat()
csv_files = set([
v.split('=')[1].rsplit(':', 1)[0]
for v in flattened_config.values() if 'file=' in str(v)
])
for f in csv_files:
f_path = os.path.join(config_model.model.timeseries_data_path, f)
parser = lambda x: datetime.datetime.strptime(x, dtformat)
try:
df = pd.read_csv(
f_path, index_col=0, parse_dates=True, date_parser=parser
)
except ValueError as e:
raise exceptions.ModelError(
"Incorrect datetime format used in {}, expecting "
"`{}`, got `{}` instead"
"".format(f, dtformat, e.args[0].split("'")[1]))
timeseries_data[f] = df
# Apply time subsetting, if supplied in model_run
subset_time_config = config_model.model.subset_time
if subset_time_config is not None:
if isinstance(subset_time_config, list):
if len(subset_time_config) == 2:
time_slice = slice(subset_time_config[0], subset_time_config[1])
else:
raise exceptions.ModelError(
'Invalid subset_time value: {}'.format(subset_time_config)
)
else:
# get the cumulative sum of timestep resolution, to find where we hit our window and horizon
timestep_cumsum = model_data.timestep_resolution.cumsum('timesteps').to_pandas()
# get the timesteps at which we start and end our windows
window_ends = timestep_cumsum.where(
(timestep_cumsum % window == 0) | (timestep_cumsum == timestep_cumsum[-1])
)
window_starts = timestep_cumsum.where(
(~np.isnan(window_ends.shift(1))) | (timestep_cumsum == timestep_cumsum[0])
).dropna()
window_ends = window_ends.dropna()
horizon_ends = timestep_cumsum[timestep_cumsum.isin(window_ends.values + window_to_horizon)]
if not any(window_starts):
raise exceptions.ModelError(
'Not enough timesteps or incorrect timestep resolution to run in '
'operational mode with an optimisation window of {}'.format(window)
)
# We will only update timseries parameters
timeseries_data_vars = [
k for k, v in model_data.data_vars.items() if 'timesteps' in v.dims
]
# Loop through each window, solve over the horizon length, and add result to result_array
# we only go as far as the end of the last horizon, which may clip the last bit of data
result_array = []
for i in range(len(window_starts)):
def _get_array(data, var, tech, **kwargs):
subset = {'techs': tech}
if kwargs is not None:
subset.update({k: v for k, v in kwargs.items()})
unusable_dims = (
set(subset.keys())
.difference(["techs", "locs"])
.difference(data[var].dims)
)
if unusable_dims:
raise exceptions.ModelError(
'Attempting to mask time based on technology {}, '
'but dimension(s) {} do not exist for parameter {}'.format(
tech, unusable_dims, var.name)
)
arr = split_loc_techs(data[var].copy()).loc[subset]
arr = arr.mean(dim=[i for i in arr.dims if i is not 'timesteps']).to_pandas()
return arr
time_res = d['_time_res'].to_series()
window_adj = int(self.config_model.opmode.window / d.attrs['time_res'])
steps = [self._sets['t'][i]
for i in range(len(self._sets['t']))
if (i % window_adj) == 0]
# Remove the last step - since we look forward at each step,
# it would take us beyond actually existing data
steps = steps[:-1]
node_vars = []
total_vars = []
cost_vars = []
d.attrs['time_res_sum'] = 0
# This will fail if the time range given is too short, i.e. there are
# no future timesteps to consider.
if len(steps) == 0:
raise exceptions.ModelError('Unable to solve iteratively with '
'current time subset and step-size')
self.generate_model(t_start=steps[0])
for index, step in enumerate(steps):
if index == 0:
self.solve(warmstart=False)
else:
self.t_start = step
self._set_t_end()
# Note: we don't update the timestep set, so it keeps the
# values it got on first construction. Instead,
# we use an offset when updating parameter data so that
# the correct values are read into the "incorrect" timesteps.
self.update_parameters(t_offset=step - steps[0])
self.solve(warmstart=iterative_warmstart)
self.load_results()
def combine_overrides(config_model, overrides):
override_dict = AttrDict()
for override in overrides:
try:
yaml_string = config_model.overrides[override].to_yaml()
override_with_imports = AttrDict.from_yaml_string(yaml_string)
except KeyError:
raise exceptions.ModelError(
'Override `{}` is not defined.'.format(override)
)
try:
override_dict.union(override_with_imports, allow_override=False)
except KeyError as e:
raise exceptions.ModelError(
str(e)[1:-1] + '. Already specified but defined again in '
'override `{}`.'.format(override)
)
return override_dict
def get_relevant_vars(array):
allowed_input_vars = [
k for k, v in model.inputs.data_vars.items()
if 'timesteps' in v.dims and len(v.dims) > 1
]
allowed_result_vars = (
['results', 'inputs', 'all', 'storage', 'resource_con', 'cost_var']
)
if ((isinstance(array, list) and not
set(array).intersection(allowed_input_vars + allowed_result_vars + carriers)) or
(isinstance(array, str) and
array not in allowed_input_vars + allowed_result_vars + carriers)):
raise exceptions.ModelError(
'Cannot plot array={}. If you want carrier flow (_prod, _con, _export) '
'then specify the name of the energy carrier as array'.format(array)
)
# relevant_vars are all variables relevant to this plotting instance
relevant_vars = []
# Ensure carriers are at the top of the list
if array == 'results':
relevant_vars += sorted(carriers) + sorted(allowed_result_vars)
elif array == 'inputs':
relevant_vars += sorted(allowed_input_vars)
elif array == 'all':
relevant_vars += sorted(carriers) + sorted(allowed_result_vars + allowed_input_vars)
elif isinstance(array, list):
relevant_vars = array