1+ import getgfs , dateutil .parser , pickle
2+ from datetime import datetime
3+ from pathlib import Path
4+
5+ __copyright__ = """
6+
7+ Copyright 2021 Jago Strong-Wright
8+
9+ This program is free software: you can redistribute it and/or modify
10+ it under the terms of the GNU General Public License as published by
11+ the Free Software Foundation, either version 3 of the License, or
12+ (at your option) any later version.
13+
14+ This program is distributed in the hope that it will be useful,
15+ but WITHOUT ANY WARRANTY; without even the implied warranty of
16+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+ GNU General Public License for more details.
18+
19+ You should have received a copy of the GNU General Public License
20+ along with this program. If not, see <https://www.gnu.org/licenses/>.
21+
22+ """
23+
24+ Path ("data/wind" ).mkdir (parents = True ,exist_ok = True )
25+
26+ class Wind :
27+ def __init__ (self ,datetime ,cache = False ):
28+ """Initites wind object so wind for some position can be searched
29+
30+ Note
31+ ----
32+ - Historic forcasts are not yet implimented in getgfs so historics not available in this
33+
34+ Args:
35+ datetime (string): datetime of flight, can be in 'any' format as long as datetime parser can work it out (for now this will need to be UTC)
36+ cache (bool, optional): cache lat/long/time profile, useful for stats models where downloading for each run is a bottle neck. Defaults to False.
37+ """
38+ self .launch_time = dateutil .parser .parse (datetime ).timestamp ()
39+ self .cache = cache
40+
41+ self .forecast = getgfs .Forecast ("0p25" )
42+ self .profiles = {}#(lat,long,datetime):interp profile
43+ self .points = []#tuples (lat,long,forecast)
44+
45+
46+ def get (self ,lat ,long ,alt ,flight_time ):
47+ lat = [float (self .forecast .coords ["lat" ]["resolution" ])* n + float (self .forecast .coords ["lat" ]["minimum" ]) for n in range (0 ,int (self .forecast .coords ["lat" ]["grads_size" ]))][self .forecast .value_to_index ("lat" ,lat )]
48+ long = [float (self .forecast .coords ["lon" ]["resolution" ])* n + float (self .forecast .coords ["lon" ]["minimum" ]) for n in range (0 ,int (self .forecast .coords ["lon" ]["grads_size" ]))][self .forecast .value_to_index ("lon" ,long )]
49+ request_timestamp = self .launch_time + flight_time
50+ request_datetime = datetime .fromtimestamp (request_timestamp ).strftime ("%Y-%m-%d %H:%M" )
51+ forecast_to_use = self .forecast .datetime_to_forecast (request_datetime )
52+ if (lat ,long , forecast_to_use ) not in self .points :
53+ if self .cache == False or not Path ("data/wind/%s_%s_%s.pkl" % (lat ,long ,forecast_to_use )).is_file ():
54+ self .profiles [(lat ,long ,forecast_to_use )]= self .forecast .get_windprofile (request_datetime ,lat ,long )
55+ self .points .append ((lat ,long ,forecast_to_use ))
56+
57+ if self .cache == True :
58+ with open ("data/wind/%s_%s_%s.pkl" % (lat ,long ,forecast_to_use ),"wb" ) as dump_file :
59+ pickle .dump (self .profiles [(lat ,long ,forecast_to_use )],dump_file )
60+ else :
61+ with open ("data/wind/%s_%s_%s.pkl" % (lat ,long ,forecast_to_use ),"rb" ) as dump_file :
62+ self .profiles [(lat ,long ,forecast_to_use )]= pickle .load (dump_file )
63+ self .points .append ((lat ,long ,forecast_to_use ))
64+
65+ return self .profiles [(lat ,long ,forecast_to_use )][0 ](alt ),self .profiles [(lat ,long ,forecast_to_use )][2 ](alt )
66+
67+ if __name__ == "__main__" :
68+ w = Wind ("20210321 15:00" ,cache = True )
69+ print (w .get (0 ,0 ,0 ,0 ))
0 commit comments