Coverage for bim2sim/plugins/PluginEnergyPlus/bim2sim_energyplus/utils/utils_postprocessing.py: 0%

117 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-03-12 17:09 +0000

1import pandas as pd 

2from matplotlib import pyplot as plt 

3import datetime as dt 

4 

5 

6class PostprocessingUtils: 

7 

8 @staticmethod 

9 def _string_to_datetime(date_str): 

10 """ 

11 Converts a date string in the format MM:DD hh:mm:ss into a datetime 

12 object. 

13 :param date_str: A date string in the specified format. 

14 :return: The converted datetime object. 

15 """ 

16 date_str = date_str.strip() 

17 # datetime_df = None 

18 

19 if date_str[7:9] != '24': 

20 timestamp = pd.to_datetime(date_str, format='%m/%d %H:%M:%S') 

21 else: 

22 # If the time is 24, set it to 0 and increment day by 1 

23 date_str = date_str[0:7] + '00' + date_str[9:] 

24 timestamp = pd.to_datetime(date_str, format='%m/%d %H:%M:%S') +\ 

25 pd.Timedelta(days=1) 

26 return timestamp 

27 

28 @staticmethod 

29 def _extract_cols_from_df(df, col_name_part): 

30 """ 

31 extract columns from an energyplus result dataframe based on parts 

32 of the column name 

33 """ 

34 col = [col for col in df.columns if col_name_part in col] 

35 return_df = df[col].copy() 

36 return_df["Date/Time"] = df["Date/Time"].copy() 

37 return_df = return_df.set_index("Date/Time", drop=True).dropna() 

38 return return_df 

39 

40 @staticmethod 

41 def read_csv_and_format_datetime(csv_name): 

42 res_df = pd.read_csv(csv_name) 

43 res_df["Date/Time"] = res_df["Date/Time"].apply( 

44 PostprocessingUtils._string_to_datetime) 

45 # correct the year based on the length to something useful. This is 

46 # needed to make plotting easier in the later processes 

47 if len(res_df["Date/Time"]) > 8761: 

48 new_year = 2020 

49 else: 

50 new_year = 2021 

51 original_year = res_df["Date/Time"][0].year 

52 res_df["Date/Time"] = res_df["Date/Time"].map( 

53 lambda x: x.replace(year=new_year) if x.year == original_year 

54 else x.replace(year=new_year+1) 

55 ) 

56 # set the index 

57 res_df = res_df.set_index('Date/Time', drop=True) 

58 # drops the year and reformats 

59 # res_df['Date/Time'] = res_df['Date/Time'].dt.strftime('%m/%d-%H:%M:%S') 

60 

61 return res_df 

62 

63 @staticmethod 

64 def shift_dataframe_to_midnight(df): 

65 # Shift the datetime index backward by one hour 

66 df.index = df.index - pd.DateOffset(hours=1) 

67 return df 

68 

69 @staticmethod 

70 def export_df_for_webtool(csv_name): 

71 res_df = pd.read_csv(csv_name) 

72 res_df["Date/Time"] = res_df["Date/Time"].apply( 

73 PostprocessingUtils._string_to_datetime) 

74 res_df['Date/Time'] = res_df['Date/Time'].dt.strftime('%m-%d ' 

75 '%H:%M:%S') # drops the year 

76 export_df = pd.DataFrame(index=res_df['Date/Time']) 

77 zone_cooling_rates_W = PostprocessingUtils._extract_cols_from_df( 

78 res_df, 'Zone Ideal Loads Zone Total Cooling Rate [W]') 

79 zone_heating_rates_W = PostprocessingUtils._extract_cols_from_df( 

80 res_df, 'Zone Ideal Loads Zone Total Heating Rate [W]') 

81 export_df['heat_demand_kW'] = zone_heating_rates_W.sum(axis=1) / 1000 

82 export_df['cooling_demand_kW'] = zone_cooling_rates_W.sum(axis=1) / \ 

83 1000 

84 return export_df 

85 

86 @staticmethod 

87 def _visualize_results(csv_name, period="week", number=28, date=False): 

88 """ 

89 Plot Zone Mean Air Temperature (Hourly) vs Outdoor Temperature per 

90 zone and as an overview on all zones. 

91 :param csv_name: path to energyplus outputs (eplusout.csv) 

92 :param period: choose plotting period ( 

93 "year"/"month"/"week"/"day"/"date") 

94 :param number: choose number of day or week (0...365 (day) or 0...52 

95 (week)) 

96 :param date: only required if period == date. enter date in format 

97 date=[int(month), int(day)] 

98 :return: 

99 """ 

100 res_df = pd.read_csv(csv_name) 

101 res_df["Date/Time"] = res_df["Date/Time"].apply( 

102 PostprocessingUtils._string_to_datetime) 

103 # df = res_df.loc[:, ~res_df.columns.str.contains('Surface Inside 

104 # Face Temperature'] 

105 zone_mean_air = PostprocessingUtils._extract_cols_from_df(res_df, 

106 "Zone Mean " 

107 "Air " 

108 "Temperature") 

109 ideal_loads = PostprocessingUtils._extract_cols_from_df(res_df, 

110 "IDEAL LOADS " 

111 "AIR " 

112 "SYSTEM:Zone " 

113 "Ideal Loads " 

114 "Zone " 

115 "Sensible") 

116 equip_rate = PostprocessingUtils._extract_cols_from_df(res_df, 

117 "Zone " 

118 "Electric " 

119 "Equipment " 

120 "Convective " 

121 "Heating Rate") 

122 people_rate = PostprocessingUtils._extract_cols_from_df(res_df, 

123 "Zone People " 

124 "Convective " 

125 "Heating Rate") 

126 rad_dir = PostprocessingUtils._extract_cols_from_df(res_df, 

127 "Site Direct " 

128 "Solar Radiation " 

129 "Rate per Area") 

130 # rad_dir_h = rad_dir.resample('1h').mean() 

131 temp = PostprocessingUtils._extract_cols_from_df(res_df, 

132 "Outdoor Air " 

133 "Drybulb " 

134 "Temperature [C](" 

135 "Hourly)") 

136 t_mean = temp.resample('24h').mean() 

137 zone_id_list = [] 

138 for col in zone_mean_air.columns: 

139 z_id = col.partition(':') 

140 if z_id[0] not in zone_id_list: 

141 zone_id_list.append(z_id[0]) 

142 if period == "year": 

143 for col in zone_mean_air.columns: 

144 ax = zone_mean_air.plot(y=[col], figsize=(10, 5), grid=True) 

145 # temp.plot(ax=ax) 

146 t_mean.plot(ax=ax) 

147 plt.show() 

148 axc = zone_mean_air.iloc[:].plot(figsize=(10, 5), grid=True) 

149 t_mean.iloc[:].plot(ax=axc) 

150 plt.show() 

151 return 

152 elif period == "month": 

153 for col in zone_mean_air.columns: 

154 ax = zone_mean_air[zone_mean_air.index.month == number].plot( 

155 y=[col], figsize=(10, 5), grid=True) 

156 # temp.plot(ax=ax) 

157 temp[temp.index.month == number].plot(ax=ax) 

158 plt.show() 

159 axc = zone_mean_air[zone_mean_air.index.month == number].plot( 

160 figsize=(10, 5), grid=True) 

161 temp[temp.index.month == number].plot(ax=axc) 

162 plt.show() 

163 return 

164 elif period == "date": 

165 month = date[0] 

166 day = date[1] 

167 for col in zone_mean_air.columns: 

168 ax = zone_mean_air.loc[ 

169 ((zone_mean_air.index.month == month) 

170 & (zone_mean_air.index.day == day))] \ 

171 .plot(y=[col], figsize=(10, 5), grid=True) 

172 # temp.plot(ax=ax) 

173 temp.loc[((temp.index.month == month) 

174 & (temp.index.day == day))].plot(ax=ax) 

175 plt.show() 

176 axc = zone_mean_air.loc[((zone_mean_air.index.month == month) 

177 & (zone_mean_air.index.day == day))] \ 

178 .plot(figsize=(10, 5), grid=True) 

179 temp.loc[((temp.index.month == month) 

180 & (temp.index.day == day))].plot(ax=axc) 

181 plt.show() 

182 return 

183 elif period == "week": 

184 min = number * 168 

185 max = (number + 1) * 168 

186 elif period == "day": 

187 min = number * 24 

188 max = (number + 1) * 24 

189 for col in zone_mean_air.columns: 

190 ax = zone_mean_air.iloc[min:max].plot(y=[col], figsize=(10, 

191 5), grid=True) 

192 # temp.plot(ax=ax) 

193 temp.iloc[min:max].plot(ax=ax) 

194 plt.show() 

195 axc = zone_mean_air.iloc[min:max].plot(figsize=(10, 5), grid=True) 

196 temp.iloc[min:max].plot(ax=axc) 

197 plt.show() 

198 

199 for zid in zone_id_list: 

200 fig, (ax1, ax2) = plt.subplots(2, sharex=True, figsize=(10, 8)) 

201 fig.suptitle("Zone " + zid, y=1.00) 

202 z_col = [col for col in ideal_loads.columns if zid in col] 

203 zma_col = [col for col in zone_mean_air.columns if zid in col] 

204 ideal_loads[z_col].iloc[min:max].plot(ax=ax1, grid=True) 

205 # ax1b = ax1.twinx() 

206 # rad_dir_h.iloc[min:max].plot(ax=ax1b) 

207 zone_mean_air[zma_col].iloc[min:max].plot(ax=ax2, grid=True, 

208 color='green') 

209 temp.iloc[min:max].plot(ax=ax2, color='black') 

210 ax1.set_title("Loads") 

211 ax2.set_title("Temperatures") 

212 ax1.autoscale() 

213 ax2.autoscale() 

214 fig.tight_layout(rect=[0, 0.03, 1, 0.8]) 

215 plt.show()