12
12
from .bnd .bnd_mod import Boundary
13
13
from .wnd .wnd_mod import Forcing
14
14
15
- def distance_2points (lat1 ,lon1 ,lat2 ,lon2 ) -> float :
15
+ def distance_2points (lat1 , lon1 , lat2 , lon2 ) -> float :
16
16
"""Calculate distance between two points"""
17
17
18
18
R = 6371.0
@@ -35,7 +35,7 @@ def min_distance(lon, lat, lon_vec , lat_vec) -> Tuple[float, int]:
35
35
"""
36
36
37
37
dx = []
38
- for n in range ( len ( lat_vec ) ):
38
+ for n , __ in enumerate ( lat_vec ):
39
39
dx .append (distance_2points (lat , lon , lat_vec [n ], lon_vec [n ]))
40
40
41
41
return np .array (dx ).min (), np .array (dx ).argmin ()
@@ -45,6 +45,130 @@ def lon_in_km(lat: float) -> float:
45
45
46
46
return distance_2points (lat , 0 , lat , 1 )
47
47
48
+ def domain_size_in_km (lon : Tuple (float , float ), lat : Tuple (float , float )) -> Tuple [float , float ]:
49
+ """Calculates approximate size of grid in km."""
50
+
51
+ km_x = distance_2points ((lat [0 ]+ lat [1 ])/ 2 , lon [0 ], (lat [0 ]+ lat [1 ])/ 2 ,lon [1 ])
52
+ km_y = distance_2points (lat [0 ], lon [0 ], lat [1 ], lon [0 ])
53
+
54
+ return km_x , km_y
55
+
56
+ def force_to_xyz (data : np .ndarray , lon : np .ndarray , lat : np .ndarray ) -> Tuple [np .ndarray , np .ndarray , np .ndarray ]:
57
+ '''If the data is given in a matrix, convert it to xyz vectors.
58
+
59
+ Does nothing is data is already in xyz.'''
60
+ # If the data is in a matrix
61
+ if len (data .shape ) > 1 :
62
+ lon0 , lat0 = np .meshgrid (lon , lat )
63
+ x = lon0 .ravel ()
64
+ y = lat0 .ravel ()
65
+ z = data .ravel ()
66
+ else :
67
+ x = lon
68
+ y = lat
69
+ z = data
70
+
71
+ return z , x , y
72
+
73
+ def set_spacing_dlon_dlat_fixed_edges (dlon : float , dlat :float , lon : Tuple [float , float ], lat : Tuple [float , float ]) -> Tuple [float , float , float , float , np .ndarray , np .ndarray ]:
74
+ """Given dlon, dlat and lon,lat edges, set other spacing varialbles.
75
+
76
+ Preserves edges (not dlon,dlat)
77
+ """
78
+ nx = int ((lon [1 ]- lon [0 ])/ dlon + 1 )
79
+ ny = int ((lat [1 ]- lat [0 ])/ dlat + 1 )
80
+
81
+ # Define longitudes and latitudes
82
+ lon_array = np .linspace (lon [0 ], lon [1 ], nx )
83
+ lat_array = np .linspace (lat [0 ], lat [1 ], ny )
84
+
85
+ if nx > 1 :
86
+ dlon = (lon [1 ]- lon [0 ])/ (nx - 1 )
87
+ else :
88
+ dlon = 0.
89
+
90
+ if ny > 1 :
91
+ dlat = (lat [1 ]- lat [0 ])/ (ny - 1 )
92
+ else :
93
+ dlat = 0.
94
+
95
+ lon = (min (lon_array ), max (lon_array ))
96
+ lat = (min (lat_array ), max (lat_array ))
97
+ km_x , km_y = domain_size_in_km (lon , lat )
98
+
99
+ # dx, dy in metres
100
+ dx = km_x * 1000 / nx
101
+ dy = km_y * 1000 / ny
102
+
103
+ return dlon , dlat , dx , dy , lon_array , lat_array
104
+
105
+ def set_spacing_dlon_dlat_floating_edges (dlon : float , dlat :float , lon : Tuple [float , float ], lat : Tuple [float , float ]) -> Tuple [float , float , float , float , np .ndarray , np .ndarray ]:
106
+ """Given dlon, dlat and lon,lat edges, set other spacing varialbles
107
+
108
+ Preserves dlon, dlat (not edges)
109
+ """
110
+ lon_array = np .arange (lon [0 ],lon [1 ]+ dlon / 2 ,dlon )
111
+ lat_array = np .arange (lat [0 ],lat [1 ]+ dlon / 2 ,dlat )
112
+
113
+ lon = (min (lon_array ), max (lon_array ))
114
+ lat = (min (lat_array ), max (lat_array ))
115
+ km_x , km_y = domain_size_in_km (lon , lat )
116
+
117
+ # Number of points
118
+ nx = len (lon_array )
119
+ ny = len (lat_array )
120
+
121
+ # dx, dy in metres
122
+ dx = km_x * 1000 / nx
123
+ dy = km_y * 1000 / ny
124
+
125
+ return dlon , dlat , dx , dy , lon_array , lat_array
126
+
127
+ def set_spacing_dx_dy (dx : float , dy :float , lon : Tuple [float , float ], lat : Tuple [float , float ]) -> Tuple [float , float , float , float , np .ndarray , np .ndarray ]:
128
+ km_x , km_y = domain_size_in_km (lon , lat )
129
+ # Number of points
130
+ nx = int (np .round (km_x * 1000 / dx )+ 1 )
131
+ ny = int (np .round (km_y * 1000 / dy )+ 1 )
132
+
133
+ # dx, dy in metres
134
+ dx = km_x * 1000 / nx
135
+ dy = km_y * 1000 / ny
136
+
137
+ if nx > 1 :
138
+ dlon = (lon [1 ]- lon [0 ])/ (nx - 1 )
139
+ else :
140
+ dlon = 0.
141
+ if ny > 1 :
142
+ dlat = (lat [1 ]- lat [0 ])/ (ny - 1 )
143
+ else :
144
+ dlat = 0.
145
+
146
+ # Define longitudes and latitudes
147
+ lon_array = np .linspace (lon [0 ], lon [1 ], nx )
148
+ lat_array = np .linspace (lat [0 ], lat [1 ], ny )
149
+
150
+ return dlon , dlat , dx , dy , lon_array , lat_array
151
+
152
+ def set_spacing_nx_ny (nx : float , ny :float , lon : Tuple [float , float ], lat : Tuple [float , float ]) -> Tuple [float , float , float , float , np .ndarray , np .ndarray ]:
153
+ # Define longitudes and latitudes
154
+ lon_array = np .linspace (lon [0 ], lon [1 ], nx )
155
+ lat_array = np .linspace (lat [0 ], lat [1 ], ny )
156
+ if nx > 1 :
157
+ dlon = (lon [1 ]- lon [0 ])/ (nx - 1 )
158
+ else :
159
+ dlon = 0.
160
+
161
+ if ny > 1 :
162
+ dlat = (lat [- 1 ]- lat [0 ])/ (ny - 1 )
163
+ else :
164
+ dlat = 0.
165
+
166
+ km_x , km_y = domain_size_in_km (lon , lat )
167
+ # dx, dy in metres
168
+ dx = km_x * 1000 / nx
169
+ dy = km_y * 1000 / ny
170
+
171
+ return dlon , dlat , dx , dy , lon_array , lat_array
48
172
49
173
def day_list (start_time , end_time ):
50
174
"""Determins a Pandas data range of all the days in the time span of the InputModel objext"""
@@ -196,7 +320,7 @@ def create_time_stamps(start_time: str, end_time: str, stride: int, hours_per_fi
196
320
197
321
# FIND FILE STAMPS
198
322
start_stamp = pd .Timestamp (start_time ) - pd .DateOffset (hours = lead_time )
199
- if last_file is not '' :
323
+ if last_file != '' :
200
324
end_stamp = pd .Timestamp (last_file )
201
325
202
326
# E.g. we want to start a forecast at 06:00 but the last (and only) file is 00:00
0 commit comments