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