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
« 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
6class PostprocessingUtils:
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
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
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
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')
61 return res_df
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
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
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()
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()