From 71c71381ace86eb987172b22de55fbb837518b26 Mon Sep 17 00:00:00 2001 From: Andy Spencer Date: Thu, 23 Jun 2011 03:23:37 +0000 Subject: [PATCH] RSL v1.41 --- CHANGES | 18 +- Makefile.am | 2 +- README | 46 +--- africa.c | 1 + anyformat_to_radar.c | 353 +++++++++++++++-------------- configure.in | 2 +- doc/RSL_radar_intro.html | 2 +- doc/RSL_ray_header_struct.html | 2 +- doc/whats_new.html | 2 + dorade_to_radar.c | 1 - examples/any_to_gif.c | 2 +- examples/any_to_ppm.c | 3 +- examples/cappi_image.c | 1 + examples/dorade_main.c | 3 +- examples/killer_sweep.c | 2 +- examples/kwaj_subtract_one_day.c | 1 + examples/lassen_to_gif.c | 3 +- examples/print_hash_table.c | 3 +- examples/print_header_info.c | 4 +- examples/qlook.c | 7 +- examples/sector.c | 3 +- examples/wsr88d_to_gif.c | 3 +- gzip.c | 1 + lassen_to_radar.c | 1 + nsig.h | 3 + nsig_to_radar.c | 10 +- radar_to_uf.c | 25 +-- rainbow.c | 1 + rainbow_to_radar.c | 1 + rapic.y | 4 +- rsl.h | 2 +- uf_to_radar.c | 5 +- wsr88d.h | 3 +- wsr88d_locations.dat | 13 +- wsr88d_m31.c | 317 +++++++++++++------------- wsr88d_to_radar.c | 369 ++++++++++++++++--------------- 36 files changed, 622 insertions(+), 597 deletions(-) diff --git a/CHANGES b/CHANGES index fb2b03f..8f7c5ee 100644 --- a/CHANGES +++ b/CHANGES @@ -1,18 +1,24 @@ /* Changes for RSL * *--------------------------------------------------------------------- - * v1.41 In progress + * v1.41 Released 6/22/2011 * * 1. wsr88d_m31.c: Simplified the WSR-88D ray structure and supporting code. - * Removed function read_data_moment. Added support for dual-polarization - * data fields. - * Added function get_wsr88d_unamb_and_nyq_vel. + * Added support for dual-polarization data fields. + * Thanks go to Andy Spencer for code contributions. + * wsr88d_to_radar.c, wsr88d_m31.c: Renamed load_wsr88d_m31_into_radar to + * wsr88d_load_m31_into_radar, to be consistent with naming convention. * 2. Added support for Sigmet 2-byte data types, as well as HydroClass 1 and 2 * byte types. Files involved: nsig_to_radar.c, nsig.c, nsig.h, volume.c. - * Modified nsig_to_radar.c and rsl.h to handle Sigmet dual PRF. Much - * thanks to Fabio Sato and Cesar Beneti for the dual PRF code. + * Modified nsig_to_radar.c and rsl.h to handle Sigmet dual PRF. + * Thanks to Fabio Sato and Cesar Beneti for the dual PRF code. * 3. Completed DORADE ingest. Files involved: dorade_to_radar.c, dorade.c, * volume.c. + * 4. rsl.h, radar.c, radar_to_uf.c, uf_to_radar.c, volume.c: modified for RHI. + * nsig_to_radar.c: Thanks go to Scott Collis for a bug fix involving RHI. + * 5. anyformat_to_radar.c: Thanks to Thiago Biscaro for fixing a pipe problem + * that caused processes to remain open. + * 6. gzip.c: Thanks to Dan Sheldon for fix for a file descriptor leak. *--------------------------------------------------------------------- * v1.40 Released 10/10/2008 * diff --git a/Makefile.am b/Makefile.am index d859d71..3c106a8 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,6 +68,6 @@ install-exec-hook: $(INSTALL) -m 644 toolkit_1BC-51_appl.h $(includedir) $(INSTALL) -m 644 wsr88d_locations.dat $(libdir) -EXTRA_DIST = CHANGES CHECK_LIST Copyright GPL LGPL wsr88d_locations.dat rapic.h +EXTRA_DIST = CHANGES Copyright GPL LGPL wsr88d_locations.dat rapic.h DISTCLEANFILES = rapic.c rapic-lex.c diff --git a/README b/README index 33a8b80..c61065a 100644 --- a/README +++ b/README @@ -1,9 +1,11 @@ -v1.40 (Released 10/10/2008) +v1.41 (Released 6/22/2011) This is the README file for the Radar Software Library (RSL). The author of RSL is John H. Merritt. +RSL is maintained by Bart Kelley . + What is RSL? This software manipulates NexRad, Lassen, UF, sigmet, kwajalein, toga, RAPIC, RADTEC, mcgill and EDGE radar formats. @@ -43,8 +45,9 @@ COPYRIGHT NOTICE: System Requirements: - HP (755/hpux), Linux, SUN (SparcII), SGI(4D/IRIX). Should run on any -other hardware. + Linux, Mac OS X 10.5. + + Note: MS Windows is not supported. Memory Requirements: 16 Mbytes of RAM just to ingest the data. Plus any for your application. @@ -98,11 +101,11 @@ INSTALLATION INSTRUCTIONS 1. Unpack the GNU compressed tar archive, example: - gtar -xzf rsl-v1.29.tgz + tar -xzf rsl-v1.29.tgz -or- - gzcat rsl-v1.29.tgz | tar xf - + zcat rsl-v1.29.tgz | tar xf - 2. If you DON'T want LASSEN capability or you find that your system can not compile the lassen routines, you must edit acconfig.h and @@ -119,39 +122,6 @@ NOTE: You can specify the --prefix=/some/other/dir as an option to configure to look in the prefix/lib directory for those libraries. The examples installed are any_to_gif and any_to_uf. -APPLYING PATCHES ----------------- - -Using patch files saves network transmission times when upgrading -to the next version of RSL. Patch files are context differences -from one RSL release to the next. The patch files are located -in the anonymous ftp directory pub/software on trmm.gsfc.nasa.gov, -and they typically have the name of the form rsl.v1.14_to_v1.15.patch.gz. - -You will be applying the patch files from the directory where 'rsl' is -a subdirectory (from the parent directory of rsl). - -Follow these steps to upgrade using patch files. This demonstrates applying -patches from version 1.11 to 1.15. - -1. Make a symbolic link called 'rsl' that points to the current version - of RSL you have. For example: - - ln -s rsl-v1.11 rsl - -2. Apply patches. Here we'll go from v1.11 to v1.15. - - zcat rsl.v1.11_to_v1.12.patch.gz | patch - zcat rsl.v1.12_to_v1.13.patch.gz | patch - zcat rsl.v1.13_to_v1.14.patch.gz | patch - zcat rsl.v1.14_to_v1.15.patch.gz | patch - -3. Rename the rsl-v1.11 directory to be rsl-v1.15. You no longer - need the 'rsl' directory. - - mv rsl-v1.11 rsl-v1.15 - rm rsl - BUILDING APPLICATIONS --------------------- diff --git a/africa.c b/africa.c index 7348587..693a7bd 100644 --- a/africa.c +++ b/africa.c @@ -22,6 +22,7 @@ */ #include #include +#include #include "africa.h" int africa_read_buffer(FILE *fp, Africa_buffer *buffer) diff --git a/anyformat_to_radar.c b/anyformat_to_radar.c index 70be908..146a5e0 100644 --- a/anyformat_to_radar.c +++ b/anyformat_to_radar.c @@ -1,172 +1,181 @@ -/* - NASA/TRMM, Code 910.1. - This is the TRMM Office Radar Software Library. - Copyright (C) 1996, 1997 - John H. Merritt - Space Applications Corporation - Vienna, Virginia - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ -/* - * By John H. Merritt - * Science Applications Corporation, Vienna, VA - */ - -#include -#include -#include -#include -#include "rsl.h" -void rsl_readflush(FILE *fp); -/*********************************************************************/ -/* */ -/* RSL_filetype */ -/* */ -/*********************************************************************/ -enum File_type RSL_filetype(char *infile) -{ - /* Open the input file and peek at the first few bytes to determine - * the type of file. - * - * UF - First two bytes 'UF' - * - or 3,4 bytes 'UF' - * - or 5,6 bytes 'UF'. This is the most common. - * - * WSR88D - First 8 bytes: 'ARCHIVE2' or 'AR2V0001' - * - * TOGA - ?? - * NSIG - ?? - * LASSEN - SUNRISE - * RSL - RSL - * MCGILL - P A B - * RAPIC - /IMAGE: - * RADTEC - 320 (decimal, in first two bytes) - * RAINBOW - First two bytes: decimal 1, followed by 'H' - */ - FILE *fp; - char magic[11]; - - if ((fp = fopen(infile, "r")) == NULL) { - perror(infile); - return UNKNOWN; - } - - /* Read the magic bytes. */ - fp = uncompress_pipe(fp); /* If gzip available. */ - if (fread(magic, sizeof(magic), 1, fp) != 1) { - char *magic_str = (char *)calloc(sizeof(magic)+1, sizeof(char)); - memcpy(magic_str, magic, sizeof(magic)); - fprintf(stderr,"Error fread: Magic is %s\n", magic_str); - free (magic_str); - perror("RSL_filetype"); - fclose(fp); - return UNKNOWN; - } - - rsl_readflush(fp); /* Fork, read and exit -- eliminates the 'Broken pipe' */ - - if (strncmp("ARCHIVE2.", magic, 9) == 0) return WSR88D_FILE; - if (strncmp("AR2V000", magic, 7) == 0) return WSR88D_FILE; - if (strncmp("UF", magic, 2) == 0) return UF_FILE; - if (strncmp("UF", &magic[2], 2) == 0) return UF_FILE; - if (strncmp("UF", &magic[4], 2) == 0) return UF_FILE; - if ((int)magic[0] == 0x0e && - (int)magic[1] == 0x03 && - (int)magic[2] == 0x13 && - (int)magic[3] == 0x01 - ) return HDF_FILE; - if (strncmp("RSL", magic, 3) == 0) return RSL_FILE; - if ((int)magic[0] == 7) return NSIG_FILE_V1; - if ((int)magic[1] == 7) return NSIG_FILE_V1; - if ((int)magic[0] == 27) return NSIG_FILE_V2; - if ((int)magic[1] == 27) return NSIG_FILE_V2; - if (strncmp("/IMAGE:", magic, 7) == 0) return RAPIC_FILE; - if ((int)magic[0] == 0x40 && - (int)magic[1] == 0x01 - ) return RADTEC_FILE; - if ((int)magic[0] == 0x01 && magic[1] == 'H') return RAINBOW_FILE; - - if (strncmp("SUNRISE", &magic[4], 7) == 0) return LASSEN_FILE; -/* The 'P A B' is just too specific to be a true magic number, but that's all - * I've got. - */ - if (strncmp("P A B ", magic, 6) == 0) return MCGILL_FILE; - /* Byte swapped ? */ - if (strncmp(" P A B", magic, 6) == 0) return MCGILL_FILE; - if (strncmp("Volume", magic, 6) == 0) return EDGE_FILE; - if (strncmp("SSWB", magic, 4) == 0) return DORADE_FILE; - if (strncmp("VOLD", magic, 4) == 0) return DORADE_FILE; - - return UNKNOWN; -} - - - - - - - -/*********************************************************************/ -/* */ -/* RSL_anyformat_to_radar */ -/* */ -/*********************************************************************/ - -Radar *RSL_anyformat_to_radar(char *infile, ...) -{ - va_list ap; - char *callid_or_file; - Radar *radar; - -/* If it is detected that the input file is WSR88D, use the second argument - * as the call id of the site, or the file name of the tape header file. - * - * Assumption: Input files are seekable. - */ - radar = NULL; - switch (RSL_filetype(infile)) { - case WSR88D_FILE: - callid_or_file = NULL; - va_start(ap, infile); - callid_or_file = va_arg(ap, char *); - va_end(ap); - radar = RSL_wsr88d_to_radar(infile, callid_or_file); - break; - case UF_FILE: radar = RSL_uf_to_radar(infile); break; - case TOGA_FILE: radar = RSL_toga_to_radar(infile); break; - case NSIG_FILE_V1: radar = RSL_nsig_to_radar(infile); break; - case NSIG_FILE_V2: radar = RSL_nsig2_to_radar(infile); break; - case RAPIC_FILE: radar = RSL_rapic_to_radar(infile); break; - case RADTEC_FILE: radar = RSL_radtec_to_radar(infile); break; - case RSL_FILE: radar = RSL_read_radar(infile); break; -#ifdef HAVE_LIBTSDISTK - case HDF_FILE: radar = RSL_hdf_to_radar(infile); break; -#endif - case RAINBOW_FILE: radar = RSL_rainbow_to_radar(infile); break; - case MCGILL_FILE: radar = RSL_mcgill_to_radar(infile); break; - case EDGE_FILE: radar = RSL_EDGE_to_radar(infile); break; - case LASSEN_FILE: radar = RSL_lassen_to_radar(infile); break; - case DORADE_FILE: radar = RSL_dorade_to_radar(infile); break; - - default: - fprintf(stderr, "Unknown input file type. File <%s> is not recognized by RSL.\n", infile); - return NULL; - } - - return radar; -} - - +/* + NASA/TRMM, Code 910.1. + This is the TRMM Office Radar Software Library. + Copyright (C) 1996, 1997 + John H. Merritt + Space Applications Corporation + Vienna, Virginia + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +/* + * By John H. Merritt + * Science Applications Corporation, Vienna, VA + */ + +#include +#include +#include +#include +#include "rsl.h" +void rsl_readflush(FILE *fp); +/*********************************************************************/ +/* */ +/* RSL_filetype */ +/* */ +/*********************************************************************/ +enum File_type RSL_filetype(char *infile) +{ + /* Open the input file and peek at the first few bytes to determine + * the type of file. + * + * UF - First two bytes 'UF' + * - or 3,4 bytes 'UF' + * - or 5,6 bytes 'UF'. This is the most common. + * + * WSR88D - First 8 bytes: 'ARCHIVE2' or 'AR2V0001' + * + * TOGA - ?? + * NSIG - ?? + * LASSEN - SUNRISE + * RSL - RSL + * MCGILL - P A B + * RAPIC - /IMAGE: + * RADTEC - 320 (decimal, in first two bytes) + * RAINBOW - First two bytes: decimal 1, followed by 'H' + */ + FILE *fp; + char magic[11]; + + if ((fp = fopen(infile, "r")) == NULL) { + perror(infile); + return UNKNOWN; + } + + /* Read the magic bytes. */ + fp = uncompress_pipe(fp); /* If gzip available. */ + if (fread(magic, sizeof(magic), 1, fp) != 1) { + char *magic_str = (char *)calloc(sizeof(magic)+1, sizeof(char)); + memcpy(magic_str, magic, sizeof(magic)); + fprintf(stderr,"Error fread: Magic is %s\n", magic_str); + free (magic_str); + perror("RSL_filetype"); + /* Thanks to Thiago Biscaro for fixing defunct process problem. */ + rsl_pclose(fp); + return UNKNOWN; + } + + /* + Closes the stream and wait for associated processes to terminate + (just like wait() ) to avoid defunct processes. The old rsl_readflush + function wasn't doing this, N calls to anyformat_to_radar would + generate N defunct processes associated with the main program + --Thiago Biscaro + */ + + rsl_pclose(fp); + + if (strncmp("ARCHIVE2.", magic, 9) == 0) return WSR88D_FILE; + if (strncmp("AR2V000", magic, 7) == 0) return WSR88D_FILE; + if (strncmp("UF", magic, 2) == 0) return UF_FILE; + if (strncmp("UF", &magic[2], 2) == 0) return UF_FILE; + if (strncmp("UF", &magic[4], 2) == 0) return UF_FILE; + if ((int)magic[0] == 0x0e && + (int)magic[1] == 0x03 && + (int)magic[2] == 0x13 && + (int)magic[3] == 0x01 + ) return HDF_FILE; + if (strncmp("RSL", magic, 3) == 0) return RSL_FILE; + if ((int)magic[0] == 7) return NSIG_FILE_V1; + if ((int)magic[1] == 7) return NSIG_FILE_V1; + if ((int)magic[0] == 27) return NSIG_FILE_V2; + if ((int)magic[1] == 27) return NSIG_FILE_V2; + if (strncmp("/IMAGE:", magic, 7) == 0) return RAPIC_FILE; + if ((int)magic[0] == 0x40 && + (int)magic[1] == 0x01 + ) return RADTEC_FILE; + if ((int)magic[0] == 0x01 && magic[1] == 'H') return RAINBOW_FILE; + + if (strncmp("SUNRISE", &magic[4], 7) == 0) return LASSEN_FILE; +/* The 'P A B' is just too specific to be a true magic number, but that's all + * I've got. + */ + if (strncmp("P A B ", magic, 6) == 0) return MCGILL_FILE; + /* Byte swapped ? */ + if (strncmp(" P A B", magic, 6) == 0) return MCGILL_FILE; + if (strncmp("Volume", magic, 6) == 0) return EDGE_FILE; + if (strncmp("SSWB", magic, 4) == 0) return DORADE_FILE; + if (strncmp("VOLD", magic, 4) == 0) return DORADE_FILE; + + return UNKNOWN; +} + + + + + + + +/*********************************************************************/ +/* */ +/* RSL_anyformat_to_radar */ +/* */ +/*********************************************************************/ + +Radar *RSL_anyformat_to_radar(char *infile, ...) +{ + va_list ap; + char *callid_or_file; + Radar *radar; + +/* If it is detected that the input file is WSR88D, use the second argument + * as the call id of the site, or the file name of the tape header file. + * + * Assumption: Input files are seekable. + */ + radar = NULL; + switch (RSL_filetype(infile)) { + case WSR88D_FILE: + callid_or_file = NULL; + va_start(ap, infile); + callid_or_file = va_arg(ap, char *); + va_end(ap); + radar = RSL_wsr88d_to_radar(infile, callid_or_file); + break; + case UF_FILE: radar = RSL_uf_to_radar(infile); break; + case TOGA_FILE: radar = RSL_toga_to_radar(infile); break; + case NSIG_FILE_V1: radar = RSL_nsig_to_radar(infile); break; + case NSIG_FILE_V2: radar = RSL_nsig2_to_radar(infile); break; + case RAPIC_FILE: radar = RSL_rapic_to_radar(infile); break; + case RADTEC_FILE: radar = RSL_radtec_to_radar(infile); break; + case RSL_FILE: radar = RSL_read_radar(infile); break; +#ifdef HAVE_LIBTSDISTK + case HDF_FILE: radar = RSL_hdf_to_radar(infile); break; +#endif + case RAINBOW_FILE: radar = RSL_rainbow_to_radar(infile); break; + case MCGILL_FILE: radar = RSL_mcgill_to_radar(infile); break; + case EDGE_FILE: radar = RSL_EDGE_to_radar(infile); break; + case LASSEN_FILE: radar = RSL_lassen_to_radar(infile); break; + case DORADE_FILE: radar = RSL_dorade_to_radar(infile); break; + + default: + fprintf(stderr, "Unknown input file type. File <%s> is not recognized by RSL.\n", infile); + return NULL; + } + + return radar; +} + + diff --git a/configure.in b/configure.in index 62a6ae5..2791831 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,5 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(rsl, v1.40.3) +AC_INIT(rsl, v1.41) AC_CONFIG_SRCDIR(volume.c) AM_INIT_AUTOMAKE diff --git a/doc/RSL_radar_intro.html b/doc/RSL_radar_intro.html index 7838d5b..c356332 100644 --- a/doc/RSL_radar_intro.html +++ b/doc/RSL_radar_intro.html @@ -19,7 +19,7 @@ Introduction

By John H. Merritt and David B. Wolff; NASA/TRMM Office
-Software Verson 1.40 (released 10/10/2008)

+Software Verson 1.41 (released 6/22/2011)
This library is an object oriented programming environment to keep application programming simple, for the casual C programmer, as well as diff --git a/doc/RSL_ray_header_struct.html b/doc/RSL_ray_header_struct.html index 2065762..500d6e5 100644 --- a/doc/RSL_ray_header_struct.html +++ b/doc/RSL_ray_header_struct.html @@ -13,7 +13,7 @@   
-
typedef struct {
  int   month; /* Date for this ray; month (1-12). */
  int   day;   /* Date for this ray; day (1-31).   */
  int   year;  /* Date for this ray; year (eg. 1993). */
  int   hour;  /* Time for this ray; hour (0-23). */
  int   minute;/* Time for this ray; minute (0-59).*/
  float sec;   /* Time for this ray; second + fraction of second. */
  float unam_rng;  /* Unambiguous range. (KM). */
  float azimuth;   /* Azimuth angle. (degrees). Must be positive
                    * 0=North, 90=east, -90/270=west.
                    * This angle is the mean azimuth for the whole ray.
                    * Eg. for NSIG the beginning and end azimuths are
                    * averaged.
                    */
  int   ray_num;   /* Ray no. within elevation scan. */
  float elev;       /* Elevation angle. (degrees). */
  int   elev_num;   /* Elevation no. within volume scan. */
  
  int   range_bin1; /* Range to first gate.(meters) */
  int   gate_size;  /* Data gate size (meters)*/
  
  float  vel_res;    /* Doppler velocity resolution */
  float sweep_rate;   /* Sweep rate. Full sweeps/min. */
  
  int prf;          /* Pulse repitition frequency, in Hz. */
  float azim_rate; /* Sweep rate in degrees/second.*/
  float fix_angle; /* Elevation angle for the sweep. (degrees). */
  float pitch;      /* Pitch angle. */
  float roll;       /* Roll  angle. */
  float heading;    /* Heading. */
  float pitch_rate; /* (angle/sec) */
  float roll_rate;  /* (angle/sec) */
  float heading_rate; /* (angle/sec) */
  float lat;          /* Latitude (degrees) */
  float lon;          /* Longitude (degrees) */
  int   alt;          /* Altitude (m) */
  float rvc;          /* Radial velocity correction (m/sec) */
  float vel_east;     /* Platform velocity to the east  (m/sec) */
  float vel_north;    /* Platform velocity to the north (m/sec) */
  float vel_up;       /* Platform velocity toward up    (m/sec) */
  float pulse_count; /* Pulses used in a single dwell time. */
  float pulse_width; /* Pulse width (micro-sec). */
  float beam_width;  /* Beamwidth in degrees. */
  float frequency;   /* Bandwidth MHz. */
  float wavelength;  /* Wavelength. Meters. */
  float nyq_vel;    /* Nyquist velocity. m/s */
  float (*f)(Range x);       /* Data conversion function. f(x). */
  Range (*invf)(float x);    /* Data conversion function. invf(x). */
  int   nbins;               /* Number of array elements for 'Range'. */
} Ray_header;
+
typedef struct {
  int   month; /* Date for this ray; month (1-12). */
  int   day;   /* Date for this ray; day (1-31).   */
  int   year;  /* Date for this ray; year (eg. 1993). */
  int   hour;  /* Time for this ray; hour (0-23). */
  int   minute;/* Time for this ray; minute (0-59).*/
  float sec;   /* Time for this ray; second + fraction of second. */
  float unam_rng;  /* Unambiguous range. (KM). */
  float azimuth;   /* Azimuth angle. (degrees). Must be positive
                    * 0=North, 90=east, -90/270=west.
                    * This angle is the mean azimuth for the whole ray.
                    * Eg. for NSIG the beginning and end azimuths are
                    * averaged.
                    */
  int   ray_num;   /* Ray no. within elevation scan. */
  float elev;       /* Elevation angle. (degrees). */
  int   elev_num;   /* Elevation no. within volume scan. */
  
  int   range_bin1; /* Range to first gate.(meters) */
  int   gate_size;  /* Data gate size (meters)*/
  
  float  vel_res;    /* Doppler velocity resolution */
  float sweep_rate;   /* Sweep rate. Full sweeps/min. */
  
  int prf;          /* Pulse repitition frequency, in Hz. */
  int prf2;         /* Second PRF, for Sigmet dual PRF. */
  float azim_rate; /* Sweep rate in degrees/second.*/
  float fix_angle; /* Elevation angle for the sweep. (degrees). */
  float pitch;      /* Pitch angle. */
  float roll;       /* Roll  angle. */
  float heading;    /* Heading. */
  float pitch_rate; /* (angle/sec) */
  float roll_rate;  /* (angle/sec) */
  float heading_rate; /* (angle/sec) */
  float lat;          /* Latitude (degrees) */
  float lon;          /* Longitude (degrees) */
  int   alt;          /* Altitude (m) */
  float rvc;          /* Radial velocity correction (m/sec) */
  float vel_east;     /* Platform velocity to the east (negative for west)   (m/sec) */
  float vel_north;    /* Platform velocity to the north (negative for south) (m/sec) */
  float vel_up;       /* Platform velocity toward up (negative for down)     (m/sec) */
  float pulse_count; /* Pulses used in a single dwell time. */
  float pulse_width; /* Pulse width (micro-sec). */
  float beam_width;  /* Beamwidth in degrees. */
  float frequency;   /* Bandwidth MHz. */
  float wavelength;  /* Wavelength. Meters. */
  float nyq_vel;    /* Nyquist velocity. m/s */
  float (*f)(Range x);       /* Data conversion function. f(x). */
  Range (*invf)(float x);    /* Data conversion function. invf(x). */
  int   nbins;               /* Number of array elements for 'Range'. */
} Ray_header;

diff --git a/doc/whats_new.html b/doc/whats_new.html index 7f430e0..4ed91ef 100644 --- a/doc/whats_new.html +++ b/doc/whats_new.html @@ -12,6 +12,8 @@

What's new?

+

+06/22/2011: Version 1.41 supports WSR-88D Level II Build 12 format.

07/24/2008: Version 1.39 supports WSR-88D Level II Build 10 format.

diff --git a/dorade_to_radar.c b/dorade_to_radar.c index b66b9a8..27de1ec 100644 --- a/dorade_to_radar.c +++ b/dorade_to_radar.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #define USE_RSL_VARS #include "rsl.h" diff --git a/examples/any_to_gif.c b/examples/any_to_gif.c index f598033..0ce222b 100644 --- a/examples/any_to_gif.c +++ b/examples/any_to_gif.c @@ -73,7 +73,7 @@ process_args(int argc, char **argv, } -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; Sweep *sweep; diff --git a/examples/any_to_ppm.c b/examples/any_to_ppm.c index 62293b1..42a41b4 100644 --- a/examples/any_to_ppm.c +++ b/examples/any_to_ppm.c @@ -9,11 +9,12 @@ * the RSL. * */ +#include #define USE_RSL_VARS #include "rsl.h" -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; Sweep *sweep; diff --git a/examples/cappi_image.c b/examples/cappi_image.c index f2ab637..6cc6c3c 100644 --- a/examples/cappi_image.c +++ b/examples/cappi_image.c @@ -7,6 +7,7 @@ */ #include +#include #include #include "rsl.h" diff --git a/examples/dorade_main.c b/examples/dorade_main.c index 120dd14..c8e2076 100644 --- a/examples/dorade_main.c +++ b/examples/dorade_main.c @@ -1,4 +1,5 @@ #include +#include #include "rsl.h" int main(int argc, char **argv) @@ -15,7 +16,7 @@ int main(int argc, char **argv) if (radar == NULL) printf("radar == NULL\n"); else - printf("radar == %x\n", radar); + printf("radar == %x\n", (unsigned int)radar); exit(0); } diff --git a/examples/killer_sweep.c b/examples/killer_sweep.c index 139b231..dba5f14 100644 --- a/examples/killer_sweep.c +++ b/examples/killer_sweep.c @@ -146,7 +146,7 @@ void chase_hi_links(Sweep *sweep) } } -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; Sweep *sweep; diff --git a/examples/kwaj_subtract_one_day.c b/examples/kwaj_subtract_one_day.c index 65acfaa..5cf6011 100644 --- a/examples/kwaj_subtract_one_day.c +++ b/examples/kwaj_subtract_one_day.c @@ -1,3 +1,4 @@ +#include #include "rsl.h" /**********************************************************************/ diff --git a/examples/lassen_to_gif.c b/examples/lassen_to_gif.c index dd9a168..5815732 100644 --- a/examples/lassen_to_gif.c +++ b/examples/lassen_to_gif.c @@ -4,9 +4,10 @@ * This program can read the file from stdin. */ +#include #include "rsl.h" -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; diff --git a/examples/print_hash_table.c b/examples/print_hash_table.c index 0505fb8..bfc12e4 100644 --- a/examples/print_hash_table.c +++ b/examples/print_hash_table.c @@ -9,6 +9,7 @@ * */ +#include #include "rsl.h" void print_link_list(Azimuth_hash *list) @@ -87,7 +88,7 @@ void poke_about_sweep(Sweep *s) } -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; Sweep *sweep; diff --git a/examples/print_header_info.c b/examples/print_header_info.c index 6167c81..991ec75 100644 --- a/examples/print_header_info.c +++ b/examples/print_header_info.c @@ -77,10 +77,10 @@ printf(" gate_size %d\n", ray->h.gate_size); /* Data gate size (meters)*/ printf(" vel_res %f\n", ray->h.vel_res); /* Doppler velocity resolution */ printf(" sweep_rate %f\n", ray->h.sweep_rate); /* Sweep rate. Full sweeps/min. */ -printf(" prf %f\n", ray->h.prf); /* Pulse repitition frequency, in Hz. */ +printf(" prf %d\n", ray->h.prf); /* Pulse repitition frequency, in Hz. */ printf(" azim_rate %f\n", ray->h.azim_rate); printf(" fix_angle %f\n", ray->h.fix_angle); -printf("pulse_count %f\n", ray->h.pulse_count); +printf("pulse_count %d\n", ray->h.pulse_count); printf("pulse_width %f\n", ray->h.pulse_width); /* Pulse width (micro-sec). */ printf(" beam_width %f\n", ray->h.beam_width); /* Beamwidth in degrees. */ printf(" frequency %f\n", ray->h.frequency); /* Bandwidth MHz. */ diff --git a/examples/qlook.c b/examples/qlook.c index 5fa6c17..f304da0 100644 --- a/examples/qlook.c +++ b/examples/qlook.c @@ -32,7 +32,7 @@ void make_pathname(char *filename, char *dir, char *pathname) { /* Make pathname by combining directory name, if given, with filename. */ - if (*dir == NULL) { + if (!dir || !dir[0]) { strcpy(pathname, filename); } else { @@ -598,7 +598,7 @@ main(int argc, char **argv) { scale = 0.5; ncbins = 21; width = 10; - printf("Calling RSL_rebin, %d %d %.2f\n", width); + printf("Calling RSL_rebin, %d\n", width); RSL_rebin_volume(dr_volume, width); if(verbose) printf("Loading zdr colortable...\n"); RSL_load_zdr_color_table(); @@ -688,8 +688,7 @@ main(int argc, char **argv) { Write uf file if requested */ if(make_uf) { - sprintf(file_suffix,"uf.gz"); - sprintf(filename,"%s_%s.%s",site_id, time_string,file_suffix); + sprintf(filename,"%s_%s.%s",site_id, time_string,"uf.gz"); printf("Creating UF file: %s\n", filename); make_pathname(filename, ufdir, pathname); RSL_radar_to_uf_gzip(radar, pathname); diff --git a/examples/sector.c b/examples/sector.c index f1655ce..a152745 100644 --- a/examples/sector.c +++ b/examples/sector.c @@ -1,4 +1,5 @@ #include +#include #include "rsl.h" /* @@ -84,7 +85,7 @@ Sweep * get_sector(Sweep *s, float lo_azimuth, float hi_azimuth) } -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; Sweep *sector; diff --git a/examples/wsr88d_to_gif.c b/examples/wsr88d_to_gif.c index 08969eb..ab486cf 100644 --- a/examples/wsr88d_to_gif.c +++ b/examples/wsr88d_to_gif.c @@ -14,9 +14,10 @@ * wsr88d_to_gif file [tape_header_file] */ +#include #include "rsl.h" -void main(int argc, char **argv) +int main(int argc, char **argv) { Radar *radar; diff --git a/gzip.c b/gzip.c index 09d0198..5b8f902 100644 --- a/gzip.c +++ b/gzip.c @@ -83,6 +83,7 @@ FILE *uncompress_pipe (FILE *fp) if (fpipe == NULL) perror("uncompress_pipe"); close(0); dup(save_fd); + close(save_fd); return fpipe; } diff --git a/lassen_to_radar.c b/lassen_to_radar.c index 3e5585e..a7ae48d 100644 --- a/lassen_to_radar.c +++ b/lassen_to_radar.c @@ -31,6 +31,7 @@ */ #include +#include #include #include #include diff --git a/nsig.h b/nsig.h index 5844ddf..b742ae7 100644 --- a/nsig.h +++ b/nsig.h @@ -34,11 +34,14 @@ #define NSIG_DTB_SQI 18 #define NSIG_DTB_RHOHV 19 #define NSIG_DTB_RHOHV2 20 +#define NSIG_DTB_DBZ2 21 #define NSIG_DTB_VELC2 22 #define NSIG_DTB_SQI2 23 #define NSIG_DTB_PHIDP2 24 #define NSIG_DTB_HCLASS 55 #define NSIG_DTB_HCLASS2 56 +#define NSIG_DTB_ZDRC 57 +#define NSIG_DTB_ZDRC2 58 /* Product type code ,value for byte 12 in product configuration * struct, III-35 diff --git a/nsig_to_radar.c b/nsig_to_radar.c index 88788e4..6ce8081 100644 --- a/nsig_to_radar.c +++ b/nsig_to_radar.c @@ -630,6 +630,14 @@ RSL_nsig_to_radar ifield = HC_INDEX; f = HC_F; invf = HC_INVF; + case NSIG_DTB_DBZ2: + ifield = CZ_INDEX; + f = CZ_F; + invf = CZ_INVF; + case NSIG_DTB_ZDRC2: + ifield = ZD_INDEX; + f = ZD_F; + invf = ZD_INVF; break; default: fprintf(stderr,"Unknown field type: %d Skipping it.\n", data_type); @@ -734,7 +742,7 @@ RSL_nsig_to_radar ray->h.wavelength = wave/100.0; /* meters */ ray->h.nyq_vel = max_vel; /* m/s */ if (elev == 0.) elev = sweep->h.elev; - ray->h.elev = elev; + ray->h.elev = (nsig_from_bang(ray_p->h.end_elev)+nsig_from_bang(ray_p->h.beg_elev))/2.0; /* Compute mean azimuth angle for ray. */ az1 = nsig_from_bang(ray_p->h.beg_azm); az2 = nsig_from_bang(ray_p->h.end_azm); diff --git a/radar_to_uf.c b/radar_to_uf.c index df237f5..0d3af56 100644 --- a/radar_to_uf.c +++ b/radar_to_uf.c @@ -58,7 +58,8 @@ extern int radar_verbose_flag; */ -typedef short UF_buffer[16384]; /* Bigger than documented 4096. */ +/* Changed old buffer size (16384) for larger dualpol files. BLK 5/20/2011 */ +typedef short UF_buffer[20000]; /* Bigger than documented 4096. */ void swap_uf_buffer(UF_buffer uf); void swap2(short *buf, int n); @@ -308,7 +309,7 @@ void RSL_radar_to_uf_fp(Radar *r, FILE *fp) if (ray->h.azimuth > 0) uf_ma[32] = ray->h.azimuth*64 + 0.5; else uf_ma[32] = ray->h.azimuth*64 - 0.5; uf_ma[33] = ray->h.elev*64 + 0.5; - uf_ma[34] = uf_sweep_mode; + uf_ma[34] = uf_sweep_mode; if (ray->h.fix_angle != 0.) uf_ma[35] = ray->h.fix_angle*64.0 + 0.5; else uf_ma[35] = sweep[k]->h.elev*64.0 + 0.5; @@ -351,18 +352,16 @@ void RSL_radar_to_uf_fp(Radar *r, FILE *fp) /* ---- Begining of LOCAL USE HEADER BLOCK. */ q_lu = 0; - /* Note: Code within "#ifdef LUHDR_VR_AZ" below is retained for testing - * and is not normally compiled. It was used to deal with azimuth - * differences between DZ and VR in WSR-88D split-cuts, now handled in - * ingest routine. - */ + /* TODO: Code within "#ifdef LUHDR_VR_AZ" below should be removed + * once testing of merge_split_cuts is completed. + */ /* 5/18/2010 Temporarily define LUHDR_VR_AZ until merge_split_cuts is completed. */ #define LUHDR_VR_AZ #ifdef LUHDR_VR_AZ /* If DZ and VR azimuths are different, store VR azimuth in Local Use * Header. This is done for WSR-88D split cuts. - */ + */ if (sweep[DZ_INDEX] && sweep[VR_INDEX]) { if (sweep[DZ_INDEX]->ray[j] && sweep[VR_INDEX]->ray[j]) { vr_az = sweep[VR_INDEX]->ray[j]->h.azimuth; @@ -413,15 +412,15 @@ void RSL_radar_to_uf_fp(Radar *r, FILE *fp) uf_dh[2] = nfield; /* 'nfield' indexes the field number. * 'k' indexes the particular field from the volume. - * RSL_ftype contains field names and is defined in rsl.h. + * RSL_ftype contains field names and is defined in rsl.h. */ if (k > max_field_names-1) { - fprintf(stderr, + fprintf(stderr, "RSL_uf_to_radar: No field name for volume index %d\n", k); - fprintf(stderr,"RSL_ftype must be updated in rsl.h for new field.\n"); - fprintf(stderr,"Quitting now.\n"); + fprintf(stderr,"RSL_ftype must be updated in rsl.h for new field.\n"); + fprintf(stderr,"Quitting now.\n"); return; - } + } memcpy(&uf_dh[3+2*(nfield-1)], RSL_ftype[k], 2); if (little_endian()) swap2(&uf_dh[3+2*(nfield-1)], 2/2); if (current_fh_index == 0) current_fh_index = len_ma+len_op+len_lu+len_dh; diff --git a/rainbow.c b/rainbow.c index e8cedc1..49d8190 100644 --- a/rainbow.c +++ b/rainbow.c @@ -22,6 +22,7 @@ */ #include +#include #include #include "rsl.h" #include "rainbow.h" diff --git a/rainbow_to_radar.c b/rainbow_to_radar.c index 1bf5599..7887063 100644 --- a/rainbow_to_radar.c +++ b/rainbow_to_radar.c @@ -22,6 +22,7 @@ */ #include +#include #include #include "rsl.h" #include "rainbow.h" diff --git a/rapic.y b/rapic.y index 0c99d12..b104757 100644 --- a/rapic.y +++ b/rapic.y @@ -327,7 +327,7 @@ float rapic_nyquist; Charlen token; } -%expect 59 +%expect 61 %% @@ -463,7 +463,7 @@ ray : RAYDATA RSL_ftype[0] = RSL_ftype[0]; /* Use yylval.token.s and yylval.token.len */ - memset(outbuf, sizeof(outbuf), '\0'); + memset(outbuf, '\0', sizeof(outbuf)); rapic_decode((unsigned char *)yylval.token.s, yylval.token.len, outbuf, &outbytes, &azim, &elev, &delta_time); /* fprintf(stderr, "RAYDATA: ray %d, ivol %d, isweep %d, azim %f, elev %f, dtime %d, size=%d\n", nray, ivolume, isweep, azim, elev, delta_time, outbytes); */ diff --git a/rsl.h b/rsl.h index 2050806..a821765 100644 --- a/rsl.h +++ b/rsl.h @@ -27,7 +27,7 @@ #include "config.h" #endif -#define RSL_VERSION_STR "v1.40.3" +#define RSL_VERSION_STR "v1.41" /**********************************************************************/ /* Configure: Define USE_TWO_BYTE_PRECISION to have RSL store internal*/ diff --git a/uf_to_radar.c b/uf_to_radar.c index 341ec33..e87b68d 100644 --- a/uf_to_radar.c +++ b/uf_to_radar.c @@ -30,7 +30,8 @@ #include "rsl.h" extern int radar_verbose_flag; -typedef short UF_buffer[16384]; /* Some UF files are bigger than 4096 +/* Changed old buffer size (16384) for larger dualpol files. BLK 5/18/2011 */ +typedef short UF_buffer[20000]; /* Some UF files are bigger than 4096 * that the UF doc's specify. */ @@ -485,7 +486,7 @@ Radar *RSL_uf_to_radar_fp(FILE *fp) radar = NULL; - setvbuf(fp,NULL,_IOFBF,(size_t)NEW_BUFSIZ); /* Faster i/o? */ + /* setvbuf(fp,NULL,_IOFBF,(size_t)NEW_BUFSIZ); * Faster i/o? */ if (fread(magic.buf, sizeof(char), 6, fp) <= 0) return NULL; /* * Check for fortran record length delimeters, NCAR kludge. diff --git a/wsr88d.h b/wsr88d.h index cc607c7..ecad620 100644 --- a/wsr88d.h +++ b/wsr88d.h @@ -139,7 +139,8 @@ typedef struct radar_site { } Wsr88d_site_info; typedef struct { - FILE *fptr; + FILE *fptr; /* this usually points to the gzip pipe */ + FILE *orig; /* save the original file pointer for cleanup */ } Wsr88d_file; #define PACKET_SIZE 2432 diff --git a/wsr88d_locations.dat b/wsr88d_locations.dat index 0df1702..cc67354 100644 --- a/wsr88d_locations.dat +++ b/wsr88d_locations.dat @@ -65,7 +65,7 @@ 3980 KHGX HOUSTON TX 29 28 19 -95 4 45 5 53111 KHNX SAN_JOAQUIN_V CA 36 18 51 -119 37 56 75 53839 KHPX FORT_CAMPBELL KY 36 44 12 -87 17 6 176 -53857 KHTX HUNTSVILLE AL 34 55 50 -86 05 00 537 +53857 KHTX HUNTSVILLE AL 34 55 50 -86 05 00 537 3928 KICT WICHITA KS 37 39 17 -97 26 34 407 13841 KILN CINCINNATI OH 39 25 13 -83 49 18 322 4833 KILX LINCOLN IL 40 9 2 -89 20 13 177 @@ -108,7 +108,7 @@ 53833 KOHX NASHVILLE TN 36 14 50 -86 33 45 176 94703 KOKX NEW_YORK_CITY NY 40 51 56 -72 51 50 26 4106 KOTX SPOKANE WA 47 40 49 -117 37 36 727 -3948 KOUN NORMAN OK 35 14 10 -97 27 44 390 +3948 KOUN NORMAN OK 35 14 10 -97 27 44 390 3816 KPAH PADUCAH KY 37 4 6 -88 46 19 119 4832 KPBZ PITTSBURGH PA 40 31 54 -80 13 6 361 24155 KPDT PENDLETON OR 45 41 26 -118 51 10 462 @@ -145,3 +145,12 @@ 43216 RKSG CMP_HUMPHRYS KOR 36 57 21 127 1 16 16 42219 RODN KADENA OKI 26 18 7 127 54 35 66 33771 KDGX JACKSON MS 32 16 33 -89 58 48 151 +53118 KICX CEDAR_CITY UT 37 35 9 -112 51 21 3231 +4844 KIWX N_INDIANA IN 41 21 0 -85 42 0 293 +53906 KSRX W_ARKANSAS AR 35 16 48 -94 21 0 195 +54776 KTYX MONTAGUE NY 43 45 3 -75 40 30 563 +0 KVWX EVANSVILLE IN 38 16 12 -87 43 12 190 +0 PHKM KOHALA HI 20 7 12 -155 46 12 1162 +0 PHMO MOLOKAI HI 21 7 12 -157 10 12 415 +0 PHWA HAWAII HI 19 4 48 -155 34 12 421 +0 TJUA SAN_JUAN PR 18 7 12 -66 4 48 931 diff --git a/wsr88d_m31.c b/wsr88d_m31.c index 4373df3..9e4c5b1 100644 --- a/wsr88d_m31.c +++ b/wsr88d_m31.c @@ -23,7 +23,9 @@ /* * This file contains routines for processing Message Type 31, the digital - * radar message type introduced in WSR-88D Level II Build 10. + * radar message type introduced in WSR-88D Level II Build 10. For more + * information, see the "Interface Control Document for the RDA/RPG" at the + * WSR-88D Radar Operations Center web site. */ #include "rsl.h" @@ -64,16 +66,16 @@ typedef struct { unsigned char radial_spot_blanking; unsigned char azm_indexing_mode; unsigned short data_block_count; - /* Data Block Pointers */ - unsigned int dbptr_vol_const; - unsigned int dbptr_elev_const; - unsigned int dbptr_radial_const; - unsigned int dbptr_ref; - unsigned int dbptr_vel; - unsigned int dbptr_sw; - unsigned int dbptr_zdr; - unsigned int dbptr_phi; - unsigned int dbptr_rho; + /* Data Block Indexes */ + unsigned int vol_const; + unsigned int elev_const; + unsigned int radial_const; + unsigned int field1; + unsigned int field2; + unsigned int field3; + unsigned int field4; + unsigned int field5; + unsigned int field6; } Ray_header_m31; /* Called Data Header Block in RDA/RPG document. */ typedef struct { @@ -115,19 +117,19 @@ void wsr88d_swap_m31_hdr(Wsr88d_msg_hdr *msghdr) } -void wsr88d_swap_m31_ray(Ray_header_m31 *wsr88d_ray) +void wsr88d_swap_m31_ray_hdr(Ray_header_m31 *ray_hdr) { int *data_ptr; - swap_4_bytes(&wsr88d_ray->ray_time); - swap_2_bytes(&wsr88d_ray->ray_date); - swap_2_bytes(&wsr88d_ray->azm_num); - swap_4_bytes(&wsr88d_ray->azm); - swap_2_bytes(&wsr88d_ray->radial_len); - swap_4_bytes(&wsr88d_ray->elev); - swap_2_bytes(&wsr88d_ray->data_block_count); - data_ptr = (int *) &wsr88d_ray->dbptr_vol_const; - for (; data_ptr <= (int *) &wsr88d_ray->dbptr_rho; data_ptr++) + swap_4_bytes(&ray_hdr->ray_time); + swap_2_bytes(&ray_hdr->ray_date); + swap_2_bytes(&ray_hdr->azm_num); + swap_4_bytes(&ray_hdr->azm); + swap_2_bytes(&ray_hdr->radial_len); + swap_4_bytes(&ray_hdr->elev); + swap_2_bytes(&ray_hdr->data_block_count); + data_ptr = (int *) &ray_hdr->vol_const; + for (; data_ptr <= (int *) &ray_hdr->field6; data_ptr++) swap_4_bytes(data_ptr); } @@ -151,7 +153,7 @@ float wsr88d_get_angle(short bitfield) float value[13] = {0.043945, 0.08789, 0.17578, 0.35156, .70313, 1.40625, 2.8125, 5.625, 11.25, 22.5, 45., 90., 180.}; - /* find which bits are set and sum corresponding values to get angle. */ + /* Find which bits are set and sum corresponding values to get angle. */ bitfield = bitfield >> 3; /* 3 least significant bits aren't used. */ for (i = 0; i < 13; i++) { @@ -242,26 +244,25 @@ void wsr88d_get_vcp_data(short *msgtype5) void get_wsr88d_unamb_and_nyq_vel(Wsr88d_ray_m31 *wsr88d_ray, float *unamb_rng, float *nyq_vel) { - int dbptr, found, ray_hdr_len; + int dindex, found; short nyq_vel_sh, unamb_rng_sh; found = 0; - ray_hdr_len = sizeof(wsr88d_ray->ray_hdr); - dbptr = wsr88d_ray->ray_hdr.dbptr_radial_const - ray_hdr_len; - if (strncmp((char *) &wsr88d_ray->data[dbptr], "RRAD", 4) == 0) found = 1; + dindex = wsr88d_ray->ray_hdr.radial_const; + if (strncmp((char *) &wsr88d_ray->data[dindex], "RRAD", 4) == 0) found = 1; else { - dbptr = wsr88d_ray->ray_hdr.dbptr_elev_const - ray_hdr_len; - if (strncmp((char *) &wsr88d_ray->data[dbptr], "RRAD", 4) == 0) + dindex = wsr88d_ray->ray_hdr.elev_const; + if (strncmp((char *) &wsr88d_ray->data[dindex], "RRAD", 4) == 0) found = 1; else { - dbptr = wsr88d_ray->ray_hdr.dbptr_vol_const - ray_hdr_len; - if (strncmp((char *) &wsr88d_ray->data[dbptr], "RRAD", 4) == 0) + dindex = wsr88d_ray->ray_hdr.vol_const; + if (strncmp((char *) &wsr88d_ray->data[dindex], "RRAD", 4) == 0) found = 1; } } if (found) { - memcpy(&unamb_rng_sh, &wsr88d_ray->data[dbptr+6], 2); - memcpy(&nyq_vel_sh, &wsr88d_ray->data[dbptr+16], 2); + memcpy(&unamb_rng_sh, &wsr88d_ray->data[dindex+6], 2); + memcpy(&nyq_vel_sh, &wsr88d_ray->data[dindex+16], 2); if (little_endian()) { swap_2_bytes(&unamb_rng_sh); swap_2_bytes(&nyq_vel_sh); @@ -278,34 +279,24 @@ void get_wsr88d_unamb_and_nyq_vel(Wsr88d_ray_m31 *wsr88d_ray, float *unamb_rng, int read_wsr88d_ray_m31(Wsr88d_file *wf, int msg_size, Wsr88d_ray_m31 *wsr88d_ray) { - Ray_header_m31 ray_hdr; - int n, bytes_to_read, ray_hdr_len; + int n; float nyq_vel, unamb_rng; - /* Read ray data header block */ - n = fread(&wsr88d_ray->ray_hdr, sizeof(Ray_header_m31), 1, wf->fptr); + /* Read wsr88d ray. */ + + n = fread(wsr88d_ray->data, msg_size, 1, wf->fptr); if (n < 1) { fprintf(stderr,"read_wsr88d_ray_m31: Read failed.\n"); return 0; } - /* Byte swap header if needed. */ - if (little_endian()) wsr88d_swap_m31_ray(&wsr88d_ray->ray_hdr); - - ray_hdr = wsr88d_ray->ray_hdr; - ray_hdr_len = sizeof(ray_hdr); - - /* Read data portion of radial. */ + /* Copy data header block to ray header structure. */ + memcpy(&wsr88d_ray->ray_hdr, &wsr88d_ray->data, sizeof(Ray_header_m31)); - bytes_to_read = msg_size - ray_hdr_len; - n = fread(wsr88d_ray->data, bytes_to_read, 1, wf->fptr); - if (n < 1) { - fprintf(stderr,"read_wsr88d_ray_m31: Read failed.\n"); - return 0; - } + if (little_endian()) wsr88d_swap_m31_ray_hdr(&wsr88d_ray->ray_hdr); - /* We retrieve unambiguous range and Nyquist velocity here so that we don't - * have to do it repeatedly for each data moment later. + /* Retrieve unambiguous range and Nyquist velocity here so that we don't + * have to do it for each data moment later. */ get_wsr88d_unamb_and_nyq_vel(wsr88d_ray, &unamb_rng, &nyq_vel); wsr88d_ray->unamb_rng = unamb_rng; @@ -315,14 +306,14 @@ int read_wsr88d_ray_m31(Wsr88d_file *wf, int msg_size, } -void wsr88d_load_ray_hdr(Wsr88d_ray_m31 wsr88d_ray, Ray *ray) +void wsr88d_load_ray_hdr(Wsr88d_ray_m31 *wsr88d_ray, Ray *ray) { int month, day, year, hour, minute, sec; float fsec; Wsr88d_ray m1_ray; Ray_header_m31 ray_hdr; - ray_hdr = wsr88d_ray.ray_hdr; + ray_hdr = wsr88d_ray->ray_hdr; m1_ray.ray_date = ray_hdr.ray_date; m1_ray.ray_time = ray_hdr.ray_time; @@ -338,8 +329,8 @@ void wsr88d_load_ray_hdr(Wsr88d_ray_m31 wsr88d_ray, Ray *ray) ray->h.ray_num = ray_hdr.azm_num; ray->h.elev = ray_hdr.elev; ray->h.elev_num = ray_hdr.elev_num; - ray->h.unam_rng = wsr88d_ray.unamb_rng; - ray->h.nyq_vel = wsr88d_ray.nyq_vel; + ray->h.unam_rng = wsr88d_ray->unamb_rng; + ray->h.nyq_vel = wsr88d_ray->nyq_vel; int elev_index; elev_index = ray_hdr.elev_num - 1; ray->h.azim_rate = vcp_data.azim_rate[elev_index]; @@ -354,7 +345,7 @@ void wsr88d_load_ray_hdr(Wsr88d_ray_m31 wsr88d_ray, Ray *ray) */ m1_ray.vol_cpat = vcp_data.vcp; m1_ray.elev_num = ray_hdr.elev_num; - m1_ray.unam_rng = (short) (wsr88d_ray.unamb_rng * 10.); + m1_ray.unam_rng = (short) (wsr88d_ray->unamb_rng * 10.); /* Get values from message type 1 routines. */ ray->h.frequency = wsr88d_get_frequency(&m1_ray); ray->h.pulse_width = wsr88d_get_pulse_width(&m1_ray); @@ -366,76 +357,101 @@ void wsr88d_load_ray_hdr(Wsr88d_ray_m31 wsr88d_ray, Ray *ray) int wsr88d_get_vol_index(char* dataname) { - int vol_index = -1; - - if (strncmp(dataname, "DREF", 4) == 0) vol_index = DZ_INDEX; - if (strncmp(dataname, "DVEL", 4) == 0) vol_index = VR_INDEX; - if (strncmp(dataname, "DSW", 3) == 0) vol_index = SW_INDEX; - if (strncmp(dataname, "DZDR", 3) == 0) vol_index = DR_INDEX; - if (strncmp(dataname, "DPHI", 3) == 0) vol_index = PH_INDEX; - if (strncmp(dataname, "DRHO", 3) == 0) vol_index = RH_INDEX; - - return vol_index; + if (strncmp(dataname, "DREF", 4) == 0) return DZ_INDEX; + if (strncmp(dataname, "DVEL", 4) == 0) return VR_INDEX; + if (strncmp(dataname, "DSW", 3) == 0) return SW_INDEX; + if (strncmp(dataname, "DZDR", 4) == 0) return DR_INDEX; + if (strncmp(dataname, "DPHI", 4) == 0) return PH_INDEX; + if (strncmp(dataname, "DRHO", 4) == 0) return RH_INDEX; + + return -1; } #define MAXRAYS_M31 800 #define MAXSWEEPS 20 -void wsr88d_load_ray(Wsr88d_ray_m31 wsr88d_ray, int data_ptr, - int isweep, int iray, Radar *radar) +void wsr88d_load_ray_into_radar(Wsr88d_ray_m31 *wsr88d_ray, int isweep, + Radar *radar) { - /* Load data into ray structure for this field or data moment. */ + /* Load data into ray structure for each data field. */ + + int data_index; + int *field_offset; + int ifield, nfields; + int iray; + const nconstblocks = 3; Data_moment_hdr data_hdr; - int ngates; + int ngates, do_swap; int i, hdr_size; + unsigned short item; float value, scale, offset; unsigned char *data; Range (*invf)(float x); float (*f)(Range x); Ray *ray; int vol_index, waveform; + char *type_str; + + int keep_hi_prf_dz = 0; /* TODO: make this an argument. */ enum waveforms {surveillance=1, doppler_w_amb_res, doppler_no_amb_res, batch}; - /* Get data moment header. */ - hdr_size = sizeof(data_hdr); - memcpy(&data_hdr, &wsr88d_ray.data[data_ptr], hdr_size); - data_ptr += hdr_size; - if (little_endian()) wsr88d_swap_data_hdr(&data_hdr); - - vol_index = wsr88d_get_vol_index(data_hdr.dataname); - if (vol_index < 0) { - fprintf(stderr,"wsr88d_load_ray: Unknown dataname %s. isweep = %d, " - "iray = %d.\n", data_hdr.dataname, isweep, iray); - return; - } - switch (vol_index) { - case DZ_INDEX: f = DZ_F; invf = DZ_INVF; break; - case VR_INDEX: f = VR_F; invf = VR_INVF; break; - case SW_INDEX: f = SW_F; invf = SW_INVF; break; - case DR_INDEX: f = DR_F; invf = DR_INVF; break; - case PH_INDEX: f = PH_F; invf = PH_INVF; break; - case RH_INDEX: f = RH_F; invf = RH_INVF; break; - } + nfields = wsr88d_ray->ray_hdr.data_block_count - nconstblocks; + field_offset = (int *) &wsr88d_ray->ray_hdr.radial_const; + do_swap = little_endian(); + iray = wsr88d_ray->ray_hdr.azm_num - 1; + + for (ifield=0; ifield < nfields; ifield++) { + field_offset++; + data_index = *field_offset; + /* Get data moment header. */ + hdr_size = sizeof(data_hdr); + memcpy(&data_hdr, &wsr88d_ray->data[data_index], hdr_size); + if (do_swap) wsr88d_swap_data_hdr(&data_hdr); + data_index += hdr_size; + + vol_index = wsr88d_get_vol_index(data_hdr.dataname); + if (vol_index < 0) { + fprintf(stderr,"wsr88d_load_ray_into_radar: Unknown dataname %s. " + "isweep = %d, iray = %d.\n", data_hdr.dataname, isweep, + iray); + return; + } + switch (vol_index) { + case DZ_INDEX: f = DZ_F; invf = DZ_INVF; + type_str = "Reflectivity"; break; + case VR_INDEX: f = VR_F; invf = VR_INVF; + type_str = "Velocity"; break; + case SW_INDEX: f = SW_F; invf = SW_INVF; + type_str = "Spectrum width"; break; + case DR_INDEX: f = DR_F; invf = DR_INVF; + type_str = "Diff. Reflectivity"; break; + case PH_INDEX: f = PH_F; invf = PH_INVF; + type_str = "Diff. Phase"; break; + case RH_INDEX: f = RH_F; invf = RH_INVF; + type_str = "Correlation Coef (Rho)"; break; + } - waveform = vcp_data.waveform[isweep]; - /* The following somewhat complicated if-statement says we'll do the - * body of the statement if: - * a) the data moment is not reflectivity, or - * b) the data moment is reflectivity and one of the following is true: - * - waveform is surveillance - * - waveform is batch - * - elevation is greater than highest split cut (i.e., 6 deg.) - */ - if (vol_index != DZ_INDEX || (waveform == surveillance || - waveform == batch || vcp_data.fixed_angle[isweep] >= 6.0)) { + waveform = vcp_data.waveform[isweep]; + + /* Ignore short-range reflectivity from velocity split cuts unless + * merging of split cuts is suppressed. The indicators for this type of + * reflectivity are surveillance mode is 0 and elevation angle is + * below 6 degrees. + */ + if (vol_index == DZ_INDEX && (vcp_data.surveil_prf_num[isweep] == 0 && + vcp_data.fixed_angle[isweep] < 6.0 && !keep_hi_prf_dz)) + continue; + + /* Load the data for this field. */ if (radar->v[vol_index] == NULL) { radar->v[vol_index] = RSL_new_volume(MAXSWEEPS); radar->v[vol_index]->h.f = f; radar->v[vol_index]->h.invf = invf; + radar->v[vol_index]->h.type_str = type_str; } if (radar->v[vol_index]->sweep[isweep] == NULL) { radar->v[vol_index]->sweep[isweep] = RSL_new_sweep(MAXRAYS_M31); @@ -453,11 +469,19 @@ void wsr88d_load_ray(Wsr88d_ray_m31 wsr88d_ray, int data_ptr, offset = data_hdr.offset; scale = data_hdr.scale; if (data_hdr.scale == 0) scale = 1.0; - data = &wsr88d_ray.data[data_ptr]; + data = &wsr88d_ray->data[data_index]; for (i = 0; i < ngates; i++) { - if (data[i] > 1) - value = (data[i] - offset) / scale; - else value = (data[i] == 0) ? BADVAL : RFVAL; + if (data_hdr.datasize_bits != 16) { + item = *data; + data++; + } else { + item = *(unsigned short *)data; + if (do_swap) swap_2_bytes(&item); + data += 2; + } + if (item > 1) + value = (item - offset) / scale; + else value = (item == 0) ? BADVAL : RFVAL; ray->range[i] = invf(value); ray->h.f = f; ray->h.invf = invf; @@ -468,24 +492,7 @@ void wsr88d_load_ray(Wsr88d_ray_m31 wsr88d_ray, int data_ptr, ray->h.nbins = ngates; radar->v[vol_index]->sweep[isweep]->ray[iray] = ray; radar->v[vol_index]->sweep[isweep]->h.nrays = iray+1; - } -} - - -void wsr88d_load_ray_into_radar(Wsr88d_ray_m31 wsr88d_ray, int isweep, int iray, - Radar *radar) -{ - int *data_ptr, hdr_size; - int i, ndatablocks, nconstblocks = 3; - - hdr_size = sizeof(wsr88d_ray.ray_hdr); - - ndatablocks = wsr88d_ray.ray_hdr.data_block_count; - data_ptr = (int *) &wsr88d_ray.ray_hdr.dbptr_ref; - for (i=0; i < ndatablocks-nconstblocks; i++) { - wsr88d_load_ray(wsr88d_ray, *data_ptr-hdr_size, isweep, iray, radar); - data_ptr++; - } + } /* for each data field */ } @@ -512,23 +519,23 @@ void wsr88d_load_sweep_header(Radar *radar, int isweep) } -Radar *load_wsr88d_m31_into_radar(Wsr88d_file *wf) +Radar *wsr88d_load_m31_into_radar(Wsr88d_file *wf) { Wsr88d_msg_hdr msghdr; Wsr88d_ray_m31 wsr88d_ray; short non31_seg_remainder[1202]; /* Remainder after message header */ - int end_of_vos = 0, isweep = 0, iray = 0; + int end_of_vos = 0, isweep = 0; int msg_hdr_size, msg_size, n; + int sweep_hdrs_written = 0, prev_elev_num = 1, prev_raynum = 0, raynum = 0; Radar *radar = NULL; - /* Message type 31 is a variable length message. All other message types - * are made up of 2432-byte segments. To handle all types, we read the - * message header and check the message type. If it is not 31, we simply - * read the remainder of the 2432-byte segment. If message type is 31, we - * use the size given in message header to determine how many bytes to - * read. For more information, see the "Interface Control Document for the - * RDA/RPG" at the WSR-88D Radar Operations Center web site. - */ + /* Message type 31 is a variable length message. All other types are made + * up of 1 or more segments, where each segment is 2432 bytes in length. + * To handle these differences, read the message header and check its type. + * If it is 31, use the size given in the message header to determine the + * number of bytes to read. If not, simply read the remainder of the + * 2432-byte segment. + */ n = fread(&msghdr, sizeof(Wsr88d_msg_hdr), 1, wf->fptr); @@ -549,36 +556,34 @@ Radar *load_wsr88d_m31_into_radar(Wsr88d_file *wf) n = read_wsr88d_ray_m31(wf, msg_size, &wsr88d_ray); /* Assume error message was issued from read routine */ if (n <= 0) return NULL; + raynum = wsr88d_ray.ray_hdr.azm_num; + if (raynum > MAXRAYS_M31) { + fprintf(stderr,"Error: raynum = %d, exceeds MAXRAYS_M31" + " (%d)\n", raynum, MAXRAYS_M31); + fprintf(stderr,"isweep = %d\n", isweep); + RSL_free_radar(radar); + return NULL; + } - /* We need to check radial status for start of new elevation. - * Sometimes this occurs without an end-of-elevation flag for the - * previous sweep, which is the trigger for loading the sweep - * header. "iray" is set to zero after end-of-elev is received, - * so that's why we check it. We issue a warning because when this - * occurs, the number of rays in the previous sweep is usually less - * than expected. + /* Check for an unexpected start of new elevation, and issue a + * warning if this has occurred. This usually means less rays than + * expected. It happens, but rarely. */ if (wsr88d_ray.ray_hdr.radial_status == START_OF_ELEV && - iray != 0) { + sweep_hdrs_written != prev_elev_num) { fprintf(stderr,"Warning: Radial status is Start-of-Elevation, " "but End-of-Elevation was not\n" "issued for elevation number %d. Number of rays = %d" - "\n", isweep+1, iray); + "\n", prev_elev_num, prev_raynum); wsr88d_load_sweep_header(radar, isweep); isweep++; - iray = 0; + sweep_hdrs_written++; + prev_elev_num = wsr88d_ray.ray_hdr.elev_num - 1; } /* Load ray into radar structure. */ - wsr88d_load_ray_into_radar(wsr88d_ray, isweep, iray, radar); - iray++; - if (iray >= MAXRAYS_M31) { - fprintf(stderr,"Error: iray = %d, equals or exceeds MAXRAYS_M31" - " (%d)\n", iray, MAXRAYS_M31); - fprintf(stderr,"isweep = %d\n", isweep); - RSL_free_radar(radar); - return NULL; - } + wsr88d_load_ray_into_radar(&wsr88d_ray, isweep, radar); + prev_raynum = raynum; } else { /* msg_type not 31 */ n = fread(&non31_seg_remainder, sizeof(non31_seg_remainder), 1, @@ -590,14 +595,13 @@ Radar *load_wsr88d_m31_into_radar(Wsr88d_file *wf) else fprintf(stderr,"Read failed.\n"); fprintf(stderr,"Current sweep index: %d\n" - "Last ray read: %d\n", isweep, iray); + "Last ray read: %d\n", isweep, prev_raynum); wsr88d_load_sweep_header(radar, isweep); return radar; } if (msghdr.msg_type == 5) { wsr88d_get_vcp_data(non31_seg_remainder); radar->h.vcp = vcp_data.vcp; - /* printf("VCP = %d\n", vcp_data.vcp); */ } } @@ -605,7 +609,8 @@ Radar *load_wsr88d_m31_into_radar(Wsr88d_file *wf) if (wsr88d_ray.ray_hdr.radial_status == END_OF_ELEV) { wsr88d_load_sweep_header(radar, isweep); isweep++; - iray = 0; + sweep_hdrs_written++; + prev_elev_num = wsr88d_ray.ray_hdr.elev_num; } /* If not at end of volume scan, read next message header. */ @@ -617,7 +622,7 @@ Radar *load_wsr88d_m31_into_radar(Wsr88d_file *wf) "Unexpected end of file.\n"); else fprintf(stderr,"Failed reading msghdr.\n"); fprintf(stderr,"Current sweep index: %d\n" - "Last ray read: %d\n", isweep, iray); + "Last ray read: %d\n", isweep, prev_raynum); wsr88d_load_sweep_header(radar, isweep); return radar; } diff --git a/wsr88d_to_radar.c b/wsr88d_to_radar.c index 0ea0672..575d9ed 100644 --- a/wsr88d_to_radar.c +++ b/wsr88d_to_radar.c @@ -44,10 +44,10 @@ Volume *copy_sweeps_into_volume(Volume *new_volume, Volume *old_volume); void float_to_range(float *x, Range *c, int n, Range (*function)(float x) ) { while (n--) { - if (*x == WSR88D_BADVAL) *c = function(BADVAL); - else if (*x == WSR88D_RFVAL) *c = function(RFVAL); - else *c = function(*x); - c++; x++; + if (*x == WSR88D_BADVAL) *c = function(BADVAL); + else if (*x == WSR88D_RFVAL) *c = function(RFVAL); + else *c = function(*x); + c++; x++; } } @@ -60,7 +60,7 @@ void float_to_range(float *x, Range *c, int n, Range (*function)(float x) ) /* March 3, 1994 */ /**********************************************************************/ int wsr88d_load_sweep_into_volume(Wsr88d_sweep ws, - Volume *v, int nsweep, unsigned int vmask) + Volume *v, int nsweep, unsigned int vmask) { int i; int iray; @@ -80,10 +80,10 @@ int wsr88d_load_sweep_into_volume(Wsr88d_sweep ws, /* Allocate memory for MAX_RAYS_IN_SWEEP rays. */ v->sweep[nsweep] = RSL_new_sweep(MAX_RAYS_IN_SWEEP); if (v->sweep[nsweep] == NULL) { - perror("wsr88d_load_sweep_into_volume: RSL_new_sweep"); - return -1; + perror("wsr88d_load_sweep_into_volume: RSL_new_sweep"); + return -1; } - + v->sweep[nsweep]->h.nrays = 0; f = (float (*)(Range x))NULL; invf = (Range (*)(float x))NULL; @@ -97,94 +97,94 @@ int wsr88d_load_sweep_into_volume(Wsr88d_sweep ws, v->sweep[nsweep]->h.f = f; for (i=0,iray=0; i 0) { - wsr88d_get_date(ws.ray[i], &mon, &day, &year); - wsr88d_get_time(ws.ray[i], &hh, &mm, &ss, &fsec); - /* - fprintf(stderr,"n %d, mon %d, day %d, year %d, hour %d, min %d, sec %d, fsec %f\n", - n, mon, day, year, hh, mm, ss, fsec); - */ - /* - * Load the sweep/ray headar information. - */ - - v->sweep[nsweep]->ray[iray] = RSL_new_ray(n); - /*(Range *)calloc(n, sizeof(Range)); */ - - ray_ptr = v->sweep[nsweep]->ray[iray]; /* Make code below readable. */ - ray_ptr->h.f = f; - ray_ptr->h.invf = invf; - ray_ptr->h.month = mon; - ray_ptr->h.day = day; - ray_ptr->h.year = year + 1900; /* Yes 1900 makes this year 2000 compliant, due to wsr88d using unix time(). */ - ray_ptr->h.hour = hh; - ray_ptr->h.minute = mm; - ray_ptr->h.sec = ss + fsec; - ray_ptr->h.unam_rng = wsr88d_get_range (ws.ray[i]); - ray_ptr->h.azimuth = wsr88d_get_azimuth (ws.ray[i]); + if (ws.ray[i] != NULL) { + wsr88d_ray_to_float(ws.ray[i], vmask, v_data, &n); + float_to_range(v_data, c_data, n, invf); + if (n > 0) { + wsr88d_get_date(ws.ray[i], &mon, &day, &year); + wsr88d_get_time(ws.ray[i], &hh, &mm, &ss, &fsec); + /* + fprintf(stderr,"n %d, mon %d, day %d, year %d, hour %d, min %d, sec %d, fsec %f\n", + n, mon, day, year, hh, mm, ss, fsec); + */ + /* + * Load the sweep/ray headar information. + */ + + v->sweep[nsweep]->ray[iray] = RSL_new_ray(n); + /*(Range *)calloc(n, sizeof(Range)); */ + + ray_ptr = v->sweep[nsweep]->ray[iray]; /* Make code below readable. */ + ray_ptr->h.f = f; + ray_ptr->h.invf = invf; + ray_ptr->h.month = mon; + ray_ptr->h.day = day; + ray_ptr->h.year = year + 1900; /* Yes 1900 makes this year 2000 compliant, due to wsr88d using unix time(). */ + ray_ptr->h.hour = hh; + ray_ptr->h.minute = mm; + ray_ptr->h.sec = ss + fsec; + ray_ptr->h.unam_rng = wsr88d_get_range (ws.ray[i]); + ray_ptr->h.azimuth = wsr88d_get_azimuth (ws.ray[i]); /* -180 to +180 is converted to 0 to 360 */ - if (ray_ptr->h.azimuth < 0) ray_ptr->h.azimuth += 360; - ray_ptr->h.ray_num = ws.ray[i]->ray_num; - ray_ptr->h.elev = wsr88d_get_elevation_angle(ws.ray[i]); - ray_ptr->h.elev_num = ws.ray[i]->elev_num; - if (vmask & WSR88D_DZ) { - ray_ptr->h.range_bin1 = ws.ray[i]->refl_rng; - ray_ptr->h.gate_size = ws.ray[i]->refl_size; - } else { - ray_ptr->h.range_bin1 = ws.ray[i]->dop_rng; - ray_ptr->h.gate_size = ws.ray[i]->dop_size; - } - ray_ptr->h.vel_res = wsr88d_get_velocity_resolution(ws.ray[i]); - vol_cpat = wsr88d_get_volume_coverage(ws.ray[i]); - switch (vol_cpat) { - case 11: ray_ptr->h.sweep_rate = 16.0/5.0; break; - case 12: ray_ptr->h.sweep_rate = 17.0/4.2; break; - case 21: ray_ptr->h.sweep_rate = 11.0/6.0; break; - case 31: ray_ptr->h.sweep_rate = 8.0/10.0; break; - case 32: ray_ptr->h.sweep_rate = 7.0/10.0; break; - case 121:ray_ptr->h.sweep_rate = 20.0/5.5; break; - default: ray_ptr->h.sweep_rate = 0.0; break; - } - - ray_ptr->h.nyq_vel = wsr88d_get_nyquist(ws.ray[i]); - ray_ptr->h.azim_rate = wsr88d_get_azimuth_rate(ws.ray[i]); - ray_ptr->h.fix_angle = wsr88d_get_fix_angle(ws.ray[i]); - ray_ptr->h.pulse_count = wsr88d_get_pulse_count(ws.ray[i]); - ray_ptr->h.pulse_width = wsr88d_get_pulse_width(ws.ray[i]); - ray_ptr->h.beam_width = .95; - ray_ptr->h.prf = wsr88d_get_prf(ws.ray[i]); - ray_ptr->h.frequency = wsr88d_get_frequency(ws.ray[i]); - ray_ptr->h.wavelength = 0.1071; /* Previously called - * wsr88d_get_wavelength(ws.ray[i]). - * See wsr88d.c for explanation. - */ - - /* It is no coincidence that the 'vmask' and wsr88d datatype - * values are the same. We expect 'vmask' to be one of - * REFL_MASK, VEL_MASK, or SW_MASK. These match WSR88D_DZ, - * WSR88D_VR, and WSR88D_SW in the wsr88d library. - */ - ray_ptr->h.nbins = n; - memcpy(ray_ptr->range, c_data, n*sizeof(Range)); - v->sweep[nsweep]->h.nrays = iray+1; - v->sweep[nsweep]->h.elev += ray_ptr->h.elev; - v->sweep[nsweep]->h.sweep_num = ray_ptr->h.elev_num; - iray++; - } - } + if (ray_ptr->h.azimuth < 0) ray_ptr->h.azimuth += 360; + ray_ptr->h.ray_num = ws.ray[i]->ray_num; + ray_ptr->h.elev = wsr88d_get_elevation_angle(ws.ray[i]); + ray_ptr->h.elev_num = ws.ray[i]->elev_num; + if (vmask & WSR88D_DZ) { + ray_ptr->h.range_bin1 = ws.ray[i]->refl_rng; + ray_ptr->h.gate_size = ws.ray[i]->refl_size; + } else { + ray_ptr->h.range_bin1 = ws.ray[i]->dop_rng; + ray_ptr->h.gate_size = ws.ray[i]->dop_size; + } + ray_ptr->h.vel_res = wsr88d_get_velocity_resolution(ws.ray[i]); + vol_cpat = wsr88d_get_volume_coverage(ws.ray[i]); + switch (vol_cpat) { + case 11: ray_ptr->h.sweep_rate = 16.0/5.0; break; + case 12: ray_ptr->h.sweep_rate = 17.0/4.2; break; + case 21: ray_ptr->h.sweep_rate = 11.0/6.0; break; + case 31: ray_ptr->h.sweep_rate = 8.0/10.0; break; + case 32: ray_ptr->h.sweep_rate = 7.0/10.0; break; + case 121:ray_ptr->h.sweep_rate = 20.0/5.5; break; + default: ray_ptr->h.sweep_rate = 0.0; break; + } + + ray_ptr->h.nyq_vel = wsr88d_get_nyquist(ws.ray[i]); + ray_ptr->h.azim_rate = wsr88d_get_azimuth_rate(ws.ray[i]); + ray_ptr->h.fix_angle = wsr88d_get_fix_angle(ws.ray[i]); + ray_ptr->h.pulse_count = wsr88d_get_pulse_count(ws.ray[i]); + ray_ptr->h.pulse_width = wsr88d_get_pulse_width(ws.ray[i]); + ray_ptr->h.beam_width = .95; + ray_ptr->h.prf = wsr88d_get_prf(ws.ray[i]); + ray_ptr->h.frequency = wsr88d_get_frequency(ws.ray[i]); + ray_ptr->h.wavelength = 0.1071; /* Previously called + * wsr88d_get_wavelength(ws.ray[i]). + * See wsr88d.c for explanation. + */ + + /* It is no coincidence that the 'vmask' and wsr88d datatype + * values are the same. We expect 'vmask' to be one of + * REFL_MASK, VEL_MASK, or SW_MASK. These match WSR88D_DZ, + * WSR88D_VR, and WSR88D_SW in the wsr88d library. + */ + ray_ptr->h.nbins = n; + memcpy(ray_ptr->range, c_data, n*sizeof(Range)); + v->sweep[nsweep]->h.nrays = iray+1; + v->sweep[nsweep]->h.elev += ray_ptr->h.elev; + v->sweep[nsweep]->h.sweep_num = ray_ptr->h.elev_num; + iray++; + } + } } v->sweep[nsweep]->h.beam_width = .95; v->sweep[nsweep]->h.vert_half_bw = .475; v->sweep[nsweep]->h.horz_half_bw = .475; /* Now calculate the mean elevation angle for this sweep. */ if (v->sweep[nsweep]->h.nrays > 0) - v->sweep[nsweep]->h.elev /= v->sweep[nsweep]->h.nrays; + v->sweep[nsweep]->h.elev /= v->sweep[nsweep]->h.nrays; else { - free(v->sweep[nsweep]); /* No rays loaded, free this sweep. */ - v->sweep[nsweep] = NULL; + free(v->sweep[nsweep]); /* No rays loaded, free this sweep. */ + v->sweep[nsweep] = NULL; } return 0; @@ -238,7 +238,7 @@ Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file) extern int *rsl_qsweep; /* See RSL_read_these_sweeps in volume.c */ extern int rsl_qsweep_max; - Radar *load_wsr88d_m31_into_radar(Wsr88d_file *wf); + Radar *wsr88d_load_m31_into_radar(Wsr88d_file *wf); sitep = NULL; /* Determine the site quasi automatically. Here is the procedure: @@ -248,42 +248,42 @@ Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file) * 3. If no valid site info, abort. */ if (call_or_first_tape_file == NULL) { - fprintf(stderr, "wsr88d_to_radar: No valid site ID info provided.\n"); - return(NULL); - } else if (strlen(call_or_first_tape_file) == 4) - sitep = wsr88d_get_site(call_or_first_tape_file); + fprintf(stderr, "wsr88d_to_radar: No valid site ID info provided.\n"); + return(NULL); + } else if (strlen(call_or_first_tape_file) == 4) + sitep = wsr88d_get_site(call_or_first_tape_file); else if (strlen(call_or_first_tape_file) == 0) { - fprintf(stderr, "wsr88d_to_radar: No valid site ID info provided.\n"); - return(NULL); + fprintf(stderr, "wsr88d_to_radar: No valid site ID info provided.\n"); + return(NULL); } if (sitep == NULL) - if (wsr88d_read_tape_header(call_or_first_tape_file, &wsr88d_tape_header) > 0) { - memcpy(site_id_str, wsr88d_tape_header.site_id, 4); - sitep = wsr88d_get_site(site_id_str); - } + if (wsr88d_read_tape_header(call_or_first_tape_file, &wsr88d_tape_header) > 0) { + memcpy(site_id_str, wsr88d_tape_header.site_id, 4); + sitep = wsr88d_get_site(site_id_str); + } if (sitep == NULL) { - fprintf(stderr,"wsr88d_to_radar: No valid site ID info found.\n"); - return(NULL); + fprintf(stderr,"wsr88d_to_radar: No valid site ID info found.\n"); + return(NULL); } - if (radar_verbose_flag) - fprintf(stderr,"SITE: %c%c%c%c\n", sitep->name[0], sitep->name[1], - sitep->name[2], sitep->name[3]); + if (radar_verbose_flag) + fprintf(stderr,"SITE: %c%c%c%c\n", sitep->name[0], sitep->name[1], + sitep->name[2], sitep->name[3]); memset(&wsr88d_sweep, 0, sizeof(Wsr88d_sweep)); /* Initialize to 0 a - * heavily used variable. - */ + * heavily used variable. + */ /* 1. Open the input wsr88d file. */ if (infile == NULL) the_file = "stdin"; /* wsr88d.c understands this to - * mean read from stdin. - */ + * mean read from stdin. + */ else the_file = infile; if ((wf = wsr88d_open(the_file)) == NULL) { - wsr88d_perror(the_file); - return NULL; + wsr88d_perror(the_file); + return NULL; } @@ -316,24 +316,23 @@ Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file) if (n <= 0 || expected_msgtype == 0) { fprintf(stderr,"RSL_wsr88d_to_radar: "); if (n <= 0) - fprintf(stderr,"wsr88d_read_file_header failed\n"); + fprintf(stderr,"wsr88d_read_file_header failed\n"); else - fprintf(stderr,"Archive II header contains unknown version " - ": '%s'\n", version); + fprintf(stderr,"Archive II header contains unknown version " + ": '%s'\n", version); wsr88d_close(wf); - free(radar); return NULL; } if (radar_verbose_flag) - print_head(wsr88d_file_header); + print_head(wsr88d_file_header); if (expected_msgtype == 31) { /* Get radar for message type 31. */ nvolumes = 6; - radar = load_wsr88d_m31_into_radar(wf); + radar = wsr88d_load_m31_into_radar(wf); if (radar == NULL) return NULL; } else { @@ -352,58 +351,58 @@ Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file) */ for (iv=0; ivv[iv] = RSL_new_volume(20); + if (rsl_qfield[iv]) radar->v[iv] = RSL_new_volume(20); /* LOOP until EOF */ nsweep = 0; for (;(n = wsr88d_read_sweep(wf, &wsr88d_sweep)) > 0; nsweep++) { - if (rsl_qsweep != NULL) { - if (nsweep > rsl_qsweep_max) break; - if (rsl_qsweep[nsweep] == 0) continue; - } - if (radar_verbose_flag) - fprintf(stderr,"Processing for SWEEP # %d\n", nsweep); - - /* wsr88d_print_sweep_info(&wsr88d_sweep); */ - - for (iv=0; iv= radar->v[iv]->h.nsweeps) { - if (radar_verbose_flag) - fprintf(stderr,"Exceeded sweep allocation of %d. " - "Adding 20 more.\n", nsweep); - new_volume = RSL_new_volume(radar->v[iv]->h.nsweeps+20); - new_volume = copy_sweeps_into_volume(new_volume, radar->v[iv]); - radar->v[iv] = new_volume; - } - if (wsr88d_load_sweep_into_volume(wsr88d_sweep, - radar->v[iv], nsweep, volume_mask[iv]) != 0) { - RSL_free_radar(radar); - return NULL; - } - } - } - if (nsweep == 0) { - /* Get Volume Coverage Pattern number for radar header. */ - i=0; - while (i < MAX_RAYS_IN_SWEEP && wsr88d_sweep.ray[i] == NULL) i++; - if (i < MAX_RAYS_IN_SWEEP) radar->h.vcp = wsr88d_get_volume_coverage( - wsr88d_sweep.ray[i]); - } - - free_and_clear_sweep(&wsr88d_sweep, 0, MAX_RAYS_IN_SWEEP); + if (rsl_qsweep != NULL) { + if (nsweep > rsl_qsweep_max) break; + if (rsl_qsweep[nsweep] == 0) continue; + } + if (radar_verbose_flag) + fprintf(stderr,"Processing for SWEEP # %d\n", nsweep); + + /* wsr88d_print_sweep_info(&wsr88d_sweep); */ + + for (iv=0; iv= radar->v[iv]->h.nsweeps) { + if (radar_verbose_flag) + fprintf(stderr,"Exceeded sweep allocation of %d. " + "Adding 20 more.\n", nsweep); + new_volume = RSL_new_volume(radar->v[iv]->h.nsweeps+20); + new_volume = copy_sweeps_into_volume(new_volume, radar->v[iv]); + radar->v[iv] = new_volume; + } + if (wsr88d_load_sweep_into_volume(wsr88d_sweep, + radar->v[iv], nsweep, volume_mask[iv]) != 0) { + RSL_free_radar(radar); + return NULL; + } + } + } + if (nsweep == 0) { + /* Get Volume Coverage Pattern number for radar header. */ + i=0; + while (i < MAX_RAYS_IN_SWEEP && wsr88d_sweep.ray[i] == NULL) i++; + if (i < MAX_RAYS_IN_SWEEP) radar->h.vcp = wsr88d_get_volume_coverage( + wsr88d_sweep.ray[i]); + } + + free_and_clear_sweep(&wsr88d_sweep, 0, MAX_RAYS_IN_SWEEP); } for (iv=0; ivv[iv]->h.type_str = strdup(field_str[iv]); - radar->v[iv]->h.nsweeps = nsweep; - } + if (rsl_qfield[iv]) { + radar->v[iv]->h.type_str = strdup(field_str[iv]); + radar->v[iv]->h.nsweeps = nsweep; + } } } wsr88d_close(wf); @@ -414,30 +413,32 @@ Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file) */ radar_load_date_time(radar); /* Magic :-) */ - radar->h.number = sitep->number; - memcpy(&radar->h.name, sitep->name, sizeof(sitep->name)); - memcpy(&radar->h.radar_name, sitep->name, sizeof(sitep->name)); /* Redundant */ - memcpy(&radar->h.city, sitep->city, sizeof(sitep->city)); - memcpy(&radar->h.state, sitep->state, sizeof(sitep->state)); - strcpy(radar->h.radar_type, "wsr88d"); - radar->h.latd = sitep->latd; - radar->h.latm = sitep->latm; - radar->h.lats = sitep->lats; - if (radar->h.latd < 0) { /* Degree/min/sec all the same sign */ - radar->h.latm *= -1; - radar->h.lats *= -1; - } - radar->h.lond = sitep->lond; - radar->h.lonm = sitep->lonm; - radar->h.lons = sitep->lons; - if (radar->h.lond < 0) { /* Degree/min/sec all the same sign */ - radar->h.lonm *= -1; - radar->h.lons *= -1; - } - radar->h.height = sitep->height; - radar->h.spulse = sitep->spulse; - radar->h.lpulse = sitep->lpulse; - + radar->h.number = sitep->number; + memcpy(&radar->h.name, sitep->name, sizeof(sitep->name)); + memcpy(&radar->h.radar_name, sitep->name, sizeof(sitep->name)); /* Redundant */ + memcpy(&radar->h.city, sitep->city, sizeof(sitep->city)); + memcpy(&radar->h.state, sitep->state, sizeof(sitep->state)); + strcpy(radar->h.radar_type, "wsr88d"); + radar->h.latd = sitep->latd; + radar->h.latm = sitep->latm; + radar->h.lats = sitep->lats; + if (radar->h.latd < 0) { /* Degree/min/sec all the same sign */ + radar->h.latm *= -1; + radar->h.lats *= -1; + } + radar->h.lond = sitep->lond; + radar->h.lonm = sitep->lonm; + radar->h.lons = sitep->lons; + if (radar->h.lond < 0) { /* Degree/min/sec all the same sign */ + radar->h.lonm *= -1; + radar->h.lons *= -1; + } + radar->h.height = sitep->height; + radar->h.spulse = sitep->spulse; + radar->h.lpulse = sitep->lpulse; + + free(sitep); + radar = RSL_prune_radar(radar); return radar; } -- 2.43.2