NOTICE: This version of the NSF Unidata web site (archive.unidata.ucar.edu) is no longer being updated.
Current content can be found at unidata.ucar.edu.

To learn about what's going on, see About the Archive Site.

Re: [ldm-users] NEXRAD3 and ucnids

Hi Karen,

Attached is the source code for ucnids.  You can compile it with the
following command:   gcc ucnids.c -o ucnids -lz

Let me know if you have any questions.

Best,
-Mike


*Mike Zuranski*
Data Engineer II
Unidata Program Center
University Corporation for Atmospheric Research


On Wed, Jan 4, 2023 at 8:59 AM Karen Cooper - NOAA Affiliate via ldm-users <
ldm-users@xxxxxxxxxxxxxxxx> wrote:

> Does anyone have an updated copy of ucnids that will decode the newer
> NEXRAD3 products?
>
> --
> *"Outside of a dog, a book is a man's best friend.  Inside of a dog, it's
> too dark to read."*
> *--Groucho Marx*
>
> -------------------------------------------
> Karen.Cooper@xxxxxxxx
>
> Phone#:  405-325-6456
> Cell:   405-834-8559
> CIWRO/OU
> National Severe Storms Laboratory
>
> _______________________________________________
> NOTE: All exchanges posted to Unidata maintained email lists are
> recorded in the Unidata inquiry tracking system and made publicly
> available through the web.  Users who post to any of the lists we
> maintain are reminded to remove any personal information that they
> do not want to be made public.
>
>
> ldm-users mailing list
> ldm-users@xxxxxxxxxxxxxxxx
> For list information or to unsubscribe,  visit:
> https://www.unidata.ucar.edu/mailing_lists/
>
/********************************************************************
* ucnids - NIDS decompression utility for data compressed with zlib
*
*   syntax: ucnids [options] ifile ofile
*   ifile and ofile can be "-" to use standard input and output
*   options: 
*     none - output uncompressed product with NOAAPORT CCB
*     -c   - output with standard WMO CCB
*     -r   - output with strippped WMO CCB (RPS output)
*     -w   - output with WXP-like WMO header
*     -n   - output stripping header and leaving raw NIDS data
********************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <zlib.h>
#include <sys/stat.h>

void mkdirs( char *path ){
   int len;
   int i;

   len = strlen( path );

   for( i = 1; i < len-1; i++ ){
      if( path[i] == '/' ){
         path[i] = 0;
         mkdir( path, 0755 );
         path[i] = '/';
      }
   }
}

int main( int argc, char **argv ){
   FILE *ifile;
   FILE *ofile;
   unsigned char soh[101];
   unsigned char seq[101];
   unsigned char wmo[101];
   unsigned char awip[101];
   unsigned char inbuf[1000];
   unsigned int insize;
   unsigned char outbuf[10000];
   z_stream zs;
   int out;
   int len;
   int iret;
   int off;
   int i;
   int verb;
   int wxp;
   int inbytes;
   int outbytes;
   int check;
   int floc;

   verb = 0;

   off = 0;
   while( 1 ){
      if( argc > 1 && !strcmp( argv[1+off], "-v" )){
         verb = 1;
         off++;
      }
      else if( argc > 1+off && !strcmp( argv[1+off], "-c" )){
         out = 1;
         off++;
      }
      else if( argc > 1+off && !strcmp( argv[1+off], "-w" )){
         out = 2;
         off++;
      }
      else if( argc > 1+off && !strcmp( argv[1+off], "-n" )){
         out = 3;
         off++;
      }
      else if( argc > 1+off && !strcmp( argv[1+off], "-r" )){
         out = 4;
         off++;
      }
      else 
         break;
   }
   if( argc == 1+off || argv[1+off][0] == '-' )
      ifile = stdin;
   else
      ifile = fopen( argv[1+off], "r" );
   if( ifile == NULL ) exit( 1 );

   if( argc < 3+off || argv[2+off][0] == '-' )
      ofile = stdin;
   else {
      mkdirs( argv[2+off] );
      ofile = fopen( argv[2+off], "w" );
      if( !ofile ) exit( 1 );
   }

   fgets( soh, 100, ifile );
   /*
      Account for both raw input (0x01) and WXP input (**)
      */
   wxp = 0;
   off = 0;
   check = ((soh[0] << 8 + soh[1]) % 31);
   if( check == 0 ){
      off = strlen( soh );
      memcpy( inbuf, soh, off );
   }
   else if( soh[0] == '\n' ){
      fgets( soh, 100, ifile );
      len = strlen( soh )-7;
      memcpy( wmo, soh+3, len );
      wmo[len] = 0;
      fgets( awip, 100, ifile );
      wxp = 1;
   }
   else if( soh[0] == '*' ){
      len = strlen( soh )-7;
      memcpy( wmo, soh+3, len );
      wmo[len] = 0;
      fgets( awip, 100, ifile );
      wxp = 1;
   }
   else if( soh[0] == 0x01 ){
      fgets( seq, 100, ifile );
      fgets( wmo, 100, ifile );
      fgets( awip, 100, ifile );
   }

   iret = 0;
   zs.total_out = 4000;

   for( i = 0; i < 1000 && (iret != Z_STREAM_END || zs.total_out == 4000); i++ 
){
      /* 
         Read in a block of data
         */
      floc = ftell( ifile );
      insize = fread( inbuf+off, 1, 1000-off, ifile ); 
      if( verb ) fprintf( stderr, "Read: %X %d\n", floc, insize );
      if( off == 0 && insize == 0 ) break;
      inbytes+=insize;
      len = insize + off;
      /* 
         Check for 789C byte sequence denoting zlib compression
         If data are not compressed, pass through raw data
         */
      check = (((inbuf[0] << 8) + inbuf[1]) % 31);
      //printf( "check %X %X %d\n", inbuf[0], inbuf[1], check );
      if( i == 0 && check != 0 ){
         if( wxp ){
            if( out == 1 ){
               fwrite( "\001\r\r\n001\r\r\n", 1, 10, ofile );
               fprintf( ofile, "%18.18s\r\r\n", wmo );
            }
            else if( out == 2 ){
               fprintf( ofile, soh );
               fprintf( ofile, awip );
            }
         }
         else {
            if( out == 1 ){
               fprintf( ofile, soh );
               fprintf( ofile, seq );
               fprintf( ofile, wmo );
               fprintf( ofile, awip );
            }
            else if( out == 2 ){
               fprintf( ofile, "** %18.18s ***\n%s", wmo, awip );
            }
         }
         fwrite( inbuf, 1, insize, ofile );
         while(( insize = fread( inbuf, 1, 1000, ifile )) > 0 ){
            fwrite( inbuf, 1, insize, ofile );
         }
         exit( 0 );
      }
      if(( check == 0 && inbuf[0] == 0x78 && i < 5 )|| iret != Z_STREAM_END ){
         zs.avail_in = len;
         zs.avail_out = 10000;
         zs.next_in = inbuf;
         zs.next_out = outbuf;
         /*
            Check to see if 4000 byte block has been read and reinitialize
            */
         if( i == 0 || iret == Z_STREAM_END ){
            zs.zalloc = NULL;
            zs.zfree = NULL;
            inflateInit( &zs );
         }
         /*
            Inflate NIDS data
            */
         iret = inflate( &zs, Z_STREAM_END );
         if( verb ) fprintf( stderr, "Inf: %d -- %d %d %d -- 10000 %d %d -- %2X 
%2X -- %2X %2X\n", 
               iret, len, zs.avail_in, zs.total_in, zs.avail_out, zs.total_out, 
               inbuf[0], inbuf[1], outbuf[0], outbuf[1] );
         off = zs.avail_in;
      }
      else {
         memcpy( outbuf, inbuf, len );
         zs.avail_out = 10000-len;
         off = 0;
         if( verb ) fprintf( stderr, "Cpy: %d - %2X %2X\n", len, inbuf[0], 
inbuf[1] );
      }
      /*  
          Process header data for first block
          WMO CCB output
          */
      if( i == 0 && out == 1 ){
         fwrite( "\001\r\r\n001\r\r\n", 1, 10, ofile );
         fwrite( outbuf+24, 1, 10000-zs.avail_out-24, ofile );
      } 
      /*
         WXP header output
         */
      else if( i == 0 && out == 2 ){
         fprintf( ofile, "** %18.18s ***\n%s", wmo, awip );
         fwrite( outbuf+54, 1, 10000-zs.avail_out-54, ofile );
      } 
      /*
         Raw NIDS output
         */
      else if( i == 0 && out == 3 ){
         fwrite( outbuf+54, 1, 10000-zs.avail_out-54, ofile );
         outbytes+=10000-zs.avail_out-54;
      } 
      /*
         Stripped WMO CCB output
         */
      else if( i == 0 && out == 4 ){
         fwrite( outbuf+24, 1, 10000-zs.avail_out-24, ofile );
      } 
      /*
         Raw output with NOAAPORT CCB
         */
      else {
         fwrite( outbuf, 1, 10000-zs.avail_out, ofile );
         outbytes+=10000-zs.avail_out;
      } 
      /*
         Move remaining data that still is compressed and prepared 
         for next inflate
         */
      memcpy( inbuf, inbuf+len-off, off );
      if( iret < 0 ) break;
   }
   exit( 0 );
}
  • 2023 messages navigation, sorted by:
    1. Thread
    2. Subject
    3. Author
    4. Date
    5. ↑ Table Of Contents
  • Search the ldm-users archives: