gistools/readers/grib2/sections/_5/templates.rs
1use crate::{
2 parsers::Reader,
3 readers::{
4 Grib2Table5_1, Grib2Table5_4, Grib2Table5_5, Grib2Table5_6, Grib2Table5_7, Grib2Table5_40,
5 },
6};
7
8/// Returns a template generator for the given template number
9#[derive(Debug, Clone, PartialEq)]
10pub enum Grib2Template5 {
11 /// Data Representation Template 5.0 - Grid point data - simple packing
12 Grib2Template50(Grib2Template50),
13 /// Data Representation Template 5.2 – Complex packing (no spatial differencing).
14 Grib2Template52(Grib2Template52),
15 /// Data Representation Template 5.3 – Complex packing and spatial differencing.
16 Grib2Template53(Grib2Template53),
17 /// Data Representation Template 5.40
18 Grib2Template540(Grib2Template540),
19 /// Data Representation Template 5.50 - Spectral data - simple packing
20 Grib2Template550(Grib2Template550),
21 /// Data Representation Template 5.51 - Spectral data - complex packing
22 Grib2Template551(Grib2Template551),
23}
24impl Grib2Template5 {
25 /// Creates a new instance of Grib2Template50
26 ///
27 /// ## Parameters
28 /// - `template`: Template number
29 ///
30 /// ## Returns
31 /// Template generator
32 pub fn new<T: Reader>(section: &T, template: u8) -> Self {
33 match template {
34 0 => Grib2Template5::Grib2Template50(Grib2Template50::new(section)),
35 2 => Grib2Template5::Grib2Template52(Grib2Template52::new(section)),
36 3 => Grib2Template5::Grib2Template53(Grib2Template53::new(section)),
37 40 => Grib2Template5::Grib2Template540(Grib2Template540::new(section)),
38 50 => Grib2Template5::Grib2Template550(Grib2Template550::new(section)),
39 51 => Grib2Template5::Grib2Template551(Grib2Template551::new(section)),
40 _ => panic!("Template 5.{template} not defined"),
41 }
42 }
43 /// Get the simple packing template
44 pub fn get_simple_packing_template(&self) -> Option<&Grib2Template50> {
45 match self {
46 Grib2Template5::Grib2Template50(template) => Some(template),
47 _ => None,
48 }
49 }
50}
51
52/// # Data Representation Template 5.0 - Grid point data - simple packing
53///
54/// [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-0.shtml)
55///
56/// ## Notes
57/// - Negative values of E or D shall be represented according to Regulation [92.1.5](https://codes.ecmwf.int/grib/format/grib2/regulations/).
58///
59/// ## Returns
60/// Description of how to decode simple unpacked data
61#[derive(Debug, Clone, PartialEq)]
62pub struct Grib2Template50 {
63 /// Reference value (R) (IEEE 32-bit floating-point value)
64 pub reference_value: f32,
65 /// Binary scale factor (E)
66 pub binary_scale_factor: i32,
67 /// Decimal scale factor (D)
68 pub decimal_scale_factor: i32,
69 /// Number of bits used for each packed value for simple packing, or for each group reference value for complex packing or spatial differencing
70 pub number_of_bits: u8,
71 /// Type of original field values (see Code [Table 5.1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml))
72 pub original_type: Grib2Table5_1,
73}
74impl Grib2Template50 {
75 /// Creates a new instance of Grib2Template50
76 pub fn new<T: Reader>(section: &T) -> Self {
77 let original_type = section.uint8(Some(20));
78 let mut binary_scale_factor = (section.uint16_be(Some(15)) & 0x7fff) as i32;
79 if section.uint16_be(Some(15)) >> 15 > 0 {
80 binary_scale_factor *= -1;
81 }
82 let mut decimal_scale_factor = (section.uint16_be(Some(17)) & 0x7fff) as i32;
83 if section.uint16_be(Some(17)) >> 15 > 0 {
84 decimal_scale_factor *= -1;
85 }
86
87 Self {
88 reference_value: section.f32_be(Some(11)),
89 binary_scale_factor,
90 decimal_scale_factor,
91 number_of_bits: section.uint8(Some(19)),
92 original_type: original_type.into(),
93 }
94 }
95}
96
97/// # Data Representation Template 5.2 – Complex packing (no spatial differencing).
98///
99/// Reads and parses the metadata fields defined by GRIB2 Template 5.2.
100/// For most templates, details of the packing process are described in Regulation 92.9.4.
101///
102/// See also:
103/// - [Template 5.2 documentation](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-2.shtml)
104/// - [Data template 7.2 for complementary info](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp7-2.shtml)
105#[derive(Debug, Clone, PartialEq)]
106pub struct Grib2Template52 {
107 /// Reference value (R) (IEEE 32-bit floating-point). Octets 12–15 in the GRIB2 documentation.
108 pub reference_value: f32,
109 /// Binary scale factor (E). Octets 16–17.
110 pub binary_scale_factor: i32,
111 /// Decimal scale factor (D). Octets 18–19.
112 pub decimal_scale_factor: i32,
113 /// Number of bits per packed value for simple packing, or per group reference for
114 /// complex packing. Octet 20 in the documentation.
115 pub number_of_bits: u8,
116 /// Type of original field values. See Code Table 5.1. Octet 21.
117 pub original_type: Grib2Table5_1,
118
119 // Fields specific to complex packing (no spatial differencing):
120 /// Group splitting method used. See Code Table 5.4. Octet 22.
121 pub group_splitting_method: Grib2Table5_4,
122 /// Missing value management. See Code Table 5.5. Octet 23.
123 pub missing_value_management: Grib2Table5_5,
124 /// Primary missing value substitute. Octets 24–27.
125 pub primary_missing_value_substitute: u32,
126 /// Secondary missing value substitute. Octets 28–31.
127 pub secondary_missing_value_substitute: u32,
128 /// Number of groups of data values (NG). Octets 32–35.
129 pub number_of_groups: u32,
130 /// Reference for group widths. Octet 36.
131 /// The group width is the number of bits used for every value in a group.
132 pub reference_for_group_widths: u8,
133 /// Number of bits used for the group widths (after subtracting the reference value). Octet 37.
134 pub group_widths_bits: u8,
135 /// Reference for group lengths. Octets 38–41.
136 /// The group length (L) is the number of values in a group.
137 pub reference_for_group_lengths: u32,
138 /// Length increment for group lengths. Octet 42.
139 /// Used in the formula: Lₙ = ref + Kₙ × len_inc.
140 pub group_length_factor: u8,
141 /// True length of the last group. Octets 43–46.
142 /// A special-case group length if the sequence doesn’t fit the formula.
143 pub true_length_of_last_group: u32,
144 /// Number of bits used for scaled group lengths (after subtracting ref
145 /// and dividing by the length increment). Octet 47.
146 pub n_bits_group_length: u8,
147}
148impl Grib2Template52 {
149 /// Creates a new instance of Grib2Template52
150 ///
151 /// ## Parameters
152 /// - `section`: Binary reader providing access to the section data.
153 ///
154 /// ## Returns
155 /// Object containing the fields of Template 5.2.
156 pub fn new<T: Reader>(section: &T) -> Self {
157 // Binary and decimal scale factors can be negative.
158 // They are stored with the sign bit in the high-order bit (bit 15).
159 let original_type_code = section.uint8(Some(20));
160
161 let mut binary_scale_factor = (section.uint16_be(Some(15)) & 0x7fff) as i32;
162 if section.uint16_be(Some(15)) >> 15 > 0 {
163 binary_scale_factor *= -1;
164 }
165 let mut decimal_scale_factor = (section.uint16_be(Some(17)) & 0x7fff) as i32;
166 if section.uint16_be(Some(17)) >> 15 > 0 {
167 decimal_scale_factor *= -1;
168 }
169 // Fields unique to 5.2 (similar to 5.3, but no spatial differencing):
170 let group_splitting_method_code = section.uint8(Some(21)); // Octet 22
171 let missing_value_management_code = section.uint8(Some(22)); // Octet 23
172 let primary_missing_value_substitute = section.uint32_be(Some(23)); // Octets 24–27
173 let secondary_missing_value_substitute = section.uint32_be(Some(27)); // Octets 28–31
174 let number_of_groups = section.uint32_be(Some(31)); // Octets 32–35
175 let reference_for_group_widths = section.uint8(Some(35)); // Octet 36
176 let group_widths_bits = section.uint8(Some(36)); // Octet 37
177 let reference_for_group_lengths = section.uint32_be(Some(37)); // Octets 38–41
178 let group_length_factor = section.uint8(Some(41)); // Octet 42
179 let true_length_of_last_group = section.uint32_be(Some(42)); // Octets 43–46
180 let n_bits_group_length = section.uint8(Some(46)); // Octet 47
181
182 Self {
183 reference_value: section.f32_be(Some(11)),
184 binary_scale_factor,
185 decimal_scale_factor,
186 number_of_bits: section.uint8(Some(19)),
187 original_type: original_type_code.into(),
188 group_splitting_method: group_splitting_method_code.into(),
189 missing_value_management: missing_value_management_code.into(),
190 primary_missing_value_substitute,
191 secondary_missing_value_substitute,
192 number_of_groups,
193 reference_for_group_widths,
194 group_widths_bits,
195 reference_for_group_lengths,
196 group_length_factor,
197 true_length_of_last_group,
198 n_bits_group_length,
199 }
200 }
201}
202
203/// # Data Representation Template 5.3 – Complex packing and spatial differencing.
204///
205/// Reads and parses the metadata fields defined by GRIB2 Template 5.3.
206/// For most templates, details of the packing process are described in Regulation 92.9.4.
207///
208/// See also:
209/// - [GRIB2 Template 5.3 documentation](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-3.shtml)
210/// - [Data template 7.3 and associated notes](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp7-3.shtml)
211/// - Spatial differencing (Regulation 92.9.4).
212#[derive(Debug, Clone, PartialEq)]
213pub struct Grib2Template53 {
214 /// Reference value (R) (IEEE 32-bit floating-point).
215 /// Octets 12–15 in the GRIB2 documentation.
216 pub reference_value: f32,
217 /// Binary scale factor (E). Octets 16–17.
218 pub binary_scale_factor: i32,
219 /// Decimal scale factor (D). Octets 18–19.
220 pub decimal_scale_factor: i32,
221 /// Number of bits per packed value for simple packing,
222 /// or per group reference for complex packing.
223 /// Octet 20 in the documentation.
224 pub number_of_bits: u8,
225 /// Type of original field values. See Code Table 5.1. Octet 21.
226 pub original_type: Grib2Table5_1,
227
228 // Fields specific to complex packing and spatial differencing:
229 /// Group splitting method used. See Code Table 5.4. Octet 22.
230 pub group_splitting_method: Grib2Table5_4,
231 /// Missing value management. See Code Table 5.5. Octet 23.
232 pub missing_value_management: Grib2Table5_5,
233 /// Primary missing value substitute. Octets 24–27.
234 pub primary_missing_value_substitute: u32,
235 /// Secondary missing value substitute. Octets 28–31.
236 pub secondary_missing_value_substitute: u32,
237 /// Number of groups of data values (NG). Octets 32–35.
238 pub number_of_groups: u32,
239 /// Reference for group widths. Octet 36.
240 /// The group width is the number of bits used for every value in a group.
241 pub reference_for_group_widths: u8,
242 /// Number of bits used for the group widths (after subtracting the reference value).
243 /// Octet 37.
244 pub group_widths_bits: u8,
245 /// Reference for group lengths. Octets 38–41.
246 /// The group length (L) is the number of values in a group.
247 pub reference_for_group_lengths: u32,
248 /// Length increment for group lengths. Octet 42.
249 /// Used in the formula: Lₙ = ref + Kₙ × len_inc.
250 pub group_length_factor: u8,
251 /// True length of the last group. Octets 43–46.
252 /// A special-case group length if the sequence doesn’t fit the formula.
253 pub true_length_of_last_group: u32,
254 /// Number of bits used for scaled group lengths (after subtracting ref
255 /// and dividing by the length increment). Octet 47.
256 pub n_bits_group_length: u8,
257 /// Order of spatial difference. See Code Table 5.6. Octet 48.
258 pub order_of_spatial_difference: Grib2Table5_6,
259 /// Number of extra descriptor octets needed for spatial differencing
260 /// (octets 6–ww in data template 7.3). Octet 49.
261 pub extra_descriptor_octets: u8,
262}
263impl Grib2Template53 {
264 /// Create a new instance of Grib2Template53
265 ///
266 /// ## Parameters
267 /// - `section`: Binary reader providing access to the section data
268 ///
269 /// ## Returns
270 /// Object containing the fields of Template 5.3
271 pub fn new<T: Reader>(section: &T) -> Self {
272 // Binary and decimal scale factors can be negative.
273 // They are stored with the sign bit in the high-order bit (bit 15).
274 let original_type_code = section.uint8(Some(20));
275 let mut binary_scale_factor = (section.uint16_be(Some(15)) & 0x7fff) as i32;
276 if section.uint16_be(Some(15)) >> 15 > 0 {
277 binary_scale_factor *= -1;
278 }
279 let mut decimal_scale_factor = (section.uint16_be(Some(17)) & 0x7fff) as i32;
280 if section.uint16_be(Some(17)) >> 15 > 0 {
281 decimal_scale_factor *= -1;
282 }
283 // New fields introduced by Template 5.3
284 let group_splitting_method_code = section.uint8(Some(21));
285 let missing_value_management_code = section.uint8(Some(22));
286 let primary_missing_value_substitute = section.uint32_be(Some(23));
287 let secondary_missing_value_substitute = section.uint32_be(Some(27));
288 let number_of_groups = section.uint32_be(Some(31));
289 let reference_for_group_widths = section.uint8(Some(35));
290 let group_widths_bits = section.uint8(Some(36));
291 let reference_for_group_lengths = section.uint32_be(Some(37));
292 let group_length_factor = section.uint8(Some(41));
293 let true_length_of_last_group = section.uint32_be(Some(42));
294 let n_bits_group_length = section.uint8(Some(46));
295 let order_of_spatial_difference_code = section.uint8(Some(47));
296 let extra_descriptor_octets = section.uint8(Some(48));
297
298 Self {
299 reference_value: section.f32_be(Some(11)),
300 binary_scale_factor,
301 decimal_scale_factor,
302 number_of_bits: section.uint8(Some(19)),
303 original_type: original_type_code.into(),
304 group_splitting_method: group_splitting_method_code.into(),
305 missing_value_management: missing_value_management_code.into(),
306 primary_missing_value_substitute,
307 secondary_missing_value_substitute,
308 number_of_groups,
309 reference_for_group_widths,
310 group_widths_bits,
311 reference_for_group_lengths,
312 group_length_factor,
313 true_length_of_last_group,
314 n_bits_group_length,
315 order_of_spatial_difference: order_of_spatial_difference_code.into(),
316 extra_descriptor_octets,
317 }
318 }
319}
320
321/// Data Representation Template 5.40
322///
323/// [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-40.shtml)
324#[derive(Debug, Clone, PartialEq)]
325pub struct Grib2Template540 {
326 /// Reference value (R) (IEEE 32-bit floating-point value) */
327 pub reference_value: f32,
328 /// Binary scale factor (E) */
329 pub binary_scale_factor: i16,
330 /// Decimal scale factor (D) */
331 pub decimal_scale_factor: i16,
332 /// Number of bits used for each packed value for simple packing, or for each group reference value for complex packing or spatial differencing */
333 pub number_of_bits: u8,
334 /// Type of original field values (see Code [Table 5.1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml)) */
335 pub original_type: Grib2Table5_1,
336 /// Type of Compression used. (see [Code Table 5.40](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-40.shtml)) */
337 pub compression_type: Grib2Table5_40,
338 /// Target compression ratio, M:1 (with respect to the bit-depth specified in octet 20),
339 /// when octet 22 indicates Lossy Compression. Otherwise, set to missing.
340 pub compression_ratio: u8,
341}
342impl Grib2Template540 {
343 /// Create a new instance of Grib2Template540
344 ///
345 /// ## Parameters
346 /// - `section`: The raw section data to parse
347 ///
348 /// ## Returns
349 /// Parsed Data Representation Information
350 pub fn new<T: Reader>(section: &T) -> Self {
351 let original_type_code = section.uint8(Some(20));
352 let compression_type = section.uint8(Some(21));
353 Self {
354 reference_value: section.f32_be(Some(11)),
355 binary_scale_factor: section.int16_be(Some(15)),
356 decimal_scale_factor: section.int16_be(Some(17)),
357 number_of_bits: section.uint8(Some(19)),
358 original_type: original_type_code.into(),
359 compression_type: compression_type.into(),
360 compression_ratio: section.uint8(Some(22)),
361 }
362 }
363}
364// export function grib2Template540(section: Reader) {
365// }
366
367/// # Data Representation Template 5.50 - Spectral data - simple packing
368///
369/// [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-50.shtml)
370///
371/// ## Notes
372/// - Removal of the real part of (0.0) coefficient from packed data is intended to reduce the
373/// variability of the coefficients, in order to improve packing accuracy.
374/// - For some spectral representations, the (0.0) coefficient represents the mean value of the
375/// parameter represented.
376/// - Negative values of E or D shall be represented according to Regulation [92.1.5](https://codes.ecmwf.int/grib/format/grib2/regulations/).
377///
378/// ## Returns
379/// Description of how to decode simple unpacked data
380#[derive(Debug, Clone, PartialEq)]
381pub struct Grib2Template550 {
382 /// Reference value (R) (IEEE 32-bit floating-point value)
383 pub reference_value: f32,
384 /// Binary scale factor (E)
385 pub binary_scale_factor: i32,
386 /// Decimal scale factor (D)
387 pub decimal_scale_factor: i32,
388 /// Number of bits used for each packed value for simple packing, or for each group reference value for complex packing or spatial differencing
389 pub number_of_bits: u8,
390 /// Type of original field values (see Code [Table 5.1](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_table5-1.shtml))
391 pub real_part_coefficient_type: f32,
392}
393impl Grib2Template550 {
394 /// Create a new instance of Grib2Template540
395 pub fn new<T: Reader>(section: &T) -> Self {
396 let mut binary_scale_factor = (section.uint16_be(Some(15)) & 0x7fff) as i32;
397 if section.uint16_be(Some(15)) >> 15 > 0 {
398 binary_scale_factor *= -1;
399 }
400 let mut decimal_scale_factor = (section.uint16_be(Some(17)) & 0x7fff) as i32;
401 if section.uint16_be(Some(17)) >> 15 > 0 {
402 decimal_scale_factor *= -1;
403 }
404
405 Self {
406 reference_value: section.f32_be(Some(11)),
407 binary_scale_factor,
408 decimal_scale_factor,
409 number_of_bits: section.uint8(Some(19)),
410 real_part_coefficient_type: section.f32_be(Some(20)),
411 }
412 }
413}
414
415/// # Data Representation Template 5.51 - Spectral data - complex packing
416///
417/// [Read more...](https://www.nco.ncep.noaa.gov/pmb/docs/grib2/grib2_doc/grib2_temp5-51.shtml)
418///
419/// ## Notes
420/// - The unpacked subset is a set of values defined in the same way as the full set of values
421/// (on a spectrum limited to j_s, k_s and m_s ), but on which scaling and packing are not applied.
422/// Associated values are stored in octets 6 onwards of section 7.
423/// - The remaining coefficients are multiplied by `(n x (n+1))p` , scaled and packed. The operator
424/// associated with this multiplication is derived from the Laplacian operator on the sphere.
425/// - The retrieval formula for a coefficient of wave number n is then: `Y = (R+X x 2e ) x 10-d x (n x(n+1))-p`
426/// where X is the packed scaled value associated with the coefficient.
427///
428/// ## Returns
429/// Description of how to decode simple unpacked data
430#[derive(Debug, Clone, PartialEq)]
431pub struct Grib2Template551 {
432 /// Reference value (R) (IEEE 32-bit floating-point value)
433 pub reference_value: f32,
434 /// Binary scale factor (E)
435 pub binary_scale_factor: i32,
436 /// Decimal scale factor (D)
437 pub decimal_scale_factor: i32,
438 /// Number of bits used for each packed value for simple packing, or for each group reference value for complex packing or spatial differencing
439 pub number_of_bits: u8,
440 /// P ― Laplacian scaling factor (expressed in 10^-6 units)
441 pub p: f32,
442 /// j_s ― pentagonal resolution parameter of the unpacked subset (see Note1)
443 pub j_s: i16,
444 /// k_s ― pentagonal resolution parameter of the unpacked subset (see Note1)
445 pub k_s: i16,
446 /// m_s ― pentagonal resolution parameter of the unpacked subset (see Note1)
447 pub m_s: i16,
448 /// t_s ― total number of values in the unpacked subset (see Note1)
449 pub t_s: i32,
450 /// Precision of the unpacked subset (see Code Table 5.7)
451 pub precision: Grib2Table5_7,
452}
453impl Grib2Template551 {
454 /// Create a new instance of Grib2Template540
455 pub fn new<T: Reader>(section: &T) -> Self {
456 let mut binary_scale_factor = (section.uint16_be(Some(15)) & 0x7fff) as i32;
457 if section.uint16_be(Some(15)) >> 15 > 0 {
458 binary_scale_factor *= -1;
459 }
460 let mut decimal_scale_factor = (section.uint16_be(Some(17)) & 0x7fff) as i32;
461 if section.uint16_be(Some(17)) >> 15 > 0 {
462 decimal_scale_factor *= -1;
463 }
464 let precision_code = section.uint8(Some(34));
465
466 Self {
467 reference_value: section.f32_be(Some(11)),
468 binary_scale_factor,
469 decimal_scale_factor,
470 number_of_bits: section.uint8(Some(19)),
471 p: section.f32_be(Some(20)),
472 j_s: section.int16_be(Some(24)),
473 k_s: section.int16_be(Some(26)),
474 m_s: section.int16_be(Some(28)),
475 t_s: section.int32_be(Some(30)),
476 precision: precision_code.into(),
477 }
478 }
479}