Skip to content
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

Asdf-Support #708

Merged
merged 35 commits into from
Aug 22, 2024
Merged

Asdf-Support #708

merged 35 commits into from
Aug 22, 2024

Conversation

ViciousEagle03
Copy link
Member

@ViciousEagle03 ViciousEagle03 commented May 20, 2024

This PR adds ASDF support for ndcube objects.

GitHub Project Board Link

This Pull Request is currently a Work In Progress and will be continuously updated as we expand support for serializing ndcube objects to ASDF.

@ViciousEagle03 ViciousEagle03 marked this pull request as draft May 20, 2024 15:58
Copy link

@braingram braingram left a comment

Choose a reason for hiding this comment

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

Thanks for sharing your work. It looks like a great start! I left a bunch of comments. I did not look over the ndcube.py changes.

ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
ndcube/asdf/resources/schemas/NDCube-0.1.0.yaml Outdated Show resolved Hide resolved
ndcube/asdf/resources/schemas/NDCube-0.1.0.yaml Outdated Show resolved Hide resolved
pyproject.toml Show resolved Hide resolved
@nabobalis nabobalis deleted the branch sunpy:asdf-support June 4, 2024 22:02
@nabobalis nabobalis closed this Jun 4, 2024
@nabobalis nabobalis reopened this Jun 4, 2024
@nabobalis nabobalis added this to the 2.4.0 milestone Jun 4, 2024
@ViciousEagle03

This comment was marked as outdated.

@nabobalis

This comment was marked as outdated.

@nabobalis nabobalis removed this from the 2.4.0 milestone Jun 4, 2024
@Cadair Cadair added this to the 2.4.0 milestone Jun 5, 2024
Copy link

@braingram braingram left a comment

Choose a reason for hiding this comment

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

I'm a bit confused. Several of the suggestions in my previous comments were marked as resolved with responses that gave me the impression they were "ok" yet the changes were not made. I was going through updating comments but stopped when I realized this PR might not be up-to-date.

Are there changes not committed that have the previous suggestions? If not, is there a reason these suggestions were dismissed?

EDIT: I'm not sure what's up with github but me posting this comment caused the PR to update for me :-/ I'm now seeing the changes made in cd31d95 which I did not previously see.

ndcube/asdf/converters/tablecoord_converter.py Outdated Show resolved Hide resolved
Copy link

@braingram braingram left a comment

Choose a reason for hiding this comment

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

Now that I'm looking at the newest code 🤦

Just a few comments/questions and one request.

Would you add asdf to the dependencies and set a version that makes the oldestdeps job happy?

@ViciousEagle03
Copy link
Member Author

Now that I'm looking at the newest code 🤦

Just a few comments/questions and one request.

Would you add asdf to the dependencies and set a version that makes the oldestdeps job happy?

Sure, I am on it.

pyproject.toml Outdated Show resolved Hide resolved
Copy link

@braingram braingram left a comment

Choose a reason for hiding this comment

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

Looks good to me. Thanks!

Copy link
Member

@Cadair Cadair left a comment

Choose a reason for hiding this comment

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

This PR looks amazing @ViciousEagle03 thanks for all your work on it. I have a few small-ish comments and then I think we can merge it.

extra_coords._mapping = node.get("mapping")
extra_coords._lookup_tables = node.get("lookup_tables", [])
extra_coords._dropped_tables = node.get("dropped_tables")
extra_coords._ndcube = node.get("ndcube")
Copy link
Member

Choose a reason for hiding this comment

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

@braingram @ViciousEagle03 is asdf smart enough to handle this circular reference and not save out the ndcube object twice? i.e. I save an NDCube which has an ExtraCoords which references the same NDCube?

Choose a reason for hiding this comment

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

Theoretically yes but I believe the converter will need to be updated.
https://asdf.readthedocs.io/en/latest/asdf/extending/converters.html#reference-cycles
That seems like a good test case.

Copy link
Member Author

@ViciousEagle03 ViciousEagle03 Jul 19, 2024

Choose a reason for hiding this comment

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

@braingram, for the current implementation I believe it is still not storing the NDCube object twice, right?
And also in the current from_yaml_tree method, it doesn't have yield but it can still deserialize the extra_coords object, that is, when the extra_coords converter is called the extra_coords.ndcube shows _PendingValue and when it gets picked up in the NDCube converter and the ndcube.extra_coords is initialized the reference to the ndcube is properly mapped in the ndcube.extra_coords._ndcube.

We can see the deserialized NDCube object and the NDCube reference address for the ExtraCoords associated is the same for the below.

(Pdb) ndcube.extra_coords._ndcube
<ndcube.ndcube.NDCube object at 0x7c84fe60c2d0>
NDCube
------
Shape: (10, 10)
Physical Types of Axes: [('em.energy', 'time', 'pos.eq.ra', 'pos.eq.dec'), ('time', 'custom:CUSTOM')]
Unit: None
Data Type: float64
(Pdb) ndcube
<ndcube.ndcube.NDCube object at 0x7c84fe60c2d0>
NDCube
------
Shape: (10, 10)
Physical Types of Axes: [('em.energy', 'time', 'pos.eq.ra', 'pos.eq.dec'), ('time', 'custom:CUSTOM')]
Unit: None
Data Type: float64
(Pdb) 

Choose a reason for hiding this comment

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

Thanks for testing this out. This looks to be working because __set__ overwrites _ndcube when _extra_coords is assigned:

value._ndcube = obj

I am not sure what's going on with __set__. @Cadair is there ever an instance where:

  • the extra_coords attached to a NDCube will reference a different NDCube?
  • extra_coords will exist without a NDCube?

Copy link
Member

Choose a reason for hiding this comment

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

the extra_coords attached to a NDCube will reference a different NDCube?

No, that should be explicitly prohibited by the descriptor.

extra_coords will exist without a NDCube?

I think this might be possible yes.

Choose a reason for hiding this comment

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

extra_coords will exist without a NDCube?

I think this might be possible yes.

Is there a minimal example that would show this? Perhaps it can be used for a test case for the converter.

Copy link
Member

Choose a reason for hiding this comment

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

I think you can just instantiate one standalone and then add some coordinates to it with the same API as you can if it's attached to the cube.

Copy link
Member

Choose a reason for hiding this comment

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

turns out you can't: #753

pyproject.toml Outdated Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved
tox.ini Outdated Show resolved Hide resolved
tox.ini Outdated Show resolved Hide resolved
tox.ini Outdated Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Show resolved Hide resolved
@braingram
Copy link

One other minor request. Would you rename the asdf directory to _asdf (to make it more explicit that this is private API)?

@ViciousEagle03
Copy link
Member Author

Apologies for the delay, @nabobalis would you mind taking a look? As I mentioned earlier, the oldestdeps is failing.

@nabobalis
Copy link
Contributor

Apologies for the delay, @nabobalis would you mind taking a look? As I mentioned earlier, the oldestdeps is failing.

It is creating a warning which is failing the CI:

AsdfWarning: Converter handles multiple tags for this extension, but does not implement a select_tag method. This previously worked because Converter subclasses inherited the now removed select_tag. This will be an error in a future version of asdf

I would just ignore the warning being created by adding it to the pytest.ini list.

@ViciousEagle03
Copy link
Member Author

Apologies for the delay, @nabobalis would you mind taking a look? As I mentioned earlier, the oldestdeps is failing.

It is creating a warning which is failing the CI:

AsdfWarning: Converter handles multiple tags for this extension, but does not implement a select_tag method. This previously worked because Converter subclasses inherited the now removed select_tag. This will be an error in a future version of asdf

I would just ignore the warning being created by adding it to the pytest.ini list.

Hey @nabobalis, thanks for the help. Even after adding the asdf.exceptions.AsdfWarning, some of the tests are still failing due to AssertionError, as the pixel_shape serialization of gWCS was added in version 0.20. I wonder if it might be simpler to skip the tests if the gWCS version is <0.20, rather than adding asdf as an optional dependency.

@nabobalis
Copy link
Contributor

Hey @nabobalis, thanks for the help. Even after adding the asdf.exceptions.AsdfWarning, some of the tests are still failing due to AssertionError, as the pixel_shape serialization of gWCS was added in version 0.20. I wonder if it might be simpler to skip the tests if the gWCS version is <0.20, rather than adding asdf as an optional dependency.

Yeah that makes sense. If there is no functional way to do pixel_shape serialization until this version of gwcs, skipping them for versions older than 0.20 is to me the best way.

Copy link
Member

@Cadair Cadair left a comment

Choose a reason for hiding this comment

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

This looks great to me. All my comments are minor.

ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
ndcube/asdf/converters/ndcube_converter.py Outdated Show resolved Hide resolved
extra_coords._mapping = node.get("mapping")
extra_coords._lookup_tables = node.get("lookup_tables", [])
extra_coords._dropped_tables = node.get("dropped_tables")
extra_coords._ndcube = node.get("ndcube")
Copy link
Member

Choose a reason for hiding this comment

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

the extra_coords attached to a NDCube will reference a different NDCube?

No, that should be explicitly prohibited by the descriptor.

extra_coords will exist without a NDCube?

I think this might be possible yes.

@Cadair Cadair merged commit 406b867 into sunpy:asdf-support Aug 22, 2024
19 checks passed
@Cadair Cadair modified the milestones: 2.4.0, asdf Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants