#!/usr/bin/perl -w

# wwvb-fix.pl
# Read STDIN and try to adjust for WWVB cycle slips.  Data should be averaged
# over a long enough time that the cycle slip shows up between two adjacent
# readings.  Also attempts to deal with chart wraps.

# Copyright 2005 John Ackermann   Version: 16 April 2005
# May be freely used provided these notices are retained, and a copy
# of any modified version that's distributed to third persons is sent
# to jra@febo.com

use Getopt::Std;
use n8ur qw(round);

#----------
# display usage
my $opt_string = 'h';

sub usage() {
print STDERR << "EOF";

usage: $0 [-h]

-h	: this (help) message
EOF
}
#----------

getopts( "$opt_string", \my %opt ) or usage() and exit;

# print usage
usage() and exit if $opt{h};

my $reading;
my $mjd;
my $value;
my $last_value = 0;
my $first = 1;
my $valid = 1;
my $adjust = 0;

while ($reading=<STDIN>) {
	if (substr($reading,0,1) ne "#") {
		($mjd,$value) = split(/\s/,$reading);
		if ($value eq "") { $value = $last_value; }
		if ($value == 1e-9) { $value = $last_value; }
		if ($value == -1e-9) { $value = $last_value; }

		if ($first) {
			 $valid = 0;
			 }
		else {
			$valid = 1;
			}

		# first, adjust for 50us rollover
		if ($valid) {
			if ($value < ($last_value-4e-5)) {
				$value -= 5e-5;
			} else {
				if ($value > $last_value+4e-5) {
					$value += 5e-5;
				}
			}

			if ($value+$adjust < $last_value-1e-5) {
				$adjust += 1.666e-5;
			} else {
				if ($value+$adjust > $last_value+1e-5) {
					$adjust -= 1.666e-5;
				}
			}
		}

		$value += $adjust;
		$last_value = $value;
		$first = 0;
		printf "%s %12.12e\n",$mjd,$value;
	}
}
