From 1869de005eb6dc97efb7b6dc908c75751418fa37 Mon Sep 17 00:00:00 2001 From: Datseris Date: Tue, 9 Feb 2021 13:48:12 +0100 Subject: [PATCH 1/6] doc improv for xarray --- docs/src/index.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index 274c092e..9191b6c8 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -126,8 +126,7 @@ function extract_dimension_values_xarray(xa, dnames = collect(xa.dims)) if d ≠ "time" push!(dim_values, x) else - # This date specification assumes up to day sampling (hence the 1:10) - dates = [np.datetime_as_string(y)[1:10] for y in x] + dates = [np.datetime_as_string(y)[1:19] for y in x] dates = DateTime.(dates) push!(dim_values, dates) end From 4423d787961e1939ece6c7c06c1c13a6b72aa48e Mon Sep 17 00:00:00 2001 From: Datseris Date: Tue, 9 Feb 2021 13:48:29 +0100 Subject: [PATCH 2/6] fix insufficient base type usage in seasonal_decmposition --- src/tsa/decomposition.jl | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/tsa/decomposition.jl b/src/tsa/decomposition.jl index 9ab49695..db82f78a 100644 --- a/src/tsa/decomposition.jl +++ b/src/tsa/decomposition.jl @@ -10,18 +10,16 @@ periodic parts of `A`, with frequencies given in `fs`, and residual contains wha `fs` is measured in 1/year. This function works even for non-equispaced time axis (e.g. monthly averages) and uses LPVSpectral.jl and SignalDecomposition.jl. """ -seasonal_decomposition(A::AbDimArray, b) = seasonal_decomposition(dims(A, Time), A, b) - -function seasonal_decomposition(t, A::AbDimArray, fs::Vector) +function seasonal_decomposition(A::AbDimArray, fs::Vector) @assert hasdim(A, Time) - E = _numbertype(T) + E = _numbertype(eltype(A)) method = Sinusoidal(E.(fs ./ DAYS_IN_ORBIT)) - seasonal = DimensionalData.basetypeof(A)(copy(Array(A)), dims(A); name = A.name*"seasonal") - residual = DimensionalData.basetypeof(A)(copy(Array(A)), dims(A); name = A.name*"residual") + seasonal = DimensionalData.basetypeof(A)(copy(Array(A)), dims(A)) + residual = DimensionalData.basetypeof(A)(copy(Array(A)), dims(A)) - # TODO: Fix this to use "real time" - truetime = Float32.(cumsum(daysinmonth.(t))) - for i in otheridxs(T, Time) + t = dims(A, Time).val + truetime = time_in_days(t, E) + for i in otheridxs(A, Time) y = Array(A[i...]) sea, res = SignalDecomposition.decompose(truetime, y, method) seasonal[i...] .= sea From ee38c6963893c5236857c28489f39a638b3ec7b3 Mon Sep 17 00:00:00 2001 From: Datseris Date: Tue, 9 Feb 2021 13:48:43 +0100 Subject: [PATCH 3/6] fix missing Symbol in definition of array --- src/core/coredefs.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/coredefs.jl b/src/core/coredefs.jl index 8ce175f3..56cd9251 100644 --- a/src/core/coredefs.jl +++ b/src/core/coredefs.jl @@ -70,7 +70,7 @@ struct ClimArray{T,N,D<:Tuple,R<:Tuple,A<:AbstractArray{T,N},Me} <: AbstractDime end ClimArray(A::DimensionalArray) = ClimArray(A.data, A.dims, A.refdims, A.name, A.metadata) ClimArray(A::ClimArray, dims::Tuple = A.dims; name = A.name, attrib = A.attrib) = -ClimArray(A.data, DimensionalData.formatdims(A.data, dims), A.refdims, name, attrib) +ClimArray(A.data, DimensionalData.formatdims(A.data, dims), A.refdims, Symbol(name), attrib) """ ClimArray(A::Array, dims::Tuple; name = "", attrib = nothing) From 8a56afeefd459f634e8c865729974870bd514d0d Mon Sep 17 00:00:00 2001 From: Datseris Date: Tue, 9 Feb 2021 13:48:58 +0100 Subject: [PATCH 4/6] add nomissing in spatial --- src/core/nc_io.jl | 2 +- src/physical_dimensions/spatial_equalarea.jl | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/core/nc_io.jl b/src/core/nc_io.jl index da2645f9..9b9b205d 100644 --- a/src/core/nc_io.jl +++ b/src/core/nc_io.jl @@ -198,7 +198,6 @@ function climarrays_to_nc(file::String, Xs; globalattr = Dict()) @warn "$i-th ClimArray has no name, naming it $(n) instead." end println("processing variable $(n)...") - println("writing dimensions...") add_dims_to_ncfile!(ds, dims(X)) println("writing the CF-variable...") attrib = X.attrib @@ -215,6 +214,7 @@ function add_dims_to_ncfile!(ds::NCDatasets.AbstractDataset, dimensions::Tuple) dnames = dim_to_commonname.(dimensions) for (i, d) ∈ enumerate(dnames) haskey(ds, d) && continue + println("writing dimension $d...") v = dimensions[i].val # this conversion to DateTime is necessary because CFTime.jl doesn't support Date eltype(v) == Date && (v = DateTime.(v)) diff --git a/src/physical_dimensions/spatial_equalarea.jl b/src/physical_dimensions/spatial_equalarea.jl index ff90c9a9..6435bb4d 100644 --- a/src/physical_dimensions/spatial_equalarea.jl +++ b/src/physical_dimensions/spatial_equalarea.jl @@ -35,6 +35,9 @@ function ClimArray_eqarea(ds::NCDatasets.AbstractDataset, var::String, name = va X = ClimArray(A, Tuple(actualdims)) X = X[Coord(si)] + if !any(ismissing, X) + X = nomissing(X) + end return ClimArray(X; name = Symbol(name), attrib) else error("Don't know how to handle this equal area grid!") From 4a473ce6251dc51a6bdcca952ef348da1d140265 Mon Sep 17 00:00:00 2001 From: Datseris Date: Tue, 9 Feb 2021 13:55:44 +0100 Subject: [PATCH 5/6] allow monthly agg to different day number --- src/core/coredefs.jl | 1 + src/physical_dimensions/temporal.jl | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/coredefs.jl b/src/core/coredefs.jl index 56cd9251..b65cd054 100644 --- a/src/core/coredefs.jl +++ b/src/core/coredefs.jl @@ -15,6 +15,7 @@ export hasdim, DimensionalArray export get_var_as_dimarray export Time, Lon, Lat, dims, Coord, Hei, Pre export EqArea, Grid, spacestructure +export DimensionalData # for accessing its functions @dim Lon IndependentDim "Longitude" @dim Lat IndependentDim "Latitude" diff --git a/src/physical_dimensions/temporal.jl b/src/physical_dimensions/temporal.jl index a7a046d5..17a0b51b 100644 --- a/src/physical_dimensions/temporal.jl +++ b/src/physical_dimensions/temporal.jl @@ -299,15 +299,15 @@ end # Monthly/yearly/daily/seasonal means ######################################################################### """ - monthlyagg(A::ClimArray, f = mean) -> B + monthlyagg(A::ClimArray, f = mean; mday = 15) -> B Create a new array where the temporal daily information has been aggregated to months using the function `f`. -By convention, the dates of the new array always have day number of `15`. +The dates of the new array always have day number of `mday`. """ -function monthlyagg(A::ClimArray, f = mean) +function monthlyagg(A::ClimArray, f = mean; mday = 15) t0 = dims(A, Time).val - startdate = Date(year(t0[1]), month(t0[1]), 15) - finaldate = Date(year(t0[end]), month(t0[end]), 16) + startdate = Date(year(t0[1]), month(t0[1]), mday) + finaldate = Date(year(t0[end]), month(t0[end]), mday+1) t = startdate:Month(1):finaldate tranges = temporalrange(t0, Dates.month) return timegroup(A, f, t, tranges, "monthly") From f10694eef6819154a4be86801fc79f13d23e6147 Mon Sep 17 00:00:00 2001 From: Datseris Date: Tue, 9 Feb 2021 15:22:21 +0100 Subject: [PATCH 6/6] add globalattr function --- docs/src/index.md | 3 ++- src/core/coredefs.jl | 3 +-- src/core/nc_io.jl | 12 +++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/docs/src/index.md b/docs/src/index.md index fd11699a..b798459f 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -74,10 +74,11 @@ using ClimateBase # hide ClimateBase.COMMONNAMES ``` -Also, two convenience functions are provided for examining the content of on-disk `.nc` files without loading all data on memory. +Also, the following convenience functions are provided for examining the content of on-disk `.nc` files without loading all data on memory. ```@docs nckeys ncdetails +globalattr ``` ### Write diff --git a/src/core/coredefs.jl b/src/core/coredefs.jl index b65cd054..0db518db 100644 --- a/src/core/coredefs.jl +++ b/src/core/coredefs.jl @@ -11,8 +11,7 @@ Time = DimensionalData.Ti AbDimArray = DimensionalData.AbstractDimArray export At, Between, Near # Selectors from DimensionalArrays.jl -export hasdim, DimensionalArray -export get_var_as_dimarray +export hasdim, DimensionalArray, dimnum export Time, Lon, Lat, dims, Coord, Hei, Pre export EqArea, Grid, spacestructure export DimensionalData # for accessing its functions diff --git a/src/core/nc_io.jl b/src/core/nc_io.jl index 9b9b205d..75c347ab 100644 --- a/src/core/nc_io.jl +++ b/src/core/nc_io.jl @@ -5,7 +5,7 @@ https://github.com/rafaqz/GeoData.jl =# using NCDatasets export NCDataset -export nckeys, ncdetails +export nckeys, ncdetails, globalattr export climarrays_to_nc dim_to_commonname(::Lat) = "lat" @@ -39,6 +39,16 @@ function ncdetails(file::String, io = stdout) end ncdetails(ds::NCDataset, io = stdout) = show(io, MIME"text/plain"(), ds) +""" + globalattr(file::String) → Dict +Return the global attributions of the .nc file. +""" +function globalattr(file::String) + NCDataset(file) do ds + return Dict(ds.attrib) + end +end + """ ClimArray(file::Union{String,NCDataset}, var::String, name = var) -> A Load the variable `var` from the `file` and convert it