]> Pileus Git - ~andy/rsl/blob - src/rainbow.c
7d5862c00f525cfc2fe1eba141c3b9d9046421ba
[~andy/rsl] / src / rainbow.c
1 /*
2     NASA/TRMM, Code 912
3     This is the TRMM Office Radar Software Library.
4     Copyright (C) 2004
5             Bart Kelley
6             George Mason University
7             Fairfax, Virginia
8
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Library General Public
11     License as published by the Free Software Foundation; either
12     version 2 of the License, or (at your option) any later version.
13
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Library General Public License for more details.
18
19     You should have received a copy of the GNU Library General Public
20     License along with this library; if not, write to the Free Software
21     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include "rsl.h"
28 #include "rainbow.h"
29
30 static int get_param_int(char *buf)
31 {
32     /* Returns an integer parameter from a header line. */
33
34     int value;
35     char *substr;
36
37     substr = index(buf, ':');
38     sscanf(substr, ": %d", &value);
39     return value;
40 }
41
42 static float get_param_float(char *buf)
43 {
44     /* Returns a floating point parameter from a header line. */
45
46     float value;
47     char *substr;
48
49     substr = index(buf, ':');
50     sscanf(substr, ": %f", &value);
51     return value;
52 }
53
54
55 static char *get_param_string(char *buf)
56 {
57     /* Returns a string parameter from a header line. */
58
59     static char string[20];
60     char *substr;
61
62     substr = index(buf, ':');
63     sscanf(substr, ": %s", string);
64     return string;
65 }
66
67 void A_label(Rainbow_hdr *rainbow_header, char* buf)
68 {
69     int labelnum;
70     char label;
71
72     sscanf(buf, "%c%d", &label, &labelnum);
73
74     if (labelnum == 3) 
75         rainbow_header->az_step = get_param_float(buf);
76      else if (labelnum == 9)
77         rainbow_header->nsweeps = get_param_int(buf);
78 }
79
80 void F_label(Rainbow_hdr *rainbow_header, char* buf)
81 {
82     int labelnum, day, month, year, sec, minute, hour;
83     float lat, lon;
84
85     sscanf(buf, "%*c%d", &labelnum);
86
87     switch (labelnum) {
88         case 3:
89             rainbow_header->compressed = get_param_int(buf);
90             break;
91         case 4:
92             sscanf(buf, "%*c%*d : %f %f", &lon, &lat);
93             rainbow_header->lon = lon;
94             rainbow_header->lat = lat;
95             break;
96         case 5:
97             sscanf(buf, "%*c%*d : %d %d %d", &day, &month, &year);
98             rainbow_header->month = month;
99             rainbow_header->day = day;
100             rainbow_header->year = year;
101             break;
102         case 6:
103             sscanf(buf, "%*c%*d : %d %d %d", &sec, &minute, &hour);
104             rainbow_header->hour = hour;
105             rainbow_header->minute = minute;
106             rainbow_header->sec = sec;
107             break;
108         case 9:
109             rainbow_header->datatype = get_param_int(buf);
110             break;
111     }
112 }
113
114 void H_label(Rainbow_hdr *rainbow_header, char* buf)
115 {
116     int labelnum;
117     char label;
118
119     sscanf(buf, "%c%d", &label, &labelnum);
120
121     if (labelnum == 3)
122       rainbow_header->filetype = get_param_int(buf);
123     else if (labelnum == 8)
124       strcpy(rainbow_header->radarname, get_param_string(buf));
125 }
126
127 void P_label(Rainbow_hdr *rainbow_header, char* buf)
128 {
129     int labelnum;
130     char label;
131
132     sscanf(buf, "%c%d", &label, &labelnum);
133
134     if (labelnum == 3)
135         rainbow_header->range_start= get_param_float(buf);
136     else if (labelnum == 4)
137         rainbow_header->range_stop = get_param_float(buf);
138     else if (labelnum == 5)
139         rainbow_header->range_step = get_param_float(buf);
140 }
141
142 void R_label(Rainbow_hdr *rainbow_header, char* buf)
143 {
144     int labelnum;
145
146     sscanf(buf, "%*c%d", &labelnum);
147
148     if (labelnum == 1)
149       rainbow_header->nbins = get_param_int(buf);
150     else if (labelnum == 2)
151       rainbow_header->bin_resolution = get_param_float(buf);
152     else if (labelnum == 8)
153       rainbow_header->nvalues = get_param_int(buf);
154 }
155
156 void W_label(Rainbow_hdr *rainbow_hdr, char* buf)
157 {
158     int labelnum, az_start, az_stop, pw_code, prf_high, prf_low, zdata;
159     int vdata, wdata, unfolding, cdata, ddata, uzdata;
160     float elev, az_step, az_rate, range_stop;
161
162     sscanf(buf, "%*c%d : %f %d %d %f %f %d %d %d %d %d %d %d %f %d %d %d",
163             &labelnum, &elev, &az_start, &az_stop, &az_step,
164             &az_rate, &pw_code, &prf_high, &prf_low, &zdata, &vdata,
165             &wdata, &unfolding, &range_stop, &cdata, &ddata, &uzdata);
166
167     /* Note: Only need to collect parameters 1, 5, 7, 8, and 13 for each
168      * elevation.  Parameters 2, 3, and 4 are fixed at 0, 359, and 1 for volume
169      * scan.  The remaining parameters can be taken once from label number 1
170      * (first elevation).  Also, don't need az_step; got it from A3. 
171      */
172
173     if (labelnum == 1) {
174         rainbow_hdr->az_start = az_start;
175         rainbow_hdr->az_stop =  az_stop;
176         rainbow_hdr->pulse_width_code = pw_code;
177         rainbow_hdr->zdata = zdata;
178         rainbow_hdr->vdata = vdata;
179         rainbow_hdr->wdata = wdata;
180         rainbow_hdr->unfolding = unfolding;
181         rainbow_hdr->cdata = cdata;
182         rainbow_hdr->ddata = ddata;
183         rainbow_hdr->uzdata = uzdata;
184     }
185     rainbow_hdr->elev_params[labelnum-1] =
186         (struct elev_params *) malloc(sizeof(struct elev_params));
187     rainbow_hdr->elev_params[labelnum-1]->elev_angle = elev;
188     rainbow_hdr->elev_params[labelnum-1]->az_rate = az_rate;
189     rainbow_hdr->elev_params[labelnum-1]->prf_high = prf_high;
190     rainbow_hdr->elev_params[labelnum-1]->prf_low = prf_low;
191     rainbow_hdr->elev_params[labelnum-1]->maxrange = range_stop;
192 }
193
194 /**********************************************************/
195 /*                                                        */
196 /*                    read_hdr_line                       */
197 /*                                                        */
198 /**********************************************************/
199
200 static int read_hdr_line(char *buf, int maxchars, FILE *fp)
201 {
202     /* Read a line from the Rainbow file header into character buffer.
203      * Function returns the first character in buffer (the "label") if
204      * the line was successfully read, -1 otherwise.
205      *
206      * Note: the following control characters (defined in rainbow.h) are used
207      * in the Rainbow header:
208      *   CR  - Carriage Return: end of a line.
209      *   ETB - End of Transmission Block: divides header into sections (we can
210      *         ignore this one.)
211      *   ETX - End of Text: end of header.
212      */
213
214     int c = 0;
215     int badline = 0, i;
216
217     i = 0;
218     while ((c = getc(fp)) != CR && c != ETX) {
219         if (c == ETB) {               
220             c = getc(fp);                /* Read past both <ETB> and the */
221             if (c == CR) c = getc(fp);   /* combination <ETB><CR>.       */
222         }
223
224         buf[i++] = c;
225
226         if (i == maxchars) {
227             badline = 1;
228             break;
229         }
230     }
231
232     if (badline) {
233         fprintf(stderr,"A header line exceeded buffer size %d.\n",maxchars);
234         fprintf(stderr,"Did not find end-of-line character 0x%02x.\n",CR);
235         buf[maxchars - 1] = '\0';  /* Make it a legal string anyway. */
236         return -1;
237     }
238
239     buf[i] = '\0';
240
241     if (c != ETX) c = (int) buf[0];
242     return c;
243 }
244
245 /**********************************************************/
246 /*                                                        */
247 /*                  read_rainbow_header                   */
248 /*                                                        */
249 /**********************************************************/
250
251 #define BUFSIZE 128
252
253 void read_rainbow_header(Rainbow_hdr *rainbow_header, FILE *fp)
254 {
255     /* Reads parameters from Rainbow file header into a rainbow header
256        structure. */
257
258     char buf[BUFSIZE];
259     int label;
260
261     /* Read each line of the header and extract parameters according to the
262      * label.  The label is a single alphabetic character at the beginning
263      * of the line which indicates a category of parameters.
264      */
265
266     while ((label = read_hdr_line(buf, BUFSIZE, fp)) != ETX && label > 0) {
267         switch (label) {
268             case 'H': H_label(rainbow_header, buf);
269                       break;
270             case 'P': P_label(rainbow_header, buf);
271                       break;
272             case 'W': W_label(rainbow_header, buf);
273                       break;
274             case 'F': F_label(rainbow_header, buf);
275                       break;
276             case 'R': R_label(rainbow_header, buf);
277                       break;
278             case 'A': A_label(rainbow_header, buf);
279                       break;
280             case 'N': rainbow_header->product = get_param_int(buf);
281                       break;
282             case 'X': /* X_label(rainbow_header, buf); */
283                       break;
284         }
285     }
286 }