-
Notifications
You must be signed in to change notification settings - Fork 66
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
Enable user to import weather file as .dat #3713
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -74,6 +74,47 @@ def copy_weather_file(source_weather_file, locator): | |||||||||||||||||||||||||||||||||||||||||||
source_weather_file=source_weather_file | ||||||||||||||||||||||||||||||||||||||||||||
)) | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
def parse_dat_weather_file(source_dat_file, output_epw_file): | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
convert a DWD .dat-file to a epw-file | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would you be able to add the header definitions of the .dat file in english in the function's docstring as well. I think this would help others understand the provided columns when debugging this in the future.
|
||||||||||||||||||||||||||||||||||||||||||||
:param string source_dat_file: source .dat | ||||||||||||||||||||||||||||||||||||||||||||
:param string output_epw_file: output EPW | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
import pandas as pd | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
print(f"Parsing .dat file: {source_dat_file}") | ||||||||||||||||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||||||||||||||||
weather_data = pd.read_csv(source_dat_file, sep="\s+", skiprows=6, header=None) | ||||||||||||||||||||||||||||||||||||||||||||
weather_data.columns = ['RW', 'HW', 'MM', 'DD', 'HH', 't', 'p', 'WR', 'WG', 'N', 'x', 'RF', 'B', 'D', 'A', 'E', | ||||||||||||||||||||||||||||||||||||||||||||
'IL'] | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+88
to
+90
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Based on the sample files that you provided, you could do the following instead.
Suggested change
This would skip all the comment header lines and read the provided column names from the file. We could use the list of column names to compare with the dataframe to make sure that whatever that is read is correct. e.g. dat_columns = ['RW', 'HW', 'MM', 'DD', 'HH', 't', 'p', 'WR', 'WG', 'N', 'x', 'RF', 'B', 'D', 'A', 'E', 'IL']
if not set(dat_columns) == set(weather_data.columns):
raise ValueError("Invalid .dat file") |
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
# from dat to epw | ||||||||||||||||||||||||||||||||||||||||||||
with open(output_epw_file, 'w') as epw_file: | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("LOCATION,Weimar,-,DEU,SRC-TMYx,105550,50.983,11.317,1,268\n") | ||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace hardcoded location with configurable parameters The location information is hardcoded for Weimar, Germany. This limits the function's reusability for other locations. Consider adding location parameters to the function signature: -def parse_dat_weather_file(source_dat_file, output_epw_file):
+def parse_dat_weather_file(source_dat_file, output_epw_file, location_name="Weimar", country="DEU",
+ latitude=50.983, longitude=11.317, elevation=268): Then update the location line: - epw_file.write("LOCATION,Weimar,-,DEU,SRC-TMYx,105550,50.983,11.317,1,268\n")
+ epw_file.write(f"LOCATION,{location_name},-,{country},SRC-TMYx,105550,{latitude},{longitude},1,{elevation}\n")
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You would need to remove these hardcoded values and use the correct values that are included in the comment header of the .dat file (the first 5 lines of the .dat file if I am not wrong). This is important for DAYSIM to know where to position the scene during raytracing.
This comment was marked as off-topic.
Sorry, something went wrong. |
||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("DESIGN CONDITIONS,0\n") | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("TYPICAL/EXTREME PERIODS,0\n") | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("GROUND TEMPERATURES,0\n") | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("HOLIDAYS/DAYLIGHT SAVINGS,No,0,0,0\n") | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("COMMENTS 1, converted from .dat to .epw by CEA\n") | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("COMMENTS 2\n") | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write("DATA PERIODS,1,1,Data,Tuesday,1/1,12/31\n") | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
for _, row in weather_data.iterrows(): | ||||||||||||||||||||||||||||||||||||||||||||
mm = int(row['MM']) | ||||||||||||||||||||||||||||||||||||||||||||
dd = int(row['DD']) | ||||||||||||||||||||||||||||||||||||||||||||
hh = int(row['HH']) | ||||||||||||||||||||||||||||||||||||||||||||
epw_line = f"1958,{mm},{dd},{hh},60,B8E7B8B8?9?0?0?0?0?0?0B8B8B8B8?0?0F8F8A7E7, " \ | ||||||||||||||||||||||||||||||||||||||||||||
f"{row['t']},99,99,{row['RF']}, {row['p']}, 9999, {row['A']}, {row['D']}, {row['B']}, {row['D']}," \ | ||||||||||||||||||||||||||||||||||||||||||||
f"-9999, -9999, -9999, -9999,{row['WR']}, {row['WG']}, 99, 9999, 9999, 9999,0, 999999999,0," \ | ||||||||||||||||||||||||||||||||||||||||||||
f" -999,-999,-999\n" | ||||||||||||||||||||||||||||||||||||||||||||
epw_file.write(epw_line) | ||||||||||||||||||||||||||||||||||||||||||||
reyery marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||
+ except pd.errors.EmptyDataError as e: | ||||||||||||||||||||||||||||||||||||||||||||
+ raise ValueError("The .dat file is empty or has incorrect format") from e | ||||||||||||||||||||||||||||||||||||||||||||
+ except pd.errors.ParserError as e: | ||||||||||||||||||||||||||||||||||||||||||||
+ raise ValueError("Failed to parse the .dat file - invalid format") from e | ||||||||||||||||||||||||||||||||||||||||||||
+ except Exception as e: | ||||||||||||||||||||||||||||||||||||||||||||
+ raise ValueError(f"Unexpected error while parsing .dat file: {str(e)}") from e | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+112
to
+117
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There are additional characters at the start of these lines that have to be removed. |
||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
def main(config): | ||||||||||||||||||||||||||||||||||||||||||||
""" | ||||||||||||||||||||||||||||||||||||||||||||
|
@@ -85,7 +126,13 @@ def main(config): | |||||||||||||||||||||||||||||||||||||||||||
locator = cea.inputlocator.InputLocator(config.scenario) | ||||||||||||||||||||||||||||||||||||||||||||
weather = config.weather_helper.weather | ||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||
if config.weather_helper.weather == 'climate.onebuilding.org': | ||||||||||||||||||||||||||||||||||||||||||||
if weather.endswith('.dat'): | ||||||||||||||||||||||||||||||||||||||||||||
print(f"Detected .dat file: {weather}") | ||||||||||||||||||||||||||||||||||||||||||||
# convert .dat in .epw | ||||||||||||||||||||||||||||||||||||||||||||
dat_weather_file = weather | ||||||||||||||||||||||||||||||||||||||||||||
epw_weather_file = locator.get_weather_file() | ||||||||||||||||||||||||||||||||||||||||||||
parse_dat_weather_file(dat_weather_file, epw_weather_file) | ||||||||||||||||||||||||||||||||||||||||||||
elif config.weather_helper.weather == 'climate.onebuilding.org': | ||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+129
to
+135
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add file validation and error handling The .dat file handling needs additional validation and cleanup. if weather.endswith('.dat'):
+ if not os.path.exists(weather):
+ raise ValueError(f"Weather file not found: {weather}")
print(f"Detected .dat file: {weather}")
- # convert .dat in .epw
dat_weather_file = weather
epw_weather_file = locator.get_weather_file()
+ try:
parse_dat_weather_file(dat_weather_file, epw_weather_file)
+ except Exception as e:
+ # Clean up any partially written EPW file
+ if os.path.exists(epw_weather_file):
+ os.remove(epw_weather_file)
+ raise 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||
print("No weather provided, fetching from online sources.") | ||||||||||||||||||||||||||||||||||||||||||||
fetch_weather_data(locator.get_weather_file(), locator.get_zone_geometry()) | ||||||||||||||||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||||||||||||||||
|
This comment was marked as off-topic.
Sorry, something went wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Mar-Ges we should only return the path of the file when parsing the weather path parameter in the config. The conversion would be done inside the weather-helper instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.