Skip to content

Commit 05fb26f

Browse files
ENH: allow to export EnvAnal profiles
1 parent f5edf69 commit 05fb26f

File tree

1 file changed

+196
-44
lines changed

1 file changed

+196
-44
lines changed

rocketpy/EnvironmentAnalysis.py

Lines changed: 196 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
__license__ = "MIT"
66

77
import bisect
8+
import json
89
import warnings
910
from collections import defaultdict
1011

@@ -2288,7 +2289,69 @@ def altitude_AGL_range(self):
22882289
max_altitude = np.min(max_altitudes)
22892290
return min_altitude, max_altitude
22902291

2291-
def process_wind_profile_over_average_day(self):
2292+
def process_temperature_profile_over_average_day(self):
2293+
"""Compute the average temperature profile for each available hour of a day, over all
2294+
days in the dataset."""
2295+
altitude_list = np.linspace(*self.altitude_AGL_range, 100)
2296+
2297+
average_temperature_profile_at_given_hour = {}
2298+
self.max_average_temperature_at_altitude = 0
2299+
hours = list(self.pressureLevelDataDict.values())[0].keys()
2300+
for hour in hours:
2301+
temperature_values_for_this_hour = []
2302+
for dayDict in self.pressureLevelDataDict.values():
2303+
try:
2304+
temperature_values_for_this_hour += [
2305+
dayDict[hour]["temperature"](altitude_list)
2306+
]
2307+
except KeyError:
2308+
# Some day does not have data for the desired hour
2309+
# No need to worry, just average over the other days
2310+
pass
2311+
mean_temperature_values_for_this_hour = np.mean(
2312+
temperature_values_for_this_hour, axis=0
2313+
)
2314+
average_temperature_profile_at_given_hour[hour] = [
2315+
mean_temperature_values_for_this_hour,
2316+
altitude_list,
2317+
]
2318+
max_temperature = np.max(mean_temperature_values_for_this_hour)
2319+
if max_temperature >= self.max_average_temperature_at_altitude:
2320+
self.max_average_temperature_at_altitude = max_temperature
2321+
self.average_temperature_profile_at_given_hour = average_temperature_profile_at_given_hour
2322+
2323+
def process_pressure_profile_over_average_day(self):
2324+
"""Compute the average pressure profile for each available hour of a day, over all
2325+
days in the dataset."""
2326+
altitude_list = np.linspace(*self.altitude_AGL_range, 100)
2327+
2328+
average_pressure_profile_at_given_hour = {}
2329+
self.max_average_pressure_at_altitude = 0
2330+
hours = list(self.pressureLevelDataDict.values())[0].keys()
2331+
for hour in hours:
2332+
pressure_values_for_this_hour = []
2333+
for dayDict in self.pressureLevelDataDict.values():
2334+
try:
2335+
pressure_values_for_this_hour += [
2336+
dayDict[hour]["pressure"](altitude_list)
2337+
]
2338+
except KeyError:
2339+
# Some day does not have data for the desired hour
2340+
# No need to worry, just average over the other days
2341+
pass
2342+
mean_pressure_values_for_this_hour = np.mean(
2343+
pressure_values_for_this_hour, axis=0
2344+
)
2345+
average_pressure_profile_at_given_hour[hour] = [
2346+
mean_pressure_values_for_this_hour,
2347+
altitude_list,
2348+
]
2349+
max_pressure = np.max(mean_pressure_values_for_this_hour)
2350+
if max_pressure >= self.max_average_pressure_at_altitude:
2351+
self.max_average_pressure_at_altitude = max_pressure
2352+
self.average_pressure_profile_at_given_hour = average_pressure_profile_at_given_hour
2353+
2354+
def process_wind_speed_profile_over_average_day(self):
22922355
"""Compute the average wind profile for each available hour of a day, over all
22932356
days in the dataset."""
22942357
altitude_list = np.linspace(*self.altitude_AGL_range, 100)
@@ -2319,9 +2382,71 @@ def process_wind_profile_over_average_day(self):
23192382
self.max_average_wind_at_altitude = max_wind
23202383
self.average_wind_profile_at_given_hour = average_wind_profile_at_given_hour
23212384

2385+
def process_wind_velocity_x_profile_over_average_day(self):
2386+
"""Compute the average windVelocityX profile for each available hour of a day, over all
2387+
days in the dataset."""
2388+
altitude_list = np.linspace(*self.altitude_AGL_range, 100)
2389+
2390+
average_windVelocityX_profile_at_given_hour = {}
2391+
self.max_average_windVelocityX_at_altitude = 0
2392+
hours = list(self.pressureLevelDataDict.values())[0].keys()
2393+
for hour in hours:
2394+
windVelocityX_values_for_this_hour = []
2395+
for dayDict in self.pressureLevelDataDict.values():
2396+
try:
2397+
windVelocityX_values_for_this_hour += [
2398+
dayDict[hour]["windVelocityX"](altitude_list)
2399+
]
2400+
except KeyError:
2401+
# Some day does not have data for the desired hour
2402+
# No need to worry, just average over the other days
2403+
pass
2404+
mean_windVelocityX_values_for_this_hour = np.mean(
2405+
windVelocityX_values_for_this_hour, axis=0
2406+
)
2407+
average_windVelocityX_profile_at_given_hour[hour] = [
2408+
mean_windVelocityX_values_for_this_hour,
2409+
altitude_list,
2410+
]
2411+
max_windVelocityX = np.max(mean_windVelocityX_values_for_this_hour)
2412+
if max_windVelocityX >= self.max_average_windVelocityX_at_altitude:
2413+
self.max_average_windVelocityX_at_altitude = max_windVelocityX
2414+
self.average_windVelocityX_profile_at_given_hour = average_windVelocityX_profile_at_given_hour
2415+
2416+
def process_wind_velocity_y_profile_over_average_day(self):
2417+
"""Compute the average windVelocityY profile for each available hour of a day, over all
2418+
days in the dataset."""
2419+
altitude_list = np.linspace(*self.altitude_AGL_range, 100)
2420+
2421+
average_windVelocityY_profile_at_given_hour = {}
2422+
self.max_average_windVelocityY_at_altitude = 0
2423+
hours = list(self.pressureLevelDataDict.values())[0].keys()
2424+
for hour in hours:
2425+
windVelocityY_values_for_this_hour = []
2426+
for dayDict in self.pressureLevelDataDict.values():
2427+
try:
2428+
windVelocityY_values_for_this_hour += [
2429+
dayDict[hour]["windVelocityY"](altitude_list)
2430+
]
2431+
except KeyError:
2432+
# Some day does not have data for the desired hour
2433+
# No need to worry, just average over the other days
2434+
pass
2435+
mean_windVelocityY_values_for_this_hour = np.mean(
2436+
windVelocityY_values_for_this_hour, axis=0
2437+
)
2438+
average_windVelocityY_profile_at_given_hour[hour] = [
2439+
mean_windVelocityY_values_for_this_hour,
2440+
altitude_list,
2441+
]
2442+
max_windVelocityY = np.max(mean_windVelocityY_values_for_this_hour)
2443+
if max_windVelocityY >= self.max_average_windVelocityY_at_altitude:
2444+
self.max_average_windVelocityY_at_altitude = max_windVelocityY
2445+
self.average_windVelocityY_profile_at_given_hour = average_windVelocityY_profile_at_given_hour
2446+
23222447
def plot_wind_profile_over_average_day(self, SAcup_altitude_constraints=False):
23232448
"""Creates a grid of plots with the wind profile over the average day."""
2324-
self.process_wind_profile_over_average_day()
2449+
self.process_wind_speed_profile_over_average_day()
23252450

23262451
# Create grid of plots for each hour
23272452
hours = list(list(self.pressureLevelDataDict.values())[0].keys())
@@ -2382,7 +2507,7 @@ def plot_wind_profile_over_average_day(self, SAcup_altitude_constraints=False):
23822507

23832508
def animate_wind_profile_over_average_day(self, SAcup_altitude_constraints=False):
23842509
"""Animation of how wind profile evolves throughout an average day."""
2385-
self.process_wind_profile_over_average_day()
2510+
self.process_wind_speed_profile_over_average_day()
23862511

23872512
# Create animation
23882513
fig, ax = plt.subplots(dpi=200)
@@ -2546,50 +2671,77 @@ def allInfo(self):
25462671
f"Percentage of Days Without Clouds: {100*self.percentage_of_days_with_no_cloud_coverage:.1f} %"
25472672
)
25482673

2549-
def exportMeanProfiles(self, filename):
2674+
def exportMeanProfiles(self, filename="export_env_analysis"):
25502675
"""
2551-
Exports the mean profiles of the weather data to a file in order to it be used as inputs on Environment Class by using the CustomAtmosphere model.
2552-
2676+
Exports the mean profiles of the weather data to a file in order to it
2677+
be used as inputs on Environment Class by using the CustomAtmosphere
2678+
model.
2679+
TODO: Improve docs
25532680
"""
25542681

2555-
# Take header information
2556-
2557-
# Use EnvAnal init info
2558-
# def __init__(
2559-
# self,
2560-
# start_date,
2561-
# end_date,
2562-
# latitude,
2563-
# longitude,
2564-
# start_hour=0,
2565-
# end_hour=24,
2566-
# surfaceDataFile=None,
2567-
# pressureLevelDataFile=None,
2568-
# timezone=None,
2569-
# unit_system="metric",
2570-
# ):
2571-
2572-
# Call important profiles
2573-
self.exportEnvAnalDictionary = {
2574-
"railLength": 0,
2575-
"gravity": 0,
2576-
"date": 0,
2577-
"latitude": 0,
2578-
"longitude": 0,
2579-
"elevation": 0,
2580-
"datum": 0,
2581-
"timeZone": 0,
2582-
"maxExpectedHeight": 0,
2583-
"atmosphericModelType": 0,
2584-
"atmosphericModelFile": 0,
2585-
"atmosphericModelDict": 0,
2586-
"atmosphericModelPressureProfile": 0,
2587-
"atmosphericModelTemperatureProfile": 0,
2588-
"atmosphericModelWindVelocityXProfile": 0,
2589-
"atmosphericModelWindVelocityYProfile": 0
2682+
self.process_temperature_profile_over_average_day()
2683+
self.process_pressure_profile_over_average_day()
2684+
self.process_wind_velocity_x_profile_over_average_day()
2685+
self.process_wind_velocity_y_profile_over_average_day()
2686+
2687+
organized_temperature_dict = {}
2688+
organized_pressure_dict = {}
2689+
organized_windX_dict = {}
2690+
organized_windY_dict = {}
2691+
2692+
for hour in self.average_temperature_profile_at_given_hour.keys():
2693+
organized_temperature_dict[hour] = np.column_stack(
2694+
(self.average_temperature_profile_at_given_hour[hour][1],
2695+
self.average_temperature_profile_at_given_hour[hour][0])
2696+
).tolist()
2697+
organized_pressure_dict[hour] = np.column_stack(
2698+
(self.average_pressure_profile_at_given_hour[hour][1],
2699+
self.average_pressure_profile_at_given_hour[hour][0])
2700+
).tolist()
2701+
organized_windX_dict[hour] = np.column_stack(
2702+
(self.average_windVelocityX_profile_at_given_hour[hour][1],
2703+
self.average_windVelocityX_profile_at_given_hour[hour][0])
2704+
).tolist()
2705+
organized_windY_dict[hour] = np.column_stack(
2706+
(self.average_windVelocityY_profile_at_given_hour[hour][1],
2707+
self.average_windVelocityY_profile_at_given_hour[hour][0])
2708+
).tolist()
2709+
2710+
self.exportEnvAnalDict = {
2711+
"start_date": self.start_date,
2712+
"end_date": self.end_date,
2713+
"start_hour": self.start_hour,
2714+
"end_hour": self.end_hour,
2715+
"latitude": self.latitude,
2716+
"longitude": self.longitude,
2717+
"elevation": self.elevation,
2718+
"timeZone": self.preferred_timezone,
2719+
"unit_system": self.unit_system,
2720+
# "maxExpectedHeight": 80000, # TODO: Implement this parameter at EnvAnalysis Class
2721+
"surfaceDataFile": self.surfaceDataFile,
2722+
"pressureLevelDataFile": self.pressureLevelDataFile,
2723+
# "surfaceDataDict": self.surfaceDataDict, # TODO: Too large, make it optional
2724+
# "pressureLevelDataDict": self.pressureLevelDataDict, # TODO: Too large, make it optional
2725+
"atmosphericModelPressureProfile": organized_pressure_dict,
2726+
"atmosphericModelTemperatureProfile": organized_temperature_dict,
2727+
"atmosphericModelWindVelocityXProfile": organized_windX_dict,
2728+
"atmosphericModelWindVelocityYProfile": organized_windY_dict
25902729
}
2591-
# Create a dictionary with all the information
2730+
25922731
# Convert to json
2593-
# Save to file
2732+
f = open(filename+".json","w")
2733+
2734+
# write json object to file
2735+
f.write(json.dumps(
2736+
self.exportEnvAnalDict,
2737+
sort_keys=False,
2738+
indent=4,
2739+
default=str)
2740+
)
2741+
2742+
# close file
2743+
f.close()
2744+
print("Your Environment Analysis file was saved, check it out: " + filename + ".json")
2745+
print("You can use it in the future by using the customAtmosphere atmospheric model.")
25942746

2595-
return None
2747+
return None

0 commit comments

Comments
 (0)