#!/bin/perl

# Sticking together of TTxx and IIxx decoding.
# (c) WMConnolley (http://www.nerc-bas.ac.uk/public/icd/wmc/) April 1996.
#
# Disclaimer: this routine is not guaranteed to work. 
#       It works with perl 4. Program may be freely used
#       for non-commercial purposes but not for commercial use. No
#       redistribution without this header.
#       Please mail me (wmc@bas.ac.uk) with bugs and flaws (but not with
#       ideas for extras).

# Purpose: take the decoded output of "temps1.pl" and stick together
# the A, B, C and D groups. Expects input preceeded by id (see temps1.pl)
# so that multiple stations can be piped

# Use: stick1.pl options filenames
# Input: expects input as formatted by "temps1.pl"
#   Searches for "%" as first character to allow temps1.pl to pass along error
#   messages
# Example: stick1.pl dew=1 89009.14.12.??.temp
# Output: to STDOUT
# See-also: temps1.pl for the decoding step
# Restrictions: you need PERL and temp1.pl
#             : guessing tens-of-thousands figure for height may be a touch dodgy

#
# Begin Code
#

# Set command-line switches (see PERL book p256!)
# Sensible ones are:
#   kelvin=1 (or any other value, in fact) - write T in kelvin
#   dew=1 - write dew point depression as dew point value
eval "\$$1=\$2" while $ARGV[0] =~ /^(\w+)=(.*)/ && shift;

while (<>) {
  if (/^%/) {print "$_\n"; next};
  s/Sfc: //;
  ($id, $p, $h, $t, $td, $d, $s)=split;
# A little check on p
  if ($p && $p <= 0) {print "Ignoring strange pressure: /$p/\n";}
# If we have this level already, may use old values
  else {if ($a{$id."/".$p}) {
    ($h1, $t1, $td1, $d1, $s1)=split(/ /,$a{$id."/".$p});
    $h=$h1 if ($h eq -999);
    $t=$t1 if ($t eq -999);
    $td=$td1 if ($td eq -999);
    $s=$s1 if ($s eq -999);
    $d=$d1 if ($d eq -999);
  }
  $rest=join(' ',($h, $t, $td, $d, $s));
  $a{$id."/".$p}=($rest)};
};

$last_h=0; $psave=1000; $tsave=250; $hsave=0;
foreach $key (sort numeric keys(%a)) {
  ($h, $t, $td, $d, $s)=split(/ /,$a{$key});
  ($id, $p)=split('/',$key);
  if (!$a{$id}) {print "$id\n"; $a{$id}=1; $last_h=0};
  $tk=$t+273.16;
  if ($kelvin) {$t=$t+273.16 unless $t eq "-999"};
  if ($dew) {$td=$t-$td unless $td eq "-999"};
  if ($h != -999 && $p < 500.) {
# Need to guess tens-of-thousands figure for height, above 500 hPa.
# Kluge hydrostatic equation
    if ($t != -999) {$tbar=($tk+$tsave)/2} else {$tbar=$tsave};
    $dp=$psave-$p; $pbar=($psave+$p)/2.;
    $tens=int(287.*$tbar/9.8*$dp/$pbar/10000);
# And make sure that they are at least monotonic!
    $h=$h+$tens*10000;
    while ($h < $last_h) {$h=$h+10000};
  };
  $last_h=$h unless ($h == -999);
  if ($d != -999) {$d=int($d+.5)} else {$d=int($d)};
  if ($s != -999) {$s=int($s+.5)} else {$s=int($s)};
  printf "%6.1f %7.1f %6.1f %6.1f %4d %4d \n", $p, $h, $t, $td, $d, $s;
# Remember the last valid pressure-temperature-height level, for guessing h
  if ($h != -999 && $t != -999) {$psave=$p; $tsave=$tk; $hsave=$h};
}

# Need this to do "numeric" not alphabetic sort
sub numeric {
  ($bid,$bp)=split('/',$b);
  ($aid,$ap)=split('/',$a);
  if ($bid lt $aid) {return 1} 
  else {if ($bid gt $aid) {return -1}
  else {($bp <=> $ap)}}
}
