Skip to content

Commit b84e81f

Browse files
authored
Dev/atomsbase integration (#18)
* set up the integration for AtomsBase * add atomsbase functions * example update before I formalize it * fix dead link * add atomsbase integration example doc * fix dependency * remove unnecessary file * update tests * update more tests * add docs to ccread func * add docs to the rest of the functions * update docs * Update tests and atomsbase funcs * update as per comment
1 parent a14e987 commit b84e81f

File tree

8 files changed

+177
-15
lines changed

8 files changed

+177
-15
lines changed

Project.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ authors = ["cclib development team"]
44
version = "0.2.0"
55

66
[deps]
7+
AtomsBase = "a963bdd2-2df7-4f54-a1ee-49d51e6be12a"
78
CondaPkg = "992eb4ea-22a4-4c89-a5bb-47a3300528ab"
89
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
9-
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
1010
PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d"
11+
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
12+
UnitfulAtomic = "a7773ee8-282e-5fa2-be4e-bd808c38a91a"
1113

1214
[compat]
1315
CondaPkg = "0.2"
14-
PyCall = "1"
1516
PythonCall = "0.9"
1617
julia = "1"
1718

docs/make.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ makedocs(;
1616
pages=[
1717
"Home" => "index.md",
1818
"How to parse files" => "io.md",
19+
"AtomsBase Integration" => "atombase.md"
1920
],
2021
)
2122

docs/src/atombase.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# AtomsBase Integration
2+
3+
Cclib.jl allows loading atom information into [AtomsBase.jl](https://github.com/JuliaMolSim/AtomsBase.jl) objects using `get_atom_objects` function:
4+
5+
```Julia
6+
# Input file can be found in the in the repo under "test" folder
7+
julia> using Cclib
8+
julia> using AtomsBase
9+
julia> mol = ccread("./Trp_polar.fchk")
10+
julia> atoms = get_atom_objects(mol)
11+
julia> atoms[1]
12+
13+
Atom(N, atomic_number = 7, atomic_mass = 14.007 u):
14+
position : [-0.069982688,0.33219872,0.28212832]u"Å"
15+
```
16+
17+
Like before, all the stored information for each atom is still accessible:
18+
19+
```Julia
20+
julia> keys(atoms[1])
21+
(:position, :velocity, :atomic_symbol, :atomic_number, :atomic_mass)
22+
```
23+
# Interoperability With Other Tools
24+
25+
We can use data loaded with Cclib.jl to perform calculations using other libraries that use AtomsBase.jl, such as [InteratomicPotentials.jl](https://github.com/cesmix-mit/InteratomicPotentials.jl)
26+
27+
First, we load the data and define the system:
28+
```Julia
29+
julia> using Cclib
30+
julia> using AtomsBase
31+
julia> using Unitful
32+
julia> using UnitfulAtomic
33+
julia> using InteratomicPotentials
34+
35+
julia> atoms = get_atom_objects("./Trp_polar.fchk")
36+
julia> boundaryconditions = [Periodic(), Periodic(), Periodic()]
37+
julia> box = [[10.0, 0.0, 0.0], [0.0, 10.0, 0.0], [0.0, 0.0, 10.0]]u"Å"
38+
julia> system = FlexibleSystem(atoms, box, boundaryconditions)
39+
40+
FlexibleSystem(C₁₁H₁₂N₂O₂, periodic = TTT):
41+
bounding_box : [ 10 0 0;
42+
0 10 0;
43+
0 0 10]u"Å"
44+
45+
.------------------------.
46+
/| H |
47+
/ | |
48+
/ | |
49+
/ | H C C H |
50+
/ H |
51+
* C C C C H C H |
52+
| H | C HN H |
53+
| | |
54+
| | C C |
55+
| | C |
56+
| | O |
57+
| .----------------------H-.
58+
| / /
59+
| / /
60+
| H/O /
61+
| / H /
62+
|/ N/
63+
*------------------------*
64+
```
65+
We can now perform calculate various properties of the system:
66+
```Julia
67+
julia> ϵ = 1.0 * 1u"eV"
68+
julia> σ = 0.25 * 1u""
69+
julia> rcutoff = 2.25 * 1u""
70+
julia> lj = LennardJones(ϵ, σ, rcutoff, [:N, :C, :O, :H])
71+
julia> potential_energy(system, lj).
72+
-0.00039418327614247183 Eₕ
73+
```
74+
Refer to InteratomicPotentials.jl documentation for more details.

docs/src/io.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@
22

33
This page outlines how to access information store in computational chemistry output files.
44

5-
### Supported formats
6-
Properties that can be parsed and supported file formats can be found [here](https://cclib.github.io/data.html").
5+
# Supported formats
6+
Properties that can be parsed and supported file formats can be found [here](https://cclib.github.io/data.html#details-of-current-implementation").
77

8-
### How to read files
8+
# How to read files
99
```Julia
10+
# Input file can be found in the in the repo under "test" folder
1011
julia> using Cclib
1112
julia> mol = ccread("uracil_two.xyz")
1213
```

src/Cclib.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
module Cclib
22
using PythonCall
33
using CondaPkg
4+
using AtomsBase
5+
using Unitful
6+
using UnitfulAtomic
47
using Logging
58

6-
include("functions.jl")
79
include("config.jl")
10+
include("functions.jl")
11+
include("ab_integration.jl")
812

913
const cclib = Ref{Py}()
1014

src/ab_integration.jl

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# Functions for AtomsBase integration https://github.com/JuliaMolSim/AtomsBase.jl/tree/master
3+
#
4+
export get_atom_objects
5+
6+
"""
7+
get_atom_objects(mol::Dict)
8+
9+
Load atom data contained in a cclib dictionary into a list
10+
of AtomsBase atom objects.
11+
12+
# Arguments
13+
- `mol::Dict`: Dictionary that was returned by `ccread` function
14+
15+
# Returns
16+
A list of AtomsBase atom objects
17+
"""
18+
function get_atom_objects(mol::Dict)
19+
atoms = [
20+
Atom(mol["atomnos"][i],
21+
vec(mol["atomcoords"][:, i, :])u"")
22+
for i in 1:mol["natom"]
23+
]
24+
return atoms
25+
end
26+
27+
"""
28+
get_atom_objects(mol::String)
29+
30+
Load atom data contained in a cclib-supported file format
31+
into a list of AtomsBase atom objects.
32+
33+
# Arguments
34+
- `mol::String`: File supported by `ccread` function
35+
36+
# Returns
37+
A list of AtomsBase atom objects
38+
"""
39+
function get_atom_objects(mol::String)
40+
return get_atom_objects(ccread(mol))
41+
end

src/functions.jl

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
#
2+
# General functions for parsing chemical outputs
3+
#
4+
15
export ccread
26

37
function pyccread(file)
@@ -16,7 +20,31 @@ function get_data(file)
1620
return datadict
1721
end
1822

19-
function ccread(file)
23+
"""
24+
ccread(file::String)
25+
26+
Read in the file of supported format and store the data
27+
it contains in a dictionary.
28+
Properties read in are accessible as dictionary keys.
29+
30+
# Arguments
31+
- `file::String`: Cclib-supported file format
32+
33+
# Returns
34+
A dictionary containing stored information
35+
36+
# Example
37+
```Julia
38+
julia> mol = ccread("uracil_two.xyz")
39+
julia> keys(mol)
40+
KeySet for a Dict{String, Any} with 4 entries. Keys:
41+
"atomcoords"
42+
"natom"
43+
"atomnos"
44+
"metadata"
45+
```
46+
"""
47+
function ccread(file::String)
2048
try
2149
if !isfile(file)
2250
@error "$(file) is not file"

test/runtests.jl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,33 @@
11
using Cclib
22
using PythonCall
33
using Test
4+
using AtomsBase
5+
46

57

68
@testset "Cclib.jl" begin
9+
test_file = "./data/uracil_two.xyz"
10+
test_ccdata = ccread(test_file)
711

812
# Check that input is read correctly
9-
@test ccread("./data/uracil_two.xyz")["natom"] == 12
10-
@test ccread("./data/uracil_two.xyz")["atomnos"] == [7, 6, 1, 8, 7, 6, 8, 6, 6, 1, 1, 1]
11-
@test ccread("./data/uracil_two.xyz")["atomcoords"] == [5.435 4.091 6.109 3.647 3.253 3.636 2.79 5.065 5.906 2.243 5.448 7.003;
12-
5.42432 4.08846 6.05396 3.68445 3.24195 3.62987 2.83542 5.0864 5.91213 2.2534 5.42415 6.9915;;;
13-
3.248 3.266 3.347 3.394 3.118 2.955 2.842 2.953 3.101 3.138 2.833 3.119;
14-
3.24732 3.26356 3.354 3.39863 3.11963 2.96568 2.83961 2.95832 3.09904 3.12801 2.83814 3.10206;;;
15-
-0.916 -0.635 -0.144 0.495 -1.717 -3.039 -3.923 -3.239 -2.202 -1.514 -4.258 -2.345;
16-
-0.9432 -0.64127 -0.15563 0.50851 -1.70419 -3.0054 -3.9297 -3.25044 -2.21101 -1.51035 -4.27067 -2.32366]
13+
@test test_ccdata["natom"] == 12
14+
@test test_ccdata["atomnos"] == [7, 6, 1, 8, 7, 6, 8, 6, 6, 1, 1, 1]
15+
@test test_ccdata["atomcoords"] == [5.435 4.091 6.109 3.647 3.253 3.636 2.79 5.065 5.906 2.243 5.448 7.003;
16+
5.42432 4.08846 6.05396 3.68445 3.24195 3.62987 2.83542 5.0864 5.91213 2.2534 5.42415 6.9915;;;
17+
3.248 3.266 3.347 3.394 3.118 2.955 2.842 2.953 3.101 3.138 2.833 3.119;
18+
3.24732 3.26356 3.354 3.39863 3.11963 2.96568 2.83961 2.95832 3.09904 3.12801 2.83814 3.10206;;;
19+
-0.916 -0.635 -0.144 0.495 -1.717 -3.039 -3.923 -3.239 -2.202 -1.514 -4.258 -2.345;
20+
-0.9432 -0.64127 -0.15563 0.50851 -1.70419 -3.0054 -3.9297 -3.25044 -2.21101 -1.51035 -4.27067 -2.32366]
1721

1822
# Check that it handles unsupported files correctly
1923
@test isnothing(ccread("./data/invalid_file.txt"))
2024
@test isnothing(ccread("./data/"))
25+
26+
# Check AtomsBase Integration
27+
test_atom_objects = get_atom_objects(test_file)
28+
@test atomic_number(test_atom_objects[1]) == 7
29+
@test atomic_symbol(test_atom_objects[1]) == :N
30+
@test atomic_number(test_atom_objects[6]) == 6
31+
@test atomic_symbol(test_atom_objects[6]) == :C
32+
2133
end

0 commit comments

Comments
 (0)