Skip to content

Commit 041bffd

Browse files
change maskingvalue
1 parent 58239c6 commit 041bffd

File tree

5 files changed

+183
-85
lines changed

5 files changed

+183
-85
lines changed

src/cfvariable.jl

Lines changed: 64 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ function cfvariable(ds,
101101
# look also at parent if defined
102102
units = _getattrib(ds,_v,_parentname,"units",nothing),
103103
calendar = _getattrib(ds,_v,_parentname,"calendar",nothing),
104-
_experimental_missing_value = missing,
104+
maskingvalue = maskingvalue(ds),
105105
)
106106

107107
v = _v
@@ -155,13 +155,13 @@ function cfvariable(ds,
155155
end
156156
end
157157

158-
__experimental_missing_value =
158+
_maskingvalue =
159159
# use NaN32 rather than NaN to avoid unnecessary promotion
160160
# to double precision
161-
if scaledtype == Float32 && _experimental_missing_value === NaN
161+
if scaledtype == Float32 && maskingvalue === NaN
162162
NaN32
163163
end
164-
__experimental_missing_value = _experimental_missing_value
164+
_maskingvalue = maskingvalue
165165

166166

167167
storage_attrib = (
@@ -172,19 +172,19 @@ function cfvariable(ds,
172172
calendar = calendar,
173173
time_origin = time_origin,
174174
time_factor = time_factor,
175-
_experimental_missing_value = __experimental_missing_value,
175+
maskingvalue = _maskingvalue,
176176
)
177177

178178
rettype = _get_rettype(ds, calendar, fillvalue, missing_value,
179-
scaledtype,__experimental_missing_value)
179+
scaledtype,_maskingvalue)
180180

181181
return CFVariable{rettype,ndims(v),typeof(v),typeof(attrib),typeof(storage_attrib)}(
182182
v,attrib,storage_attrib)
183183

184184
end
185185

186186

187-
function _get_rettype(ds, calendar, fillvalue, missing_value, rettype, _experimental_missing_value)
187+
function _get_rettype(ds, calendar, fillvalue, missing_value, rettype, maskingvalue)
188188
# rettype can be a date if calendar is different from nothing
189189
if calendar !== nothing
190190
DT = nothing
@@ -205,8 +205,7 @@ function _get_rettype(ds, calendar, fillvalue, missing_value, rettype, _experime
205205
end
206206

207207
if (fillvalue !== nothing) || (!isempty(missing_value))
208-
#rettype = Union{Missing,rettype}
209-
rettype = promote_type(typeof(_experimental_missing_value),rettype)
208+
rettype = promote_type(typeof(maskingvalue),rettype)
210209
end
211210
return rettype
212211
end
@@ -239,7 +238,7 @@ The result can also be `nothing` if the variable has no time units.
239238
"""
240239
time_factor(v::CFVariable) = v._storage_attrib.time_factor
241240

242-
_experimental_missing_value(v::CFVariable) = v._storage_attrib._experimental_missing_value
241+
maskingvalue(v::CFVariable) = v._storage_attrib.maskingvalue
243242

244243
# fillvalue can be NaN (unfortunately)
245244
@inline isfillvalue(data,fillvalue) = data == fillvalue
@@ -288,62 +287,75 @@ end
288287
@inline fromdate(data,time_origin,time_factor) = data
289288

290289

291-
@inline CFtransform_experimental_missing_value(data,_experimental_missing_value) = data
292-
@inline CFtransform_experimental_missing_value(data::Missing,_experimental_missing_value) = _experimental_missing_value
290+
@inline CFtransformmaskingvalue(data,maskingvalue) = data
291+
@inline CFtransformmaskingvalue(data::Missing,maskingvalue) = maskingvalue
293292

294-
@inline CFinvtransform_experimental_missing_value(data::Missing,_experimental_missing_value::Missing) = missing
295-
@inline CFinvtransform_experimental_missing_value(data,_experimental_missing_value::Missing) = data
293+
@inline CFinvtransformmaskingvalue(data,maskingvalue::Missing) = data
296294

297-
# fall-back if _experimental_missing_value is not missing
298-
@inline function CFinvtransform_experimental_missing_value(data,_experimental_missing_value)
299-
# note NaN === NaN is true
300-
if data === _experimental_missing_value
295+
# fall-back if maskingvalue is not missing
296+
# for numbers we use == (rather ===) so that 40 == 40. is true
297+
# but we need to double check for NaNs
298+
@inline function CFinvtransformmaskingvalue(data::Number,maskingvalue::Number)
299+
if (data == maskingvalue) || (isnan(maskingvalue) && isnan(data))
301300
return missing
302301
else
303302
data
304303
end
305304
end
306305

306+
# if maskingvalue is not a number e.g. nothing, isnan is not defined
307+
@inline function CFinvtransformmaskingvalue(data,maskingvalue)
308+
if data === maskingvalue
309+
return missing
310+
else
311+
data
312+
end
313+
end
314+
315+
316+
307317
# Transformation pipelne
308318
#
309-
# fillvalue to missing -> scale -> add offset -> transform to dates -> missing to alternative sentinel value
319+
# fillvalue to missing -> scale -> add offset -> transform to dates -> missing to maskingvalue (alternative sentinel value)
310320
#
311321
# Inverse transformation pipleine
312322
#
313-
# alternative sentinel value to missing -> round float if should be ints -> encode dates -> remove offset -> inverse scalling -> missing to fillvalue
323+
# maskingvalue to missing -> round float if should be ints -> encode dates -> remove offset -> inverse scalling -> missing to fillvalue
314324
#
315325
# All steps are optional and can be skipped if not applicable
316326

317327

318-
@inline function CFtransform(data,fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DTcast)
319-
return CFtransform_experimental_missing_value(
320-
asdate(
321-
CFtransform_offset(
322-
CFtransform_scale(
323-
CFtransform_missing(data,fv),
324-
scale_factor),
325-
add_offset),
326-
time_origin,time_factor,DTcast),
327-
_experimental_missing_value)
328+
@inline function CFtransform(data,fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DTcast)
329+
return CFtransformmaskingvalue(
330+
asdate(
331+
CFtransform_offset(
332+
CFtransform_scale(
333+
CFtransform_missing(
334+
data,fv),
335+
scale_factor),
336+
add_offset),
337+
time_origin,time_factor,DTcast),
338+
maskingvalue)
328339
end
329340

330341
# round float to integers
331342
_approximate(::Type{T},data) where T <: Integer = round(T,data)
332343
_approximate(::Type,data) = data
333344

334345

335-
@inline function CFinvtransform(data,fv,inv_scale_factor,minus_offset,time_origin,inv_time_factor,_experimental_missing_value,DT)
336-
return CFtransform_experimental_missing_value(
337-
_approximate(
346+
@inline function CFinvtransform(data,fv,inv_scale_factor,minus_offset,time_origin,inv_time_factor,maskingvalue,DT)
347+
return _approximate(
338348
DT,
339349
CFtransform_replace_missing(
340350
CFtransform_scale(
341351
CFtransform_offset(
342-
fromdate(data,time_origin,inv_time_factor),
352+
fromdate(
353+
CFinvtransformmaskingvalue(
354+
data,maskingvalue),
355+
time_origin,inv_time_factor),
343356
minus_offset),
344357
inv_scale_factor),
345-
fv)),
346-
_experimental_missing_value)
358+
fv))
347359
end
348360

349361

@@ -354,27 +366,27 @@ end
354366
# CFtransform.(data,fv,scale_factor,add_offset,time_origin,time_factor,DTcast)
355367

356368
# for scalars
357-
@inline CFtransformdata(data,fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DTcast) =
358-
CFtransform(data,fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DTcast)
369+
@inline CFtransformdata(data,fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DTcast) =
370+
CFtransform(data,fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DTcast)
359371

360372
# in-place version
361-
@inline function CFtransformdata!(out,data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value) where {T,N}
373+
@inline function CFtransformdata!(out,data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue) where {T,N}
362374
DTcast = eltype(out)
363375
@inbounds @simd for i in eachindex(data)
364-
out[i] = CFtransform(data[i],fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DTcast)
376+
out[i] = CFtransform(data[i],fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DTcast)
365377
end
366378
return out
367379
end
368380

369381
# for arrays
370-
@inline function CFtransformdata(data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DTcast) where {T,N}
382+
@inline function CFtransformdata(data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DTcast) where {T,N}
371383
out = Array{DTcast,N}(undef,size(data))
372-
return CFtransformdata!(out,data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value)
384+
return CFtransformdata!(out,data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue)
373385
end
374386

375387
@inline function CFtransformdata(
376388
data::AbstractArray{T,N},fv::Tuple{},scale_factor::Nothing,
377-
add_offset::Nothing,time_origin::Nothing,time_factor::Nothing,_experimental_missing_value,::Type{T}) where {T,N}
389+
add_offset::Nothing,time_origin::Nothing,time_factor::Nothing,maskingvalue,::Type{T}) where {T,N}
378390
# no transformation necessary (avoid allocation)
379391
return data
380392
end
@@ -394,32 +406,32 @@ end
394406
# end
395407

396408
# for arrays
397-
@inline function CFinvtransformdata(data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DT) where {T,N}
409+
@inline function CFinvtransformdata(data::AbstractArray{T,N},fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DT) where {T,N}
398410
inv_scale_factor = _inv(scale_factor)
399411
minus_offset = _minus(add_offset)
400412
inv_time_factor = _inv(time_factor)
401413

402414
out = Array{DT,N}(undef,size(data))
403415
@inbounds @simd for i in eachindex(data)
404-
out[i] = CFinvtransform(data[i],fv,inv_scale_factor,minus_offset,time_origin,inv_time_factor,_experimental_missing_value,DT)
416+
out[i] = CFinvtransform(data[i],fv,inv_scale_factor,minus_offset,time_origin,inv_time_factor,maskingvalue,DT)
405417
end
406418
return out
407419
end
408420

409421
@inline function CFinvtransformdata(
410422
data::AbstractArray{T,N},fv::Tuple{},scale_factor::Nothing,
411-
add_offset::Nothing,time_origin::Nothing,time_factor::Nothing,_experimental_missing_value,::Type{T}) where {T,N}
423+
add_offset::Nothing,time_origin::Nothing,time_factor::Nothing,maskingvalue,::Type{T}) where {T,N}
412424
# no transformation necessary (avoid allocation)
413425
return data
414426
end
415427

416428
# for scalar
417-
@inline function CFinvtransformdata(data,fv,scale_factor,add_offset,time_origin,time_factor,_experimental_missing_value,DT)
429+
@inline function CFinvtransformdata(data,fv,scale_factor,add_offset,time_origin,time_factor,maskingvalue,DT)
418430
inv_scale_factor = _inv(scale_factor)
419431
minus_offset = _minus(add_offset)
420432
inv_time_factor = _inv(time_factor)
421433

422-
return CFinvtransform(data,fv,inv_scale_factor,minus_offset,time_origin,inv_time_factor,_experimental_missing_value,DT)
434+
return CFinvtransform(data,fv,inv_scale_factor,minus_offset,time_origin,inv_time_factor,maskingvalue,DT)
423435
end
424436

425437

@@ -433,7 +445,7 @@ end
433445
function Base.getindex(v::CFVariable, indexes::Union{Integer,Colon,AbstractRange{<:Integer},AbstractVector{<:Integer}}...)
434446
data = v.var[indexes...]
435447
return CFtransformdata(data,fill_and_missing_values(v),scale_factor(v),add_offset(v),
436-
time_origin(v),time_factor(v),_experimental_missing_value(v),eltype(v))
448+
time_origin(v),time_factor(v),maskingvalue(v),eltype(v))
437449
end
438450

439451
function Base.setindex!(v::CFVariable,data::Array{Missing,N},indexes::Union{Int,Colon,AbstractRange{<:Integer}}...) where N
@@ -452,7 +464,7 @@ function Base.setindex!(v::CFVariable,data::Union{T,Array{T,N}},indexes::Union{I
452464
v.var[indexes...] = CFinvtransformdata(
453465
data,fill_and_missing_values(v),scale_factor(v),add_offset(v),
454466
time_origin(v),time_factor(v),
455-
_experimental_missing_value(v),
467+
maskingvalue(v),
456468
eltype(v.var))
457469
return data
458470
end
@@ -466,7 +478,7 @@ function Base.setindex!(v::CFVariable,data,indexes::Union{Int,Colon,AbstractRang
466478
data,fill_and_missing_values(v),
467479
scale_factor(v),add_offset(v),
468480
time_origin(v),time_factor(v),
469-
_experimental_missing_value(v),
481+
maskingvalue(v),
470482
eltype(v.var))
471483

472484
return data
@@ -599,6 +611,6 @@ close(ds)
599611
fmv = fill_and_missing_values(v)
600612
return CFtransformdata!(data,buffer,fmv,scale_factor(v),add_offset(v),
601613
time_origin(v),time_factor(v),
602-
_experimental_missing_value(v))
614+
maskingvalue(v))
603615
end
604616
end

src/dataset.jl

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ end
120120

121121

122122

123-
_experimental_missing_value(ds::AbstractDataset) = missing
123+
maskingvalue(ds::AbstractDataset) = missing
124124

125125
"""
126126
v = getindex(ds::AbstractDataset, varname::SymbolOrString)
@@ -160,9 +160,7 @@ because both variables are related thought the bounds attribute following the CF
160160
See also [`cfvariable(ds, varname)`](@ref).
161161
"""
162162
function Base.getindex(ds::AbstractDataset,varname::SymbolOrString)
163-
return cfvariable(
164-
ds, varname,
165-
_experimental_missing_value = _experimental_missing_value(ds))
163+
return cfvariable(ds, varname)
166164
end
167165

168166

0 commit comments

Comments
 (0)