Skip to content

Commit

Permalink
Merge pull request #25 from alchem0x2A/singleio
Browse files Browse the repository at this point in the history
Singleio
  • Loading branch information
alchem0x2A authored Sep 28, 2023
2 parents 5c4a6e7 + 2cb2bf9 commit 1ee9279
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 21 deletions.
18 changes: 1 addition & 17 deletions sparc/calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import subprocess

from .io import SparcBundle
from .utils import _find_default_sparc, h2gpts
from .utils import _find_default_sparc, h2gpts, deprecated
from warnings import warn, warn_explicit
from .api import SparcAPI
import datetime
Expand All @@ -27,22 +27,6 @@
defaultAPI = SparcAPI()


def deprecated(message):
def decorator(func):
def new_func(*args, **kwargs):
warn(
"Function {} is deprecated sparc-dft-api >= v0.2! {}".format(
func.__name__, message
),
category=DeprecationWarning,
)
return func(*args, **kwargs)

return new_func

return decorator


class SPARC(FileIOCalculator):
# TODO: magmom should be a possible input
implemented_properties = ["energy", "forces", "fermi", "stress"]
Expand Down
82 changes: 80 additions & 2 deletions sparc/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from .sparc_parsers.pseudopotential import copy_psp_file, parse_psp8_header
from .common import psp_dir as default_psp_dir
from .download_data import is_psp_download_complete
from .utils import string2index
from .utils import string2index, deprecated

from ase.calculators.singlepoint import SinglePointDFTCalculator
from ase.units import Hartree
Expand Down Expand Up @@ -671,6 +671,61 @@ def write_sparc(filename, images, **kwargs):
return


@deprecated("Reading individual .ion is not recommended. Please use read_sparc instead.")
def read_ion(filename, **kwargs):
"""Parse an .ion file inside the SPARC bundle using a wrapper around SparcBundle
The reader works only when other files (.inpt) exist.
The returned Atoms object of read_ion method only contains the initial positions
"""
parent_dir = Path(filename).parent
sb = SparcBundle(directory=parent_dir)
atoms = sb._read_ion_and_inpt()
return atoms

@deprecated("Writing individual .ion file is not recommended. Please use write_sparc instead.")
def write_ion(filename, atoms, **kwargs):
"""Write .ion and .inpt files using the SparcBundle wrapper.
This is only for backward compatibility
"""
label = Path(filename).with_suffix("").name
parent_dir = Path(filename).parent
sb = SparcBundle(directory=parent_dir, label=label)
sb._write_ion_and_inpt(atoms, **kwargs)
return atoms


def read_static(filename, index=-1, **kwargs):
"""Parse a .static file bundle using a wrapper around SparcBundle
The reader works only when other files (.ion, .inpt) exist.
"""
parent_dir = Path(filename).parent
sb = SparcBundle(directory=parent_dir)
atoms_or_images = sb.convert_to_ase(index=index, **kwargs)
return atoms_or_images


def read_geopt(filename, index=-1, **kwargs):
"""Parse a .geopt file bundle using a wrapper around SparcBundle
The reader works only when other files (.ion, .inpt) exist.
"""
parent_dir = Path(filename).parent
sb = SparcBundle(directory=parent_dir)
atoms_or_images = sb.convert_to_ase(index=index, **kwargs)
return atoms_or_images


def read_aimd(filename, index=-1, **kwargs):
"""Parse a .static file bundle using a wrapper around SparcBundle
The reader works only when other files (.ion, .inpt) exist.
"""
parent_dir = Path(filename).parent
sb = SparcBundle(directory=parent_dir)
atoms_or_images = sb.convert_to_ase(index=index, **kwargs)
return atoms_or_images


def register_ase_io_sparc(name="sparc"):
"""
Monkey patching the ase.io and ase.io.formats
Expand Down Expand Up @@ -772,6 +827,29 @@ def _new_filetype(filename, read=True, guess=True):
"Atomatic format inference for sparc is not correctly registered. "
"You may need to use format=sparc in ase.io.read and ase.io.write. "
)
# Add additional formats including .ion (r/w), .static, .geopt, .aimd
F(
"ion",
desc="SPARC .ion file",
module="sparc",
code="1S",
ext="ion",
)
F(
"static",
desc="SPARC single point results",
module="sparc",
code="+S",
ext="static",
)
F(
"geopt",
desc="SPARC geometric optimization results",
module="sparc",
code="+S",
ext="geopt",
)
F("aimd", desc="SPARC AIMD results", module="sparc", code="+S", ext="aimd")

# TODO: remove print options as it may be redundant
print("Successfully registered sparc format with ase.io!")
print("Successfully registered sparc formats with ase.io!")
17 changes: 17 additions & 0 deletions sparc/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,26 @@
import os
import shutil
import numpy as np
from warnings import warn
from typing import Union, List, Optional


def deprecated(message):
def decorator(func):
def new_func(*args, **kwargs):
warn(
"Function {} is deprecated sparc-dft-api >= v0.2! {}".format(
func.__name__, message
),
category=DeprecationWarning,
)
return func(*args, **kwargs)

return new_func

return decorator


def string2index(string: str) -> Union[int, slice, str]:
"""Convert index string to either int or slice
This method is a copy of ase.io.formats.string2index
Expand Down
26 changes: 24 additions & 2 deletions tests/test_000_ase_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,31 @@ def fake_read_sparc(filename, *args, **kwargs):
assert atoms.get_chemical_formula() == "Al"


def test_ase_io_filetype():
"""If hacked ase.io.formats.filetype correctly recognized sparc format"""
def test_ase_io_filetype(fs):
"""If hacked ase.io.formats.filetype correctly recognized sparc format
Due to the implementation of ase.io.formats, single file tests should be
done on non-empty files
"""
import sparc
from ase.io.formats import filetype

fs.create_dir("test.sparc")
fs.create_file("test.sparc/test.ion")
fs.create_file("test.sparc/test.static")
fs.create_file("test.sparc/test.geopt")
fs.create_file("test.sparc/test.aimd")
with open("test.sparc/test.ion", "w") as fd:
fd.write("\n")
with open("test.sparc/test.static", "w") as fd:
fd.write("\n")
with open("test.sparc/test.geopt", "w") as fd:
fd.write("\n")
with open("test.sparc/test.aimd", "w") as fd:
fd.write("\n")

assert filetype("test.sparc") == "sparc"
assert filetype("test.sparc/test.ion") == "ion"
assert filetype("test.sparc/test.static") == "static"
assert filetype("test.sparc/test.geopt") == "geopt"
assert filetype("test.sparc/test.aimd") == "aimd"

0 comments on commit 1ee9279

Please sign in to comment.