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