bufr2synop 0.24.0
bufr2tac_x08.c
Go to the documentation of this file.
1/***************************************************************************
2 * Copyright (C) 2013-2022 by Guillermo Ballester Valor *
3 * gbv@ogimet.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20/*!
21 \file bufr2tac_x08.c
22 \brief decodes the descriptors with X = 08 (Significance Qualifiers)
23
24 As there is no significance information in synop we use this descriptors as
25 off/on interruptor.
26*/
27#include "bufr2tac.h"
28
29/*!
30 \fn int syn_parse_x08 ( struct synop_chunks *syn, struct bufr2tac_subset_state *s )
31 \brief Parse a expanded descriptor with X = 08
32 \param syn pointer to a struct \ref synop_chunks where to set the results
33 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
34
35 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
36*/
37int syn_parse_x08 ( struct synop_chunks *syn, struct bufr2tac_subset_state *s )
38{
39 if ( syn == NULL )
40 {
41 return 1;
42 }
43
44 switch ( s->a->desc.y )
45 {
46 case 2: // 0 08 002 . Vertical significance (surface observations)
48 {
49 s->clayer = 0; // clean vertical significance;
50 return 0;
51 }
52
53 if ( s->ival == 21 || s->ival == 1 )
54 {
55 s->clayer = 1; // first cloud layer or first no CB layer
56 }
57 else if ( s->ival == 22 || s->ival == 2 )
58 {
59 s->clayer = 2; // second cloud layer or second no CB layer
60 }
61 else if ( s->ival == 23 || s->ival == 3 )
62 {
63 s->clayer = 3; // third cloud layer or third no CB layer
64 }
65 else if ( s->ival == 24 || s->ival == 4 )
66 {
67 s->clayer = 4; // fourth cloud layer or CB layer
68 }
69 else if ( s->ival == 10 )
70 {
71 s->clayer = -1; // base of cloud layer below level station and top over level station
72 }
73 else if ( s->ival == 11 )
74 {
75 s->clayer = -2; // base and top of cloud layer below level station
76 }
77 else if ( s->ival <= 9 && s->ival >= 7 )
78 {
79 s->clayer = s->ival;
80 }
81 else if ( s->ival == 5 || s->ival == 62 )
82 {
83 // 5 should be used for N = 9 and 62 for N = 0
84 s->clayer = s->ival;
85 }
86 break;
87
88 case 22: // 0 08 022 . Total number
89 case 23: // 0 08 023 . First-order statistics
90 case 24: // 0 08 024 . Difference statistics
92 {
93 return 0;
94 }
95 if ( s->isq )
96 {
97 s->isq = 0;
98 }
99 else
100 {
101 s->isq = 1;
102 }
103 break;
104
105 default:
106 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
107 bufr2tac_set_error ( s, 0, "syn_parse_x08()", "Descriptor not parsed" );
108 break;
109 }
110 return 0;
111}
112
113/*!
114 \fn int buoy_parse_x08 ( struct buoy_chunks *b, struct bufr2tac_subset_state *s )
115 \brief Parse a expanded descriptor with X = 08
116 \param b pointer to a struct \ref buoy_chunks where to set the results
117 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
118
119 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
120*/
122{
123 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
124 {
125 return 0;
126 }
127
128 if ( b == NULL )
129 {
130 return 1;
131 }
132
133 switch ( s->a->desc.y )
134 {
135 case 22: // 0 08 022 . Total number
136 case 23: // 0 08 023 . First-order statistics
137 case 24: // 0 08 024 . Difference statistics
138 if ( s->isq )
139 {
140 s->isq = 0;
141 }
142 else
143 {
144 s->isq = 1;
145 }
146 break;
147
148 default:
149 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
150 bufr2tac_set_error ( s, 0, "buoy_parse_x08()", "Descriptor not parsed" );
151 break;
152 }
153 return 0;
154}
155
156/*!
157 \fn int climat_parse_x08 ( struct climat_chunks *c, struct bufr2tac_subset_state *s )
158 \brief Parse a expanded descriptor with X = 08
159 \param c pointer to a struct \ref climat_chunks where to set the results
160 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
161
162 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
163*/
165{
166 char caux[16];
167
168 if ( c == NULL )
169 {
170 return 1;
171 }
172
173 switch ( s->a->desc.y )
174 {
175 case 20: // 0 08 020 . Total number of missing entities (days)
176 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
177 {
178 return 0;
179 }
180 if ( s->is_normal == 0 )
181 {
182 switch ( s->isq_val )
183 {
184 // days of missing data
185 case 1: // pressure
186 sprintf ( c->s1.mpmp, "%02d", s->ival );
187 c->mask |= CLIMAT_SEC1;
188 break;
189 case 2: // temperature
190 sprintf ( c->s1.mtmt, "%02d", s->ival );
191 c->mask |= CLIMAT_SEC1;
192 break;
193 case 4: // vapour pressure
194 sprintf ( c->s1.meme, "%02d", s->ival );
195 c->mask |= CLIMAT_SEC1;
196 break;
197 case 5: // precipitation
198 sprintf ( c->s1.mrmr, "%02d", s->ival );
199 c->mask |= CLIMAT_SEC1;
200 break;
201 case 6: // sunshine duration
202 sprintf ( c->s1.msms, "%02d", s->ival );
203 c->mask |= CLIMAT_SEC1;
204 break;
205 case 7: // Maximum temperature
206 if ( s->ival < 10 )
207 {
208 sprintf ( caux, "%d", s->ival );
209 c->s1.mtx[0] = caux[0];
210 c->s1.mtx[1] = 0;
211 }
212 else
213 {
214 c->s1.mtx[0] = '9';
215 }
216 c->mask |= CLIMAT_SEC1;
217 break;
218 case 8: // Minimum temperature
219 if ( s->ival < 10 )
220 {
221 sprintf ( caux, "%d", s->ival );
222 c->s1.mtn[0] = caux[0];
223 c->s1.mtn[1] = 0;
224 }
225 else
226 {
227 c->s1.mtn[0] = '9';
228 }
229 c->mask |= CLIMAT_SEC1;
230 break;
231 default:
232 break;
233 }
234 }
235 else
236 {
237 switch ( s->isq_val )
238 {
239 // years of missing data
240 case 1: // pressure
241 sprintf ( c->s2.ypyp, "%02d", s->ival );
242 c->mask |= CLIMAT_SEC2;
243 break;
244 case 2: // temperature
245 sprintf ( c->s2.ytyt, "%02d", s->ival );
246 c->mask |= CLIMAT_SEC2;
247 break;
248 case 3: // extreme temperature
249 sprintf ( c->s2.ytxytx, "%02d", s->ival );
250 c->mask |= CLIMAT_SEC2;
251 break;
252 case 4: // vapour pressure
253 sprintf ( c->s2.yeye, "%02d", s->ival );
254 c->mask |= CLIMAT_SEC2;
255 break;
256 case 5: // precipitation
257 sprintf ( c->s2.yryr, "%02d", s->ival );
258 c->mask |= CLIMAT_SEC2;
259 break;
260 case 6: // sunshine duration
261 sprintf ( c->s2.ysys, "%02d", s->ival );
262 c->mask |= CLIMAT_SEC2;
263 break;
264 default:
265 break;
266 }
267 }
268 break;
269
270 case 22:
271 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
272 {
273 return 0;
274 }
275 switch ( s->isq_val )
276 {
277 case 0:
278 sprintf ( c->s3.f10, "%02d", s->ival );
279 c->mask |= CLIMAT_SEC3;
280 break;
281 case 1:
282 sprintf ( c->s3.f20, "%02d", s->ival );
283 c->mask |= CLIMAT_SEC3;
284 break;
285 case 2:
286 sprintf ( c->s3.f30, "%02d", s->ival );
287 c->mask |= CLIMAT_SEC3;
288 break;
289 case 3:
290 sprintf ( c->s3.Tx0, "%02d", s->ival );
291 c->mask |= CLIMAT_SEC3;
292 break;
293 case 4:
294 sprintf ( c->s3.T25, "%02d", s->ival );
295 c->mask |= CLIMAT_SEC3;
296 break;
297 case 5:
298 sprintf ( c->s3.T30, "%02d", s->ival );
299 c->mask |= CLIMAT_SEC3;
300 break;
301 case 6:
302 sprintf ( c->s3.T35, "%02d", s->ival );
303 c->mask |= CLIMAT_SEC3;
304 break;
305 case 7:
306 sprintf ( c->s3.T40, "%02d", s->ival );
307 c->mask |= CLIMAT_SEC3;
308 break;
309 case 8:
310 sprintf ( c->s3.Tn0, "%02d", s->ival );
311 c->mask |= CLIMAT_SEC3;
312 break;
313 case 10:
314 sprintf ( c->s3.R01, "%02d", s->ival );
315 c->mask |= CLIMAT_SEC3;
316 break;
317 case 11:
318 sprintf ( c->s3.R05, "%02d", s->ival );
319 c->mask |= CLIMAT_SEC3;
320 break;
321 case 12:
322 sprintf ( c->s3.R10, "%02d", s->ival );
323 c->mask |= CLIMAT_SEC3;
324 break;
325 case 13:
326 sprintf ( c->s3.R50, "%02d", s->ival );
327 c->mask |= CLIMAT_SEC3;
328 break;
329 case 14:
330 sprintf ( c->s3.R100, "%02d", s->ival );
331 c->mask |= CLIMAT_SEC3;
332 break;
333 case 15:
334 sprintf ( c->s3.R150, "%02d", s->ival );
335 c->mask |= CLIMAT_SEC3;
336 break;
337 case 16:
338 sprintf ( c->s3.s00, "%02d", s->ival );
339 c->mask |= CLIMAT_SEC3;
340 break;
341 case 17:
342 sprintf ( c->s3.s01, "%02d", s->ival );
343 c->mask |= CLIMAT_SEC3;
344 break;
345 case 18:
346 sprintf ( c->s3.s10, "%02d", s->ival );
347 c->mask |= CLIMAT_SEC3;
348 break;
349 case 19:
350 sprintf ( c->s3.s50, "%02d", s->ival );
351 c->mask |= CLIMAT_SEC3;
352 break;
353 case 20:
354 sprintf ( c->s3.V1, "%02d", s->ival );
355 c->mask |= CLIMAT_SEC3;
356 break;
357 case 21:
358 sprintf ( c->s3.V2, "%02d", s->ival );
359 c->mask |= CLIMAT_SEC3;
360 break;
361 case 22:
362 sprintf ( c->s3.V3, "%02d", s->ival );
363 c->mask |= CLIMAT_SEC3;
364 break;
365 case 23:
366 sprintf ( c->s4.Dgr, "%02d", s->ival );
367 c->mask |= CLIMAT_SEC4;
368 break;
369 case 24:
370 sprintf ( c->s4.Dts, "%02d", s->ival );
371 c->mask |= CLIMAT_SEC4;
372 break;
373 default:
374 break;
375 }
376 break;
377
378 case 23: // 0 08 023 . First-order statistics.
379 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
380 {
381 s->isq = 0;
382 s->isq_val = 0;
383 }
384 else
385 {
386 s->isq = 1;
387 s->isq_val = s->ival;
388 }
389 break;
390
391 case 50: // 0 08 050 . Qualifier for number of missing values in calculation of statistic
392 case 52: // 0 08 052 . Conditions for which number of days of occurrence follows
393 case 53: // 0 08 053 . Day of occurrence qualifier (= 0; on 1 day only) (= 1; on 2 or more days)
394 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
395 {
396 s->isq = 0;
397 s->isq_val = -1;
398 return 0;
399 }
400 s->isq = 1;
401 s->isq_val = s->ival;
402 break;
403
404 default:
405 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
406 bufr2tac_set_error ( s, 0, "climat_parse_x08()", "Descriptor not parsed" );
407 break;
408 }
409
410 return 0;
411}
412
413/*!
414 \fn int temp_parse_x08 ( struct temp_chunks *t, struct bufr2tac_subset_state *s )
415 \brief Parse a expanded descriptor with X = 08
416 \param t pointer to a struct \ref temp_chunks where to set the results
417 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
418
419 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
420*/
422{
423 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
424 {
425 return 0;
426 }
427
428 if ( t == NULL )
429 {
430 return 1;
431 }
432
433 switch ( s->a->desc.y )
434 {
435 case 2: // 0 08 002.
436 // this is to mark of the begining or end of cloud surface data
437 if ( s->isq == 0 )
438 {
439 s->isq = 1;
440 }
441 else
442 {
443 s->isq = 0;
444 }
445 break;
446
447 case 21: // 0 08 021. Time significance
448 if ( s->ival != 18 )
449 {
450 return 1; // it should be 18 (launch date/time)
451 }
452 break;
453
454 case 42: // 0 08 042. Extended vertical sounding significance
455 if ( s->rep > 0 && s->r->n > 0 )
456 {
457 s->r->raw[s->r->n - 1].flags = s->ival;
458 }
459 else if ( s->w->n > 0 )
460 {
461 // wind shear case
462 s->w->raw[s->w->n - 1].flags = s->ival;
463 }
464 break;
465
466 default:
467 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
468 bufr2tac_set_error ( s, 0, "temp_parse_x08()", "Descriptor not parsed" );
469 break;
470 }
471 return 0;
472}
int BUFR2TAC_DEBUG_LEVEL
Definition: bufr2tac.c:31
Include header file for binary bufr2tac.
int bufr2tac_set_error(struct bufr2tac_subset_state *s, int severity, char *origin, char *explanation)
int syn_parse_x08(struct synop_chunks *syn, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 08.
Definition: bufr2tac_x08.c:37
int buoy_parse_x08(struct buoy_chunks *b, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 08.
Definition: bufr2tac_x08.c:121
int climat_parse_x08(struct climat_chunks *c, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 08.
Definition: bufr2tac_x08.c:164
int temp_parse_x08(struct temp_chunks *t, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 08.
Definition: bufr2tac_x08.c:421
#define DESCRIPTOR_VALUE_MISSING
Bit mask for a missing value in a struct bufr_atom_data.
Definition: bufrdeco.h:140
#define CLIMAT_SEC4
mask bit meaning section 4 of climat is solicited to or parsed with success
Definition: metclimat.h:52
#define CLIMAT_SEC3
mask bit meaning section 3 of climat is solicited to or parsed with success
Definition: metclimat.h:47
#define CLIMAT_SEC2
mask bit meaning section 2 of climat is solicited to or parsed with success
Definition: metclimat.h:42
#define CLIMAT_SEC1
mask bit meaning section 1 of climat is solicited to or parsed with success
Definition: metclimat.h:37
stores information needed to parse a sequential list of expanded descriptors for a subset
Definition: bufr2tac.h:246
struct temp_raw_wind_shear_data * w
Definition: bufr2tac.h:286
struct bufr_atom_data * a
Definition: bufr2tac.h:249
struct temp_raw_data * r
Definition: bufr2tac.h:285
uint32_t mask
Definition: bufrdeco.h:437
struct bufr_descriptor desc
Definition: bufrdeco.h:436
contains all possible substrings from a synop report is parsed with success
Definition: metbuoy.h:197
contains all possible substrings from a synop report is parsed with success
Definition: metclimat.h:213
struct climat_sec4 s4
Definition: metclimat.h:221
struct climat_sec1 s1
Definition: metclimat.h:218
struct climat_sec2 s2
Definition: metclimat.h:219
struct climat_sec3 s3
Definition: metclimat.h:220
char mtmt[4]
Definition: metclimat.h:98
char mtx[2]
Definition: metclimat.h:99
char mrmr[4]
Definition: metclimat.h:102
char mtn[2]
Definition: metclimat.h:100
char mpmp[4]
Definition: metclimat.h:97
char msms[4]
Definition: metclimat.h:103
char meme[4]
Definition: metclimat.h:101
char yryr[4]
Definition: metclimat.h:130
char ytxytx[4]
Definition: metclimat.h:128
char ypyp[4]
Definition: metclimat.h:126
char ytyt[4]
Definition: metclimat.h:127
char ysys[4]
Definition: metclimat.h:131
char yeye[4]
Definition: metclimat.h:129
char Tx0[4]
Definition: metclimat.h:144
char T25[4]
Definition: metclimat.h:139
char R50[4]
Definition: metclimat.h:148
char f20[4]
Definition: metclimat.h:156
char f30[4]
Definition: metclimat.h:157
char s10[4]
Definition: metclimat.h:153
char R150[4]
Definition: metclimat.h:150
char T35[4]
Definition: metclimat.h:141
char Tn0[4]
Definition: metclimat.h:143
char V2[4]
Definition: metclimat.h:159
char R100[4]
Definition: metclimat.h:149
char s01[4]
Definition: metclimat.h:152
char R10[4]
Definition: metclimat.h:147
char T30[4]
Definition: metclimat.h:140
char R05[4]
Definition: metclimat.h:146
char s00[4]
Definition: metclimat.h:151
char V1[4]
Definition: metclimat.h:158
char V3[4]
Definition: metclimat.h:160
char T40[4]
Definition: metclimat.h:142
char R01[4]
Definition: metclimat.h:145
char s50[4]
Definition: metclimat.h:154
char f10[4]
Definition: metclimat.h:155
char Dgr[4]
Definition: metclimat.h:186
char Dts[4]
Definition: metclimat.h:185
contains all possible substrings from a synop report is parsed with success
Definition: metsynop.h:293
Store the whole TEMP report.
Definition: mettemp.h:511
struct temp_raw_point_data raw[TEMP_NMAX_POINTS *4]
Definition: mettemp.h:215
size_t n
Definition: mettemp.h:214
struct temp_raw_wind_shear_point raw[TEMP_NMAX_POINTS]
Definition: mettemp.h:240