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

Multi year ramp 2024 #158

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
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
121 changes: 106 additions & 15 deletions ramp/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ def __init__(
if self.random_seed:
random.seed(self.random_seed)


@property
def date_start(self):
"""Start date of the daily profiles generated by the UseCase instance"""
Expand Down Expand Up @@ -386,8 +387,9 @@ def calc_peak_time_range(self, peak_enlarge=None):
# The peak_time is randomly enlarged based on the calibration parameter peak_enlarge
return np.arange(peak_time - rand_peak_enlarge, peak_time + rand_peak_enlarge)

"""Added a new input here: num_years"""
def generate_daily_load_profiles(
self, days=None, flat=True, cases=None, verbose=False
self, days=None, flat=True, cases=None, verbose=False, num_years = 1, num_user_lim = None, num_app_lim = None, promotion = 'no'
):
"""
Iterate over the days and generate a daily profile for each of the days
Expand All @@ -407,14 +409,87 @@ def generate_daily_load_profiles(
-------
daily_profiles: numpy array
"""
if cases is not None:
# =============================================================================
# if cases is not None:
# results = {}
# for case in cases:
# profiles = self.generate_daily_load_profiles(days=days, flat=True)
# results[f"case {case}"] = pd.Series(
# index=self.datetimeindex, data=profiles
# )
# answer = Plot(pd.concat(results, axis=1))
# =============================================================================
if num_years > 1:
if promotion == 'yes': #add new appliances if the promotion year has come
app_prom_df = pd.read_excel("Appliance_promotion_example.xlsx")
results = {}
for case in cases:
profiles = self.generate_daily_load_profiles(days=days, flat=True)
results[f"case {case}"] = pd.Series(
original_user_info = {}
new_user_info = {}
for y in range(num_years):
#print("Year ",y)
#print("Number of days: ", self.days)
for user in self.users: #for each user category
#increase the number of users in the user category based on the uniform distribution for all users
if user.num_users < num_user_lim[user.user_name]:
#print("The old number of users: ",user.user_name, user.num_users)
user_increase = int(np.heaviside(y,0)*round(random.uniform(0,3))) # heaviside function is used to make sure that no increases are made in year 0
if user.num_users + user_increase > num_user_lim[user.user_name]:
user_increase = num_user_lim[user.user_name] - user.num_users
user.num_users = random.choice([user.num_users,user.num_users+user_increase])
#print("The new number of users:", user.num_users,"\nUser Increase:", user_increase)
#if user.num_users == num_user_lim[user.user_name]:
# print("Maximum number of users reached")

for app in user.App_list:
if app.number < num_app_lim[app.name]:
#print("The old number of apps: ",app.name, app.number)
app_increase = int(np.heaviside(y,0)*round(random.uniform(0,3)))
if app.number + app_increase > num_app_lim[app.name]:
app_increase = num_app_lim[app.name] - app.number
app.number = random.choice([app.number,app.number+app_increase])
#print("The new number of apps: ",app.number,"\nApp increase: ",app_increase)
#if app.number == num_app_lim[app.name]:
#print("Max number of appliances reached")
for user in self.users:
for n_prom in range(app_prom_df.shape[0]):
if app_prom_df.loc[n_prom,'promotee_name'] == user.user_name and app_prom_df.loc[n_prom,'promotion_year'] == y: #check which appliances have to be promoted
user_new = User(user.user_name + "_promotion", user.num_users, user.user_preference)
self.add_user(user_new)
user_new.add_appliance(
number=int(app_prom_df.loc[n_prom,'number']),
power=float(app_prom_df.loc[n_prom,'power']),
num_windows=int(app_prom_df.loc[n_prom,'num_windows']),
func_time=int(app_prom_df.loc[n_prom,'func_time']),
time_fraction_random_variability=float(app_prom_df.loc[n_prom,'time_fraction_random_variability']),
func_cycle=int(app_prom_df.loc[n_prom,'func_cycle']),
#fixed=app_prom_df.loc[n_prom,'fixed'],
#flat=app_prom_df.loc[n_prom,'flat'],
name=app_prom_df.loc[n_prom,'name'],
occasional_use=float(app_prom_df.loc[n_prom,'occasional_use']),
window_1 = np.array([app_prom_df.loc[n_prom,'window_1_start'],app_prom_df.loc[n_prom,'window_1_end']],dtype=np.intc),
window_2 = np.array([app_prom_df.loc[n_prom,'window_2_start'],app_prom_df.loc[n_prom,'window_2_end']],dtype=np.intc),
window_3 = np.array([app_prom_df.loc[n_prom,'window_3_start'],app_prom_df.loc[n_prom,'window_3_end']],dtype=np.intc),
random_var_w = float(app_prom_df.loc[n_prom,'random_var_w'])
)
#temp_inst.windows([20*60, 24*60], random_var_w=0.3)
# =============================================================================
# if y == 0:
# for user in self.users:
# original_user_info[user.user_name] = user.num_users
# elif y == num_years-1:
# for user in self.users:
# new_user_info[user.user_name] = user.num_users
# print(user.App_list)
# print(original_user_info)
# print(new_user_info)
# =============================================================================
self.save("multiyear output year " + str(y)) # just for checking the use_case. Can be commented out
profiles = self.generate_daily_load_profiles(days=days, flat=True, num_years = 1)
results[f"y {y}"] = pd.Series(
index=self.datetimeindex, data=profiles
)
answer = Plot(pd.concat(results, axis=1))

answer = pd.concat(results, axis=1)
else:
if self.days is None:
if days is not None:
Expand Down Expand Up @@ -613,30 +688,30 @@ def load(self, filename: str) -> None:

# assign windows arguments
for k in WINDOWS_PARAMETERS:
if "window" in k:
w_start = row.get(k + "_start", np.NaN)
w_end = row.get(k + "_end", np.NaN)
if "window" in k:
w_start = row.get(k + "_start", np.nan)
w_end = row.get(k + "_end", np.nan)
if not np.isnan(w_start) and not np.isnan(w_end):
appliance_parameters[k] = np.array(
[w_start, w_end], dtype=np.intc
)
else:
val = row.get(k, np.NaN)
val = row.get(k, np.nan)
if not np.isnan(val):
appliance_parameters[k] = val

# assign duty cycles arguments
for duty_cycle_params in DUTY_CYCLE_PARAMETERS:
for k in duty_cycle_params:
if "cw" in k:
cw_start = row.get(k + "_start", np.NaN)
cw_end = row.get(k + "_end", np.NaN)
cw_start = row.get(k + "_start", np.nan)
cw_end = row.get(k + "_end", np.nan)
if not np.isnan(cw_start) and not np.isnan(cw_end):
appliance_parameters[k] = np.array(
[cw_start, cw_end], dtype=np.intc
)
else:
val = row.get(k, np.NaN)
val = row.get(k, np.nan)
if not np.isnan(val):
appliance_parameters[k] = val

Expand Down Expand Up @@ -667,7 +742,8 @@ def __init__(
# TODO check type of Usecase
self.usecase = usecase
self.user_name = user_name
self.num_users = num_users
"""Changed self.num_users = num_users to self._num_users = num_users"""
self._num_users = num_users
self.user_preference = user_preference
self.rand_daily_pref = 0
self.load = None
Expand Down Expand Up @@ -822,6 +898,16 @@ def num_days(self):
if self.usecase.is_initialized is True:
answer = self.usecase.num_days
return answer

"""Added a new propery with a setter: num_users"""
@property
def num_users(self):
return self._num_users

@num_users.setter
def num_users(self, new_num_users):
self._num_users = new_num_users


def save(self, filename: str = None) -> Union[pd.DataFrame, None]:
"""Saves/returns the model database including all appliances as a single pd.DataFrame or excel file.
Expand Down Expand Up @@ -1046,7 +1132,7 @@ def generate_aggregated_load_profile(
"""

self.load = np.zeros(1440) # initialise empty load for User instance
for _ in range(self.num_users):
for _ in range(self._num_users):
# iterates for every single user within a User class.
self.load = self.load + self.generate_single_load_profile(
prof_i, peak_time_range, day_type
Expand Down Expand Up @@ -1317,6 +1403,11 @@ def __eq__(self, other_appliance) -> bool:
answer = np.array([])
for attribute in APPLIANCE_ATTRIBUTES:
if hasattr(self, attribute) and hasattr(other_appliance, attribute):
#nice_attr = getattr(self, attribute)
#print(nice_attr)
#nice_other_attr = getattr(other_appliance, attribute)
#print(nice_other_attr)
#print("attribute is:", attribute)
answer = np.append(
answer,
[getattr(self, attribute) == getattr(other_appliance, attribute)],
Expand Down