Exemplo n.º 1
0
Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file)
/*
 * Gets all volumes from the nexrad file.  Input file is 'infile'.
 * Site information is extracted from 'call_or_first_tape_file'; this
 * is typically a disk file called 'nex.file.1'.
 *
 *  -or-
 *
 * Uses the string in 'call_or_first_tape_file' as the 4 character call sign
 * for the sight.  All UPPERCASE characters.  Normally, this call sign
 * is extracted from the file 'nex.file.1'.
 *
 * Returns a pointer to a Radar structure; that contains the different
 * Volumes of data.
 */
{
  Radar *radar;
  Volume *new_volume;
  Wsr88d_file *wf;
  Wsr88d_sweep wsr88d_sweep;
  Wsr88d_file_header wsr88d_file_header;
  Wsr88d_tape_header wsr88d_tape_header;
  int n;
  int nsweep;
  int i;
  int iv;
  int nvolumes;
  int volume_mask[] = {WSR88D_DZ, WSR88D_VR, WSR88D_SW};
  char *field_str[] = {"Reflectivity", "Velocity", "Spectrum width"};
  Wsr88d_site_info *sitep;
  char site_id_str[5];
  char *the_file;
  int expected_msgtype = 0;
  char version[8];

  extern int rsl_qfield[]; /* See RSL_select_fields in volume.c */
  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);

  sitep = NULL;
/* Determine the site quasi automatically.  Here is the procedure:
 *    1. Determine if we have a call sign.
 *    2. Try reading 'call_or_first_tape_file' from disk.  This is done via
 *       wsr88d_read_tape_header.
 *    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);
  else if (strlen(call_or_first_tape_file) == 0) {
	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 (sitep == 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]);

  
  memset(&wsr88d_sweep, 0, sizeof(Wsr88d_sweep)); /* Initialize to 0 a 
												   * heavily used variable.
												   */

/* 1. Open the input wsr88d file. */
  if (infile == NULL) the_file = "stdin";  /* wsr88d.c understands this to
											* mean read from stdin.
											*/
  else the_file = infile;

  if ((wf = wsr88d_open(the_file)) == NULL) {
	wsr88d_perror(the_file);
	return NULL;
  }



/* 2. Read wsr88d headers. */
  /* Return # bytes, 0 or neg. on fail. */
  n = wsr88d_read_file_header(wf, &wsr88d_file_header);
  /*
   * Get the expected digital radar message type based on version string
   * from the Archive II header.  The message type is 31 for Build 10, and 1
   * for prior builds.  Note that we consider AR2V0001 to be message type 1,
   * because it has been in the past, but with Build 10 this officially
   * becomes the version number for Evansville (KVWX), which will use message
   * type 31.  This could be a problem if RSL is used to process KVWX.
   */
  if (n > 0) {
      strncpy(version, wsr88d_file_header.title.filename, 8);
      if (strncmp(version,"AR2V0004",8) == 0 ||
	      strncmp(version,"AR2V0003",8) ==0 ||
	      strncmp(version,"AR2V0002",8) == 0) {
	  expected_msgtype = 31;
      }
      else if (strncmp(version,"ARCHIVE2",8) == 0 ||
	      strncmp(version,"AR2V0001",8) == 0) {
	  expected_msgtype = 1;
      }
  }

  if (n <= 0 || expected_msgtype == 0) {
      fprintf(stderr,"RSL_wsr88d_to_radar: ");
      if (n <= 0)
	  fprintf(stderr,"wsr88d_read_file_header failed\n");
      else
	  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);


  if (expected_msgtype == 31) {

      /* Get radar for message type 31. */
      nvolumes = 6;
      radar = load_wsr88d_m31_into_radar(wf);
      if (radar == NULL) return NULL;
  }
  else {
      /* Get radar for message type 1. */
      nvolumes = 3;
      /* Allocate all Volume pointers. */
      radar = RSL_new_radar(MAX_RADAR_VOLUMES);
      if (radar == NULL) return NULL;

    /* Clear the sweep pointers. */
      clear_sweep(&wsr88d_sweep, 0, MAX_RAYS_IN_SWEEP);

    /* Allocate a maximum of 30 sweeps for the volume. */
    /* Order is important.  WSR88D_DZ, WSR88D_VR, WSR88D_SW, is 
     * assigned to the indexes DZ_INDEX, VR_INDEX and SW_INDEX respectively.
     */ 

      for (iv=0; iv<nvolumes; iv++)
	    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);
      }

      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;
	    }
      }
  }
  wsr88d_close(wf);

/*
 * Here we will assign the Radar_header information.  Take most of it
 * from an existing volume's header.  
 */
  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 = RSL_prune_radar(radar);
  return radar;
}
Exemplo n.º 2
0
main (int argc, char **argv)
{

  Radar *new_radar, *tmp_radar, *radar;
  Sweep *s, *new_sweep;
  float min_range, max_range, low_azim, hi_azim;
  int j, i;
  char type;
  Volume *new_volume, *v;

/*
  RSL_radar_verbose_on();
*/
  if (argc < 8) {
	fprintf(stderr, "%s type(r|v|s) min_range max_range low_azim hi_azim ref_uf_file out_file\n", argv[0]);
	exit(-1);
  }

  i = 1;
  type = argv[i++][0];
  min_range = (float) atoi(argv[i++]);
  max_range = (float) atoi(argv[i++]);
  low_azim = (float) atoi(argv[i++]);
  hi_azim = (float) atoi(argv[i++]);

  radar = RSL_uf_to_radar(argv[i++]);
  if (!radar) exit(-1);

  RSL_load_refl_color_table();

  switch(type) {
  case 'r': 
  case 'v':
	v = RSL_copy_volume(radar->v[DZ_INDEX]);
	if (!v) exit(-1);
	if ((v = RSL_clear_volume(v)) == NULL) exit(-1);

	printf("volume's nsweeps - %d\n", v->h.nsweeps);
	for (j = 0; j < v->h.nsweeps; j++) {
	  printf("loading sweep %d\n", j);
	  v->sweep[j] = load_sweep(v->sweep[j]);

	}
	/* test get*from radar */
	if (type == 'r') {
	  if ((tmp_radar = RSL_new_radar(radar->h.nvolumes)) == NULL) exit (-1);
	  tmp_radar->h = radar->h;
	  tmp_radar->v[DZ_INDEX] = v;
	  new_radar = RSL_get_window_from_radar(tmp_radar,min_range, max_range, 
											low_azim, hi_azim); 
	  if (new_radar == NULL) {
		printf("null new radar\n");
		exit(-1);
	  }
	  RSL_volume_to_gif(new_radar->v[DZ_INDEX], argv[i], 500, 500, max_range);
	  RSL_free_radar(tmp_radar);
	  RSL_free_radar(new_radar);
	}
	else {
	  new_volume = RSL_get_window_from_volume(v, min_range, max_range, low_azim,
											hi_azim);
	  if (new_volume != NULL)
		RSL_volume_to_gif(new_volume, argv[i], 500, 500, max_range);
/*
	RSL_bscan_volume(new_volume);
*/
	  RSL_free_volume(new_volume);
	}
	break;
  case 's':
	s = RSL_copy_sweep(radar->v[DZ_INDEX]->sweep[0]);
	s = RSL_clear_sweep(s);
	s = load_sweep(s);
	if (!s) {
	  printf("null sweep\n");
	  exit(-1);
	}
	new_sweep = RSL_get_window_from_sweep(s, min_range, max_range, 
											low_azim, hi_azim  );

	RSL_sweep_to_gif(new_sweep, argv[i], 500, 500, max_range);
/*
	RSL_bscan_sweep(new_sweep);
*/
	RSL_free_sweep(new_sweep);

	break;
  default:
	break;
  }
  RSL_free_radar(radar);
  printf("done\n");
  exit (0);

}
Exemplo n.º 3
0
void nexr_list_lev ( char *filnam, int *lenfnam,
		char *radparm, int *lenparm, int *ier)

{

int i, nbin, iret;
long    flen, lofset = 20;
char cfil[LLPATH], cprm[LLMXLN];
char stid[]="KFTG", callid[5];

Radar *radar=NULL;
FILE *fp;


*ier = 0;

strncpy(cfil, filnam, *lenfnam);
strncpy(cprm, radparm, *lenparm);
cfil[*lenfnam] = '\0';
cprm[*lenparm] = '\0';

/* get actual file name to use in rsl call */
cfl_inqr ( cfil, NULL, &flen, cfil, &iret);

RSL_select_fields(cprm, NULL);

/*
if ( cprm[0] == 'd' )
        VINDEX = DZ_INDEX;
else if ( cprm[0] == 's' )
        VINDEX = SW_INDEX;
else if ( cprm[0] == 'v' )
        VINDEX = VR_INDEX;
*/

/*
 * see if we can get the station ID from bytes 21-24, otherwise, just use any ID
 */

fp = cfl_ropn ( cfil, NULL, &iret );
if  ( iret != 0 )  {
    printf("failed to open %s\n",cfil);
    *ier = -1;
    return;
    }
else {
    cfl_seek ( fp, lofset, SEEK_SET, &iret );
    if  ( iret != 0 )  {
        *ier = -1;
        cfl_clos ( fp, &iret );
        return;
        }
    }

cfl_read ( fp, 4, (unsigned char *)callid, &nbin, &iret );
cfl_clos ( fp, &iret );

if (( nbin < 4 )||(callid[0] < 'A')||(callid[0] > 'Z')) /* use a safe station ID....we aren't plotting lat/lon anyhow */
   strcpy(callid,stid);
else
   callid[4] = '\0';


/*RSL_radar_verbose_on();*/
RSL_read_these_sweeps("all", NULL);
radar = RSL_wsr88d_to_radar(cfil, callid);
/*RSL_radar_verbose_off();*/

if ( radar == NULL )
   {
   printf("failed to open %s\n",cfil);
   *ier = -1;
   return;
   }

for (i=0; i<radar->h.nvolumes; i++) {
   if (radar->v[i]) {
        printf("Volume %s: Sweeps available %d\n", cprm, radar->v[i]->h.nsweeps);
        print_header_for_volume(radar->v[i]);
      }
   }

RSL_free_radar(radar);


}
Exemplo n.º 4
0
Radar *RSL_wsr88d_to_radar(char *infile, char *call_or_first_tape_file)
/*
 * Gets all volumes from the nexrad file.  Input file is 'infile'.
 * Site information is extracted from 'call_or_first_tape_file'; this
 * is typically a disk file called 'nex.file.1'.
 *
 *  -or-
 *
 * Uses the string in 'call_or_first_tape_file' as the 4 character call sign
 * for the sight.  All UPPERCASE characters.  Normally, this call sign
 * is extracted from the file 'nex.file.1'.
 *
 * Returns a pointer to a Radar structure; that contains the different
 * Volumes of data.
 */
{
  Radar *radar;
  Volume *new_volume;
  Wsr88d_file *wf;
  Wsr88d_sweep wsr88d_sweep;
  Wsr88d_file_header wsr88d_file_header;
  Wsr88d_tape_header wsr88d_tape_header;
  int n;
  int nsweep;
  int iv;
  int nvolumes;
  int volume_mask[] = {WSR88D_DZ, WSR88D_VR, WSR88D_SW};
  char *field_str[] = {"Reflectivity", "Velocity", "Spectrum width"};
  Wsr88d_site_info *sitep;
  char site_id_str[5], failid[]="KFTG";
  char *the_file;

  extern int rsl_qfield[]; /* See RSL_select_fields in volume.c */
  extern int *rsl_qsweep; /* See RSL_read_these_sweeps in volume.c */
  extern int rsl_qsweep_max;

  /* initialize site id to a failsafe value */
 wsr88d_set_station_id(failid, -9999.0, -9999.0, -9999.0);

  sitep = NULL;
/* Determine the site quasi automatically.  Here is the procedure:
 *    1. Determine if we have a call sign.
 *    2. Try reading 'call_or_first_tape_file' from disk.  This is done via
 *       wsr88d_read_tape_header.
 *    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);
  else if (strlen(call_or_first_tape_file) < 3) {
	/*fprintf(stderr, "wsr88d_to_radar: No valid site ID info provided, using default.\n");
	strcpy(site_id_str,failid);
        sitep = wsr88d_get_site(site_id_str); -*enough for now. Message 31 contains ICAO and lat/lon */
	/*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 (sitep == 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]);*/

  
  memset(&wsr88d_sweep, 0, sizeof(Wsr88d_sweep)); /* Initialize to 0 a 
												   * heavily used variable.
												   */

/* 1. Open the input wsr88d file. */
  if (infile == NULL) the_file = "stdin";  /* wsr88d.c understands this to
											* mean read from stdin.
											*/
  else the_file = infile;

  if ((wf = wsr88d_open(the_file)) == NULL) {
	wsr88d_perror(the_file);
	return NULL;
  }

  nvolumes = 3;
  radar = RSL_new_radar(MAX_RADAR_VOLUMES); /* Allocate all Volume pointers. */
  if (radar == NULL) return NULL;



/* 2. Read wsr88d headers. */
  /* Return # bytes, 0 or neg. on fail. */
  n = wsr88d_read_file_header(wf, &wsr88d_file_header);
  if (n <= 0 ||
	  (strncmp(wsr88d_file_header.title.filename, "ARCHIVE2.", 9) != 0 &&
	   strncmp(wsr88d_file_header.title.filename, "AR2V000", 7) != 0))
  {
	wsr88d_close(wf);
	free(radar);
	return NULL;
  }


  if (radar_verbose_flag)
	print_head(wsr88d_file_header);

/* Clear the sweep pointers. */
  clear_sweep(&wsr88d_sweep, 0, MAX_RAYS_IN_SWEEP);

/* Allocate a maximum of 30 sweeps for the volume. */
/* Order is important.  WSR88D_DZ, WSR88D_VR, WSR88D_SW, is 
 * assigned to the indexes DZ_INDEX, VR_INDEX and SW_INDEX respectively.
 */ 

  for (iv=0; iv<nvolumes; iv++)
	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]) {
		if (nsweep >= radar->v[iv]->h.nsweeps) { /* Exceeded sweep limit.
												  * Allocate more sweeps.
												  * Copy all previous sweeps.
												  */
		  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;
		}
	  }
	}
	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;
	}
  }
  wsr88d_close(wf);

/*
 * Here we will assign the Radar_header information.  Take most of it
 * from an existing volume's header.  
 */
  /* set the sitep info from level2 info, message31 if present (TODO) */
  if ( sitep == NULL ) {
     float mess31_lat, mess31_lon, mess31_elev;
     float dms;
     wsr88d_get_station_id(site_id_str, &mess31_lat, &mess31_lon, &mess31_elev);
     sitep = wsr88d_get_site(site_id_str);
     mess31_lon = mess31_lon * -1.0;
     if ( sitep == NULL ) {
        printf("setting site information to ID %s lat %f lon %f elev %f\n",
		site_id_str, mess31_lat, mess31_lon, mess31_elev);
        sitep = (Wsr88d_site_info *)malloc(sizeof(Wsr88d_site_info));
        sitep->number = -9999;
        sprintf(sitep->name,"%s\0",site_id_str); 
        sprintf(sitep->city,"--\0");
        sprintf(sitep->state,"--\0");
        dms = fabs(mess31_lat);
        sitep->latd = floor(dms);
        dms = (dms - (float)sitep->latd)*60;
        sitep->latm = floor(dms);
        dms = (dms - (float)sitep->latm)*60;
        sitep->lats = floor(dms);
        dms = fabs(mess31_lon);
        sitep->lond = floor(dms);
        dms = (dms - (float)sitep->lond)*60;
        sitep->lonm = floor(dms);
        dms = (dms - (float)sitep->lonm)*60;
        sitep->lons = floor(dms);
        if ( mess31_lat < 0 ) {
           sitep->latd *= -1;
           sitep->latm *= -1;
           sitep->lats *= -1;
        }
        if ( mess31_lon < 0 ) {
           sitep->lond *= -1;
           sitep->lonm *= -1;
           sitep->lons *= -1;
        }
        sitep->height = (int)mess31_elev;
        sitep->bwidth = -9999;
	sitep->spulse = 1530;
        sitep->lpulse = 4630;
        
     }
  }

  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;

	free(sitep);
		
  radar = RSL_prune_radar(radar);
  return radar;
}