55__license__ = "MIT"
66
77import bisect
8+ import json
89import warnings
910from 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