Skip to content

Commit

Permalink
Merge pull request #598 from EttoreZ/issue239_extendForecast
Browse files Browse the repository at this point in the history
Issue239 extend forecast
  • Loading branch information
EttoreZ authored Dec 13, 2023
2 parents fc742c9 + dff59a4 commit 34cf952
Show file tree
Hide file tree
Showing 10 changed files with 6,745 additions and 12 deletions.
67 changes: 55 additions & 12 deletions data/data_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -333,20 +333,36 @@ def get_data(self, horizon=24*3600, interval=None, index=None,
# the closest possible point under stop will be the end
# point in order to keep interval unchanged among index.
index = np.arange(start,stop+0.1,interval).astype(int)
else:
if not isinstance(index, np.ndarray):
index = np.asarray(index)

# Reindex to the desired index
data_slice_reindexed = data_slice.reindex(index)

for key in data_slice_reindexed.keys():
# Use linear interpolation for continuous variables
if key in self.categories['weather']:
f = interpolate.interp1d(self.case.data.index,
self.case.data[key], kind='linear')
# Use forward fill for discrete variables
else:
f = interpolate.interp1d(self.case.data.index,
self.case.data[key], kind='zero')
data_slice_reindexed.loc[:,key] = f(index)
start = index[0]
# 1 year in (s)
year = 31536000
# Starting year
year_start = int(np.floor(start/year))*year
# Normalizing index with respect to starting year
index_norm = index - year_start
stop_norm = index_norm[-1]
# If stop happens across the year divide df and interpolate separately
if stop_norm > data_slice.index[-1]:
idx_year = (np.abs(index_norm - year)).argmin() + 1
# Take previous index value if index at idx_year > year
if index_norm[idx_year - 1] - year > np.finfo(float).eps:
idx_year = idx_year -1
df_slice1 = data_slice.reindex(index_norm[:idx_year])
df_slice1 = self.interpolate_data(df_slice1,index_norm[:idx_year])
df_slice2 = data_slice.reindex(index_norm[idx_year:] - year)
df_slice2 = self.interpolate_data(df_slice2,index_norm[idx_year:] - year)
df_slice2.index = df_slice2.index + year
data_slice_reindexed = pd.concat([df_slice1,df_slice2])
else:
data_slice_reindexed = data_slice.reindex(index_norm)
data_slice_reindexed = self.interpolate_data(data_slice_reindexed,index_norm)
# Add starting year back to index desired by user
data_slice_reindexed.index = data_slice_reindexed.index + year_start

if plot:
if category is None:
Expand Down Expand Up @@ -503,7 +519,34 @@ def get_data_metadata(self):
data_metadata[key] = metadata

return data_metadata

def interpolate_data(self,df,index):
'''Interpolate testcase data.
Parameters
----------
df: pandas.DataFrame
Dataframe that needs to be interpolated
index: np.array()
Index to use to get interpolated data
Returns
-------
df: pandas.DataFrame
Interpolated dataframe
'''
for key in df.keys():
# Use linear interpolation for continuous variables
if key in self.categories['weather']:
f = interpolate.interp1d(self.case.data.index,
self.case.data[key], kind='linear')
# Use forward fill for discrete variables
else:
f = interpolate.interp1d(self.case.data.index,
self.case.data[key], kind='zero')
df.loc[:,key] = f(index)
return df

if __name__ == "__main__":
import sys
Expand Down
1,886 changes: 1,886 additions & 0 deletions testing/references/data/testcase2/tc2_data_retrieved_over_year.csv

Large diffs are not rendered by default.

1,886 changes: 1,886 additions & 0 deletions testing/references/data/testcase3/tc3_data_retrieved_over_year.csv

Large diffs are not rendered by default.

1,406 changes: 1,406 additions & 0 deletions testing/references/forecast/testcase2/tc2_forecast_over_year.csv

Large diffs are not rendered by default.

1,406 changes: 1,406 additions & 0 deletions testing/references/forecast/testcase3/tc3_forecast_over_year.csv

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions testing/references/testcase2/advance_over_year.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
keys,value
CO2RooAir_y,123.1382838102673
PCoo_y,0.0
PFan_y,0.8739606953892677
PHea_y,1844.306909142125
PPum_y,0.0
TRooAir_y,295.1440582575692
oveTSetRooCoo_activate,0.0
oveTSetRooCoo_u,296.15
oveTSetRooHea_activate,0.0
oveTSetRooHea_u,295.15
time,31537800.0
6 changes: 6 additions & 0 deletions testing/references/testcase2/put_forecast_over_year.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
time,EmissionsBiomassPower,EmissionsDistrictHeatingPower,EmissionsElectricPower,EmissionsGasPower,EmissionsSolarThermalPower,HDifHor,HDirNor,HGloHor,HHorIR,InternalGainsCon[1],InternalGainsLat[1],InternalGainsRad[1],LowerSetp[1],Occupancy[1],PriceBiomassPower,PriceDistrictHeatingPower,PriceElectricPowerConstant,PriceElectricPowerDynamic,PriceElectricPowerHighlyDynamic,PriceGasPower,PriceSolarThermalPower,TBlaSky,TDewPoi,TDryBul,TWetBul,UpperCO2[1],UpperSetp[1],ceiHei,cloTim,lat,lon,nOpa,nTot,pAtm,relHum,solAlt,solDec,solHouAng,solTim,solZen,winDir,winSpe
31534200,0.0,0.1,0.5,0.2,0.0,0.0,0.0,0.0,245.708333333,19.2,9.6,28.8,295.15,0.0,0.2,0.1,0.2,0.1,-0.0776457135308,0.07,0.0,256.636351915,259.379166667,272.625,268.72819641,894.0,296.15,31452.875,31534200.0,0.693942910593,-1.83015225364,0.3875,0.775,101325.0,0.317916666667,-1.25485882436,-0.4032265228,2290.07494135,31533990.938,2.82565515116,1.82168740677,1.7675
31536000,0.0,0.1,0.5,0.2,0.0,0.0,0.0,0.0,245.0,19.2,9.6,28.8,295.15,0.0,0.2,0.1,0.2,0.1,2.6470940280699998e-14,0.07,0.0,256.473613407,259.15,272.45,268.540745643,894.0,296.15,36600.0,31536000.0,0.693942910593,-1.83015225364,0.4,0.8,101325.0,0.31,-1.27976763694,-0.403200665926,2290.20580064,31535790.3823,2.85056396373,1.91986217719,2.1
31537800,0.0,0.1,0.5,0.2,0.0,0.0,0.0,0.0,251.5,19.2,9.6,28.8,295.15,0.0,0.2,0.1,0.2,0.1,0.0,0.07,0.0,257.868968045,266.025,273.15,270.496356538,894.0,296.15,77777.0,1800.0,0.693942910593,-1.83015225364,0.225,0.525,101325.0,0.54,-1.26316008346,-0.402859568716,-3.02402826328,1616.62641254,2.83395641025,3.44266194956,2.525
31539600,0.0,0.1,0.5,0.2,0.0,0.0,0.0,0.0,253.0,19.2,9.6,28.8,295.15,0.0,0.2,0.1,0.2,0.1,0.0776457135308,0.07,0.0,258.454386802,266.55,273.15,270.675045605,894.0,296.15,77777.0,3600.0,0.693942910593,-1.83015225364,0.3,0.7,101325.0,0.57,-1.21170311874,-0.402832949277,-2.89316937192,3416.06533739,2.78249944554,3.54301838155,2.8
31541400,0.0,0.1,0.5,0.2,0.0,0.0,0.0,0.0,254.375,19.2,9.6,28.8,295.15,0.0,0.2,0.1,0.2,0.1,0.0776457135308,0.07,0.0,258.910390202,266.957720588,273.15,270.815940601,894.0,296.15,77777.0,5400.0,0.693942910593,-1.83015225364,0.36875,0.84125,101325.0,0.59375,-1.1376691186,-0.402806275407,-2.76231047229,5215.50437585,2.70846544539,3.59319659754,3.06875
20 changes: 20 additions & 0 deletions testing/test_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,22 @@ def test_get_data_index(self):
# Check the data retrieved with the manager
df_man = pd.DataFrame(data_dict).set_index('time')
self.compare_ref_timeseries_df(df_man, self.ref_data_index)

def test_get_data_over_year(self):
'''Check that the data manager can retrieve the test case data
when an arbitrary time index across the year is provided.
'''

# Define index
index = np.arange(362*24*3600, (362+7)*24*3600, 321)

# Get the data
data_dict = self.man.get_data(index=index)

# Check the data retrieved with the manager
df_man = pd.DataFrame(data_dict).set_index('time')
self.compare_ref_timeseries_df(df_man, self.ref_data_over_year)

class DataManagerSingleZoneTest(unittest.TestCase, utilities.partialChecks,
PartialDataManagerTest):
Expand Down Expand Up @@ -321,6 +337,8 @@ def setUp(self):
'references', 'data', 'testcase2', 'tc2_data_retrieved_default.csv')
self.ref_data_index = os.path.join(testing_root_dir,
'references', 'data', 'testcase2', 'tc2_data_retrieved_index.csv')
self.ref_data_over_year = os.path.join(testing_root_dir,
'references', 'data', 'testcase2', 'tc2_data_retrieved_over_year.csv')

class DataManagerMultiZoneTest(unittest.TestCase, utilities.partialChecks,
PartialDataManagerTest):
Expand Down Expand Up @@ -352,6 +370,8 @@ def setUp(self):
'references', 'data', 'testcase3', 'tc3_data_retrieved_default.csv')
self.ref_data_index = os.path.join(testing_root_dir,
'references', 'data', 'testcase3', 'tc3_data_retrieved_index.csv')
self.ref_data_over_year = os.path.join(testing_root_dir,
'references', 'data', 'testcase3', 'tc3_data_retrieved_over_year.csv')

class FindDaysTest(unittest.TestCase, utilities.partialChecks):
'''Tests module to find peak and typical heating and cooling
Expand Down
24 changes: 24 additions & 0 deletions testing/test_forecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,24 @@ def test_get_forecast_interval(self):
# Check the forecast
df_forecaster = pd.DataFrame(forecast).set_index('time')
self.compare_ref_timeseries_df(df_forecaster, ref_filepath)

def test_get_forecast_over_year(self):
'''Check that the forecaster is able to retrieve the data across
the year
'''
self.case.initialize(364*24*3600, 0)
# Load the data into the test case
forecast = self.forecaster.get_forecast(self.forecast_points,
horizon=2*24*3600,
interval=123)

# Set reference file path
ref_filepath = self.ref_forecast_over_year

# Check the forecast
df_forecaster = pd.DataFrame(forecast).set_index('time')
self.compare_ref_timeseries_df(df_forecaster, ref_filepath)

class ForecasterSingleZoneTest(unittest.TestCase, utilities.partialChecks,
PartialForecasterTest):
Expand Down Expand Up @@ -91,6 +109,9 @@ def setUp(self):

self.ref_forecast_interval = os.path.join(utilities.get_root_path(),
'testing', 'references', 'forecast', 'testcase2', 'tc2_forecast_interval.csv')

self.ref_forecast_over_year = os.path.join(utilities.get_root_path(),
'testing', 'references', 'forecast', 'testcase2', 'tc2_forecast_over_year.csv')

class ForecasterMultiZoneTest(unittest.TestCase, utilities.partialChecks,
PartialForecasterTest):
Expand Down Expand Up @@ -120,6 +141,9 @@ def setUp(self):

self.ref_forecast_interval = os.path.join(utilities.get_root_path(),
'testing', 'references', 'forecast', 'testcase3', 'tc3_forecast_interval.csv')

self.ref_forecast_over_year = os.path.join(utilities.get_root_path(),
'testing', 'references', 'forecast', 'testcase3', 'tc3_forecast_over_year.csv')

if __name__ == '__main__':
utilities.run_tests(os.path.basename(__file__))
44 changes: 44 additions & 0 deletions testing/test_testcase2.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,5 +174,49 @@ def setUp(self):
self.measurement = 'PFan_y'
self.forecast_point = 'EmissionsBiomassPower'

class SimOverYear(unittest.TestCase, utilities.partialChecks):
'''Test if testcase can simulate across the year and retrieve forecasts.
'''

def setUp(self):
'''Setup for each test.
'''

self.url = 'http://127.0.0.1:5000'

def test_advance_over_year(self):
'''Tests that simulation can advance over one year.
'''

# Run test
requests.put('{0}/initialize'.format(self.url), json={'start_time':365*24*3600 - 1800, 'warmup_period':0})
y = requests.post('{0}/advance'.format(self.url), json={}).json()['payload']
# Check trajectories
df = pd.DataFrame.from_dict(y, orient = 'index', columns=['value'])
df.index.name = 'keys'
ref_filepath = os.path.join(utilities.get_root_path(), 'testing', 'references', 'testcase2', 'advance_over_year.csv')
self.compare_ref_values_df(df, ref_filepath)

def test_put_forecast_over_year(self):
'''Tests that forecast across the year can be retrived.
'''

horizon = 7200
interval = 1800
# Initialize
requests.put('{0}/initialize'.format(self.url), json={'start_time':365*24*3600 - 1800, 'warmup_period':0})
# Test case forecast
forecast_points = list(requests.get('{0}/forecast_points'.format(self.url)).json()['payload'].keys())
forecast = requests.put('{0}/forecast'.format(self.url), json={'point_names':forecast_points, 'horizon':horizon, 'interval':interval}).json()['payload']
df_forecaster = pd.DataFrame(forecast).set_index('time')
# Set reference file path
ref_filepath = os.path.join(utilities.get_root_path(), 'testing', 'references', 'testcase2', 'put_forecast_over_year.csv')
# Check the forecast
self.compare_ref_timeseries_df(df_forecaster, ref_filepath)

if __name__ == '__main__':
utilities.run_tests(os.path.basename(__file__))

0 comments on commit 34cf952

Please sign in to comment.