-
Notifications
You must be signed in to change notification settings - Fork 22
/
misc.jl
174 lines (147 loc) · 5.02 KB
/
misc.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# Chemfiles.jl, a modern library for chemistry file reading and writing
# Copyright (C) Guillaume Fraux and contributors -- BSD license
export ChemfilesError
struct ChemfilesError <: Exception
message::AbstractString
end
Base.show(io::IO, e::ChemfilesError) = show(io, "Chemfiles error: $(e.message)")
"""
Get the last error message from the chemfiles runtime.
"""
function last_error()
unsafe_string(lib.chfl_last_error())
end
"""
Clear any error messages stored by the chemfiles runtime.
"""
function clear_errors()
__check(lib.chfl_clear_errors())
end
# Default to the standard logging infrastructure
function __default_warning_callback(message::String)
@warn "$message"
end
# Store the warning callback in a global to prevent garbage collection
WARNING_CALLBACK = nothing
function _warning_callback_adaptator(message)
try
WARNING_CALLBACK(unsafe_string(message))
catch error
@warn "caught $error in warning callback"
end
end
"""
Set the global warning `callback` to be used for each warning event.
The `callback` function must take a `String` and return nothing.
"""
function set_warning_callback(callback::Function)
global WARNING_CALLBACK
WARNING_CALLBACK = callback
ptr = @cfunction(_warning_callback_adaptator, Cvoid, (Ptr{UInt8},))
__check(lib.chfl_set_warning_callback(ptr))
end
"""
Read configuration data from the file at `path`.
By default, chemfiles reads configuration from any file name `.chemfilesrc`
in the current directory or any parent directory. This function can be used
to add data from another configuration file.
This function will fail if there is no file at `path`, or if the file is
incorectly formatted. Data from the new configuration file will overwrite
any existing data.
"""
function add_configuration(path::String)
__check(lib.chfl_add_configuration(pointer(path)))
end
"""
Metadata associated with one of the format Chemfiles can read/write
$(TYPEDFIELDS)
"""
struct FormatMetadata
"""Name of the format"""
name::String
"""Extension associated with the format, or `nothing` if there is no extension
associated."""
extension::Union{String,Nothing}
"""Extended user-facing description of the format"""
description::String
"""URL pointing to the format definition/reference"""
reference::String
"""Is reading files in this format implemented?"""
read::Bool
"""Is writing files in this format implemented?"""
write::Bool
"""Does this format support in-memory IO?"""
memory::Bool
"""Does this format support storing atomic positions?"""
positions::Bool
"""Does this format support storing atomic velocities?"""
velocities::Bool
"""Does this format support storing unit cell information?"""
unit_cell::Bool
"""Does this format support storing atom names or types?"""
atoms::Bool
"""Does this format support storing bonds between atoms?"""
bonds::Bool
"""Does this format support storing residues?"""
residues::Bool
end
function Base.show(io::IO, metadata::FormatMetadata)
print(io, "FormatMetadata(")
print(io, "name=\"$(metadata.name)\", ")
if metadata.extension === nothing
print(io, "extension=nothing, ")
else
print(io, "extension=\"$(metadata.extension)\", ")
end
print(io, "description=\"$(metadata.description)\", ")
print(io, "reference=\"$(metadata.reference)\", ")
print(io, "read=$(metadata.read), "),
print(io, "write=$(metadata.write), "),
print(io, "memory=$(metadata.memory), "),
print(io, "positions=$(metadata.positions), "),
print(io, "velocities=$(metadata.velocities), "),
print(io, "unit_cell=$(metadata.unit_cell), "),
print(io, "atoms=$(metadata.atoms), "),
print(io, "bonds=$(metadata.bonds), "),
print(io, "residues=$(metadata.residues)"),
print(io, ")")
end
function FormatMetadata(metadata::lib.chfl_format_metadata)
name = unsafe_string(metadata.name)
if metadata.extension == C_NULL
extension = nothing
else
extension = unsafe_string(metadata.extension)
end
description = unsafe_string(metadata.description)
reference = unsafe_string(metadata.reference)
return FormatMetadata(
name,
extension,
description,
reference,
convert(Bool, metadata.read[]),
convert(Bool, metadata.write[]),
convert(Bool, metadata.memory[]),
convert(Bool, metadata.positions[]),
convert(Bool, metadata.velocities[]),
convert(Bool, metadata.unit_cell[]),
convert(Bool, metadata.atoms[]),
convert(Bool, metadata.bonds[]),
convert(Bool, metadata.residues[]),
)
end
"""
Get the full list of formats supported by Chemfiles, and associated metadata
"""
function format_list()
metadata = Ref{Ptr{lib.chfl_format_metadata}}()
count = Ref{UInt64}(0)
lib.chfl_formats_list(metadata, count)
all = FormatMetadata[]
for i in 1:count[]
push!(all, FormatMetadata(unsafe_load(metadata[], i)))
end
lib.chfl_free(Ptr{Cvoid}(metadata[]))
return all
end