]> Pileus Git - ~andy/rsl/blob - rapic.y
RSL v1.42
[~andy/rsl] / rapic.y
1 /*
2     NASA/TRMM, Code 910.1.
3     This is the TRMM Office Radar Software Library.
4     Copyright (C) 1998
5             John H. Merritt
6             Space Applications Corporation
7             Vienna, Virginia
8
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.
13
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.
18
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.
22 */
23 %{
24 #define USE_RSL_VARS
25 #include "rapic_routines.h"
26 #include "rsl.h"
27 #include <stdlib.h>
28 #include <math.h>
29 #include <string.h>
30
31 int rapicerror(char *s);
32 int rapicwrap(char *s);
33 int rapicwrap(char *s);
34 int yywrap(char *s);
35 int rapiclex(void);
36
37 int nsweep = 0;
38 float angres;
39 Radar *radar, *rapic_radar = NULL;
40 Volume *volume;
41 Sweep *sweep;
42 Ray *ray;
43
44 /* Rapic format declarations. */
45 Rapic_sweep_header rh;
46 Rapic_sweep *rs;
47
48 unsigned char outbuf[2000000];
49 int outbytes;
50 float azim, elev;
51 float save_elev;
52 int delta_time;
53 int nray = 0;
54 int ifield;
55 int ivolume, isweep, iray;
56 int station_id;
57
58 int sweepcount[5];
59
60 extern int radar_verbose_flag;
61 float rapic_nyquist;
62   %}
63
64 /* 2/18/98 - John Merritt
65  *
66  * This grammar parses the NT Rapic radar format.  The grammar
67  * is not minimal, however, it is self documenting; it closely matches
68  * the brief documentation.
69  */
70
71 /*-----------------------------------------------------------------
72  * NT Rapic Volume Structure:
73  * NOTE:   '*' marked tokens are preent only in versions > 10.0
74  * 
75  *  ImageHeader:
76  *      The header contains a set of tokens followed by data.
77  *      Each token is seperated by '\n' and all the data is
78  *      in ascii.
79  *  ScanHeader:
80  *         Scan header has the scan details like fieldname,
81  *      date/time azimuth,elevation etc.
82  *      The different sets of Tokens together with the data
83  *      are seperate by '\0'.
84  *   ScanData:
85  *         This represents the field data in runlehgth code.
86  *      Each Ray data contains azimuth,elevation,delta time
87  *      since start of this scan and the actual data.
88  *      
89  *      Here is a brief explanation of each of the Tokens.
90  *      
91  * 
92  * ImageHeader:
93  * 
94  * 1    /IMAGE:         <seqno> <imgno>
95  *      <seqno>         4 digit number
96  *      <imgno>         10 digit number
97  *      
98  * 2    /IMAGESCANS:    <nscans>
99  *      <nscans>        Number of scans in this volume
100  *              
101  * 3    /IMAGESIZE:     <size>
102  *      <size>          Size of image in bytes
103  * 
104  * 4    /SCAN       <scanno:> <seqno> <datetime> <???> <elev> <fieldno> <???> <offset> <size>
105  *      <scanno:>   1 - <number of scans> 
106  *      <seqno>     seqnum as given in /IMAGE:
107  *      <datetime>  yymoddhhmm
108  *      <???>       Don't care ( I don't know )
109  *      <elev>      Target Elevation in degrees.
110  *      <fieldno>   0-4 
111  *          0 Reflectivity     ?? Index? haven't seen this yet. ??
112  *                  1 Velocity         Confirmed this index.
113  *                  2 Width            Confirmed.
114  *              3 ZDR              ?? Index? haven't seen this yet. ??
115  *                  4 Uncorrected Reflectivity. Confirmed.
116  *      <???>       Don't care
117  *      <offset>    Offset to start of scan header
118  *      <size>      Size of this scan
119  *                  add offset to size to get to the next scan
120  *      /SCAN is repeated for each scan in the volume.
121  *      NOTE:
122  *      Unlike other formats each scan need not represent a seperate
123  *      elevation.
124  *      
125  * 5    /IMAGEHEADER END:
126  *      Indicates the end of Image header.
127  * 
128  *  ScanHeader:
129  * 
130  *      COUNTRY:        <code>
131  *      <code>          is a country code number
132  *      
133  *      NAME:           <Name>
134  *      <Name>          8 char long station name
135  *      
136  *      STNID:          <idno>
137  *      <idno>          A unique number indexing into station details
138  *      
139  *      LATITUDE:       <lat.lat>               *
140  *      <lat.lat>       Latitude in degrees     
141  *      
142  *      LONGITUDE:      <lon.lon>               *
143  *      <lon.lon>       Longitude in degrees
144  *      
145  *      HEIGHT:         <alt>                   *
146  *      <alt>           Radar height in meters
147  *      
148  *      DATE:           <datno>
149  *      <datno>         year = datno % 100
150  *                      if year > 80 year += 1900
151  *                      else year += 2000
152  *                      doy  = datno / 100
153  *                      Get the julian Number from year,1,1 and add doy -1
154  *                      Use Julian date conversion to get calendar date.
155  *                      NOTE: As simple as remembering your partner's DOB.
156  *                      
157  *      TIME:           <hh.mm>
158  *      <hh.mm>         Hour and minute
159  *      
160  *      TIMESTAMP:      <yyyymoddhhmmss>        *
161  *      <yyyymoddhhmmss> year,month,day,hour,min,sec
162  *      
163  *      VERS:           <versionNumber>
164  *      <versionNumber> 10.01
165  *      
166  *      FREQUENCY:      <freq>                  *
167  *      <freq>          Radar Frequency.
168  *      
169  *      PRF:            <prf>
170  *      <prf>           Pulse repetition Frequency
171  *      
172  *      PULSELENGTH:    <len>                   *
173  *      <len>           Pulse length
174  *      
175  *      RNGRES:         <gatewidth>
176  *      <gatewidth>     Range between gates
177  *      
178  *      ANGRES:         <angle>
179  *      <angle>         BeamWidth in degrees.
180  *
181  *      CLEARAIR:               ON or OFF
182  *      
183  *      VIDRES:         <res>
184  *      <res>           Video Resolution can be 
185  *                      16 OR 256.
186  *                      
187  *      STARTRNG:       <rng>
188  *      <rng>           Range to First gate in meters.
189  *      
190  *      ENDRNG:         <rng>
191  *      <rng>           Maximum range.
192  *      
193  *      PRODUCT:        <type> <[id]>
194  *      <type>          Ascii text
195  *                      VOLUMETRIC
196  *                      NORMAL
197  *                      
198  *      <[id]>          <id number>
199  *      
200  *      PASS:           <no> of <nscans>
201  *      <no>            Number of this scan
202  *      <nscans>        Max scan no.
203  *      
204  *      IMGFMT:         <type>
205  *      <type>          PPI,RHI etc.
206  *      
207  *      ELEV:           <elev>
208  *      <elev>          Elevation in degrees
209  *      
210  *      VIDEO:          <field>
211  *      <field>         Field Name Vel,Refl,Vel,UnCorRefl,Zdr,Wid
212  *      
213  *      VELLVL:         <level>
214  *      <level>         Velocity Level 
215  *      
216  *      NYQUIST:        <nyq>
217  *      <nyq>           Nyquist Velocity
218  *      
219  *      UNFOLDING:      <ratio>                 *
220  *      <ratio>         None or x:y
221  *      
222  * 
223  *      @               <data>                  *
224  *      <data>          AAA.A,EEE.E,TTT=LEN16D1D1D1NLD1D1D1NLNL
225  *      
226  *      AAA.A           Azimuth in degrees
227  *      EEE.E           Elevation in degress
228  *      TTT             Delta time in seconds since the start of this scan
229  *      LEN16           2 byte long length of radial
230  *      
231  *      D1              Run length coded Data.
232  *      NL              Null The Next Byte is count of NULL data.
233  *      NLNL            End of this Radial
234  * 
235  *         eg.          There will be no white space in the actual radial data.
236  *                              
237  *                      @066.1,010.6,004=002082B2817F8C84830048D72D0038
238  *                                       999C0036202D35FD2C00238A99008AFE920000
239  *                      Azimuth = 66.1
240  *                      Elev    = 10.6
241  *                      Dt      = 4 sec since the start
242  *                      0020    = Bytes to follow
243  *                      Data    = 82,B2,81,7F,8C,84,83
244  *                      0048    = 48H null bytes
245  *                      Data    = D7,2D
246  *                      0038    = 38H null bytes
247  *                      Data    = 99,9C
248  *                      0036    = 36H Null bytes
249  *                      ........................
250  *                      0000    = End of Data.
251  *      In  versions before 10.1                        
252  *      @               <data>                  
253  *      <data>          AAALEN16D1D1D1NLD1D1D1NLNL
254  *      
255  *      AAA             Azimuth in degrees
256  *      LEN16           2 byte long length of radial
257  *      
258  *      D1              Run length coded Data.
259  *      NL              Null The Next Byte is count of NULL data.
260  *      NLNL            End of this Radial
261  * 
262  *         eg.          There will be no white space in the actual radial data.
263  *                              
264  *                      @066002082B2817F8C84830048D72D0038
265  *                          999C0036202D35FD2C00238A99008AFE920000
266  *                      Azimuth = 66
267  *                      0020    = Bytes to follow
268  *                      Data    = 82,B2,81,7F,8C,84,83
269  *                      0048    = 48H null bytes
270  *                      Data    = D7,2D
271  *                      0038    = 38H null bytes
272  *                      Data    = 99,9C
273  *                      0036    = 36H Null bytes
274  *                      ........................
275  *                      0000    = End of Data.
276  *                      
277  * Please see the attached sample.vol to give a overall picture of the data.
278  * This is the dump of the volume with white space inserted to make it readable.
279  * Radial data dump is in hex.
280  */
281
282 %token IMAGE IMAGESCANS IMAGESIZE IMAGEEND
283 %token SCAN IMAGEHEADEREND
284 %token NUMBER
285 %token ALPHA
286 %token FLOATNUMBER
287 %token BRACKETNUM
288
289 %token COUNTRY
290 %token NAME
291 %token STNID
292 %token LATITUDE
293 %token LONGITUDE
294 %token HEIGHT
295 %token DATE
296 %token TIME
297 %token TIMESTAMP
298 %token VERS
299 %token FREQUENCY
300 %token PRF
301 %token PULSELENGTH
302 %token RNGRES
303 %token ANGRES
304 %token ANGLERATE
305 %token CLEARAIR ON OFF
306 %token VIDRES
307 %token STARTRNG
308 %token ENDRNG
309 %token PRODUCT
310 %token PASS
311 %token IMGFMT
312 %token ELEV
313 %token VIDEO
314 %token VELLVL
315 %token NYQUIST
316 %token UNFOLDING
317 %token AT
318 %token VOLUMETRIC
319 %token NORMAL
320 %token OF
321 %token REFL VEL UNCORREFL ZDR WID
322 %token NONE
323 %token RAYDATA
324 %token ENDRADARIMAGE
325
326 %union {
327   Charlen token;
328 }
329
330 %expect 61
331
332 %%
333
334 rapic_recognized : complete_header sweeps imageend
335 {
336   if (radar_verbose_flag) fprintf(stderr, "SUCCESSFUL parse\n");
337   sprintf(radar->h.name, "%s", rh.namestr);
338   sprintf(radar->h.radar_name, "%s", rh.namestr);
339
340   radar = fill_header(radar);
341   radar = RSL_prune_radar(radar);
342   rapic_radar = radar;
343   YYACCEPT;
344 }
345
346 sweeps : sweep
347        | sweeps sweep
348
349 sweep  : sweepheader rays ENDRADARIMAGE
350 {
351   /* Attach the sweep to the volume. */
352   if (radar_verbose_flag) fprintf(stderr, "Attach the sweep %d to the volume %d.\n",
353                   isweep, ivolume);
354   radar->v[ivolume]->sweep[isweep] = sweep;
355   radar->v[ivolume]->h.f    = sweep->h.f;
356   radar->v[ivolume]->h.invf = sweep->h.invf;
357 }
358
359 sweepheader : scanheader
360 {
361   /*  float c =  RSL_SPEED_OF_LIGHT; */
362   if (rh.angle_resolution != 0) 
363         sweep = RSL_new_sweep((int)(360.0/rh.angle_resolution+0.5));
364   if (fabs(rh.elev - save_elev) > .5) { /* New sweep elevation. */
365         isweep++;
366         save_elev = rh.elev;
367   }
368   nray = 0;
369   /* rapic_nyquist = c*((float)rh.prf/10.)/(4.*(float)rh.freq*100000.0); */
370 }
371
372 imageend : IMAGEEND seqno imgno
373
374 complete_header : imageheader IMAGEHEADEREND
375 {
376   if (radar_verbose_flag) fprintf(stderr, "sweepcount[0] = %d\n", sweepcount[0]);
377   if (sweepcount[0] > 0) {
378         radar->v[DZ_INDEX] = RSL_new_volume(sweepcount[0]);
379         radar->v[DZ_INDEX]->h.type_str = strdup("Reflectivity");
380   }
381   if (radar_verbose_flag) fprintf(stderr, "sweepcount[1] = %d\n", sweepcount[1]);
382   if (sweepcount[1] > 0) {
383         volume = radar->v[VR_INDEX] = RSL_new_volume(sweepcount[1]);
384         volume->h.type_str = strdup("Velocity");
385         volume->h.calibr_const = 0.0;
386   }
387   if (radar_verbose_flag) fprintf(stderr, "sweepcount[2] = %d\n", sweepcount[2]);
388   if (sweepcount[2] > 0) {
389         radar->v[SW_INDEX] = RSL_new_volume(sweepcount[2]);
390         volume->h.type_str = strdup("Spectral Width");
391         volume->h.calibr_const = 0.0;
392   }
393   if (radar_verbose_flag) fprintf(stderr, "sweepcount[3] = %d\n", sweepcount[3]);
394   if (sweepcount[3] > 0) {
395         radar->v[ZD_INDEX] = RSL_new_volume(sweepcount[3]);
396         volume->h.type_str = strdup("Reflectivity Depolarization Ratio");
397         volume->h.calibr_const = 0.0;
398   }
399   if (radar_verbose_flag) fprintf(stderr, "sweepcount[4] = %d\n", sweepcount[4]);
400   if (sweepcount[4] > 0) {
401         radar->v[ZT_INDEX] = RSL_new_volume(sweepcount[4]);
402         volume->h.type_str = strdup("Total Reflectivity");
403         volume->h.calibr_const = 0.0;
404   }
405   isweep = -1; /* It keeps track of the sweep number across all field
406                 * types; volumes.  It is immediately bumped to 0 when
407                 * the sweepheader is parsed.
408                                 */
409   save_elev = 99999;
410 }
411                 ;
412
413 imageheader : imageheader_item
414             | imageheader imageheader_item
415             | /* Empty */
416             ;
417
418 imageheader_item : IMAGE seqno imgno
419 {
420   radar = RSL_new_radar(MAX_RADAR_VOLUMES);
421   sweepcount[0] = 0;
422   sweepcount[1] = 0;
423   sweepcount[2] = 0;
424   sweepcount[3] = 0;
425   sweepcount[4] = 0;
426   radar->h.number = atoi($<token.s>2);
427 }
428  
429                  | IMAGESCANS number
430                  | IMAGESIZE number
431 {
432   if (atoi($<token.s>2) <= 0) {
433         fprintf(stderr, "RAPIC: /IMAGESIZE == %d.  RAPIC ingest returning NULL.\n", atoi($<token.s>2));
434         YYERROR;
435   }
436 }
437                              | scanlist
438                  ;
439
440 scanlist : SCAN scanno ':' seqno datetime dc elev fieldno dc offset size
441 {
442   ifield = atoi($<token.s>8);
443   sweepcount[ifield]++;
444 }
445
446 /*
447  * Now, describe some scan header fields.
448  */
449
450 rays      : ray
451           | rays ray
452           | /* EMPTY */
453           ;
454
455 ray : RAYDATA
456  {
457
458    /*   fprintf(stderr, "YACC len=%d text=<", yylval.token.len); */
459    /*   binprint(yylval.token.s, yylval.token.len); */
460    /*   fprintf(stderr, ">\n"); */
461
462    /* Quiet the compilier, because I only use the rsl_f_list and rsl_invf_list. */
463    RSL_ftype[0] = RSL_ftype[0];
464
465    /* Use yylval.token.s and yylval.token.len */
466    memset(outbuf, '\0', sizeof(outbuf));
467    rapic_decode((unsigned char *)yylval.token.s, yylval.token.len, outbuf, &outbytes,
468                                 &azim, &elev, &delta_time);
469    /*   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); */
470
471    ray = RSL_new_ray(outbytes);
472    rapic_load_ray_header(rh, nray, isweep, elev, azim, &ray->h); /* Mostly from the scanheader (rh). */
473    ray->h.azimuth = azim;
474    /*    if (39<azim && azim <40) { */
475    ray->h.elev = elev;
476    ray->h.sec += delta_time;
477    ray->h.f    = RSL_f_list[ivolume]; /* Data conversion function. f(x). */
478    ray->h.invf = RSL_invf_list[ivolume]; /* invf(x). */
479
480    rapic_fix_time(ray);
481    rapic_load_ray_data(outbuf, outbytes, ivolume, ray);
482 #define DODO
483 #undef DODO
484 #ifdef DODO
485    if (ray->h.ray_num == 0 && ivolume == 1 && isweep == 0)
486          { int i;
487    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);
488          for (i=0; i<ray->h.nbins; i++) {
489            fprintf(stderr,"YACCray->range[%d] = %d  %f\n", i, (int)ray->range[i],
490                            ray->h.f(ray->range[i]));
491          }
492          }
493 #endif
494    /* Attach the ray to the sweep. */
495    sweep->ray[nray]      = ray;
496    sweep->h.beam_width   = ray->h.beam_width;
497    sweep->h.vert_half_bw = sweep->h.beam_width / 2.0;
498    sweep->h.horz_half_bw = sweep->h.beam_width / 2.0;
499    sweep->h.sweep_num    = isweep;
500    sweep->h.elev         = ray->h.elev;
501    sweep->h.f            = ray->h.f;
502    sweep->h.invf         = ray->h.invf;
503    nray++;
504    /*   } */
505 }
506
507 scanheader : scanheaditem
508            | scanheader scanheaditem
509            | /* EMPTY */
510           ;
511
512 /* Each of these items are the header for a sweep. */
513
514 scanheaditem
515 : NAME        namestr { memmove(rh.namestr,$<token.s>2,$<token.len>2); }
516 | COUNTRY     code    { rh.country       = atoi($<token.s>2); }
517 | STNID           idno    { rh.station_id_no = atoi($<token.s>2); }
518 | LATITUDE        lat     { rh.lat           = atof($<token.s>2); }
519 | LONGITUDE       lon     { rh.lon           = atof($<token.s>2); }
520 | HEIGHT          alt     { rh.height        = atof($<token.s>2); }
521 | DATE            datno   { rh.datno         = atoi($<token.s>2); }
522 | TIME            hhmm    { rh.hhmm          = atof($<token.s>2); }
523 | TIMESTAMP       yyyymoddhhmmss { memmove(rh.yyyymoddhhmmss,$<token.s>2,$<token.len>2); }
524 | VERS            versionNumber  { rh.versionNumber    = atof($<token.s>2); }
525 | FREQUENCY   freq           { rh.freq             = atoi($<token.s>2); }
526 | PRF         prf            { rh.prf              = atoi($<token.s>2); }
527 | PULSELENGTH len            { rh.pulselen         = atof($<token.s>2); }
528 | RNGRES          gatewidth      { rh.range_resolution = atoi($<token.s>2); }
529 | ANGLERATE       anglerate      { rh.anglerate        = atof($<token.s>2); }
530 | CLEARAIR        clearair       { memmove(rh.clearair,$<token.s>2,$<token.len>2);}
531 | ANGRES          angle          { rh.angle_resolution = atof($<token.s>2); }
532 | VIDRES          res            { rh.video_resolution = atoi($<token.s>2); }
533 | STARTRNG        rng            { rh.start_range      = atoi($<token.s>2); }
534 | ENDRNG          rng            { rh.end_range        = atoi($<token.s>2); }
535 | PRODUCT         typeid BRACKETNUM { memmove(rh.product_type,$<token.s>2,$<token.len>2); }
536 | PRODUCT
537 | PASS            noofnscans
538 | ELEV            elev  { rh.elev    = atof($<token.s>2); }
539 | VELLVL          level { rh.vellvl  = atof($<token.s>2); }
540 | NYQUIST         nyq   
541 {
542   rh.nyquist = atof($<token.s>2);
543   rapic_nyquist = rh.nyquist;
544 }
545 | VIDEO           field { memmove(rh.video,$<token.s>2,$<token.len>2); }
546 | IMGFMT          type  { memmove(rh.imgfmt,$<token.s>2,$<token.len>2); }
547 | UNFOLDING       ratio /* Already loaded: rh.ratio1, rh.ratio2 */
548 ;
549
550 real     : number
551          | FLOATNUMBER
552
553 number   : NUMBER
554
555 seqno    : number
556 scanno   : number
557 imgno    : number
558 datetime : number
559 dc       : real
560          | ALPHA
561 elev     : real
562 fieldno  : number
563 offset   : number
564 size     : number
565 datno    : number
566
567 code     : number
568 namestr  : ALPHA
569 idno     : number
570 lat      : real
571 lon      : real
572 alt      : real
573 hhmm     : real
574
575 yyyymoddhhmmss : number
576 versionNumber  : real
577
578 freq       : number
579 prf        : number
580 len        : real
581 gatewidth  : number
582 angle      : real
583 anglerate  : real
584 clearair   : ON
585            | OFF
586 res        : number
587 rng        : number
588 typeid     :  VOLUMETRIC
589            |  NORMAL
590
591 noofnscans : no OF nscans
592 no         : number {rh.scannum = atoi($<token.s>1);}
593 nscans     : number {rh.ofscans = atoi($<token.s>1);}
594 type       : ALPHA
595
596 field : REFL      {ivolume = DZ_INDEX; volume = radar->v[ivolume];}
597       | VEL       {ivolume = VR_INDEX; volume = radar->v[ivolume];}
598       | UNCORREFL {ivolume = ZT_INDEX; volume = radar->v[ivolume];}
599       | ZDR       {ivolume = ZD_INDEX; volume = radar->v[ivolume];}
600       | WID       {ivolume = SW_INDEX; volume = radar->v[ivolume];}
601
602 level : real
603 nyq   : real
604
605 ratio : NONE        {rh.ratio1 = 0; rh.ratio2 = 0;}
606 | number ':' number {rh.ratio1 = atoi($<token.s>1); rh.ratio2 = atoi($<token.s>3);}
607
608
609
610 %%
611
612 int rapicerror(char *s)
613 {
614   fprintf(stderr, "RAPIC ERROR: <%s> on token <", s);
615   binprint(yylval.token.s, yylval.token.len);
616   fprintf(stderr, ">\n");
617   return 1;
618 }
619
620 int rapicwrap(char *s)
621 {
622   yywrap(s);
623   return 1;
624 }