[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Decoders error



Dan,

I found the source of the decoders error message that you sent me awhile
back.  The sao2nc decoder was using the wrong literal. Attached is the
fixed version of sao2nc.

Robb...

===============================================================================
Robb Kambic                                Unidata Program Center
Software Engineer III                      Univ. Corp for Atmospheric Research
address@hidden             WWW: http://www.unidata.ucar.edu/
===============================================================================
#! /usr/local/bin/perl
#
#  usage: sao2nc [cdlfile] netcdf
#
# This sao to netCDF decoder was created by using a sao decoder provided by
# Mark Albright as a starting point.  Robb Kambic added a netCDF wrapper to
# change the output from ascii to netCDF format.
#
use NetCDF ;

# process input parameters
if( $#ARGV == 0 ) {
        $ncfile = $ARGV[ 0 ] ;
} elsif( $#ARGV == 1 ) {
        $cdlfile = $ARGV[ 0 ] ;
        $ncfile = $ARGV[ 1 ] ;
} else {
        die "Wrong number of parameters " ;
}

# set interrupt handler
$SIG{ 'INT' }  = 'cleanup' ;
$SIG{ 'TERM' }  = 'cleanup' ;
$SIG{ 'KILL' }  = 'cleanup' ;
$SIG{ 'QUIT' }  = 'cleanup' ;

# default value
$F = -9999 ;

# change to home
chdir() ;
chdir( "/home/rkambic/code/decoders/perldec/marka" ) ;

# open or create ncfiles
if( -e $ncfile ) {
        $ncid = NetCDF::open( "$ncfile", WRITE ) ;
        $record_id = NetCDF::dimid( $ncid, "record" ) ;
        $name_id =  "xxxxxx"  ;
        $recnum =  -1  ;
        NetCDF::diminq( $ncid, $record_id, $name_id, $recnum ) ;

} else {
        die "Wrong or missing cdlfile parameter" unless  -e $cdlfile ;
        if( index( $ncfile, '/' ) != -1 ) {
                $dir = substr( $ncfile, 0, rindex( $ncfile, '/' ) ) ;
                if( ! -e $dir ) {
                        system( "mkdir -p $dir" ) ;
                }
        }

        if( -e "util/ncgen" ) {
                $ncgen = "util/ncgen" ;
        } elsif( -e "/usr/local/ldm/util/ncgen" ) {
                $ncgen = "/usr/local/ldm/util/ncgen" ;
        } elsif( -e "/upc/netcdf/bin/ncgen" ) {
                $ncgen = "/upc/netcdf/bin/ncgen" ;
        } elsif( -e "./ncgen" ) {
                $ncgen = "./ncgen" ;
        } else {
                open( NCGEN, "which ncgen |" ) ;
                $ncgen = <NCGEN> ;
                close( NCGEN ) ;

                if( $ncgen =~ /no ncgen/ ) {
                        die "Can't find NetCDF utility 'ncgen' in PATH, 
util/ncgen
        /usr/local/ldm/util/ncgen, /upc/netcdf/bin/ncgen, or ./ncgen : $!\n" ;
                } else {
                        $ncgen = "ncgen" ;
                }
        }

        system( "$ncgen -o $ncfile $cdlfile" ) ;
        $ncid = NetCDF::open( "$ncfile", WRITE ) ;
        # NetCDF record counter
        $recnum = 0 ;
}

# set fill mode
NetCDF::setfill($ncid, NetCDF::NOFILL) == 0 || die "Couldn't set fill mode\n";

select( STDOUT ) ;

# read in station data
if( -e "etc/city_sfc.dat" ) {
        $sfile = "etc/city_sfc.dat" ;
} elsif( -e "./city_sfc.dat" ) {
        $sfile = "./city_sfc.dat" ;
} else {
        die "Can't file city_sfc.dat station file" ;
}
open( STATION, "$sfile" ) || die "could not open $sfile: $!\n" ;

while( <STATION> ) {
        @station = split ;
        @station = reverse( @station ) ;
        $station[ 4 ] =~ /(\d)/ ;
        
        # set these vars ( $lat, $lon, $elev, $priority, $wmo_id ) 
        $STATIONS{ "$station[ 5 ]" } = 
                "$station[ 3 ] $station[ 2 ] $station[ 1 ] $1 $station[ 0 ]" ;
}
close STATION ;

$cover{'SCT'} = 3 ;
$cover{'BKN'} = 6 ;
$cover{'OVC'} = 8 ;
$cover{'0VC'} = 8 ;     # Occasionally observers misspell OVC

$pre1995 = "" ;         # Hard wired to process sao obs from 1995

# Now begin parsing file and decoding observations breaking on cntrl C
$/ = "\cC" ;

# set select processing here
while( 1 ) {
        open( STDIN, '-' ) ;
        vec($rin,fileno(STDIN),1) = 1;
        $timeout = 600 ;
        $nfound = 0 ;
        $nfound = select( $rout = $rin, undef, undef, $timeout );
        # timed out
        if( ! $nfound ) {
                #print "nfound = 0 \n" ;
                &cleanup() ;
        }

        &cleanup() if( eof( STDIN ) ) ;

   $_ = <STDIN> ;     # Process each bulletin
   s#\cM##g ;
   s#\cC##g ;

   if( s/^\s*\001\s*\d\d\d\s+S\w(\w\w)\d{1,2} [CK]\w\w\w \d{2}(\d{2})(\d{2})( 
RTD\d\d)?\s+//s ) {
      # Ignore bulletins of Canadian and Mexican hourlies
      #print "$&\n" ;
      $header_hr  = $2 ;
      $header_min = $3 ;
   }
   else {
      #print STDERR "Couldn't match header.\n" ;
      #print STDERR "$_\n\n" ;
      next ;      # Advance to the next bulletin
   }

   # Usually reports are separated by a RS character
   if( /\036/ ) {
      s/[ \n]RSNK /\036RSNK / ;         # Separate RSNK from the HMS report   
      @reports = split ( /\036/ ) ;
   }
   elsif( /=\n/ ) {
#      s/[ \n]RSNK /=RSNK / ;            # Separate RSNK from the HMS report
      @reports = split( /=\n/ ) ;
   }    
   else {
#      s/[ \n]RSNK /\nRSNK / ;           # Separate RSNK from the HMS report
      @reports = split ( /\n/ ) ;
   }

   for ( @reports ) {                   # Process each report in the bulletin  
      $raw = $lat = $lon = $elev = $priority = "" ;
      $id = $type = $hr = $min = $ceiling = $skyc = $vis = $wea = $pres =
      $t = $td = $wdir = $wspd = $wgst = $alt = $ptend = $deltap =
      $pcp1 = $pcp3_6 = $xt = $pcp24 = $snow = $tmax = $tmin = $comment = "" ;
      $ptend_found = $read_cloud = $snowfall = $snowh2o = "" ;
      $asos = $ramos = $amos = $awos = $correction = $dashx = "" ;
      $one_inch = $two_inch = $three_inch = "" ;

      # save original undecoded report
      $raw = $_ ;

              # Remove multiple spaces, newlines and trailing = from report
      s#[\s=\$]+$## ;    s#/\n\s*#/ # ;   s#\n# #g ;   s#\s{2,}# #g ;
#      s#\s*\n\s*/#/#g ; 

      if( /FINO/ ) { next ; }  
      $hold_report = $_ ;

      if( s/^(\w{3,4}) (SA|RS|SP|USP) (COR |RTD )?([0-2]\d)([0-5]\d) (COR |RTD 
)?// ) {
         $id   = $1 ;
#      if( !($id eq "CNK" || $id eq "ALS" || $id eq "DDC" || $id eq "GLD" )) {
#      next ; }           # These 2 lines used to check ASOS decoding
         $type = $2 ;
         $correction = $3 ;
         $hr   = $4 ;
         $min  = $5 ;
      }
      elsif( s/^RSNK // ) {   # Treat Rattlesnake Mtn. as special case
         $id = "RSN" ;
         $type = "SA" ;
         $hr = $header_hr ;
         $min = $header_min ;
         if( s#^([-\d]+)/(\d\d)(\d\d)(G(\d+))?## ) {
            $t = $1 ;
            $wdir = $2 ;
            $wspd = $3 ;
            $wgst = $5 ;
         }
      }
      else { next ; }

      if( $id eq "LAX" ) {  # Handles city temperature appended at end of report
         if( s#/ ?(CITY\s*[\d/]{2,3})## ) {
            $comment = " $1" ;
         }
      }

#       Extract station's latitude, longitude, elevation, priority.

        ( $lat, $lon, $elev, $priority, $wmo_id ) = 
                        split( ' ', $STATIONS{ "$id" } ) ;


      if( $lat eq "" ) {        # Station not found in directory
         #print STDERR "Couldn't find $id in station directory.\n" ;
         next ;
      }

      if( s/^AUTOB // ) {  # for now skip AUTOB reports for SDB, DRT, and INW
         next ;
      }

      if( s/^AMOS // ) {  # Stations such as SMP
         $amos = "TRUE" ;
      }

      if( s#^RAMOS /## ) { # Process RAMOS reports somewhat differently
         $ramos = "TRUE" ;
      }

      if( s/^A[O0]2A? // ) { # Process ASOS reports somewhat differently
        $asos = "TRUE" ;
        if( s/CLR BLO 120 // ) {
           $ceiling = "888" ;
        }
        s/^MM // ;
      }

      if( s/^AWOS // ) {   # Process AWOS reports somewhat differently
         $awos = "TRUE" ;
         if( s/CLR BLO 120 // ) {    # Sky cover is unknown for this case
#            $ceiling = ">120" ;
            $ceiling = "888" ;         # Above value confusing to fortran io 
         }
         if( s/^M // ) {        # sky cover info missing
           $ceiling = "M" ;
         }
         if( s/SLP (\d\d\d)// ) {      # OTH reports in this manner
            $pres = $1 ;
         }
      }

      if( s/^-X // ) {
         $dashx = "TRUE" ;
         $skyc = 0 ;
      }

      if( s/^W ?(\d{1,2}) ?X // ) {        # Sky obscured
         $skyc = 9 ;
         $ceiling = $1 ;
      }
      elsif( s/^CLR // ) {       # Clear
         $skyc = 0 ;
         $ceiling = 999 ;
      }
      else {
         # Capture each cloud layer
         while ( s/^[ME]?(\d{1,3})V? ?(-?)(SCT|BKN|[0O]VC) // ) {
            $thin = $2 ;
            if( ( $3 eq "BKN" || $3 eq "OVC"  || $3 eq "0VC" ) && !$ceiling ) {
               if( !$thin ) { $ceiling = $1 ; }
            }
            $skyc = $cover{$3} ;
            $read_cloud = "TRUE" ;
         }
         if( !$ceiling && ( $read_cloud || $dashx ) ) {
            $ceiling = 999 ;
         }
      }

   #This section assumes sky info accompanied by vis and pres weather
      if( $ceiling ne "" ) {
         if( $ceiling eq "M" ) { $ceiling = "" ; } 
         # Now decode visibility and present weather
         if( s#^((<?\d{1,2}/\d{1,2})|(\d{1,3}\+?)) ?([A-Z+-]*) ## ) {
            $vis = $1 ;
            $wea = $4 ;
         } 
         if( s#^(\d)/(\d{1,2})## ) {  # Check whether more visibility follows
            if( $2 > $1 ) {            # Otherwise must be T and Td 
               $vis .= $1 . "/" . $2 ;
               if( s#^([A-Z]+[A-Z+-]*) ## ) {
                  $wea = $1 ;
               }
               else {
                  s#^ ## ;     # If no present weather then remove leading space
               }
            }
            else {           # T and Td are both single digits
               $t = $1 ;
               $td= $2 ;
               if( s#^/E?(\d\d)(\d\d)(G(\d+))?/## ) {
                  $wdir = $1 ;
                  $wspd = $2 ;
                  $wgst = $4 ;
               }
            }
         }
      }
      $wea =~ s/^V// ;  # Remove reference to variable visibility from $wea
         
      if( $vis =~ m#^<1/4# ) {        # AWOS stations report in this way
         $vis = "1/8" ;
      }
#  Use this code to change visibility to decimal notation if needed
      if( $vis =~ m#^(\d?)(\d)/(\d{1,2})# ) {       # Fractional visibility
         if( $3 != 0 ) { $vis = $1 + $2/$3 ; }
         else { $vis = "" ; }
      }

      # Regular(SA or RS) obs on the hour, or amos/asos report
      if( $type ne "SP" || $amos  || $asos || $awos ) { 
         if( s#^E?(\w+)/ ?([\w-]+)/([\w-]+)/E?(\d\d)(\d\d)(G(\d+)| M)?/## ){ 
            $pres = $1 ;
            $t    = $2 ;
            $td   = $3 ;
            $wdir = $4 ;
            $wspd = $5 ;
            $wgst = $7 ;
         }
         elsif( s#^ ?([\w-]+)/([\w-]+)/E?(\d\d)(\d\d)(G(\d+)| M)?/## ){ 
            $t    = $1 ;
            $td   = $2 ;
            $wdir = $3 ;
            $wspd = $4 ;
            $wgst = $6 ;
            $td =~ s/M//g ;     # Check for missing value
         }
         else {
            $skyc = $ceiling = $vis = $wea = "" ;
         }
         if( $pres =~ /[a-zA-Z]/ || length( $pres ) != 3 ) { $pres = "" ; }
         if( $t    =~ /[a-zA-Z]/ ) { $t  = "" ; }
         if( $td   =~ /[a-zA-Z]/ ) { $td = "" ; }         
      }
      else {                     # Special report(SP)
         if( s#^E?(\d\d)(\d\d)(G(\d+))?/## ) {
            $wdir = $1 ;
            $wspd = $2 ;
            $wgst = $4 ;
         }
      }

      if( $wdir ne "" ) {
         $wdir *= 10 ;
         if( $wdir == 0 ) { $wdir = "00" ; }
      }

      if( $ramos && s#PK WND (\d{2,3})## ) {
         $wgst = $1 ;
         $wgst =~ s/^0(\d)$/$1/ ;
      }

      if( $amos && s/PK WND (\d{2,3}) \d\d\d// ) {
         unless ( $wgst ) { 
            $wgst = $1 ;
#            $wgst =~ s/^0(\d\d)/$1/ ;
         }
      }

      if( $wspd ne "" ) { $wspd *= 1 ; }
      if( $wgst ne "" ) { $wgst *= 1 ; }

      if( $wspd ne "" ) { # If wind was found then search for altimeter setting
         if( s#^(\d\d\d|M)/?# # ) {    # Altimeter setting
            $alt = $1 ;   $alt =~ s#M##g ;
         }
      }

      if( $asos ) {
         if( s/ PCPN (\d\d\d\d|M)( |$)/ / ) {
            $pcp1 = $1 ;
            if( $pcp1 eq "0000" ) { $pcp1 = " T" ; }
            if( $pcp1 =~ /^\d+$/ ) {
               $pcp1 *= 1 ;   # Remove leading zeroes
               if( $pcp1 < 10 ) { $pcp1 = "0" . $pcp1 ; }
            }
         }
         else { $pcp1 = " 0" ; }
      }
         
      if( s/ NOSPL// ) {      # no specials(SP) between hours
         $comment .= $& ;
      }

      if( $hr == 7 && $min > 45 ) {
         if( s# 98(\d\d\d)([ /]|$)# # ) {
            $sunshine = $1/60. + .05 ;
            $sunshine =~ s/(\.\d)\d*/$1/ ;
            $comment = " sunshine=$sunshine hrs" . $comment ;
         }
      }
      if( $hr >= 4 && $hr <= 11 ) {   # Midnight Local Standard Time
         if( s# 4(\d)(\d{3})(\d)(\d{3})([ /]|$)# # ) {
            $tmax = $1 ? -$2*1 : $2*1 ;
            $tmin = $3 ? -$4*1 : $4*1 ;
            $comment .= " Mx=$tmax Mn=$tmin" ;
            if( $id eq "RSN" ) { $comment = "Hanford:" . $comment ; }
         }
      }

      $hourly_3 = $hourly_6 = $hourly_12 = "" ;
      if( ($hr+1)%3 == 0  &&  $min>20  &&  $type ne "SP" ) {
         $hourly_3 = "TRUE" ;
         if( ( $hr+1 )% 6 == 0 ) { $hourly_6  = "TRUE" ; }
         if( ( $hr+1 )%12 == 0 ) { $hourly_12 = "TRUE" ; }
      }
      elsif( $hr%3 == 0  &&  $min<30  &&  $type ne "SP" ) {
         $hourly_3 = "TRUE" ;
         if( $hr% 6 == 0 ) { $hourly_6  = "TRUE" ; }
         if( $hr%12 == 0 ) { $hourly_12 = "TRUE" ; }
      }

  # Process only 3-hourly SA or RS reports in the next block
      if( $hourly_3 && !$ramos ) {

         if( $hourly_12 ) {   # Process only 12-hourly SA/RS reports here
            if( s/(( [A-Z]{3})? RADAT \w+)// ){
               $comment .= $1 ;
            }
         }

         if( $asos || ! $pre1995 ) {
            if( s# 5(\d)(\d\d\d)([ /]|$)# # ) {
               $ptend = $1 ;
               $deltap = $2 ;
               $deltap =~ s/0(\d\d)/$1/ ;
               $ptend_found = "TRUE" ;
            }

            if( s# 6(\d\d\d)/([ /]|$)# # ) {
               $pcp3_6 = $1 ;
               if( $pcp3_6 eq "000" ) { $pcp3_6 = "T" ; }
               $pcp3_6 =~ s/0(\d\d)/$1/ ;
            }
            elsif( s# 6////( |$)# # ) { $pcp3_6 = "" ; }
            elsif( $ptend_found ) { $pcp3_6 = "0" ; }

            if( $hr == 11 ) {   # 12 GMT only
               if( s# 7(\d{4})([ /]|$)# # ) {
                  $pcp24 = $1 ;
                  $pcp24 *= 1 ;
                  if( $pcp24 < 10 ) { $pcp24 = "0" . $pcp24 ; }
               }
               elsif( s# 7////([ /]|$)# # ) { $pcp24 = "" ; }
               elsif( $ptend_found ) { $pcp24 = "0" ; }
            }

            if( s# 1(\d)(\d\d\d)([ /]|$)# # ) {
               $tmax = $1 ? -$2*1 : $2*1 ;
            }
            else { s# 1////([ /]|$)# # ; }

            if( s# 2(\d)(\d\d\d)([ /]|$)# # ) {
               $tmin = $1 ? -$2*1 : $2*1 ;
            }
            else { s# 2////([ /]|$)# # ; }

            if( $hr <= 6 || $hr == 23 ) {  # 00 and 06 GMT
               $xt = $tmax ;
            }
            else { $xt = $tmin ; }      # 12 and 18 GMT
            
            if( s# 8/([\d/]{3})([ /]|$)# # ) {
               $comment .= " C$1" ;
            }
            
#            if( s/ 901(\d\d)( |$)/ / ) { # New snowfall in inches
#               $snowfall = $1 ;
#            }

            if( s# 933(\d\d\d)([ /]|$)# # ) { # Water equivalent snow depth in
               $snowh2o = $1/10. ;         # tenths of inch
            }
            if( $snowh2o ) {
               $snowh2o += .05 ;
               $snowh2o =~ s/(\.\d)\d*/$1/ ;
            }

            if( s# 4/(\d\d\d)([ /]|$)# # ) {   # Snow depth in inches
               $snow = $1 ;
               $snow =~ s#^0+## ;
            }
         }              # end of ASOS processing
         else {         # non ASOS stations
            if( s/ 901(\d\d)( |$)/ / ) { # New snowfall in inches
               $snowfall = $1 ;
            }
            if( s/ 902(\d\d)( |$)/ / ) { # Water equivalent snow depth in
               $snowh2o = $1/10. ;         # tenths of inch
            }
            if( s/ 903(\d\d)( |$)/ / ) { # Water equivalent snow depth in
               $snowh2o += $1 ;            # whole inches
            }
            if( $snowh2o ) {
               $snowh2o += .05 ;
               $snowh2o =~ s/(\.\d)\d*/$1/ ;
            }
            while ( s/ 904(\d\d)( |$)/ / ) {   # Snow depth in inches
               if( $1 == 99 ) { $snow = $snow + 100 ; }
               else { $snow = $snow + $1 ; }
            }   
                # probably Max/Min temp and 24 hr precipitation
            if( s/ 4(\d\d)(\d\d)( 2(\d\d\d\d))?( |$)/ / ) {
               if( $1 eq "00" ) {            # found ptend/precip group instead
                  $ptend = "4" ;
                  $deltap = $1 ;
                  $pcp3_6 = $2 ;
                  $ptend_found = 1 ;
               }
               else {                           # found Max and Min temperature
                  $tmax = $1 ;
                  $tmin = $2 ;
                  if( $pcp24 = $4 ) {
                     $pcp24 *= 1 ;               # Remove leading zeroes ;
                     if( $pcp24 < 10 ) { $pcp24 = "0" . $pcp24 ; }
                  }
               }
            }

            if( s# [A-Z]{1,2}R[\d/]{2}[ \w]*$## ) { # Runway condition
               $comment .= $& ;
            }

#            s#[\s/]+$## ; # Remove trailing slashes such as found on OTH report

            if( $hourly_12 ) {
               if( s/ 2(\d\d\d\d)\s*$// ) {    # 24 hr precipitation
                  $pcp24 = $1 ;
                  $pcp24 *= 1 ;               # Remove leading zeroes ;
                  if( $pcp24 < 10 ) { $pcp24 = "0" . $pcp24 ; }
               }
            }

            if( s# 1\d[\d/][\d/]( |$)# # ) {  # Cloud types
               $comment = $& . " " . $comment ;
            }

            if( s/ (\d{1,2})\s*$/ / ) {
                $xt = $1 ;
            }

            if( s/ 99(\d\d\d)\s*$/ / ) { # Pressure change exceeds 9.9 mb
               $deltap = $1 ;
            }
 
            if( s/ ONE\s*$/ / )   { $one_inch = "TRUE" ; }
            elsif( s/ TWO\s*$/ / )   { $two_inch = "TRUE" ; }
            elsif( s/ THREE\s*$/ / ) { $three_inch = "TRUE" ; }

            if( !$ptend_found && s#[ /](\d)(\d\d)(\d\d)?\s*$# # ) {
               $ptend  = $1 ;
               if( !$deltap ) { $deltap = $2 ; }
               $pcp3_6 = $3 ;
               if( $one_inch )   { $pcp3_6 += 100 ; }
               elsif( $two_inch )   { $pcp3_6 += 200 ; }
               elsif( $three_inch ) { $pcp3_6 += 300 ; }
               if( !$pcp3_6 ) {
                  $pcp3_6 = "0" ;
               }
            # Military stations do not report precip at 03, 09, 15, and 21GMT.
               if( !$hourly_6 ) {
                  if( $id eq "GRF"||$id eq "TCM"||$id eq "NUW"||$id eq "SKA" ) {
                     $pcp3_6 = "" ;
                  }
               }
            }
            if( $pcp3_6 eq "00" ) { $pcp3_6 = "-1" ; } # Trace precip coded as 
-1
         }
      }                  # end of 3-hourly processing

      # Clean up in preparation for adding to comment field
      s#^[/ ]*## ;  s#[/ ]*$## ; s# / # #g ;  s#\s+# # ;
      s# #_#g ; s#,#;#g ;  # Substitute ; for , and underscore for spaces

      $comment = $_ . $comment ;

      if( $snowh2o ) {
         $comment = "snowH2O=$snowh2o " . $comment ;  
      }
  
      $comment = $correction . $comment ;
      $comment =~ s#^\s+## ;
      $comment = $pcp1 . " " . $comment ;
#      if( $asos ) {
#         $pcp1str = sprintf ( "%3.3s ", $pcp1 ) ;
#         $comment = $pcp1str . $comment ;
#      }

      # Needed for using with list directed fortran io
      #$id = "\"" . $id . "\"" ;

      $t =~ s/(-?)(0+)([1-9]+)/$1$3/ ;  
      $td =~ s/(-?)(0+)([1-9]+)/$1$3/ ;  

      # expand abreviations and partial numbers
      if( $alt && $alt < 500 ) {
        $alt = "3" . "$alt" ;
        $alt /= 100 ;
      } elsif( $alt && $alt > 500 ) {
        $alt = "2" . "$alt" ;
        $alt /= 100 ;
      }
      if( $pres && $pres < 600 ) {
        $pres = "10" . "$pres" ;
        $pres /= 10 ;
      } elsif( $pres && $pres > 600 ) {
        $pres = "9" . "$pres" ;
        $pres /= 10 ;
      }

if( 0 ) {
      $report_dec = join(',', $id, $type, $priority, $hr, $min, $lat, $lon,
                               $elev, $ceiling, $skyc, $vis, $wea, $pres, $t,
                               $td, $wdir, $wspd, $wgst, $alt, $ptend, $deltap,
                               $pcp3_6, $xt, $pcp24, $snow, $tmax, $tmin,
                               $comment ) ;

      print "\n---$hold_report---\n" ;
      print OUT $report_dec, "\n" ;
}

        # set defaults for NetCDF
        $hr = $F unless $hr ;
        $t = $F unless $t ;
        $td = $F unless $td ;
        $pres = $F unless $pres ;
        $wdir = $F unless $wdir ;
        $wspd = $F unless $wspd ;
        $wgst = $F unless $wgst ;
        $alt = $F unless $alt ;
        $vis = $F unless $vis ;
        $wea = $F unless $wea ;
        $ptend = $F unless $ptend ;
        $deltap = $F unless $deltap ;
        $pcp1 = $F unless $pcp1 ;
        $pcp3 = $F unless $pcp3 ;
        $pcp6 = $F unless $pcp6 ;
        $pcp24 = $F unless $pcp24 ;
        $tmax = $F unless $tmax ;
        $tmin = $F unless $tmin ;


        # output the NetCDF data here
        $datap[ 0 ] = \$wmo_id ;
        #&charord( \@id, $id, 4 ) ;
        &padstr( \$id, 4 ) ;
        $datap[ 1 ] = \$id ;
        $datap[ 2 ] = \$lat ;
        $datap[ 3 ] = \$lon ;
        $datap[ 4 ] = \$elev ;
        $datap[ 5 ] = \$hr ;
        $datap[ 6 ] = \$hr ;
        $datap[ 7 ] = \$t ;
        $datap[ 8 ] = \$td ;
        $datap[ 9 ] = \$pres ;
        $datap[ 10 ] = \$wdir ;
        $datap[ 11 ] = \$wspd ;
        $datap[ 12 ] = \$wgst ;
        $datap[ 13 ] = \$alt ;
        $datap[ 14 ] = \$vis ;
#print "$wea\n" ;
        @wea = ( $wea, 
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0) ;
        $datap[ 15 ] = \@wea ;
        &padstr( \$stn_type, 1 ) ;
        $datap[ 16 ] = \$stn_type ;
        &padstr( \$type, 2 ) ;
        $datap[ 17 ] = \$type ;
        $datap[ 18 ] = \$ptend ;
        $datap[ 19 ] = \$deltap ;
        $datap[ 20 ] = \$pcp1 ;
        $datap[ 21 ] = \$pcp3 ;
        $datap[ 22 ] = \$pcp6 ;
        $datap[ 23 ] = \$pcp24 ;
        $datap[ 24 ] = \$tmax ;
        $datap[ 25 ] = \$tmin ;
        &padarr( \@cc, 5, 8 ) ;
        $datap[ 26 ] = \@cc ;
        $datap[ 27 ] = \[ 0, 0, 0, 0, 0 ] ;
        &padarr( \@cloudtype, 5, 1 ) ;
        $datap[ 28 ] = \@cloudtype ;
        #&padstr( \$comment, 256 ) ;
        #$datap[ 29 ] = \$comment ;
        &padstr( \$raw, 256 ) ;
        $datap[ 29 ] = \$raw ;

        $result = NetCDF::recput( $ncid, $recnum, [ @datap ] ) ;
        #$result = NetCDF::recput( $ncid, $recnum, [ \$wmo_id ] ) ;
        #print STDOUT "NetCDF::recput result = $result\n" ;

        $recnum++ ;
        #last ;

   } # end of for ( @reports ) loop

   &cleanup() if( eof( STDIN ) ) ;

} # end while( 1 )
&cleanup();
exit( 0 ) ; #should never get here

sub cleanup
{

local( $sig ) = @_ ;

#print "Caught a SIG$sig --shutting down\n" if( $sig ) ;
$result = NetCDF::close( $ncid ) ;
#print STDOUT "NetCDF::close result = $result\n" ;

#close OUT ;      
exit( 0 ) ;

}

# pad str to correct length
sub padstr
{

( $str, $len ) = @_ ;

local( $size, $i ) ;

$size = length( $$str ) ;

for( $i = $size; $i < $len; $i++ ) {
        $$str .= "\0" ;
        #print "$$str,\n" ;
}

}

# pad arr to correct length
sub padarr
{

( $arr, $x, $y ) = @_ ;

local( $size, $i, $j ) ;

for( $i = 0; $i < $x; $i++ ) {
        $size = length( $$arr[ $i ] ) ;
        for( $j = $size; $j < $y; $j++ ) {
                $$arr[ $i ] .= "\0" ;
                #print STDOUT ",$$arr[ $i ],\n" ;
        }
}
}