#!/bin/csh -f
#+
#OSIRIS library of scripts
#
#NAME
#     move - basic move telescope command for osiris (in instr coords)
#
#SYNOPSIS
#     osirisMoveTel mode1 [scale1] [filt1] x1 y1 mode2 [scale2] [filt2] x2 y2
#                   file [filename]
#
#DESCRIPTION
#     this script will issue the proper xy move to the telescope to move an
#     object to/from any pixel on the osiris imager or spectrograph.  this
#     accounts for the small sky offsets between the spectrograph scales, and
#     for the variable spectrograph field of view with different narrowband
#     filters.
#
#     this script is primarily designed to be called from the OTGUI, but
#     may be called from the command line if desired.
#
#OPTIONS
#     mode1, mode2
#          imag or spec
#
#     scale1, scale2
#          required if mode is spec [0.100, 0.050, 0.035, 0.020]
#          not present for imag
#
#     filt1, filt2
#          required if mode is spec
#          not present for imag
#
#     x1 y1
#          "from" coordinates, lenslets if mode is spec, pixels if mode is imag
#          can use [c, ctr, center] instead of a number.
#          decimal coords ARE allowed for lenslets, but decimal coords ARE NOT
#          allowed for imager pixels.  if decimal pixels are given, they are
#          automatically truncated to the integer-only part.
#
#     x2 y2
#          "to" coordinates - see description for x1 y1
#
#     file [filename]
#          filename to log telescope moves to, if desired
#
#     -m
#          simulate calls to RPC servers.  during simulated calls, the 
#          command is echoed (instead of being executed).
#
#EXAMPLES
#     osirisMoveTel imag 400 400 spec 0.035 Kn4 35 40
#          moves an object at imager pixel 400,400 to spectrograph pixel
#          35,40 in 0.035"/lenslet and Kn4 filter
#
#ENVIRONMENT VARIABLES
#     none
#
#FILES
#     osirisSpecCenters.dat, osirisScaleOffsets.dat
#
#SERVERS & KEYWORDS
#     none
#
#SCRIPTS CALLED
#     help, syncheck, osirisScriptMsg, osirisCoordI2S, xy
#
#EXIT STATUS
#     0 - normal exit, no error
#     1 - script aborted by an interrupt
#     2 - syncheck error
#     3 - error parsing command line input
#     other errors...
#
#SEE ALSO
#     ???
#-
#
# Modification History:
# 20050222 - MB: Initial version created
# 20051118 - MB: Fixed algorithm to allow centering in all SPEC NB filters
# 20051119 - MB: Added info line before issuing xy command
# 20080304 - JLW: Updated filter list with new pupil filters
# 20080514 - jlyke: chg fgrep to awk to avoid returning multiple lines
# 20120420 - ksummers: added file option to allow moves to be logged
# 20181020 - jlyke: new imager 2kx2k
#

# 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.

# A more detailed error checking is performed on the arguments below...

# Set these variables for testing
#set test
#set simall

# Set up to trap interrupts (Ctrl-C, etc.)
onintr abort

# Set default variable values
set fcmd = $0
set cmd = ${fcmd:t}
set sfiltlist = "[Jbb,Hbb,Kbb,Zbb,Kcb,Jn1,Jn2,Jn3,Jn4,Hn1,Hn2,Hn3,Hn4,Hn5,Kn1,Kn2,Kn3,Kn4,Kn5,Zn4,Kc3,Kc4,Kc5,Drk]"
set sscalelist = "[0.100,0.10,0.1,0.050,0.05,0.035,0.020,0.02]"
set sscale1 = ""
set sfilter1 = ""
set sscale2 = ""
set sfilter2 = ""
set Xc1 = 0 # coords of center visible lenslet/pixel for mode1
set Yc1 = 0 # coords of center visible lenslet/pixel for mode1
set Xc2 = 0 # coords of center visible lenslet/pixel for mode2
set Yc2 = 0 # coords of center visible lenslet/pixel for mode2
set Xsref1 = 0 # spec lenslet referenced to 0,0 in instr coords xcoord1
set Ysref1 = 0 # spec lenslet referenced to 0,0 in instr coords ycoord1
set Xsref2 = 0 # spec lenslet referenced to 0,0 in instr coords xcoord2
set Ysref2 = 0 # spec lenslet referenced to 0,0 in instr coords ycoord2
set Xsoff1 = 0 # offset (arcsec) between ref lenslet and 0.020 ref lenslet
set Ysoff1 = 0 # offset (arcsec) between ref lenslet and 0.020 ref lenslet
set Xsoff2 = 0 # offset (arcsec) between ref lenslet and 0.020 ref lenslet
set Ysoff2 = 0 # offset (arcsec) between ref lenslet and 0.020 ref lenslet
set Xicp = 1024  # imager center x-pixel
set Yicp = 1024  # imager center y-pixel
set cmdpre = ""
set cmdsuf = ""
set datfiledir = "$KROOT/rel/default/data"
set specfiltctrfile = "${datfiledir}/osirisSpecCenters.dat"
set specscaleoffsetfile = "${datfiledir}/osirisScaleOffsets.dat"
set filename = ""

# Get and check the command line arguments
set noglob

# Check the first "mode" argument
set CheckStatus = `syncheck -command $0 $1 -pattern [imag,spec]`
if ("$CheckStatus" == "OK") then
    set mode1 = $1
    shift
else
    osirisScriptMsg -T "${cmd}: Unknown mode1 specified <${1}> - script"\
	"aborted."
    exit 3
endif

# Get and check the scale and filter if mode1=spec
if ("$mode1" == "spec") then
    set CheckStatus = `syncheck -command $0 ${argv[1-2]} -pattern $sscalelist $sfiltlist`
    if ("$CheckStatus" == "OK") then
	set sscale1 = $1
	shift
	set sfilter1 = $1
	shift
    else
	osirisScriptMsg -T "${cmd}: Invalid spec scale1 or filter1 specified"\
	    "- script aborted."
	exit 3
    endif
endif

# Get and check the first x coordinates
if (("$1" == "c") || ("$1" == "ctr") || ("$1" == "center")) then
    set x1 = "c"
else
    set CheckStatus = `syncheck -command $0 $1 -silent -pattern float`
    set error = $status
    if ($error == 0) then
	set x1 = $1
    else
	osirisScriptMsg -T "${cmd}: Invalid x1 coordinates specified <${1}> -"\
	    "script aborted."
	exit 3
    endif
endif
shift

# Get and check the first y coordinates
if (("$1" == "c") || ("$1" == "ctr") || ("$1" == "center")) then
    set y1 = "c"
else
    set CheckStatus = `syncheck -command $0 $1 -silent -pattern float`
    set error = $status
    if ($error == 0) then
	set y1 = $1
    else
	osirisScriptMsg -T "${cmd}: Invalid y1 coordinates specified <${1}> -"\
	    "script aborted."
	exit 3
    endif
endif
shift
unset CheckStatus


# Check the second "mode" argument
set CheckStatus = `syncheck -command $0 $1 -pattern [imag,spec]`
if ("$CheckStatus" == "OK") then
    set mode2 = $1
    shift
else
    osirisScriptMsg -T "${cmd}: Unknown mode2 specified <${1}> - script"\
	"aborted."
    exit 3
endif

# Get and check the scale and filter if mode2=spec
if ("$mode2" == "spec") then
    set CheckStatus = `syncheck -command $0 ${argv[1-2]} -pattern $sscalelist $sfiltlist`
    if ("$CheckStatus" == "OK") then
	set sscale2 = $1
	shift
	set sfilter2 = $1
	shift
    else
	osirisScriptMsg -T "${cmd}: Invalid spec scale2 or filter2 specified"\
	    "- script aborted."
	exit 3
    endif
endif

# Get and check the first x coordinates
if (("$1" == "c") || ("$1" == "ctr") || ("$1" == "center")) then
    set x2 = "c"
else
    set CheckStatus = `syncheck -command $0 $1 -silent -pattern float`
    set error = $status
    if ($error == 0) then
	set x2 = $1
    else
	osirisScriptMsg -T "${cmd}: Invalid x2 coordinates specified <${1}> -"\
	    "script aborted."
	exit 3
    endif
endif
shift

# Get and check the first y coordinates
if (("$1" == "c") || ("$1" == "ctr") || ("$1" == "center")) then
    set y2 = "c"
else
    set CheckStatus = `syncheck -command $0 $1 -silent -pattern float`
    set error = $status
    if ($error == 0) then
	set y2 = $1
    else
	osirisScriptMsg -T "${cmd}: Invalid y2 coordinates specified <${1}> -"\
	    "script aborted."
	exit 3
    endif
endif
shift

if ($1 == "file") then
    shift
    set filename = $1
    echo "Write output to ${filename}"
    shift
endif


# Check for additional flags (if any)
while ($#argv != 0)
    switch ($1)
	case -m:
	    set sim
	    set cmdpre = "echo ${cmd}: sim:"
	    set cmdsuf = "-m"
	    breaksw
	default:
	    echo "${cmd}: Invalid command line flag $1 specified."
	    # set the error code for an error with command line input
	    exit 3
	    breaksw
    endsw
    shift
end


# Simulate the telescope commands if requested
if ($?simall) then
    set sim
    set cmdpre = "echo ${cmd}: sim:"
    set cmdsuf = "-m"
endif


# Now assign the filter/scale dependent parameters for mode1
if ("${mode1}" == "spec") then
    # Get the center lenslet for filter1
    set Xc1 = `awk '/^'$sfilter1'/ {print $2}' $specfiltctrfile`
    set Yc1 = `awk '/^'$sfilter1'/ {print $3}' $specfiltctrfile`

    # Get the reference lenslet for filter1
    set Xsref1 = `awk '/^'$sfilter1'/ {print $4}' $specfiltctrfile`
    set Ysref1 = `awk '/^'$sfilter1'/ {print $5}' $specfiltctrfile`

    # Get the spatial offset for scale1
    set Xsoff1 = `awk '/^'$sscale1'/ {print $2}' $specscaleoffsetfile`
    set Ysoff1 = `awk '/^'$sscale1'/ {print $3}' $specscaleoffsetfile`
else
    # The first mode is imag, set the imag center coords
    set Xc1 = $Xicp
    set Yc1 = $Yicp
endif

# Now assign the filter/scale dependent parameters for mode2
if ("${mode2}" == "spec") then
    # Get the center lenslet for filter2
    set Xc2 = `awk '/^'$sfilter2'/ {print $2}' $specfiltctrfile`
    set Yc2 = `awk '/^'$sfilter2'/ {print $3}' $specfiltctrfile`

    # Get the reference lenslet for filter2
    set Xsref2 = `awk '/^'$sfilter2'/ {print $4}' $specfiltctrfile`
    set Ysref2 = `awk '/^'$sfilter2'/ {print $5}' $specfiltctrfile`

    # Get the spatial offset for scale2
    set Xsoff2 = `awk '/^'$sscale2'/ {print $2}' $specscaleoffsetfile`
    set Ysoff2 = `awk '/^'$sscale2'/ {print $3}' $specscaleoffsetfile`
else
    # The second mode is imag, set the imag center coords
    set Xc2 = $Xicp
    set Yc2 = $Yicp
endif


# Check if we need to translate any center coordinates to actual numbers
if ("${x1}" == "c") then
    set x1 = $Xc1
endif

if ("${y1}" == "c") then
    set y1 = $Yc1
endif

if ("${x2}" == "c") then
    set x2 = $Xc2
endif

if ("${y2}" == "c") then
    set y2 = $Yc2
endif


# For testing, display the variables and their values
if ($?test) then
    echo ""
    echo "Current Script Variables:"
    echo mode1 =    $mode1 $sscale1 $sfilter1
    echo coords1 =  $x1 $y1
    echo lcenter1 = $Xc1 $Yc1
    echo lref1    = $Xsref1 $Ysref1
    echo loffset1 = $Xsoff1 $Ysoff1
    echo ""
    echo mode2 =    $mode2 $sscale2 $sfilter2
    echo coords2 =  $x2 $y2
    echo lcenter2 = $Xc2 $Yc2
    echo lref2    = $Xsref2 $Ysref2
    echo loffset2 = $Xsoff2 $Ysoff2
    echo ""
    echo cmdpre = $cmdpre
    echo cmdsuf = $cmdsuf
#    exit
endif


# Now calculate the position of the first coordinates in instrument coords
# Note: Instrument coords defined by the 0.020 lenslets
switch ("${mode1}")
    case imag:
	set newcoords = `osirisCoordI2S $x1 $y1` 
	set inst_x1 = `echo $newcoords | cut -f1 -d" "`
	set inst_y1 = `echo $newcoords | cut -f2 -d" "`
	unset newcoords
	breaksw
    case spec:
	set inst_x1 = `echo "(($x1 - $Xsref1) * $sscale1) - $Xsoff1" | bc -l`
	set inst_y1 = `echo "(($y1 - $Ysref1) * $sscale1) - $Ysoff1" | bc -l`
	breaksw
    default:
	osirisScriptMsg -T "${cmd}: mode1 unknown <${mode1}> - aborting."
	exit 3
	breaksw
    endsw

switch ("${mode2}")
    case imag:
	set newcoords = `osirisCoordI2S $x2 $y2` 
	set inst_x2 = `echo $newcoords | cut -f1 -d" "`
	set inst_y2 = `echo $newcoords | cut -f2 -d" "`
	unset newcoords
	breaksw
    case spec:
	set inst_x2 = `echo "(($x2 - $Xsref2) * $sscale2) - $Xsoff2" | bc -l`
	set inst_y2 = `echo "(($y2 - $Ysref2) * $sscale2) - $Ysoff2" | bc -l`
	breaksw
    default:
	osirisScriptMsg -T "${cmd}: mode2 unknown <${mode2}> - aborting."
	exit 3
	breaksw
    endsw

# Calculate move in instrument coords (arcsec)
set offset_x = `echo "${inst_x1} - ${inst_x2}" | bc -l`
set offset_y = `echo "${inst_y1} - ${inst_y2}" | bc -l`

# inform the user what move will be made
osirisScriptMsg -T "${cmd}: Moving xy $offset_x $offset_y"
if (${filename} != "") then
   osirisScriptMsg -f ${filename} "${cmd}: Moving xy $offset_x $offset_y"
endif

# actually move the telescope
$cmdpre xy $offset_x $offset_y

### could add error checking here for failed xy

goto done

abort:
# Block of code to handle interrupts.
osirisScriptMsg -T "${cmd}: abort, exit 1"
exit 1

done:
# is there anything that needs to go here?
osirisScriptMsg -T "${cmd}: done"
exit