bufr2synop 0.24.0
bufr2tac_sqparse.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_sqparse.c
22 \brief file with the code to parse a sequence of descriptors for a subset
23 */
24#include "bufr2tac.h"
25
26/*!
27 \fn int find_descriptor(int *haystack, size_t nlst, int needle)
28 \brief Try to find a descriptor in an array
29 \param haystack array of integers as descriptors
30 \param nlst number of descriptors in array
31 \param needle descriptor to find
32
33 it returns 1 if found, 0 otherwise.
34*/
35int find_descriptor ( int *haystack, size_t nlst, int needle )
36{
37 size_t i = 0;
38 while ( ( i < nlst ) && ( haystack[i] != needle ) )
39 {
40 i++;
41 }
42 return ( i < nlst );
43}
44
45
46/*!
47 \fn int find_descriptor(int *haystack, size_t nlst, int needlemin, int needlemax)
48 \brief Try to find a descriptor in an array between two limits
49 \param haystack array of integers as descriptors
50 \param nlst number of descriptors in array
51 \param needlemin minimum descriptor to find
52 \param needlemax maximum descriptor to find
53
54 It tries to find a descriptor in haystack which is greater or equal to needlemin and
55 lesser or equal to needlemax
56
57 it returns 1 if found, 0 otherwise.
58*/
59int find_descriptor_interval ( int *haystack, size_t nlst, int needlemin, int needlemax )
60{
61 size_t i = 0;
62
63 while ( ( i < nlst ) && ( haystack[i] > needlemax || haystack[i] < needlemin ) )
64 {
65 i++;
66 }
67 return ( i < nlst );
68}
69
70/*!
71 \fn int parse_subset_sequence(struct metreport *m, struct bufr_subset_sequence_data *sq, struct bufr2tac_subset_state *st, int *kdtlst, size_t nlst, int *ksec1, char *err)
72 \brief Parse a sequence of expanded descriptors for a subset
73 \param m pointer to a struct \ref metreport where to set the data
74 \param sq pointer to a struct \ref bufr_subset_sequence_data where the values for sequence of descriptors for a subset has been decoded
75 \param st pointer to a struct \ref bufr2tac_subset_state
76 \param kdtlst array of integers with descriptors
77 \param nlst number of descriptors in \a kdtlst
78 \param ksec1 array of auxiliar integers decoded by bufrdc ECMWF library
79 \param err string where to write errors if any
80*/
81int parse_subset_sequence ( struct metreport *m, struct bufr_subset_sequence_data *sq, struct bufr2tac_subset_state *st, int *kdtlst, size_t nlst, int *ksec1, char *err )
82{
83 /* Clean the state */
84 memset ( st, 0, sizeof ( struct bufr2tac_subset_state ) );
85
86 /* First task to do is figure out the type of report */
87 switch ( ksec1[5] )
88 {
89 case 0:
90 if ( find_descriptor_interval ( kdtlst, nlst, 307071, 307073 ) )
91 {
92 strcpy ( st->type_report, "CLIMAT" ); // FM-71 CLIMAT
93 }
94 else if ( find_descriptor_interval ( kdtlst, nlst, 307079, 307086 ) ||
95 find_descriptor ( kdtlst, nlst,307091 ) ||
96 find_descriptor ( kdtlst, nlst,307092 ) ||
97 find_descriptor ( kdtlst, nlst,307096 ) ||
98 find_descriptor ( kdtlst, nlst,307182 ) ||
99 ksec1[6] == 0 || ksec1[6] == 1 || ksec1[6] == 2 )
100 {
101 strcpy ( st->type_report,"AAXX" ); // FM-12 synop
102 }
103 else if ( find_descriptor ( kdtlst, nlst,307090 ) ||
104 find_descriptor ( kdtlst, nlst,301092 ) ||
105 ksec1[6] == 3 || ksec1[6] == 4 || ksec1[6] == 5 )
106 {
107 strcpy ( st->type_report,"OOXX" ); // FM-14 synop-mobil
108 }
109 break;
110 case 1:
111 if ( find_descriptor_interval ( kdtlst, nlst, 308004, 308005 ) ||
112 find_descriptor ( kdtlst, nlst,301093 ) ||
113 find_descriptor ( kdtlst, nlst,308009 ) ||
114 find_descriptor ( kdtlst, nlst,1011 ) )
115 {
116 strcpy ( st->type_report,"BBXX" ); // FM-13 ship
117 }
118 else if ( find_descriptor_interval ( kdtlst, nlst, 308001, 308003 ) ||
119 find_descriptor ( kdtlst, nlst,315008 ) ||
120 find_descriptor ( kdtlst, nlst,315009 ) ||
121 find_descriptor ( kdtlst, nlst,1005 ) ||
122 find_descriptor ( kdtlst, nlst,2036 ) ||
123 find_descriptor ( kdtlst, nlst,2149 ) ||
124 ksec1[6] == 25 )
125 {
126 strcpy ( st->type_report,"ZZYY" ); // FM-18 buoy
127 }
128 else if ( find_descriptor_interval ( kdtlst, nlst, 308011, 308013 ) )
129 {
130 strcpy ( st->type_report, "CLIMAT SHIP" ); // FM-71 CLIMAT SHIP
131 }
132 else if ( find_descriptor ( kdtlst, nlst,307090 ) )
133 {
134 // FIXME Some FM-14 are coded as category 1
135 strcpy ( st->type_report,"OOXX" ); // FM-14 synop-mobil
136 }
137 break;
138 case 2:
139 if ( find_descriptor_interval ( kdtlst, nlst, 309050, 309051 ) )
140 {
141 strcpy ( st->type_report,"PPXX" ); // PILOT, PILOT SHIP, PILOT DROP or PILOT MOBIL
142 }
143 else if ( find_descriptor ( kdtlst, nlst, 309052 ) ||
144 find_descriptor ( kdtlst, nlst, 309057 )
145 )
146 {
147 strcpy ( st->type_report,"TTXX" ); // TEMP, TEMP SHIP, TEMP MOBIL
148 }
149 break;
150 default:
151 sprintf ( err, "The data category %d is not parsed at the moment", ksec1[5] );
152 return 1;
153 }
154
155
156 if ( st->type_report[0] == '\0' )
157 {
158 sprintf ( err, "Cannot find the report type\n" );
159 return 1;
160 }
161
162 //if(DEBUG)
163 // printf("Going to parse a %s report\n", st->type_report);
164
165
166 if ( strcmp ( st->type_report,"AAXX" ) == 0 || strcmp ( st->type_report,"BBXX" ) == 0 || strcmp ( st->type_report,"OOXX" ) == 0 )
167 {
168 // Parse FM-12, FM-13 and FM-14
169 if ( parse_subset_as_synop ( m, st, sq, err ) == 0 )
170 {
173 return print_synop_report ( m );
174 }
175
176 }
177 else if ( strcmp ( st->type_report,"ZZYY" ) == 0 )
178 {
179 // parse BUOY
180 if ( parse_subset_as_buoy ( m, st, sq, err ) == 0 )
181 {
184 return print_buoy_report ( m );
185 }
186 }
187 else if ( strcmp ( st->type_report,"TTXX" ) == 0 )
188 {
189 // psrse TEMP
190 if ( parse_subset_as_temp ( m, st, sq, err ) == 0 )
191 {
194 return print_temp_report ( m );
195 }
196 }
197 else if ( strcmp ( st->type_report,"CLIMAT" ) == 0 )
198 {
199 // psrse CLIMAT
200 if ( parse_subset_as_climat ( m, st, sq, err ) == 0 )
201 {
204 return print_climat_report ( m );
205 }
206 }
207
208 // when reached this point we have han error
211 return 1;
212}
int BUFR2TAC_DEBUG_LEVEL
Definition: bufr2tac.c:31
Include header file for binary bufr2tac.
int parse_subset_as_synop(struct metreport *m, struct bufr2tac_subset_state *s, struct bufr_subset_sequence_data *sq, char *err)
parses a subset sequence as an Land fixed SYNOP FM-12, SHIP FM-13 or SYNOP-mobil FM-14 report
#define bufr_subset_sequence_data
To use bufrdeco library with legacy old code using ECMWF library which is not used currently.
Definition: bufr2tac.h:220
int print_buoy_report(struct metreport *m)
prints a buoy into a string
int parse_subset_as_temp(struct metreport *m, struct bufr2tac_subset_state *s, struct bufr_subset_sequence_data *sq, char *err)
Definition: bufr2tac_temp.c:75
int print_climat_report(struct metreport *m)
prints a climat into a string
int parse_subset_as_climat(struct metreport *m, struct bufr2tac_subset_state *s, struct bufr_subset_sequence_data *sq, char *err)
int print_synop_report(struct metreport *m)
prints a synop into a string
int bufr2tac_print_error(struct bufr2tac_error_stack *e)
int parse_subset_as_buoy(struct metreport *m, struct bufr2tac_subset_state *s, struct bufr_subset_sequence_data *sq, char *err)
Definition: bufr2tac_buoy.c:74
int print_temp_report(struct metreport *m)
print the four parts of a decoded TEMP report from a BUFR file into strings
int find_descriptor(int *haystack, size_t nlst, int needle)
Try to find a descriptor in an array.
int parse_subset_sequence(struct metreport *m, struct bufr_subset_sequence_data *sq, struct bufr2tac_subset_state *st, int *kdtlst, size_t nlst, int *ksec1, char *err)
Parse a sequence of expanded descriptors for a subset.
int find_descriptor_interval(int *haystack, size_t nlst, int needlemin, int needlemax)
stores information needed to parse a sequential list of expanded descriptors for a subset
Definition: bufr2tac.h:246
char type_report[16]
Definition: bufr2tac.h:247
struct bufr2tac_error_stack e
Definition: bufr2tac.h:248
all the information for a meteorological report in WMO text format from a BUFR file
Definition: bufr2tac.h:309