ERA5 ncwrite fails
Balinus opened this issue · 5 comments
Tried to save a ClimArray containing ERA5 tasmax data and it failed due to a potential wrong _FillValue
.
I can provide the file, but it is ~750MB. I do not remember where and when I downloaded it.
julia> fileERA5 = "/media/proy/Data/DATA/ERA5_tasmax.nc"
julia> A = ncread(fileERA5, "t2m")
julia> A
ClimArray (named t2m) with dimensions:
Longitude (type Lon): 0.0f0:0.25f0:359.75f0 (Sampled: Ordered Regular Points)
Latitude (type Lat): 90.0f0:-0.25f0:-90.0f0 (Sampled: Ordered Regular Points)
Time (type Ti): DateTime[2000-01-01T00:00:00, 2000-01-02T00:00:00, …, 2000-12-30T00:00:00, 2000-12-31T00:00:00] (Sampled: Ordered Irregular Points)
attributes: Dict{String, Any} with 6 entries:
"missing_value" => -32767
"units" => "K"
"add_offset" => 256.979
"long_name" => "2 metre temperature"
"scale_factor" => 0.00192051
"_FillValue" => -32767
and data: 1440×721×366 Array{Float64, 3}
[:, :, 1]
264.693 264.063 263.793 263.725 263.631 263.608 263.585 263.608 263.821 … 244.088 244.011 244.009 243.971 243.958 243.84 243.721 243.441
264.693 264.063 263.793 263.725 263.631 263.612 263.595 263.624 263.829 244.079 244.006 244.006 243.969 243.956 243.84 243.721 243.441
264.693 264.063 263.793 263.725 263.633 263.616 263.604 263.639 263.837 244.071 244.0 244.002 243.969 243.956 243.84 243.721 243.441
264.693 264.063 263.793 263.727 263.633 263.618 263.614 263.656 263.844 244.061 243.994 243.998 243.967 243.956 243.838 243.721 243.441
⋮ ⋮ ⋱ ⋮ ⋮
264.693 264.063 263.798 263.737 263.654 263.608 263.562 263.572 263.766 244.107 244.032 244.023 243.977 243.961 243.842 243.721 243.441
264.693 264.063 263.796 263.733 263.645 263.608 263.57 263.583 263.785 244.102 244.027 244.019 243.975 243.959 243.842 243.721 243.441
264.693 264.063 263.795 263.729 263.637 263.608 263.577 263.597 263.804 244.094 244.019 244.015 243.973 243.958 243.84 243.721 243.441
[and 365 more slices...]
julia > ncwrite("testClimateBase.nc", A)
processing variable t2m...
writing dimension lon...
writing dimension lat...
writing dimension time...
writing the CF-variable...
ERROR: NetCDF error: NetCDF: Not a valid data type or _FillValue type mismatch (NetCDF error code: -45)
Stacktrace:
[1] check
@ ~/.julia/packages/NCDatasets/eDnxY/src/errorhandling.jl:33 [inlined]
[2] nc_put_att(ncid::Int32, varid::Int32, name::String, data::Int16)
@ NCDatasets ~/.julia/packages/NCDatasets/eDnxY/src/netcdf_c.jl:521
[3] setindex!(a::NCDatasets.Attributes{NCDataset{Nothing}}, data::Int16, name::String)
@ NCDatasets ~/.julia/packages/NCDatasets/eDnxY/src/attributes.jl:57
[4] defVar(ds::NCDataset{Nothing}, name::String, vtype::DataType, dimnames::Tuple{String, String, String}; kwargs::Base.Iterators.Pairs{Symbol, Vector{Pair{String, Any}}, Tuple{Symbol}, NamedTuple{(:attrib,), Tuple{Vector{Pair{String, Any}}}}})
@ NCDatasets ~/.julia/packages/NCDatasets/eDnxY/src/cfvariable.jl:158
[5] _defVar(ds::NCDataset{Nothing}, name::String, data::Array{Float64, 3}, nctype::Type, dimnames::Tuple{String, String, String}; attrib::Dict{String, Any}, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
@ NCDatasets ~/.julia/packages/NCDatasets/eDnxY/src/cfvariable.jl:234
[6] #defVar#40
@ ~/.julia/packages/NCDatasets/eDnxY/src/cfvariable.jl:187 [inlined]
[7] ncwrite(file::String, Xs::Tuple{ClimArray{Float64, 3, Tuple{Lon{StepRangeLen{Float32, Float64, Float64}, DimensionalData.Sampled{DimensionalData.Ordered{DimensionalData.ForwardIndex, DimensionalData.ForwardArray, DimensionalData.ForwardRelation}, DimensionalData.Regular{Float32}, DimensionalData.Points}, Dict{String, String}}, Lat{StepRangeLen{Float32, Float64, Float64}, DimensionalData.Sampled{DimensionalData.Ordered{DimensionalData.ReverseIndex, DimensionalData.ForwardArray, DimensionalData.ForwardRelation}, DimensionalData.Regular{Float32}, DimensionalData.Points}, Dict{String, String}}, Ti{Vector{DateTime}, DimensionalData.Sampled{DimensionalData.Ordered{DimensionalData.ForwardIndex, DimensionalData.ForwardArray, DimensionalData.ForwardRelation}, DimensionalData.Irregular{DimensionalData.AutoBounds}, DimensionalData.Points}, Dict{String, String}}}, Tuple{}, Array{Float64, 3}, Dict{String, Any}}}; globalattr::Dict{Any, Any})
@ ClimateBase ~/.julia/packages/ClimateBase/klYxO/src/core/nc_io.jl:348
[8] #ncwrite#34
@ ~/.julia/packages/ClimateBase/klYxO/src/core/nc_io.jl:319 [inlined]
[9] ncwrite(file::String, X::ClimArray{Float64, 3, Tuple{Lon{StepRangeLen{Float32, Float64, Float64}, DimensionalData.Sampled{DimensionalData.Ordered{DimensionalData.ForwardIndex, DimensionalData.ForwardArray, DimensionalData.ForwardRelation}, DimensionalData.Regular{Float32}, DimensionalData.Points}, Dict{String, String}}, Lat{StepRangeLen{Float32, Float64, Float64}, DimensionalData.Sampled{DimensionalData.Ordered{DimensionalData.ReverseIndex, DimensionalData.ForwardArray, DimensionalData.ForwardRelation}, DimensionalData.Regular{Float32}, DimensionalData.Points}, Dict{String, String}}, Ti{Vector{DateTime}, DimensionalData.Sampled{DimensionalData.Ordered{DimensionalData.ForwardIndex, DimensionalData.ForwardArray, DimensionalData.ForwardRelation}, DimensionalData.Irregular{DimensionalData.AutoBounds}, DimensionalData.Points}, Dict{String, String}}}, Tuple{}, Array{Float64, 3}, Dict{String, Any}})
@ ClimateBase ~/.julia/packages/ClimateBase/klYxO/src/core/nc_io.jl:319
[10] top-level scope
@ REPL[113]:1
pkg> st
Status `~/Project.toml`
[35604d93] ClimateBase v0.12.3
[85f8d34a] NCDatasets v0.11.3
Yeah, the type of the Fill Value is Integer, while the type of the data is Float.
Should we check and autoconvert the type of fill value to the type of the array?
(notice: this is not our problem per se. It's a problem of NCDatasets.jl that doesn't provide the convenience of automatic conversion)
ah I see! I guess we could add an optional parameter to ncwrite
?
Hi! I got the same problem here. Is there are any ways to solve this?
Yeap, the solution is quite trivial. Either do a PR here and modify the function ncwrite
to automatically convert the _FillValue
argument to the element type of the data. Or, do a similar PR at NCDatasets.jl that does the same thing in the function NCDatasets.write
.
Or just do this on your end. Just convert the _FillValue
field of the metadata dictionary to be float instead of integer.