Repository navigation
Particles not moving: CROCO and xarray #1665
Description
Hi,
My particles in a simple OpenDrift script (see file opendirft_minimo.py) are not moving
(see file salida_OD_nook.log)
Software and hardware:
OpenDrift version 1.14.2
Platform: Linux, 5.14.0-503.22.1.el9_5.x86_64
30.807357788085938 GB memory
12 processors (x86_64)
NumPy version 2.3.2
SciPy version 1.16.0
Matplotlib version 3.10.3
NetCDF4 version 1.7.2
Xarray version 2025.7.1
ADIOS (adios_db) version 1.2.5
Copernicusmarine version 2.2.1
Python version 3.13.5 | packaged by conda-forge | (main, Jun 16 2025, 08:27:50) [GCC 13.3.0]
max and min vels are zero. There are errors while trying to read the masks
ERROR opendrift.models.basemodel.environment:650: 'mask_u'
If I try to add the croco_grd.nc file as a gridfile, I get the following error (see file salida_OD_nook_grd.log)
mosa_native = reader_ROMS_native.Reader(filename_nc,gridfile='croco_grd.nc')
File "/home/asepulveda/opendrift/opendrift/readers/reader_ROMS_native.py", line 159, in init
self.Dataset = xr.merge([self.Dataset, gf])
~~~~~~~~^^^^^^^^^^^^^^^^^^^^
File "/home/asepulveda/miniconda3/envs/pnud/lib/python3.1/site-packages/xarray/structure/merge.py", line 984, in merge
merge_result = merge_core(
dict_like_objects,
...<3 lines>...
fill_value=fill_value,
)
File "/home/asepulveda/miniconda3/envs/pnud/lib/python3.1/site-packages/xarray/structure/merge.py", line 709, in merge_core
variables, out_indexes = merge_collected(
~~~~~~~~~~~~~~~^
collected, prioritized, compat=compat, combine_attrs=combine_attrs
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/asepulveda/miniconda3/envs/pnud/lib/python3.1/site-packages/xarray/structure/merge.py", line 302, in merge_collected
merged_vars[name] = unique_variable(
~~~~~~~~~~~~~~~^
name, variables, compat, equals.get(name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
)
^
File "/home/asepulveda/miniconda3/envs/pnud/lib/python3.1/site-packages/xarray/structure/merge.py", line 150, in unique_variable
raise MergeError(
...<2 lines>...
)
xarray.structure.merge.MergeError: conflicting values for variable 'h' on objects to be combined. You can skip this check by specifying compat='override'.
All works fine in an older version of OpenDrift (see file salida_OD_ok.log)
Software and hardware:
OpenDrift version 1.7.3
Platform: Linux, 4.19.0-26-amd64
125.79486846923828 GB memory
56 processors ()
NumPy version 1.26.4
SciPy version 1.7.0
Matplotlib version 3.4.1
NetCDF4 version 1.5.6
Xarray version 2024.2.0
OilLibrary version 1.1.3
Python version 3.9.2 | packaged by conda-forge | (default, Feb 21 2021, 05:02:46) [GCC 9.3.0]
Do I have to modify merge.py in the xarray repository?
ncdump_avg.log
opendrift_minimo.py
salida_OD_nook.log
salida_OD_nook_grd.log
salida_OD_ok.log
Activity
knutfrode commentedon Aug 20, 2025
Hi,
The first problem seems to be that
his found in both ROMS-file and the gridfile, and then Xarray don't know which to use.I added now
compat=overrideto the merge command, as was suggested:230d6d8
Thus you can update and see if it makes a difference (or make your netCDF-files abailable).
The second problem seems to be that
mask_uis missing, but this is perhaps found in the grd-file that was not merged?Older versions of the ROMS reader probably worked because they neglected the mask altogether.
AndresSepulveda commentedon Aug 20, 2025
Thanks Knut,
New error now. A quick solution would be to use an older version of OpenDrift. This is an open ocean domain so there is not much need of mask variables. How do I install an older version using conda?
The error message is
File "/home/asepulveda/miniconda3/envs/pnud/lib/python3.13/site-packages/xarray/structure/merge.py", line 1024, in merge
merge_result = merge_core(
dict_like_objects,
...<3 lines>...
fill_value=fill_value,
)
File "/home/asepulveda/miniconda3/envs/pnud/lib/python3.13/site-packages/xarray/structure/merge.py", line 766, in merge_core
raise MergeError(
...<2 lines>...
)
xarray.structure.merge.MergeError: unable to determine if these variables should be coordinates or not in the merged result: {'lat_v', 'lon_v', 'lon_u', 'lat_rho', 'lon_rho', 'lat_u'}
Regards,
Andres
knutfrode commentedon Aug 22, 2025
The ROMS reader has had a number of "fixes" for CROCO data over the years, as CROCO files seem to be very variable, and also not very stringent.
Are these specific output files, including the grd-file, raw output from a plain and standardised CROCO setup?
Or are they customized locally by the user (e.g. yourself), i.e. different from what other users might have?
In the latter case, it is impossible to make the ROMS reader "digest" all possible forms of data- and grd-files that end-users might have (e.g. as here where variable h is duplicated in both data-file and grd-file, which does not sound like a good idea).
If this output format is identical to other CROCO setups elsewhere, it is better to adapt the ROMS reader to this format, instead of using older versions of OpenDrift.
E.g. older versions of the ROMS reader do not support providing an Xarray dataset directly, only filenames, with possible wildcards.
If output files are non-standard or manipulated, opening and merging them locally with Xarray (including merging in the missing variables from grd-file) might be a flexible solution.
If these files are standardized (i.e. not post-processed by anyone), it would be useful if you could provide a minimalistic sample file with two time steps only, and the corresponding grd-file (ideally < 0.5 MB).
Then I could include this in the test-suit, so ensure the ROMS reader will handle CROCO data also in the future.
AndresSepulveda commentedon Aug 22, 2025
Thanks Knut,
There is not much liberty in what non-prognostic variables are in a CROCO output file, but yeah, they do repeat the h variable in the GRD and in the HIS/AVG output. It seems the HIS/AVG are meant to be kind of stand alone for reading, but they are not completely stand alone.
I will provide you with a minimalistic output of the default test case for CROCO (Benguela configuration) in the latest CROCO stable version, 2.1.0.
knutfrode commentedon Aug 22, 2025
Good.
Maybe you could make 3 timesteps, instead of 2, but in a single file.
But a small region is preferrable to minimise size.
AndresSepulveda commentedon Aug 25, 2025
Hi Knut,
Here are the files for the default case in the latest CROCO.
Domain size is 41x42 (dx=30km)
croco_grd.nc.gz
croco_his.nc.gz
knutfrode commentedon Aug 27, 2025
Hi,
One (of several) problem seem to be that the dimensions of e.g. current components are not the same as the corresponding masks (from grd-file).
E.g. the horizontal dimensions of
uare(eta_rho, xi_u)which I assume must be a bug, and should instead be(eta_u, xi_u)as for the corresponding mask?I made now a fix for this in the ROMS-reader, which now also handles the second problem of duplicate variables in his- and grd-files:
58cfaa5#diff-e8bb6de9d5f842a302a347821fd8734bbae0109243a85aea2d3cf02b8b5bdd6d
After this, your sample files work well, and I added also a reduced version (removed unnecessary variables and lower layers) in the repository and a corresponding test.
A third problem with the Croco-output, which btw is not critical in this specific case, is the use of
standard_namefor elements which are not found in the official standard_name table: https://cfconventions.org/Data/cf-standard-names/current/build/cf-standard-name-table.htmlExamples are
ocean_s_coordinate_g2_at_w_locationandlongitude_at_u_locationThis is bad practice, and undermines the very purpose of the
standard_nametable. If anything,long_nameshould be used instead ofstandard_namehere.If you have contact with the croco-developers, you are welcome to forward/repost these concerns - as it is better to fix these problems at the origin, instead of independent softwares (such as OpenDrift) needing to make ugly, hardcoded workarounds.
I have not yet made a new conda version (1.14.3) including this fix, but will come within a day or two.
knutfrode commentedon Aug 28, 2025
OpenDrift 1.14.3 (with mentioned fix for Croco) is now available on conda-forge: https://anaconda.org/conda-forge/opendrift