@@ -101,7 +101,7 @@ function cfvariable(ds,
101
101
# look also at parent if defined
102
102
units = _getattrib (ds,_v,_parentname," units" ,nothing ),
103
103
calendar = _getattrib (ds,_v,_parentname," calendar" ,nothing ),
104
- _experimental_missing_value = missing ,
104
+ maskingvalue = maskingvalue (ds) ,
105
105
)
106
106
107
107
v = _v
@@ -155,13 +155,13 @@ function cfvariable(ds,
155
155
end
156
156
end
157
157
158
- __experimental_missing_value =
158
+ _maskingvalue =
159
159
# use NaN32 rather than NaN to avoid unnecessary promotion
160
160
# to double precision
161
- if scaledtype == Float32 && _experimental_missing_value === NaN
161
+ if scaledtype == Float32 && maskingvalue === NaN
162
162
NaN32
163
163
end
164
- __experimental_missing_value = _experimental_missing_value
164
+ _maskingvalue = maskingvalue
165
165
166
166
167
167
storage_attrib = (
@@ -172,19 +172,19 @@ function cfvariable(ds,
172
172
calendar = calendar,
173
173
time_origin = time_origin,
174
174
time_factor = time_factor,
175
- _experimental_missing_value = __experimental_missing_value ,
175
+ maskingvalue = _maskingvalue ,
176
176
)
177
177
178
178
rettype = _get_rettype (ds, calendar, fillvalue, missing_value,
179
- scaledtype,__experimental_missing_value )
179
+ scaledtype,_maskingvalue )
180
180
181
181
return CFVariable {rettype,ndims(v),typeof(v),typeof(attrib),typeof(storage_attrib)} (
182
182
v,attrib,storage_attrib)
183
183
184
184
end
185
185
186
186
187
- function _get_rettype (ds, calendar, fillvalue, missing_value, rettype, _experimental_missing_value )
187
+ function _get_rettype (ds, calendar, fillvalue, missing_value, rettype, maskingvalue )
188
188
# rettype can be a date if calendar is different from nothing
189
189
if calendar != = nothing
190
190
DT = nothing
@@ -205,8 +205,7 @@ function _get_rettype(ds, calendar, fillvalue, missing_value, rettype, _experime
205
205
end
206
206
207
207
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)
210
209
end
211
210
return rettype
212
211
end
@@ -239,7 +238,7 @@ The result can also be `nothing` if the variable has no time units.
239
238
"""
240
239
time_factor (v:: CFVariable ) = v. _storage_attrib. time_factor
241
240
242
- _experimental_missing_value (v:: CFVariable ) = v. _storage_attrib. _experimental_missing_value
241
+ maskingvalue (v:: CFVariable ) = v. _storage_attrib. maskingvalue
243
242
244
243
# fillvalue can be NaN (unfortunately)
245
244
@inline isfillvalue (data,fillvalue) = data == fillvalue
@@ -288,62 +287,75 @@ end
288
287
@inline fromdate (data,time_origin,time_factor) = data
289
288
290
289
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
293
292
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
296
294
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))
301
300
return missing
302
301
else
303
302
data
304
303
end
305
304
end
306
305
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
+
307
317
# Transformation pipelne
308
318
#
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)
310
320
#
311
321
# Inverse transformation pipleine
312
322
#
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
314
324
#
315
325
# All steps are optional and can be skipped if not applicable
316
326
317
327
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)
328
339
end
329
340
330
341
# round float to integers
331
342
_approximate (:: Type{T} ,data) where T <: Integer = round (T,data)
332
343
_approximate (:: Type ,data) = data
333
344
334
345
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 (
338
348
DT,
339
349
CFtransform_replace_missing (
340
350
CFtransform_scale (
341
351
CFtransform_offset (
342
- fromdate (data,time_origin,inv_time_factor),
352
+ fromdate (
353
+ CFinvtransformmaskingvalue (
354
+ data,maskingvalue),
355
+ time_origin,inv_time_factor),
343
356
minus_offset),
344
357
inv_scale_factor),
345
- fv)),
346
- _experimental_missing_value)
358
+ fv))
347
359
end
348
360
349
361
@@ -354,27 +366,27 @@ end
354
366
# CFtransform.(data,fv,scale_factor,add_offset,time_origin,time_factor,DTcast)
355
367
356
368
# 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)
359
371
360
372
# 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}
362
374
DTcast = eltype (out)
363
375
@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)
365
377
end
366
378
return out
367
379
end
368
380
369
381
# 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}
371
383
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 )
373
385
end
374
386
375
387
@inline function CFtransformdata (
376
388
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}
378
390
# no transformation necessary (avoid allocation)
379
391
return data
380
392
end
@@ -394,32 +406,32 @@ end
394
406
# end
395
407
396
408
# 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}
398
410
inv_scale_factor = _inv (scale_factor)
399
411
minus_offset = _minus (add_offset)
400
412
inv_time_factor = _inv (time_factor)
401
413
402
414
out = Array {DT,N} (undef,size (data))
403
415
@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)
405
417
end
406
418
return out
407
419
end
408
420
409
421
@inline function CFinvtransformdata (
410
422
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}
412
424
# no transformation necessary (avoid allocation)
413
425
return data
414
426
end
415
427
416
428
# 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)
418
430
inv_scale_factor = _inv (scale_factor)
419
431
minus_offset = _minus (add_offset)
420
432
inv_time_factor = _inv (time_factor)
421
433
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)
423
435
end
424
436
425
437
433
445
function Base. getindex (v:: CFVariable , indexes:: Union{Integer,Colon,AbstractRange{<:Integer},AbstractVector{<:Integer}} ...)
434
446
data = v. var[indexes... ]
435
447
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))
437
449
end
438
450
439
451
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
452
464
v. var[indexes... ] = CFinvtransformdata (
453
465
data,fill_and_missing_values (v),scale_factor (v),add_offset (v),
454
466
time_origin (v),time_factor (v),
455
- _experimental_missing_value (v),
467
+ maskingvalue (v),
456
468
eltype (v. var))
457
469
return data
458
470
end
@@ -466,7 +478,7 @@ function Base.setindex!(v::CFVariable,data,indexes::Union{Int,Colon,AbstractRang
466
478
data,fill_and_missing_values (v),
467
479
scale_factor (v),add_offset (v),
468
480
time_origin (v),time_factor (v),
469
- _experimental_missing_value (v),
481
+ maskingvalue (v),
470
482
eltype (v. var))
471
483
472
484
return data
@@ -599,6 +611,6 @@ close(ds)
599
611
fmv = fill_and_missing_values (v)
600
612
return CFtransformdata! (data,buffer,fmv,scale_factor (v),add_offset (v),
601
613
time_origin (v),time_factor (v),
602
- _experimental_missing_value (v))
614
+ maskingvalue (v))
603
615
end
604
616
end
0 commit comments