@@ -76,17 +76,19 @@ class ModelMetadata:
7676
7777 def __str__ (self ) -> str :
7878 """Return a pretty-printed string representation of the metadata."""
79- pretty : str = "" .join ((
80- "Model:" ,
81- "\n \t {self.name} ({self.resolution} resolution)" ,
82- "\t Coordinates:" ,
83- "\n " .join (
84- f"\t \t { dim } : { vals } "
85- if len (vals ) < 5
86- else f"\t \t { dim } : { vals [:3 ]} ... { vals [- 3 :]} "
87- for dim , vals in self .expected_coordinates .__dict__ .items ()
88- ),
89- ))
79+ pretty : str = "" .join (
80+ (
81+ "Model:" ,
82+ "\n \t {self.name} ({self.resolution} resolution)" ,
83+ "\t Coordinates:" ,
84+ "\n " .join (
85+ f"\t \t { dim } : { vals } "
86+ if len (vals ) < 5
87+ else f"\t \t { dim } : { vals [:3 ]} ... { vals [- 3 :]} "
88+ for dim , vals in self .expected_coordinates .__dict__ .items ()
89+ ),
90+ )
91+ )
9092 return pretty
9193
9294 def with_region (self , region : str ) -> "ModelMetadata" :
@@ -97,36 +99,91 @@ def with_region(self, region: str) -> "ModelMetadata":
9799 """
98100 match region :
99101 case "uk" :
100- return self .expected_coordinates .crop (
101- north = 62 , west = - 12 , south = 48 , east = 3 ,
102- ).map (lambda coords : dataclasses .replace (
103- self , name = f"{ self .name } _uk" , expected_coordinates = coords ,
104- )).unwrap ()
102+ return (
103+ self .expected_coordinates .crop (
104+ north = 62 ,
105+ west = - 12 ,
106+ south = 48 ,
107+ east = 3 ,
108+ )
109+ .map (
110+ lambda coords : dataclasses .replace (
111+ self ,
112+ name = f"{ self .name } _uk" ,
113+ expected_coordinates = coords ,
114+ )
115+ )
116+ .unwrap ()
117+ )
105118 case "uk-north60" :
106119 # same as uk. but north is 60, not 62
107- return self .expected_coordinates .crop (
108- north = 60 , west = - 12 , south = 48 , east = 3 ,
109- ).map (lambda coords : dataclasses .replace (
110- self , name = f"{ self .name } _uk" , expected_coordinates = coords ,
111- )).unwrap ()
120+ return (
121+ self .expected_coordinates .crop (
122+ north = 60 ,
123+ west = - 12 ,
124+ south = 48 ,
125+ east = 3 ,
126+ )
127+ .map (
128+ lambda coords : dataclasses .replace (
129+ self ,
130+ name = f"{ self .name } _uk" ,
131+ expected_coordinates = coords ,
132+ )
133+ )
134+ .unwrap ()
135+ )
112136 case "india" :
113- return self .expected_coordinates .crop (
114- north = 35 , west = 67 , south = 6 , east = 97 ,
115- ).map (lambda coords : dataclasses .replace (
116- self , name = f"{ self .name } _india" , expected_coordinates = coords ,
117- )).unwrap ()
137+ return (
138+ self .expected_coordinates .crop (
139+ north = 35 ,
140+ west = 67 ,
141+ south = 6 ,
142+ east = 97 ,
143+ )
144+ .map (
145+ lambda coords : dataclasses .replace (
146+ self ,
147+ name = f"{ self .name } _india" ,
148+ expected_coordinates = coords ,
149+ )
150+ )
151+ .unwrap ()
152+ )
118153 case "west-europe" :
119- return self .expected_coordinates .crop (
120- north = 63 , west = - 12 , south = 35 , east = 26 ,
121- ).map (lambda coords : dataclasses .replace (
122- self , name = f"{ self .name } _west-europe" , expected_coordinates = coords ,
123- )).unwrap ()
154+ return (
155+ self .expected_coordinates .crop (
156+ north = 63 ,
157+ west = - 12 ,
158+ south = 35 ,
159+ east = 26 ,
160+ )
161+ .map (
162+ lambda coords : dataclasses .replace (
163+ self ,
164+ name = f"{ self .name } _west-europe" ,
165+ expected_coordinates = coords ,
166+ )
167+ )
168+ .unwrap ()
169+ )
124170 case "nl" :
125- return self .expected_coordinates .crop (
126- north = 54 , west = 2 , south = 50 , east = 8 ,
127- ).map (lambda coords : dataclasses .replace (
128- self , name = f"{ self .name } _nl" , expected_coordinates = coords ,
129- )).unwrap ()
171+ return (
172+ self .expected_coordinates .crop (
173+ north = 54 ,
174+ west = 2 ,
175+ south = 50 ,
176+ east = 8 ,
177+ )
178+ .map (
179+ lambda coords : dataclasses .replace (
180+ self ,
181+ name = f"{ self .name } _nl" ,
182+ expected_coordinates = coords ,
183+ )
184+ )
185+ .unwrap ()
186+ )
130187 case _:
131188 log .warning (f"Unknown region '{ region } ', not cropping expected coordinates." )
132189 return self
@@ -163,6 +220,7 @@ def month_its(self, year: int, month: int) -> list[dt.datetime]:
163220 its .append (dt .datetime (year , month , day , hour , tzinfo = dt .UTC ))
164221 return its
165222
223+
166224class Models :
167225 """Namespace containing known models."""
168226
@@ -212,8 +270,8 @@ class Models:
212270 Parameter .TEMPERATURE_SL ,
213271 ],
214272 ensemble_stat = ["mean" , "std" , "P10" , "P25" , "P75" , "P90" ],
215- latitude = [v / 10 for v in range (900 , - 900 , - 1 )],
216- longitude = [v / 10 for v in range (- 1800 , 1800 , 1 )],
273+ latitude = [v / 10 for v in range (900 , - 900 , - 1 )],
274+ longitude = [v / 10 for v in range (- 1800 , 1800 , 1 )],
217275 ),
218276 running_hours = [0 , 12 ],
219277 )
@@ -241,8 +299,8 @@ class Models:
241299 # Parameter.TOTAL_PRECIPITATION_RATE_GL,
242300 ],
243301 ensemble_member = list (range (1 , 51 )),
244- latitude = [v / 10 for v in range (900 , - 900 , - 1 )],
245- longitude = [v / 10 for v in range (- 1800 , 1800 , 1 )],
302+ latitude = [v / 10 for v in range (900 , - 900 , - 1 )],
303+ longitude = [v / 10 for v in range (- 1800 , 1800 , 1 )],
246304 ),
247305 running_hours = [0 , 6 , 12 , 18 ],
248306 )
@@ -283,7 +341,7 @@ class Models:
283341 MO_UM_GLOBAL_17KM : ModelMetadata = ModelMetadata (
284342 name = "um-global" ,
285343 resolution = "17km" ,
286- expected_coordinates = NWPDimensionCoordinateMap (
344+ expected_coordinates = NWPDimensionCoordinateMap (
287345 init_time = [],
288346 step = list (range (0 , 48 , 1 )),
289347 variable = [
@@ -299,16 +357,17 @@ class Models:
299357 Parameter .WIND_V_COMPONENT_10m ,
300358 Parameter .VISIBILITY_SL ,
301359 ],
302- latitude = [
303- float (f"{ lat :.4f} " ) for lat in np .arange (89.856 , - 89.856 - 0.156 , - 0.156 )
304- ],
360+ latitude = [float (f"{ lat :.4f} " ) for lat in np .arange (89.856 , - 89.856 - 0.156 , - 0.156 )],
305361 longitude = [
306- float (f"{ lon :.4f} " ) for lon in np .concatenate ([
307- np .arange (- 45 , 45 , 0.234 ),
308- np .arange (45 , 135 , 0.234 ),
309- np .arange (135 , 225 , 0.234 ),
310- np .arange (225 , 315 , 0.234 ),
311- ])
362+ float (f"{ lon :.4f} " )
363+ for lon in np .concatenate (
364+ [
365+ np .arange (- 45 , 45 , 0.234 ),
366+ np .arange (45 , 135 , 0.234 ),
367+ np .arange (135 , 225 , 0.234 ),
368+ np .arange (225 , 315 , 0.234 ),
369+ ]
370+ )
312371 ],
313372 # TODO: Change to -180 -> 180
314373 ),
@@ -338,8 +397,7 @@ class Models:
338397 ],
339398 ),
340399 latitude = [
341- float (f"{ lat :.4f} " )
342- for lat in np .arange (89.953125 , - 89.953125 - 0.09375 , - 0.09375 )
400+ float (f"{ lat :.4f} " ) for lat in np .arange (89.953125 , - 89.953125 - 0.09375 , - 0.09375 )
343401 ],
344402 longitude = [
345403 float (f"{ lon :.4f} " )
@@ -406,9 +464,9 @@ class Models:
406464 ],
407465 ),
408466 # Taken from iris-grib reading in MetOffice UKV data
409- y_laea = [int (y ) for y in np .arange (start = 700000 , stop = - 576000 - 2000 , step = - 2000 )],
410- x_laea = [int (x ) for x in np .arange (start = - 576000 , stop = 332000 + 2000 , step = 2000 )],
467+ y_laea = [int (y ) for y in np .arange (start = 700000 , stop = - 576000 - 2000 , step = - 2000 )],
468+ x_laea = [int (x ) for x in np .arange (start = - 576000 , stop = 332000 + 2000 , step = 2000 )],
411469 ),
412- running_hours = list (range (0 , 24 , 3 )), # Only first 12 steps available for hourly runs
470+ running_hours = list (range (0 , 24 , 3 )), # Only first 12 steps available for hourly runs
413471 )
414472 """MetOffice's Unified Model in the UKV configuration, at a resolution of 2km"""
0 commit comments