import Base.size, Base.show, Base.keys import ..TIME: TIME_t ############## public types ############## struct Variable varID::Cint streamID::Cint missValue::Cdouble name::String stdName::String longName::String unit::String code::Integer grid::AbstractGrid zAxis::AbstractZAxis tAxis::AbstractTAxis end export Variable """ define a variable template that could use to construct an cdiDataset """ struct VariableTemplate missValue::Cdouble name::String stdName::String longName::String unit::String code::Integer grid::AbstractGrid zAxis::AbstractZAxis time::TIME_t end export VariableTemplate const VariableDataType{N} = AbstractArray{Float64, N} const VariableMissingDataType{N} = AbstractArray{Union{Missing,Float64}, N} export VariableDataType, VariableMissingDataType ############## public functions ############## Base.size(var::Variable) = size(var.grid)..., size(var.zAxis)... Base.size(var::VariableTemplate) = size(var.grid)..., size(var.zAxis)... export size Base.length(var::Variable) = length(var.grid) * length(var.zAxis) Base.length(var::VariableTemplate) = length(var.grid) * length(var.zAxis) export length function Base.show(io::IO, v::Variable; indent="") printstyled(io, indent, "Variable: ", v.name, "\n", color=:light_green) print(io, indent, "ID: ", v.varID, "\n") print(io, indent, "standard name: ", v.stdName, "\n") print(io, indent, "long name: ", v.longName, "\n") print(io, indent, "unit: ", v.unit, "\n") print(io, indent, "code: ", v.code, "\n") print(io, indent, "miss value: ", v.missValue, "\n") end export show Base.keys(v::Variable) = v.name export keys """ Return the associated grid """ getGrid(var::Variable) = var.grid getGrid(var::VariableTemplate) = var.grid export getGrid """ Return the associated z-axis """ getZAxis(var::Variable) = var.zAxis getZAxis(var::VariableTemplate) = var.zAxis export getZAxis function loadData(var::Variable)::VariableDataType data = Array{Float64}(undef, size(var)...) return loadData!(data, var) end function loadMissingData(var::Variable)::VariableMissingDataType data = loadData(var) data = convert(VariableMissingDataType, data) for i in CartesianIndices(data) data[i] = data[i] == var.missValue ? missing : data[i] end return data end export loadData, loadMissingData function loadData!(data::VariableDataType{N}, var::Variable)::VariableDataType where {N} streamReadVar(var.streamID, var.varID, reshape(data, :)) return data end function loadData!(data::VariableDataType{1}, var::Variable)::VariableDataType streamReadVar(var.streamID, var.varID, data) return data end export loadData! function loadMissingData!(data::VariableMissingDataType{N}, var::Variable)::VariableMissingDataType where {N} tmp = similar(data, Float64) streamReadVar(var.streamID, var.varID, reshape(tmp, :)) for i in CartesianIndices(data) data[i] = tmp[i] == var.missValue ? missing : tmp[i] end return data end function loadMissingData!(data::VariableMissingDataType{1}, var::Variable)::VariableMissingDataType tmp = similar(data, Float64) streamReadVar(var.streamID, var.varID, tmp) for i in CartesianIndices(data) data[i] = tmp[i] == var.missValue ? missing : tmp[i] end return data end export loadMissingData! function storeData!(var::Variable, data::VariableDataType{N}) where {N} @assert length(var) == length(data) "data has not correct size" streamWriteVar(var.streamID, var.varID, reshape(data, :), 0) return nothing end function storeData!(var::Variable, data::VariableDataType{1}) @assert length(var) == length(data) "data has not correct size" streamWriteVar(var.streamID, var.varID, data, 0) return nothing end export storeData! function Variable(name::AbstractString, grid::AbstractGrid, zAxis::AbstractZAxis, time::TIME_t; unit::AbstractString="", stdName::AbstractString=name, longName::AbstractString="", code::Integer=-1, missValue::Cdouble=typemin(Cdouble)) @debug "load variable: " * name return VariableTemplate(missValue, name, stdName, longName, unit, code, grid, zAxis, time) end # Get variable Member """ unit(var) Return the variable unit as string """ unit(var::Variable) = var.unit unit(var::VariableTemplate) = var.unit export unit """ zAxis(var) Return the associated z-axis struct """ zAxis(var::Variable) = var.zAxis zAxis(var::VariableTemplate) = var.zAxis export zAxis """ tAxis(var) Return the associated t-axis struct """ tAxis(var::Variable) = var.tAxis export tAxis """ grid(var) Return the associated grid struct """ grid(var::Variable) = var.grid grid(var::VariableTemplate) = var.grid export grid