@@ -233,10 +233,12 @@ def eval(self, time: datetime, z, y, x, particle=None, applyConversion=True):
233233
234234 tau , ti = _search_time_index (self , time )
235235 position = self .grid .search (z , y , x , ei = _ei )
236- _update_particle_states (particle , position )
236+ _update_particle_states_position (particle , position )
237237
238238 value = self ._interp_method (self , ti , position , tau , time , z , y , x )
239239
240+ _update_particle_states_interp_value (particle , value )
241+
240242 if applyConversion :
241243 value = self .units .to_target (value , z , y , x )
242244 return value
@@ -313,16 +315,21 @@ def eval(self, time: datetime, z, y, x, particle=None, applyConversion=True):
313315
314316 tau , ti = _search_time_index (self .U , time )
315317 position = self .grid .search (z , y , x , ei = _ei )
316- _update_particle_states (particle , position )
318+ _update_particle_states_position (particle , position )
317319
318320 if self ._vector_interp_method is None :
319321 u = self .U ._interp_method (self .U , ti , position , tau , time , z , y , x )
320322 v = self .V ._interp_method (self .V , ti , position , tau , time , z , y , x )
321323 if "3D" in self .vector_type :
322324 w = self .W ._interp_method (self .W , ti , position , tau , time , z , y , x )
325+ else :
326+ w = 0.0
323327 else :
324328 (u , v , w ) = self ._vector_interp_method (self , ti , position , time , z , y , x )
325329
330+ for vel in (u , v , w ):
331+ _update_particle_states_interp_value (particle , vel )
332+
326333 if applyConversion :
327334 u = self .U .units .to_target (u , z , y , x )
328335 v = self .V .units .to_target (v , z , y , x )
@@ -344,14 +351,30 @@ def __getitem__(self, key):
344351 return _deal_with_errors (error , key , vector_type = self .vector_type )
345352
346353
347- def _update_particle_states (particle , position ):
354+ def _update_particle_states_position (particle , position ):
348355 """Update the particle states based on the position dictionary."""
349356 if particle and "X" in position : # TODO also support uxgrid search
350- particle .state = np .where (position ["X" ][0 ] < 0 , StatusCode .ErrorOutOfBounds , particle .state )
351- particle .state = np .where (position ["Y" ][0 ] < 0 , StatusCode .ErrorOutOfBounds , particle .state )
352- particle .state = np .where (position ["Z" ][0 ] == RIGHT_OUT_OF_BOUNDS , StatusCode .ErrorOutOfBounds , particle .state )
353- particle .state = np .where (
354- position ["Z" ][0 ] == LEFT_OUT_OF_BOUNDS , StatusCode .ErrorThroughSurface , particle .state
357+ particle .state = np .maximum (
358+ np .where (position ["X" ][0 ] < 0 , StatusCode .ErrorOutOfBounds , particle .state ), particle .state
359+ )
360+ particle .state = np .maximum (
361+ np .where (position ["Y" ][0 ] < 0 , StatusCode .ErrorOutOfBounds , particle .state ), particle .state
362+ )
363+ particle .state = np .maximum (
364+ np .where (position ["Z" ][0 ] == RIGHT_OUT_OF_BOUNDS , StatusCode .ErrorOutOfBounds , particle .state ),
365+ particle .state ,
366+ )
367+ particle .state = np .maximum (
368+ np .where (position ["Z" ][0 ] == LEFT_OUT_OF_BOUNDS , StatusCode .ErrorThroughSurface , particle .state ),
369+ particle .state ,
370+ )
371+
372+
373+ def _update_particle_states_interp_value (particle , value ):
374+ """Update the particle states based on the interpolated value, but only if state is not an Error already."""
375+ if particle :
376+ particle .state = np .maximum (
377+ np .where (np .isnan (value ), StatusCode .ErrorInterpolation , particle .state ), particle .state
355378 )
356379
357380
0 commit comments