@@ -80,7 +80,13 @@ def _(ArgumentParser, Path):
8080def _ (grib_dir , init_time , lead_time , load_state_from_grib , param ):
8181 # load grib file
8282 grib_file = grib_dir / f"{ init_time } _{ lead_time } .grib"
83- state = load_state_from_grib (grib_file , paramlist = [param ])
83+ if param == "10sp" :
84+ paramlist = ["10u" , "10v" ]
85+ elif param == "sp" :
86+ paramlist = ["u" , "v" ]
87+ else :
88+ paramlist = [param ]
89+ state = load_state_from_grib (grib_file , paramlist = paramlist )
8490 return (state ,)
8591
8692
@@ -120,17 +126,27 @@ def _k_to_c(arr):
120126 except Exception :
121127 return arr - 273.15
122128
129+ def _ms_to_knots (arr ):
130+ # robust conversion with pint, fallback if dtype unsupported
131+ try :
132+ return (_ureg .Quantity (arr , _ureg .meter / _ureg .second ).to (_ureg .knot )).magnitude
133+ except Exception :
134+ return arr * 1.943844
135+
123136 except Exception :
124- LOG .warning ("pint not available; falling back to K->C by subtracting 273.15 " )
137+ LOG .warning ("pint not available; falling back hardcoded conversions " )
125138
126139 def _k_to_c (arr ):
127140 return arr - 273.15
128141
142+ def _ms_to_knots (arr ):
143+ return arr * 1.943844
144+
129145 def preprocess_field (param : str , state : dict ):
130146 """
131147 - Temperatures (2t, 2d, t, d): K -> °C
132- - Wind speed at 10m (10sp): sqrt(10u^2 + 10v^2)
133- - Wind speed (sp): sqrt(u^2 + v^2)
148+ - Wind speed at 10m (10sp): m/s -> kn, sqrt(10u^2 + 10v^2)
149+ - Wind speed (sp): m/s -> kn, sqrt(u^2 + v^2)
134150 Returns: (field_array, units_override or None)
135151 """
136152 fields = state ["fields" ]
@@ -139,18 +155,14 @@ def preprocess_field(param: str, state: dict):
139155 return _k_to_c (fields [param ]), "°C"
140156 # 10m wind speed (allow legacy 'uv' alias)
141157 if param == "10sp" :
142- u = fields .get ("10u" )
143- v = fields .get ("10v" )
144- if u is None or v is None :
145- raise KeyError ("Required components 10u/10v not in state['fields']" )
146- return np .sqrt (u ** 2 + v ** 2 ), "m s$^{-1}$"
158+ u = _ms_to_knots (fields ["10u" ])
159+ v = _ms_to_knots (fields ["10v" ])
160+ return np .sqrt (u ** 2 + v ** 2 ), "kn"
147161 # wind speed from standard-level components
148162 if param == "sp" :
149- u = fields .get ("u" )
150- v = fields .get ("v" )
151- if u is None or v is None :
152- raise KeyError ("Required components u/v not in state['fields']" )
153- return np .sqrt (u ** 2 + v ** 2 ), "m s$^{-1}$"
163+ u = _ms_to_knots (fields ["u" ])
164+ v = _ms_to_knots (fields ["v" ])
165+ return np .sqrt (u ** 2 + v ** 2 ), "kn"
154166 # default: passthrough
155167 return fields [param ], None
156168 return (preprocess_field ,)
0 commit comments