3 This is the TRMM Office Radar Software Library.
4 Copyright (C) 1996, 1997
6 Space Applications Corporation
9 This library is free software; you can redistribute it and/or
10 modify it under the terms of the GNU Library General Public
11 License as published by the Free Software Foundation; either
12 version 2 of the License, or (at your option) any later version.
14 This library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Library General Public License for more details.
19 You should have received a copy of the GNU Library General Public
20 License along with this library; if not, write to the Free
21 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *------------------------------------------------------------
26 *------------------------------------------------------------
30 * wsr88d_read_file_header
31 * wsr88d_read_tape_header
39 * wsr88d_get_atmos_atten_factor
40 * wsr88d_get_velocity_resolution
41 * wsr88d_get_volume_coverage
42 * wsr88d_get_elevation_angle
47 * wsr88d_get_vcp_info(int vcp_num,int el_num)
48 * wsr88d_get_fix_angle(Wsr88d_ray *ray)
49 * wsr88d_get_pulse_count(Wsr88d_ray *ray)
50 * wsr88d_get_azimuth_rate(Wsr88d_ray *ray)
51 * wsr88d_get_pulse_width(Wsr88d_ray *ray)
52 * wsr88d_get_prt(Wsr88d_ray *ray)
53 * wsr88d_get_prf(Wsr88d_ray *ray)
54 * wsr88d_get_wavelength(Wsr88d_ray *ray)
55 * wsr88d_get_frequency(Wsr88d_ray *ray)
57 * Misc. routines: (canidates for possible inclusion into the library)
60 * free_and_clear_sweep
63 * Cvt_date <- From Dan Austin
64 * Cvt_time <- From Dan Austin
74 static int little_endian(void)
77 unsigned char byte[4];
86 static void swap_4_bytes(void *word)
99 static void swap_2_bytes(void *word)
109 /**********************************************************************/
110 /* D E B U G G I N G R O U T I N E S F O L L O W */
111 /**********************************************************************/
112 /************************************************
113 * Cvt_date- convert the date in days since 1/1/70 (Julian) to mm/dd/yy
115 * long int date_in - input julian date
116 * returns: output date
117 * calls from: Cvt_pckt_hdr
119 ************************************************/
122 int Cvt_date(long int date_in)
128 itime *= 24*60*60; /* Seconds/day * days. */
130 tm_time = gmtime(&itime);
131 mm = tm_time->tm_mon+1;
132 dd = tm_time->tm_mday;
133 yy = tm_time->tm_year;
135 return 10000.0*yy+100.0*mm+dd;
138 /************************************************
139 * Cvt_time- converts 24 hr time in msecs after midnight to hhmmss
141 * long int time_in - input time in msecs after midnight
142 * returns: double *time_out - output time
143 * calls from: Cvt_pckt_hdr
145 ************************************************/
146 float Cvt_time(long int time_in)
158 return hh*10000 + mm*100 + (float) t;
160 /**********************************************************************/
162 /* done 2/28 print_head */
164 /**********************************************************************/
165 void print_head(Wsr88d_file_header h)
168 fprintf(stderr,"Filename : ");
169 for (i=0;i<9;i++) fprintf(stderr,"%c", h.title.filename[i]); printf("\n");
171 fprintf(stderr,"Extension: ");
172 for (i=0;i<3;i++) fprintf(stderr,"%c", h.title.ext[i]); printf("\n");
174 fprintf(stderr,"Julian date: %d\n", Cvt_date(h.title.file_date));
175 fprintf(stderr," time: %f\n", Cvt_time(h.title.file_time));
180 void print_packet_info(Wsr88d_packet *p)
182 fprintf(stderr,"%5hd %5hd %5hd %5hd %5hd %5hd %5hd %10.3f %6d\n",
183 p->msg_type, p->id_seq, p->azm, p->ray_num, p->ray_status, p->elev, p->elev_num,
184 Cvt_time((int)p->ray_time), Cvt_date((int)p->ray_date));
190 /**********************************************************************/
191 /* End of debug routines. */
192 /**********************************************************************/
194 void free_and_clear_sweep(Wsr88d_sweep *s, int low, int high)
196 /* Frees and sets the ray pointers to NULL.
197 * Assumes that rays pointers have been allocated.
200 for (i=low; i<high; i++)
201 if (s->ray[i] != NULL) {
207 void clear_sweep(Wsr88d_sweep *s, int low, int high)
210 * Simply set all sweep pointers to NULL.
213 for (i=low; i<high; i++)
217 void wsr88d_print_sweep_info(Wsr88d_sweep *s)
221 fprintf(stderr,"Mtype ID azim ray# rstat elev elev# time date\n");
222 fprintf(stderr,"----- ----- ----- ----- ----- ----- ----- ---------- ------\n");
224 for (i=0; i<MAX_RAYS_IN_SWEEP; i++) {
225 if (s->ray[i] != NULL)
226 print_packet_info((Wsr88d_packet *) s->ray[i]);
230 /**********************************************************************/
232 /* done 2/28 wsr88d_open */
234 /**********************************************************************/
236 Wsr88d_file *wsr88d_open(char *filename)
238 Wsr88d_file *wf = (Wsr88d_file *)malloc(sizeof(Wsr88d_file));
241 if ( strcmp(filename, "stdin") == 0 ) {
243 wf->fptr = fdopen(save_fd,"r");
245 wf->fptr = fopen(filename, "r");
248 if (wf->fptr == NULL) return NULL;
249 wf->fptr = uncompress_pipe(wf->fptr);
250 #define NEW_BUFSIZ 16384
251 setvbuf(wf->fptr,NULL,_IOFBF,(size_t)NEW_BUFSIZ); /* Faster i/o? */
256 /**********************************************************************/
258 /* done 2/28 wsr88d_perror */
260 /**********************************************************************/
261 int wsr88d_perror(char *message)
264 * I want to use a global 'wsr88d_errno' and
265 * have this routine print an appropriate message.
268 /* This is a simple model now. */
269 fprintf(stderr, "wsr88d_error: ");
274 /**********************************************************************/
276 /* done 2/28 wsr88d_close */
278 /**********************************************************************/
279 int wsr88d_close(Wsr88d_file *wf)
282 rc = rsl_pclose(wf->fptr);
288 /**********************************************************************/
290 /* wsr88d_swap_file_header */
292 /**********************************************************************/
293 void wsr88d_swap_file_header(Wsr88d_file_header *header)
295 swap_4_bytes(&header->title.file_date);
296 swap_4_bytes(&header->title.file_time);
299 /**********************************************************************/
301 /* done 2/28 wsr88d_read_file_header */
303 /**********************************************************************/
304 int wsr88d_read_file_header(Wsr88d_file *wf,
305 Wsr88d_file_header *wsr88d_file_header)
308 n = fread(&wsr88d_file_header->title,
309 sizeof(wsr88d_file_header->title), 1, wf->fptr);
311 wsr88d_swap_file_header(wsr88d_file_header);
315 /**********************************************************************/
317 /* done 8/18 wsr88d_read_tape_header */
319 /**********************************************************************/
320 int wsr88d_read_tape_header(char *first_file,
321 Wsr88d_tape_header *wsr88d_tape_header)
327 if ((fp = fopen(first_file, "r")) == NULL) {
332 n = fread(wsr88d_tape_header, sizeof(Wsr88d_tape_header), 1, fp);
334 fprintf(stderr, "WARNING: %s is smaller than 31616 bytes. It is not a tape header file.\n", first_file);
336 /* Try to read one more character. If we can, then this is not a
337 * tape header file. I suppose that we could look for '.' as the
338 * 9-th character and if it were there, then too this is not a tape
341 if (fread(&c, sizeof(char), 1, fp) > 0) {
342 fprintf(stderr, "WARNING: %s is larger than 31616 bytes. It is not a tape header file.\n", first_file);
343 memset(wsr88d_tape_header, 0, sizeof(Wsr88d_tape_header));
345 } else { /* Ok so far. Now check the first 8 bytes for "ARCHIVE2" */
346 if (strncmp(wsr88d_tape_header->archive2, "ARCHIVE2", 8) != 0) {
347 fprintf(stderr, "WARNING: %s is 31616 bytes. However, the first 8 bytes are not 'ARCHIVE2'.\n", first_file);
348 memset(wsr88d_tape_header, 0, sizeof(Wsr88d_tape_header));
360 /**********************************************************************/
362 /* not done N/A wsr88d_read_header */
364 /**********************************************************************/
365 int wsr88d_read_header(Wsr88d_file *wf, Wsr88d_header *wsr88d_header)
367 fprintf(stderr,"Routine: wsr88d_read_header\n");
372 /**********************************************************************/
374 /* done 3/2 wsr88d_read_sweep */
376 /**********************************************************************/
377 int wsr88d_read_sweep(Wsr88d_file *wf, Wsr88d_sweep *wsr88d_sweep)
380 Wsr88d_ray wsr88d_ray;
385 /* One sweep is defined as staying at the same RDA elevation number. */
386 /* We can read the file and check for that, however, we will need to
387 * buffer our input. The solution is to read the file and check the
388 * radial status. If it is '2' then we have reached the END OF ELEVATION.
389 * Here is a complete list of radial status codes:
390 * 0 = Start of new elevation.
391 * 1 = Intermediate radial.
392 * 2 = End of elevation.
393 * 3 = Beginning of volume scan.
394 * 4 = End of volume scan.
398 * 1. Skip packets until. Start of new elevation or
399 * Beginning of Volume scan. STAT=0 or 3.
400 * 2. Read until End of elevation. STAT=2 or 4. Skip message type != 1.
405 n = wsr88d_read_ray(wf, &wsr88d_ray);
408 while ((wsr88d_ray.msg_type & 15) != 1 && n > 0) {
410 fprintf(stderr,"SKIPPING packet: type %d, radial status %d\n",
411 wsr88d_ray.msg_type, wsr88d_ray.ray_status);
413 n = wsr88d_read_ray(wf, &wsr88d_ray);
416 if (n <= 0) return n; /* Read failure. */
419 while ( ! end_of_volume ) {
420 if ((wsr88d_ray.msg_type & 15) != 1) {
422 fprintf(stderr,"SKIPPING (amid a sweep) packet: type %d, "
423 "radial status %d\n",
424 wsr88d_ray.msg_type, wsr88d_ray.ray_status);
428 /* Load this ray into the sweep. */
429 ray_num = wsr88d_ray.ray_num;
430 /* Double check against # records we've seen. */
431 /* It is possible that a reset occurs and we begin to overwrite
432 * previously loaded rays. I've seen this occur, rarely, in the
433 * WSR88D data. I must trust 'ray_num'.
436 if (nrec+1 != ray_num) {
437 fprintf(stderr, "Data says %d is ray_num, but, I've seen %d "
438 "records.\n", ray_num, nrec+1);
441 if (wsr88d_sweep->ray[ray_num] == NULL) {
442 wsr88d_sweep->ray[ray_num] = (Wsr88d_ray *) malloc (sizeof(Wsr88d_ray));
444 memcpy(wsr88d_sweep->ray[ray_num], &wsr88d_ray, sizeof(Wsr88d_ray));
446 n = wsr88d_read_ray(wf, &wsr88d_ray);
448 end_of_volume = wsr88d_ray.ray_status == 2 ||
449 wsr88d_ray.ray_status == 4 ||
453 /* Process the last packet of the input data. */
454 if (wsr88d_ray.ray_status == 2 || wsr88d_ray.ray_status == 4) {
455 /* Load this ray into the sweep. */
456 ray_num = wsr88d_ray.ray_num;
457 if (wsr88d_sweep->ray[ray_num] == NULL) {
458 wsr88d_sweep->ray[ray_num] = (Wsr88d_ray *) malloc (sizeof(Wsr88d_ray));
460 memcpy(wsr88d_sweep->ray[ray_num], &wsr88d_ray, sizeof(Wsr88d_ray));
463 /* Just to be safe, clear all ray pointers left in this sweep to
464 * the maximum MAX_RAYS_IN_SWEEP. This is required when the
465 * wsr88d_sweep is reused and not cleared.
467 free_and_clear_sweep(wsr88d_sweep, ray_num+1, MAX_RAYS_IN_SWEEP);
470 fprintf(stderr,"Processed %d records for elevation number %d\n",
471 nrec+1, wsr88d_ray.elev_num);
472 wsr88d_print_sweep_info(wsr88d_sweep);
477 /**********************************************************************/
479 /* wsr88d_swap_ray */
481 /**********************************************************************/
482 void wsr88d_swap_ray(Wsr88d_ray *wsr88d_ray)
485 half_word = (short *)wsr88d_ray;
486 for (; half_word<(short *)&wsr88d_ray->msg_time; half_word++)
487 swap_2_bytes(half_word);
489 swap_4_bytes(&wsr88d_ray->msg_time);
490 swap_2_bytes(&wsr88d_ray->num_seg);
491 swap_2_bytes(&wsr88d_ray->seg_num);
492 swap_4_bytes(&wsr88d_ray->ray_time);
494 half_word = (short *) &wsr88d_ray->ray_date;
495 for (; half_word<(short *)&wsr88d_ray->sys_cal; half_word++)
496 swap_2_bytes(half_word);
498 swap_4_bytes(&wsr88d_ray->sys_cal);
500 half_word = (short *) &wsr88d_ray->refl_ptr;
501 for (; half_word<(short *)&wsr88d_ray->data[0]; half_word++)
502 swap_2_bytes(half_word);
506 /**********************************************************************/
508 /* done 2/28 wsr88d_read_ray */
510 /**********************************************************************/
511 int wsr88d_read_ray(Wsr88d_file *wf, Wsr88d_ray *wsr88d_ray)
514 n = fread(wsr88d_ray, sizeof(Wsr88d_ray), 1, wf->fptr);
515 /* if (n > 0) print_packet_info(wsr88d_ray); */
517 wsr88d_swap_ray(wsr88d_ray);
522 /**********************************************************************/
524 /* not done N/A wsr88d_read_ray_header */
526 /**********************************************************************/
527 int wsr88d_read_ray_header(Wsr88d_file *wf,
528 Wsr88d_ray_header *wsr88d_ray_header)
530 fprintf(stderr,"Stub routine: wsr88d_read_ray_header.\n");
534 /**********************************************************************/
536 /* done 3/3 wsr88d_ray_to_float */
538 /**********************************************************************/
539 int wsr88d_ray_to_float(Wsr88d_ray *ray,
540 int THE_DATA_WANTED, float v[], int *n)
543 * Input: *ray - WSR-88D packet
544 * Output: THE_DATA_WANTED - Indicates which field to convert. Fields:
545 * WSR88D_DZ, WSR88D_VR, WSR88D_SW
546 * v[] - The output vector of float values.
547 * n - Length of the output vector. 0 = no data.
551 * No allocation of space for the output vector performed here.
554 /* Code from Dan Austin (cvt_pckt_data.c) was the template for this. */
557 int num_ref_gates,num_vel_gates,num_spec_gates;
558 int refl_ptr, vel_ptr,spec_ptr,res_flag;
563 num_ref_gates = ray->num_refl;
564 num_vel_gates = ray->num_dop;
565 num_spec_gates = ray->num_dop; /* 'num_dop', this is not a typo. */
567 /* The data pointers are specified from the begining of the
568 * 'Digital Radar Data (Message) Header'. Since we have a structure
569 * that defines all the header variables and a member called 'data'.
570 * we must subtract the length of the 'message header' from the data
571 * pointer. Hopefully, the reflecivity pointer will be 0 meaning the
572 * first element of the 'data' member; ray->data[0];
574 #define LENGTH_OF_MESSAGE 100
575 if (num_ref_gates > 0) refl_ptr = ray->refl_ptr - LENGTH_OF_MESSAGE;
578 vel_ptr = ray->vel_ptr - LENGTH_OF_MESSAGE;
579 spec_ptr = ray->spc_ptr - LENGTH_OF_MESSAGE;
581 res_flag = ray->vel_res;
585 fprintf(stderr,"refl_ptr = %d #g = %d, ", refl_ptr, num_ref_gates);
586 fprintf(stderr," vel_ptr = %d #g = %d, ", vel_ptr, num_vel_gates);
587 fprintf(stderr,"spec_ptr = %d #g = %d, ", spec_ptr, num_spec_gates);
588 fprintf(stderr,"res_flag = %d\n", res_flag);
591 if (THE_DATA_WANTED == WSR88D_DZ) {
592 /* do the reflectivity data (dbZ)*/
593 if (refl_ptr+num_ref_gates > 2300)
594 fprintf(stderr, "WARNING: # refl index (%d) exceeds maximum (2300)\n",
595 refl_ptr+num_ref_gates);
597 for(i=0; i<num_ref_gates; i++) {
598 ival = ray->data[refl_ptr+i];
600 v[i] = (((ival-2.0)/2.0)-32.0);
604 v[i] = WSR88D_BADVAL;
609 } else if (THE_DATA_WANTED == WSR88D_VR) {
610 /* do the velocity data (M/S) */
611 if (vel_ptr+num_vel_gates > 2300)
612 fprintf(stderr, "WARNING: # vel index (%d) exceeds maximum (2300)\n",
613 vel_ptr+num_vel_gates);
615 for(i=0; i<num_vel_gates;i++) {
616 ival = ray->data[vel_ptr+i];
618 if (res_flag == 2) /* High resolution: 0.5 m/s */
619 v[i] = (((ival-2.0)/2.0)-63.5);
621 v[i] = ((ival-2.0)-127.0);
625 v[i] = WSR88D_BADVAL;
630 } else if (THE_DATA_WANTED == WSR88D_SW) {
631 /* now do the spectrum width data (M/S)*/
632 if (spec_ptr+num_spec_gates > 2300)
633 fprintf(stderr, "WARNING: # spec index (%d) exceeds maximum (2300)\n",
634 spec_ptr+num_spec_gates);
636 for(i=0;i<num_spec_gates;i++) {
637 ival = ray->data[spec_ptr+i];
639 v[i] = (((ival-2)/2.0)-63.5);
643 v[i] = WSR88D_BADVAL;
654 /**********************************************************************/
655 /* Functions that convert some message header values. */
656 /**********************************************************************/
657 /**********************************************************************/
659 /* done 3/3 float wsr88d_get_nyquist */
660 /* done 3/3 float wsr88d_get_atmos_atten_factor */
661 /* done 3/3 float wsr88d_get_velocity_resolution */
662 /* done 3/3 int wsr88d_get_volume_coverage */
663 /* done 3/3 float wsr88d_get_elevation_angle */
664 /* done 3/3 float wsr88d_get_azimuth */
665 /* done 3/3 float wsr88d_get_range */
666 /* done 3/3 void wsr88d_get_date */
667 /* done 3/3 void wsr88d_get_time */
668 /* done 5/20 int *wsr88d_get_vcp_info */
669 /* done 5/20 float wsr88d_get_fix_angle */
670 /* done 5/20 int wsr88d_get_pulse_count */
671 /* done 5/20 float wsr88d_get_azimuth_rate */
672 /* done 5/20 float wsr88d_get_pulse_width */
673 /* done 5/20 float wsr88d_get_prf */
674 /* done 5/20 float wsr88d_get_prt */
675 /* done 5/20 float wsr88d_get_wavelength */
676 /* done 5/20 float wsr88d_get_frequency */
678 /**********************************************************************/
679 float wsr88d_get_nyquist(Wsr88d_ray *ray)
681 return ray->nyq_vel/100.0;
684 float wsr88d_get_atmos_atten_factor(Wsr88d_ray *ray)
686 return ray->atm_att/1000.0;
689 float wsr88d_get_velocity_resolution(Wsr88d_ray *ray)
691 if (ray->vel_res == 2) return 0.5;
695 int wsr88d_get_volume_coverage(Wsr88d_ray *ray)
697 if (ray->vol_cpat == 11) return 11;
698 if (ray->vol_cpat == 12) return 12;
699 if (ray->vol_cpat == 21) return 21;
700 if (ray->vol_cpat == 31) return 31;
701 if (ray->vol_cpat == 32) return 32;
702 if (ray->vol_cpat == 121) return 121;
706 float wsr88d_get_elevation_angle(Wsr88d_ray *ray)
708 return ray->elev/8.0*(180.0/4096.0);
711 float wsr88d_get_azimuth(Wsr88d_ray *ray)
713 return ray->azm/8.0*(180.0/4096.0);
716 float wsr88d_get_range(Wsr88d_ray *ray)
718 return ray->unam_rng/10.0;
722 void wsr88d_get_date(Wsr88d_ray *ray, int *mm, int *dd, int *yy)
736 itime = ray->ray_date - 1;
737 itime *= 24*60*60; /* Seconds/day * days. */
739 tm_time = gmtime(&itime);
740 *mm = tm_time->tm_mon+1;
741 *dd = tm_time->tm_mday;
742 *yy = tm_time->tm_year;
745 void wsr88d_get_time(Wsr88d_ray *ray, int *hh, int *mm, int *ss, float *fsec)
751 * fsec (fraction of second)
756 *hh = *mm = *ss = *fsec = 0;
772 * Get_vcp_info - gets info about the volume coverage pattern for this scan
774 * int vcp_num - volume coverage pattern number
775 * int el_num - elevation number w/in vcp
776 * returns: int *vcp_info - ptr to array w/vcp info
777 * calls from: Nexrad2uf
781 /* this database contains volume coverage patterns & associated info: */
782 /* (0)= vcp # (1)=pulse width for vcp "Id$" */
783 /* line[1-n]: (n,0)= elev. # for vcp (n,1)= (fixed angle)*8*(4096/180) */
784 /* (n,2)= pulse count (n,3)= (azimuthal sweep rate)*8*(4096/45) */
786 static int vcp11[68] ={11,514,88,17,13600,88,0,14000,264,16,12664,264,0,14000,440,6,11736,608,6,24760,784,6,24760,952,10,12712,1128,10,12720,1368,0,18328,1584,0,18496,1824,0,18512,2184,0,18544,2552,0,18576,3040,0,18640,3552,0,18712};
788 static int vcp12[53]={12,514,91,15,15401,91,0,18204,164,15,15401,164,0,18204,237,15,15401,237,0,18204,328,3,19297,437,3,20393,564,3,20393,728,3,20393,928,3,20393,1165,0,20680,1456,0,20680,1820,0,21033,2276,0,20929,2840,0,20929,3550,0,20929};
790 static int vcp21[48]={21,514,88,28,8256,88,0,8272,264,28,8256,264,0,8272,440,8,7888,608,8,7888,784,8,8160,1096,12,8160,1800,0,10640,2656,0,10432,3552,0,10496};
792 static int vcp31[36]={31,516,88,63,3672,88,0,3688,272,63,3672,272,0,3688,456,63,3672,456,0,3688,640,0,3688,816,0,3688};
794 static int vcp32[32]={32,514,88,64,3616,88,0,3312,272,64,3616,272,0,3312,456,11,2960,640,11,2960,816,11,2960};
796 static int vcp121[62]={121,514,91,11,21336,91,0,21696,91,0,19952,91,0,15584,264,11,21336,264,0,21696,264,0,19952,264,0,15584,437,6,13985,437,0,19952,437,0,15584,610,6,15729,610,0,19952,610,0,15584,783,6,11872,783,0,21481,1092,6,14712,1802,0,21481,2658,0,21696,3550,0,21696};
798 static int vcp300[20]={300,514,88,28,8256,88,0,8272,440,8,8160,1800,0,10384};
800 int *wsr88d_get_vcp_info(int vcp_num,int el_num)
803 * This routine from Dan Austin. Program component of nex2uf.
805 static int vcp_info[4];
811 /* case statement to get vcp info */
814 fix_angle = vcp11[(3*el_num)-1];
815 pulse_cnt = vcp11[(3*el_num)];
816 az_rate = vcp11[(3*el_num)+1];
817 pulse_width = vcp11[1];
820 fix_angle = vcp12[(3*el_num)-1];
821 pulse_cnt = vcp12[(3*el_num)];
822 az_rate = vcp12[(3*el_num)+1];
823 pulse_width = vcp12[1];
826 fix_angle = vcp21[(3*el_num)-1];
827 pulse_cnt = vcp21[(3*el_num)];
828 az_rate = vcp21[(3*el_num)+1];
829 pulse_width = vcp21[1];
832 fix_angle = vcp31[(3*el_num)-1];
833 pulse_cnt = vcp31[(3*el_num)];
834 az_rate = vcp31[(3*el_num)+1];
835 pulse_width = vcp31[1];
838 fix_angle = vcp32[(3*el_num)-1];
839 pulse_cnt = vcp32[(3*el_num)];
840 az_rate = vcp32[(3*el_num)+1];
841 pulse_width = vcp32[1];
844 fix_angle = vcp300[(3*el_num)-1];
845 pulse_cnt = vcp300[(3*el_num)];
846 az_rate = vcp300[(3*el_num)+1];
847 pulse_width = vcp300[1];
850 fix_angle = vcp121[(3*el_num)-1];
851 pulse_cnt = vcp121[(3*el_num)];
852 az_rate = vcp121[(3*el_num)+1];
853 pulse_width = vcp121[1];
856 fix_angle = vcp11[(3*el_num)-1];
857 pulse_cnt = vcp11[(3*el_num)];
858 az_rate = vcp11[(3*el_num)+1];
859 pulse_width = vcp11[1];
862 fix_angle = vcp12[(3*el_num)-1];
863 pulse_cnt = vcp12[(3*el_num)];
864 az_rate = vcp12[(3*el_num)+1];
865 pulse_width = vcp12[1];
868 fix_angle = vcp21[(3*el_num)-1];
869 pulse_cnt = vcp21[(3*el_num)];
870 az_rate = vcp21[(3*el_num)+1];
871 pulse_width = vcp21[1];
881 /* get array for output */
882 vcp_info[0]=fix_angle;
883 vcp_info[1]=pulse_cnt;
885 vcp_info[3]=pulse_width;
888 /* return the value array */
893 float wsr88d_get_fix_angle(Wsr88d_ray *ray)
896 vcp_info = wsr88d_get_vcp_info(ray->vol_cpat, ray->elev_num);
897 return vcp_info[0]/8.0*180./4096.0;
899 int wsr88d_get_pulse_count(Wsr88d_ray *ray)
902 vcp_info = wsr88d_get_vcp_info(ray->vol_cpat, ray->elev_num);
905 float wsr88d_get_azimuth_rate(Wsr88d_ray *ray)
908 vcp_info = wsr88d_get_vcp_info(ray->vol_cpat, ray->elev_num);
909 return vcp_info[2]/8.0*45./4096.0;
911 float wsr88d_get_pulse_width(Wsr88d_ray *ray)
914 vcp_info = wsr88d_get_vcp_info(ray->vol_cpat, ray->elev_num);
915 return vcp_info[3]/299.792458;
918 float wsr88d_get_prf(Wsr88d_ray *ray)
921 float c = 299792458.0;
924 range = wsr88d_get_range(ray)*1000.0;
925 if (range != 0) prf = c/(2*range);
931 float wsr88d_get_prt(Wsr88d_ray *ray)
936 prf = wsr88d_get_prf(ray);
937 if (prf != 0) prt = 1.0/prf;
942 /* Note: wsr88d_get_wavelength() below is no longer used because of differences
943 * in wavelength for velocity and reflectivity. The function computes
944 * wavelength when Nyquist is present, but returns a constant wavelength
945 * otherwise. Nyquist is present for velocity, but not for reflectivity. The
946 * fact is that WSR-88D radars use a constant wavelength, 10.7 cm., which is
947 * the value now used where this function was formerly called in
948 * wsr88d_load_sweep_into_volume().
951 float wsr88d_get_wavelength(Wsr88d_ray *ray)
957 prf = wsr88d_get_prf(ray);
958 nyquist = wsr88d_get_nyquist(ray);
959 /* If required info to determine wavelength does not exist,
960 just use 10 cm. All wsr88d radars are 10cm. MJK */
961 if ((prf == 0) || (nyquist == 0.0)) wavelength = 0.10;
962 else wavelength = 4*nyquist/prf;
966 float wsr88d_get_frequency(Wsr88d_ray *ray)
969 float c = 299792458.0;
971 /* Carrier freq (GHz). Revised 12 Jun 97. MJK */
972 freq = (c / wsr88d_get_wavelength(ray)) * 1.0e-9;