Skip to content

feat(graphs): support area positional argument in GraphInspector #415

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 23 commits into
base: main
Choose a base branch
from

Conversation

JPXKQX
Copy link
Member

@JPXKQX JPXKQX commented Jul 10, 2025

Description

This PR adds the positional argument area in the GraphInspector class. It can also be used in the CLI as follows,

anemoi-graphs inspect graph.pt output_viz_subset/ --area=40,10,20,30

What problem does this change solve?

The current inspection tools are great for debugging and designing our graphs, but they lack the ability to support high-resolution graphics.

What issue or task does this change relate to?

Additional notes

As a contributor to the Anemoi framework, please ensure that your changes include unit tests, updates to any affected dependencies and documentation, and have been tested in a parallel setting (i.e., with multiple GPUs). As a reviewer, you are also responsible for verifying these aspects and requesting changes if they are not adequately addressed. For guidelines about those please refer to https://anemoi.readthedocs.io/en/latest/

By opening this pull request, I affirm that all authors agree to the Contributor License Agreement.


📚 Documentation preview 📚: https://anemoi-training--415.org.readthedocs.build/en/415/


📚 Documentation preview 📚: https://anemoi-graphs--415.org.readthedocs.build/en/415/


📚 Documentation preview 📚: https://anemoi-models--415.org.readthedocs.build/en/415/

@JPXKQX JPXKQX self-assigned this Jul 10, 2025
@github-actions github-actions bot added enhancement New feature or request graphs labels Jul 10, 2025
@JPXKQX JPXKQX added the ATS Approval Not Needed No approval needed by ATS label Jul 10, 2025
@github-actions github-actions bot added the bug Something isn't working label Jul 10, 2025
@github-project-automation github-project-automation bot moved this to Now In Progress in Anemoi-dev Jul 22, 2025
@@ -20,8 +20,8 @@ You can define your graph in a YAML configuration file, following the
same approach described in the other usage sections. This YAML file
should specify the nodes, edges, and any attributes required for your
graph. For more details on how to structure your recipe, refer to the
examples in the :doc:`usage-getting_started` and
:doc:`usage-limited_area` sections.
examples in the :ref:`usage-getting_started` and
Copy link
Collaborator

Choose a reason for hiding this comment

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

I guess this is fixing a broken link from before in the dosc?

"Nodes from which to remove the unconnected nodes."
area: tuple[float, float, float, float] = Field(default=(40, 10, 30, 20))
"Area of interest to crop the nodes, (north, west, south, east)."
nodes_name: str | Iterable[str]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is repeated


# Convert area limits to [-90, 90]x[0,360]
west, east = west % 360, (east - 1) % 360 + 1
assert (west - east) % 360 != 0, "West and East limits must be different."
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'd add a few more asserts to ensure values are in the expected limits (-90,90) and (0,360)


def compute_mask(self, graph: HeteroData, nodes_name: str) -> torch.Tensor:
"""Compute the mask of connected nodes."""
latlons = graph[nodes_name].x * 180 / torch.pi
Copy link
Collaborator

Choose a reason for hiding this comment

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

could we use np.rad2deg instead?

def compute_mask(self, graph: HeteroData, nodes_name: str) -> torch.Tensor:
"""Compute the mask of connected nodes."""
latlons = graph[nodes_name].x * 180 / torch.pi
mask = SubsetNodesInArea.points_inside_area(lats=latlons[:, 0], lons=latlons[:, 1], area=self.area)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you think we will be using this method somewhere else or what's the motivation for making it a staticmethod?

graph = self.update_edge_indices(graph)
graph = self.add_attribute(graph)
for nodes_name in self.nodes_names:
mask = self.compute_mask(graph, nodes_name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

if those are going to be hidden methods and the update_graph is the public one could be make those _ compute_mask for clarity?

connected_mask[edges.edge_index[1]] = True

return connected_mask


class SubsetNodesInArea(BaseNodeMaskingProcessor):
Copy link
Collaborator

Choose a reason for hiding this comment

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

could be have a test for this also on graphs/tests/processors/test_post_process.py?

Copy link
Collaborator

@anaprietonem anaprietonem left a comment

Choose a reason for hiding this comment

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

A few suggestions, nice feature! Thanks for implementing this Mario!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ATS Approval Not Needed No approval needed by ATS bug Something isn't working enhancement New feature or request graphs
Projects
Status: Now In Progress
Development

Successfully merging this pull request may close these issues.

2 participants