Skip to content

Particles not moving: CROCO and xarray #1665

Open

Description

@AndresSepulveda

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

  1. knutfrode commented on Aug 20, 2025

    @knutfrode
    Collaborator

    Hi,
    The first problem seems to be that h is found in both ROMS-file and the gridfile, and then Xarray don't know which to use.
    I added now compat=override to 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_u is 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.

  2. AndresSepulveda commented on Aug 20, 2025

    @AndresSepulveda
    ContributorAuthor

    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

  3. knutfrode commented on Aug 22, 2025

    @knutfrode
    Collaborator

    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.

  4. AndresSepulveda commented on Aug 22, 2025

    @AndresSepulveda
    ContributorAuthor

    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.

  5. knutfrode commented on Aug 22, 2025

    @knutfrode
    Collaborator

    Good.
    Maybe you could make 3 timesteps, instead of 2, but in a single file.
    But a small region is preferrable to minimise size.

  6. AndresSepulveda commented on Aug 25, 2025

    @AndresSepulveda
    ContributorAuthor

    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

  7. knutfrode commented on Aug 27, 2025

    @knutfrode
    Collaborator

    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 u are (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_name for elements which are not found in the official standard_name table: https://cfconventions.org/Data/cf-standard-names/current/build/cf-standard-name-table.html
    Examples are ocean_s_coordinate_g2_at_w_location and longitude_at_u_location
    This is bad practice, and undermines the very purpose of the standard_name table. If anything, long_name should be used instead of standard_name here.

    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.

  8. knutfrode commented on Aug 28, 2025

    @knutfrode
    Collaborator

    OpenDrift 1.14.3 (with mentioned fix for Croco) is now available on conda-forge: https://anaconda.org/conda-forge/opendrift

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions