#!/usr/bin/perl -w

#  Program to extract annual precipitation from
#  NCDC TD3220 (Cooperative Summary of the Month) data sets

use strict;
my @stn=('050109','051121','051564','054082','054413','059243','141179','141699','143527','143837','145363','145856','145906','146378','147093','148495','250640','250810','252065','252690','253365','253735','253910','254110','255090','255310','255565','256480','256585','257070','258255','258320','258735','259020');
my %stn = (
   '050109' => "Akron 4 E",
   '051121' => "Burlington",
   '051564' => "Cheyenne Wells",
   '054082' => "Holyoke",
   '054413' => "Julesburg",
   '059243' => "Wray",
   '141179' => "Burr Oak 1 N",
   '141699' => "Colby 1SW",
   '143527' => "Hays 1 S",
   '143837' => "Hoxie",
   '145363' => "Minneapolis",
   '145856' => "Norton 9 SSE",
   '145906' => "Oberlin1 E",
   '146374' => "Phillipsburg 1 SSE",
   '146378' => "Phillipsburg #2",
   '147093' => "Saint Francis",
   '148495' => "Wakeeny",
   '250640' => "Beaver City",
   '250810' => "Bertrand",
   '252065' => "Culbertson",
   '252690' => "Elwood 8 S",
   '253365' => "Gothenburg",
   '253735' => "Hebron",
   '253910' => "Holdredge",
   '254110' => "Imperial",
   '255090' => "Madrid",
   '255310' => "McCook",
   '255565' => "Minden",
   '256480' => "Palisade",
   '256585' => "Paxton",
   '257070' => "Red Cloud",
   '258255' => "Stratton",
   '258320' => "Superior",
   '258735' => "Upland",
   '259020' => "Wauneta 3 NW",
   );

#  Read average monthly precip
my %avg;
if (@ARGV>0 && $ARGV[0] eq '-a')
{
   shift @ARGV;
   open(DAT , "<avgmo.ppt") || die "Cannot open file avgmo.ppt";
   while (my $line = <DAT>)
   {
      my ($stn,@avg) = split(' ',$line);
      $avg{$stn} = [undef,@avg];
   }
   close(DAT);
}

#  Process command line
(@ARGV>0) || die "Usage:  $0 [-a] <year> [stn:per=val]\n";
my $yr = shift @ARGV;

#
#  Initialize data structures
#
my %ppt;
foreach my $stn (@stn)
{
   $ppt{$stn}{$yr} = undef;
}

#
#  Create fill hash
#
my %fill;
foreach my $fill (@ARGV)
{
   ($fill =~ /^(\d+):(.*)=(.*)$/) || die "Invalid stn:per=val\n";
   my ($stn,$per,$val) = ($1,$2,$3);
   exists($ppt{$stn}) || die "Unknown station $stn\n";
   if ($per =~ /^(\d+)\/(\d+)$/)
   {
      $fill{$stn}{$2}{$1} = $val;
   }
   else
   {
      $ppt{$stn}{$per} = $val;
   }
}

#
#  Read TD3220 data
#
open(TD , "<TD3220") || die "Cannot open data file TD3220\n";
while (my $line = <TD>)
{
   #  Get station, data type and year
   my $stn  = substr($line,3,6);
   exists($ppt{$stn}) || next;
   my $type = substr($line,11,4);
   my $unit = substr($line,15,2);
   ($type eq 'TPCP') || next;
   ($unit eq 'HI') || die "Odd units $type $unit\n$line\n";
   my $yr = substr($line,17,4);
   exists($ppt{$stn}{$yr}) || next;
   #  Extract data
   my $n  = substr($line,27,3);
   my ($ann,$sum);
   my %mo = ('01'=>1,'02'=>1,'03'=>1,'04'=>1,'05'=>1,'06'=>1,'07'=>1,'08'=>1,'09'=>1,'10'=>1,'11'=>1,'12'=>1);
   for (my $k=0;$k<$n;$k++)
   {
      my $mo = substr($line,12*$k+30,2);
      (substr($line,12*$k+32,2) eq '00') || warn "Month does not end in 00\n";
      my $val = substr($line,12*$k+34,6)/100;
      if ($mo == 13)
      {
         $ann = $val;
      }
      else
      {
         $sum += $val;
         delete $mo{$mo};
      }
   }
   defined($ann) && defined($sum) && (abs($ann-$sum)<=0.01 || warn "ANN MISMATCH $stn:$ann $sum\n");
   #  Check for fills
   foreach my $mo (keys %mo)
   {
      exists($fill{$stn}{$yr}{$mo}) || next;
      $sum += $fill{$stn}{$yr}{$mo};
      delete $mo{$mo};
   }
   #  Check for averages
   foreach my $mo (keys %mo)
   {
      exists($avg{$stn}) || next;
      $sum += $avg{$stn}[$mo];
      delete $mo{$mo};
   }
   #  Check results
   defined($ann) || defined($sum) || die "Record with no data $stn $yr\n";
   $ppt{$stn}{$yr} = $sum;
   (%mo) && warn "$stn ($stn{$stn}) missing ",join(' ',map {"$_/$yr"} sort keys %mo)."\n";
}
close(TD);

#
#  Check if all stations were found
#
foreach my $stn (@stn)
{
   unless (defined($ppt{$stn}{$yr}))
   {
      warn "No data for $stn $yr\n";
      $ppt{$stn}{$yr} = 0;
   }
}

#  Output data
print $yr;
foreach my $stn (@stn)
{
   printf "%8.2f" , $ppt{$stn}{$yr};
}
print "\n";
