forked from ACEsuit/ACEfriction.jl
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdatautils.jl
More file actions
150 lines (126 loc) · 4.47 KB
/
datautils.jl
File metadata and controls
150 lines (126 loc) · 4.47 KB
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
module DataUtils
using ProgressMeter
using JuLIP
using ACEfriction.mUtils: reinterpret
using StaticArrays, SparseArrays
export FrictionData, BlockDenseArray
export save_h5fdata, load_h5fdata
using HDF5
function _array2svector(x::Array{T,2}) where {T}
return [ SVector{3}(x[i,:]) for i in 1:size(x)[1] ]
end
function _svector2array(c_vec::Vector{SVector{N_rep, T}}) where {N_rep,T<:Number}
"""
input: c_vec each
N_basis = length(c_vec)
N_rep = numbero of channels
"""
c_matrix = Array{T}(undef,length(c_vec),N_rep)
for j in eachindex(c_vec)
c_matrix[j,:] = c_vec[j]
end
return c_matrix
end
"""
save_h5fdata(rdata, filename )
Saves a friction tensor dataset with the HDF5 file structure expected by `load_h5fdata`, for use in training scripts.
# Arguments
## `rdata`:
A `Vector{NamedTuple}` containing the training data in the following format.
```
(
at = ::JuLIP.Atoms,
friction_tensor = sparse(::Matrix),
friction_indices = ::Vector{Int}
)
```
## `filename`
Name of the file to save to (including h5 extension).
"""
function save_h5fdata(rdata, filename )
fid = h5open(filename, "w")
try
# iterate over each data entry
write_attribute(fid, "N_data", length(rdata))
@showprogress for (i,d) in enumerate(rdata)
g = create_group(fid, "$i")
# write atoms data
ag = create_group(g, "atoms")
dset_pos = create_dataset(ag, "positions", Float64, (length(d.at.X), 3))
for (k,x) in enumerate(d.at.X)
dset_pos[k,:] = x
end
write(ag, "atypes", Int.(d.at.Z))
write(ag, "cell", Matrix(d.at.cell))
write(ag, "pbc", Array(d.at.pbc))
# write friction data
fg = create_group(g, "friction_tensor")
(I,J,V) = findnz(d.friction_tensor)
write(fg, "ft_I", I)
write(fg, "ft_J", J)
dset_ft = create_dataset(fg, "ft_val", Float64, (length(V), 3, 3))
for (k,v) in enumerate(V)
dset_ft[k,:,:] = v
end
write(fg, "ft_mask", d.friction_indices)
end
catch
close(fid)
rethrow(e)
end
HDF5.close(fid)
end
_hdf52Atoms( ag::HDF5.Group ) = JuLIP.Atoms(;
X=[SVector{3}(d) for d in eachslice(read(ag["positions"]); dims=1)],
Z=read(ag["atypes"]),
cell= read(ag["cell"]),
pbc=read(ag["pbc"])
)
function _hdf52ft( ftg::HDF5.Group )
spft = sparse( read(ftg["ft_I"]),read(ftg["ft_J"]), [SMatrix{3,3}(d) for d in eachslice(read(ftg["ft_val"]); dims=1)] )
ft_mask = read(ftg["ft_mask"])
return (friction_tensor = spft, mask = ft_mask)
end
function load_h5fdata(filename)
fid = h5open(filename, "r")
N_data = read_attribute(fid, "N_data")
rdata = @showprogress [begin
at = _hdf52Atoms( fid["$i/atoms/"])
spft, ft_mask = _hdf52ft( fid["$i/friction_tensor/"])
(at=at, friction_tensor=spft, friction_indices=ft_mask)
end
for i=1:N_data]
HDF5.close(fid)
return rdata
end
"""
Semi-sparse matrix representation of a square matrix M of unspecified dimension. Entries of M are
specified by the fields `values::Matrix{T}` and `indexmap` assuming
1. `M[k,l] = 0` if either of the indices `k`, `l` is not contained in `indexmap`.
2. values[i,j] = M[indexmap[i],indexmap[j]]
"""
struct BlockDenseMatrix{T} <: AbstractArray{Float64,2}
tensor::Matrix{T}
indices
end
function BlockDenseArray(full_tensor::Matrix; indices=1:size(full_tensor,1))
@assert size(full_tensor,1) == size(full_tensor,2)
return BlockDenseMatrix(full_tensor[indices,indices], indices)
end
struct FrictionData{A}
atoms::Atoms
friction_tensor::A
friction_indices
friction_tensor_ref
end
function FrictionData(d::NamedTuple{(:at, :friction_tensor, :friction_indices)})
return FrictionData(d.at, d.friction_tensor, d.friction_indices, nothing)
end
function FrictionData(d::NamedTuple{(:at, :friction_tensor, :friction_indices,:friction_indices_ref)})
return FrictionData(d.at, d.friction_tensor, d.friction_indices, d.friction_tensor_ref)
end
# function FrictionData(atoms::Atoms, friction_tensor, friction_indices;
# friction_tensor_ref=nothing)
# return FrictionData(atoms, friction_tensor, friction_indices, weights, friction_tensor_ref)
# end
end