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

aniSileSiesta #544

Merged
merged 5 commits into from
Mar 8, 2023
Merged

aniSileSiesta #544

merged 5 commits into from
Mar 8, 2023

Conversation

tfrederiksen
Copy link
Contributor

This PR enables reading of siesta ANI files.

Copy link
Owner

@zerothi zerothi left a comment

Choose a reason for hiding this comment

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

Great addition!

It is however a generic file format and should perhaps be contained in the xyzSile then the aniSileSiesta could simply be a subclass of the xyz sile.

sisl/io/siesta/ani.py Outdated Show resolved Hide resolved
sisl/io/siesta/ani.py Outdated Show resolved Hide resolved
sisl/io/siesta/ani.py Outdated Show resolved Hide resolved
sisl/io/siesta/ani.py Fixed Show fixed Hide fixed
sisl/io/siesta/ani.py Fixed Show fixed Hide fixed
@codecov
Copy link

codecov bot commented Mar 2, 2023

Codecov Report

Merging #544 (d7fd5af) into main (0b5164b) will increase coverage by 0.01%.
The diff coverage is 94.73%.

❗ Current head d7fd5af differs from pull request most recent head a7f81b3. Consider uploading reports for the commit a7f81b3 to get more accurate results

@@            Coverage Diff             @@
##             main     #544      +/-   ##
==========================================
+ Coverage   86.23%   86.25%   +0.01%     
==========================================
  Files         365      366       +1     
  Lines       46425    46500      +75     
==========================================
+ Hits        40036    40107      +71     
- Misses       6389     6393       +4     
Impacted Files Coverage Δ
sisl/io/sile.py 86.72% <91.30%> (+0.39%) ⬆️
sisl/io/siesta/__init__.py 100.00% <100.00%> (ø)
sisl/io/siesta/ani.py 100.00% <100.00%> (ø)
sisl/io/tests/test_xyz.py 100.00% <100.00%> (ø)
sisl/io/xyz.py 97.26% <100.00%> (+0.15%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

@tfrederiksen
Copy link
Contributor Author

OK, do you then see the .ANI format as basically a xyzSile (but one with several entries)?

@zerothi
Copy link
Owner

zerothi commented Mar 2, 2023

Yes, that (I think) is the actual xyz file format. So for siesta we would simply do add_sile("ani", xyzSile, ...) and then don't do anything else.

@zerothi
Copy link
Owner

zerothi commented Mar 2, 2023

Yes, that (I think) is the actual xyz file format. So for siesta we would simply do add_sile("ani", xyzSile, ...) and then don't do anything else.

Well, perhaps we should do:

aniSileSiesta(xyzSile): pass

add_sile("ani", aniSileSiesta, ...)

sisl/io/siesta/ani.py Fixed Show fixed Hide fixed
@tfrederiksen
Copy link
Contributor Author

What about handling the sile as something that can be iterated:

s = sisl.get_sile(anifile)
g0 = s.read_geometry()
g1 = s.read_geometry()

Right now the xyzSile forces a start from the beginning, but this could be changed.

@zerothi
Copy link
Owner

zerothi commented Mar 2, 2023

What about handling the sile as something that can be iterated:

s = sisl.get_sile(anifile)
g0 = s.read_geometry()
g1 = s.read_geometry()

Right now the xyzSile forces a start from the beginning, but this could be changed.

This should work already in the xyzSile

s = sisl.get_sile(anifile)
with s:
    g0 = s.read_geometry()
    g1 = s.read_geometry()

@tfrederiksen
Copy link
Contributor Author

tfrederiksen commented Mar 2, 2023

This should work already in the xyzSile

s = sisl.get_sile(anifile)
with s:
    g0 = s.read_geometry()
    g1 = s.read_geometry()

Yes, sorry, this works!

@tfrederiksen
Copy link
Contributor Author

Am I on the right track with wrapping the single-time read_geometry function for multiple read attempts as done here?

sisl/io/xyz.py Fixed Show fixed Hide fixed
@zerothi
Copy link
Owner

zerothi commented Mar 3, 2023

Am I on the right track with wrapping the single-time read_geometry function for multiple read attempts as done here?

Yes, I think something like this.

My idea would be to unify MD output files with a decorator, so essentially something like this:

@sile_fh_open
@read_multiple(start=0, step=None)
def read_geometry(self, atoms=None, sc=None)
...

where the decorator ensures correct calls and adds documentation etc.

def read_multiple(start=0, step=None):
    "decorate a function for doing multiple reads "
    def decorator(func):
        @wraps
        def f(*args, *, start=start, stop=stop, **kwargs):
                 if stop is None:
 return func(*args, **kwargs)
...

something like the above could work and make interfaces the same, what do you think?

@tfrederiksen
Copy link
Contributor Author

tfrederiksen commented Mar 5, 2023

What do you think of the current layout? I tried to follow your suggestions.

Maybe for the ANI files it would be natural to have all=True as a default?

@tfrederiksen
Copy link
Contributor Author

How should write be handled for lists of geometries? Would it make sense that a multiple-read call returns an instance from a new class like GeometryCollection (instead of a simple list)?

sisl/io/sile.py Outdated Show resolved Hide resolved
sisl/io/siesta/ani.py Outdated Show resolved Hide resolved
sisl/io/sile.py Outdated Show resolved Hide resolved
sisl/io/sile.py Outdated Show resolved Hide resolved
sisl/io/xyz.py Show resolved Hide resolved
@tfrederiksen
Copy link
Contributor Author

How should write be handled for lists of geometries? Would it make sense that a multiple-read call returns an instance from a new class like GeometryCollection (instead of a simple list)?

Any thoughts on this?

Copy link
Owner

@zerothi zerothi left a comment

Choose a reason for hiding this comment

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

I would also like to remove the unnecessary commits, could you rebase and squash the commits that shouldn't be used? Then I can have a final go and get this in?

sisl/io/siesta/ani.py Outdated Show resolved Hide resolved
sisl/io/sile.py Outdated Show resolved Hide resolved
@pfebrer
Copy link
Contributor

pfebrer commented Mar 6, 2023

How should write be handled for lists of geometries? Would it make sense that a multiple-read call returns an instance from a new class like GeometryCollection (instead of a simple list)?

As I have said already on several other issues, I think sisl should have a well defined way of working with trajectories :) Otherwise, just reading trajectories from files as lists of Geometry objects and afterwards concatenating their coordinates in a numpy array is far from optimal. It would also be cool to add MD analysis tools into sisl, but since there's no defined way to treat trajectories, there is no space right now in the package for them, which is sad :(

@tfrederiksen
Copy link
Contributor Author

I would also like to remove the unnecessary commits, could you rebase and squash the commits that shouldn't be used? Then I can have a final go and get this in?

I've cleaned up the commits. Let me know if you want me to do more changes, otherwise feel free to modify further.


def test_xyz_multiple(sisl_tmp):
f = sisl_tmp('sisl.xyz', _dir)
open(f, 'w').write("""1

Check warning

Code scanning / CodeQL

File is not always closed

File is opened but is not closed.
It should now be able to handle more cases and more easily transfer
data to a required data-structure.

Added an xyz skip function which is much faster than the read_geometry
call.

Changed default all=True for the ANI file.
Changed the suffix for ANI files to be capitalized.

Added a postprocess function for post-processing the data returned
by the read_multiple function. This would enable one to merge stuff etc.

Signed-off-by: Nick Papior <[email protected]>
@pfebrer
Copy link
Contributor

pfebrer commented Mar 8, 2023

Hi! I'm checking the sile_read_multiple function and the all argument seems odd to me. start, stop, step are already enough, no?

Why not go with the conventions of slicing in python? I.e. behaving exactly as slice.

Additionally, I know it looks a bit ugly at first sight but numpy.mgrid does something like:

gc = xyzSile(f).read_geometry[4::10]

Just something to think about, not that I personally think it's a good idea :)

@zerothi
Copy link
Owner

zerothi commented Mar 8, 2023

Hi! I'm checking the sile_read_multiple function and the all argument seems odd to me. start, stop, step are already enough, no?

See discussion here #544 (comment)

mnt: fixed and simplified some logic in the read_multiple function

# start by reading past start
for _ in range(start):
r = skip_call(*args, **kwargs)

Check notice

Code scanning / CodeQL

Unused local variable

Variable r is not used.
g = xyzSile(f).read_geometry(stop=2, step=1)
assert g[0].na == 1 and g[-1].na == 2

g = xyzSile(f).read_geometry(sc=None, atoms=None)

Check notice

Code scanning / CodeQL

Unused local variable

Variable g is not used.
@zerothi zerothi merged commit f36b0c3 into zerothi:main Mar 8, 2023
@tfrederiksen tfrederiksen deleted the aniSileSiesta branch March 19, 2024 08:21
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.

3 participants