bufr2synop 0.24.0
bufr2tac_x20.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_x20.c
22 \brief decodes the descriptors with X = 20 (Observed phenomena)
23 */
24#include "bufr2tac.h"
25
26/*!
27 \fn char * percent_to_okta ( char *target, double perc )
28 \brief Converts percent cloud cover into okta
29 \param perc the precent cloud cover
30 \param target the resulting okta string
31*/
32char * percent_to_okta ( char *target, double perc )
33{
34 if ( perc == 0.0 )
35 {
36 strcpy ( target,"0" );
37 }
38 else if ( perc < ( 25.0 - 6.25 ) )
39 {
40 strcpy ( target,"1" );
41 }
42 else if ( perc < ( 37.5 - 6.25 ) )
43 {
44 strcpy ( target,"2" );
45 }
46 else if ( perc < ( 50.0 - 6.25 ) )
47 {
48 strcpy ( target,"3" );
49 }
50 else if ( perc < ( 62.5 -6.25 ) )
51 {
52 strcpy ( target,"4" );
53 }
54 else if ( perc < ( 75.0 - 6.25 ) )
55 {
56 strcpy ( target,"5" );
57 }
58 else if ( perc < ( 87.5 - 6.25 ) )
59 {
60 strcpy ( target,"6" );
61 }
62 else if ( perc < 100.0 )
63 {
64 strcpy ( target,"7" );
65 }
66 else if ( perc <= 112.5 )
67 {
68 strcpy ( target,"8" );
69 }
70 else if ( perc == 113.0 )
71 {
72 strcpy ( target,"9" );
73 }
74 return target;
75}
76
77/*!
78 \fn char * m_to_h ( char *target, double h )
79 \brief converts the altitude of cloud layer into h string code
80 \param h the altitude in meters
81 \param target the resulting h coded string
82*/
83char * m_to_h ( char *target, double h )
84{
85 if ( h < 50.0 )
86 {
87 strcpy ( target,"0" );
88 }
89 else if ( h < 100.0 )
90 {
91 strcpy ( target,"1" );
92 }
93 else if ( h < 200.0 )
94 {
95 strcpy ( target,"2" );
96 }
97 else if ( h < 300.0 )
98 {
99 strcpy ( target,"3" );
100 }
101 else if ( h < 600.0 )
102 {
103 strcpy ( target,"4" );
104 }
105 else if ( h < 1000.0 )
106 {
107 strcpy ( target,"5" );
108 }
109 else if ( h < 1500.0 )
110 {
111 strcpy ( target,"6" );
112 }
113 else if ( h < 2000.0 )
114 {
115 strcpy ( target,"7" );
116 }
117 else if ( h < 2500.0 )
118 {
119 strcpy ( target,"8" );
120 }
121 else
122 {
123 strcpy ( target,"9" );
124 }
125 return target;
126
127}
128
129/*!
130 \fn char * m_to_9h ( char *target, double h )
131 \brief converts the altitude of cloud layer into 9h string code
132 \param h the altitude in meters
133 \param target the resulting 9x coded string
134*/
135char * m_to_9h ( char *target, double h )
136{
137 if ( h < 50.0 )
138 {
139 strcpy ( target,"90" );
140 }
141 else if ( h < 100.0 )
142 {
143 strcpy ( target,"91" );
144 }
145 else if ( h < 200.0 )
146 {
147 strcpy ( target,"92" );
148 }
149 else if ( h < 300.0 )
150 {
151 strcpy ( target,"93" );
152 }
153 else if ( h < 600.0 )
154 {
155 strcpy ( target,"94" );
156 }
157 else if ( h < 1000.0 )
158 {
159 strcpy ( target,"95" );
160 }
161 else if ( h < 1500.0 )
162 {
163 strcpy ( target,"96" );
164 }
165 else if ( h < 2000.0 )
166 {
167 strcpy ( target,"97" );
168 }
169 else if ( h < 2500.0 )
170 {
171 strcpy ( target,"98" );
172 }
173 else
174 {
175 strcpy ( target,"99" );
176 }
177 return target;
178
179}
180
181
182/*!
183 \fn char * m_to_hh ( char *target, double h )
184 \brief converts the altitude of cloud layer into hh string code
185 \param h the altitude in meters
186 \param target the resulting h coded string
187*/
188char * m_to_hh ( char *target, double h )
189{
190 int ih = ( int ) h;
191
192 if ( ih <= 1500 )
193 {
194 sprintf ( target, "%02d", ih / 30 );
195 }
196 else if ( ih <= 9000 )
197 {
198 if ( ih < 1800 )
199 {
200 strcpy ( target, "50" );
201 }
202 else
203 {
204 sprintf ( target, "%2d", ( ih / 300 ) + 50 );
205 }
206 }
207 else if ( ih <= 21000 )
208 {
209 sprintf ( target, "%2d", ( ih / 500 ) + 50 );
210 }
211 else
212 {
213 strcpy ( target,"89" );
214 }
215 return target;
216
217}
218
219
220/*!
221 \fn char * vism_to_VV ( char *target, double V )
222 \brief Convert horizontal visibilty in meters to a VV string
223 \param V the visibility (m)
224 \param target the resulting VV string
225*/
226char * vism_to_VV ( char *target, double V )
227{
228 if ( V < 100.0 )
229 {
230 strcpy ( target, "00" );
231 }
232 else if ( V <= 5000.0 )
233 {
234 sprintf ( target, "%02d", ( int ) ( V + 0.1 ) / 100 );
235 }
236 else if ( V < 6000.0 )
237 {
238 sprintf ( target, "50" ); // this is to avoid 51-55 range
239 }
240 else if ( V <= 30000.0 )
241 {
242 sprintf ( target, "%02d", ( int ) ( V + 0.1 ) / 1000 + 50 );
243 }
244 else if ( V <= 70000.0 )
245 {
246 sprintf ( target, "%02d", ( int ) ( V - 30000.0 ) / 5000 + 80 );
247 }
248 else
249 {
250 strcpy ( target, "89" );
251 }
252 return target;
253}
254
255/*!
256 \fn char * m_to_RR ( char *target, double m )
257 \brief Convert distance (m) in RR code (3570)
258 \param m the distance/diameter (m)
259 \param target the resulting RR string
260*/
261char * m_to_RR ( char *target, double m )
262{
263 int ix;
264 ix = ( int ) ( m * 1000.0 + 0.5 );
265
266 if ( m > 0.4 )
267 {
268 strcpy ( target, "98" );
269 }
270 if ( m > 0.0 && m < 0.00065 )
271 {
272 sprintf ( target, "%02d", ( int ) ( m * 10000.0 + 0.5 ) );
273 }
274 else if ( ix <= 55 )
275 {
276 sprintf ( target, "%02d", ix );
277 }
278 else if ( ix <= 400 )
279 {
280 sprintf ( target, "%02d", ( ix / 10 ) + 50 );
281 }
282 else
283 {
284 strcpy ( target, "99" );
285 }
286 return target;
287}
288
289
290/*!
291 \fn int syn_parse_x20 ( struct synop_chunks *syn, struct bufr2tac_subset_state *s )
292 \brief Parse a expanded descriptor with X = 20
293 \param syn pointer to a struct \ref synop_chunks where to set the results
294 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
295
296 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
297*/
299{
300 char aux[16];
301
302 switch ( s->a->desc.y )
303 {
304 case 1: // 0 20 001 . Horizontal visibility
305 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
306 {
307 return 0;
308 }
309 vism_to_VV ( syn->s1.VV, s->val );
310 break;
311
312 case 3: // 0 20 003 . Present weather
313 // there are some cases
314 // Case 1)
315 // On current templates, sec1 WW is NOT preceeded by a time displacament descriptor
316 // In some national cases, a further complementary info about weather conditions is
317 // precedeed by two time displacament descriptors giving the time interval from where
318 // significant weather is described. In such cases we will use 902tt and 903tt, or
319 // 964.. if the period macthes with W1W2 period
320 // If WW = 20-29 and period matches last hour we then use 962.. group
321 // as the indication of period and 966WW as weather
322 if ( ( s->i - 1 ) == s->k_itval && ( s->i - 2 ) == s->k_jtval )
323 {
324 // check missing value
325 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
326 {
327 return 0;
328 }
329 // check no significan weather.
330 if ( s->ival == 100 || s->ival == 508 )
331 {
332 return 0;
333 }
334
335 // parse period
336 if ( s->itval == 0 && s->jtval == s->tw1w2 )
337 {
338 // Case of W1W2 interval
339 if ( syn->s3.d9.n == SYNOP_NMISC )
340 {
341 return 0;
342 }
343 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "964" );
344 s->SnSn = 964;
345 }
346 else if ( s->itval == 0 && s->jtval == -3600 && syn->s1.ww[0] == '2' )
347 {
348 // case of ww 20-29 and period equal to last hour. We will use 962...
349 if ( syn->s3.d9.n == SYNOP_NMISC )
350 {
351 return 0;
352 }
353 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "962" );
354 s->SnSn = 962;
355 }
356 else
357 {
358 if ( ( syn->s3.d9.n + 2 ) >= SYNOP_NMISC )
359 {
360 return 0;
361 }
362 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "902" );
363 secs_to_tt ( syn->s3.d9.misc[syn->s3.d9.n].spsp, s->jtval );
364 syn->s3.d9.n++;
365 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "903" );
366 secs_to_tt ( syn->s3.d9.misc[syn->s3.d9.n].spsp, s->itval );
367 syn->s3.d9.n++;
368 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "966" );
369 s->SnSn = 966;
370 }
371
372 // now set the value
373 if ( s->ival < 100 )
374 {
375 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].spsp , "%02d", s->ival );
376 syn->mask |= SYNOP_SEC3;
377 }
378 else if ( s->ival < 200 )
379 {
380 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].spsp, "%02d", s->ival % 100 );
381 syn->mask |= SYNOP_SEC3;
382 }
383 syn->s3.d9.n++;
384 }
385
386 // Case 2)
387 // Complementary present weather after 7wwW1W1 has been set.
388 // If last itval == 0 the we assume that the info should be set on 960.. groups
389 else if ( syn->s1.ww[0] && s->itval == 0 )
390 {
391 // check if overflowed 9 struct
392 if ( syn->s3.d9.n == SYNOP_NMISC )
393 {
394 return 0;
395 }
396 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "960" );
397 s->SnSn = 960;
398
399 if ( s->ival < 0 )
400 {
401 return 0;
402 }
403 if ( s->ival < 100 )
404 {
405 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].spsp , "%02d", s->ival );
406 syn->mask |= SYNOP_SEC3;
407 }
408 else if ( s->ival < 200 )
409 {
410 sprintf ( syn->s3.d9.misc[syn->s3.d9.n].spsp, "%02d", s->ival % 100 );
411 syn->mask |= SYNOP_SEC3;
412 }
413 syn->s3.d9.n++;
414 }
415 else
416 {
417 // 7wwW1W2 group
418 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
419 {
421 return 0;
422 }
423 if ( s->ival < 100 )
424 {
425 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
426 {
427 strcpy ( syn->s1.ix, "1" );
428 }
429 else if ( s->type == 1 || s->type == 2 )
430 {
431 strcpy ( syn->s1.ix, "1" );
432 }
433 else if ( s->type == 0 )
434 {
435 strcpy ( syn->s1.ix, "4" );
436 }
437 sprintf ( syn->s1.ww, "%02d", s->ival );
438 syn->mask |= SYNOP_SEC1;
439 }
440 else if ( s->ival == 100 )
441 {
442 strcpy ( syn->s1.ix, "5" );
443 syn->mask |= SYNOP_SEC1;
445 }
446 else if ( s->ival < 200 )
447 {
448 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
449 {
450 strcpy ( syn->s1.ix, "7" );
451 }
452 else if ( s->type == 0 || s->type == 2 )
453 {
454 strcpy ( syn->s1.ix, "7" );
455 }
456 sprintf ( syn->s1.ww, "%02d", s->ival % 100 );
457 syn->mask |= SYNOP_SEC1;
458 }
459 else if ( s->ival == 508 )
460 {
461 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
462 {
463 strcpy ( syn->s1.ix, "5" );
464 }
465 else if ( s->type == 0 || s->type == 2 )
466 {
467 strcpy ( syn->s1.ix, "5" );
468 }
470 }
471 else if ( s->ival == 509 )
472 {
473 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
474 {
475 strcpy ( syn->s1.ix, "6" );
476 }
477 else if ( s->type == 0 || s->type == 2 )
478 {
479 strcpy ( syn->s1.ix, "6" );
480 }
482 }
483
484 //printf("%s%s* %s\n", syn->s0.II, syn->s0.iii, syn->s1.ww);
485 }
486 break;
487
488 case 4: // 0 20 004 . Past weather (1)
489 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
490 {
492 return 0;
493 }
494
495 // stores w1w2 period
496 s->tw1w2 = s->itval;
497 if ( s->ival < 10 )
498 {
499 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
500 {
501 strcpy ( syn->s1.ix,"1" );
502 }
503 else if ( syn->s1.ix[0] == '/' )
504 {
505 if ( s->type == 1 || s->type == 2 )
506 {
507 strcpy ( syn->s1.ix, "1" );
508 }
509 else if ( s->type == 0 )
510 {
511 strcpy ( syn->s1.ix, "4" );
512 }
513 }
514 sprintf ( syn->s1.W1, "%d", s->ival );
515 syn->mask |= SYNOP_SEC1;
516 }
517 else if ( s->ival == 10 )
518 {
519 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
520 {
521 if ( s->type == 1 || s->type == 2 )
522 {
523 strcpy ( syn->s1.ix, "2" );
524 }
525 else if ( s->type == 0 )
526 {
527 strcpy ( syn->s1.ix, "5" );
528 }
529 }
531 }
532 else
533 {
534 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
535 {
536 strcpy ( syn->s1.ix,"7" );
537 }
538 else if ( s->type == 0 || s->type == 2 )
539 {
540 strcpy ( syn->s1.ix, "7" );
541 }
542 sprintf ( syn->s1.W1, "%d", abs ( s->ival ) % 10 );
543 syn->mask |= SYNOP_SEC1;
544 }
545 break;
546
547 case 5: // 0 20 005 . Past weather (2)
548 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
549 {
551 return 0;
552 }
553 if ( s->ival < 10 )
554 {
555 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
556 {
557 strcpy ( syn->s1.ix,"1" );
558 }
559 else if ( syn->s1.ix[0] == '/' )
560 {
561 if ( s->type == 1 || s->type == 2 )
562 {
563 strcpy ( syn->s1.ix, "1" );
564 }
565 else if ( s->type == 0 )
566 {
567 strcpy ( syn->s1.ix, "4" );
568 }
569 }
570 sprintf ( syn->s1.W2, "%d", s->ival );
571 syn->mask |= SYNOP_SEC1;
572 }
573 else if ( s->ival == 10 )
574 {
575 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
576 {
577 if ( s->type == 1 || s->type == 2 )
578 {
579 strcpy ( syn->s1.ix, "2" );
580 }
581 else if ( s->type == 0 )
582 {
583 strcpy ( syn->s1.ix, "5" );
584 }
585 }
587 }
588 else
589 {
590 if ( syn->s1.ix[0] == '/' && ( ( s->mask & SUBSET_MASK_HAVE_TYPE_STATION ) == 0 ) )
591 {
592 strcpy ( syn->s1.ix, "7" );
593 }
594 else if ( s->type == 0 || s->type == 2 )
595 {
596 strcpy ( syn->s1.ix, "7" );
597 }
598 sprintf ( syn->s1.W2, "%d", abs ( s->ival ) % 10 );
599 syn->mask |= SYNOP_SEC1;
600 }
601 break;
602
603 case 10: // 0 20 010 . Cloud cover (total)
604 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
605 {
606 return 0;
607 }
608 percent_to_okta ( syn->s1.N, s->val );
609 break;
610
611 case 11: // 0 20 011 . Cloud amount
612 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
613 {
614 return 0;
615 }
616 if ( s->clayer == 0 || s->clayer == 5 || s->clayer == 7 || s->clayer == 8 || s->clayer == 62 )
617 {
618 if ( s->ival <= 8 )
619 {
620 sprintf ( syn->s1.Nh, "%1d", abs(s->ival) % 10 );
621 }
622 else if ( s->ival <= 10 )
623 {
624 sprintf ( syn->s1.Nh, "9" );
625 }
626 else if ( s->ival == 15 )
627 {
628 sprintf ( syn->s1.Nh, "/" );
629 }
630 syn->mask |= SYNOP_SEC1;
631 }
632 else if ( s->clayer < 0 )
633 {
634 if ( s->ival <= 8 )
635 {
636 sprintf ( syn->s4.N1, "%1d", abs(s->ival) % 10 );
637 }
638 else if ( s->ival <= 10 )
639 {
640 sprintf ( syn->s4.N1, "9" );
641 }
642 else if ( s->ival == 15 )
643 {
644 sprintf ( syn->s4.N1, "/" );
645 }
646 syn->mask |= SYNOP_SEC4;
647 }
648 else if ( s->clayer > 0 && s->clayer < 5 )
649 {
650 if ( s->ival <= 8 )
651 {
652 sprintf ( syn->s3.nub[s->clayer - 1].Ns, "%1d", s->ival );
653 }
654 else if ( s->ival <= 10 )
655 {
656 sprintf ( syn->s3.nub[s->clayer - 1].Ns, "9" );
657 }
658 else if ( s->ival == 15 )
659 {
660 sprintf ( syn->s3.nub[s->clayer - 1].Ns, "/" );
661 }
662 syn->mask |= SYNOP_SEC3;
663 }
664 break;
665
666 case 12: // 0 20 012 . Cloud type
667 if ( s->clayer == 0 || s->clayer == 5 || s->clayer == 7 || s->clayer == 8 || s->clayer == 62 )
668 {
669 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
670 {
671 return 0;
672 }
673 if ( s->ival < 10 )
674 {
675 sprintf ( syn->s3.C, "%d", abs(s->ival) % 10 );
676 syn->mask |= SYNOP_SEC3;
677 }
678 else if ( s->ival >= 10 && s->ival < 20 )
679 {
680 sprintf ( syn->s1.Ch, "%1d", s->ival % 10 );
681 syn->mask |= SYNOP_SEC1;
682 }
683 else if ( s->ival >= 20 && s->ival < 30 )
684 {
685 sprintf ( syn->s1.Cm, "%1d", s->ival % 10 );
686 syn->mask |= SYNOP_SEC1;
687 }
688 else if ( s->ival >= 30 && s->ival < 40 )
689 {
690 sprintf ( syn->s1.Cl, "%1d", s->ival % 10 );
691 syn->mask |= SYNOP_SEC1;
692 }
693 else if ( s->ival == 59 )
694 {
695 sprintf ( syn->s1.Nh, "/" );
696 syn->mask |= SYNOP_SEC1;
697 }
698 else if ( s->ival == 60 )
699 {
700 sprintf ( syn->s1.Ch, "/" );
701 syn->mask |= SYNOP_SEC1;
702 }
703 else if ( s->ival == 61 )
704 {
705 sprintf ( syn->s1.Cm, "/" );
706 syn->mask |= SYNOP_SEC1;
707 }
708 else if ( s->ival == 62 )
709 {
710 sprintf ( syn->s1.Cl, "/" );
711 syn->mask |= SYNOP_SEC1;
712 }
713 }
714 else if ( s->clayer < 0 )
715 {
716 // case of base of clouds below station level
717 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
718 {
719 return 0;
720 }
721 if ( s->ival == 59 )
722 {
723 sprintf ( syn->s4.C1, "/" );
724 syn->mask |= SYNOP_SEC4;
725 }
726 else if ( s->ival < 10 )
727 {
728 sprintf ( syn->s4.C1, "%1d", abs (s->ival) % 10 );
729 syn->mask |= SYNOP_SEC4;
730 }
731 }
732 else if ( s->clayer > 0 && s->clayer < 5 )
733 {
734 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
735 {
736 sprintf ( syn->s3.nub[s->clayer - 1].C, "/" );
737 return 0;
738 }
739 if ( s->ival == 59 || s->ival >= 10 )
740 {
741 sprintf ( syn->s3.nub[s->clayer - 1].C, "/" );
742 }
743 else
744 {
745 // C clouds for 8 groups SEC 3
746 sprintf ( syn->s3.nub[s->clayer - 1].C, "%1d", s->ival % 10 );
747 }
748 syn->mask |= SYNOP_SEC3;
749 }
750 break;
751
752 case 13: // 0 20 013 . Height of base of cloud
753 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
754 {
755 return 0;
756 }
757 if ( s->clayer == 0 || s->clayer == 7 || s->clayer == 5 || s->clayer == 62 ) // first layer or low layer is for sec1
758 {
759 m_to_h ( syn->s1.h, s->val );
760 }
761 else if ( s->clayer > 0 && s->clayer < 5 )
762 {
763 if ( syn->s3.nub[s->clayer - 1].Ns[0] )
764 {
765 m_to_hh ( syn->s3.nub[s->clayer - 1].hshs, s->val );
766 }
767 else
768 {
769 m_to_9h ( syn->s3.nub[s->clayer - 1].hshs, s->val );
770 }
771 }
772 break;
773
774 case 14: // 0 20 014 . Height of Top of cloud
775 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
776 {
777 return 0;
778 }
779 if ( s->clayer < 0 ) // base below station level
780 {
781 m_to_hh ( syn->s4.H1H1, s->val );
782 syn->mask |= SYNOP_SEC4;
783 }
784 break;
785
786 case 17:
787 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
788 {
789 return 0;
790 }
791 if ( s->clayer < 0 && s->ival < 10 ) // base below station level
792 {
793 sprintf ( syn->s4.Ct, "%d", abs(s->ival) % 10 );
794 syn->mask |= SYNOP_SEC4;
795 }
796 break;
797
798 case 21: // 0 20 021 . Type of precipitation
799 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
800 {
801 return 0;
802 }
803
804 if ( syn->s0.A1[0] == '6' ) // for Reg VI
805 {
806 // flag table width = 30 bits
807 if ( s->ival & ( 1 << ( 30 - 15 ) ) &&
808 ( s->ival & ( 1 << ( 30 - 16 ) ) ) == 0 &&
809 ( s->ival & ( 1 << ( 30 - 20 ) ) ) == 0
810 )
811 {
812 // Only Glaze
813 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "934" );
814 s->SnSn = 934;
815 // here we increase counter
816 syn->s3.d9.n++;
817 }
818 else if ( s->ival & ( 1 << ( 30 - 16 ) ) &&
819 ( s->ival & ( 1 << ( 30 - 15 ) ) ) == 0 &&
820 ( s->ival & ( 1 << ( 30 - 20 ) ) ) == 0
821 )
822 {
823 // Only Rime
824 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "935" );
825 s->SnSn = 935;
826 // here we increase counter
827 syn->s3.d9.n++;
828 }
829 else if ( s->ival & ( 1 << ( 30 - 20 ) ) &&
830 ( s->ival & ( 1 << ( 30 - 15 ) ) ) == 0 &&
831 ( s->ival & ( 1 << ( 30 - 16 ) ) ) == 0
832 )
833 {
834 // Only Wet snow
835 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "937" );
836 s->SnSn = 937;
837 // here we increase counter
838 syn->s3.d9.n++;
839 }
840 else if ( s->ival & ( 1 << ( 30 - 15 ) ) ||
841 s->ival & ( 1 << ( 30 - 16 ) ) ||
842 s->ival & ( 1 << ( 30 - 20 ) ) )
843 {
844 // Compound deposit
845 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "936" );
846 s->SnSn = 936;
847 // here we increase counter
848 syn->s3.d9.n++;
849 }
850 }
851 break;
852
853 case 23: // 0 20 023 . Other weather phenomena
854 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
855 {
856 return 0;
857 }
858
859 if ( syn->s0.A1[0] == '6' ) // for Reg VI
860 {
861 // flag table width = 18 bits
862 if ( s->ival & ( 1 << ( 18 - 1 ) ) )
863 {
864 // Dust/sand whirl
865 syn->s3.d9.misc[syn->s3.d9.n].spsp[0] = '5'; // moderate intensity
866 syn->s3.d9.misc[syn->s3.d9.n].spsp[1] = '/'; // at the moment
867 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "919" );
868 s->SnSn = 919;
869 // here we increase counter
870 syn->s3.d9.n++;
871 }
872 else if ( ( s->ival & ( 1 << ( 18 - 9 ) ) ) ||
873 ( s->ival & ( 1 << ( 18 - 10 ) ) )
874 )
875 {
876 // Funnel clouds
877 syn->s3.d9.misc[syn->s3.d9.n].spsp[0] = '3'; // assumed less than 3 Km from station
878 syn->s3.d9.misc[syn->s3.d9.n].spsp[1] = '/'; // at the moment
879 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "919" );
880 s->SnSn = 919;
881 // here we increase counter
882 syn->s3.d9.n++;
883 }
884 else if ( s->ival & ( 1 << ( 18 - 12 ) ) )
885 {
886 syn->s3.d9.misc[syn->s3.d9.n].spsp[0] = '0'; // assumed less than 3 Km from station
887 syn->s3.d9.misc[syn->s3.d9.n].spsp[1] = '/'; // at the moment
888 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "919" );
889 s->SnSn = 919;
890 // here we increase counter
891 syn->s3.d9.n++;
892 }
893 else if ( s->ival & ( 1 << ( 18 - 2 ) ) )
894 {
895 syn->s3.d9.misc[syn->s3.d9.n].spsp[0] = '2'; // FIXME What kind of squall ?
896 syn->s3.d9.misc[syn->s3.d9.n].spsp[1] = '/'; // at the moment
897 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "918" );
898 s->SnSn = 918;
899 // here we increase counter
900 syn->s3.d9.n++;
901 }
902 }
903 break;
904
905 case 24: // 0 20 024 . Intensity of phenomena
906 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
907 {
908 return 0;
909 }
910 if ( syn->s0.A1[0] == '6' ) // for Reg VI
911 {
912 if ( s->SnSn == 919 )
913 {
914 if ( syn->s3.d9.misc[syn->s3.d9.n - 1].spsp[0] == '5' )
915 {
916 if ( s->ival == 1 )
917 {
918 syn->s3.d9.misc[syn->s3.d9.n - 1].spsp[0] = '4';
919 }
920 else if ( s->ival == 3 || s->ival == 4 )
921 {
922 syn->s3.d9.misc[syn->s3.d9.n - 1].spsp[0] = '6';
923 }
924 }
925 }
926 }
927 break;
928
929 case 25: // 0 20 025 . Obscuration
930 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
931 {
932 return 0;
933 }
934
935 if ( syn->s0.A1[0] == '6' ) // for Reg VI
936 {
937 // flag table width = 21 bits
938 if ( s->ival & ( 1 << ( 21 - 1 ) ) )
939 {
940 // Dust/sand whirl
941 syn->s3.d9.misc[syn->s3.d9.n].spsp[0] = '1'; // We next willl modify
942 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "929" );
943 s->SnSn = 929;
944 // here we increase counter
945 syn->s3.d9.n++;
946 }
947
948 }
949 break;
950
951 case 26: // 9 29 026 . Character of obscuration
952 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
953 {
954 return 0;
955 }
956 if ( syn->s0.A1[0] == '6' ) // for Reg VI
957 {
958 if ( s->SnSn == 929 )
959 {
960 if ( s->ival == 6 )
961 {
962 syn->s3.d9.misc[syn->s3.d9.n - 1].spsp[0] = '6';
963 }
964 }
965 }
966 break;
967
968 case 27: // 0 20 027 . Phenomenon occurrence
969 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
970 {
971 if ( syn->s0.A1[0] == '6' ) // for Reg VI
972 {
973 // flag table width = 9 bits
974 if ( s->SnSn == 919 || s->SnSn == 918 )
975 {
976 syn->s3.d9.misc[syn->s3.d9.n - 1].SpSp[0] = 0;
977 }
978 }
979 return 0;
980 }
981 if ( syn->s0.A1[0] == '6' ) // for Reg VI
982 {
983 // flag table width = 9 bits
984 if ( s->SnSn == 919 || s->SnSn == 918 )
985 {
986 if ( ( s->ival & ( 1 << ( 9 - 3 ) ) ) == 0 )
987 {
988 syn->s3.d9.misc[syn->s3.d9.n - 1].SpSp[0] = 0; // No valid group
989 }
990 }
991 }
992 break;
993
994 case 40: // 9 29 040 . Evolution of drift of snow
995 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
996 {
997 return 0;
998 }
999 if ( syn->s0.A1[0] == '6' ) // for Reg VI
1000 {
1001 if ( s->SnSn == 929 )
1002 {
1003 sprintf ( aux, "%d", s->ival % 10 );
1004 syn->s3.d9.misc[syn->s3.d9.n - 1].spsp[1] = aux[0]; // S8'
1005 }
1006 }
1007 break;
1008
1009 case 54: // 0 20 054 . True direction from which clouds are moving
1010 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1011 {
1012 return 0;
1013 }
1014 if ( syn->s0.A1[0] == '6' ) // for Reg VI
1015 {
1016 grad_to_D ( aux, s->val );
1017 if ( s->SnSn == 919 || s->SnSn == 918 )
1018 {
1019 syn->s3.d9.misc[syn->s3.d9.n - 1].spsp[1] = aux[0];
1020 }
1021 else if ( s->clayer == 7 )
1022 {
1023 grad_to_D ( syn->s3.Dl, s->val );
1024 }
1025 else if ( s->clayer == 8 )
1026 {
1027 grad_to_D ( syn->s3.Dm, s->val );
1028 }
1029 else if ( s->clayer == 9 )
1030 {
1031 grad_to_D ( syn->s3.Dh, s->val );
1032 }
1033 syn->mask |= SYNOP_SEC3;
1034 }
1035 else if ( syn->s0.A1[0] == '4' ) // for Reg IV
1036 {
1037 grad_to_D ( aux, s->val );
1038 if ( s->clayer == 7 )
1039 {
1040 syn->s3.XoXoXoXo[1] = aux[0];
1041 }
1042 else if ( s->clayer == 8 )
1043 {
1044 syn->s3.XoXoXoXo[2] = aux[0];
1045 }
1046 else if ( s->clayer == 9 )
1047 {
1048 syn->s3.XoXoXoXo[3] = aux[0];
1049 }
1050 syn->mask |= SYNOP_SEC3;
1051 }
1052 else // other Regions
1053 {
1054 if ( s->clayer == 7 )
1055 {
1056 grad_to_D ( syn->s3.Dl, s->val );
1057 }
1058 else if ( s->clayer == 8 )
1059 {
1060 grad_to_D ( syn->s3.Dm, s->val );
1061 }
1062 else if ( s->clayer == 9 )
1063 {
1064 grad_to_D ( syn->s3.Dh, s->val );
1065 }
1066 syn->mask |= SYNOP_SEC3;
1067 }
1068 break;
1069
1070 case 55: // 0 20 055 . State of sky in tropics
1071 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1072 {
1073 return 0;
1074 }
1075 if ( strcmp ( syn->s0.A1, "4" ) == 0 )
1076 {
1077 // For REG IV
1078 if ( s->ival < 10 )
1079 {
1080 sprintf ( aux,"%d", s->ival );
1081 syn->s3.XoXoXoXo[0] = aux[0];
1082 }
1083 else
1084 {
1085 syn->s3.XoXoXoXo[0] = '/';
1086 }
1087 // then copy data direction of cloud drift from 3 02 047 if any
1088 if ( syn->s3.Dl[0] )
1089 {
1090 syn->s3.XoXoXoXo[1] = syn->s3.Dl[0];
1091 }
1092 if ( syn->s3.Dm[0] )
1093 {
1094 syn->s3.XoXoXoXo[1] = syn->s3.Dm[0];
1095 }
1096 if ( syn->s3.Dh[0] )
1097 {
1098 syn->s3.XoXoXoXo[1] = syn->s3.Dh[0];
1099 }
1100 syn->mask |= SYNOP_SEC3;
1101 }
1102 break;
1103
1104 case 62: // 0 20 062 . State of the ground (with or without snow)
1105 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1106 {
1107 return 0;
1108 }
1109 if ( strcmp ( syn->s0.A1, "2" ) == 0 )
1110 {
1111 // For REG II
1112 if ( s->ival < 10 )
1113 {
1114 sprintf ( aux,"%d", s->ival );
1115 sprintf ( syn->s3.E, "%d", s->ival );
1116 syn->s3.XoXoXoXo[0] = aux[0];
1117 }
1118 else if ( s->ival < 20 )
1119 {
1120 syn->s3.XoXoXoXo[0] = '/';
1121 sprintf ( syn->s3.E1,"%d", s->ival % 10 );
1122 }
1123 if ( syn->s3.XoXoXoXo[1] == 0 )
1124 {
1125 // In case of still no snTgTg
1126 syn->s3.XoXoXoXo[1] = '/';
1127 syn->s3.XoXoXoXo[2] = '/';
1128 syn->s3.XoXoXoXo[3] = '/';
1129 }
1130 }
1131 else
1132 {
1133 // The Other regs
1134 if ( s->ival < 10 )
1135 {
1136 sprintf ( syn->s3.E,"%d", abs(s->ival) % 10 );
1137 }
1138 else if ( s->ival < 20 )
1139 {
1140 sprintf ( syn->s3.E1,"%d", s->ival % 10 );
1141 }
1142 }
1143 syn->mask |= SYNOP_SEC3;
1144 break;
1145
1146 case 66: // 0 20 066 . Max diameter of hailstones
1147 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1148 {
1149 return 0;
1150 }
1151 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1152 {
1153 m_to_RR ( syn->s3.d9.misc[syn->s3.d9.n].spsp, s->val );
1154 strcpy ( syn->s3.d9.misc[syn->s3.d9.n].SpSp, "932" );
1155 s->SnSn = 932;
1156 // here we increase counter
1157 syn->s3.d9.n++;
1158 }
1159 break;
1160
1161 case 67: // 0 20 067 . Diameter of deposit
1162 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1163 {
1164 return 0;
1165 }
1166 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1167 {
1168 m_to_RR ( syn->s3.d9.misc[syn->s3.d9.n - 1].spsp, s->val );
1169 }
1170 break;
1171
1172 case 101: // 0 20 101. Locust (acridian) name
1173 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1174 {
1175 return 0;
1176 }
1177 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1178 {
1179 if ( s->ival < 10 )
1180 {
1181 sprintf ( aux, "%d", s->ival );
1182 syn->s3.R8[0][0] = aux[0]; // Ln
1183 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1184 }
1185 }
1186 break;
1187
1188 case 102: // 0 20 102. Locust (maturity) color
1189 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1190 {
1191 return 0;
1192 }
1193 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1194 {
1195 if ( s->ival < 10 )
1196 {
1197 sprintf ( aux, "%d", s->ival );
1198 syn->s3.R8[0][1] = aux[0]; // Lc
1199 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1200 }
1201 }
1202 break;
1203
1204 case 103: // 0 20 103. Stage of development of locusts
1205 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1206 {
1207 return 0;
1208 }
1209 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1210 {
1211 if ( s->ival < 10 )
1212 {
1213 sprintf ( aux, "%d", s->ival );
1214 syn->s3.R8[0][2] = aux[0]; // Ld
1215 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1216 }
1217 }
1218 break;
1219
1220 case 104: // 0 20 104. Organization state of swarm or band of locusts
1221 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1222 {
1223 return 0;
1224 }
1225 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1226 {
1227 if ( s->ival < 10 )
1228 {
1229 sprintf ( aux, "%d", s->ival );
1230 syn->s3.R8[0][3] = aux[0]; // Lg
1231 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1232 }
1233 }
1234 break;
1235
1236 case 105: // 0 20 105. Size of swarm or band of locusts and duration of
1237 // passage of swarm
1238 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1239 {
1240 return 0;
1241 }
1242 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1243 {
1244 if ( s->ival < 10 )
1245 {
1246 sprintf ( aux, "%d", s->ival );
1247 syn->s3.R8[1][0] = aux[0]; // Sl
1248 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1249 }
1250 }
1251 break;
1252
1253 case 106: // 0 20 106. Locust population density
1254 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1255 {
1256 return 0;
1257 }
1258 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1259 {
1260 if ( s->ival < 10 )
1261 {
1262 sprintf ( aux, "%d", s->ival );
1263 syn->s3.R8[1][1] = aux[0]; // dl
1264 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1265 }
1266 }
1267 break;
1268
1269 case 107: // 0 20 107. Direction of movements of locust swarm
1270 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1271 {
1272 return 0;
1273 }
1274 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1275 {
1276 if ( s->ival < 10 )
1277 {
1278 sprintf ( aux, "%d", s->ival );
1279 syn->s3.R8[1][1] = aux[0]; // Dl
1280 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1281 }
1282 }
1283 break;
1284
1285 case 108: // 0 20 108. Extent of vegetation
1286 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1287 {
1288 return 0;
1289 }
1290 if ( strcmp ( syn->s0.A1, "1" ) == 0 ) // Only for Region I
1291 {
1292 if ( s->ival < 8 )
1293 {
1294 sprintf ( aux, "%d", s->ival );
1295 syn->s3.R8[1][1] = aux[0]; // Dl
1296 syn->mask |= ( SYNOP_SEC3 | SYNOP_SEC3_8 );
1297 }
1298 }
1299 break;
1300
1301 default:
1302 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
1303 bufr2tac_set_error ( s, 0, "syn_parse_x20()", "Descriptor not parsed" );
1304 break;
1305 }
1306
1307 // check about h
1308 if ( syn->s1.h[0] == '/' && syn->s1.N[0] == '0' )
1309 {
1310 syn->s1.h[0] = '9';
1311 }
1312
1313 return 0;
1314}
1315
1316/*!
1317 \fn int buoy_parse_x20 ( struct buoy_chunks *b, struct bufr2tac_subset_state *s )
1318 \brief Parse a expanded descriptor with X = 20
1319 \param b pointer to a struct \ref buoy_chunks where to set the results
1320 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
1321
1322 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
1323*/
1325{
1326 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1327 {
1328 return 0;
1329 }
1330
1331 if ( b == NULL )
1332 {
1333 return 1;
1334 }
1335
1336 switch ( s->a->desc.y )
1337 {
1338 default:
1339 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
1340 bufr2tac_set_error ( s, 0, "buoy_parse_x20()", "Descriptor not parsed" );
1341 break;
1342 }
1343 return 0;
1344}
1345
1346/*!
1347 \fn int temp_parse_x20 ( struct temp_chunks *t, struct bufr2tac_subset_state *s )
1348 \brief Parse a expanded descriptor with X = 20
1349 \param t pointer to a struct \ref temp_chunks where to set the results
1350 \param s pointer to a struct \ref bufr2tac_subset_state where is stored needed information in sequential analysis
1351
1352 It returns 0 if success, 1 if problems when processing. If a descriptor is not processed returns 0 anyway
1353*/
1355{
1356
1357 switch ( s->a->desc.y )
1358 {
1359 case 11: // 0 20 011 . Cloud amount
1360 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1361 {
1362 return 0;
1363 }
1364 if ( s->ival <= 8 )
1365 {
1366 sprintf ( t->b.s8.Nh, "%1d", abs(s->ival) % 10 );
1367 }
1368 else if ( s->ival <= 10 )
1369 {
1370 sprintf ( t->b.s8.Nh, "9" );
1371 }
1372 else if ( s->ival == 15 )
1373 {
1374 sprintf ( t->b.s8.Nh, "/" );
1375 }
1376 t->b.mask |= TEMP_SEC_8;
1377 break;
1378
1379 case 12: // 0 20 012 . Cloud type
1380 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1381 {
1382 return 0;
1383 }
1384 if ( s->ival >= 10 && s->ival < 20 )
1385 {
1386 sprintf ( t->b.s8.Ch, "%1d", s->ival % 10 );
1387 }
1388 else if ( s->ival >= 20 && s->ival < 30 )
1389 {
1390 sprintf ( t->b.s8.Cm, "%1d", s->ival % 10 );
1391 }
1392 else if ( s->ival >= 30 && s->ival < 40 )
1393 {
1394 sprintf ( t->b.s8.Cl, "%1d", s->ival % 10 );
1395 }
1396 else if ( s->ival == 59 )
1397 {
1398 sprintf ( t->b.s8.Nh, "/" );
1399 }
1400 else if ( s->ival == 60 )
1401 {
1402 sprintf ( t->b.s8.Ch, "/" );
1403 }
1404 else if ( s->ival == 61 )
1405 {
1406 sprintf ( t->b.s8.Cm, "/" );
1407 }
1408 else if ( s->ival == 62 )
1409 {
1410 sprintf ( t->b.s8.Cl, "/" );
1411 }
1412 t->b.mask |= TEMP_SEC_8;
1413 break;
1414
1415 case 13: // 0 20 013 . Height of base of cloud
1416 if ( s->a->mask & DESCRIPTOR_VALUE_MISSING )
1417 {
1418 return 0;
1419 }
1420 m_to_h ( t->b.s8.h, s->val );
1421 break;
1422
1423 default:
1424 if ( BUFR2TAC_DEBUG_LEVEL > 1 && (s->a->mask & DESCRIPTOR_VALUE_MISSING) == 0 )
1425 bufr2tac_set_error ( s, 0, "temp_parse_x20()", "Descriptor not parsed" );
1426 break;
1427 }
1428 return 0;
1429}
1430
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)
#define SUBSET_MASK_HAVE_NO_SIGNIFICANT_WW
Bit mask to mark a struct bufr_subset_sequence_data without WW information.
Definition: bufr2tac.h:92
char * grad_to_D(char *D, double grad)
Converts true direction in grads to D (code table 0700)
Definition: bufr2tac_x05.c:32
char * secs_to_tt(char *tt, int secs)
get tt code from seconds
Definition: bufr2tac_x11.c:34
#define SUBSET_MASK_HAVE_TYPE_STATION
Bit mask to mark a struct bufr_subset_sequence_data having type station information.
Definition: bufr2tac.h:86
#define SUBSET_MASK_HAVE_NO_SIGNIFICANT_W1
Bit mask to mark a struct bufr_subset_sequence_data without W1 information.
Definition: bufr2tac.h:98
#define SUBSET_MASK_HAVE_NO_SIGNIFICANT_W2
Bit mask to mark a struct bufr_subset_sequence_data without W1 information.
Definition: bufr2tac.h:104
char * m_to_9h(char *target, double h)
converts the altitude of cloud layer into 9h string code
Definition: bufr2tac_x20.c:135
int syn_parse_x20(struct synop_chunks *syn, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 20.
Definition: bufr2tac_x20.c:298
char * percent_to_okta(char *target, double perc)
Converts percent cloud cover into okta.
Definition: bufr2tac_x20.c:32
char * vism_to_VV(char *target, double V)
Convert horizontal visibilty in meters to a VV string.
Definition: bufr2tac_x20.c:226
int temp_parse_x20(struct temp_chunks *t, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 20.
char * m_to_hh(char *target, double h)
converts the altitude of cloud layer into hh string code
Definition: bufr2tac_x20.c:188
char * m_to_RR(char *target, double m)
Convert distance (m) in RR code (3570)
Definition: bufr2tac_x20.c:261
char * m_to_h(char *target, double h)
converts the altitude of cloud layer into h string code
Definition: bufr2tac_x20.c:83
int buoy_parse_x20(struct buoy_chunks *b, struct bufr2tac_subset_state *s)
Parse a expanded descriptor with X = 20.
#define DESCRIPTOR_VALUE_MISSING
Bit mask for a missing value in a struct bufr_atom_data.
Definition: bufrdeco.h:140
#define SYNOP_SEC3_8
mask bit meaning optional/regional 8 part, section 3 for synop is solicited to or parsed with success
Definition: metsynop.h:69
#define SYNOP_NMISC
number of misc3 struct to store the parsed results of 9SpSpspsp groups
Definition: metsynop.h:84
#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_SEC4
mask bit meaning section 4 or synop is solicited to or parsed with success
Definition: metsynop.h:54
#define TEMP_SEC_8
mask bit meaning sec 8 of a part of TEMP report parsed with success
Definition: mettemp.h:101
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
struct misc3 misc[SYNOP_NMISC]
Definition: metsynop.h:210
size_t n
Definition: metsynop.h:209
char spsp[4]
Definition: metsynop.h:204
char SpSp[4]
Definition: metsynop.h:203
char hshs[4]
Definition: metsynop.h:194
char Ns[2]
Definition: metsynop.h:192
char C[2]
Definition: metsynop.h:193
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_sec3 s3
Definition: metsynop.h:300
struct synop_sec4 s4
Definition: metsynop.h:301
struct synop_sec0 s0
Definition: metsynop.h:297
char A1[2]
Definition: metsynop.h:94
char Cl[2]
Definition: metsynop.h:149
char ix[2]
Definition: metsynop.h:124
char Ch[2]
Definition: metsynop.h:151
char h[2]
Definition: metsynop.h:125
char N[2]
Definition: metsynop.h:127
char VV[4]
Definition: metsynop.h:126
char Cm[2]
Definition: metsynop.h:150
char ww[4]
Definition: metsynop.h:144
char Nh[2]
Definition: metsynop.h:148
char W1[2]
Definition: metsynop.h:146
char W2[2]
Definition: metsynop.h:147
char Dh[2]
Definition: metsynop.h:249
char E[2]
Definition: metsynop.h:227
char XoXoXoXo[6]
Definition: metsynop.h:222
char Dl[2]
Definition: metsynop.h:247
char R8[SYNOP_NMISC][6]
Definition: metsynop.h:258
struct nub3 nub[SYNOP_NNUB]
Definition: metsynop.h:259
struct data9 d9
Definition: metsynop.h:260
char C[2]
Definition: metsynop.h:250
char Dm[2]
Definition: metsynop.h:248
char E1[2]
Definition: metsynop.h:229
char Ct[2]
Definition: metsynop.h:272
char H1H1[4]
Definition: metsynop.h:271
char C1[2]
Definition: metsynop.h:270
char N1[2]
Definition: metsynop.h:269
char Cm[2]
Definition: mettemp.h:443
char h[2]
Definition: mettemp.h:442
char Ch[2]
Definition: mettemp.h:444
char Cl[2]
Definition: mettemp.h:441
char Nh[2]
Definition: mettemp.h:440
struct temp_b_sec8 s8
Definition: mettemp.h:474
int mask
Definition: mettemp.h:468
Store the whole TEMP report.
Definition: mettemp.h:511
struct temp_b b
Definition: mettemp.h:516