rafaqz / Rasters.jl

Raster manipulation for the Julia language
MIT License
214 stars 36 forks source link

NetCDF-4 classic model file: empty `char` variable cannot be read #305

Closed mauro3 closed 1 year ago

mauro3 commented 2 years ago

I'm trying to read the Bedmachine Antarctica dataset: https://sites.ps.uci.edu/morlighem/dataproducts/bedmachine-antarctica/ (download from here but needs registering). It throws the error:

julia> Raster("bm.nc")
ERROR: MethodError: no method matching Raster(::Char, ::Tuple{}, ::Tuple{}, ::Symbol, ::DimensionalData.Dimensions.LookupArrays.Metadata{Rasters.NCDfile, Dict{Symbol, Any}}, ::Missing)
Closest candidates are:
  Raster(::A, ::D, ::R, ::Na, ::Me, ::Mi) where {T, N, D<:Tuple, R<:Tuple, A<:AbstractArray{T, N}, Na, Me, Mi} at ~/.julia/packages/Rasters/fANS1/src/array.jl:222
  Raster(::Any, ::Tuple; name, kw...) at ~/.julia/packages/Rasters/fANS1/src/array.jl:241
  Raster(::Any, ::AbstractString, ::Any; crs, mappedcrs, dims, refdims, name, metadata, missingval, source, write, lazy) at ~/.julia/packages/Rasters/fANS1/src/array.jl:264
  ...
Stacktrace:
  [1] Raster(ds::NCDatasets.CFVariable{Char, 0, NCDatasets.Variable{Char, 0, NCDatasets.NCDataset{Nothing}}, NCDatasets.Attributes{NCDatasets.NCDataset{Nothing}}, NamedTuple{(:fillvalue, :missing_values, :scale_factor, :add_offset, :calendar, :time_origin, :time_factor), Tuple{Nothing, Tuple{}, Nothing, Nothing, Nothing, Nothing, Nothing}}}, filename::String, key::Symbol; crs::Nothing, mappedcrs::Nothing, dims::Nothing, refdims::Tuple{}, name::Symbol, metadata::DimensionalData.Dimensions.LookupArrays.Metadata{Rasters.NCDfile, Dict{Symbol, Any}}, missingval::Missing, source::Type, write::Bool, lazy::Bool)
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/array.jl:279
  [2] Raster(ds::NCDatasets.CFVariable{Char, 0, NCDatasets.Variable{Char, 0, NCDatasets.NCDataset{Nothing}}, NCDatasets.Attributes{NCDatasets.NCDataset{Nothing}}, NamedTuple{(:fillvalue, :missing_values, :scale_factor, :add_offset, :calendar, :time_origin, :time_factor), Tuple{Nothing, Tuple{}, Nothing, Nothing, Nothing, Nothing, Nothing}}}, filename::String, key::Symbol)
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/array.jl:264
  [3] Raster(ds::NCDatasets.NCDataset{Nothing}, filename::String, key::Nothing; kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:34
  [4] Raster(ds::NCDatasets.NCDataset{Nothing}, filename::String, key::Nothing)
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:32
  [5] (::Rasters.var"#51#52"{Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, String})(ds::NCDatasets.NCDataset{Nothing})
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/array.jl:261
  [6] _open(f::Rasters.var"#51#52"{Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, String}, ::Type{Rasters.NCDfile}, ds::NCDatasets.NCDataset{Nothing}; key::Nothing, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:222
  [7] _open
    @ ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:221 [inlined]
  [8] #745
    @ ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:218 [inlined]
  [9] NCDatasets.NCDataset(::Rasters.var"#745#746"{Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, Rasters.var"#51#52"{Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}}, String}}, ::String, ::Vararg{String}; kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ NCDatasets ~/.julia/packages/NCDatasets/EkOvO/src/dataset.jl:241
 [10] NCDatasets.NCDataset(::Function, ::String, ::Vararg{String})
    @ NCDatasets ~/.julia/packages/NCDatasets/EkOvO/src/dataset.jl:238
 [11] #_open#744
    @ ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:217 [inlined]
 [12] _open(f::Function, ::Type{Rasters.NCDfile}, filename::String)
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/sources/ncdatasets.jl:214
 [13] _open(f::Function, filename::String; kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/convenience.jl:20
 [14] _open(f::Function, filename::String)
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/convenience.jl:19
 [15] Raster(filename::String; name::Nothing, key::Nothing, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/array.jl:259
 [16] Raster(filename::String)
    @ Rasters ~/.julia/packages/Rasters/fANS1/src/array.jl:258
 [17] top-level scope
    @ REPL[32]:1

trying to read separate variables works, except for:

julia> Raster("bm.nc", key=:mapping)
ERROR: MethodError: no method matching Raster(::Char, ::Tuple{}, ::Tuple{}, ::Symbol, ::DimensionalData.Dimensions.LookupArrays.Metadata{Rasters.NCDfile, Dict{Symbol, Any}}, ::Missing)
Closest candidates are:
  Raster(::A, ::D, ::R, ::Na, ::Me, ::Mi) where {T, N, D<:Tuple, R<:Tuple, A<:AbstractArray{T, N}, Na, Me, Mi} at ~/.julia
...

which shows the same error. The ncdump shows:

$ ncdump -v mapping bm.nc                    
netcdf BedMachineAntarctica_2020-07-15_v02 {                                                                            
dimensions:                                                                                                             
        x = 13333 ;                                                                                                     
        y = 13333 ;                                                                                                     
variables:                                                                                                              
        char mapping ;                                                                                                  
                mapping:grid_mapping_name = "polar_stereographic" ;                                                     
                mapping:latitude_of_projection_origin = -90. ;                                                          
                mapping:standard_parallel = -71. ;                                                                      
                mapping:straight_vertical_longitude_from_pole = 0. ;                                                    
                mapping:semi_major_axis = 6378273. ;
                mapping:inverse_flattening = 298.27940504282 ;
                mapping:false_easting = 0. ;
                mapping:false_northing = 0. ;
        int x(x) ;
                x:long_name = "Cartesian x-coordinate" ;
                x:standard_name = "projection_x_coordinate" ;
                x:units = "meter" ;
...
data:

 mapping = "" ;
}

So the mapping field does not seem to contain any data just metadata. Note that NCStack used to work.

The filetype is NetCDF-4 classic model.

rafaqz commented 2 years ago

Does RasterStack work?

Raster without arguments just loads the first variable.

The problem seems to be that the contents of the mapping variable is not an array. We may need to handle this explicitly.

mauro3 commented 2 years ago

Yes, RasterStack works. Thanks!

rafaqz commented 2 years ago

Would be nice for Raster to take the first valid variable rather than just the first variable...

rafaqz commented 1 year ago

This is fixed