X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=src%2Frapic_parse.y;fp=src%2Frapic_parse.y;h=b10475702322bc9e593b5c22a8b27fa64ab25413;hb=9260f544ed14229e3fc5af3f8c6dacd4882efa78;hp=0000000000000000000000000000000000000000;hpb=7099e6588b7bb1b0f178f4284120a2debff29e8f;p=~andy%2Frsl diff --git a/src/rapic_parse.y b/src/rapic_parse.y new file mode 100644 index 0000000..b104757 --- /dev/null +++ b/src/rapic_parse.y @@ -0,0 +1,624 @@ +/* + NASA/TRMM, Code 910.1. + This is the TRMM Office Radar Software Library. + Copyright (C) 1998 + John H. Merritt + Space Applications Corporation + Vienna, Virginia + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ +%{ +#define USE_RSL_VARS +#include "rapic_routines.h" +#include "rsl.h" +#include +#include +#include + +int rapicerror(char *s); +int rapicwrap(char *s); +int rapicwrap(char *s); +int yywrap(char *s); +int rapiclex(void); + +int nsweep = 0; +float angres; +Radar *radar, *rapic_radar = NULL; +Volume *volume; +Sweep *sweep; +Ray *ray; + +/* Rapic format declarations. */ +Rapic_sweep_header rh; +Rapic_sweep *rs; + +unsigned char outbuf[2000000]; +int outbytes; +float azim, elev; +float save_elev; +int delta_time; +int nray = 0; +int ifield; +int ivolume, isweep, iray; +int station_id; + +int sweepcount[5]; + +extern int radar_verbose_flag; +float rapic_nyquist; + %} + +/* 2/18/98 - John Merritt + * + * This grammar parses the NT Rapic radar format. The grammar + * is not minimal, however, it is self documenting; it closely matches + * the brief documentation. + */ + +/*----------------------------------------------------------------- + * NT Rapic Volume Structure: + * NOTE: '*' marked tokens are preent only in versions > 10.0 + * + * ImageHeader: + * The header contains a set of tokens followed by data. + * Each token is seperated by '\n' and all the data is + * in ascii. + * ScanHeader: + * Scan header has the scan details like fieldname, + * date/time azimuth,elevation etc. + * The different sets of Tokens together with the data + * are seperate by '\0'. + * ScanData: + * This represents the field data in runlehgth code. + * Each Ray data contains azimuth,elevation,delta time + * since start of this scan and the actual data. + * + * Here is a brief explanation of each of the Tokens. + * + * + * ImageHeader: + * + * 1 /IMAGE: + * 4 digit number + * 10 digit number + * + * 2 /IMAGESCANS: + * Number of scans in this volume + * + * 3 /IMAGESIZE: + * Size of image in bytes + * + * 4 /SCAN + * 1 - + * seqnum as given in /IMAGE: + * yymoddhhmm + * Don't care ( I don't know ) + * Target Elevation in degrees. + * 0-4 + * 0 Reflectivity ?? Index? haven't seen this yet. ?? + * 1 Velocity Confirmed this index. + * 2 Width Confirmed. + * 3 ZDR ?? Index? haven't seen this yet. ?? + * 4 Uncorrected Reflectivity. Confirmed. + * Don't care + * Offset to start of scan header + * Size of this scan + * add offset to size to get to the next scan + * /SCAN is repeated for each scan in the volume. + * NOTE: + * Unlike other formats each scan need not represent a seperate + * elevation. + * + * 5 /IMAGEHEADER END: + * Indicates the end of Image header. + * + * ScanHeader: + * + * COUNTRY: + * is a country code number + * + * NAME: + * 8 char long station name + * + * STNID: + * A unique number indexing into station details + * + * LATITUDE: * + * Latitude in degrees + * + * LONGITUDE: * + * Longitude in degrees + * + * HEIGHT: * + * Radar height in meters + * + * DATE: + * year = datno % 100 + * if year > 80 year += 1900 + * else year += 2000 + * doy = datno / 100 + * Get the julian Number from year,1,1 and add doy -1 + * Use Julian date conversion to get calendar date. + * NOTE: As simple as remembering your partner's DOB. + * + * TIME: + * Hour and minute + * + * TIMESTAMP: * + * year,month,day,hour,min,sec + * + * VERS: + * 10.01 + * + * FREQUENCY: * + * Radar Frequency. + * + * PRF: + * Pulse repetition Frequency + * + * PULSELENGTH: * + * Pulse length + * + * RNGRES: + * Range between gates + * + * ANGRES: + * BeamWidth in degrees. + * + * CLEARAIR: ON or OFF + * + * VIDRES: + * Video Resolution can be + * 16 OR 256. + * + * STARTRNG: + * Range to First gate in meters. + * + * ENDRNG: + * Maximum range. + * + * PRODUCT: <[id]> + * Ascii text + * VOLUMETRIC + * NORMAL + * + * <[id]> + * + * PASS: of + * Number of this scan + * Max scan no. + * + * IMGFMT: + * PPI,RHI etc. + * + * ELEV: + * Elevation in degrees + * + * VIDEO: + * Field Name Vel,Refl,Vel,UnCorRefl,Zdr,Wid + * + * VELLVL: + * Velocity Level + * + * NYQUIST: + * Nyquist Velocity + * + * UNFOLDING: * + * None or x:y + * + * + * @ * + * AAA.A,EEE.E,TTT=LEN16D1D1D1NLD1D1D1NLNL + * + * AAA.A Azimuth in degrees + * EEE.E Elevation in degress + * TTT Delta time in seconds since the start of this scan + * LEN16 2 byte long length of radial + * + * D1 Run length coded Data. + * NL Null The Next Byte is count of NULL data. + * NLNL End of this Radial + * + * eg. There will be no white space in the actual radial data. + * + * @066.1,010.6,004=002082B2817F8C84830048D72D0038 + * 999C0036202D35FD2C00238A99008AFE920000 + * Azimuth = 66.1 + * Elev = 10.6 + * Dt = 4 sec since the start + * 0020 = Bytes to follow + * Data = 82,B2,81,7F,8C,84,83 + * 0048 = 48H null bytes + * Data = D7,2D + * 0038 = 38H null bytes + * Data = 99,9C + * 0036 = 36H Null bytes + * ........................ + * 0000 = End of Data. + * In versions before 10.1 + * @ + * AAALEN16D1D1D1NLD1D1D1NLNL + * + * AAA Azimuth in degrees + * LEN16 2 byte long length of radial + * + * D1 Run length coded Data. + * NL Null The Next Byte is count of NULL data. + * NLNL End of this Radial + * + * eg. There will be no white space in the actual radial data. + * + * @066002082B2817F8C84830048D72D0038 + * 999C0036202D35FD2C00238A99008AFE920000 + * Azimuth = 66 + * 0020 = Bytes to follow + * Data = 82,B2,81,7F,8C,84,83 + * 0048 = 48H null bytes + * Data = D7,2D + * 0038 = 38H null bytes + * Data = 99,9C + * 0036 = 36H Null bytes + * ........................ + * 0000 = End of Data. + * + * Please see the attached sample.vol to give a overall picture of the data. + * This is the dump of the volume with white space inserted to make it readable. + * Radial data dump is in hex. + */ + +%token IMAGE IMAGESCANS IMAGESIZE IMAGEEND +%token SCAN IMAGEHEADEREND +%token NUMBER +%token ALPHA +%token FLOATNUMBER +%token BRACKETNUM + +%token COUNTRY +%token NAME +%token STNID +%token LATITUDE +%token LONGITUDE +%token HEIGHT +%token DATE +%token TIME +%token TIMESTAMP +%token VERS +%token FREQUENCY +%token PRF +%token PULSELENGTH +%token RNGRES +%token ANGRES +%token ANGLERATE +%token CLEARAIR ON OFF +%token VIDRES +%token STARTRNG +%token ENDRNG +%token PRODUCT +%token PASS +%token IMGFMT +%token ELEV +%token VIDEO +%token VELLVL +%token NYQUIST +%token UNFOLDING +%token AT +%token VOLUMETRIC +%token NORMAL +%token OF +%token REFL VEL UNCORREFL ZDR WID +%token NONE +%token RAYDATA +%token ENDRADARIMAGE + +%union { + Charlen token; +} + +%expect 61 + +%% + +rapic_recognized : complete_header sweeps imageend +{ + if (radar_verbose_flag) fprintf(stderr, "SUCCESSFUL parse\n"); + sprintf(radar->h.name, "%s", rh.namestr); + sprintf(radar->h.radar_name, "%s", rh.namestr); + + radar = fill_header(radar); + radar = RSL_prune_radar(radar); + rapic_radar = radar; + YYACCEPT; +} + +sweeps : sweep + | sweeps sweep + +sweep : sweepheader rays ENDRADARIMAGE +{ + /* Attach the sweep to the volume. */ + if (radar_verbose_flag) fprintf(stderr, "Attach the sweep %d to the volume %d.\n", + isweep, ivolume); + radar->v[ivolume]->sweep[isweep] = sweep; + radar->v[ivolume]->h.f = sweep->h.f; + radar->v[ivolume]->h.invf = sweep->h.invf; +} + +sweepheader : scanheader +{ + /* float c = RSL_SPEED_OF_LIGHT; */ + if (rh.angle_resolution != 0) + sweep = RSL_new_sweep((int)(360.0/rh.angle_resolution+0.5)); + if (fabs(rh.elev - save_elev) > .5) { /* New sweep elevation. */ + isweep++; + save_elev = rh.elev; + } + nray = 0; + /* rapic_nyquist = c*((float)rh.prf/10.)/(4.*(float)rh.freq*100000.0); */ +} + +imageend : IMAGEEND seqno imgno + +complete_header : imageheader IMAGEHEADEREND +{ + if (radar_verbose_flag) fprintf(stderr, "sweepcount[0] = %d\n", sweepcount[0]); + if (sweepcount[0] > 0) { + radar->v[DZ_INDEX] = RSL_new_volume(sweepcount[0]); + radar->v[DZ_INDEX]->h.type_str = strdup("Reflectivity"); + } + if (radar_verbose_flag) fprintf(stderr, "sweepcount[1] = %d\n", sweepcount[1]); + if (sweepcount[1] > 0) { + volume = radar->v[VR_INDEX] = RSL_new_volume(sweepcount[1]); + volume->h.type_str = strdup("Velocity"); + volume->h.calibr_const = 0.0; + } + if (radar_verbose_flag) fprintf(stderr, "sweepcount[2] = %d\n", sweepcount[2]); + if (sweepcount[2] > 0) { + radar->v[SW_INDEX] = RSL_new_volume(sweepcount[2]); + volume->h.type_str = strdup("Spectral Width"); + volume->h.calibr_const = 0.0; + } + if (radar_verbose_flag) fprintf(stderr, "sweepcount[3] = %d\n", sweepcount[3]); + if (sweepcount[3] > 0) { + radar->v[ZD_INDEX] = RSL_new_volume(sweepcount[3]); + volume->h.type_str = strdup("Reflectivity Depolarization Ratio"); + volume->h.calibr_const = 0.0; + } + if (radar_verbose_flag) fprintf(stderr, "sweepcount[4] = %d\n", sweepcount[4]); + if (sweepcount[4] > 0) { + radar->v[ZT_INDEX] = RSL_new_volume(sweepcount[4]); + volume->h.type_str = strdup("Total Reflectivity"); + volume->h.calibr_const = 0.0; + } + isweep = -1; /* It keeps track of the sweep number across all field + * types; volumes. It is immediately bumped to 0 when + * the sweepheader is parsed. + */ + save_elev = 99999; +} + ; + +imageheader : imageheader_item + | imageheader imageheader_item + | /* Empty */ + ; + +imageheader_item : IMAGE seqno imgno +{ + radar = RSL_new_radar(MAX_RADAR_VOLUMES); + sweepcount[0] = 0; + sweepcount[1] = 0; + sweepcount[2] = 0; + sweepcount[3] = 0; + sweepcount[4] = 0; + radar->h.number = atoi($2); +} + + | IMAGESCANS number + | IMAGESIZE number +{ + if (atoi($2) <= 0) { + fprintf(stderr, "RAPIC: /IMAGESIZE == %d. RAPIC ingest returning NULL.\n", atoi($2)); + YYERROR; + } +} + | scanlist + ; + +scanlist : SCAN scanno ':' seqno datetime dc elev fieldno dc offset size +{ + ifield = atoi($8); + sweepcount[ifield]++; +} + +/* + * Now, describe some scan header fields. + */ + +rays : ray + | rays ray + | /* EMPTY */ + ; + +ray : RAYDATA + { + + /* fprintf(stderr, "YACC len=%d text=<", yylval.token.len); */ + /* binprint(yylval.token.s, yylval.token.len); */ + /* fprintf(stderr, ">\n"); */ + + /* Quiet the compilier, because I only use the rsl_f_list and rsl_invf_list. */ + RSL_ftype[0] = RSL_ftype[0]; + + /* Use yylval.token.s and yylval.token.len */ + memset(outbuf, '\0', sizeof(outbuf)); + rapic_decode((unsigned char *)yylval.token.s, yylval.token.len, outbuf, &outbytes, + &azim, &elev, &delta_time); + /* fprintf(stderr, "RAYDATA: ray %d, ivol %d, isweep %d, azim %f, elev %f, dtime %d, size=%d\n", nray, ivolume, isweep, azim, elev, delta_time, outbytes); */ + + ray = RSL_new_ray(outbytes); + rapic_load_ray_header(rh, nray, isweep, elev, azim, &ray->h); /* Mostly from the scanheader (rh). */ + ray->h.azimuth = azim; + /* if (39h.elev = elev; + ray->h.sec += delta_time; + ray->h.f = RSL_f_list[ivolume]; /* Data conversion function. f(x). */ + ray->h.invf = RSL_invf_list[ivolume]; /* invf(x). */ + + rapic_fix_time(ray); + rapic_load_ray_data(outbuf, outbytes, ivolume, ray); +#define DODO +#undef DODO +#ifdef DODO + if (ray->h.ray_num == 0 && ivolume == 1 && isweep == 0) + { int i; + fprintf(stderr, "RAYDATA: ray %d, ivol %d, isweep %d, azim %f, elev %f, dtime %d, size=%d\n", nray, ivolume, isweep, azim, elev, delta_time, outbytes); + for (i=0; ih.nbins; i++) { + fprintf(stderr,"YACCray->range[%d] = %d %f\n", i, (int)ray->range[i], + ray->h.f(ray->range[i])); + } + } +#endif + /* Attach the ray to the sweep. */ + sweep->ray[nray] = ray; + sweep->h.beam_width = ray->h.beam_width; + sweep->h.vert_half_bw = sweep->h.beam_width / 2.0; + sweep->h.horz_half_bw = sweep->h.beam_width / 2.0; + sweep->h.sweep_num = isweep; + sweep->h.elev = ray->h.elev; + sweep->h.f = ray->h.f; + sweep->h.invf = ray->h.invf; + nray++; + /* } */ +} + +scanheader : scanheaditem + | scanheader scanheaditem + | /* EMPTY */ + ; + +/* Each of these items are the header for a sweep. */ + +scanheaditem +: NAME namestr { memmove(rh.namestr,$2,$2); } +| COUNTRY code { rh.country = atoi($2); } +| STNID idno { rh.station_id_no = atoi($2); } +| LATITUDE lat { rh.lat = atof($2); } +| LONGITUDE lon { rh.lon = atof($2); } +| HEIGHT alt { rh.height = atof($2); } +| DATE datno { rh.datno = atoi($2); } +| TIME hhmm { rh.hhmm = atof($2); } +| TIMESTAMP yyyymoddhhmmss { memmove(rh.yyyymoddhhmmss,$2,$2); } +| VERS versionNumber { rh.versionNumber = atof($2); } +| FREQUENCY freq { rh.freq = atoi($2); } +| PRF prf { rh.prf = atoi($2); } +| PULSELENGTH len { rh.pulselen = atof($2); } +| RNGRES gatewidth { rh.range_resolution = atoi($2); } +| ANGLERATE anglerate { rh.anglerate = atof($2); } +| CLEARAIR clearair { memmove(rh.clearair,$2,$2);} +| ANGRES angle { rh.angle_resolution = atof($2); } +| VIDRES res { rh.video_resolution = atoi($2); } +| STARTRNG rng { rh.start_range = atoi($2); } +| ENDRNG rng { rh.end_range = atoi($2); } +| PRODUCT typeid BRACKETNUM { memmove(rh.product_type,$2,$2); } +| PRODUCT +| PASS noofnscans +| ELEV elev { rh.elev = atof($2); } +| VELLVL level { rh.vellvl = atof($2); } +| NYQUIST nyq +{ + rh.nyquist = atof($2); + rapic_nyquist = rh.nyquist; +} +| VIDEO field { memmove(rh.video,$2,$2); } +| IMGFMT type { memmove(rh.imgfmt,$2,$2); } +| UNFOLDING ratio /* Already loaded: rh.ratio1, rh.ratio2 */ +; + +real : number + | FLOATNUMBER + +number : NUMBER + +seqno : number +scanno : number +imgno : number +datetime : number +dc : real + | ALPHA +elev : real +fieldno : number +offset : number +size : number +datno : number + +code : number +namestr : ALPHA +idno : number +lat : real +lon : real +alt : real +hhmm : real + +yyyymoddhhmmss : number +versionNumber : real + +freq : number +prf : number +len : real +gatewidth : number +angle : real +anglerate : real +clearair : ON + | OFF +res : number +rng : number +typeid : VOLUMETRIC + | NORMAL + +noofnscans : no OF nscans +no : number {rh.scannum = atoi($1);} +nscans : number {rh.ofscans = atoi($1);} +type : ALPHA + +field : REFL {ivolume = DZ_INDEX; volume = radar->v[ivolume];} + | VEL {ivolume = VR_INDEX; volume = radar->v[ivolume];} + | UNCORREFL {ivolume = ZT_INDEX; volume = radar->v[ivolume];} + | ZDR {ivolume = ZD_INDEX; volume = radar->v[ivolume];} + | WID {ivolume = SW_INDEX; volume = radar->v[ivolume];} + +level : real +nyq : real + +ratio : NONE {rh.ratio1 = 0; rh.ratio2 = 0;} +| number ':' number {rh.ratio1 = atoi($1); rh.ratio2 = atoi($3);} + + + +%% + +int rapicerror(char *s) +{ + fprintf(stderr, "RAPIC ERROR: <%s> on token <", s); + binprint(yylval.token.s, yylval.token.len); + fprintf(stderr, ">\n"); + return 1; +} + +int rapicwrap(char *s) +{ + yywrap(s); + return 1; +}