Known issues
NetCDF: Not a valid data type or _FillValue
type mismatch
Trying to define the _FillValue
, produces the following error:
ERROR: LoadError: NCDatasets.NetCDFError(-45, "NetCDF: Not a valid data type or _FillValue type mismatch")
The error could be generated by a code like this:
using NCDatasets, DataStructures
# ...
tempvar = defVar(ds,"temp",Float32,("lonc","latc","time"), attrib = OrderedDict(
"_FillValue" => -9999.))
or
using NCDatasets
# ...
tempvar = defVar(ds,"temp",Float32,("lonc","latc","time"), fillvalue = -9999.)
In fact, _FillValue
must have the same data type as the corresponding variable. In the case above, tempvar
is a 32-bit float and the number -9999.
is a 64-bit float (aka double, which is the default floating point type in Julia). It is sufficient to convert the value -9999.
to a 32-bit float -9999.f0
(or Float32(-9999.)
).
Defining the attributes _FillValue
, add_offset
, scale_factor
, units
and calendar
An error like Cannot
convert
an object of type Missing
(or similar) is generated by code like this:
v = defVar(ds,"var_with_all_missing_data",Float32,("lon",))
v.attrib["_FillValue"] = fv
v[1] = missing
This produces the following error:
ERROR: LoadError: MethodError: Cannot `convert` an object of type Missing to an object of type Float32
Closest candidates are:
convert(::Type{T}, ::T) where T<:Number at number.jl:6
convert(::Type{T}, ::Number) where T<:Number at number.jl:7
convert(::Type{T}, ::Base.TwicePrecision) where T<:Number at twiceprecision.jl:250
...
Stacktrace:
[1] fill!(::SubArray{Float32,1,NCDatasets.CFVariable{Float32,1,NCDatasets.Variable{Float32,1},NCDatasets.Attributes},Tuple{UnitRange{Int64}},false}, ::Missing) at ./multidimensional.jl:865
[2] copyto! at ./broadcast.jl:871 [inlined]
[3] materialize!(::SubArray{Float32,1,NCDatasets.CFVariable{Float32,1,NCDatasets.Variable{Float32,1},NCDatasets.Attributes},Tuple{UnitRange{Int64}},false}, ::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{0},Nothing,typeof(identity),Tuple{Base.RefValue{Missing}}}) at ./broadcast.jl:822
One should use define the _FillValue
(and similar attributes like add_offset
, scale_factor
, units
and calendar
affecting the type of the data) in the call of defVar
:
using DataStructures
v = defVar(ds,"var_with_all_missing_data",Int32,("lon",), fillvalue = fv, attrib = OrderedDict(
"scale_factor" => 0.1,
"add_offset" => 0.1
))
This change was introduced in NCDatasets
version 0.10
Multiple versions of HDF5 or NetCDF libraries
Having outdated versions of HDF5 or NetCDF libraries installed can be an issue on Windows if they are included in the system PATH
environment variable. It is advised to adapt the system PATH
to remove the locations containing these libraries.
Using a custom NetCDF library
The NetCDF library libnetcdf.so
is installed as an artifact via the package NetCDF_jll. You can override which libnetcdf.so
gets loaded through the Preferences
package, as follows:
# install these packages if necessary
using Preferences, NetCDF_jll
set_preferences!(NetCDF_jll, "libnetcdf_path" => "/path/to/libnetcdf.so.xyz")
where /path/to/libnetcdf.so.xyz
is the full path to the NetCDF library. This will create a LocalPreferences.toml
file in your top-level project with the following content:
[NetCDF_jll]
libnetcdf_path = "/path/to/libnetcdf.so.xyz"
However, the dependencies of the library version libnetcdf.so.xyz
(in particular libcurl.so
and libmbedtls.so
) should be compatible with the dependencies of julia (in the folder .../julia-x.y.z/lib/julia
). On Linux, you can list the library dependencies with the shell command ldd
, for example:
ldd /path/to/libnetcdf.so.xyz
OPeNDAP on Windows fails with Assertion failed: ocpanic
On windows, NetCDF 4.7.4 can fail with this error:
Assertion failed: ocpanic(("state->auth.curlflags.cookiejar != NULL")), file ocinternal.c, line 566
when accessing OPeNDAP URLs, like these:
using NCDatasets
ds = NCDataset("https://thredds.jpl.nasa.gov/thredds/dodsC/ncml_aggregation/OceanTemperature/modis/terra/11um/4km/aggregate__MODIS_TERRA_L3_SST_THERMAL_DAILY_4KM_DAYTIME_V2019.0.ncml#fillmismatch")
See also the issue report: https://github.com/Unidata/netcdf-c/issues/2380. The work-around is to create a .dodsrc
in the current working directory with the content:
HTTP.COOKIEJAR=C:\Users\USERNAME\AppData\Local\Temp\
where USERNAME is your username. The directory should exist and be writable by the user. You can run pwd()
to determine the current working directory. Note that the initial current working directory can be different depending you how you start julia (from the command line or from jupyter notebook for example). Julia need to be restarted after this file is placed in the your working directory.
version `CURL_4' not found
Julia and NetCDF_jll have several common dependencies (curl, MbedTLS, zlib). Non-official julia builds will work only if they use exactly the same library version as those used to compile NetCDF. This is unlikely to be the case in general and outside of our control. Therefore non-official julia builds are not supported. Official julia builds are available at https://julialang.org/downloads/.
Using for example the julia package from on Arch Linux, leads to this error:
julia> using NCDatasets
ERROR: LoadError: InitError: could not load library "/root/.julia/artifacts/461703969206dd426cc6b4d99f69f6ffab2a9779/lib/libnetcdf.so"
/usr/lib/julia/libcurl.so: version `CURL_4' not found (required by /root/.julia/artifacts/461703969206dd426cc6b4d99f69f6ffab2a9779/lib/libnetcdf.so)
Stacktrace:
[1] macro expansion
@ ~/.julia/packages/JLLWrappers/QpMQW/src/products/library_generators.jl:54 [inlined]
[2] __init__()
@ NetCDF_jll ~/.julia/packages/NetCDF_jll/BYHmI/src/wrappers/x86_64-linux-gnu.jl:12
[3] top-level scope
@ stdin:1
during initialization of module NetCDF_jll
You will likely have similar issues with julia installed from other package managers (like Debian/Ubuntu apt, Homebrew...). The only supported solution is to install the offical julia builds.
Even when the official build of julia, this error can occur on Linux if an incompatible library is loaded when the user set LD_LIBRARY_PATH
and LD_PRELOAD
:
ERROR: LoadError: InitError: could not load library "/home/user/.julia/artifacts/461703969206dd426cc6b4d99f69f6ffab2a9779/lib/libnetcdf.so"
/usr/lib/x86_64-linux-gnu/libcurl.so: version `CURL_4' not found (required by /home/user/.julia/artifacts/461703969206dd426cc6b4d99f69f6ffab2a9779/lib/libnetcdf.so)
Please make sure that your LD_LIBRARY_PATH
and LD_PRELOAD
are empty or verify that the all loaded libraries are binary compatible. You can check these environement variables by running the following commands in a terminal:
echo $LD_PRELOAD
echo $LD_LIBRARY_PATH
If you must set $LD_LIBRARY_PATH
for some application, consider to use a wrapper script for this application or recompiling the application with the -rpath
linker option rather than setting this variable globally.
Corner cases
An attribute representing a vector with a single value (e.g.
[1]
) will be read back as a scalar (1
) (same behavior in python netCDF4 1.3.1).NetCDF and Julia distinguishes between a vector of chars and a string, but both are returned as string for ease of use, in particular an attribute representing a vector of chars
['u','n','i','t','s']
will be read back as the string"units"
.While reading a NetCDF time variable, the dates are converted using the Julia's
DateTime
(based on the proleptic Gregorian calendar following the ISO 8601 standard) when possible. When data is written to a NetCDF file (without specifying the calendar), the dates are saved using the default calendar of the NetCDF CF convention (the mixed Julian/Gregorian calendar, called"standard"
) when possible. It is recommended that the time origin specified by the units is after 15 October 1582 in which case the mixed Julian/Gregorian calendar is identical to the proleptic Gregorian calendar.