问题描述
我从 AWS(亚马逊网络服务)上托管的 noaa-16 存储桶下载了一个数据集(“OR_GLM-L2-LCFA_G16_s20202530000000_e20202530000200_c20202530000226.nc”)。该数据集包含一个名为“flash_time_offset_of_first_event”的变量,详细说明自 2020 年 9 月 9 日以来的秒数,在 00:00:00 和 00:00:20 之间...
using NCDatasets
flash_times = []
fname1 = "OR_GLM-L2-LCFA_G16_s20202530000000_e20202530000200_c20202530000226.nc"
fpath1 = string("C:\\mydir\\",fname1)
NCDataset(fpath1) do ds
[push!(flash_times,string(x)) for x in ds["flash_time_offset_of_first_event"][:,:]]
end
产生:
sort(flash_times)
481-element Array{Any,1}:
"2020-09-08T23:59:42.594"
"2020-09-08T23:59:42.672"
"2020-09-08T23:59:42.688"
⋮
"2020-09-09T00:00:07.324"
"2020-09-09T00:00:07.366"
"2020-09-09T00:00:07.42"
问题是时间与值图中显示的时间不匹配,如在 Panoply 中绘制的(如下所示)。在 Panoply 中,绘制的值范围从 ~-0.7s (2020-09-08T23:59:59.3) 到 ~19.4s (2020-09-09T00:00:19.4):
@info("",Earliest_time=sort(flash_times)[1],Latest_time=sort(flash_times)[end])
产生:
┌ Info:
│ Earliest_time = "2020-09-08T23:59:42.594"
└ Latest_time = "2020-09-09T00:00:07.42"
我的问题:我该如何正确提取这些时间,或者更正我提取的时间? NetCDF 还包含 scale_factor
和 add_offset
变量的信息,但到目前为止我还没有能够实现这些。我还尝试使用 NetCDF 包提取 netCDF 数据,但这会返回一个整数数组,我已尝试(未成功)使用 scale_factor
和 add_offset
变量进行转换。
解决方法
NCDatasets 已经自动应用了 scale_factor
和 add_offset
属性,但是这里还有另一个属性 _Unsigned
,NCDatasets 还不知道,而其他库,如在 Panoply 中使用的和 xarray 做。我为它创建了这个问题:https://github.com/Alexander-Barth/NCDatasets.jl/issues/133。
所以简而言之,数据存储为 Int16
,并且在后半部分具有负值。由于这些负值应该被解释为无符号(正)值,这会影响最终出现的日期。我们现在可以自己挖掘并应用这些步骤,以从原始数据中获得正确的值:
using NCDatasets
using Downloads
using Dates
url = "http://ftp.cptec.inpe.br/goes/goes16/glm/2020/09/09/OR_GLM-L2-LCFA_G16_s20202530000000_e20202530000200_c20202530000226.nc"
path = Downloads.download(url)
ds = NCDataset(path)
var = ds["flash_time_offset_of_first_event"]
# flash_time_offset_of_first_event (481)
# Datatype: Int16
# Dimensions: number_of_flashes
# Attributes:
# long_name = GLM L2+ Lightning Detection: time of occurrence of first constituent event in flash
# standard_name = time
# _Unsigned = true
# scale_factor = 0.0003814756
# add_offset = -5.0
# units = seconds since 2020-09-09 00:00:00.000
# axis = T
# see the issue,these dates are incorrect
extrema(var)
# DateTime("2020-09-08T23:59:42.594")
# DateTime("2020-09-09T00:00:07.420")
raw = var.var[:] # Vector{Int16}
# interpret as unsigned,and apply scale and offset
val = reinterpret(unsigned(eltype(raw)),raw) .* NCDatasets.scale_factor(var) .+ NCDatasets.add_offset(var)
# get dates by adding these as seconds to the epoch
epoch = DateTime("2020-09-09T00:00:00")
times = epoch .+ Millisecond.(round.(Int,val .* 1000))
extrema(times) # these are as expected
# DateTime("2020-09-08T23:59:59.251")
# DateTime("2020-09-09T00:00:19.408")
当然这并不理想,用户在 NCDatasets 本身中解决这个问题会更容易。