/* 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
*
$(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
-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 <Bartie.L.Kelley@nasa.gov>.
+
What is RSL?
This software manipulates NexRad, Lassen, UF, sigmet, kwajalein,
toga, RAPIC, RADTEC, mcgill and EDGE radar formats.
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.
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
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
---------------------
*/
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "africa.h"
int africa_read_buffer(FILE *fp, Africa_buffer *buffer)
-/*
- 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 <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-#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;
-}
-
-
+/*\r
+ NASA/TRMM, Code 910.1.\r
+ This is the TRMM Office Radar Software Library.\r
+ Copyright (C) 1996, 1997\r
+ John H. Merritt\r
+ Space Applications Corporation\r
+ Vienna, Virginia\r
+\r
+ This library is free software; you can redistribute it and/or\r
+ modify it under the terms of the GNU Library General Public\r
+ License as published by the Free Software Foundation; either\r
+ version 2 of the License, or (at your option) any later version.\r
+\r
+ This library is distributed in the hope that it will be useful,\r
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ Library General Public License for more details.\r
+\r
+ You should have received a copy of the GNU Library General Public\r
+ License along with this library; if not, write to the Free\r
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\r
+*/\r
+/*\r
+ * By John H. Merritt\r
+ * Science Applications Corporation, Vienna, VA\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include "rsl.h"\r
+void rsl_readflush(FILE *fp);\r
+/*********************************************************************/\r
+/* */\r
+/* RSL_filetype */\r
+/* */\r
+/*********************************************************************/\r
+enum File_type RSL_filetype(char *infile)\r
+{\r
+ /* Open the input file and peek at the first few bytes to determine\r
+ * the type of file.\r
+ * \r
+ * UF - First two bytes 'UF'\r
+ * - or 3,4 bytes 'UF'\r
+ * - or 5,6 bytes 'UF'. This is the most common.\r
+ *\r
+ * WSR88D - First 8 bytes: 'ARCHIVE2' or 'AR2V0001'\r
+ *\r
+ * TOGA - ??\r
+ * NSIG - ??\r
+ * LASSEN - SUNRISE\r
+ * RSL - RSL\r
+ * MCGILL - P A B\r
+ * RAPIC - /IMAGE:\r
+ * RADTEC - 320 (decimal, in first two bytes)\r
+ * RAINBOW - First two bytes: decimal 1, followed by 'H'\r
+ */\r
+ FILE *fp;\r
+ char magic[11];\r
+\r
+ if ((fp = fopen(infile, "r")) == NULL) {\r
+ perror(infile);\r
+ return UNKNOWN;\r
+ }\r
+\r
+ /* Read the magic bytes. */\r
+ fp = uncompress_pipe(fp); /* If gzip available. */\r
+ if (fread(magic, sizeof(magic), 1, fp) != 1) {\r
+ char *magic_str = (char *)calloc(sizeof(magic)+1, sizeof(char));\r
+ memcpy(magic_str, magic, sizeof(magic));\r
+ fprintf(stderr,"Error fread: Magic is %s\n", magic_str);\r
+ free (magic_str);\r
+ perror("RSL_filetype");\r
+ /* Thanks to Thiago Biscaro for fixing defunct process problem. */\r
+ rsl_pclose(fp);\r
+ return UNKNOWN;\r
+ }\r
+\r
+ /*\r
+ Closes the stream and wait for associated processes to terminate\r
+ (just like wait() ) to avoid defunct processes. The old rsl_readflush\r
+ function wasn't doing this, N calls to anyformat_to_radar would\r
+ generate N defunct processes associated with the main program\r
+ --Thiago Biscaro\r
+ */\r
+\r
+ rsl_pclose(fp);\r
+ \r
+ if (strncmp("ARCHIVE2.", magic, 9) == 0) return WSR88D_FILE;\r
+ if (strncmp("AR2V000", magic, 7) == 0) return WSR88D_FILE;\r
+ if (strncmp("UF", magic, 2) == 0) return UF_FILE;\r
+ if (strncmp("UF", &magic[2], 2) == 0) return UF_FILE;\r
+ if (strncmp("UF", &magic[4], 2) == 0) return UF_FILE;\r
+ if ((int)magic[0] == 0x0e &&\r
+ (int)magic[1] == 0x03 &&\r
+ (int)magic[2] == 0x13 &&\r
+ (int)magic[3] == 0x01\r
+ ) return HDF_FILE;\r
+ if (strncmp("RSL", magic, 3) == 0) return RSL_FILE;\r
+ if ((int)magic[0] == 7) return NSIG_FILE_V1;\r
+ if ((int)magic[1] == 7) return NSIG_FILE_V1;\r
+ if ((int)magic[0] == 27) return NSIG_FILE_V2;\r
+ if ((int)magic[1] == 27) return NSIG_FILE_V2;\r
+ if (strncmp("/IMAGE:", magic, 7) == 0) return RAPIC_FILE;\r
+ if ((int)magic[0] == 0x40 &&\r
+ (int)magic[1] == 0x01\r
+ ) return RADTEC_FILE;\r
+ if ((int)magic[0] == 0x01 && magic[1] == 'H') return RAINBOW_FILE;\r
+\r
+ if (strncmp("SUNRISE", &magic[4], 7) == 0) return LASSEN_FILE;\r
+/* The 'P A B' is just too specific to be a true magic number, but that's all\r
+ * I've got.\r
+ */\r
+ if (strncmp("P A B ", magic, 6) == 0) return MCGILL_FILE;\r
+ /* Byte swapped ? */\r
+ if (strncmp(" P A B", magic, 6) == 0) return MCGILL_FILE;\r
+ if (strncmp("Volume", magic, 6) == 0) return EDGE_FILE;\r
+ if (strncmp("SSWB", magic, 4) == 0) return DORADE_FILE;\r
+ if (strncmp("VOLD", magic, 4) == 0) return DORADE_FILE;\r
+\r
+ return UNKNOWN;\r
+}\r
+ \r
+\r
+\r
+\r
+ \r
+\r
+\r
+/*********************************************************************/\r
+/* */\r
+/* RSL_anyformat_to_radar */\r
+/* */\r
+/*********************************************************************/\r
+\r
+Radar *RSL_anyformat_to_radar(char *infile, ...)\r
+{\r
+ va_list ap;\r
+ char *callid_or_file;\r
+ Radar *radar;\r
+\r
+/* If it is detected that the input file is WSR88D, use the second argument\r
+ * as the call id of the site, or the file name of the tape header file.\r
+ *\r
+ * Assumption: Input files are seekable.\r
+ */\r
+ radar = NULL;\r
+ switch (RSL_filetype(infile)) {\r
+ case WSR88D_FILE:\r
+ callid_or_file = NULL;\r
+ va_start(ap, infile);\r
+ callid_or_file = va_arg(ap, char *);\r
+ va_end(ap);\r
+ radar = RSL_wsr88d_to_radar(infile, callid_or_file);\r
+ break;\r
+ case UF_FILE: radar = RSL_uf_to_radar(infile); break;\r
+ case TOGA_FILE: radar = RSL_toga_to_radar(infile); break;\r
+ case NSIG_FILE_V1: radar = RSL_nsig_to_radar(infile); break;\r
+ case NSIG_FILE_V2: radar = RSL_nsig2_to_radar(infile); break;\r
+ case RAPIC_FILE: radar = RSL_rapic_to_radar(infile); break;\r
+ case RADTEC_FILE: radar = RSL_radtec_to_radar(infile); break;\r
+ case RSL_FILE: radar = RSL_read_radar(infile); break;\r
+#ifdef HAVE_LIBTSDISTK\r
+ case HDF_FILE: radar = RSL_hdf_to_radar(infile); break;\r
+#endif\r
+ case RAINBOW_FILE: radar = RSL_rainbow_to_radar(infile); break;\r
+ case MCGILL_FILE: radar = RSL_mcgill_to_radar(infile); break;\r
+ case EDGE_FILE: radar = RSL_EDGE_to_radar(infile); break;\r
+ case LASSEN_FILE: radar = RSL_lassen_to_radar(infile); break;\r
+ case DORADE_FILE: radar = RSL_dorade_to_radar(infile); break;\r
+\r
+ default:\r
+ fprintf(stderr, "Unknown input file type. File <%s> is not recognized by RSL.\n", infile);\r
+ return NULL;\r
+ }\r
+ \r
+ return radar;\r
+}\r
+\r
+\r
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
<h4>
By <a href="john.merritt.html">John H. Merritt</a> and <a href="david.wolff.html">David
B. Wolff</a>; NASA/TRMM Office<br>
-Software Verson 1.40 (released 10/10/2008)</h4>
+Software Verson 1.41 (released 6/22/2011)</h4>
<hr>This library is an object oriented programming environment to keep
application programming simple, for the casual C programmer, as well as
<a href="index.html"><img src="rsl.gif">
</a><a href="index.html"> </a>
<hr>
-<pre>typedef struct {<br> int month; /* Date for this ray; month (1-12). */<br> int day; /* Date for this ray; day (1-31). */<br> int year; /* Date for this ray; year (eg. 1993). */<br> int hour; /* Time for this ray; hour (0-23). */<br> int minute;/* Time for this ray; minute (0-59).*/<br> float sec; /* Time for this ray; second + fraction of second. */<br> float unam_rng; /* Unambiguous range. (KM). */<br> float azimuth; /* Azimuth angle. (degrees). Must be positive<br> * 0=North, 90=east, -90/270=west.<br> * This angle is the mean azimuth for the whole ray.<br> * Eg. for NSIG the beginning and end azimuths are<br> * averaged.<br> */<br> int ray_num; /* Ray no. within elevation scan. */<br> float elev; /* Elevation angle. (degrees). */<br> int elev_num; /* Elevation no. within volume scan. */<br> <br> int range_bin1; /* Range to first gate.(meters) */<br> int gate_size; /* Data gate size (meters)*/<br> <br> float vel_res; /* Doppler velocity resolution */<br> float sweep_rate; /* Sweep rate. Full sweeps/min. */<br> <br> int prf; /* Pulse repitition frequency, in Hz. */<br> float azim_rate; /* Sweep rate in degrees/second.*/<br> float fix_angle; /* Elevation angle for the sweep. (degrees). */<br> float pitch; /* Pitch angle. */<br> float roll; /* Roll angle. */<br> float heading; /* Heading. */<br> float pitch_rate; /* (angle/sec) */<br> float roll_rate; /* (angle/sec) */<br> float heading_rate; /* (angle/sec) */<br> float lat; /* Latitude (degrees) */<br> float lon; /* Longitude (degrees) */<br> int alt; /* Altitude (m) */<br> float rvc; /* Radial velocity correction (m/sec) */<br> float vel_east; /* Platform velocity to the east (m/sec) */<br> float vel_north; /* Platform velocity to the north (m/sec) */<br> float vel_up; /* Platform velocity toward up (m/sec) */<br> float pulse_count; /* Pulses used in a single dwell time. */<br> float pulse_width; /* Pulse width (micro-sec). */<br> float beam_width; /* Beamwidth in degrees. */<br> float frequency; /* Bandwidth MHz. */<br> float wavelength; /* Wavelength. Meters. */<br> float nyq_vel; /* Nyquist velocity. m/s */<br> float (*f)(Range x); /* Data conversion function. f(x). */<br> Range (*invf)(float x); /* Data conversion function. invf(x). */<br> int nbins; /* Number of array elements for 'Range'. */<br>} Ray_header;</pre>
+<pre>typedef struct {<br> int month; /* Date for this ray; month (1-12). */<br> int day; /* Date for this ray; day (1-31). */<br> int year; /* Date for this ray; year (eg. 1993). */<br> int hour; /* Time for this ray; hour (0-23). */<br> int minute;/* Time for this ray; minute (0-59).*/<br> float sec; /* Time for this ray; second + fraction of second. */<br> float unam_rng; /* Unambiguous range. (KM). */<br> float azimuth; /* Azimuth angle. (degrees). Must be positive<br> * 0=North, 90=east, -90/270=west.<br> * This angle is the mean azimuth for the whole ray.<br> * Eg. for NSIG the beginning and end azimuths are<br> * averaged.<br> */<br> int ray_num; /* Ray no. within elevation scan. */<br> float elev; /* Elevation angle. (degrees). */<br> int elev_num; /* Elevation no. within volume scan. */<br> <br> int range_bin1; /* Range to first gate.(meters) */<br> int gate_size; /* Data gate size (meters)*/<br> <br> float vel_res; /* Doppler velocity resolution */<br> float sweep_rate; /* Sweep rate. Full sweeps/min. */<br> <br> int prf; /* Pulse repitition frequency, in Hz. */<br> int prf2; /* Second PRF, for Sigmet dual PRF. */<br> float azim_rate; /* Sweep rate in degrees/second.*/<br> float fix_angle; /* Elevation angle for the sweep. (degrees). */<br> float pitch; /* Pitch angle. */<br> float roll; /* Roll angle. */<br> float heading; /* Heading. */<br> float pitch_rate; /* (angle/sec) */<br> float roll_rate; /* (angle/sec) */<br> float heading_rate; /* (angle/sec) */<br> float lat; /* Latitude (degrees) */<br> float lon; /* Longitude (degrees) */<br> int alt; /* Altitude (m) */<br> float rvc; /* Radial velocity correction (m/sec) */<br> float vel_east; /* Platform velocity to the east (negative for west) (m/sec) */<br> float vel_north; /* Platform velocity to the north (negative for south) (m/sec) */<br> float vel_up; /* Platform velocity toward up (negative for down) (m/sec) */<br> float pulse_count; /* Pulses used in a single dwell time. */<br> float pulse_width; /* Pulse width (micro-sec). */<br> float beam_width; /* Beamwidth in degrees. */<br> float frequency; /* Bandwidth MHz. */<br> float wavelength; /* Wavelength. Meters. */<br> float nyq_vel; /* Nyquist velocity. m/s */<br> float (*f)(Range x); /* Data conversion function. f(x). */<br> Range (*invf)(float x); /* Data conversion function. invf(x). */<br> int nbins; /* Number of array elements for 'Range'. */<br>} Ray_header;</pre>
<br>
</body>
</html>
<h1>
What's new?</h1>
+<h2>
+06/22/2011: Version 1.41 supports WSR-88D Level II Build 12 format.</h2>
<h2>
07/24/2008: Version 1.39 supports WSR-88D Level II Build 10 format.</h2>
<h2>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
-#include <strings.h>
#include <string.h>
#define USE_RSL_VARS
#include "rsl.h"
}
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
Sweep *sweep;
* the RSL.
*
*/
+#include <stdlib.h>
#define USE_RSL_VARS
#include "rsl.h"
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
Sweep *sweep;
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "rsl.h"
#include <stdio.h>
+#include <stdlib.h>
#include "rsl.h"
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);
}
}
}
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
Sweep *sweep;
+#include <stdlib.h>
#include "rsl.h"
/**********************************************************************/
* This program can read the file from stdin.
*/
+#include <stdlib.h>
#include "rsl.h"
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
*
*/
+#include <stdlib.h>
#include "rsl.h"
void print_link_list(Azimuth_hash *list)
}
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
Sweep *sweep;
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. */
{
/* Make pathname by combining directory name, if given, with filename. */
- if (*dir == NULL) {
+ if (!dir || !dir[0]) {
strcpy(pathname, filename);
}
else {
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();
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);
#include <stdio.h>
+#include <stdlib.h>
#include "rsl.h"
/*
}
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
Sweep *sector;
* wsr88d_to_gif file [tape_header_file]
*/
+#include <stdlib.h>
#include "rsl.h"
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
Radar *radar;
if (fpipe == NULL) perror("uncompress_pipe");
close(0);
dup(save_fd);
+ close(save_fd);
return fpipe;
}
*/
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <math.h>
#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
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);
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);
*/
-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);
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;
/* ---- 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;
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;
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "rsl.h"
#include "rainbow.h"
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "rsl.h"
#include "rainbow.h"
Charlen token;
}
-%expect 59
+%expect 61
%%
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); */
#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*/
#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.
*/
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.
} 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
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
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
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
/*
* 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"
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 {
}
-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);
}
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++) {
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);
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;
}
-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;
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];
*/
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);
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);
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;
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 */
}
}
-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);
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,
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); */
}
}
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. */
"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;
}
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++;
}
}
/* 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;
/* 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;
v->sweep[nsweep]->h.f = f;
for (i=0,iray=0; i<MAX_RAYS_IN_SWEEP; 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]);
+ 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;
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:
* 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;
}
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 {
*/
for (iv=0; iv<nvolumes; iv++)
- if (rsl_qfield[iv]) radar->v[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<nvolumes; iv++) {
- if (rsl_qfield[iv]) {
- /* Exceeded sweep limit.
- * Allocate more sweeps.
- * Copy all previous sweeps.
- */
- if (nsweep >= 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<nvolumes; iv++) {
+ if (rsl_qfield[iv]) {
+ /* Exceeded sweep limit.
+ * Allocate more sweeps.
+ * Copy all previous sweeps.
+ */
+ if (nsweep >= 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; iv<nvolumes; iv++) {
- if (rsl_qfield[iv]) {
- radar->v[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);
*/
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;
}