-
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathInferenceObjectsNCDatasetsExt.jl
More file actions
114 lines (106 loc) · 4.17 KB
/
Copy pathInferenceObjectsNCDatasetsExt.jl
File metadata and controls
114 lines (106 loc) · 4.17 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
module InferenceObjectsNCDatasetsExt
using DimensionalData: DimensionalData, Dimensions, Lookups
using NCDatasets: NCDatasets
using InferenceObjects
function InferenceObjects.from_netcdf(path::AbstractString; kwargs...)
return NCDatasets.NCDataset(path, "r"; kwargs...) do ds
return from_netcdf(ds; load_mode=:eager)
end
end
function InferenceObjects.from_netcdf(ds::NCDatasets.NCDataset; load_mode::Symbol=:lazy)
return _from_netcdf(ds, Val(load_mode))
end
function _from_netcdf(ds, load_mode)
groups_iter = Iterators.map(ds.group) do (group_name, group)
layerdims = (;
map(NCDatasets.dimnames(group)) do dim_name
index = collect(group[dim_name])
if index == eachindex(index)
# discard the index if it is just the default
index = Lookups.NoLookup()
end
return Symbol(dim_name) => Dimensions.Dim{Symbol(dim_name)}(index)
end...
)
var_iter = Iterators.filter(∉(keys(layerdims)) ∘ Symbol ∘ first, group)
data = (;
map(var_iter) do (var_name, var)
vals = _var_to_array(var, load_mode)
dims = Tuple(NamedTuple{map(Symbol, NCDatasets.dimnames(var))}(layerdims))
name = Symbol(var_name)
attrib = if load_mode isa Val{:eager}
filter(!=("_FillValue") ∘ first, Dict{String,Any}(var.attrib))
else
var.attrib
end
metadata = isempty(attrib) ? Lookups.NoMetadata() : attrib
da = DimensionalData.DimArray(vals, dims; name, metadata)
return name => da
end...
)
group_metadata = if load_mode isa Val{:eager}
Dict{String,Any}(group.attrib)
else
group.attrib
end
return Symbol(group_name) => Dataset(data; metadata=group_metadata)
end
return InferenceData(; groups_iter...)
end
_var_to_array(var, load_mode) = var
function _var_to_array(var, load_mode::Val{:eager})
arr = as_array(Array(var))
attr = var.attrib
try
arr_nomissing = NCDatasets.nomissing(arr)
if eltype(arr_nomissing) <: Integer && (get(attr, "dtype", nothing) == "bool")
return convert(Array{Bool}, arr_nomissing)
end
return arr_nomissing
catch e
if eltype(arr) <: Union{Integer,Missing} && (get(attr, "dtype", nothing) == "bool")
return convert(Array{Union{Missing,Bool}}, arr)
end
return arr
end
end
function InferenceObjects.convert_to_inference_data(ds::NCDatasets.NCDataset; kwargs...)
return from_netcdf(ds)
end
function InferenceObjects.to_netcdf(
data, path::AbstractString; group::Symbol=:posterior, kwargs...
)
NCDatasets.NCDataset(ds -> to_netcdf(data, ds; group), path, "c"; kwargs...)
return path
end
function InferenceObjects.to_netcdf(
data, ds::NCDatasets.NCDataset; group::Symbol=:posterior
)
idata = convert_to_inference_data(data; group)
for (group_name, group_data) in pairs(idata)
group_attrib = collect(InferenceObjects.attributes(group_data))
group_ds = NCDatasets.defGroup(ds, String(group_name); attrib=group_attrib)
for dim in Dimensions.dims(group_data)
dim_name = String(Dimensions.name(dim))
NCDatasets.defDim(group_ds, dim_name, length(dim))
index = parent(Dimensions.lookup(group_data, dim))
var = NCDatasets.defVar(group_ds, dim_name, eltype(index), (dim_name,))
copyto!(var, index)
end
for (var_name, da) in pairs(group_data)
dimnames = map(String, Dimensions.name(Dimensions.dims(da)))
attrib = Dict(DimensionalData.metadata(da))
if eltype(da) <: Bool && (get(attrib, "dtype", "bool") == "bool")
da = convert(AbstractArray{Int8}, da)
attrib["dtype"] = "bool"
end
NCDatasets.defVar(
group_ds, String(var_name), parent(da), dimnames; attrib=collect(attrib)
)
end
end
return ds
end
as_array(x) = fill(x)
as_array(x::AbstractArray) = x
end # module