/* Changes for RSL
*
*---------------------------------------------------------------------
+ * v1.43 Released 4/30/2011
+ *
+ * 1. nsig_to_radar.c: Added antenna scan mode to radar header.
+ * Added azimuth to sweep header for RHI.
+ * Fixed a bug that caused incorrect elevation in ray headers for RHI.
+ * 2. nsig.c (nsig_read_sweep): Bug fix: Removed static qualifier from
+ * ingest structure definitions, which caused problems if multiple radars
+ * are ingested. Also turned off debug print accidently left on
+ * in previous release. Thanks to James Ward for the bug report.
+ * 3. wsr88d.c, wsr88d_to_radar.c: Fixed problem that occurred in the rare
+ * case in which a non-data message appears among data messages.
+ * wsr88d_to_radar.c: Bug fix: Initialize sweep elevation.
+ * Thanks to Dan Sheldon for the bug reports and fixes.
+ * 4. configure.in: Changed default directory to /usr/local/trmm/.
+ * 5. Removed references to EDGE. Thanks to Andy Spencer for the patch.
+ *---------------------------------------------------------------------
* v1.42 Released 7/12/2011
*
* 1. radar_to_uf.c (RSL_radar_to_uf_fp): Changed scale_factor used for storing
lib_LTLIBRARIES = librsl.la
-librsl_la_LDFLAGS = -version-info 1:42
+librsl_la_LDFLAGS = -version-info 1:43
librsl_la_SOURCES = \
$(rapic_c) $(radtec_c)\
dorade.c dorade_print.c dorade_to_radar.c\
lassen.c lassen_to_radar.c \
-edge_to_radar.c \
radar.c volume.c image_gen.c cappi.c fraction.c read_write.c farea.c \
range.c radar_to_uf.c uf_to_radar.c wsr88d_to_radar.c \
carpi.c cube.c sort_rays.c toga_to_radar.c gts.c histogram.c \
-v1.42 (Released 7/12/2011)
+v1.43 (Released 4/30/2012)
This is the README file for the Radar Software Library (RSL).
What is RSL?
This software manipulates NexRad, Lassen, UF, sigmet, kwajalein,
-toga, RAPIC, RADTEC, mcgill and EDGE radar formats.
+toga, RAPIC, RADTEC, and mcgill radar formats.
The radar data is used by the NASA TRMM Office to produce rain
and climatological products. This software
System Requirements:
Linux, Mac OS X 10.5.
- Note: MS Windows is not supported.
+Note: RSL is not supported on Microsoft Windows.
Memory Requirements:
16 Mbytes of RAM just to ingest the data. Plus any for your application.
Compression library. Call PKWARE, Inc. at 414-354-8699 or via
http://www.pkware.com.
- libetor The EDGE libraray to decode the EDGE format.
- This is available from Enterprise Electronics
- Corporation, Enterprise, Alabama, USA 36330
- 334-347-3478.
-
Example mainlines are provided in the directory examples.
INSTALLATION INSTRUCTIONS
1. Unpack the GNU compressed tar archive, example:
- tar -xzf rsl-v1.29.tgz
+ tar -xzf rsl-v1.43.tgz
-or-
- zcat rsl-v1.29.tgz | tar xf -
+ zcat rsl-v1.43.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
QUESTIONS
---------
-Contact the TRMM Office help at help@radar.gsfc.nasa.gov
+Contact the TRMM Office help at gsfc-rsl-help@lists.nasa.gov
--- /dev/null
+Thanks to the following folks who helped make RSL a better product.
+Ther contributions include reporting bugs, offering suggestions, and sending
+code for bug fixes. Thanks again!
+
+Cesar Beneti
+Thiago Biscaro
+Stacy Brodzik
+Eric Bruning
+Scott Collis
+Patrick Gatlin
+John Hall
+David Kingsmill
+Fabio Sato
+Daniel Sheldon
+Andy Spencer
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
#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
dnl Process this file with autoconf to produce a configure script.
-AC_INIT(rsl, v1.42)
+AC_INIT(rsl, v1.43)
AC_CONFIG_SRCDIR(volume.c)
AM_INIT_AUTOMAKE
AM_CONFIG_HEADER(config.h)
dnl Default for GVS and friends.
-AC_PREFIX_DEFAULT(/usr/local/trmm/GVBOX)
+AC_PREFIX_DEFAULT(/usr/local/trmm)
dnl Checks for programs.
AC_PROG_CC
<p>RSL output format
<p>RAPIC (Berrimah Austrailia)
<p>RADTEC (SPANDAR, requires PKWARE compression tools)
-<p>EDGE
<p>DORADE
<p>For TOGA and KWAJALEIN files, there is no standard magic information
available. It may not be possible for RSL_anyformat_to_radar to recognize
int height; /* height of site in meters above sea level*/
int spulse; /* length of short pulse (ns)*/
int lpulse; /* length of long pulse (ns) */
- int vcp; /* Volume Coverage Pattern (for WSR-88D only) */
+ int scan_mode; /* 0 = PPI, 1 = RHI */
+ int vcp; /* Volume Coverage Pattern (WSR-88D only) */
} Radar_header;</pre>
</body>
Input</h1>
<a href="RSL_anyformat_to_radar.html">Radar *RSL_anyformat_to_radar(char
*infile [, char *callid_or_first_file]);</a>
-<br><a href="RSL_edge_to_radar.html">Radar *RSL_edge_to_radar(char *infile);</a>
<br><a href="RSL_kwaj_to_radar.html">Radar *RSL_kwaj_to_radar(char *infile);</a>
<br><a href="RSL_lassen_to_radar.html">Radar *RSL_lassen_to_radar(char
*infile);</a>
<p>
<hr></center>
-<h2>
-Current RSL Version 1.42, released 7/12/2011<br>
-Supports WSR-88D Level II Build 12 Format</h2>
+<h2>Current RSL Version 1.43, released 4/30/2012</h2>
In support of the <a href="http://trmm-fc.gsfc.nasa.gov">Tropical Rainfall
Measuring Mission</a>'s (TRMM) <a href="http://trmm-fc.gsfc.nasa.gov/trmm_gv/index.html">Global
<td>Yes</td>
-<td>No</td>
-</tr>
-
-<tr>
-<td>EDGE</td>
-
-<td>Yes</td>
-
<td>No</td>
</tr>
</table></center>
(alphabetical and grouped by object returned)</h5>
<a href="RSL_anyformat_to_radar.html">Radar *RSL_anyformat_to_radar(char
*infile [, char *callid_or_first_file]);</a>
-<br><a href="RSL_edge_to_radar.html">Radar *RSL_edge_to_radar(char *infile);</a>
<br><a href="RSL_get_win.html">Radar *RSL_get_window_from_radar(Radar *r,
float min_range, float max_range, float low_azim, float hi_azim);</a>
<br><a href="RSL_hdf_to_radar.html">Radar *RSL_hdf_to_radar(char *infile);</a>
<td>None</td>
</tr>
-<tr>
-<td>EDGE</td>
-
-<td><a href="RSL_edge_to_radar.html">RSL_edge_to_radar</a></td>
-
-<td>None</td>
</tr>
</table>
RSL is designed to provide you with a uniform data structure so that you
<h1>
What's new?</h1>
+<h2> Version 1.43:</h2>
+Mostly bug fixes. See <a href="../CHANGES">CHANGES</a>.
<h2>
Version 1.42: Bug fix.</h2>
Changed scale_factor used for storing differential phase (PH) in UF from 100 to
structure.
<h2>
Version 1.23 release (what's new since v1.18).</h2>
-RSL now accpets the EDGE format. See <a href="RSL_edge_to_radar.html">RSL_edge_to_radar</a>.
+RSL now accpets the EDGE format.
KDP definition changed. It now normalizes the value based on the
radar wavelength. A bug in the RADTEC ingest routine was removed.
Other than that, mostly bug fixes that were very minor. Added <a href="RSL_color_table.html">RSL_set_color_table</a>
{
NSIG_Sweep **s;
int i, j, n;
- static NSIG_Ingest_data_header **idh = NULL;
- static NSIG_Raw_prod_bhdr *bhdr = NULL;
+ NSIG_Ingest_data_header **idh = NULL;
+ NSIG_Raw_prod_bhdr *bhdr = NULL;
NSIG_Ray *nsig_ray;
int data_mask, iray, nrays[12], max_rays;
int masks[5];
*/
#define Vprint
-/* #undef Vprint */
+#undef Vprint
/* Determine if we need to byte-swap values. */
(void)nsig_endianess(&prod_file->rec1);
/* This is a NEW sweep. */
iray = 0;
#ifdef Vprint
- int isweep;
+ {int isweep;
isweep = NSIG_I2(idh[0]->sweep_num);
printf("Number of rays in sweep %d is %d\n", isweep, max_rays);
-
+ }
#endif
/* Allocate memory for sweep. */
s = (NSIG_Sweep **) calloc (nparams, sizeof(NSIG_Sweep*));
float azm, elev, pitch, roll, heading, azm_rate, elev_rate,
pitch_rate, roll_rate, heading_rate,
lat, lon;
+ float fix_angle;
int alt; /* Altitude */
float rvc; /* Radial correction velocity m/s */
float vel_east, vel_north, vel_up; /* Platform velocity vectors m/sec */
radar->h.height = (int)sea_lvl_hgt;
radar->h.spulse = (int)(pw*1000);
radar->h.lpulse = (int)(pw*1000);
+ ant_scan_mode = NSIG_I2(prod_file->rec2.task_config.scan_info.ant_scan_mode);
+ if(ant_scan_mode == 2 || ant_scan_mode == 7) radar->h.scan_mode = RHI;
+ else radar->h.scan_mode = PPI;
if (radar_verbose_flag) {
#ifdef NSIG_VER2
sweep->h.beam_width = beam_width;
sweep->h.vert_half_bw = vert_half_bw;
sweep->h.horz_half_bw = horz_half_bw;
- elev = nsig_from_bang(nsig_sweep[itype]->idh.fix_ang);
- sweep->h.elev = elev;
+ fix_angle = nsig_from_bang(nsig_sweep[itype]->idh.fix_ang);
+ if (radar->h.scan_mode == PPI) sweep->h.elev = fix_angle;
+ else sweep->h.azimuth = fix_angle;
for(j = 0; j < num_rays; j++)
{
else
ray->h.unam_rng = 0.0;
ray->h.prf2 = (int) prf2;
- ray->h.fix_angle = (float)sweep->h.elev;
+ ray->h.fix_angle = fix_angle;
ray->h.azim_rate = azim_rate;
ray->h.pulse_count = num_samples;
ray->h.pulse_width = pw;
/* 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. */
+/* 7/25/2011 There's really no need to remove this code after merge_split_cuts.
+ * We can continue using it for exact VR azimuth in RSL. Non-RSL programs can
+ * use the mandatory header azimuth, which is exact for DZ and a close
+ * approximation for VR when merge-split-cuts is applied.
+ */
+/* Preprocessor directives are for testing. */
#define LUHDR_VR_AZ
#ifdef LUHDR_VR_AZ
/* If DZ and VR azimuths are different, store VR azimuth in Local Use
#include "config.h"
#endif
-#define RSL_VERSION_STR "v1.42"
+#define RSL_VERSION_STR "v1.43"
/**********************************************************************/
/* Configure: Define USE_TWO_BYTE_PRECISION to have RSL store internal*/
/* so you shouldn't have to modify anything here. */
/**********************************************************************/
#ifndef COLORDIR
-#define COLORDIR "/usr/local/trmm/GVBOX/lib/colors"
+#define COLORDIR "/usr/local/trmm/lib/colors"
#endif
/* These are the color table indexes. See RSL_set/get_color_table. */
/* File format types recognized by RSL. */
enum File_type {UNKNOWN, WSR88D_FILE, UF_FILE, LASSEN_FILE,
- TOGA_FILE, NSIG_FILE_V1, NSIG_FILE_V2,
- RSL_FILE, MCGILL_FILE, HDF_FILE, RAPIC_FILE,
- RADTEC_FILE, EDGE_FILE, DORADE_FILE, RAINBOW_FILE};
+ TOGA_FILE, NSIG_FILE_V1, NSIG_FILE_V2,
+ RSL_FILE, MCGILL_FILE, HDF_FILE, RAPIC_FILE,
+ RADTEC_FILE, DORADE_FILE, RAINBOW_FILE};
/* Pick a BADVAL that is out of range. That is, the range
* of the conversion cannot include these reserved values.
typedef struct _azimuth_hash {
- Ray *ray;
+ Ray *ray;
struct _azimuth_hash *next, *ray_high, *ray_low;
} Azimuth_hash;
} Sweep_header;
typedef struct {
- Sweep_header h;
+ Sweep_header h;
Ray **ray; /* ray[0..nrays-1]. */
} Sweep;
} Volume_header;
typedef struct {
- Volume_header h; /* Specific info for each elev. */
- /* Includes resolution: km/bin. */
- Sweep **sweep; /* sweep[0..nsweeps-1]. */
+ Volume_header h; /* Specific info for each elev. */
+ /* Includes resolution: km/bin. */
+ Sweep **sweep; /* sweep[0..nsweeps-1]. */
} Volume;
typedef struct
{
- float lat, lon;
- float dx, dy, dz;
- int nx, ny, nz;
- char *data_type;
- Carpi **carpi; /* Pointers to carpi[0] thru carpi[nz-1] */
+ float lat, lon;
+ float dx, dy, dz;
+ int nx, ny, nz;
+ char *data_type;
+ Carpi **carpi; /* Pointers to carpi[0] thru carpi[nz-1] */
} Cube;
typedef struct
{
- float dx, dy;
- int nx, ny;
- char *data_type;
+ float dx, dy;
+ int nx, ny;
+ char *data_type;
float (*f)(Slice_value x); /* Data conversion function. f(x). */
Slice_value (*invf)(float x); /* Data conversion function. invf(x). */
- Slice_value **data; /* data[ny][nx]. */
+ Slice_value **data; /* data[ny][nx]. */
} Slice;
typedef struct {
int hour, minute;
float sec; /* Second plus fractional part. */
char radar_type[50]; /* Type of radar. Use for QC-ing the data.
- * Supported types are:
+ * Supported types are:
* "wsr88d", "lassen", "uf",
* "nsig", "mcgill",
- * "kwajalein", "rsl", "toga",
+ * "kwajalein", "rsl", "toga",
* "rapic", (rapic is Berrimah Austrailia)
- * "radtec", (SPANDAR radar at Wallops Is, VA)
- * "EDGE",
- * "dorade",
- * "south_africa".
+ * "radtec", (SPANDAR radar at Wallops Is, VA)
+ * "dorade",
+ * "south_africa".
* Set by appropriate ingest routine.
*/
int nvolumes;
*28 = VT_INDEX = Radial Velocity Combined (DORADE)
*29 = NP_INDEX = Normalized Coherent Power (DORADE)
*30 = HC_INDEX = HydroClass (Sigmet)
- *31 = VC_INDEX = Radial Velocity Corrected (Sigmet)
- *32 = V2_INDEX = Radial Velocity for VCP 121 second Doppler cut.
- *33 = S2_INDEX = Spectrum Width for VCP 121 second Doppler cut.
- *34 = V3_INDEX = Radial Velocity for VCP 121 third Doppler cut.
- *35 = S3_INDEX = Spectrum Width for VCP 121 third Doppler cut.
+ *31 = VC_INDEX = Radial Velocity Corrected (Sigmet)
+ *32 = V2_INDEX = Radial Velocity for VCP 121 second Doppler cut.
+ *33 = S2_INDEX = Spectrum Width for VCP 121 second Doppler cut.
+ *34 = V3_INDEX = Radial Velocity for VCP 121 third Doppler cut.
+ *35 = S3_INDEX = Spectrum Width for VCP 121 third Doppler cut.
*/
} Radar;
Radar *RSL_africa_to_radar(char *infile);
Radar *RSL_anyformat_to_radar(char *infile, ...);
Radar *RSL_dorade_to_radar(char *infile);
-Radar *RSL_EDGE_to_radar(char *infile);
Radar *RSL_fix_radar_header(Radar *radar);
Radar *RSL_get_window_from_radar(Radar *r, float min_range, float max_range,float low_azim, float hi_azim);
Radar *RSL_hdf_to_radar(char *infile);
int RSL_write_volume(Volume *v, FILE *fp);
unsigned char *RSL_rhi_sweep_to_cart(Sweep *s, int xdim, int ydim, float range,
- int vert_scale);
+ int vert_scale);
unsigned char *RSL_sweep_to_cart(Sweep *s, int xdim, int ydim, float range);
void RSL_add_dbz_offset_to_ray(Ray *r, float dbz_offset);
void RSL_load_green_table(char *infile);
void RSL_load_blue_table(char *infile);
void RSL_print_histogram(Histogram *histogram, int min_range, int max_range,
- char *filename);
+ char *filename);
void RSL_print_version();
-void RSL_prune_radar_on();
-void RSL_prune_radar_off();
void RSL_radar_to_uf(Radar *r, char *outfile);
void RSL_radar_to_uf_gzip(Radar *r, char *outfile);
void RSL_radar_verbose_off(void);
void RSL_rebin_zdr_sweep(Sweep *s);
void RSL_rebin_zdr_volume(Volume *v);
void RSL_rhi_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, float range,
- int vert_scale);
+ int vert_scale);
void RSL_select_fields(char *field_type, ...);
void RSL_set_color_table(int icolor, char buffer[256], int ncolors);
void RSL_sweep_to_gif(Sweep *s, char *outfile, int xdim, int ydim, float range);
void RSL_volume_to_pict(Volume *v, char *basename, int xdim, int ydim, float range);
void RSL_volume_to_ppm(Volume *v, char *basename, int xdim, int ydim, float range);
void RSL_write_gif(char *outfile, unsigned char *image,
- int xdim, int ydim, char c_table[256][3]);
+ int xdim, int ydim, char c_table[256][3]);
void RSL_write_pgm(char *outfile, unsigned char *image,
int xdim, int ydim);
void RSL_write_pict(char *outfile, unsigned char *image,
void RSL_write_ppm(char *outfile, unsigned char *image,
int xdim, int ydim, char c_table[256][3]);
-
Cappi *RSL_new_cappi(Sweep *sweep, float height);
Cappi *RSL_cappi_at_h(Volume *v, float height, float max_range);
Carpi *RSL_cappi_to_carpi(Cappi *cappi, float dx, float dy,
- float lat, float lon,
- int nx, int ny, int radar_x, int radar_y);
+ float lat, float lon,
+ int nx, int ny, int radar_x, int radar_y);
Carpi *RSL_new_carpi(int nrows, int ncols);
Carpi *RSL_volume_to_carpi(Volume *v, float h, float grnd_r,
- float dx, float dy, int nx, int ny,
- int radar_x, int radar_y, float lat, float lon);
+ float dx, float dy, int nx, int ny,
+ int radar_x, int radar_y, float lat, float lon);
Cube *RSL_new_cube(int ncarpi);
Cube *RSL_volume_to_cube(Volume *v, float dx, float dy, float dz,
- int nx, int ny, int nz, float grnd_r,
- int radar_x, int radar_y, int radar_z);
+ int nx, int ny, int nz, float grnd_r,
+ int radar_x, int radar_y, int radar_z);
Slice *RSL_new_slice(int nrows, int ncols);
Slice *RSL_get_slice_from_cube(Cube *cube, int x, int y, int z);
Histogram *RSL_allocate_histogram(int low, int hi);
Histogram *RSL_get_histogram_from_ray(Ray *ray, Histogram *histogram,
- int low, int hi, int min_range,
- int max_range);
+ int low, int hi, int min_range,
+ int max_range);
Histogram *RSL_get_histogram_from_sweep(Sweep *sweep, Histogram *histogram,
- int low, int hi, int min_range,
- int max_range);
+ int low, int hi, int min_range,
+ int max_range);
Histogram *RSL_get_histogram_from_volume(Volume *volume, Histogram *histogram,
- int low, int hi, int min_range,
- int max_range);
+ int low, int hi, int min_range,
+ int max_range);
Histogram *RSL_read_histogram(char *infile);
int no_command (char *cmd);
int rsl_pclose(FILE *fp);
/* Carpi image generation functions. These are modified clones of the
- corresponding sweep image generation functions.
+ corresponding sweep image generation functions.
*/
unsigned char *RSL_carpi_to_cart(Carpi *carpi, int xdim, int ydim,
- float range);
+ float range);
void RSL_carpi_to_gif(Carpi *carpi, char *outfile, int xdim, int ydim,
- float range);
+ float range);
void RSL_carpi_to_pict(Carpi *carpi, char *outfile, int xdim, int ydim,
- float range);
+ float range);
void RSL_carpi_to_ppm(Carpi *carpi, char *outfile, int xdim, int ydim,
- float range);
+ float range);
void RSL_carpi_to_pgm(Carpi *carpi, char *outfile, int xdim, int ydim,
- float range);
+ float range);
/* Internal storage conversion functions. These may be any conversion and
* may be dynamically defined; based on the input data conversion.
************************************************/
float Cvt_time(long int time_in)
{
- double t;
- int hh,mm;
+ double t;
+ int hh,mm;
- t = time_in;
+ t = time_in;
t /= 1000.0;
hh = t/3600;
t -= hh*3600;
mm = t/60;
t -= mm*60;
-
- return hh*10000 + mm*100 + (float) t;
+
+ return hh*10000 + mm*100 + (float) t;
}
/**********************************************************************/
/* */
void print_packet_info(Wsr88d_packet *p)
{
fprintf(stderr,"%5hd %5hd %5hd %5hd %5hd %5hd %5hd %10.3f %6d\n",
- p->msg_type, p->id_seq, p->azm, p->ray_num, p->ray_status, p->elev, p->elev_num,
- Cvt_time((int)p->ray_time), Cvt_date((int)p->ray_date));
+ p->msg_type, p->id_seq, p->azm, p->ray_num, p->ray_status, p->elev, p->elev_num,
+ Cvt_time((int)p->ray_time), Cvt_date((int)p->ray_date));
}
*/
int i;
for (i=low; i<high; i++)
- if (s->ray[i] != NULL) {
- free(s->ray[i]);
- s->ray[i] = NULL;
- }
+ if (s->ray[i] != NULL) {
+ free(s->ray[i]);
+ s->ray[i] = NULL;
+ }
}
void clear_sweep(Wsr88d_sweep *s, int low, int high)
*/
int i;
for (i=low; i<high; i++)
- s->ray[i] = NULL;
+ s->ray[i] = NULL;
}
void wsr88d_print_sweep_info(Wsr88d_sweep *s)
fprintf(stderr,"----- ----- ----- ----- ----- ----- ----- ---------- ------\n");
for (i=0; i<MAX_RAYS_IN_SWEEP; i++) {
- if (s->ray[i] != NULL)
- print_packet_info((Wsr88d_packet *) s->ray[i]);
+ if (s->ray[i] != NULL)
+ print_packet_info((Wsr88d_packet *) s->ray[i]);
}
}
int save_fd;
if ( strcmp(filename, "stdin") == 0 ) {
- save_fd = dup(0);
- wf->fptr = fdopen(save_fd,"r");
+ save_fd = dup(0);
+ wf->fptr = fdopen(save_fd,"r");
} else {
- wf->fptr = fopen(filename, "r");
+ wf->fptr = fopen(filename, "r");
}
if (wf->fptr == NULL) return NULL;
/* */
/**********************************************************************/
int wsr88d_read_file_header(Wsr88d_file *wf,
- Wsr88d_file_header *wsr88d_file_header)
+ Wsr88d_file_header *wsr88d_file_header)
{
int n;
n = fread(&wsr88d_file_header->title,
- sizeof(wsr88d_file_header->title), 1, wf->fptr);
+ sizeof(wsr88d_file_header->title), 1, wf->fptr);
if (little_endian())
- wsr88d_swap_file_header(wsr88d_file_header);
+ wsr88d_swap_file_header(wsr88d_file_header);
return n;
}
/* */
/**********************************************************************/
int wsr88d_read_tape_header(char *first_file,
- Wsr88d_tape_header *wsr88d_tape_header)
+ Wsr88d_tape_header *wsr88d_tape_header)
{
FILE *fp;
int n;
char c;
if ((fp = fopen(first_file, "r")) == NULL) {
- perror(first_file);
- return 0;
+ perror(first_file);
+ return 0;
}
n = fread(wsr88d_tape_header, sizeof(Wsr88d_tape_header), 1, fp);
if (n == 0) {
- fprintf(stderr, "WARNING: %s is smaller than 31616 bytes. It is not a tape header file.\n", first_file);
- } else {
- /* Try to read one more character. If we can, then this is not a
- * tape header file. I suppose that we could look for '.' as the
- * 9-th character and if it were there, then too this is not a tape
- * header file.
- */
- if (fread(&c, sizeof(char), 1, fp) > 0) {
- fprintf(stderr, "WARNING: %s is larger than 31616 bytes. It is not a tape header file.\n", first_file);
- memset(wsr88d_tape_header, 0, sizeof(Wsr88d_tape_header));
- n = 0;
- } else { /* Ok so far. Now check the first 8 bytes for "ARCHIVE2" */
- if (strncmp(wsr88d_tape_header->archive2, "ARCHIVE2", 8) != 0) {
- fprintf(stderr, "WARNING: %s is 31616 bytes. However, the first 8 bytes are not 'ARCHIVE2'.\n", first_file);
- memset(wsr88d_tape_header, 0, sizeof(Wsr88d_tape_header));
- n = 0;
- }
- }
-
+ fprintf(stderr, "WARNING: %s is smaller than 31616 bytes. It is not a tape header file.\n", first_file);
+ } else {
+ /* Try to read one more character. If we can, then this is not a
+ * tape header file. I suppose that we could look for '.' as the
+ * 9-th character and if it were there, then too this is not a tape
+ * header file.
+ */
+ if (fread(&c, sizeof(char), 1, fp) > 0) {
+ fprintf(stderr, "WARNING: %s is larger than 31616 bytes. It is not a tape header file.\n", first_file);
+ memset(wsr88d_tape_header, 0, sizeof(Wsr88d_tape_header));
+ n = 0;
+ } else { /* Ok so far. Now check the first 8 bytes for "ARCHIVE2" */
+ if (strncmp(wsr88d_tape_header->archive2, "ARCHIVE2", 8) != 0) {
+ fprintf(stderr, "WARNING: %s is 31616 bytes. However, the first 8 bytes are not 'ARCHIVE2'.\n", first_file);
+ memset(wsr88d_tape_header, 0, sizeof(Wsr88d_tape_header));
+ n = 0;
+ }
+ }
+
}
fclose(fp);
return n;
/* Step 1. */
while ((wsr88d_ray.msg_type & 15) != 1 && n > 0) {
- /*
- fprintf(stderr,"SKIPPING packet: type %d, radial status %d\n",
- wsr88d_ray.msg_type, wsr88d_ray.ray_status);
- */
- n = wsr88d_read_ray(wf, &wsr88d_ray);
+ /*
+ fprintf(stderr,"SKIPPING packet: type %d, radial status %d\n",
+ wsr88d_ray.msg_type, wsr88d_ray.ray_status);
+ */
+ n = wsr88d_read_ray(wf, &wsr88d_ray);
}
if (n <= 0) return n; /* Read failure. */
end_of_volume = 0;
/* Step 2. */
while ( ! end_of_volume ) {
- if ((wsr88d_ray.msg_type & 15) != 1) {
- /*
- fprintf(stderr,"SKIPPING (amid a sweep) packet: type %d, "
- "radial status %d\n",
- wsr88d_ray.msg_type, wsr88d_ray.ray_status);
- */
-
- } else {
- /* Load this ray into the sweep. */
- ray_num = wsr88d_ray.ray_num;
- /* Double check against # records we've seen. */
- /* It is possible that a reset occurs and we begin to overwrite
- * previously loaded rays. I've seen this occur, rarely, in the
- * WSR88D data. I must trust 'ray_num'.
- */
- /*
- if (nrec+1 != ray_num) {
- fprintf(stderr, "Data says %d is ray_num, but, I've seen %d "
- "records.\n", ray_num, nrec+1);
- }
- */
- if (wsr88d_sweep->ray[ray_num] == NULL) {
- wsr88d_sweep->ray[ray_num] = (Wsr88d_ray *) malloc (sizeof(Wsr88d_ray));
- }
- memcpy(wsr88d_sweep->ray[ray_num], &wsr88d_ray, sizeof(Wsr88d_ray));
- }
- n = wsr88d_read_ray(wf, &wsr88d_ray);
- if (n > 0) nrec++;
+ if ((wsr88d_ray.msg_type & 15) != 1) {
+ /*
+ fprintf(stderr,"SKIPPING (amid a sweep) packet: type %d, "
+ "radial status %d\n",
+ wsr88d_ray.msg_type, wsr88d_ray.ray_status);
+ */
+
+ } else {
+ /* Load this ray into the sweep. */
+ ray_num = wsr88d_ray.ray_num;
+ /* Double check against # records we've seen. */
+ /* It is possible that a reset occurs and we begin to overwrite
+ * previously loaded rays. I've seen this occur, rarely, in the
+ * WSR88D data. I must trust 'ray_num'.
+ */
+ /*
+ if (nrec+1 != ray_num) {
+ fprintf(stderr, "Data says %d is ray_num, but, I've seen %d "
+ "records.\n", ray_num, nrec+1);
+ }
+ */
+ if (wsr88d_sweep->ray[ray_num] == NULL) {
+ wsr88d_sweep->ray[ray_num] = (Wsr88d_ray *) malloc (sizeof(Wsr88d_ray));
+ }
+ memcpy(wsr88d_sweep->ray[ray_num], &wsr88d_ray, sizeof(Wsr88d_ray));
+ }
+ n = wsr88d_read_ray(wf, &wsr88d_ray);
+ if (n > 0) nrec++;
end_of_volume = wsr88d_ray.ray_status == 2 ||
- wsr88d_ray.ray_status == 4 ||
- n <= 0;
+ wsr88d_ray.ray_status == 4 ||
+ n <= 0;
}
/* Process the last packet of the input data. */
- if (wsr88d_ray.ray_status == 2 || wsr88d_ray.ray_status == 4) {
- /* Load this ray into the sweep. */
- ray_num = wsr88d_ray.ray_num;
- if (wsr88d_sweep->ray[ray_num] == NULL) {
- wsr88d_sweep->ray[ray_num] = (Wsr88d_ray *) malloc (sizeof(Wsr88d_ray));
- }
- memcpy(wsr88d_sweep->ray[ray_num], &wsr88d_ray, sizeof(Wsr88d_ray));
+ if ((wsr88d_ray.ray_status == 2 || wsr88d_ray.ray_status == 4) &&
+ (wsr88d_ray.msg_type & 15) == 1) {
+ /* Load this ray into the sweep. */
+ ray_num = wsr88d_ray.ray_num;
+ if (wsr88d_sweep->ray[ray_num] == NULL) {
+ wsr88d_sweep->ray[ray_num] = (Wsr88d_ray *) malloc (sizeof(Wsr88d_ray));
+ }
+ memcpy(wsr88d_sweep->ray[ray_num], &wsr88d_ray, sizeof(Wsr88d_ray));
}
/* Just to be safe, clear all ray pointers left in this sweep to
/*
fprintf(stderr,"Processed %d records for elevation number %d\n",
- nrec+1, wsr88d_ray.elev_num);
+ nrec+1, wsr88d_ray.elev_num);
wsr88d_print_sweep_info(wsr88d_sweep);
*/
return nrec;
short *half_word;
half_word = (short *)wsr88d_ray;
for (; half_word<(short *)&wsr88d_ray->msg_time; half_word++)
- swap_2_bytes(half_word);
+ swap_2_bytes(half_word);
swap_4_bytes(&wsr88d_ray->msg_time);
swap_2_bytes(&wsr88d_ray->num_seg);
half_word = (short *) &wsr88d_ray->ray_date;
for (; half_word<(short *)&wsr88d_ray->sys_cal; half_word++)
- swap_2_bytes(half_word);
+ swap_2_bytes(half_word);
swap_4_bytes(&wsr88d_ray->sys_cal);
half_word = (short *) &wsr88d_ray->refl_ptr;
for (; half_word<(short *)&wsr88d_ray->data[0]; half_word++)
- swap_2_bytes(half_word);
+ swap_2_bytes(half_word);
}
n = fread(wsr88d_ray, sizeof(Wsr88d_ray), 1, wf->fptr);
/* if (n > 0) print_packet_info(wsr88d_ray); */
if (little_endian())
- wsr88d_swap_ray(wsr88d_ray);
+ wsr88d_swap_ray(wsr88d_ray);
return n;
}
/* */
/**********************************************************************/
int wsr88d_read_ray_header(Wsr88d_file *wf,
- Wsr88d_ray_header *wsr88d_ray_header)
+ Wsr88d_ray_header *wsr88d_ray_header)
{
fprintf(stderr,"Stub routine: wsr88d_read_ray_header.\n");
return 0;
/* */
/**********************************************************************/
int wsr88d_ray_to_float(Wsr88d_ray *ray,
- int THE_DATA_WANTED, float v[], int *n)
+ int THE_DATA_WANTED, float v[], int *n)
{
/*
* Input: *ray - WSR-88D packet
/* Code from Dan Austin (cvt_pckt_data.c) was the template for this. */
- /* declarations */
+ /* declarations */
int num_ref_gates,num_vel_gates,num_spec_gates;
int refl_ptr, vel_ptr,spec_ptr,res_flag;
int ival;
*/
if (THE_DATA_WANTED == WSR88D_DZ) {
- /* do the reflectivity data (dbZ)*/
- if (refl_ptr+num_ref_gates > 2300)
- fprintf(stderr, "WARNING: # refl index (%d) exceeds maximum (2300)\n",
- refl_ptr+num_ref_gates);
- else {
- for(i=0; i<num_ref_gates; i++) {
- ival = ray->data[refl_ptr+i];
- if(ival > 1)
- v[i] = (((ival-2.0)/2.0)-32.0);
- else if (ival == 1)
- v[i] = WSR88D_RFVAL;
- else /* ival = 0 */
- v[i] = WSR88D_BADVAL;
- }
- *n = num_ref_gates;
- }
+ /* do the reflectivity data (dbZ)*/
+ if (refl_ptr+num_ref_gates > 2300)
+ fprintf(stderr, "WARNING: # refl index (%d) exceeds maximum (2300)\n",
+ refl_ptr+num_ref_gates);
+ else {
+ for(i=0; i<num_ref_gates; i++) {
+ ival = ray->data[refl_ptr+i];
+ if(ival > 1)
+ v[i] = (((ival-2.0)/2.0)-32.0);
+ else if (ival == 1)
+ v[i] = WSR88D_RFVAL;
+ else /* ival = 0 */
+ v[i] = WSR88D_BADVAL;
+ }
+ *n = num_ref_gates;
+ }
} else if (THE_DATA_WANTED == WSR88D_VR) {
- /* do the velocity data (M/S) */
- if (vel_ptr+num_vel_gates > 2300)
- fprintf(stderr, "WARNING: # vel index (%d) exceeds maximum (2300)\n",
- vel_ptr+num_vel_gates);
- else {
- for(i=0; i<num_vel_gates;i++) {
- ival = ray->data[vel_ptr+i];
- if(ival > 1)
- if (res_flag == 2) /* High resolution: 0.5 m/s */
- v[i] = (((ival-2.0)/2.0)-63.5);
- else
- v[i] = ((ival-2.0)-127.0);
- else if (ival == 1)
- v[i] = WSR88D_RFVAL;
- else /* ival = 0 */
- v[i] = WSR88D_BADVAL;
- }
- *n = num_vel_gates;
- }
-
+ /* do the velocity data (M/S) */
+ if (vel_ptr+num_vel_gates > 2300)
+ fprintf(stderr, "WARNING: # vel index (%d) exceeds maximum (2300)\n",
+ vel_ptr+num_vel_gates);
+ else {
+ for(i=0; i<num_vel_gates;i++) {
+ ival = ray->data[vel_ptr+i];
+ if(ival > 1)
+ if (res_flag == 2) /* High resolution: 0.5 m/s */
+ v[i] = (((ival-2.0)/2.0)-63.5);
+ else
+ v[i] = ((ival-2.0)-127.0);
+ else if (ival == 1)
+ v[i] = WSR88D_RFVAL;
+ else /* ival = 0 */
+ v[i] = WSR88D_BADVAL;
+ }
+ *n = num_vel_gates;
+ }
+
} else if (THE_DATA_WANTED == WSR88D_SW) {
- /* now do the spectrum width data (M/S)*/
- if (spec_ptr+num_spec_gates > 2300)
- fprintf(stderr, "WARNING: # spec index (%d) exceeds maximum (2300)\n",
- spec_ptr+num_spec_gates);
- else {
- for(i=0;i<num_spec_gates;i++) {
- ival = ray->data[spec_ptr+i];
- if(ival > 1)
- v[i] = (((ival-2)/2.0)-63.5);
- else if (ival == 1)
- v[i] = WSR88D_RFVAL;
- else /* ival = 0 */
- v[i] = WSR88D_BADVAL;
- }
- *n = num_spec_gates;
- }
+ /* now do the spectrum width data (M/S)*/
+ if (spec_ptr+num_spec_gates > 2300)
+ fprintf(stderr, "WARNING: # spec index (%d) exceeds maximum (2300)\n",
+ spec_ptr+num_spec_gates);
+ else {
+ for(i=0;i<num_spec_gates;i++) {
+ ival = ray->data[spec_ptr+i];
+ if(ival > 1)
+ v[i] = (((ival-2)/2.0)-63.5);
+ else if (ival == 1)
+ v[i] = WSR88D_RFVAL;
+ else /* ival = 0 */
+ v[i] = WSR88D_BADVAL;
+ }
+ *n = num_spec_gates;
+ }
}
return *n;
/*
* This routine from Dan Austin. Program component of nex2uf.
*/
- static int vcp_info[4];
- int fix_angle;
- int pulse_cnt;
- int az_rate;
- int pulse_width;
-
- /* case statement to get vcp info */
- switch(vcp_num) {
- case 11:
- fix_angle = vcp11[(3*el_num)-1];
- pulse_cnt = vcp11[(3*el_num)];
- az_rate = vcp11[(3*el_num)+1];
- pulse_width = vcp11[1];
- break;
- case 12:
- fix_angle = vcp12[(3*el_num)-1];
- pulse_cnt = vcp12[(3*el_num)];
- az_rate = vcp12[(3*el_num)+1];
- pulse_width = vcp12[1];
- break;
- case 21:
- fix_angle = vcp21[(3*el_num)-1];
- pulse_cnt = vcp21[(3*el_num)];
- az_rate = vcp21[(3*el_num)+1];
- pulse_width = vcp21[1];
- break;
- case 31:
- fix_angle = vcp31[(3*el_num)-1];
- pulse_cnt = vcp31[(3*el_num)];
- az_rate = vcp31[(3*el_num)+1];
- pulse_width = vcp31[1];
- break;
- case 32:
- fix_angle = vcp32[(3*el_num)-1];
- pulse_cnt = vcp32[(3*el_num)];
- az_rate = vcp32[(3*el_num)+1];
- pulse_width = vcp32[1];
- break;
- case 300:
- fix_angle = vcp300[(3*el_num)-1];
- pulse_cnt = vcp300[(3*el_num)];
- az_rate = vcp300[(3*el_num)+1];
- pulse_width = vcp300[1];
- break;
- case 121:
- fix_angle = vcp121[(3*el_num)-1];
- pulse_cnt = vcp121[(3*el_num)];
- az_rate = vcp121[(3*el_num)+1];
- pulse_width = vcp121[1];
- break;
- case 211:
- fix_angle = vcp11[(3*el_num)-1];
- pulse_cnt = vcp11[(3*el_num)];
- az_rate = vcp11[(3*el_num)+1];
- pulse_width = vcp11[1];
- break;
- case 212:
- fix_angle = vcp12[(3*el_num)-1];
- pulse_cnt = vcp12[(3*el_num)];
- az_rate = vcp12[(3*el_num)+1];
- pulse_width = vcp12[1];
- break;
- case 221:
- fix_angle = vcp21[(3*el_num)-1];
- pulse_cnt = vcp21[(3*el_num)];
- az_rate = vcp21[(3*el_num)+1];
- pulse_width = vcp21[1];
- break;
- default:
- fix_angle = 0;
- pulse_cnt = 0;
- az_rate = 0;
- pulse_width= 0;
- break;
- }
-
- /* get array for output */
- vcp_info[0]=fix_angle;
- vcp_info[1]=pulse_cnt;
- vcp_info[2]=az_rate;
- vcp_info[3]=pulse_width;
-
-
- /* return the value array */
- return(vcp_info);
+ static int vcp_info[4];
+ int fix_angle;
+ int pulse_cnt;
+ int az_rate;
+ int pulse_width;
+
+ /* case statement to get vcp info */
+ switch(vcp_num) {
+ case 11:
+ fix_angle = vcp11[(3*el_num)-1];
+ pulse_cnt = vcp11[(3*el_num)];
+ az_rate = vcp11[(3*el_num)+1];
+ pulse_width = vcp11[1];
+ break;
+ case 12:
+ fix_angle = vcp12[(3*el_num)-1];
+ pulse_cnt = vcp12[(3*el_num)];
+ az_rate = vcp12[(3*el_num)+1];
+ pulse_width = vcp12[1];
+ break;
+ case 21:
+ fix_angle = vcp21[(3*el_num)-1];
+ pulse_cnt = vcp21[(3*el_num)];
+ az_rate = vcp21[(3*el_num)+1];
+ pulse_width = vcp21[1];
+ break;
+ case 31:
+ fix_angle = vcp31[(3*el_num)-1];
+ pulse_cnt = vcp31[(3*el_num)];
+ az_rate = vcp31[(3*el_num)+1];
+ pulse_width = vcp31[1];
+ break;
+ case 32:
+ fix_angle = vcp32[(3*el_num)-1];
+ pulse_cnt = vcp32[(3*el_num)];
+ az_rate = vcp32[(3*el_num)+1];
+ pulse_width = vcp32[1];
+ break;
+ case 300:
+ fix_angle = vcp300[(3*el_num)-1];
+ pulse_cnt = vcp300[(3*el_num)];
+ az_rate = vcp300[(3*el_num)+1];
+ pulse_width = vcp300[1];
+ break;
+ case 121:
+ fix_angle = vcp121[(3*el_num)-1];
+ pulse_cnt = vcp121[(3*el_num)];
+ az_rate = vcp121[(3*el_num)+1];
+ pulse_width = vcp121[1];
+ break;
+ case 211:
+ fix_angle = vcp11[(3*el_num)-1];
+ pulse_cnt = vcp11[(3*el_num)];
+ az_rate = vcp11[(3*el_num)+1];
+ pulse_width = vcp11[1];
+ break;
+ case 212:
+ fix_angle = vcp12[(3*el_num)-1];
+ pulse_cnt = vcp12[(3*el_num)];
+ az_rate = vcp12[(3*el_num)+1];
+ pulse_width = vcp12[1];
+ break;
+ case 221:
+ fix_angle = vcp21[(3*el_num)-1];
+ pulse_cnt = vcp21[(3*el_num)];
+ az_rate = vcp21[(3*el_num)+1];
+ pulse_width = vcp21[1];
+ break;
+ default:
+ fix_angle = 0;
+ pulse_cnt = 0;
+ az_rate = 0;
+ pulse_width= 0;
+ break;
+ }
+
+ /* get array for output */
+ vcp_info[0]=fix_angle;
+ vcp_info[1]=pulse_cnt;
+ vcp_info[2]=az_rate;
+ vcp_info[3]=pulse_width;
+
+
+ /* return the value array */
+ return(vcp_info);
}
prf = wsr88d_get_prf(ray);
nyquist = wsr88d_get_nyquist(ray);
- /* If required info to determine wavelength does not exist,
- just use 10 cm. All wsr88d radars are 10cm. MJK */
+ /* If required info to determine wavelength does not exist,
+ just use 10 cm. All wsr88d radars are 10cm. MJK */
if ((prf == 0) || (nyquist == 0.0)) wavelength = 0.10;
else wavelength = 4*nyquist/prf;
return wavelength;
float freq;
float c = 299792458.0;
- /* Carrier freq (GHz). Revised 12 Jun 97. MJK */
- freq = (c / wsr88d_get_wavelength(ray)) * 1.0e-9;
+ /* Carrier freq (GHz). Revised 12 Jun 97. MJK */
+ freq = (c / wsr88d_get_wavelength(ray)) * 1.0e-9;
return freq;
}
* The directory should be the same as the LIBDIR in the makefile.
*/
#ifndef WSR88D_SITE_INFO_FILE
-#define WSR88D_SITE_INFO_FILE "/usr/local/trmm/GVBOX/lib/wsr88d_locations.dat"
+#define WSR88D_SITE_INFO_FILE "/usr/local/trmm/lib/wsr88d_locations.dat"
#endif
/*===============================================================*/
typedef struct {
float wsr88d_get_prt(Wsr88d_ray *ray);
float wsr88d_get_wavelength(Wsr88d_ray *ray);
float wsr88d_get_frequency(Wsr88d_ray *ray);
+void wsr88d_keep_hi_prf_dz();
+void wsr88d_no_hi_prf_dz();
int no_command (char *cmd);
FILE *uncompress_pipe (FILE *fp);
SSAI
Lanham, Maryland
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
+ 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 program is distributed in the hope that it will be useful,
+ 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 General Public License for more details.
+ 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 General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
+ 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., 51 Franklin St, Fifth Floor,
+ Boston, MA 02110-1301, USA.
*/
} Wsr88d_ray_m31;
-enum radial_status {START_OF_ELEV, INTERMED_RADIAL, END_OF_ELEV, BEGIN_VOS,
- END_VOS};
-
void wsr88d_swap_m31_hdr(Wsr88d_msg_hdr *msghdr)
{
return -1;
}
-
#define MAXRAYS_M31 800
#define MAXSWEEPS 20
int vol_index, waveform;
char *type_str;
- int keep_hi_prf_dz = 0; /* TODO: make this an argument. */
+ int keep_hi_prf_dz = 0; /* TODO: implement an interface for this. */
enum waveforms {surveillance=1, doppler_w_amb_res, doppler_no_amb_res,
batch};
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
+ * keep_hi_prf_dz is set. The indicators for this type of
+ * reflectivity are surveillance mode of 0 and elevation angle
* below 6 degrees.
*/
if (vol_index == DZ_INDEX && (vcp_data.surveil_prf_num[isweep] == 0 &&
short non31_seg_remainder[1202]; /* Remainder after message header */
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;
+ int prev_elev_num = 1, prev_raynum = 0, raynum = 0;
Radar *radar = NULL;
+ enum radial_status {START_OF_ELEV, INTERMED_RADIAL, END_OF_ELEV, BEGIN_VOS,
+ END_VOS};
+
- /* 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.
+ /* Message type 31 is a variable length message. All other types consist of
+ * 1 or more segments of length 2432 bytes. To handle all types, we read
+ * the message header and check the type. If not 31, then simply read
+ * the remainder of the 2432-byte segment. If it is 31, use the size given
+ * in message header to determine how many bytes to read.
*/
n = fread(&msghdr, sizeof(Wsr88d_msg_hdr), 1, wf->fptr);
if (little_endian()) wsr88d_swap_m31_hdr(&msghdr);
/* Get size of the remainder of message. The given size is in
- * halfwords, but we want it in bytes, so double it.
+ * halfwords; convert it to bytes.
*/
msg_size = (int) msghdr.msg_size * 2 - msg_hdr_size;
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) {
}
/* 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.
+ * warning if this has occurred. This condition usually means
+ * less rays then expected in the sweep that just ended.
*/
if (wsr88d_ray.ray_hdr.radial_status == START_OF_ELEV &&
- sweep_hdrs_written != prev_elev_num) {
+ wsr88d_ray.ray_hdr.elev_num-1 > isweep) {
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", prev_elev_num, prev_raynum);
wsr88d_load_sweep_header(radar, isweep);
isweep++;
- 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, radar);
prev_raynum = raynum;
+
+ /* Check for end of sweep */
+ if (wsr88d_ray.ray_hdr.radial_status == END_OF_ELEV) {
+ wsr88d_load_sweep_header(radar, isweep);
+ isweep++;
+ prev_elev_num = wsr88d_ray.ray_hdr.elev_num;
+ }
}
else { /* msg_type not 31 */
n = fread(&non31_seg_remainder, sizeof(non31_seg_remainder), 1,
}
}
- /* Check for end of sweep */
- if (wsr88d_ray.ray_hdr.radial_status == END_OF_ELEV) {
- wsr88d_load_sweep_header(radar, isweep);
- isweep++;
- sweep_hdrs_written++;
- prev_elev_num = wsr88d_ray.ray_hdr.elev_num;
- }
-
/* If not at end of volume scan, read next message header. */
if (wsr88d_ray.ray_hdr.radial_status != END_VOS) {
n = fread(&msghdr, sizeof(Wsr88d_msg_hdr), 1, wf->fptr);
if (n < 1) {
fprintf(stderr,"Warning: load_wsr88d_m31_into_radar: ");
- if (feof(wf->fptr) != 0) fprintf(stderr,
- "Unexpected end of file.\n");
+ if (feof(wf->fptr) != 0)
+ fprintf(stderr,"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, prev_raynum);
wsr88d_load_sweep_header(radar, isweep);
- return radar;
+ end_of_vos = 1;
}
}
else {
end_of_vos = 1;
wsr88d_load_sweep_header(radar, isweep);
}
- if (feof(wf->fptr) != 0) end_of_vos = 1;
} /* while not end of vos */
return radar;
perror("wsr88d_load_sweep_into_volume: RSL_new_sweep");
return -1;
}
-
+
+ v->sweep[nsweep]->h.elev = 0;
v->sweep[nsweep]->h.nrays = 0;
f = (float (*)(Range x))NULL;
invf = (Range (*)(float x))NULL;
if (v->sweep[nsweep]->h.nrays > 0)
v->sweep[nsweep]->h.elev /= v->sweep[nsweep]->h.nrays;
else {
- free(v->sweep[nsweep]); /* No rays loaded, free this sweep. */
+ RSL_free_sweep(v->sweep[nsweep]); /* No rays loaded, free this sweep. */
v->sweep[nsweep] = NULL;
}
*/
if (n > 0) {
strncpy(version, wsr88d_file_header.title.filename, 8);
- if (strncmp(version,"AR2V0006",8) == 0 ||
+ if (strncmp(version,"AR2V0007",8) == 0 ||
+ strncmp(version,"AR2V0006",8) == 0 ||
strncmp(version,"AR2V0004",8) == 0 ||
strncmp(version,"AR2V0003",8) == 0 ||
strncmp(version,"AR2V0002",8) == 0) {