2 #include "rapic_routines.h"
5 #include <netinet/in.h>
6 void rapic_decode(unsigned char *inbuf, int inbytes, unsigned char *outbuf, int *outbytes,
7 float *azim, float *elev, int *delta_time)
9 /* Decode RLE rapic buffer.
11 * Output to 'outbuf' and indicate the size w/ 'nout'.
14 /* There is some risidual parsing to do:
17 * <data> AAA.A,EEE.E,TTT=LEN16D1D1D1NLD1D1D1NLNL
19 * AAA.A Azimuth in degrees
20 * EEE.E Elevation in degress
21 * TTT Delta time in seconds since the start of this scan
22 * LEN16 2 byte long length of radial
24 * D1 Run length coded Data.
25 * NL Null The Next Byte is count of NULL data.
26 * NLNL End of this Radial
28 * eg. There will be no white space in the actual radial data.
30 * @066.1,010.6,004=002082B2817F8C84830048D72D0038
31 * 999C0036202D35FD2C00238A99008AFE920000
34 * Dt = 4 sec since the start
35 * 0020 = Bytes to follow
36 * Data = 82,B2,81,7F,8C,84,83
37 * 0048 = 48H null bytes
39 * 0038 = 38H null bytes
41 * 0036 = 36H Null bytes
42 * ........................
44 * In versions before 10.1
46 * <data> AAALEN16D1D1D1NLD1D1D1NLNL
48 * AAA Azimuth in degrees
49 * LEN16 2 byte long length of radial
51 * D1 Run length coded Data.
52 * NL Null The Next Byte is count of NULL data.
53 * NLNL End of this Radial
55 * eg. There will be no white space in the actual radial data.
57 * @066002082B2817F8C84830048D72D0038
58 * 999C0036202D35FD2C00238A99008AFE920000
60 * 0020 = Bytes to follow
61 * Data = 82,B2,81,7F,8C,84,83
62 * 0048 = 48H null bytes
64 * 0038 = 38H null bytes
66 * 0036 = 36H Null bytes
67 * ........................
73 /* The parser won't give us a line w/o '@' at the begining nor '\0\0'
74 * at the end. So we can be sure of that.
79 unsigned short nnulls;
82 /* Find the '=' and start RLE decode from there. */
84 memset(prefix, '\0', sizeof(prefix));
85 memcpy(prefix, &inbuf[1], 15);
87 sscanf(prefix, "%f,%f,%d", azim, elev, delta_time);
88 /* fprintf(stderr, "AZIM=%f, ELEV=%f, TTT=%d\n", *azim, *elev, *delta_time); */
90 /* Now, decode RLE. Don't care about 17,18 (they are the RLE buf size) */
91 memcpy(&i16, &inbuf[17], 2);
93 /* fprintf(stderr, "Expecting %d bins\n", (int)i16); */
96 /* fprintf(stderr, "i=%d byte=%2.2x(next %2.2x%2.2x) outbytes=%d\n", i, (unsigned char)inbuf[i], (unsigned char)inbuf[i+1], (unsigned char)inbuf[i+2], *outbytes); */
97 if (inbuf[i] == '\0') { /* Next byte is a count of NULL's */
99 nnulls = (int)inbuf[i];
100 /* fprintf(stderr, "NULL .. number of nulls=%4.4x\n", nnulls); */
101 memset(&outbuf[*outbytes], '\0', (int)nnulls);
104 /* fprintf(stderr, "Data\n"); */
106 outbuf[*outbytes] = inbuf[i];
112 /* fprintf(stderr, "Decoded RLE: len=%d buf=<", *outbytes); */
113 /* binprint(outbuf, *outbytes); */
114 /* fprintf(stderr, ">\n"); */
119 /*---------------------------------------------------------*/
123 /*---------------------------------------------------------*/
124 void binprint(char *s, int n)
129 fprintf(stderr,"%c", s[i]);
133 /* Shut the damn linker up for librsl.so on Linux. This reference is
134 * in the HDF library; don't need it, don't care.
142 void rapic_fix_time (Ray *ray)
146 /* Fixes possible overflow values in month, day, year, hh, mm, ss */
147 /* Normally, ss should be the overflow. This code ensures end of
148 * month, year and century are handled correctly by using the Unix
151 if (ray == NULL) return;
152 memset(&the_time, 0, sizeof(struct tm));
153 the_time.tm_sec = ray->h.sec;
154 fsec = ray->h.sec - the_time.tm_sec;
155 the_time.tm_min = ray->h.minute;
156 the_time.tm_hour = ray->h.hour;
157 the_time.tm_mon = ray->h.month - 1;
158 the_time.tm_year = ray->h.year - 1900;
159 the_time.tm_mday = ray->h.day;
160 the_time.tm_isdst = -1;
161 (void) mktime(&the_time);
162 /* The time is fixed. */
163 ray->h.sec = the_time.tm_sec;
165 ray->h.minute = the_time.tm_min;
166 ray->h.hour = the_time.tm_hour;
167 ray->h.month = the_time.tm_mon + 1;
168 ray->h.year = the_time.tm_year + 1900;
169 ray->h.day = the_time.tm_mday;
173 void rapic_load_ray_header(Rapic_sweep_header rh, int iray, int isweep, float elev, float azim, Ray_header *h)
175 sscanf(rh.yyyymoddhhmmss,"%4d%2d%2d%2d%2d%2f",
176 &h->year,&h->month,&h->day,
177 &h->hour, &h->minute, &h->sec);
179 h->unam_rng = rh.end_range/1000.0; /* Unambiguous range. (KM). */
180 h->azimuth = azim; /* Azimuth angle. (degrees). Must be positive
181 * 0=North, 90=east, -90/270=west.
182 * This angle is the mean azimuth for the whole ray.
183 * Eg. for NSIG the beginning and end azimuths are
186 h->ray_num = iray; /* Ray no. within elevation scan. */
187 h->elev = rh.elev; /* Elevation angle. (degrees). */
188 h->elev_num = isweep; /* Elevation no. within volume scan. */
190 h->range_bin1 = rh.start_range; /* Range to first gate.(meters) */
191 h->gate_size = rh.range_resolution; /* Data gate size (meters)*/
193 h->vel_res = rh.range_resolution; /* Doppler velocity resolution */
194 h->sweep_rate = rh.anglerate/6.0; /* Sweep rate. Full sweeps/min. */
196 h->prf = rh.prf; /* Pulse repetition frequency, in Hz. */
197 h->azim_rate = rh.anglerate; /* degrees/sec */
199 h->pitch = 0; /* Pitch angle. */
200 h->roll = 0; /* Roll angle. */
201 h->heading = 0; /* Heading. */
202 h->pitch_rate = 0; /* (angle/sec) */
203 h->roll_rate = 0; /* (angle/sec) */
204 h->heading_rate = 0; /* (angle/sec) */
205 h->lat = rh.lat; /* Latitude (degrees) */
206 h->lon = rh.lon; /* Longitude (degrees) */
207 h->alt = rh.height; /* Altitude (m) */
208 h->rvc = 0; /* Radial velocity correction (m/sec) */
209 h->vel_east = 0; /* Platform velocity to the east (m/sec) */
210 h->vel_north = 0; /* Platform velocity to the north (m/sec) */
211 h->vel_up = 0; /* Platform velocity toward up (m/sec) */
212 h->pulse_count = 0; /* Pulses used in a single dwell time. */
213 h->pulse_width = rh.pulselen; /* Pulse width (micro-sec). */
214 h->beam_width = rh.angle_resolution; /* Beamwidth in degrees. */
215 h->frequency = rh.freq/1000.0; /* Carrier freq. GHz. */
216 h->wavelength = 0; /* Wavelength. Meters. */
217 h->nyq_vel = rh.nyquist; /* Nyquist velocity. m/s */
222 extern float rapic_nyquist;
224 float RAPIC_DZ_F(unsigned char x) {
225 if (x == 0) return NOECHO;
226 return (((float)x-64)/2.0); /* rapic -> float */
229 float RAPIC_VR_F(unsigned char x) {
230 if (x == 0) return BADVAL;
231 return (((float)((int)x-128))/128.0*rapic_nyquist); /* rapic -> float */
234 float RAPIC_SW_F(unsigned char x) {
235 if (x == 0) return NOECHO;
236 return (((float)x)/256.0*rapic_nyquist); /* rapic -> float */
239 float RAPIC_ZT_F(unsigned char x) {
240 return RAPIC_DZ_F(x);
243 float RAPIC_ZD_F(unsigned char x) {
244 if (x == 0) return NOECHO;
245 return (((float)x-128)/16.0); /* rapic -> float */
248 /* USE RSL INDEXING! */
249 static float (*RAPIC_f_list[])(unsigned char x) = {RAPIC_DZ_F,
259 void rapic_load_ray_data(unsigned char *buf, int bufsize, int ifield, Ray *ray)
261 /* ifield is the RSL numbering scheme for field types. The conversion
262 * is done in rapic.y. In other words, we've already converted rapic
263 * index to RSL indexes.
266 for (i=0; i<bufsize; i++) {
267 ray->range[i] = ray->h.invf(RAPIC_f_list[ifield](buf[i]));
268 /* fprintf(stderr,"i=%d ifield=%d, buf[%d]=%2.2x, ray->range[%d]=%4.4x value=%f\n", i,ifield,i,buf[i],i,ray->range[i], RAPIC_f_list[ifield](buf[i]) ); */
270 ray->h.nbins = bufsize;
273 Radar *fill_header(Radar *radar)
275 /* Learn as much as possible from the Ray headers. Place this
276 * information into radar->h.xxxxxx
284 if (radar == NULL) return NULL;
285 for (i=0; i<radar->h.nvolumes && !(volume = radar->v[i]); i++)
287 if (volume == NULL) return NULL;
289 ray = RSL_get_first_ray_of_volume(volume);
290 if (ray == NULL) return NULL;
292 radar->h.month = ray->h.month;
293 radar->h.day = ray->h.day;
294 radar->h.year = ray->h.year;
295 radar->h.hour = ray->h.hour;
296 radar->h.minute= ray->h.minute;
297 radar->h.sec = ray->h.sec; /* Second plus fractional part. */
298 sprintf(radar->h.radar_type, "rapic"); /* Type of radar. */
299 /* nvolumes is already filled in YACC. */
300 /* number is already filled in YACC. */
301 /* name is already filled in YACC. */
302 /* radar_name is already filled in YACC. */
303 /* radar->h.city[15]; */ /* Not available from RAPIC. */
304 /* radar->h.state[3]; */ /* Not available from RAPIC. */
305 /* radar->h.country[15]; */ /* Not available from RAPIC. */
307 /** Latitude deg, min, sec **/
308 radar->h.latd = (int)ray->h.lat;
309 tmp = (ray->h.lat - radar->h.latd) * 60.0;
310 radar->h.latm = (int)tmp;
311 radar->h.lats = (int)((tmp - radar->h.latm) * 60.0);
312 /** Longitude deg, min, sec **/
313 radar->h.lond = (int)ray->h.lon;
314 tmp = (ray->h.lon - radar->h.lond) * 60.0;
315 radar->h.lonm = (int)tmp;
316 radar->h.lons = (int)((tmp - radar->h.lonm) * 60.0);
318 radar->h.height = ray->h.alt; /* height of site in meters above sea level*/
319 radar->h.spulse = 0; /* length of short pulse (ns)*/
320 radar->h.lpulse = 0; /* length of long pulse (ns) */