#!/bin/sh
#
# coherence - calculate and plot coherence analysis of two waveforms in run
#
# Usage:  coherence [-w wn1,wn2] [-f freq] [-r st,en] [-p plttype] runfile ...
#
# where:  -w wn1,wn2	specifies the waveform numbers for the two waveforms,
#			separated by a comma
#			(default is 0,1)
#	  -f freq	specifies frequency to which you want each waveform
#			downsampled, where frequencies up to half of this will
#			be plotted (default is the full sample rate of first WF)
#	  -r st,en	specifies start and end of the analysis range, in sec.
#			(default is taken from analysis parameters, or all)
#	  -p plttype	specifies type of plot file generated: plt, gif, png,
#			svg, eps, or pdf (default is plt, for HPGL output)
#			you can also use "x" to display the plot via xhpgl
#			rather than saving it, or "-" to send HPGL to stdout,
#	  runfile	specifies one or more run file names to be measured
#			(no default, runfile must be specified)
#
#			If a specified runfile is actually CSV text data,
#			rather than a run, the waveform numbers specified by
#			the -w option select the columns of data from the CSV
#			file, the -f option specifies the actual sampling rate
#			of the data in the file, not a downsampling rate, and
#			the -r option is ignored.
#
# coherence performs a specturm analysis on the specified waveforms using
# David M. Halliday's NeuroSpec 2.0 software (http://www.neurospec.org/).
# A coherence graph is generated for each runfile, using the specified range.
# Each graph (one per runfile) is stored in runfile-wnn-nn-coh.plt, unless an
# alternate format is selected by the -p option.  The nn parts of the file name
# are the two 2-digit waveform numbers.  It will append -rst-en after the
# waveform number, if a time range is given with the -r option, where st and en
# are the start and end times. The cumulant density vs lag graph is included
# in the same output plot file as the coherence vs frequency graph.
#
# E.g.:  coherence -w 0,7 -f 500 aojedro4damp02
#	 coherence -p svg -w 4,5 -f 2000 -r 8,20 cell8-05
#
# Copyright (c) 2016, Gilles Detillieux, Spinal Cord Research Centre,
# University of Manitoba.  All Rights Reserved.
#

nspecdir=`locate psp_ch1cl.m 2>/dev/null | sed -n 's|/[^/]*\.m$||p' | head -1`
case "$nspecdir" in
"")	echo "coherence: Can't locate psp_ch1cl.m module from NeuroSpec" >&2
	exit 1
	;;
esac
ov=`octave --version | sed -n '1{s/.* //;s/\.//g;p;q;}'`
ovm=`octave --version | sed -n '1{s/.* //;s/\..*//;p;q;}'`
lwfnum=0,1
ropt=
gwfopt=
fftopt=
plttype=plt
while :
do
	case "$1" in
	-\?|-help|--help)	sed -n '3,/^# Univ/s/^#/ /p' "$0"; exit ;;
	-w)	shift; lwfnum="$1"; shift ;;
	-w[0-9]*)	lwfnum=`expr "x$1" : 'x-w\(.*\)'`; shift ;;
	-f)	shift; gwfopt="$gwfopt -f$1"; shift ;;
	-f[0-9]*)	gwfopt="$gwfopt $1"; shift ;;
	-r)	shift; gwfopt="$gwfopt -r$1"; ropt="-r$1"; shift ;;
	-r[0-9]*)	gwfopt="$gwfopt $1"; ropt="$1"; shift ;;
	-p)	shift; plttype="$1"; shift ;;
	-p[A-Za-z]*)	plttype=`expr "x$1" : 'x-p\(.*\)'`; shift ;;
	-*)	set --; break ;;
	*)	break ;;
	esac
done

case "$#" in
0)	echo "Usage:  coherence [-w wn1,wn2] [-f freq] [-r st,en] [-p plttype] runfile ...
	or coherence --help	for detailed usage information" >&2; exit 1 ;;
esac

case "$lwfnum" in
[0-9]*\,[0-9]*)	;;
*)	echo "$0: Invalid pair of waveform numbers: -w $lwfnum" >&2
	exit 1
	;;
esac

density=
tsuff="$plttype"
#plttype=`expr "$plttype" : '\([^,]*\),*.*'`
case "$plttype" in
-)	tsuff=tmp.plt ;;
x)	tsuff=tmp.plt ;;
plt)	;;
svg)	;;
eps)	;;
gif)	tsuff=tmp.eps density="-density 140" ;;
png)	tsuff=tmp.eps density="-density 140" ;;
pdf)	tsuff=tmp.eps ;;
*)	echo "$0: Invalid plottype: -p $plttype" >&2
	exit 1
	;;
esac

T=`mktemp /tmp/whXXXXXXX`
trap 'rm -f $T' 0
trap 'exit 1' 1 2 3 13 15

results=0
numruns=$#
ropt=`echo "$ropt" | tr ',' '-'`
for run
do
	test $# -gt 1 && echo "Analysing $run..." >&2
	lwst="W.F. $lwfnum"
	lwfnums=`echo "$lwfnum" | tr ',' ' '`
	#numwfs=`echo "$lwfnums" | wc -w`
	ft=`file "$run" 2>/dev/null`
	case "$ft" in
	*text*)	# assume CSV text file...
		case "$lwfnum" in
		0,1)	# we want columns 1,2 for csv data
			lwfnums="1 2"
			;;
		esac
		lwst="columns `echo $lwfnums | tr ' ' ','`"
		;;
	esac
	rfile=`echo "$run" | sed 's/\.frm$//'`
	fwfs=
	w=w
	for wfnum in $lwfnums
	do
		fwf=$wfnum
		case "$fwf" in [0-9])	fwf="0$fwf" ;; esac
		fwfs="$fwfs-$w$fwf"
		w=
	done
	#ofile="$rfile$fwfs$ropt-coh.csv"
	pfile="$rfile$fwfs$ropt-coh.$plttype"
	tfile="$rfile$fwfs$ropt-coh.$tsuff"
	case "$tsuff" in tmp.*) tfile=$T ;; esac
	ptype=`echo "$tsuff" | sed 's/tmp.//'`
	gp=
	case "$ptype" in
	eps)	ptype=epsc2 ;;
	plt)	ptype=hpgl
		# Octave 3.8.x & up don't need gnuplot, but HPGL output needs
		# pstoedit when not using gnuplot. pstoedit not easily available
		# on RHEL 7, so use gnuplot for HPGL...
		if [ "$ovm" -gt 3 -o "$ov" -ge 380 ]
		then
			gp='graphics_toolkit("gnuplot");'
		fi
		;;
	esac
	echo "Getting $lwst from $rfile..." >&2
	case "$ft" in
	*text*)	# assume CSV text file...
	  f=$gwfopt
	  case "$f" in
	  *-f[0-9]*)	;;
	  *)	f='-f10000'
		echo "No -f specified for $rfile, assuming $f." >&2
		;;
	  esac
	  echo getwfdata -h $f "$rfile" $lwfnums |
	    cat - "$rfile" |
	    awk -F, '/getwfdata.* -f/ {
			f=$0; sub(/^.* -f/, "", f); sub(/ .*/, "", f);
			r=1.0/f;
			c1=$0; sub(/  *[0-9][0-9]*$/, "", c1); sub(/^.* /, "", c1);
			c2=$0; sub(/^.* /, "", c2);
		 }
		 NR>1 { printf("%g,%g,%g\n",(NR-2)*r,$(c1),$(c2)); }' \
	    > "$T"
	  ;;
	*)	# assume run file...
	  getwfdata -h $gwfopt "$rfile" $lwfnums |
	    awk -F, '/getwfdata.* -f/ {
			f=$0; sub(/^.* -f/, "", f); sub(/ .*/, "", f);
			r=1.0/f;
		 }
		 NR>2 { printf("%g,%g,%g\n",(NR-3)*r,$1/1000.0,$2/1000.0); }' \
	    > "$T"
	  ;;
	esac
	if [ -s "$T" ]
	then
		results=`expr $results + 1`
		bn=`basename "$rfile" .prm`
		title="$bn, $lwst"
		echo "Coherence analysis on $lwst from $rfile..." >&2
		octave --traditional ${nspecdir:+--path} ${nspecdir} >&2 <<!
$gp
cohdata=load('-ascii','$T');
freq=1.0/(cohdata(2,1)-cohdata(1,1));
seg_pwr=10;	% frequency resolution
nyq=freq/2;	% nyquist frequency
ch_max=0.5;	% upper limit for coherence estimate
lag=100;	% total lag range for time domain including -ve lags (ms)
[f,t,cl]=sp2a2_m1(0,cohdata(:,2),cohdata(:,3),freq,seg_pwr,'');
cl.what='$title';
figure;
subplot(2,1,1);
psp_ch1(f,cl,nyq,ch_max);
subplot(2,1,2);
psp_q1(t,cl,lag,lag/2);
print('$tfile','-d$ptype');
!
		case "$tsuff" in
		svg)	if ! grep -s "xmlns=" "$pfile" >/dev/null
			then
				# add missing style info to gnuplot svg output:
				sed -i -e \
		's,xmlns:,xmlns="http://www.w3.org/2000/svg" &,' "$pfile"
			fi ;;
		tmp.*)	mysuff=`expr "$tsuff" : 'tmp.\(.*\)'`
			# octave 3.8.x & up add suffix to temp. file...
			if [ -s "$tfile.$mysuff" ]
			then
				tfile="$tfile.$mysuff"
			elif [ -s "$tfile.$ptype" ]
			then
				tfile="$tfile.$ptype"
			fi
			case "$plttype" in
			-)	cat "$tfile" ;;
			x)	xhpgl "$tfile" ;;
			*)	convert $density "$tfile" "$pfile" ;;
			esac
			rm -f "$tfile" ;;
		esac
		case "$plttype" in
		[-x])	;;
		*)	test -s "$pfile" &&
			    echo "Generated '$pfile'." >&2 ;;
		esac
	fi
	numruns=`expr $numruns - 1`
	test $numruns -gt 0 && echo "" >&2
done

test "$results" -gt 0 || exit 2
