5 /*----------------------------------------------------------------------**
9 **----------------------------------------------------------------------**
13 ** Converts an EDGE Volume structure to an RSL Radar structure
17 ** Radar *RSL_EDGE_to_radar(EDGE_filename); -* Usage Section with comments *-
18 ** char *EDGE_filename; -* name of EDGE volume file *-
22 ** This program creates an RSL radar data structure copies an Edge
23 ** volume data structure into it and returns the pointer to the Radar
28 ** Copyright (c) 1997 by Enterprise Electronics Corporation
29 ** All Rights Reserved
31 ** This program is copyright by Enterprise Electronics Corpora-
32 ** tion, Enterprise, Alabama, USA 36330 (334) 347-3478. It is
33 ** licensed for use on a specific CPU and is not to be
34 ** transferred or otherwise divulged. Copies or modifications of
35 ** this program must carry this copyright notice.
41 ** Software Suite - EDGE
43 ** Reference number - SP1/PGM/
44 ** Revision number - $Revision: 1.3 $
45 ** Release State - $State: Exp $
46 ** Author, designer - Don Burrows
47 ** Modification Date - $Date: 1999/11/23 00:36:00 $
48 ** Modified by - $Author: merritt $
49 ** $Source: /nfs/trmm/src/CVS/rsl/edge_to_radar.c,v $
51 ** MODIFICATION RECORD
53 ** $Log: edge_to_radar.c,v $
54 ** Revision 1.3 1999/11/23 00:36:00 merritt
55 ** auto configure scripts added
57 ** Revision 1.2 1999/04/02 16:14:45 merritt
60 ** Revision 1.1 1999/03/31 22:35:16 merritt
61 ** round 1 for edge incorporation. Still seg faults for any_to_gif
64 **----------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------*/
67 /* Feature Test Switches */
68 /*----------------------------------------------------------------------*/
69 #define _POSIX_SOURCE 1
71 /*----------------------------------------------------------------------*/
72 /* System Headers { full list in stdinc.h } */
73 /*----------------------------------------------------------------------*/
74 #include <stdio.h> /* stdio library */
75 #include <stddef.h> /* Some popular symbols */
76 #include <stdlib.h> /* Some standard funct. */
77 #include <unistd.h> /* POSIX symbols definitions */
82 /*----------------------------------------------------------------------*/
83 /* Application Headers */
84 /*----------------------------------------------------------------------*/
88 /*----------------------------------------------------------------------*/
90 /*----------------------------------------------------------------------*/
93 /*----------------------------------------------------------------------*/
94 /* External (Import) Variables */
95 /*----------------------------------------------------------------------*/
96 extern int radar_verbose_flag;
98 /*----------------------------------------------------------------------*/
99 /* External Functions */
100 /*----------------------------------------------------------------------*/
102 /*----------------------------------------------------------------------*/
103 /* Structures and Unions */
104 /*----------------------------------------------------------------------*/
106 /*----------------------------------------------------------------------*/
107 /* Global (Export) Variables */
108 /*----------------------------------------------------------------------*/
110 /*----------------------------------------------------------------------*/
111 /* Local (Static) Variables */
112 /*----------------------------------------------------------------------*/
113 static struct vol_struct *EDGE_vol=NULL;
114 static int num_sweeps,num_rays,num_bins,gate_width;
115 static float azimuth,elevation;
116 static float prf,wavelength,nyq_vel,meansr;
117 static struct tm *sweeptime;
118 static float lat,lon;
119 static int bytes_bin;
120 static float beam_width;
121 static float (*f)(Range x);
122 static Range (*invf)(float x);
124 /*----------------------------------------------------------------------*/
125 /* Signal Catching Functions */
126 /*----------------------------------------------------------------------*/
128 /*----------------------------------------------------------------------*/
130 /*----------------------------------------------------------------------*/
132 Ray *Fill_Ray_Header(int num_bins,int isweep,int iray)
136 RSL_ray = RSL_new_ray(num_bins);
137 RSL_ray->h.sec = sweeptime->tm_sec;
138 RSL_ray->h.minute = sweeptime->tm_min;
139 RSL_ray->h.hour = sweeptime->tm_hour;
140 RSL_ray->h.day = sweeptime->tm_mday;
141 RSL_ray->h.month = sweeptime->tm_mon+1;
142 RSL_ray->h.year = sweeptime->tm_year + 1900;
143 RSL_ray->h.unam_rng = 149851.274/prf;
144 RSL_ray->h.azimuth = azimuth;
145 RSL_ray->h.ray_num = iray;
146 RSL_ray->h.elev = elevation;
147 RSL_ray->h.elev_num = isweep;
148 RSL_ray->h.range_bin1 = gate_width;
149 RSL_ray->h.gate_size = gate_width;
150 RSL_ray->h.vel_res = nyq_vel/128.0;
151 RSL_ray->h.sweep_rate = meansr;
152 RSL_ray->h.prf = prf;
153 RSL_ray->h.azim_rate =
154 (float)EDGE_vol->sweep[isweep].rad.antenna_speed*0.55;
155 RSL_ray->h.lat = lat;
156 RSL_ray->h.lon = lon;
157 RSL_ray->h.alt = EDGE_vol->sweep[isweep].rad.antenna_height;
159 RSL_ray->h.pulse_count = EDGE_vol->sweep[isweep].rad.pulses;
160 RSL_ray->h.pulse_count = EDGE_vol->sweep[isweep].rad.pulse_width*1.2+0.8;
161 RSL_ray->h.beam_width = beam_width;
162 RSL_ray->h.frequency = 299.702547/wavelength;
163 RSL_ray->h.wavelength = wavelength;
164 RSL_ray->h.nyq_vel = nyq_vel;
166 RSL_ray->h.invf = invf;
167 RSL_ray->h.nbins = num_bins;
171 /*----------------------------------------------------------------------*/
173 /*----------------------------------------------------------------------*/
175 Radar *RSL_EDGE_to_radar(char *EDGE_filename)
179 Sweep *sweep_u,*sweep_z,*sweep_v,*sweep_w,*sweep_d=NULL;
180 unsigned char *EDGE_ray;
181 unsigned short *sray;
183 float start_azimuth,end_azimuth;
186 float uz,cz,rv,sw,zdr=0;
188 if (radar_verbose_flag) printf("EDGE_to_radar(%s)\n",EDGE_filename);
190 /** Load the EDGE volume structure **/
191 if (load_data((char **)&EDGE_vol,EDGE_filename,VOL_FILE) == -1)
194 fprintf(stderr,"EDGE_to_radar: Could not load EDGE Volume File: %s\n",EDGE_filename);
197 /** Allocating memory for radar structure **/
198 RSL_rad = RSL_new_radar(MAX_RADAR_VOLUMES);
201 fprintf(stderr, "EDGE_to_radar: radar is NULL\n");
205 bytes_bin = BYTES_BIN(EDGE_vol);
206 prf = (float)EDGE_vol->sweep[0].rad.prf1;
207 wavelength = EDGE_vol->sweep[0].rad.wavelength;
208 if (radar_verbose_flag) printf("bytes_bin: %d prf %5.0f wavelength %4.1f\n",
209 bytes_bin,prf,wavelength*100.0);
210 nyq_vel = prf*wavelength/4.0;
211 num_sweeps = EDGE_vol->num_sweeps;
212 if (radar_verbose_flag) printf("nyq_vel %5.1f num_sweeps %d\n",nyq_vel,num_sweeps);
215 for(i=0;i<num_sweeps-1;i++)
216 meansr += (float)(EDGE_vol->sweep[i+1].date-EDGE_vol->sweep[i].date);
217 meansr /= (float)num_sweeps-1.0;
218 meansr = 60.0/meansr;
220 voltime = gmtime(&EDGE_vol->date);
221 if (num_sweeps > MAX_SWEEPS) num_sweeps = MAX_SWEEPS;
224 /* Now fill the Radar header */
225 RSL_rad->h.sec = voltime->tm_sec;
226 RSL_rad->h.minute = voltime->tm_min;
227 RSL_rad->h.hour = voltime->tm_hour;
228 RSL_rad->h.day = voltime->tm_mday;
229 RSL_rad->h.month = voltime->tm_mon + 1;
230 RSL_rad->h.year = voltime->tm_year + 1900;
231 strcpy(RSL_rad->h.radar_type,"EDGE");
232 RSL_rad->h.nvolumes = NEEDED_VOLS;
233 RSL_rad->h.number = 553;/* What is this number supposed to be??? */
234 memmove(RSL_rad->h.name,EDGE_vol->sweep[0].rad.site_name,
235 sizeof(RSL_rad->h.name));
236 memmove(RSL_rad->h.radar_name,EDGE_vol->sweep[0].rad.radar_type,
237 sizeof(RSL_rad->h.radar_name));
238 memmove(RSL_rad->h.city,EDGE_vol->sweep[0].rad.site_name,
239 sizeof(RSL_rad->h.city));
240 memmove(RSL_rad->h.state,state,sizeof(RSL_rad->h.state));
241 RSL_rad->h.latd = EDGE_vol->sweep[0].rad.lat_deg;
242 RSL_rad->h.latm = EDGE_vol->sweep[0].rad.lat_min;
243 RSL_rad->h.lats = EDGE_vol->sweep[0].rad.lat_sec;
244 RSL_rad->h.lond = EDGE_vol->sweep[0].rad.long_deg;
245 RSL_rad->h.lonm = EDGE_vol->sweep[0].rad.long_min;
246 RSL_rad->h.lons = EDGE_vol->sweep[0].rad.long_sec;
247 if (RSL_rad->h.latd < 0)
249 if(RSL_rad->h.latm > 0) RSL_rad->h.latm *= -1;
250 if(RSL_rad->h.lats > 0) RSL_rad->h.lats *= -1;
252 if (RSL_rad->h.lond < 0)
254 if(RSL_rad->h.lonm > 0) RSL_rad->h.lonm *= -1;
255 if(RSL_rad->h.lons > 0) RSL_rad->h.lons *= -1;
257 lat = (float)RSL_rad->h.latd+(float)RSL_rad->h.latm/60.0+
258 (float)RSL_rad->h.lats/3600.0;
259 lon = (float)RSL_rad->h.lond+(float)RSL_rad->h.lonm/60.0+
260 (float)RSL_rad->h.lons/3600.0;
261 RSL_rad->h.height = EDGE_vol->sweep[0].rad.antenna_height;
262 RSL_rad->h.spulse = EDGE_vol->sweep[0].rad.pulse_width*1200 + 800;
263 RSL_rad->h.lpulse = EDGE_vol->sweep[0].rad.pulse_width*1200 + 800;
264 if (radar_verbose_flag) printf("Radar Header Filled\n");
266 Done with Radar header
267 Now create the necessary volumes and fill the
271 RSL_rad->v[DZ_INDEX] = RSL_new_volume(num_sweeps);
272 if (radar_verbose_flag) printf("DZ volume created index is %d\n",DZ_INDEX);
273 if ((RSL_rad->v[DZ_INDEX]->h.type_str = malloc(25)) != NULL)
275 RSL_rad->v[DZ_INDEX]->h.type_str[24] = '\0';
276 strcpy(RSL_rad->v[DZ_INDEX]->h.type_str,"Uncorrected Reflectivity");
278 if (radar_verbose_flag) printf("Uncorrected Reflectivity\n");
279 RSL_rad->v[DZ_INDEX]->h.nsweeps = num_sweeps;
280 if (radar_verbose_flag) printf("num_sweeps %d assigned\n",num_sweeps);
281 RSL_rad->v[DZ_INDEX]->h.f = DZ_F;
282 if (radar_verbose_flag) printf("DZ_F assigned\n");
283 RSL_rad->v[DZ_INDEX]->h.invf = DZ_INVF;
284 if (radar_verbose_flag) printf("DZ volume created and header Filled\n");
286 RSL_rad->v[CZ_INDEX] = RSL_new_volume(num_sweeps);
287 if ((RSL_rad->v[CZ_INDEX]->h.type_str = malloc(23)) != NULL)
289 RSL_rad->v[CZ_INDEX]->h.type_str[22] = '\0';
290 strcpy(RSL_rad->v[CZ_INDEX]->h.type_str,"Corrected Reflectivity");
292 RSL_rad->v[CZ_INDEX]->h.nsweeps = num_sweeps;
293 RSL_rad->v[CZ_INDEX]->h.f = CZ_F;
294 RSL_rad->v[CZ_INDEX]->h.invf = CZ_INVF;
295 if (radar_verbose_flag) printf("CZ volume created and header Filled\n");
297 RSL_rad->v[VR_INDEX] = RSL_new_volume(num_sweeps);
298 if ((RSL_rad->v[VR_INDEX]->h.type_str = malloc(16)) != NULL)
300 RSL_rad->v[VR_INDEX]->h.type_str[15] = '\0';
301 strcpy(RSL_rad->v[VR_INDEX]->h.type_str,"Radial Velocity");
303 RSL_rad->v[VR_INDEX]->h.nsweeps = num_sweeps;
304 RSL_rad->v[VR_INDEX]->h.f = VR_F;
305 RSL_rad->v[VR_INDEX]->h.invf = VR_INVF;
306 if (radar_verbose_flag) printf("VR volume created and header Filled\n");
308 RSL_rad->v[SW_INDEX] = RSL_new_volume(num_sweeps);
309 if ((RSL_rad->v[SW_INDEX]->h.type_str = malloc(15)) != NULL)
311 RSL_rad->v[SW_INDEX]->h.type_str[14] = '\0';
312 strcpy(RSL_rad->v[SW_INDEX]->h.type_str,"Spectrum Width");
314 RSL_rad->v[SW_INDEX]->h.nsweeps = num_sweeps;
315 RSL_rad->v[SW_INDEX]->h.f = SW_F;
316 RSL_rad->v[SW_INDEX]->h.invf = SW_INVF;
317 if (radar_verbose_flag) printf("SW volume created and header Filled\n");
321 RSL_rad->v[ZD_INDEX] = RSL_new_volume(num_sweeps);
322 strcpy(RSL_rad->v[ZD_INDEX]->h.type_str,"Differential Reflectivity");
323 if ((RSL_rad->v[ZD_INDEX]->h.type_str = malloc(26)) != NULL)
325 RSL_rad->v[ZD_INDEX]->h.type_str[25] = '\0';
326 strcpy(RSL_rad->v[ZD_INDEX]->h.type_str,"Differential Reflectivity");
328 RSL_rad->v[ZD_INDEX]->h.nsweeps = num_sweeps;
329 RSL_rad->v[ZD_INDEX]->h.f = ZD_F;
330 RSL_rad->v[ZD_INDEX]->h.invf = ZD_INVF;
331 if (radar_verbose_flag) printf("ZD volume created and header Filled\n");
334 Volume Headers complete now fill the sweeps
337 for (i=0;i<num_sweeps;i++)
339 if (radar_verbose_flag) printf("Sweep number %d\n",i);
340 num_rays = EDGE_vol->sweep[i].num_rays;
341 sray = (unsigned short *)RAY_PTR(EDGE_vol,i,10);
342 elevation = ((float)(BINEL2IANG100(sray[1])) +
343 (float)(BINEL2IANG100(sray[3])))/200.0;
344 sweeptime = gmtime(&EDGE_vol->sweep[i].date);
346 In newer versions of edge the beam width will be EDGE_vol->sweep[i].rad.beam_width
350 RSL_rad->v[DZ_INDEX]->sweep[i] = RSL_new_sweep(num_rays);
351 sweep_u = RSL_rad->v[DZ_INDEX]->sweep[i];
352 sweep_u->h.sweep_num = i;
353 sweep_u->h.elev = elevation;
354 sweep_u->h.beam_width = beam_width;
355 sweep_u->h.vert_half_bw = beam_width/2.0;
356 sweep_u->h.horz_half_bw = beam_width/2.0;
357 sweep_u->h.nrays = num_rays;
359 sweep_u->h.invf = DZ_INVF;
361 RSL_rad->v[CZ_INDEX]->sweep[i] = RSL_new_sweep(num_rays);
362 sweep_z = RSL_rad->v[CZ_INDEX]->sweep[i];
363 sweep_z->h.sweep_num = i;
364 sweep_z->h.elev = elevation;
365 sweep_z->h.beam_width = beam_width;
366 sweep_z->h.vert_half_bw = beam_width/2.0;
367 sweep_z->h.horz_half_bw = beam_width/2.0;
368 sweep_z->h.nrays = num_rays;
370 sweep_z->h.invf = CZ_INVF;
372 RSL_rad->v[VR_INDEX]->sweep[i] = RSL_new_sweep(num_rays);
373 sweep_v = RSL_rad->v[VR_INDEX]->sweep[i];
374 sweep_v->h.sweep_num = i;
375 sweep_v->h.elev = elevation;
376 sweep_v->h.beam_width = beam_width;
377 sweep_v->h.vert_half_bw = beam_width/2.0;
378 sweep_v->h.horz_half_bw = beam_width/2.0;
379 sweep_v->h.nrays = num_rays;
381 sweep_v->h.invf = VR_INVF;
383 RSL_rad->v[SW_INDEX]->sweep[i] = RSL_new_sweep(num_rays);
384 sweep_w = RSL_rad->v[SW_INDEX]->sweep[i];
385 sweep_w->h.sweep_num = i;
386 sweep_w->h.elev = elevation;
387 sweep_w->h.beam_width = beam_width;
388 sweep_w->h.vert_half_bw = beam_width/2.0;
389 sweep_w->h.horz_half_bw = beam_width/2.0;
390 sweep_w->h.nrays = num_rays;
392 sweep_w->h.invf = SW_INVF;
396 RSL_rad->v[ZD_INDEX]->sweep[i] = RSL_new_sweep(num_rays);
397 sweep_d = RSL_rad->v[ZD_INDEX]->sweep[i];
398 sweep_d->h.sweep_num = i;
399 sweep_d->h.elev = elevation;
400 sweep_d->h.beam_width = beam_width;
401 sweep_d->h.vert_half_bw = beam_width/2.0;
402 sweep_d->h.horz_half_bw = beam_width/2.0;
403 sweep_d->h.nrays = num_rays;
405 sweep_d->h.invf = ZD_INVF;
408 Sweeps are complete now to do the rays
410 num_bins = (int)EDGE_vol->sweep[i].rad.gates;
411 for (j=0;j<num_rays;j++)
413 sray = (unsigned short *)RAY_PTR(EDGE_vol,i,j);
414 elevation = ((float)(BINEL2IANG100(sray[1])) +
415 (float)(BINEL2IANG100(sray[3])))/200.0;
416 gate_width = EDGE_vol->sweep[i].rad.gw1;
417 start_azimuth =BIN2IANG(sray[0]);
418 end_azimuth =BIN2IANG(sray[2]);
419 azimuth = (start_azimuth + end_azimuth)/2.0;
420 if (fabs(end_azimuth - start_azimuth) > 180.0) azimuth = azimuth - 180.0;
421 if (azimuth < 0.0) azimuth = azimuth + 360.0;
425 sweep_u->ray[j] = Fill_Ray_Header(num_bins,i,j);
428 sweep_z->ray[j] = Fill_Ray_Header(num_bins,i,j);
431 sweep_v->ray[j] = Fill_Ray_Header(num_bins,i,j);
434 sweep_w->ray[j] = Fill_Ray_Header(num_bins,i,j);
439 sweep_d->ray[j] = Fill_Ray_Header(num_bins,i,j);
441 EDGE_ray = RAY_PTR(EDGE_vol,i,j);
444 Now fill the rest of the ray
446 for (k=0;k<num_bins;k++)
448 uz = (float)EDGE_ray[k*bytes_bin+2];
449 if (uz == 0.0) uz = NOECHO;
450 else if (uz > 255.0) uz = BADVAL;
451 else uz = uz/2.0-32.0;
452 cz = (float)EDGE_ray[k*bytes_bin];
453 if (cz == 0.0) cz = NOECHO;
454 else if (cz > 255.0) cz = BADVAL;
455 else cz = cz/2.0-32.0;
456 rv = (float)EDGE_ray[k*bytes_bin+1];
457 if (rv == 0.0) rv = NOECHO;
458 else if (rv > 255.0) rv = BADVAL;
459 else rv = (rv-128.0)/128.0*nyq_vel;
460 sw = (float)EDGE_ray[k*bytes_bin+3];
461 if (sw == 0.0) sw = NOECHO;
462 else if (sw > 255.0) sw = BADVAL;
463 else sw = sw/128.0*nyq_vel;
466 zdr = (float)EDGE_ray[k*bytes_bin+4];
467 if (zdr == 0.0) zdr = NOECHO;
468 else if (zdr > 255.0) zdr = BADVAL;
469 else zdr = (zdr-128.0)/16.0;
471 sweep_u->ray[j]->range[k] = DZ_INVF(uz);
472 sweep_z->ray[j]->range[k] = CZ_INVF(cz);
473 sweep_v->ray[j]->range[k] = VR_INVF(rv);
474 sweep_w->ray[j]->range[k] = SW_INVF(sw);
475 if (bytes_bin == 5) sweep_d->ray[j]->range[k] = DR_INVF(zdr);
479 if (radar_verbose_flag)
480 printf("EDGE to RSL conversion complete\n");
482 RSL_rad = RSL_prune_radar(RSL_rad);
485 /*-END OF MODULE--------------------------------------------------------*/
487 Radar *RSL_EDGE_to_radar(char *infile)
490 "The library libetor.a (or .so) was not found when RSL was installed,\n\
491 therefore, EDGE capability was disabled. If you now have libetor, then\n\
492 you must reinstall RSL to enable EDGE.\n"