Skip to content

Update MeshXY's .filters method to work with coordinates that do not have a standard name and allow the mesh to be saved#7185

Draft
pt331 wants to merge 6 commits into
SciTools:mainfrom
pt331:no-standard-name-mesh-errors
Draft

Update MeshXY's .filters method to work with coordinates that do not have a standard name and allow the mesh to be saved#7185
pt331 wants to merge 6 commits into
SciTools:mainfrom
pt331:no-standard-name-mesh-errors

Conversation

@pt331

@pt331 pt331 commented Jul 1, 2026

Copy link
Copy Markdown

Description

closes #4863

In investgating the issue, we found that when saving a Mesh and converting them to MeshCoords had root a root problem in Mesh.filters(), where it was ultimately trying to guess the coord's axis, which relies on the standard_name.

This pull request addresses the issue by adding mesh_filters, which directly pulls the coordinates out of the mesh, without needing to consider their names. The construction of the mesh already gave us the information needed to do this. The original filters function calls mesh_filters before sending it to the metadata_filter like before, but removing the axis from the call because it is already accounted for.

To make the filter slightly more intelligent and to avoid the hasattr(self, "face_coords") line, _Mesh2DCoordinateManager implements its own mesh_filters to deal with face coordinates separately. It also gave the added benefit of raising a ValueError specific to the _Mesh1DCoordinateManager case, where it mentions that it only expects node and edge locations (not face). However, this has broken tests, so I will need to check if this causes any unexpected issues for users.

In the case for saving coordinates without a standard_name, we decided that naming it as "unknown" should be suffice, like what is done for cubes. In the case of using ncdump with the MWE:

ncdump -h ~/mesh_new.nc 
netcdf mesh_new {
dimensions:
        Mesh2d_node = 3 ;
        Mesh2d_face = 1 ;
        Mesh_2d_face_N_nodes = 3 ;
variables:
        int Mesh_2d ;
                Mesh_2d:cf_role = "mesh_topology" ;
                Mesh_2d:topology_dimension = 2 ;
                Mesh_2d:node_coordinates = "unknown unknown_0" ;
                Mesh_2d:face_coordinates = "unknown_1 unknown_2" ;
                Mesh_2d:face_node_connectivity = "mesh2d_face" ;
        int64 unknown(Mesh2d_node) ;
        int64 unknown_0(Mesh2d_node) ;
        int64 unknown_1(Mesh2d_face) ;
        int64 unknown_2(Mesh2d_face) ;
        int64 mesh2d_face(Mesh2d_face, Mesh_2d_face_N_nodes) ;
                mesh2d_face:cf_role = "face_node_connectivity" ;
                mesh2d_face:start_index = 0LL ;

// global attributes:
                :Conventions = "CF-1.7" ;
}

There may be some way to give a more meaningful name, but it will involve making assumptions which may not apply to everyone.

I have tried my hand at adding types as I go along, but most areas are beyond my knowledge. Ultimately, I would like to remove the Any types I added to make mypy happy, but will take more time for me to know how to best update them.

Checklist

Important

The Iris core developers are here to help! If anything below is unclear, just post a comment asking for help 😊


Tip

Things you can trigger on this PR:

  • Add this label to trigger benchmarks: benchmark_this Request that this pull request be benchmarked to check if it introduces performance shifts
  • Visit this URL - swapping 9999 for this PR's number - to re-trigger the CLA check:
    https://cla-assistant.io/check/SciTools/iris?pullRequest=9999

@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.15%. Comparing base (9c5eb0a) to head (5be6d48).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7185   +/-   ##
=======================================
  Coverage   90.15%   90.15%           
=======================================
  Files          91       91           
  Lines       24989    24990    +1     
  Branches     4687     4686    -1     
=======================================
+ Hits        22528    22529    +1     
  Misses       1683     1683           
  Partials      778      778           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@pt331 pt331 changed the title Fix MeshXY's .coords method Allow for saving Mesh dat that have coordinates without a standard-name MeshXY's .coords method Jul 3, 2026
@pt331 pt331 changed the title Allow for saving Mesh dat that have coordinates without a standard-name MeshXY's .coords method Allow for saving Mesh dat that have coordinates without a standard-name MeshXY's .filters method Jul 3, 2026
@pt331 pt331 changed the title Allow for saving Mesh dat that have coordinates without a standard-name MeshXY's .filters method Update MeshXY's .filters method to work with coordinates that do not have a standard name and allow the mesh to be saved Jul 3, 2026

@trexfeathers trexfeathers left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks lovely!

I imagine you're looking into the test failures. I don't know what to make of the docs failure though; I'll look into that.

attributes=None,
axis=None,
item: str | None | Any = None,
standard_name: str | None = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know more than I do in this space. Is Optional[str] frowned upon, or a matter of personal choice?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's mostly a personal choice and it's also best practice: https://typing.python.org/en/latest/reference/best_practices.html#shorthand-syntax . It's easier to write and doesn't need to import something. There has been some discussion I've also seen discussions where they could have a different semantic meanings: https://stackoverflow.com/a/73591412 (not that I agree with them)
It might be worth adding something to a style guide if this is a distinction worth having though.

var_name=None,
attributes=None,
axis=None,
item: str | None | Any = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
item: str | None | Any = None,
item: str | None | _DimensionalMetadata | BaseMetadata = None,

A dictionary of attributes desired on the object. If ``None``,
does not check for ``attributes``.
attributes : Mapping, optional, Any
A mapping of attributes desired on the object. If ``None``,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suggestion is less technically pure, but it would be helpful to find a way to mention dict in the phrasing here. Plenty of our users don't know what a Mapping is.

@pt331 pt331 Jul 3, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah that's fair. I'll add it as part of the comments. I actually can't remember why I changed it from a dict to a Mapping. I have a feeling mypy was shouting at me when somewhere else a mapping was created and I had to change it for that.

attributes=None,
axis=None,
location=None,
item: str | object | None = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
item: str | object | None = None,
item: str | None | _DimensionalMetadata | BaseMetadata = None,

attributes : dict, optional
A dictionary of attributes desired on the coordinates. If ``None``,
attributes : Mapping, optional
A mapping of attributes desired on the coordinates. If ``None``,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, some way to communicate to novice users that Mapping covers dict.

attributes=None,
axis=None,
location=None,
item: str | None | Any = None,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
item: str | None | Any = None,
item: str | None | _DimensionalMetadata | BaseMetadata = None,

@trexfeathers

Copy link
Copy Markdown
Contributor

Explanation for the docs failure: #7191 (comment)

Our docs builds on Readthedocs are vulnerable because we have not yet managed to lock the dependency versions there - unlike all our tests, which is why the rest of the CI on this PR is still fine. See SciTools/workflows#38

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

Labels

None yet

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

save_mesh and Mesh.to_MeshCoord fails with confusing errors when input coordinates do not have standard_name

2 participants