Skip to content

Commit

Permalink
Experimental CommonDataModel extension
Browse files Browse the repository at this point in the history
Implements read-only version of interface defined by
https://github.com/JuliaGeo/CommonDataModel.jl

Create CommonDataModel adaptor with eg

julia> PB.CDModel(modeldata)
  • Loading branch information
sjdaines committed Dec 30, 2024
1 parent fb92d7b commit 22bb340
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 2 deletions.
12 changes: 10 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,16 @@ TestEnv = "1e6cf692-eddd-4d53-88a5-2d735e33781b"
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
YAML = "ddb6d928-2868-570f-bddf-ab3f9cf99eb6"

[weakdeps]
CommonDataModel = "1fbeeb36-5f17-413c-809b-666fb144f157"

[extensions]
CommonDataModelExt = "CommonDataModel"

[compat]
Atomix = "0.1, 1.0"
BenchmarkTools = "1.0"
CommonDataModel = "0.3.7"
DataFrames = "1.1"
DocStringExtensions = "0.8, 0.9"
Documenter = "1"
Expand All @@ -52,12 +59,13 @@ StructArrays = "0.6, 0.7"
TestEnv = "1.0"
TimerOutputs = "0.5"
YAML = "0.4.7"
julia = "1.6"
julia = "1.10"

[extras]
CommonDataModel = "1fbeeb36-5f17-413c-809b-666fb144f157"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Documenter", "Logging", "Test"]
test = ["CommonDataModel", "Documenter", "Logging", "Test"]
93 changes: 93 additions & 0 deletions ext/CommonDataModelExt/CommonDataModelExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
module CommonDataModelExt

import PALEOboxes as PB
import CommonDataModel as CDM

#####################################
# Wrapper types
######################################

struct ModelCDM <: CDM.AbstractDataset
model::PB.Model
modeldata::Union{Nothing, PB.AbstractModelData}
end

PB.CDModel(model::PB.Model) = ModelCDM(model, nothing)
PB.CDModel(modeldata::PB.AbstractModelData) = ModelCDM(modeldata.model, modeldata)

struct DomainCDM <: CDM.AbstractDataset
domain::PB.Domain
modeldata::Union{Nothing, PB.AbstractModelData}
end

PB.CDModel(domain::PB.Domain) = DomainCDM(domain, nothing)


struct VariableDomainCDM <: CDM.AbstractDataset
variabledomain::PB.VariableDomain
modeldata::Union{Nothing, PB.AbstractModelData}
data
end

PB.CDModel(variabledomain::PB.VariableDomain) = VariableDomainCDM(variabledomain, nothing, nothing)

######################################
# Model
######################################

# iterable with all group names
CDM.groupnames(m::ModelCDM) = [d.name for d in m.model.domains]

CDM.group(m::ModelCDM, name::AbstractString) = DomainCDM(PB.get_domain(m.model, name; allow_not_found=false), m.modeldata)

###############################################
# Domain
################################################

CDM.name(d::DomainCDM) = d.domain.name

# TODO
# parentdataset(d::DomainCDM)

# returns a list of variable names as strings
Base.keys(d::DomainCDM) = [v.name for v in PB.get_variables(d.domain)]

function CDM.variable(d::DomainCDM, varname::AbstractString)
variabledomain = PB.get_variable(d.domain, varname; allow_not_found=false)
if isnothing(d.modeldata)
data = nothing
else
data = PB.get_data(variabledomain, d.modeldata)
end
return VariableDomainCDM(variabledomain, d.modeldata, data)
end

CDM.dimnames(d::DomainCDM) = [nd.name for nd in PB.get_dimensions(d.domain)]

CDM.dim(d::DomainCDM, name::AbstractString) = PB.get_dimension(d.domain, name).size


###############################################
# VariableDomain
################################################

CDM.name(v::VariableDomainCDM) = v.variabledomain.name

CDM.dataset(v::VariableDomainCDM) = DomainCDM(v.variabledomain.domain, v.modeldata)

CDM.dimnames(v::VariableDomainCDM) = [nd.name for nd in PB.get_dimensions(v.variabledomain)]

Base.ndims(v::VariableDomainCDM) = length(CDM.dimnames(v))

Base.size(v::VariableDomainCDM) = (nd.size for nd in PB.get_dimensions(v.variabledomain))

CDM.attribnames(v::VariableDomainCDM) = keys(v.variabledomain.attributes)

CDM.attrib(v::VariableDomainCDM, name::Symbol) = v.variabledomain.attributes[name]

Base.getindex(v::VariableDomainCDM, indices...) = Base.getindex(v.data, indices...)

Base.eltype(v::VariableDomainCDM) = Base.eltype(v.data)


end # module
11 changes: 11 additions & 0 deletions src/Types.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
# TODO there doesn't seem to be an easy way of parameterising ModelData by an Array type ?
const PaleoArrayType = Array

################################
# CommonDataModel adaptor
################################

"""
CDModel(x)
Create a CommonDataModel adaptor for PALEO object x
"""
function CDModel end

################################
# Parameters
###############################
Expand Down

0 comments on commit 22bb340

Please sign in to comment.