#!/bin/sh
#
# addi2run -- add imaging data to run files
#
# Usage:  addi2run [-s wfnum] [-u 'units'] [-a] [-b] [-i] runfile imgfile
#
# where:  -s wfnum	specifies the waveform number for the frame sync
#			pulse signal
#			(default is to look for the first waveform with
#			 "sync" in its name, or else just the first waveform)
#	  -u 'units'	specifies the units in which the imaging data are given
#			(default is "deltaF/F")
#	  -a		specifies the imaging data values are repeated after
#			each sync pulse, up to the next pulse
#	  -b		specifies the imaging data values are repeated before
#			each sync pulse, up to the previous pulse
#	  -i		specifies the imaging data values are interpolated
#			between sync pulses (default mode)
#			(any combination of these 3 modes can be used and
#			 a waveform is generated for each one)
#	  runfile	specifies the name of the run file to be modified
#	  imgfile	specifies the name of the ASCII file containing the
#			imaging data
#
# Imaging data file format is a multi-column, tab delimited, ASCII text file.
# First line is column headings, rest are data values.  First column is time
# in seconds for each "frame", with 0.00 as the first frame.  Rest of columns
# are intensity values expressed as deltaF/F averaged from one or more regions
# of interest.  Intensity values are assumed to be no larger than +/- 655.
#
# Imaging data samples will be aligned to sync pulses on the frame sync
# waveform, and upsampled to at least 1/20 the rate of that signal using linear
# interpolation between sync pulses and zero-padding the signal at both ends,
# by default.  If the -a or -b mode options are used, imaging data samples
# are instead repeated after or before their corresponding sync pulses, up to
# the next or previous pulse.  If more than one of the -a, -b or -i options
# is specified, addi2run will generate a waveform using each of the requested
# methods.
#
# Copyright (c) 2006-8, Gilles Detillieux, Spinal Cord Research Centre,
# University of Manitoba.  All Rights Reserved.
#

swfnum=
units="deltaF/F"
modes=
while :
do
	case "$1" in
	-\?|-help|--help)	sed -n '3,/^# Univ/s/^#/ /p' "$0"; exit ;;
	-s[0-9]*)	swfnum=`expr "x$1" : 'x-s\(.*\)'`; shift ;;
	-s)	shift; swfnum="$1"; shift ;;
	-u[0-9]*)	units=`expr "x$1" : 'x-u\(.*\)'`; shift ;;
	-u)	shift; units="$1"; shift ;;
	-[abi]*)	modes="$modes"`expr "x$1" : 'x-\([abi]*\).*'`; shift ;;
	-*)	set --; break ;;
	*)	break ;;
	esac
done

if [ "$#" -ne 2 ]
then
	echo "Usage:  $0 [-s wfnum] [-u 'units'] [-a] [-b] [-i] runfile imgfile
	or  $0 --help  for detailed usage information" >&2
	exit 1
fi

rfile="$1"
ifile="$2"
if [ ! -r "$ifile" ]
then
	echo "$0: Can't read imaging data file: $ifile" >&2
	exit 1
fi

lastwf=`dumprun "$rfile" | sed -n '1,/^WF /d; s/^ //; / uV /s/  .*//p' | tail -1`
case "$lastwf" in
"")	echo "$0: Can't find last waveform in $rfile" >&2
	exit 1
	;;
esac

test -z "$swfnum" &&
  swfnum=`dumprun "$rfile" | sed -n '1,/^WF /d; s/^ //; / uV .*[Ss][Yy][Nn][Cc]/{s/  .*//p; q;}'`
test -z "$swfnum" &&
  swfnum=`dumprun "$rfile" | sed -n '1,/^WF /d; s/^ //; / uV /{s/  .*//p; q;}'`

case "$swfnum" in
"")	echo "$0: Can't find sync waveform in $rfile" >&2
	exit 1
	;;
[0-9]*)	;;
*)	echo "$0: Invalid number for spike waveform: -s $swfnum" >&2
	exit 1
	;;
esac

syncs=`sysvecho "sf${rfile}\nnnqw${swfnum}\nssvdqqk\nqsswn$swfnum}\nqqgnnqcw-1\nqdutpqnPULSE=x\\\\\\\\n\nqqagavpb\nqyn" |
	TERM=dumb DISPLAY= analysis 2>/dev/null | sed -n 's/^ *PULSE=//p'`
case "$syncs" in
"")	echo "$0: Can't find sync pulses on waveform $swfnum in $rfile" >&2
	exit 1
	;;
esac

ptsdiv=`dumprun "$rfile" | sed -n '1,/^WF /d; s/^ //; /^'"$swfnum"' .* uV /p'`
swdiv=`echo "$ptsdiv" | awk '{print $3}'`
test -z "$swdiv" && swdiv=1
swdiv=`echo \""$syncs"\" |
	awk '{ if (NR > 1) s += $1-last; last = $1; }
	     END {
		sd = '\""$swdiv"\"';
		d = 20;
		if (NR > 1) {
		    s /= NR-1;
		    while (d > s/sd/2) {
			if (d > 5)
			    d -= 5;
			else
			    --d;
		    }
		}
		print d;
	     }'`

case "$rfile" in
*.frm)	rfile=`expr "$rfile" : '\(.*\)\.frm'` ;;
esac

case "$modes" in
"")	modes=i ;;
esac
modecnt=`echo "$modes" | wc -c | tr -d ' \011'`

column=0
tr '\015' '\012' < "$ifile" | head -1 | tr '\011' '\012' |
  while read label
  do
    column=`expr $column + 1`
    case "$label" in
    Time*)	continue ;;
    esac
    modelist=$modes
    while [ -n "$modelist" ]
    do
	mode=`expr "$modelist" : '\(.\).*'`
	modelist=`expr "$modelist" : '.\(.*\)'`
	wlabel=$label
	if [ "$modecnt" -gt 1 ]
	then
		case "$mode" in
		a)	wlabel="$wlabel [after]" ;;
		b)	wlabel="$wlabel [before]" ;;
		*)	wlabel="$wlabel [interp]" ;;
		esac
	fi
	lastwf=`expr $lastwf + 1`
	if [ "$lastwf" -gt 99 ]
	then
		echo "$0: Reached last available waveform number before '$wlabel' in $ifile" >&2
		exit 1
	fi
	fwf=$lastwf
	if [ "$fwf" -le 9 ]
	then
		fwf="0$fwf"
	fi
	echo "Creating $rfile.w$fwf: $wlabel..." >&2
	# Create new waveform file using divisor of $swdiv (default 20):
	sysvecho "sf${rfile}\nnnqmfw${swfnum}\nd${swdiv}\ng${lastwf}\nqqcw${lastwf}\nl1000\nh50\nz0\nn${wlabel} (mV=${units})\nqsqqyn" |
		TERM=dumb DISPLAY= analysis 2>/dev/null
	ptsdiv=`dumprun "$rfile" | sed -n '1,/^WF /d; s/^ //; /^'"$lastwf"' .* uV /p'`
	pts=`echo "$ptsdiv" | awk '{print $2}'`
	div=`echo "$ptsdiv" | awk '{print $3}'`
	if [ -z "$pts" -o -z "$div" -o ! -r "$rfile.w$fwf" ]
	then
		echo "$0: Can't create/use waveform number $lastwf for '$wlabel' in $ifile" >&2
		exit 1
	fi

	(echo "$syncs"; tr '\015' '\012' < "$ifile") |
	    LOCALE=C LANG=C LC_CTYPE=C \
	       awk 'BEGIN {
			nsync = 0; nimg = 0;
			col = '"$column"'; pts = '"$pts"'; div = '"$div"';
			mode = "'"$mode"'";
		    }
		    NF == 1 && $1 ~ /[0-9]/ { sync[nsync++] = $1/div }
		    /^Time/ { next }
		    /^$/ { next }
		    NF > 1 { img[nimg++] = $(col) }
		    END {
			soff = 0; ioff = 0;
			if (nsync > nimg)
			    soff = nsync-nimg;
			else if (nimg > nsync)
			    ioff = nimg-nsync;
			off = 0;
			for (i = 0; i < pts; i++) {
			  while (soff+off < nsync-1 && sync[soff+off+1] < i)
			    ++off;
			  if (mode == "a") {
			    while (soff+off < nsync-1 && sync[soff+off+1] <= i)
				++off;
			    if (i < sync[soff]-1)
				v = 0;
			    else
				v = img[ioff+off];
			  } else if (mode == "b") {
			    while (soff+off < nsync-1 && sync[soff+off+1] <= i)
				++off;
			    if (i < sync[soff]-1)
				v = img[ioff+off];
			    else if (i > sync[nsync-1]+1)
				v = 0;
			    else
				v = img[ioff+off+1];
			  } else {
			    if (i < sync[soff]-1 || i > sync[nsync-1]+1)
				v = 0;
			    else
				v = img[ioff+off] + (img[ioff+off+1]-img[ioff+off]) * (i-sync[soff+off]) / (sync[soff+off+1]-sync[soff+off]);
			  }
			  v = int(v*50);
			  printf("%c%c", int(v / 256 + 256) % 256, (int(v)+65536) % 256);
			}
		    }' - > "$rfile.w$fwf"
    done
  done

#print "mode=" mode ", i=" i ", off=" off ", v=" v >> "/dev/stderr"
#print "mode=" mode ", col=" col ", pts=" pts ", div=" div >> "/dev/stderr"
#print "nsync=" nsync, "nimg=" nimg, "soff=" soff, "ioff=" ioff, "pts=" pts, "div=" div, "sync[" nsync-1 "]=" sync[nsync-1], "img[" nimg-1 "]=" img[nimg-1] >> "'"$rfile-w$fwf"'.txt"
