#!/bin/bash
#
# This script modifies the gravity observations of a given input file with a
# normally (Gaussian) distributed distubation value.
#
# Dependencies on external programs:
#  gawk
#
# (C) 2008 Peter L. Smilde
#

#==============================================================================

function usage()
{
		echo "Usage: `basename $0` [-s stdev] [-d seed] [-h] inputfile outputfile"
}

function showhelp()
{
		usage
		echo
		echo " This script modifies the gravity observations of a given input file with a"
		echo " normally (Gaussian) distributed distubation value."
		echo " Inputfile must NOT be equal to outputfile!"
		echo
		echo " - Option -s standard deviation of disturbation of gravity value."
		echo " - Option -d initializes the random number generator with a (repeatable)"
		echo "     seed (positive integer)."
}

#==============================================================================

STDEV=1
SEED=-1

#-------------------------
# Get commandline options
#-------------------------

while getopts "s:d:h" OPTIONS ; do
		case $OPTIONS in
				s ) STDEV=$OPTARG;;
				d ) SEED=$OPTARG;;
				h ) showhelp; exit 0;;
				\? ) usage; exit 1;;
				* ) usage; exit 0;;
		esac
 
done
shift $(($OPTIND-1))

if [ $# -lt 2 ] ; then
		echo "ERROR: please enter the name of input and  output file."
		usage; exit 1 
else
		INFILE="$1"
		OUTFILE="$2"
fi

LANG=C;gawk -v s=$STDEV -v seed=$SEED '
function normdist (e,s,  __v1,__v2,__rr,__f) {
	if (have_spare==0) {
		do {
			__v1=2.*rand()-1.;
			__v2=2.*rand()-1.;
			__rr=__v1*__v1+__v2*__v2;
		}
		while (__rr>1. ||  __rr==0.);

		__f=sqrt(-2.*log(__rr)/__rr);
		spare=__v1*__f;
		have_spare=1;
		return e + s*__v2*__f;
	}
	else {
		have_spare=0;
		return e + s*spare;
	} 
}

BEGIN {
  if (seed<0) {
    srand();
  }
  else {
    srand(seed)
  }
}

/^[^!#]/ && NF>=7 {
	printf("%-4s%12.3f%12.3f%11.3f%11.3f%11.3f%6d\n", $1,$2,$3,$4+normdist(0,s),$5,$6,$7);
	next;
}

{
		print $0
}' "$INFILE" > "$OUTFILE"