bufr2synop 0.24.0
bufr2tac_x12.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_x12.c
22 \brief decodes the descriptors with X = 12 (Temperature)
23 */
24#include "bufr2tac.h"
25
26/*!
27 \fn char * kelvin_to_snTTT ( char *target, double T )
28 \brief converts a kelvin temperature value into a snTTT string
29 \param T the temperature ( Kelvin )
30 \param target string with the result
31*/
32char * kelvin_to_snTTT ( char *target, double T )
33{
34 int ic;
35 double Tx = T;
36
37 if ( Tx > 15 && Tx < 34.0 ) // guess there is an scale error on coding , we better manage T * 10
38 {
39 Tx *= 10.0;
40 }
41 if ( Tx < 173.205 || Tx > 340.0 )
42 {
43 return NULL;
44 }
45
46 // tenths of degree (Celsius)
47 // Patch introduced on 22-Dec-2019 due to some roundings errors from India and Australia
48 // not converting properly from Kelvin to Celsius for Tmax and Tmin
49 // Changed '0.5' to '0.45'
50 //ic = ( int ) ( floor ( 10.0 * ( Tx - 273.15 ) + 0.5 ) );
51 ic = ( int ) ( floor ( 10.0 * ( Tx - 273.15 ) + 0.45 ) );
52 if ( ic < 0 )
53 {
54 sprintf ( target, "1%03d", -ic );
55 }
56 else
57 {
58 sprintf ( target, "0%03d", ic );
59 }
60 return target;
61}
62
63/*!
64 \fn char * kelvin_to_snTT ( char *target, double T )
65 \brief converts a kelvin temperature value into a snTT string
66 \param T the temperature ( Kelvin )
67 \param target string with the result
68*/
69char * kelvin_to_snTT ( char *target, double T )
70{
71 int ic;
72 if ( T < 173.65 || T > 340.0 )
73 {
74 return NULL;
75 }
76
77 // Whole degrees (Celsius)
78 ic = ( int ) ( floor ( ( T - 273.15 ) + 0.5 ) );
79 if ( ic < 0 )
80 {
81 sprintf ( target, "1%02d", -ic );
82 }
83 else
84 {
85 sprintf ( target, "%03d", ic );
86 }
87 return target;
88}
89
90/*!
91 \fn char * kelvin_to_TT ( char *target, double T )
92 \brief converts a kelvin temperature value into a TT string
93 \param T the temperature ( Kelvin )
94 \param target string with the result
95*/
96char * kelvin_to_TT ( char *target, double T )
97{
98 int ic;
99 if ( T < 150.0 || T > 340.0 )
100 {
101 return NULL;
102 }
103
104 // Whole degrees (Celsius)
105 ic = ( int ) ( floor ( ( T - 273.15 ) + 0.5 ) );
106 if ( ic < 0 )
107 {
108 sprintf ( target, "%02d", 50 - ic );
109 }
110 else
111 {
112 sprintf ( target, "%02d", ic );
113 }
114 return target;
115}
116
117/*!
118 \fn char * kelvin_to_TTTT ( char *target, double T )
119 \brief converts a kelvin temperature value into a TTTT string
120 \param T the temperature ( Kelvin )
121 \param target string with the result
122*/
123char * kelvin_to_TTTT ( char *target, double T )
124{
125 int ic;
126 if ( T < 150.0 || T > 340.0 )
127 {
128 return NULL;
129 }
130 // hundreth of degrees (Celsius)
131 ic = ( int ) ( floor ( 100.0 * ( T - 273.15 ) + 0.5 ) );
132 if ( ic < 0 )
133 {
134 ic = 5000 - ic;
135 }
136 sprintf ( target, "%04d", ic );
137 return target;
138}
139
140
141/*!
142 \fn char * kelvin_to_TTTa(char *target, double T)
143 \brief Set temperature TTTa
144 \param target result as string
145 \param T temperature (kelvin)
146*/
147char * kelvin_to_TTTa ( char *target, double T )
148{
149 int ix;
150
151 if ( T == MISSING_REAL )
152 {
153 sprintf ( target, "///" );
154 return target;
155 }
156
157 ix = ( int ) ( 10.0 * ( T - 273.15 ) );
158
159 if ( ix >= 0 )
160 {
161 ix &= ~1;
162 }
163 else
164 {
165 ix = ( -ix );
166 ix |= 1;
167 }
168 sprintf ( target, "%03d", ix );
169 return target;
170}
171
172/*!
173 \fn char * dewpoint_depression_to_DnDn ( char * target, double T, double Td )
174 \brief Set DnDn (dewpoint depression)
175 \param target string to set as result
176 \param T temperature (Kelvin)
177 \param Td dewpoint (Kelvin)
178*/
179char * dewpoint_depression_to_DnDn ( char * target, double T, double Td )
180{
181 int ix;
182 double dpd = T - Td;
183
184 if ( T == MISSING_REAL || Td == MISSING_REAL )
185 {
186 strcpy ( target, "//" );
187 return target;
188 }
189
190 if ( dpd < 0.0 )
191 {
192 return NULL;
193 }
194
195 if ( dpd > 50.0 )
196 {
197 strcpy ( target, "//" );
198 return target;
199 }
200
201 ix = ( int ) ( 10.0 * dpd );
202
203 if ( ix >= 55 )
204 {
205 ix = 50 + ( ix + 5 ) / 10;
206 }
207 sprintf ( target, "%02d", ix );
208
209 return target;
210}
211
212/*!
213 \fn int syn_parse_x12 ( struct synop_chunks *syn, struct bufr2tac_subset_state *s )
214 \brief Parse a expanded descriptor with X = 12
215 \param syn pointer to a struct \ref synop_chunks where to set the results
216 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
217
218 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
219*/
221{
222 char aux[16];
223
224 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
225 {
226 return 0;
227 }
228
229 switch ( s->a->desc.y )
230 {
231 case 1: // 0 12 001 . Air temperature
232 case 4: // 0 12 004 . Air temperatura at 2 m
233 case 101: // 0 12 101 . Air temperature
234 case 104: // 0 12 104 . Air temperature at 2 m
235 if ( syn->s1.TTT[0] == 0 )
236 {
237 if ( kelvin_to_snTTT ( aux, s->val ) )
238 {
239 syn->s1.sn1[0] = aux[0];
240 strcpy ( syn->s1.TTT, aux + 1 );
241 syn->mask |= SYNOP_SEC1;
242 }
243 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
244 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
245 }
246 break;
247
248 case 3: // 0 12 003 . Dewpoint temperature
249 case 6: // 0 12 006 . Dewpoint temperature at 2 m
250 case 103: // 0 12 103 . Dewpoint temperature
251 case 106: // 0 12 106 . Dewpoint temperature at 2 m
252 if ( syn->s1.TdTdTd[0] == 0 )
253 {
254 if ( kelvin_to_snTTT ( aux, s->val ) )
255 {
256 syn->s1.sn2[0] = aux[0];
257 strcpy ( syn->s1.TdTdTd, aux + 1 );
258 syn->mask |= SYNOP_SEC1;
259 }
260 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
261 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
262 }
263 break;
264
265 case 14: // 0 12 014 . Maximum temperature at 2 m , past 12 hours
266 case 21: // 0 12 021 . Maximum temperature.
267 case 114: // 0 12 114 . Maximum temperature at 2 m , past 12 hours
268 case 116: // 0 12 116 . Maximum temperature at 2 m , past 24 hours
269 if ( syn->s3.TxTxTx[0] == 0 && ( s->itval % ( 3 * 3600 ) ) == 0 ) // only for 3, 6 ... hours
270 {
271 if ( kelvin_to_snTTT ( aux, s->val ) )
272 {
273 syn->s3.snx[0] = aux[0];
274 strcpy ( syn->s3.TxTxTx, aux + 1 );
275 syn->mask |= SYNOP_SEC3;
276 }
277 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
278 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
279 }
280 break;
281
282 case 11: // 0 12 011 . Maximum temperature at heigh and over the period specified
283 case 111: // 0 12 111 . Maximum temperature at heigh and over the period specified
284 if ( syn->s3.TxTxTx[0] == 0 &&
285 ( s->hsensor >= 1.0 || s->hsensor <= 0 ) &&
286 ( time_period_duration ( s ) % ( 12 * 3600 ) ) == 0 ) // only for 12 , 24 hours
287 {
288 if ( kelvin_to_snTTT ( aux, s->val ) )
289 {
290 syn->s3.snx[0] = aux[0];
291 strcpy ( syn->s3.TxTxTx, aux + 1 );
292 syn->mask |= SYNOP_SEC3;
293 }
294 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
295 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
296 }
297 break;
298
299
300 case 15: // 0 12 015 . Minimum temperature at 2 m , past 12 hours
301 case 22: // 0 12 022 . Minimum temperature.
302 case 115: // 0 12 115 . Minimum temperature at 2 m , past 12 hours
303 case 117: // 0 12 117 . Minimum temperature at 2 m , past 24 hours
304 if ( syn->s3.TnTnTn[0] == 0 && ( s->itval % ( 3 * 3600 ) ) == 0 ) // only for 3, 6 ... hours
305 {
306 if ( kelvin_to_snTTT ( aux, s->val ) )
307 {
308 syn->s3.snn[0] = aux[0];
309 strcpy ( syn->s3.TnTnTn, aux + 1 );
310 syn->mask |= SYNOP_SEC3;
311 }
312 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
313 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
314 }
315 break;
316
317 case 12: // 0 12 012 . Minimum temperature at heigh and over the period specified
318 case 112: // 0 12 112 . Minimum temperature at heigh and over the period specified
319 if ( syn->s3.TnTnTn[0] == 0 &&
320 ( s->hsensor >= 1.0 || s->hsensor <= 0 ) &&
321 ( time_period_duration ( s ) % ( 12 * 3600 ) ) == 0 ) // only for 12 , 24 hours
322 {
323 if ( kelvin_to_snTTT ( aux, s->val ) )
324 {
325 syn->s3.snn[0] = aux[0];
326 strcpy ( syn->s3.TnTnTn, aux + 1 );
327 syn->mask |= SYNOP_SEC3;
328 }
329 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
330 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
331 }
332 break;
333
334 case 2: // 0 12 002 . Wet bulb temperature
335 case 5: // 0 12 005 . Wet bulb temperature at 2 m
336 case 102: // 0 12 102 . Wet bulb temperature
337 case 105: // 0 12 105 . Wet bulb temperature at 2 m
338 if ( syn->s2.TbTbTb[0] == 0 )
339 {
340 if ( kelvin_to_snTTT ( aux, s->val ) )
341 {
342 syn->s2.sw[0] = aux[0];
343 strcpy ( syn->s2.TbTbTb, aux + 1 );
344 syn->mask |= SYNOP_SEC2;
345 }
346 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
347 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
348 }
349 break;
350
351 case 113: // 0 12 113 . Ground minimum temperature, past 12 hours
352 if ( strcmp ( "6", syn->s0.A1 ) == 0 ||
353 strcmp ( "3", syn->s0.A1 ) == 0 ||
354 strcmp ( "2", syn->s0.A1 ) == 0
355 ) // region III or VI
356 {
357 if ( kelvin_to_snTT ( aux, s->val ) )
358 {
359 strcpy ( syn->s3.jjj, aux );
360 syn->mask |= SYNOP_SEC3;
361 }
362 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
363 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTT()", "Unspected parse problem" );
364 }
365 else if ( strcmp ( "1", syn->s0.A1 ) == 0 )
366 {
367 if ( kelvin_to_TT ( aux, s->val ) )
368 {
369 syn->s3.XoXoXoXo[0] = aux[0];
370 syn->s3.XoXoXoXo[1] = aux[1];
371 if ( syn->s3.XoXoXoXo[2] == 0 )
372 {
373 syn->s3.XoXoXoXo[2] = '/';
374 }
375 if ( syn->s3.XoXoXoXo[3] == 0 )
376 {
377 syn->s3.XoXoXoXo[3] = '/';
378 }
379 syn->mask |= SYNOP_SEC3;
380 }
381 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
382 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTT()", "Unspected parse problem" );
383 }
384 break;
385
386 case 121: // 0 12 121 . Ground minimum temperature (at the time of observation)
387 if ( strcmp ( "2", syn->s0.A1 ) == 0 ) // region II
388 {
389 if ( kelvin_to_snTT ( aux, s->val ) )
390 {
391 syn->s3.XoXoXoXo[1] = aux[0];
392 syn->s3.XoXoXoXo[2] = aux[1];
393 syn->s3.XoXoXoXo[3] = aux[2];
394 syn->mask |= SYNOP_SEC3;
395 }
396 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
397 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTT()", "Unspected parse problem" );
398 }
399 break;
400
401 case 120: // 0 12 120 . Ground temperature
402 if ( strcmp ( "2", syn->s0.A1 ) == 0 ) // Only for Region II
403 {
404 if ( kelvin_to_snTT ( aux, s->val ) )
405 {
406 if ( syn->s3.E1[0] )
407 syn->s3.XoXoXoXo[0] = '/';
408 else if ( syn->s3.E[0] )
409 syn->s3.XoXoXoXo[0] = syn->s3.E[0];
410 syn->s3.XoXoXoXo[1] = aux[0];
411 syn->s3.XoXoXoXo[2] = aux[1];
412 syn->s3.XoXoXoXo[3] = aux[2];
413 }
414 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
415 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_snTT()", "Unspected parse problem" );
416 }
417 break;
418
419 case 122: // 0 12 122 . Ground minimum temperature during preceding night
420 if ( strcmp ( "1", syn->s0.A1 ) == 0 ) // Only for Region I
421 {
422 if ( kelvin_to_TT ( aux, s->val ) )
423 {
424 syn->s3.XoXoXoXo[0] = aux[0];
425 syn->s3.XoXoXoXo[1] = aux[1];
426 if ( syn->s3.XoXoXoXo[2] == 0 )
427 {
428 syn->s3.XoXoXoXo[2] = '/';
429 }
430 if ( syn->s3.XoXoXoXo[3] == 0 )
431 {
432 syn->s3.XoXoXoXo[3] = '/';
433 }
434 syn->mask |= SYNOP_SEC3;
435 }
436 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
437 bufr2tac_set_error ( s, 1, "syn_parse_x12()->kelvin_to_TT()", "Unspected parse problem" );
438 }
439 else if ( strcmp ( "2", syn->s0.A1 ) == 0 ||
440 strcmp ( "3", syn->s0.A1 ) == 0 ) // Region II and III
441 {
442 if ( kelvin_to_snTT ( aux, s->val ) )
443 {
444 strcpy ( syn->s3.jjj, aux );
445 syn->mask |= SYNOP_SEC3;
446 }
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_x12()", "Descriptor not parsed" );
453 break;
454 }
455 return 0;
456}
457
458/*!
459 \fn int buoy_parse_x12 ( struct buoy_chunks *b, struct bufr2tac_subset_state *s )
460 \brief Parse a expanded descriptor with X = 12
461 \param b pointer to a struct \ref buoy_chunks where to set the results
462 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
463
464 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
465*/
467{
468 char aux[16];
469
470 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
471 {
472 return 0;
473 }
474
475 switch ( s->a->desc.y )
476 {
477 case 1: // 0 12 001 . Air temperature
478 case 4: // 0 12 004 . Air temperatura at 2 m
479 case 101: // 0 12 101 . Air temperature
480 case 104: // 0 12 104 . Air temperature at 2 m
481 if ( b->s1.TTT[0] == 0 )
482 {
483 if ( kelvin_to_snTTT ( aux, s->val ) )
484 {
485 b->s1.sn1[0] = aux[0];
486 strcpy ( b->s1.TTT, aux + 1 );
487 b->mask |= BUOY_SEC1;
488 }
489 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
490 bufr2tac_set_error ( s, 1, "buoy_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
491 }
492 break;
493 case 3: // 0 12 003 . Dewpoint temperature
494 case 6: // 0 12 006 . Dewpoint temperature at 2 m
495 case 103: // 0 12 103 . Dewpoint temperature
496 case 106: // 0 12 106 . Dewpoint temperature at 2 m
497 if ( b->s1.TdTdTd[0] == 0 )
498 {
499 if ( kelvin_to_snTTT ( aux, s->val ) )
500 {
501 b->s1.sn2[0] = aux[0];
502 strcpy ( b->s1.TdTdTd, aux + 1 );
503 b->mask |= BUOY_SEC1;
504 }
505 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
506 bufr2tac_set_error ( s, 1, "buoy_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
507 }
508 break;
509
510 default:
511 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
512 bufr2tac_set_error ( s, 0, "buoy_parse_x12()", "Descriptor not parsed" );
513 break;
514 }
515 return 0;
516}
517
518/*!
519 \fn int climat_parse_x12 ( struct climat_chunks *c, struct bufr2tac_subset_state *s )
520 \brief Parse a expanded descriptor with X = 12
521 \param c pointer to a struct \ref climat_chunks where to set the results
522 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
523
524 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
525*/
527{
528 char aux[16];
529
530 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
531 {
532 return 0;
533 }
534
535 if ( c == NULL )
536 {
537 return 1;
538 }
539
540 switch ( s->a->desc.y )
541 {
542 case 101:
543 if ( s->is_normal == 0 )
544 {
545 if ( s->isq_val == 4 ) // mean value
546 {
547 if ( kelvin_to_snTTT ( aux, s->val ) )
548 {
549 c->s1.s[0] = aux[0];
550 strcpy ( c->s1.TTT, aux + 1 );
551 c->mask |= CLIMAT_SEC1;
552 }
553 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
554 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
555 }
556 else if ( s->isq_val == 2 ) // maximum value
557 {
558 if ( kelvin_to_snTTT ( aux, s->val ) )
559 {
560 c->s4.sax[0] = aux[0];
561 strcpy ( c->s4.Tax, aux + 1 );
562 if ( s->more_days == 0 )
563 {
564 sprintf ( c->s4.yax, "%02d", s->day );
565 }
566 else
567 {
568 sprintf ( c->s4.yax, "%02d", ( s->day + 50 ) % 100 );
569 }
570 c->mask |= CLIMAT_SEC4;
571 }
572 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
573 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
574
575 }
576 else if ( s->isq_val == 3 ) // minimum value
577 {
578 if ( kelvin_to_snTTT ( aux, s->val ) )
579 {
580 c->s4.san[0] = aux[0];
581 strcpy ( c->s4.Tan, aux + 1 );
582 if ( s->more_days == 0 )
583 {
584 sprintf ( c->s4.yan, "%02d", s->day );
585 }
586 else
587 {
588 sprintf ( c->s4.yan, "%02d", ( s->day + 50 ) % 100 );
589 }
590 c->mask |= CLIMAT_SEC4;
591 }
592 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
593 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
594 }
595 }
596 else
597 {
598 if ( c->s2.TTT[0] == 0 )
599 {
600 if ( kelvin_to_snTTT ( aux, s->val ) )
601 {
602 c->s2.s[0] = aux[0];
603 strcpy ( c->s2.TTT, aux + 1 );
604 c->mask |= CLIMAT_SEC2;
605 }
606 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
607 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
608 }
609
610 }
611 break;
612
613 case 118: // 0 12 118 . Maximum temperature at heigh specified, past 24 h
614 if ( s->is_normal == 0 )
615 {
616 if ( c->s1.TxTxTx[0] == 0 )
617 {
618 if ( kelvin_to_snTTT ( aux, s->val ) )
619 {
620 c->s1.sx[0] = aux[0];
621 strcpy ( c->s1.TxTxTx, aux + 1 );
622 c->mask |= CLIMAT_SEC1;
623 }
624 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
625 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
626 }
627 }
628 else
629 {
630 if ( c->s2.TxTxTx[0] == 0 )
631 {
632 if ( kelvin_to_snTTT ( aux, s->val ) )
633 {
634 c->s2.sx[0] = aux[0];
635 strcpy ( c->s2.TxTxTx, aux + 1 );
636 c->mask |= CLIMAT_SEC2;
637 }
638 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
639 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
640 }
641 }
642 break;
643
644 case 119: // 0 12 119 . Minimum temperature at heigh specified, past 24 h
645 if ( s->is_normal == 0 )
646 {
647 if ( c->s1.TnTnTn[0] == 0 )
648 {
649 if ( kelvin_to_snTTT ( aux, s->val ) )
650 {
651 c->s1.sn[0] = aux[0];
652 strcpy ( c->s1.TnTnTn, aux + 1 );
653 c->mask |= CLIMAT_SEC1;
654 }
655 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
656 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
657 }
658 }
659 else
660 {
661 if ( c->s2.TnTnTn[0] == 0 )
662 {
663 if ( kelvin_to_snTTT ( aux, s->val ) )
664 {
665 c->s2.sn[0] = aux[0];
666 strcpy ( c->s2.TnTnTn, aux + 1 );
667 c->mask |= CLIMAT_SEC2;
668 }
669 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
670 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
671 }
672 }
673 break;
674
675 case 151: // 0 12 151 . Standard deviation of daily mean temperature
676 sprintf ( aux, "%03d", ( int ) ( s->val * 10.0 + 0.5 ) );
677 if ( s->is_normal == 0 )
678 {
679 strcpy ( c->s1.ststst, aux );
680 c->mask |= CLIMAT_SEC1;
681 }
682 else
683 {
684 strcpy ( c->s2.ststst, aux );
685 c->mask |= CLIMAT_SEC2;
686 }
687 break;
688
689 case 152: // 0 12 152 . Highest daily mean temperature
690 if ( s->a1->desc.x == 4 && s->a1->desc.y == 3 )
691 {
692 if ( kelvin_to_snTTT ( aux, s->val ) )
693 {
694 c->s4.sx[0] = aux[0];
695 strcpy ( c->s4.Txd, aux + 1 );
696 }
697 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
698 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
699
700 if ( s->isq_val == 0 )
701 {
702 sprintf ( c->s4.yx, "%02d", s->day );
703 }
704 else
705 {
706 sprintf ( c->s4.yx, "%02d", ( s->day + 50 ) % 100 );
707 }
708 c->mask |= CLIMAT_SEC4;
709 }
710 break;
711
712 case 153: // 0 12 153 . Lowest daily mean temperature
713 if ( s->a1->desc.x == 4 && s->a1->desc.y == 3 )
714 {
715 if ( kelvin_to_snTTT ( aux, s->val ) )
716 {
717 c->s4.sn[0] = aux[0];
718 strcpy ( c->s4.Tnd, aux + 1 );
719 }
720 else if ( BUFR2TAC_DEBUG_LEVEL > 0 )
721 bufr2tac_set_error ( s, 1, "climat_parse_x12()->kelvin_to_snTTT()", "Unspected parse problem" );
722
723 if ( s->isq_val == 0 )
724 {
725 sprintf ( c->s4.yn, "%02d", s->day );
726 }
727 else
728 {
729 sprintf ( c->s4.yn, "%02d", ( s->day + 50 ) % 100 );
730 }
731 c->mask |= CLIMAT_SEC4;
732 }
733 break;
734
735 default:
736 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
737 bufr2tac_set_error ( s, 0, "climat_parse_x12()", "Descriptor not parsed" );
738 break;
739 }
740 return 0;
741}
742
743/*!
744 \fn int temp_parse_x12 ( struct temp_chunks *t, struct bufr2tac_subset_state *s )
745 \brief Parse a expanded descriptor with X = 12
746 \param t pointer to a struct \ref temp_chunks where to set the results
747 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
748
749 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
750*/
752{
753 if ( t == NULL )
754 {
755 return 1;
756 }
757
758 switch ( s->a->desc.y )
759 {
760 case 101: // 0 12 101. Temperature/dry-bulb temperature (scale 2)
761 if ( s->rep > 0 && s->r->n > 0 )
762 {
763 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
764 {
765 s->r->raw[s->r->n - 1].T = MISSING_REAL;
766 }
767 else
768 {
769 s->r->raw[s->r->n - 1].T = s->val;
770 }
771 }
772 break;
773
774 case 103: // 0 12 103. Dew-point temperature (scale 2)
775 if ( s->rep > 0 && s->r->n > 0 )
776 {
777 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
778 {
779 s->r->raw[s->r->n - 1].Td = MISSING_REAL;
780 }
781 else
782 {
783 s->r->raw[s->r->n - 1].Td = s->val;
784 }
785 }
786 break;
787
788 default:
789 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
790 bufr2tac_set_error ( s, 0, "temp_parse_x12()", "Descriptor not parsed" );
791 break;
792 }
793
794 return 0;
795}
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
char * dewpoint_depression_to_DnDn(char *target, double T, double Td)
Set DnDn (dewpoint depression)
Definition: bufr2tac_x12.c:179
char * kelvin_to_TTTT(char *target, double T)
converts a kelvin temperature value into a TTTT string
Definition: bufr2tac_x12.c:123
char * kelvin_to_TTTa(char *target, double T)
Set temperature TTTa.
Definition: bufr2tac_x12.c:147
int climat_parse_x12(struct climat_chunks *c, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 12.
Definition: bufr2tac_x12.c:526
int syn_parse_x12(struct synop_chunks *syn, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 12.
Definition: bufr2tac_x12.c:220
int temp_parse_x12(struct temp_chunks *t, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 12.
Definition: bufr2tac_x12.c:751
int buoy_parse_x12(struct buoy_chunks *b, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 12.
Definition: bufr2tac_x12.c:466
char * kelvin_to_snTTT(char *target, double T)
converts a kelvin temperature value into a snTTT string
Definition: bufr2tac_x12.c:32
char * kelvin_to_TT(char *target, double T)
converts a kelvin temperature value into a TT string
Definition: bufr2tac_x12.c:96
char * kelvin_to_snTT(char *target, double T)
converts a kelvin temperature value into a snTT string
Definition: bufr2tac_x12.c:69
#define MISSING_REAL
The missing default value for real values.
Definition: bufrdeco.h:78
#define DESCRIPTOR_VALUE_MISSING
Bit mask for a missing value in a struct bufr_atom_data.
Definition: bufrdeco.h:140
#define BUOY_SEC1
mask bit meaning section 1 of buoy is solicited to or parsed with success
Definition: metbuoy.h:38
#define CLIMAT_SEC4
mask bit meaning section 4 of climat is solicited to or parsed with success
Definition: metclimat.h:52
#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_SEC1
mask bit meaning section 1 or synop is solicited to or parsed with success
Definition: metsynop.h:39
#define SYNOP_SEC3
mask bit meaning section 3 or synop is solicited to or parsed with success
Definition: metsynop.h:49
#define SYNOP_SEC2
mask bit meaning section 2 or synop is solicited to or parsed with success
Definition: metsynop.h:44
stores information needed to parse a sequential list of expanded descriptors for a subset
Definition: bufr2tac.h:246
struct bufr_atom_data * a1
Definition: bufr2tac.h:250
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
int mask
Definition: metbuoy.h:198
struct buoy_sec1 s1
Definition: metbuoy.h:202
char sn2[2]
Definition: metbuoy.h:98
char TTT[4]
Definition: metbuoy.h:97
char TdTdTd[4]
Definition: metbuoy.h:99
char sn1[2]
Definition: metbuoy.h:96
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
char s[2]
Definition: metclimat.h:84
char sx[2]
Definition: metclimat.h:87
char TxTxTx[4]
Definition: metclimat.h:88
char TTT[4]
Definition: metclimat.h:85
char sn[2]
Definition: metclimat.h:89
char ststst[4]
Definition: metclimat.h:86
char TnTnTn[4]
Definition: metclimat.h:90
char TTT[4]
Definition: metclimat.h:116
char TnTnTn[4]
Definition: metclimat.h:121
char TxTxTx[4]
Definition: metclimat.h:119
char ststst[4]
Definition: metclimat.h:117
char sn[2]
Definition: metclimat.h:120
char sx[2]
Definition: metclimat.h:118
char s[2]
Definition: metclimat.h:115
char sax[2]
Definition: metclimat.h:174
char sx[2]
Definition: metclimat.h:168
char Tnd[4]
Definition: metclimat.h:172
char yx[4]
Definition: metclimat.h:170
char san[2]
Definition: metclimat.h:177
char yn[4]
Definition: metclimat.h:173
char Tax[4]
Definition: metclimat.h:175
char yax[4]
Definition: metclimat.h:176
char Tan[4]
Definition: metclimat.h:178
char yan[4]
Definition: metclimat.h:179
char Txd[4]
Definition: metclimat.h:169
char sn[2]
Definition: metclimat.h:171
contains all possible substrings from a synop report is parsed with success
Definition: metsynop.h:293
struct synop_sec1 s1
Definition: metsynop.h:298
struct synop_sec2 s2
Definition: metsynop.h:299
struct synop_sec3 s3
Definition: metsynop.h:300
struct synop_sec0 s0
Definition: metsynop.h:297
char A1[2]
Definition: metsynop.h:94
char sn1[2]
Definition: metsynop.h:131
char sn2[2]
Definition: metsynop.h:133
char TdTdTd[4]
Definition: metsynop.h:134
char TTT[4]
Definition: metsynop.h:132
char TbTbTb[6]
Definition: metsynop.h:182
char sw[2]
Definition: metsynop.h:181
char TnTnTn[4]
Definition: metsynop.h:226
char E[2]
Definition: metsynop.h:227
char XoXoXoXo[6]
Definition: metsynop.h:222
char TxTxTx[4]
Definition: metsynop.h:224
char snn[2]
Definition: metsynop.h:225
char E1[2]
Definition: metsynop.h:229
char snx[2]
Definition: metsynop.h:223
char jjj[4]
Definition: metsynop.h:228
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