1# Copyright 2005-2018 ECMWF.
2#
3# This software is licensed under the terms of the Apache Licence Version 2.0
4# which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
5#
6# In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
7# virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
8#
9
10# START grib1::section
11# SECTION 4, Binary data section
12#  Length of section
13# (octets)
14position offsetSection4;
15
16# Due to a trick done by GRIBEX to support large GRIBs, we need a special treatment
17# of the message length and of the section4 lenth, so instead of
18# length[3] section4Length                     ;
19# we get:
20g1_section4_length[3] section4Length(totalLength);
21
22meta section4Pointer section_pointer(offsetSection4,section4Length,4);
23
24g1_half_byte_codeflag halfByte;
25flags[1] dataFlag "grib1/11.table" = 0 : read_only;
26signed[2] binaryScaleFactor = 0 : read_only,dump;
27ibmfloat referenceValue : read_only,dump;
28
29meta referenceValueError reference_value_error(referenceValue,ibm);
30
31flagbit sphericalHarmonics(dataFlag,7) : dump;
32flagbit complexPacking(dataFlag,6) : dump;
33flagbit integerPointValues(dataFlag,5) : dump;
34flagbit additionalFlagPresent(dataFlag,4) : edition_specific,dump;
35
36# second order packing
37if (complexPacking && sphericalHarmonics==0) {
38	unsigned[1] widthOfFirstOrderValues : dump ;
39	unsigned [2] N1;
40	flags[1] extendedFlag "grib1/11-2.table";
41
42	#  Undocumented use of octet 14 extededFlags
43	#  Taken from d2ordr.F
44	#         R------- only bit 1 is reserved.
45	#         -0------ single datum at each grid point.
46	#         -1------ matrix of values at each grid point.
47	#         --0----- no secondary bit map.
48	#         --1----- secondary bit map present.
49	#         ---0---- second order values have constant width.
50	#         ---1---- second order values have different widths.
51	#         ----0--- no general extended second order packing.
52	#         ----1--- general extended second order packing used.
53	#         -----0-- standard field ordering in section 4.
54	#         -----1-- boustrophedonic ordering in section 4.
55	#         ------00 no spatial differencing used.
56	#         ------01 1st-order spatial differencing used.
57	#         ------10 2nd-order    "         "         " .
58	#         ------11 3rd-order    "         "         " .
59
60	#ksec4(8)
61	flagbit matrixOfValues              (extendedFlag,6) = 0  : dump;
62	#ksec4(9)
63	flagbit secondaryBitmapPresent      (extendedFlag,5) = 0  : dump;
64	#ksec4(10)
65	flagbit secondOrderOfDifferentWidth (extendedFlag,4) = 0  : dump;
66	#ksec4(12)
67	flagbit generalExtended2ordr        (extendedFlag,3) = 0  : dump;
68	#ksec4(13)
69	flagbit boustrophedonicOrdering     (extendedFlag,2) = 0  : dump;
70	#ksec4(14)
71	flagbit twoOrdersOfSPD              (extendedFlag,1) = 0  : dump;
72	#ksec4(15)
73	flagbit plusOneinOrdersOfSPD        (extendedFlag,0) = 0  : dump;
74	meta orderOfSPD evaluate(plusOneinOrdersOfSPD + 2 * twoOrdersOfSPD);
75	alias secondaryBitmap = secondaryBitmapPresent;
76	alias boustrophedonic=boustrophedonicOrdering;
77}  else {
78	transient orderOfSPD=2;
79	transient boustrophedonic=0;
80}
81transient hideThis=0;
82
83concept packingType {
84#set uses the last one
85#get returns the first match
86  "grid_simple"                       = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
87  "grid_ieee"                         = { sphericalHarmonics = 0; complexPacking = 0;
88                                          integerPointValues=1; additionalFlagPresent=1;}
89  "spectral_complex"                  = { sphericalHarmonics = 1; complexPacking = 1;
90											additionalFlagPresent = 0; }
91  "spectral_simple"                   = { sphericalHarmonics = 1; complexPacking = 0; additionalFlagPresent = 0;
92                                          representationMode=1;}
93  "spectral_ieee"                  = { sphericalHarmonics = 1; complexPacking = 1;
94											additionalFlagPresent = 0;hideThis=1; }
95  "grid_simple_matrix"                = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 1;}
96
97  "grid_second_order_row_by_row"        = {	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
98  											matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=0; }
99  "grid_second_order_constant_width"    = {	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=0;
100  											matrixOfValues=0; secondaryBitmapPresent=1; generalExtended2ordr=0; }
101  "grid_second_order_general_grib1"    = {sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
102  									matrixOfValues=0; secondaryBitmapPresent=1; generalExtended2ordr=0; }
103  "grid_second_order_no_SPD"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
104  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
105									plusOneinOrdersOfSPD=0; twoOrdersOfSPD=0;}
106  "grid_second_order"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
107  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
108									plusOneinOrdersOfSPD=0; twoOrdersOfSPD=1; boustrophedonic=1;}
109  "grid_second_order"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
110  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
111									plusOneinOrdersOfSPD=0; twoOrdersOfSPD=1; boustrophedonic=0;}
112  "grid_second_order_no_boustrophedonic"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
113  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
114									plusOneinOrdersOfSPD=0; twoOrdersOfSPD=1; boustrophedonic=0;}
115  "grid_second_order_boustrophedonic"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
116  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
117									plusOneinOrdersOfSPD=0; twoOrdersOfSPD=1; boustrophedonic=1;}
118  "grid_second_order_SPD1"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
119  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
120									plusOneinOrdersOfSPD=1; twoOrdersOfSPD=0; }
121  "grid_second_order_SPD2"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
122  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
123									plusOneinOrdersOfSPD=0; twoOrdersOfSPD=1; }
124  "grid_second_order_SPD3"  = { 	sphericalHarmonics = 0; complexPacking = 1; secondOrderOfDifferentWidth=1;
125  									matrixOfValues=0; secondaryBitmapPresent=0; generalExtended2ordr=1;
126									plusOneinOrdersOfSPD=1; twoOrdersOfSPD=1; }
127  "grid_jpeg"                         = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
128  "grid_png"                          = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
129  "grid_ccsds"                        = { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
130  "grid_simple_log_preprocessing"= { sphericalHarmonics = 0; complexPacking = 0; additionalFlagPresent = 0;}
131} : dump;
132
133
134alias ls.packingType=packingType;
135alias typeOfPacking=packingType;
136
137if( binaryScaleFactor == -32767) {
138
139unsigned[1] bitsPerValue : dump ;
140alias numberOfBitsContainingEachPackedValue = bitsPerValue;
141
142  constant dataRepresentationTemplateNumber = 0;
143  constant bitMapIndicator = 0;
144  # For grib 1 -> 2
145  position offsetBeforeData;
146  transient numberOfCodedValues=numberOfPoints;
147  meta values data_dummy_field(
148        section4Length,
149        offsetBeforeData,
150        offsetSection4,
151        unitsFactor,
152        unitsBias,
153        changingPrecision,
154        numberOfCodedValues,
155        bitsPerValue,
156        referenceValue,
157        binaryScaleFactor,
158        decimalScaleFactor,
159        halfByte,
160		packingType,
161		grid_ieee,precision,
162        missingValue,
163        numberOfPoints,
164        bitmap
165      ) : dump;
166} else {
167  template dataValues "grib1/data.[packingType:s].def";
168}
169
170position offsetAfterData;
171
172transient dataLength=(offsetAfterData-offsetBeforeData)/8;
173
174if (bitmapPresent==1) {
175  alias numberOfEffectiveValues=numberOfDataPoints;
176} else {
177  alias numberOfEffectiveValues=numberOfCodedValues;
178}
179
180_if (sphericalHarmonics) {
181	alias numberOfEffectiveValues=numberOfValues;
182}
183
184meta changeDecimalPrecision decimal_precision(bitsPerValue,decimalScaleFactor,changingPrecision,values)  : edition_specific;
185meta decimalPrecision decimal_precision(bitsPerValue,decimalScaleFactor,changingPrecision)  : edition_specific;
186alias setDecimalPrecision=changeDecimalPrecision;
187
188meta bitsPerValueAndRepack bits_per_value(values,bitsPerValue)  : edition_specific;
189alias setBitsPerValue=bitsPerValueAndRepack;
190
191meta scaleValuesBy scale_values(values,missingValue) : edition_specific;
192meta offsetValuesBy offset_values(values,missingValue) : edition_specific;
193
194concept gridType {
195#set uses the last one
196#get returns the first match
197  "regular_ll"           = {dataRepresentationType = 0;  sphericalHarmonics = 0; PLPresent=0;}
198  "reduced_ll"           = {dataRepresentationType = 0;  sphericalHarmonics = 0; PLPresent=1; Ni=missing(); }
199  "mercator"             = {dataRepresentationType = 1;  sphericalHarmonics = 0; PLPresent=0; }
200  "lambert"              = {dataRepresentationType = 3;  sphericalHarmonics = 0; PLPresent=0; }
201  "polar_stereographic"  = {dataRepresentationType = 5;  sphericalHarmonics = 0; PLPresent=0; }
202  "UTM"                  = {dataRepresentationType = 6;  sphericalHarmonics = 0; PLPresent=0; }
203  "simple_polyconic"     = {dataRepresentationType = 7;  sphericalHarmonics = 0; PLPresent=0; }
204  "albers"               = {dataRepresentationType = 8;  sphericalHarmonics = 0; PLPresent=0; }
205  "miller"               = {dataRepresentationType = 8;  sphericalHarmonics = 0; PLPresent=0; }
206  "rotated_ll"           = {dataRepresentationType = 10; sphericalHarmonics = 0; PLPresent=0; }
207  "stretched_ll"         = {dataRepresentationType = 20; sphericalHarmonics = 0; PLPresent=0; }
208  "stretched_rotated_ll" = {dataRepresentationType = 30; sphericalHarmonics = 0; PLPresent=0; }
209  "regular_gg"           = {dataRepresentationType = 4;  sphericalHarmonics = 0; PLPresent=0; }
210  "rotated_gg"           = {dataRepresentationType = 14; sphericalHarmonics = 0; PLPresent=0; }
211  "stretched_gg"         = {dataRepresentationType = 24; sphericalHarmonics = 0; PLPresent=0; }
212  "stretched_rotated_gg" = {dataRepresentationType = 34; sphericalHarmonics = 0; PLPresent=0; }
213  "reduced_gg"           = {dataRepresentationType = 4;  sphericalHarmonics = 0;
214                            PLPresent=1; numberOfPointsAlongAParallel = missing();
215                            iDirectionIncrement = missing(); ijDirectionIncrementGiven=0;}
216
217  "reduced_rotated_gg"   = {dataRepresentationType = 14;  sphericalHarmonics = 0;
218                            PLPresent=1; numberOfPointsAlongAParallel = missing();
219                            iDirectionIncrement = missing(); ijDirectionIncrementGiven=0;}
220  "reduced_stretched_gg" = {dataRepresentationType = 24;  sphericalHarmonics = 0;
221                            PLPresent=1; numberOfPointsAlongAParallel = missing();
222                            iDirectionIncrement = missing(); ijDirectionIncrementGiven=0;}
223  "reduced_stretched_rotated_gg" = {dataRepresentationType = 34;  sphericalHarmonics = 0;
224                            PLPresent=1; numberOfPointsAlongAParallel = missing();
225                            iDirectionIncrement = missing(); ijDirectionIncrementGiven=0;}
226
227# For consistency add the prefix regular_
228"regular_rotated_gg"           = { dataRepresentationType = 14; sphericalHarmonics = 0; PLPresent=0; } # = rotated_gg
229"regular_stretched_gg"         = { dataRepresentationType = 24; sphericalHarmonics = 0; PLPresent=0; } # = stretched_gg
230"regular_stretched_rotated_gg" = { dataRepresentationType = 34; sphericalHarmonics = 0; PLPresent=0; } # = stretched_rotated_gg
231
232
233  "sh"                   = {dataRepresentationType = 50; sphericalHarmonics = 1; PLPresent=0; }
234  "rotated_sh"           = {dataRepresentationType = 60; sphericalHarmonics = 1; PLPresent=0; }
235  "stretched_sh"         = {dataRepresentationType = 70; sphericalHarmonics = 1; PLPresent=0; }
236  "stretched_rotated_sh" = {dataRepresentationType = 80; sphericalHarmonics = 1; PLPresent=0; }
237  "space_view"           = {dataRepresentationType = 90; sphericalHarmonics = 0; PLPresent=0; }
238  "unknown"              = {PLPresent=0;}
239  "unknown_PLPresent"    = {PLPresent=1;}
240} : dump;
241
242alias ls.gridType=gridType;
243alias geography.gridType=gridType;
244alias typeOfGrid=gridType;
245
246meta getNumberOfValues size(values) : edition_specific,dump ;
247
248if (complexPacking==0 || sphericalHarmonics==1) {
249	padtoeven padding_sec4_1(offsetSection4,section4Length) ;
250}
251
252meta md5Section4 md5(offsetSection4,section4Length);
253alias md5DataSection = md5Section4;
254
255