bufr2synop 0.24.0
bufr2tac_x14.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_x14.c
22 \brief decodes the descriptors with X = 14 (Radiation)
23 */
24#include "bufr2tac.h"
25
26/*!
27 \fn int check_kj_m2(double val)
28 \brief Check if a radiation value can be wrote in Kj/m2 using up to 4 chars
29 \param val radiation value in J/m2
30
31 Returns 1 if success, 0 otherwise
32*/
33int check_kj_m2 ( double val )
34{
35 return ( fabs ( val ) < 1.0e7 ) ? 1 : 0;
36}
37
38/*!
39 \fn int check_j_cm2(double val)
40 \brief Check if a radiation value can be wrote in J/cm2 using up to 4 chars
41 \param val radiation value in J/m2
42
43 Returns 1 if success, 0 otherwise
44*/
45int check_j_cm2 ( double val )
46{
47 return ( fabs ( val ) < 1.0e8 ) ? 1 : 0;
48}
49
50
51/*!
52 \fn int syn_parse_x14 ( struct synop_chunks *syn, struct bufr2tac_subset_state *s )
53 \brief Parse a expanded descriptor with X = 14
54 \param syn pointer to a struct \ref synop_chunks where to set the results
55 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
56
57 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
58*/
59int syn_parse_x14 ( struct synop_chunks *syn, struct bufr2tac_subset_state *s )
60{
61 int tpd;
62
63 switch ( s->a->desc.y )
64 {
65 case 1: // 0 14 001 long-wave radiation 24 hours
66 case 11:
68 {
69 return 0;
70 }
71 strcpy ( syn->s3.j524[4], "4" );
72 sprintf ( syn->s3.FFFF24[4], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
73 syn->mask |= SYNOP_SEC3;
74 break;
75
76 case 2: // 0 14 002 Long-wave radiation
77 case 12:
79 {
80 return 0;
81 }
82 tpd = time_period_duration ( s );
83 if ( tpd == ( 24 * 3600 ) )
84 {
85 if ( check_j_cm2 ( s->val ) == 0 )
86 return 0;
87 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
88 {
89 if ( strcmp ( "06", syn->e.HH ) == 0 )
90 {
91 if ( s->ival >= 0 )
92 {
93 strcpy ( syn->s3.j524[4], "4" );
94 sprintf ( syn->s3.FFFF24[4], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
95 }
96 else
97 {
98 strcpy ( syn->s3.j524[5], "5" );
99 sprintf ( syn->s3.FFFF24[5], "%04d", ( int ) ( - ( s->val ) / 10000.0 + 0.5 ) );
100 }
101 syn->mask |= SYNOP_SEC3;
102 }
103 }
104 else
105 {
106 if ( s->ival >= 0 )
107 {
108 strcpy ( syn->s3.j524[4], "4" );
109 sprintf ( syn->s3.FFFF24[4], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
110 }
111 else
112 {
113 strcpy ( syn->s3.j524[5], "5" );
114 sprintf ( syn->s3.FFFF24[5], "%04d", ( int ) ( - ( s->val ) / 10000.0 + 0.5 ) );
115 }
116 syn->mask |= SYNOP_SEC3;
117 }
118 }
119 else if ( tpd == 3600 )
120 {
121 if ( check_kj_m2 ( s->val ) == 0 )
122 return 0;
123 if ( s->ival >= 0 )
124 {
125 strcpy ( syn->s3.j5[4], "4" );
126 sprintf ( syn->s3.FFFF[4], "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
127 }
128 else
129 {
130 strcpy ( syn->s3.j5[4], "5" );
131 sprintf ( syn->s3.FFFF[4], "%04d", ( int ) ( - ( s->val ) / 1000.0 + 0.5 ) );
132 }
133 }
134 syn->mask |= SYNOP_SEC3;
135 break;
136
137 case 3: // 0 14 003 short-wave radiation 24 hours
138 case 13:
139 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
140 {
141 return 0;
142 }
143 if ( check_j_cm2 ( s->val ) == 0 )
144 return 0;
145 strcpy ( syn->s3.j524[6], "6" );
146 sprintf ( syn->s3.FFFF24[6], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
147 syn->mask |= SYNOP_SEC3;
148 break;
149
150 case 4: // 0 14 002 short-wave radiation
151 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
152 {
153 return 0;
154 }
155 tpd = time_period_duration ( s );
156 if ( tpd == ( 24 * 3600 ) )
157 {
158 if ( check_j_cm2 ( s->val ) == 0 )
159 return 0;
160 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
161 {
162 if ( strcmp ( "06", syn->e.HH ) == 0 )
163 {
164 strcpy ( syn->s3.j524[6], "6" );
165 sprintf ( syn->s3.FFFF24[6], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
166 }
167 }
168 else
169 {
170 strcpy ( syn->s3.j524[6], "6" );
171 sprintf ( syn->s3.FFFF24[6], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
172 }
173 }
174 else if ( tpd == 3600 )
175 {
176 if ( check_kj_m2 ( s->val ) == 0 )
177 return 0;
178 strcpy ( syn->s3.j5[6], "6" );
179 sprintf ( syn->s3.FFFF[6], "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
180 }
181 syn->mask |= SYNOP_SEC3;
182 break;
183
184 case 14: // 0 14 014 Net short wave radiation integrated over period specified
185 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
186 {
187 return 0;
188 }
189 tpd = time_period_duration ( s );
190 if ( tpd == ( 24 * 3600 ) )
191 {
192 if ( check_j_cm2 ( s->val ) == 0 )
193 return 0;
194 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
195 {
196 if ( strcmp ( "06", syn->e.HH ) == 0 )
197 {
198 sprintf ( syn->s3.FFFF507, "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
199 syn->mask |= SYNOP_SEC3;
200 }
201 }
202 else
203 {
204 sprintf ( syn->s3.FFFF507, "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
205 syn->mask |= SYNOP_SEC3;
206 }
207 }
208 else if ( tpd == 3600 )
209 {
210 if ( check_kj_m2 ( s->val ) == 0 )
211 return 0;
212 sprintf ( syn->s3.FFFF407, "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
213 }
214 syn->mask |= SYNOP_SEC3;
215 break;
216
217
218 case 16: // 0 14 016 Short wave radiation integrated over period specified
219 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
220 {
221 return 0;
222 }
223 tpd = time_period_duration ( s );
224 if ( tpd == ( 24 * 3600 ) )
225 {
226 if ( check_j_cm2 ( s->val ) == 0 )
227 return 0;
228 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
229 {
230 if ( strcmp ( "06", syn->e.HH ) == 0 )
231 {
232 if ( s->ival >= 0 )
233 {
234 strcpy ( syn->s3.j524[0], "0" );
235 sprintf ( syn->s3.FFFF24[0], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
236 }
237 else
238 {
239 strcpy ( syn->s3.j524[1], "1" );
240 sprintf ( syn->s3.FFFF24[1], "%04d", ( int ) ( - ( s->val ) / 10000.0 + 0.5 ) );
241 }
242 syn->mask |= SYNOP_SEC3;
243 }
244 }
245 else
246 {
247 if ( s->ival >= 0 )
248 {
249 strcpy ( syn->s3.j524[0], "0" );
250 sprintf ( syn->s3.FFFF24[0], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
251 }
252 else
253 {
254 strcpy ( syn->s3.j524[1], "1" );
255 sprintf ( syn->s3.FFFF24[1], "%04d", ( int ) ( - ( s->val ) / 10000.0 + 0.5 ) );
256 }
257 syn->mask |= SYNOP_SEC3;
258 }
259 }
260 else if ( tpd == 3600 )
261 {
262 if ( check_kj_m2 ( s->val ) == 0 )
263 return 0;
264 if ( s->ival >= 0 )
265 {
266 strcpy ( syn->s3.j5[0], "0" );
267 sprintf ( syn->s3.FFFF[0], "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
268 }
269 else
270 {
271 strcpy ( syn->s3.j5[1], "1" );
272 sprintf ( syn->s3.FFFF[1], "%04d", ( int ) ( - ( s->val ) / 1000.0 + 0.5 ) );
273 }
274 }
275 syn->mask |= SYNOP_SEC3;
276 break;
277
278 case 28: // 0 14 028 Global solar radiation integrated over period specified
279 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
280 {
281 return 0;
282 }
283 tpd = time_period_duration ( s );
284 if ( tpd == ( 24 * 3600 ) )
285 {
286 if ( check_j_cm2 ( s->val ) == 0 )
287 return 0;
288 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
289 {
290 if ( strcmp ( "06", syn->e.HH ) == 0 )
291 {
292 strcpy ( syn->s3.j524[2], "2" );
293 sprintf ( syn->s3.FFFF24[2], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
294 syn->mask |= SYNOP_SEC3;
295 }
296 }
297 else
298 {
299 strcpy ( syn->s3.j524[2], "2" );
300 sprintf ( syn->s3.FFFF24[2], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
301 syn->mask |= SYNOP_SEC3;
302 }
303 }
304 else if ( tpd == 3600 )
305 {
306 if ( check_kj_m2 ( s->val ) == 0 )
307 return 0;
308 strcpy ( syn->s3.j5[2], "2" );
309 sprintf ( syn->s3.FFFF[2], "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
310 }
311 syn->mask |= SYNOP_SEC3;
312 break;
313
314 case 29: // 0 14 029 Diffuse solar radiation integrated over period specified
315 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
316 {
317 return 0;
318 }
319 tpd = time_period_duration ( s );
320 if ( tpd == ( 24 * 3600 ) )
321 {
322 if ( check_j_cm2 ( s->val ) == 0 )
323 return 0;
324 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
325 {
326 if ( strcmp ( "06", syn->e.HH ) == 0 )
327 {
328 strcpy ( syn->s3.j524[3], "3" );
329 sprintf ( syn->s3.FFFF24[3], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
330 syn->mask |= SYNOP_SEC3;
331 }
332 }
333 else
334 {
335 strcpy ( syn->s3.j524[3], "3" );
336 sprintf ( syn->s3.FFFF24[3], "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
337 syn->mask |= SYNOP_SEC3;
338 }
339 }
340 else if ( tpd == 3600 )
341 {
342 if ( check_kj_m2 ( s->val ) == 0 )
343 return 0;
344 strcpy ( syn->s3.j5[3], "3" );
345 sprintf ( syn->s3.FFFF[3], "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
346 }
347 syn->mask |= SYNOP_SEC3;
348 break;
349
350
351 case 30: // 0 14 030 Direct solar radiation integrated over period specified
352 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
353 {
354 return 0;
355 }
356 tpd = time_period_duration ( s );
357 if ( tpd == ( 24 * 3600 ) )
358 {
359 if ( check_j_cm2 ( s->val ) == 0 )
360 return 0;
361 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
362 {
363 if ( strcmp ( "06", syn->e.HH ) == 0 )
364 {
365 sprintf ( syn->s3.FFFF508, "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
366 syn->mask |= SYNOP_SEC3;
367 }
368 }
369 else
370 {
371 sprintf ( syn->s3.FFFF508, "%04d", ( int ) ( s->val / 10000.0 + 0.5 ) );
372 syn->mask |= SYNOP_SEC3;
373 }
374 }
375 else if ( tpd == 3600 )
376 {
377 if ( check_kj_m2 ( s->val ) == 0 )
378 return 0;
379 sprintf ( syn->s3.FFFF408, "%04d", ( int ) ( s->val / 1000.0 + 0.5 ) );
380 }
381 syn->mask |= SYNOP_SEC3;
382 break;
383
384 case 31: // 0 14 031 Total sunshine
385 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
386 {
387 return 0;
388 }
389 tpd = time_period_duration ( s );
390 if ( tpd == ( 24 * 3600 ) )
391 {
392 if ( check_j_cm2 ( s->val ) == 0 )
393 return 0;
394 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
395 {
396 if ( strcmp ( "06", syn->e.HH ) == 0 )
397 {
398 sprintf ( syn->s3.SSS, "%03d", (abs(s->ival) / 6) % 1000 );
399 syn->mask |= SYNOP_SEC3;
400 }
401 }
402 else
403 {
404 sprintf ( syn->s3.SSS, "%03d", (abs(s->ival) / 6) % 1000 );
405 syn->mask |= SYNOP_SEC3;
406 }
407 }
408 else if ( tpd == 3600 )
409 {
410 if ( check_kj_m2 ( s->val ) == 0 )
411 return 0;
412 sprintf ( syn->s3.SS, "%02d", abs(s->ival / 6) % 100 );
413 syn->mask |= SYNOP_SEC3;
414 }
415 break;
416
417 case 32: // 0 14 032 Total sunshine (hours)
418 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
419 {
420 return 0;
421 }
422 tpd = time_period_duration ( s );
423 if ( tpd == ( 24 * 3600 ) )
424 {
425 if ( check_j_cm2 ( s->val ) == 0 )
426 return 0;
427 if ( strcmp ( "07", syn->s0.II ) == 0 ) // France
428 {
429 if ( strcmp ( "06", syn->e.HH ) == 0 )
430 {
431 sprintf ( syn->s3.SSS, "%03d", s->ival * 10 );
432 syn->mask |= SYNOP_SEC3;
433 }
434 }
435 else
436 {
437 sprintf ( syn->s3.SSS, "%03d", s->ival * 10 );
438 syn->mask |= SYNOP_SEC3;
439 }
440 }
441 else if ( tpd == 3600 )
442 {
443 if ( check_kj_m2 ( s->val ) == 0 )
444 return 0;
445 sprintf ( syn->s3.SS, "%02d", s->ival * 10 );
446 syn->mask |= SYNOP_SEC3;
447 }
448 break;
449
450 default:
451 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
452 bufr2tac_set_error ( s, 0, "syn_parse_x14()", "Descriptor not parsed" );
453 break;
454 }
455
456 return 0;
457}
458
459/*!
460 \fn int buoy_parse_x14 ( struct buoy_chunks *b, struct bufr2tac_subset_state *s )
461 \brief Parse a expanded descriptor with X = 14
462 \param b pointer to a struct \ref buoy_chunks where to set the results
463 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
464
465 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
466*/
468{
469 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
470 {
471 return 0;
472 }
473
474 if ( b == NULL )
475 {
476 return 1;
477 }
478
479 switch ( s->a->desc.y )
480 {
481 default:
482 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
483 bufr2tac_set_error ( s, 0, "buoy_parse_x14()", "Descriptor not parsed" );
484 break;
485 }
486 return 0;
487}
488
489/*!
490 \fn int climat_parse_x14 ( struct climat_chunks *c, struct bufr2tac_subset_state *s )
491 \brief Parse a expanded descriptor with X = 14
492 \param c pointer to a struct \ref climat_chunks where to set the results
493 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
494
495 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
496*/
498{
499 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
500 {
501 return 0;
502 }
503
504 if ( c == NULL )
505 {
506 return 1;
507 }
508
509 switch ( s->a->desc.y )
510 {
511 case 32: // 0 14 032 . Total sunshine
512 if ( s->is_normal == 0 )
513 {
514 sprintf ( c->s1.S1S1S1, "%03d", s->ival );
515 c->mask |= CLIMAT_SEC1;
516 }
517 else
518 {
519 sprintf ( c->s2.S1S1S1, "%03d", s->ival );
520 c->mask |= CLIMAT_SEC2;
521 }
522 break;
523
524 case 33: // 0 14 033 . total sunshine percentage
525 sprintf ( c->s1.pspsps, "%03d", s->ival );
526 c->mask |= CLIMAT_SEC1;
527 break;
528
529 default:
530 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
531 bufr2tac_set_error ( s, 0, "climat_parse_x14()", "Descriptor not parsed" );
532 break;
533 }
534 return 0;
535}
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 time_period_duration(struct bufr2tac_subset_state *s)
Get time period duration in seconds.
Definition: bufr2tac_x04.c:33
int buoy_parse_x14(struct buoy_chunks *b, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 14.
Definition: bufr2tac_x14.c:467
int check_kj_m2(double val)
Check if a radiation value can be wrote in Kj/m2 using up to 4 chars.
Definition: bufr2tac_x14.c:33
int syn_parse_x14(struct synop_chunks *syn, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 14.
Definition: bufr2tac_x14.c:59
int check_j_cm2(double val)
Check if a radiation value can be wrote in J/cm2 using up to 4 chars.
Definition: bufr2tac_x14.c:45
int climat_parse_x14(struct climat_chunks *c, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 14.
Definition: bufr2tac_x14.c:497
#define DESCRIPTOR_VALUE_MISSING
Bit mask for a missing value in a struct bufr_atom_data.
Definition: bufrdeco.h:140
#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
#define SYNOP_SEC3
mask bit meaning section 3 or synop is solicited to or parsed with success
Definition: metsynop.h:49
stores information needed to parse a sequential list of expanded descriptors for a subset
Definition: bufr2tac.h:246
struct bufr_atom_data * a
Definition: bufr2tac.h:249
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_sec1 s1
Definition: metclimat.h:218
struct climat_sec2 s2
Definition: metclimat.h:219
char pspsps[4]
Definition: metclimat.h:96
char S1S1S1[4]
Definition: metclimat.h:95
char S1S1S1[4]
Definition: metclimat.h:125
char HH[4]
Definition: metcommon.h:36
contains all possible substrings from a synop report is parsed with success
Definition: metsynop.h:293
struct synop_sec3 s3
Definition: metsynop.h:300
struct report_date_ext e
Definition: metsynop.h:295
struct synop_sec0 s0
Definition: metsynop.h:297
char II[4]
Definition: metsynop.h:101
char FFFF408[6]
Definition: metsynop.h:240
char SSS[4]
Definition: metsynop.h:237
char j5[7][2]
Definition: metsynop.h:243
char SS[4]
Definition: metsynop.h:238
char FFFF[7][6]
Definition: metsynop.h:244
char FFFF507[6]
Definition: metsynop.h:241
char FFFF407[6]
Definition: metsynop.h:239
char j524[7][2]
Definition: metsynop.h:245
char FFFF24[7][6]
Definition: metsynop.h:246
char FFFF508[6]
Definition: metsynop.h:242