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

Multistatereporter variable pos frequency #767

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

Conversation

ianmkenney
Copy link

@ianmkenney ianmkenney commented Jan 16, 2025

Continuation of #712. There are multiple avenues to address the current failing tests. I would like to address those concerns here before continuing in that PR.

@ianmkenney ianmkenney force-pushed the multistatereporter_variable_pos_frequency branch 2 times, most recently from a0e7dbb to a262c2b Compare January 17, 2025 18:25
@ianmkenney ianmkenney changed the title Multistatereporter variable pos frequency and masked arrays [DNM/WIP] Multistatereporter variable pos frequency and masked arrays Jan 17, 2025
@ianmkenney ianmkenney changed the base branch from multistatereporter_variable_pos_frequency to main January 17, 2025 18:33
@ianmkenney
Copy link
Author

This PR will take over #712.

Accessing data from netCDF returns a masked array, even if no data is
masked. For valid data, extract it and give back just the basic numpy
array. For invalid data, give back a nan array with the proper shape.
@ianmkenney ianmkenney changed the title [DNM/WIP] Multistatereporter variable pos frequency and masked arrays [DNM/WIP] Multistatereporter variable pos frequency Jan 17, 2025
Copy link

codecov bot commented Jan 17, 2025

Codecov Report

Attention: Patch coverage is 98.23009% with 2 lines in your changes missing coverage. Please review.

Project coverage is 84.91%. Comparing base (f3f355a) to head (c211252).

Additional details and impacted files

@ianmkenney ianmkenney changed the title [DNM/WIP] Multistatereporter variable pos frequency Multistatereporter variable pos frequency Jan 17, 2025
@ianmkenney
Copy link
Author

@ijpulidos @IAlibay @mikemhenry I can't request reviewers, but I think this is ready for review.

Copy link
Contributor

@ijpulidos ijpulidos 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 good to me. Thanks a lot! Great work. Just a couple of non-blocking comments.

raise IndexError
# pull the valid data out of masked array
positions = unit.Quantity(x.data, unit.nanometers)
except (IndexError, KeyError):
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-blocking comment. Should we try outputting something here when an error is caught? Maybe something warning users that there's missing data or something similar. What are the reasons for the array to be masked?

Copy link
Author

Choose a reason for hiding this comment

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

On the topic of how MaskedArrays work here. Assuming that a particular coordinate exists in a dimension (e.g. at least some data exists for a given iteration) we always get back a MaskedArray. The MaskedArray will have a data attribute with a numpy array that will be masked by the MaskedArrays mask attribute. If the data was all valid, then we just pull that information out and expose it to the user. If no data exists at that dimension coordinate, then we'll just get an IndexError so we give back a zero array in place of the nonsense data inside the MaskedArray. By doing it this way, a user never has to deal with a MaskedArray.

I think that if the data was masked it's basically the same behavior as if the data didn't exist and we would have expected a zero array anyways. I don't really see much of a reason to give a warning about this since having a giant array of zeros is kind of a warning already. I'd even be careful saying the data is missing since that would imply it should have been there in the first place.

information, 0 would prevent information being written
velocity_interval : int, default 1
the frequency at which to write positions relative to analysis
information, 0 would prevent information being written
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-blocking question. This might be too late now to ask, but why is that we want positions and velocities to be stored at different intervals? Does it make sense to define a state (i.e. with positions and velocities) from different intervals? Just thinking about ways of not having to deal with the "complexity" of having to check for pos and vel intervals independently.

Copy link
Author

Choose a reason for hiding this comment

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

I think this would depend on the intent of the simulation. I could see that someone interested in doing VAC calculations wouldn't care as much about the positions.

Copy link
Contributor

Choose a reason for hiding this comment

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

So the one case I can think of is that you might not want to store the velocities but you do want to store the positions.

I might be wrong, but as far as I remember the "state" is stored in the checkpoint? So you could recover a simulation from the checkpoint, and just store positions in the simulation file.

@IAlibay
Copy link
Contributor

IAlibay commented Jan 17, 2025

I'll be testing this in a Protocol before I review :)

@@ -100,6 +100,12 @@ class MultiStateReporter(object):
analysis_particle_indices : tuple of ints, Optional. Default: () (empty tuple)
If specified, it will serialize positions and velocities for the specified particles, at every iteration, in the
reporter storage (.nc) file. If empty, no positions or velocities will be stored in this file for any atoms.
position_interval : int, default 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we store these values inside of the NetCDF file as additional variables? This would make it a lot easier to know what the spacing is between frames, rather than having to iterate through the positions.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm being blind sorry 🙈 - it's below

@@ -100,6 +100,12 @@ class MultiStateReporter(object):
analysis_particle_indices : tuple of ints, Optional. Default: () (empty tuple)
If specified, it will serialize positions and velocities for the specified particles, at every iteration, in the
reporter storage (.nc) file. If empty, no positions or velocities will be stored in this file for any atoms.
position_interval : int, default 1
the frequency at which to write positions relative to analysis
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you also make it clear here that this controls whether or not box_vectors are written down? (it's self-evident, but it might be good to make it clear to users)

@@ -202,6 +214,16 @@ def checkpoint_interval(self):
"""Returns the checkpoint interval"""
return self._checkpoint_interval

@property
def position_interval(self):
"""Interval relative to energies that positions are written at"""
Copy link
Contributor

Choose a reason for hiding this comment

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

And box_vectors

# pass zeros as velocities when key is not found (<0.21.3 behavior)
velocities = np.zeros_like(positions)

if 'box_vectors' in storage.variables:
# Restore box vectors.
x = storage.variables['box_vectors'][read_iteration, replica_index, :, :].astype(np.float64)
# TODO: Are box vectors also variably saved?
Copy link
Contributor

Choose a reason for hiding this comment

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

From wwhat I can tell, they seem to be saved at the same rate as positions - worth double checking though!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants