🎓 Parcels v4 migration guide#
This migration guide gives some tips if you want to migrate your Parcels v3 code to Parcels v4. The biggest changes are in the Kernel API and the way that FieldSets are created. The other changes are mostly small and should be easy to fix.
Description of change
How to migrate
Kernels#
The Kernel API has had some major changes (see also below)
Add the
@parcels.validate_kernel decorator above your Kernel function definition to check for errors and warnings.
The Kernel loop is 'vectorized': the input of a Kernel is a collection of particles
Functions should work on a collection of particles instead of a single particle
Use
numpy functions instead of math functions
Functions shouldn't be converted to
Kernel objects in a pset.execute() call
Simply pass the function(s) as a list to
pset.execute()
The
time argument in the Kernel signature is removed
Use
particle.t
particle.lon, particle.lat and particle.depth are renamed
Use
particles.x, particles.y and particles.z
particle_dlon particle_dlat and particle_ddepth are renamed
Use
particles.dx, particles.dy and particles.dz
The
particle argument in the Kernel signature is renamed to particles
Change the argument name in your Kernel signature to
particles
particle.delete() is no longer valid
Use
StatusCode.Delete in combination with boolean indexing - as detailed here
Kernels are not concatenated under the hood, so can't access each others variables or states
Use fieldset.context or particle data to share information between kernels
The
InteractionKernel class is removed as normal Kernels now have access to all particles
Particle-particle interaction can be performed within normal Kernels
Automatic conversion from depth to sigma grids under the hood is removed
Explicitly use
convert_z_to_sigma_croco in sampling kernels (such as the AdvectionRK4_3D_CROCO or SampleOMegaCroco kernels) when working with CROCO data
The default advection scheme is changed from RK4 to RK2 as it is faster while the accuracy is comparable for most applications
Use
pset.execute(parcels.AdvectionRK2) for advection
FieldSet#
FieldSet.from_<modelname>() is removed
Convert the model data first to SGrid (for example with a
parcels.covert_<MODEL>_to_sgrid() function) and then use FieldSet.from_sgrid_conventions(), as also described in the Quickstart tutorial
FieldSet.interp_method doesn't accept a string (e.g. "linear" or "nearest")
Use an Interpolation function such as
parcels.interpolators.Linear or parcels.interpolators.Nearest
FieldSet.add_constant is removed to reflect that this value no longer has to be constant
Use
FieldSet.add_context to add a context variable to the FieldSet
Particle#
Particle.add_variable() is removed
Use
Particle.add_variables(), which also takes a list of Variables
Parameters
indices, timestamps, and time_periodic removed from FieldSet constructors.
Simply manipulate the datasets with Xarray to the same effect before passing them to Parcels.
ParticleSet#
pset.execute() does not require Kernel objects
Simply pass the function(s) as a list to
pset.execute()
repeatdt is removed
See the Delayed starts tutorial for how to implement repeated releases of particles
lonlatdepth_dtype is removed
Set the dtype of your particle variables directly
ParticleSet.execute() expects
datatime, numpy.datetime64 or numpy.timedelta.64 for runtime and endtime
Update
runtime and endtime to use numpy.datetime64 or numpy.timedelta.64
ParticleSet.from_field(), ParticleSet.from_line(), ParticleSet.from_list() are removed
Use the
ParticleSet constructor directly
ParticleFile#
ParticleFiles output is in parquet format
Read the output with
polars.read_parquet() or (to automatically handle cftime) parcels.read_particlefile(). For compatility with old postprocessing codes, convert the new Parquet output to v3-style zarr output using parcels.particlefile_to_v3_zarr()
ParticleFile is not a method of the ParticleSet class
Use
ParticleFile(...) instead of pset.ParticleFile(...)
ParticleFile errors out if there's existing output
Remove the existing output file or add
mode="w" to overwrite
The output file does not have a
trajectory dimension
Use
particle_id instead of trajectory in your code
ParticleFile does not have a name attribute
Use
ParticleFile.path, which can be a string or a Path
ParticleFile does not have a chunks argument
Remove the
chunks argument from your code
ParticleFile does not have a to_write="once" argument
Either write all timesteps of a variable, or none
Particles are not written when they are deleted
Call
ParticleFile.write() inside a kernel to write out deleted particles
Field#
Calling
Field.eval() directly gives a warning if any values are out of bounds
Use
Field.eval() as before, but check for warnings
Field.eval() returns an array of floats (related to the vectorization)
Use
Field.eval() as before, but expect an array of floats instead of a single float
The
NestedField class is removed
See the Nested Grids tutorial for how to set up Nested Grids in v4
applyConversion is removed
Interpolation on VectorFields automatically converts from m/s to degrees/s for spherical meshes. Other conversion of units should be handled in Interpolators or Kernels
GridSet#
GridSet is a list
Change
fieldset.gridset.grids[0] to fieldset.gridset[0]
UnitConverters#
The
UnitConverter class is removed
Remove any
UnitConverter usage from your code and Interpolation functions should handle unit conversion internally, based on the units of the coordinate values in the Dataset, or the value of SphericalMesh(radius=...)".