GRIB API学习笔记09——GRIB API高级话题1

目录

All you wouldn’t like to know, but you must know

1.1.  Simple Packing

IEEE 64 floating point
|
| Simple packing
|
N-bits scaled/biased integer
N通常为8,10,16,24

1.1.1.   Keys

values
decimalPrecision
changeDecimalPrecision
packingError (read only)
下面的key只在明白打包的工作原理时才使用
referenceValue (read only)
bitsPerValue
decimalScaleFactor
binaryScaleFactor (read only)
注意:设置decimalPrecision不重新打包数据,但是设置changeDecimalPrecision重新打包数据。

1.1.2.   原理:离散化

1.1.3.   实例

设想一个假象的12小时500百帕位势高度预报,取值范围从5340到5460。
decimal precision设为1,我们将所有数值放大10倍,范围变为53400到54600.
选择合适的decimalScaleFactor D,使原始数据乘以10^D后,整数部分有足够的精度包含所有信息。
referenceValue是最小值(如53400)。减去这个值使剩余的非负残差范围在0到1200。
这个范围需要的位长度为11,所以所有数值现在打包在11位长的字里面。

1.2.  恒定场Constant fields

恒定场中所有数值都是相同的。
重复同一个值非常低效。
该常数值是唯一需要保存的,而数据段为空。
恒定场都很小,并且精确编码。
可以很简单地被创建:
grib_set –d 1 in.grib out.grib
恒定场中打包参数未被设置(bitsPerValue=0)
我们载入一个常量场
grib_new_from_file(infile,igrib)
设置一些非常量数值,此处我们并不知道打包参数
grib_set(igrib,’values’,values)
写入到文件中
grib_write(igrib,outfile)
这种情况下我们期待什么样的packingError?
恒定场中打包参数未被设置,GRIB API不知道我们需要什么样的精度,做出一个安全的选择:bitsPerValue=24(三字节)
最佳实践:在打包数据前设置decimalPrecision或bitsPerValue
[code]
grib_new_from_file(infile,igrib)
grib_set(igrib,’decimalPrecision’,4)
grib_set(igrib,’values’,values)
grib_write(igrib,outfile)

grib_new_from_file(infile,igrib)
grib_set(igrib,’bitsPerValue’,16)
grib_set(igrib,’values’,values)
grib_write(igrib,outfile)
[/code]

1.3.  位图 Bitmap

位图是二进制值的数组,大小与格点个数(numberOfPoints)相同。
0->没有值
1->值存在
假设missingValue=9999.00
不存在bitmap时

<td valign="top" width="142">
  <p align="left">
    <b>values</b>
  </p>
</td>

<td valign="top" width="142">
  <p align="left">
    <b>values</b>
  </p>
</td>
<td valign="top" width="142">
  <p align="left">
    <b>2.25</b>
  </p>
</td>

<td valign="top" width="142">
  <p align="left">
    <b>2.12</b>
  </p>
</td>
<td valign="top" width="142">
  <p align="left">
    <b>9999</b>
  </p>
</td>

<td valign="top" width="142">
  <p align="left">
    <b>9999</b>
  </p>
</td>
<td valign="top" width="142">
  <p align="left">
    <b>9999</b>
  </p>
</td>

<td valign="top" width="142">
  <p align="left">
    <b>9999</b>
  </p>
</td>
<td valign="top" width="142">
  <p align="left">
    <b>0.63</b>
  </p>
</td>

<td valign="top" width="142">
  <p align="left">
    <b>0.33</b>
  </p>
</td>

** **
为了节省空间,我们在数据段中只保存真实存在的数值,bitmap用来指示哪些点在数据段中有值。
设为0的点在数据段中没有对应值。

1.4.  Multi fields

GRIB单个消息中可以包含多个内容,section2-7均可以重复。
注:每种重复都是从section2-4开始,到section 7结束。目前没有相关例子。

例:
将预报时效12小时和24小时两段放到同一个grib2消息中
Section 0: Indicator Section
Section 1: Identification Section
Section 2: Local Use Section (optional)
Section 3: Grid Definition Section
Section 4: Product Definition Section (hour = 12)      | repetition 1
Section 5: Data Representation Section                    |
Section 6: Bit-Map Section                                        |
Section 7: Data Section                                              |
Section 4: Product Definition Section (hour = 24)      | repetition 2
Section 5: Data Representation Section                    |
Section 6: Bit-Map Section                                        |
Section 7: Data Section                                              |
Section 8: End Section
注意,网格定义段没有重复,它在所有预报时效保持不变。
例:multi.f90
[code]
! 打开对多段消息的支持
call grib_multi_support_on()
! 关闭
!call grib_multi_support_off()
call grib_new_from_file(ifile,igrib, iret)
! 遍历文件中的所有消息
do while (iret /= GRIB_END_OF_FILE)
call grib_new_from_file(ifile,igrib, iret)
end do
[/code]
** **
例:write_multi.f90
[code]
sec=4
do step=0,240,12
call grib_set(in_gribid,”step”,step)
! Append in_gribid to multi_gribid
! Start from section sec
call grib_multi_append(in_gribid,sec,multi_gribid)
enddo
! write messages to a file
call grib_multi_write(multi_gribid,outfile)
[/code]