Skip to content

Commit

Permalink
fixing bugs (#26)
Browse files Browse the repository at this point in the history
* fixing bugs

(1) adapted `step` and `reset` logic in BuildingEnv to align with new treatment of episode_len; (2) alerts user when `block_size` is too large following split into seasons

* R

* Removing unnecessary files

* Removing unnecessary files

* updating test file
  • Loading branch information
ewilk0 authored May 31, 2024
1 parent a824756 commit 7288154
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 31 deletions.
32 changes: 17 additions & 15 deletions ...les/building/test_stochastic_generator.py → ...ples/building/test_building_stochastic.py
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import sys
sys.path.append("/Users/ethanwilk/Documents/sustaingym/sustaingym/envs/building")
from env import BuildingEnv
from utils import ParameterGenerator

Expand All @@ -7,15 +9,15 @@

from tqdm import tqdm

block_size = 24 # always in hours
episode_len = 365 # number of episodes in one year of data
time_res = 3600 # always in seconds
block_size = 12 # in hours
episode_len = 24 # number of timesteps in each episode
time_res = 3600 # resolution in seconds
summer_params = ParameterGenerator(
building="OfficeSmall",
weather="Hot_Dry",
location="Tucson",
stochastic_summer_percentage=1.0,
stochasic_generator_block_size=block_size,
stochastic_summer_percentage=1.,
block_size=block_size,
episode_len=episode_len,
time_res=time_res,
)
Expand All @@ -24,7 +26,7 @@
weather="Hot_Dry",
location="Tucson",
stochastic_summer_percentage=0.0,
stochasic_generator_block_size=block_size,
block_size=block_size,
episode_len=episode_len,
time_res=time_res,
)
Expand All @@ -44,15 +46,15 @@
winter_obs = []
neutral_obs = []

num_running_periods = episode_len
num_running_periods = 365
seed_start = None

print("Collecting weather data...")
for i in tqdm(range(num_running_periods)):
done = False
this_summer_obs, _ = summer_env.reset(seed=seed_start)
this_winter_obs, _ = winter_env.reset(seed=seed_start)
this_neutral_obs, _ = neutral_env.reset(seed=seed_start)
this_summer_obs, _ = summer_env.reset(seed=None)
this_winter_obs, _ = winter_env.reset(seed=None)
this_neutral_obs, _ = neutral_env.reset(seed=None)
if i == 0:
summer_obs = this_summer_obs.copy()
winter_obs = this_winter_obs.copy()
Expand All @@ -70,7 +72,7 @@
winter_obs = np.vstack((winter_obs, this_winter_obs))
neutral_obs = np.vstack((neutral_obs, this_neutral_obs))

ewm_periods = 30 # num_periods
ewm_periods = 100 # num_periods
feature_mappings = {
-2: "heat gain from irradiance",
-3: "ground temperature",
Expand All @@ -83,9 +85,9 @@
winter_series = pd.Series(winter_obs[:, ft_idx])
neutral_series = pd.Series(neutral_obs[:, ft_idx])

summer_ewma = summer_series.ewm(ewm_periods).mean() # [30:]
winter_ewma = winter_series.ewm(ewm_periods).mean() # [30:]
neutral_ewma = neutral_series.ewm(ewm_periods).mean() # [30:]
summer_ewma = summer_series.rolling(ewm_periods, center=True, min_periods=1).mean()
winter_ewma = winter_series.rolling(ewm_periods, center=True, min_periods=1).mean()
neutral_ewma = neutral_series.rolling(ewm_periods, center=True, min_periods=1).mean()

plt.figure()
plt.title(f"Summer vs. winter for {feature_mappings[ft_idx]}")
Expand All @@ -104,4 +106,4 @@
plt.xlabel("Time")
plt.ylabel("Feature value")
plt.legend()
plt.show()
plt.show()
22 changes: 11 additions & 11 deletions sustaingym/envs/building/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ def __init__(self, parameters: dict[str, Any]):
self.statelist: list[np.ndarray] = []
self.actionlist: list[np.ndarray] = []
self.epoch = 0
self.num_epoch_runs = 0

# Initialize zonal temperature
self.X_new = self.target
Expand Down Expand Up @@ -299,16 +300,13 @@ def step(

# Increment the epochs counter
self.epoch += 1
self.num_epoch_runs += 1

# Check if the environment has reached the end of the weather data
if (
self.epoch % (self.length_of_weather // self.episode_len) == 0
and self.epoch != 0
):
done = True
if self.epoch >= self.length_of_weather - 1:
done = True
if self.epoch >= self.length_of_weather:
self.epoch = 0
if self.num_epoch_runs >= self.episode_len:
done = True

# Return the new state, reward, done flag, and info
return self.state, reward, done, done, info
Expand Down Expand Up @@ -338,12 +336,14 @@ def reset(
super().reset(seed=seed, options=options)

# Initialize the episode counter
num_episodes = self.length_of_weather // self.episode_len
if seed is None:
episode = self.np_random.integers(low=0, high=num_episodes)
self.epoch = self.np_random.integers(low=0, high=self.length_of_weather-1)
else:
episode = seed % num_episodes
self.epoch = episode * self.episode_len
# uses seed to determine which observation of the year to map to
num_days_normalizer = ((self.episode_len * self.timestep) // 86_400) * 365
self.epoch = int((seed / num_days_normalizer) * self.length_of_weather)
self.epoch = min(self.epoch, self.length_of_weather-1)
self.num_epoch_runs = 0

# Initialize state and action lists
self.statelist = []
Expand Down
2 changes: 2 additions & 0 deletions sustaingym/envs/building/stochastic_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ def get_empirical_dist(

if block_size is None:
block_size = self.block_size

assert block_size < num_obs, "Block size should be less than number of obs"

mu_vectors = []
cov_matrices = []
Expand Down
15 changes: 10 additions & 5 deletions sustaingym/envs/building/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,11 @@ def generate_stochastic_ambient_features(
(block_size x num_rows, num_obs_features).
"""
generator = StochasticUncontrollableGenerator(block_size=block_size)
generator.split_observations_into_seasons(observation_data=data)
generator.get_empirical_dist(season='summer', block_size=block_size)
generator.get_empirical_dist(season='winter', block_size=block_size)
generator.split_observations_into_seasons(data=data)
generator.get_empirical_dist(season='summer')
generator.get_empirical_dist(season='winter')
samples = generator.draw_samples_from_dist(
num_samples=num_rows, summer_percentage=stochastic_summer_percentage)
num_samples=num_rows, summer_frac=stochastic_summer_percentage)
return samples


Expand All @@ -481,6 +481,7 @@ def ParameterGenerator(
root: str = "",
stochastic_summer_percentage: float | None = None,
episode_len: int = 288,
block_size: int = None
) -> dict[str, Any]:
"""Generates parameters from the selected building and temperature file for the env.
Expand Down Expand Up @@ -526,6 +527,9 @@ def ParameterGenerator(
distribution. None if not using stochastic features
episode_len: number of time steps in each episode (default: 288 steps at 5-min
time_res is 1 day)
block_size: size (in hours) of blocks of data to fit distributions to (e.g.,
block_size=24 will sample daily blocks of 24 hourly observations to
fit distributions to)
Returns:
parameters: Contains all parameters needed for environment initialization.
Expand Down Expand Up @@ -589,11 +593,12 @@ def ParameterGenerator(

if stochastic_summer_percentage is not None:
num_hours_per_episode = int(episode_len * time_res / 60 / 60)
this_block_size = block_size if block_size is not None else num_hours_per_episode
samples = generate_stochastic_ambient_features(
stochastic_summer_percentage,
len(all_data),
all_data,
block_size=num_hours_per_episode)
block_size=this_block_size)
oneyear = samples[:, 0]
oneyearrad = samples[:, 1]
all_ground_temp = samples[:, 2]
Expand Down

0 comments on commit 7288154

Please sign in to comment.