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

Make atom_columns of XYZ load_one more hackable #200

Open
FarnazH opened this issue Aug 26, 2020 · 2 comments
Open

Make atom_columns of XYZ load_one more hackable #200

FarnazH opened this issue Aug 26, 2020 · 2 comments
Milestone

Comments

@FarnazH
Copy link
Member

FarnazH commented Aug 26, 2020

Make it easier for the user to change how a column is parsed. For example, change the units of coordinates from angstrom to bohr.

@FarnazH FarnazH added this to the 1.0.0 milestone Aug 26, 2020
@tovrstra
Copy link
Member

tovrstra commented Apr 1, 2021

I'll mention here how this can be accomplished at the time of writing. We can see from there how to simplify it.

from iodata import load_one
from iodata.formats.xyz import DEFAULT_ATOM_COLMNS

ATOM_COLUMNS = [
    DEFAULT_ATOM_COLUMNS[0],
    ("atcoords", None, (3,), float,
     (lambda word: float(word)),
     (lambda value: "{:15.10f}".format(value)))
]

data = load_one("example_in_bohr.xyz", atom_columns=ATOM_COLUMNS)

@tovrstra
Copy link
Member

tovrstra commented Apr 1, 2021

The main limitation of the current approach of defining the columns is that everything must be repeated when one is only interested in just changing one little detail. Here is an attempt to get around this...

We can define the columns through dictionaries, in which it is easier to override certain fields, while the rest is kept to the default. We can put this in iodata.xyz:

DEFAULT_COLUMN_SETTINGS = {
    "atnums", {
        "dictkey": None,
        "shape": (),
        "type": int,
        "parse": (lambda word: int(word) if word.isdigit() else sym2num[word.title()]),
        "format": (lambda atnum: "{:2s}".format(num2sym[atnum])),
        "unit": angstrom,
    }
    "atcoords", {
        "dictkey": None,
        "shape": (3,),
        "type": float,
        "parse": (lambda word: float(word)),
        "format": (lambda value: format(value, "15.10f")),
        "unit": angstrom,
    }
}
DEFAULT_COLUMNS = ["atnums", "atcoords"]

We can add optional arguments for load_one and dump_one in iodata.xyz to override these two defaults. For the case of column_settings, dictionary updates can be used, such that it becomes possible to modify just one setting in the defaults, without having to repeat everything. This would allow switching units for XYZ files as follows:

from iodata import load_one

data = load_one("example_in_bohr.xyz", column_settings={"atcoords": {"unit": 1}})

@FarnazH What do you think?

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

No branches or pull requests

2 participants