/* * * ################################################################## * ################################################################## * ###### ###### * ###### 88D2ARPS ###### * ###### ###### * ###### Developed by ###### * ###### Center for Analysis and Prediction of Storms ###### * ###### University of Oklahoma ###### * ###### ###### * ################################################################## * ################################################################## * * fakeio.c * *####################################################################### * * PURPOSE: * * Emulates the behavior of the NSSL WSR-88D realtime and * Archive II tape reading software. Arrays filled with fake * data are passed to the calling program as if they were * being read from the realtime buffer or tape stream. * * To use: Replace links to NSSL 88D libraries with * object code from this file. * * Some shortcomings of version 1.0: * A few calls are not supported. * Set_radar_name doesn't read the radar table and change location. * Storm mode only is emulated. * Runs faster than realtime (sleeps can be inserted in read_radial). * * Things for the future: * Address shortcomings, above. * More sophisticated fake data, such as read from a file, * analytic field or even a cloud model. * *####################################################################### * * AUTHOR: Keith Brewster * March, 1995 version 1.0 * kbrewster@ou.edu * * MODIFICATION HISTORY: * *####################################################################### * */ #include <stdio.h> #include <stdlib.h> #include <strings.h> #include <math.h> #include <time.h> struct tm rtime, *radtime; struct count_struct { int iazi; int iangle; int itilt; int iscan; } radcount; struct loc_struct { char rsite[80]; char radid[4]; int latitude; int longitude; int altitude; } radinfo; /* **** End of structure definitions **** */ /* set_radar_name */ /* Assigns radar name in location structure but does not look up the lat,lon,elev like the real radar reader. */ void set_radar_name(site) char site[80]; { extern struct loc_struct radinfo; strcpy(radinfo.rsite,site); } /* get_field_number */ /* Assigns field number based on input string. Must agree with action of get_data_field. */ int get_field_num(fchar) char fchar[3]; { if(strcmp(fchar,"DBZ") == 0) return(0); else if(strcmp(fchar,"VEL") == 0) return(1); else if(strcmp(fchar,"SPW") == 0) return(2); else if(strcmp(fchar,"SNR") == 0) return(3); else return(-1); } /* radar_init */ /* Initializes the radar counters. prints a warning message that fake data is being used. */ void radar_init(drive) char drive[80]; { extern struct count_struct radcount; extern struct tm rtime, *radtime; printf("\n\n *************FAKE DATA***********************\n\n"); printf(" Initializing a2io_fake for file testing only.\n"); printf("\n\n *************FAKE DATA***********************\n\n"); radtime =&rtime; radcount.iazi=0; radcount.iangle=100; radcount.itilt=1; radcount.iscan=1; } /* read_radial */ /* Emulates the act of reading a radial. Gets the time from the system and increments counters that pretend that the radar is spinning and going through a normal sequence of elev angles. Unlike the true read_radial, data are not buffered for use by get_data_field, rather get_data_field makes things up as it goes along */ /* These are the tilts for the WSR-88D storm mode */ /* The precise behavior of the 0.5 degree scans */ /* is not replicated */ #define MAXTILT 16 static int kelev[MAXTILT] = {50,50,50,150,240,340,430,530,620,750, 870,1000,1200,1400,1670,1950}; int read_radial() { extern struct tm rtime, *radtime; extern struct count_struct radcount; extern int kelev[]; int istat; long curtime[2], *tp; long timez[2], *tzp; tp = curtime; tzp = timez; radcount.iazi=radcount.iazi+100; if ( radcount.iazi > 35999 ) { radcount.iazi=radcount.iazi-36000; radcount.itilt++; if ( radcount.itilt > MAXTILT) { radcount.itilt=1; radcount.iscan++; } } radcount.iangle=kelev[radcount.itilt - 1]; istat=gettimeofday(tp,tzp); radtime=gmtime(tp); return(0); } int get_first_gate(ifield) int ifield; { if( ifield == 0 ) return(1000); else if ( ifield == 1) return(1000); else if ( ifield == 2) return(1000); else if ( ifield == 3) return(1000); else return(-999); } int get_gate_spacing(ifield) int ifield; { if( ifield == 0 ) return(1000); else if ( ifield == 1) return(250); else if ( ifield == 2) return(250); else if ( ifield == 3) return(1000); else return(-999); } /* get_data_field */ /* returns fake data Some day this could read from a storm model or other more realistic fake data generator. Reflectivity data are assigned an increasing function of range Velocity data are assigned a value like a constant horiz wind Spectrum Width data are constant = 0.5 ms-1 SNR data are constant = 40. */ int get_data_field(ifield,field,nsize) int ifield; float field[]; int nsize; { extern struct count_struct radcount; float twopi,dtr; float sinaz,cosaz,dxdr,dydr,dsdr; float mpgate,mgate0,x0,y0,xscale,yscale,x,y,u,v; int i; float *ptr; ptr=field; if( ifield == 0 ) for (i = 0; i < nsize; i++){ *ptr = (0.1 * (float) i); ptr++; } else if( ifield == 1 ) for (i = 0; i < nsize; i++){ /* *ptr =-abs (20.0 * sin (dtr * 0.01 * (float) radcount.iazi) );*/ /* *ptr = 20.0 * sin (dtr * 0.01 * (float) radcount.iazi);*/ dtr=0.017453292; twopi = 6.283185307; mpgate=250.; mgate0=1000.; x0 = 15000.; y0 = 15000.; xscale = twopi / 50000.; yscale = twopi / 50000.; cosaz = cos (dtr * 0.01 * (float) radcount.iazi); sinaz = sin (dtr * 0.01 * (float) radcount.iazi); dxdr = mpgate * cosaz ; dydr = mpgate * sinaz ; dsdr = cos (dtr * 0.01 * (float) radcount.iangle); for (i = 0; i < nsize; i++){ x = x0 + dxdr * (mgate0 + (float) i); y = y0 + dydr * (mgate0 + (float) i); u = 10.0 * sin (yscale * y); v =-10.0 * sin (xscale * x); *ptr = 10.0 * dsdr * (u * sinaz + v * cosaz); ptr++; } } else if( ifield == 2 ) for (i = 0; i < nsize; i++){ *ptr = 0.5; ptr++; } else if( ifield == 3 ) for (i = 0; i < nsize; i++){ *ptr = 40.; ptr++; } else return(-1); return(0); } /* get_year */ /* returns year time is controlled by read_radial */ int get_year() { extern struct tm *radtime; return(radtime->tm_year); } /* get_month */ /* returns number of month (1-12) time is controlled by read_radial */ int get_month() { extern struct tm *radtime; int imon; imon=radtime->tm_mon + 1; return(imon); } /* get_day */ /* returns day time is controlled by read_radial */ int get_day() { extern struct tm *radtime; return(radtime->tm_mday); } /* get_hour */ /* returns hour time is controlled by read_radial */ int get_hour() { extern struct tm *radtime; return(radtime->tm_hour); } /* get_min */ /* returns minute time is controlled by read_radial */ int get_min() { extern struct tm *radtime; return(radtime->tm_min); } /* get_sec */ /* returns seconds time is controlled by read_radial */ int get_sec() { extern struct tm *radtime; return(radtime->tm_sec); } /* get_azi */ /* returns radar azimuth angle angle is controlled by read_radial */ int get_azi() { extern struct count_struct radcount; return(radcount.iazi); } /* get_fixed_angle */ /* returns radar elevation angle angle is controlled by read_radial */ int get_fixed_angle() { extern struct count_struct radcount; return(radcount.iangle); } /* get_scan */ /* returns radar scan number number is controlled by read_radial */ int get_scan() { extern struct count_struct radcount; return(radcount.iscan); } /* get_tilt */ /* returns radar tilt number number is controlled by read_radial */ int get_tilt() { extern struct count_struct radcount; return(radcount.itilt); } /* get_status */ /* status returned is fixed at 1, status is always good in radar nirvana */ int get_status(index) int index; { return(1); } /* get_rt_mode */ /* rt_mode returned is fixed at 1, real-time / int get_rt_mode() { return(1); } /* get_nyquist */ /* nyquist velocity returned is fixed at 35.0 ms-1 */ int get_nyquist() { return(3500); } /* get_vcp */ /* vcp returned is fixed at 41 */ int get_vcp() { return(41); } /* get_latitude */ /* latitude returned is fixed at 35.23N */ int get_latitude() { /* return(3523000); */ /* return(3674000); */ return(3523000); } /* get_longitude */ /* longitude returned is fixed at 97.46W */ int get_longitude() { /* return(9746000); */ /* return(9812750); */ return(9746000); } /* get_altitude */ /* altitude returned is fixed at 381 m */ int get_altitude() { return(381); } /* get_number_of_gates * * Need to be checked for correctness -- Y. Wang. * Just added for compiling 88d2arps_fake. * */ int get_number_of_gates(int n) { return 0; }