#!/bin/csh -f
#+
#OSIRIS library of scripts
#
#NAME
#     osirisAutoRamp - configure exposure based on itime
#
#SYNOPSIS
#     osirisAutoRamp mode [-t #] [-m] itimeInSeconds
#
#DESCRIPTION
#     Determines optimal exposure ramp (configuration) based on the 
#     the integration time passed in as a float in seconds.  It then
#     sets the appropriate keywords: itime, sampmode, groups, reads.
#
#     Currently, the algorithm is as follows:
#
#     - MCDS will be used always.  
#     - The maximum number of read pairs that fit within the integration time
#       will be used up to the limit of 64.
#
#    This script assumes full frames.  Read time obtained from server 
#    (readtime keyword).
#
#OPTIONS
#     mode
#          specfies detector, "SPEC" or "IMAG".
#
#     itimeInSeconds
#	   specifies integration time seconds as a float
#
#     -t NUM
#          ID number to attach to all script generated errors, warnings, and
#          questions that are passed to the OGS.  The ID number is separated
#          from the rest of the message with a ";".
#
#     -m
#          simulate the exposure - do not actually set keywords. 
#          during simulated mode the setting of keywords will be 
#          echoed to the screen.
#
#
#
#EXAMPLES
#     osirisAutoRamp IMAG 5.7 -m
#          Takes 3 simulated IMAG exposures
#
#FILES
#     none
#
#SEE ALSO
#     ???
#-
#
# Modifcation History:
# 20041005 - MB: Copied from NIRC2 and adapted for OSIRIS
# 20041018 - MB: Added -t and -nw flags, expanded -s to be like take_dataset
# 20050911 - MB: Added support for LBWFS modes "Loop N" and "Infinite Loop"
# 20060413 - MB: Commented out lbwfs_time_check.txt stuff (was for testing)
#
# 20160308 - JLW: changed wfgo to upwfgo for OSIRIS Spec Upgrade
# 20180626 - jlyke: change osirisup to osiris
# 20190528 - jlyke: add numreads 8 option
# 20200626 - jlyke: keep numreads = 1 under 10 seconds
# 20210226 - jlyke: handle "0" exposure time, print exposure time if one arg
# Boiler plate for "-h" support for command autohelp.

if ("$1" == "-h") then
    help $0 | more
    exit $status
endif

# Boilerplate for syncheck.
# Note that the boiler plate should be transparent for all usages,
# but to make correct use of syncheck you will need to specify the
# correct pattern.

### need to figure out how make syncheck work with flags like "-s"...
#set noglob
#set CheckStatus = `syncheck -command $0 $* -pattern [SPEC,spec,IMAG,imag] {text int:1,9999999} {text} {text}` 
#unset noglob

#if ("$CheckStatus" != "OK") then
#    help $0
#    exit 1
#endif

# End of help/syncheck boiler plate.

# Set up to trap control-C
onintr ctrlc
### should also trap other interrupts (like kill, etc)

# TODO: chech argnum

# Decide if we should use SPEC or IMAG
set mode = $1
switch ($mode)
    case "SPEC":
    case "spec":
	set M = "s"
	set mode = "spec"
	breaksw
    case "IMAG":
    case "imag":
	set M = "i"
	set mode = "imag"
	breaksw
    default:
	osirisScriptMsg -T "${cmd} ${mode}: Specified mode must be SPEC or IMAG - aborting."
	exit 1
	breaksw
endsw
shift

if ($#argv == 0 ) then
  osirisTint $mode
  exit
endif

set itime=$1
shift

##echo mode=${mode}
##echo M=${M}
##echo itime=${itime}

set fcmd = $0
set cmd = ${fcmd:t}
set cmdpre=""
set cmdsuf=""
set idnum=0
# Check for more flags
set noglob
while ($#argv != 0)
##echo "${cmd} ${mode}: Checking ${1}..."
    switch ($1)
	case -t:
	    set CheckStatus = `syncheck -command $1 $2 -pattern int`
	    if ("$CheckStatus" == "OK") then
		set idnum = $2
		shift
	    else
		osirisScriptMsg -T "${cmd} ${mode}: Invalid script ID number"\
		    "specified <${2}> - using default."
	    endif
	    unset Checkstatus
	    breaksw

	case -m:
	    set sim
	    set cmdpre = "echo ${cmd} ${mode}: sim:"
	    set cmdsuf = "-m"
	    breaksw

	default:
	    osirisScriptMsg -T "${cmd} ${mode}: Invalid command line flag $1 specified."
	    osirisScriptMsg -T "${cmd} ${mode}: Usage: $0 mode itimeInSec [-t #] [-m]"
	    # set the error code for an error with command line input
	    exit 2
	    breaksw
    endsw
    shift
end
unset noglob

# number of allowed read pairs is 
# itime/readtime rounded down.
set readtime=`show -s o${M}ds -terse readtime`
osirisScriptMsg -t $idnum -T "${cmd}: Frame read time is ${readtime} seconds."
set fltreads=`math "${itime} / ${readtime}"`
set reads = `echo ${fltreads}  | cut -d. -f1`

set itimeInMs=`echo "${itime} * 1000" | bc | cut -d. -f1`

if (${itimeInMs} < 10000 ) then
  set reads = 1
else if (${itimeInMs} <= 60000) then 
  if (${reads} > 4) then 
    set reads = 4
  endif
else if (${itimeInMs} <= 120000) then
    set reads = 8
else if (${itimeInMs} <= 300000) then 
    set reads = 16
else
    set reads = 32
endif

#echo "readtime = ${readtime}"
#echo "itimeInMs= ${itimeInMs}"
#echo "reads = ${reads}"
#exit

$cmdpre modify -s o${M}ds sampmode=3
set error = $status
if ($error != 0) then
    osirisScriptMsg -t $idnum -T -W "${cmd}: Error setting samping mode to MCDS"
    exit $error
else
    osirisScriptMsg -t $idnum -T "${cmd}: Sampling mode set to MCDS."
endif

$cmdpre modify -s o${M}ds numreads=${reads}
set error = $status
if ($error != 0) then
    osirisScriptMsg -t $idnum -T -W "${cmd}: Error setting number of reads - aborting."
    exit $error
else
    osirisScriptMsg -t $idnum -T "${cmd}: reads set to ${reads}"
endif

# capture passing "0" as itime
if (${itimeInMs} == 0 ) then
  set tmin = `osirisTmin $mode`
  set itimeInMs=`echo "${tmin} * 1000" | bc | cut -d. -f1`
endif

$cmdpre modify -s o${M}ds itime=${itimeInMs}
set error = $status
if ($error != 0) then
    osirisScriptMsg -t $idnum -T -W "${cmd}: Error setting itime."
    exit $error
else
    osirisScriptMsg -t $idnum -T "${cmd}: ${mode} itime set to ${itimeInMs} ms."
endif


#TODO groups

goto done

ctrlc:

# Block of code to handle interrupts.
exit 1

done:
# is there anything that needs to go here?
exit