Skip to content

Commit

Permalink
Support for (A)XSF XCrySDen file format (#22)
Browse files Browse the repository at this point in the history
* Shamelessly copy from extxyz interface for xsf interface

* Fix typo in filename

* Rename XSF to XCrySDenStructureFormat
  • Loading branch information
azadoks committed Jul 11, 2023
1 parent 5aa66ca commit 8db2ec1
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ PeriodicTable = "7b2266bf-644c-5ea3-82d8-af4bbd25a884"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a"
XCrySDenStructureFormat = "02310045-4665-40c9-a658-98c497d2eca9"

[compat]
AtomsBase = "0.3"
Expand All @@ -22,6 +23,7 @@ PeriodicTable = "1"
Reexport = "1"
Unitful = "1"
UnitfulAtomic = "1"
XCrySDenStructureFormat = "0.1"
julia = "1.6"

[extras]
Expand Down
43 changes: 43 additions & 0 deletions src/xsf.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import XCrySDenStructureFormat as XSF

"""
Parse or write file using [XSF](https://github.com/azadoks/XCrySDenStructureFormat.jl)
Supported formats:
- [XSF](http://www.xcrysden.org/doc/XSF.html)
"""
struct XsfParser <: AbstractParser end

function supports_parsing(::XsfParser, file; save, trajectory)
_, ext = splitext(file)
ext in (".xsf", ".axsf")
end

function load_system(::XsfParser, file::AbstractString, index=nothing)
if isnothing(index)
frames = XSF.load_xsf(file)
isempty(frames) && error(
"XSF returned no frames. Check the passed file is a valid (a)xsf file."
)
return last(frames)
else
return XSF.load_xsf(file)[index]
end
end

function save_system(::XsfParser, file::AbstractString, system::AbstractSystem)
XSF.save_xsf(file, system)
end

function load_trajectory(::XsfParser, file::AbstractString)
XSF.load_xsf(file)
end

function save_system(::XsfParser, file::AbstractString, system::AbstractSystem)
XSF.save_xsf(file, system)
end

function save_trajectory(::XsfParser, file::AbstractString,
systems::AbstractVector{<:AbstractSystem})
XSF.save_xsf(file, systems)
end
37 changes: 37 additions & 0 deletions test/xsf.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using AtomsIO
using Test
using AtomsBaseTesting

@testset "XSF system write / read" begin
system = make_test_system().system
mktempdir() do d
outfile = joinpath(d, "output.xsf")
save_system(XsfParser(), outfile, system)
system2 = load_system(XsfParser(), outfile)
test_approx_eq(system, system2; rtol=1e-6)
end
end

@testset "XSF trajectory write/read" begin
systems = [make_test_system().system for _ in 1:3]
mktempdir() do d
outfile = joinpath(d, "output.axsf")
save_trajectory(XsfParser(), outfile, systems)
newsystems = load_trajectory(XsfParser(), outfile)
for (system, newsystem) in zip(systems, newsystems)
test_approx_eq(system, newsystem; rtol=1e-6)
end
test_approx_eq(systems[end], load_system(XsfParser(), outfile); rtol=1e-6)
test_approx_eq(systems[2], load_system(XsfParser(), outfile, 2); rtol=1e-6)
end
end

@testset "ExtXYZ supports_parsing" begin
import AtomsIO: supports_parsing
prefix = "test"
save = trajectory = true
@test supports_parsing(XsfParser(), prefix * ".xsf"; save, trajectory)
@test supports_parsing(XsfParser(), prefix * ".axsf"; save, trajectory)
@test !supports_parsing(XsfParser(), prefix * ".bxsf"; save, trajectory)
@test !supports_parsing(XsfParser(), prefix * ".cif"; save, trajectory)
end

0 comments on commit 8db2ec1

Please sign in to comment.