#!/usr/bin/perl


# This script computes scan mirror configuration parameters for scan maps.
# Once the integration time and map type (a "filled" map means the 160um
# scan leg is filled in, as in a slow MIPS scan, while the "sparse" map
# means that the 160um array covers only every other row, as in a fast MIPS
# scan) is picked, the other parameters are fixed for forward or reverse
# legs.  If you want to change the interval between stimflashes, adjust
# the stim_interval variable below.

# complaints to cengelbracht@as.arizona.edu
# last updated:  2003-03-14


# set parameters here
$mips_second = 1.048576;	# ratio of MIPS second to real second
$stim_interval = 120;		# desired time between stims, in seconds
$ogain = 32.635;		# optical gain from sky coords to csmm coords
$egain = 2.17;			# electronic gain in arcsec/LSB
$pixsize_160 = 15.99;		# 160um pixel size, in arcsec


# get command-line arguments

if ($ARGV[0]) {$itime = int ($ARGV[0]);}
else {
   print "Please enter desired integration time, in MIPS seconds: ";
   $itime = int (<STDIN>);
}
unless (($itime >= 2) && ($itime <= 62)) {
   print "Integration time must be between 2 and 62 seconds.\n";
   exit;
}

if ($ARGV[1]) {$maptype = $ARGV[1];}
else {
   print "Please enter map type (filled/sparse): ";
   chop ($maptype = <STDIN>);
}
if ($maptype eq "f") {$maptype = "filled";}
if ($maptype eq "s") {$maptype = "sparse";}
unless (($maptype eq "filled") || ($maptype eq "sparse")) {
   print "Map type must be \"filled\" (f) or \"sparse\" (s).\n";
   exit;
}

if ($ARGV[2]) {$scandir = $ARGV[2];}
else {
   print "Please enter scan direction (fwd/rev): ";
   chop ($scandir = <STDIN>);
}
if ($scandir eq "f") {$scandir = "fwd";}
if ($scandir eq "r") {$scandir = "rev";}
unless (($scandir eq "fwd") || ($scandir eq "rev")) {
   print "Scan direction must be \"fwd\" (f) or \"rev\" (r).\n";
   exit;
}


# this is how long the dce takes in real seconds
$dcetime = ($itime + 0.5) * $mips_second;


# stimcycle must be odd for filled map - doesn't matter for sparse map
$stimcycle = sprintf "%0.0f", $stim_interval / $dcetime;
if ($maptype eq "filled") {$stimcycle += ($stimcycle + 1) % 2;}


# $jump is the average jumpsize, while $jump2 is the size of the second
# jump (~48" for the filled map, while all jumps are ~64" for the sparse map)
if ($maptype eq "filled") {$jump = 2 * $pixsize_160; $jump2 = 3 * $pixsize_160;}
if ($maptype eq "sparse") {$jump = 4 * $pixsize_160; $jump2 = $jump;}


# forward scan implies positive scan mirror direction, while reverse scan
# implies negative scan mirror direction
if ($scandir eq "fwd") {$rampdir = 0; $sign = -1;}
if ($scandir eq "rev") {$rampdir = 1; $sign = 1;}


# this is the desired rate of scan mirror motion in arcsec/sec on the sky
$rate = ($stimcycle - 1) / $stimcycle * $jump / $dcetime;


# ...and this is the closest corresponding rampslope parameter
$rampslope = sprintf "%0.0f", 10000 / $rate / $ogain * $egain;

# ...and this is the corresponding spacecraft slew rate
$slew_rate = $egain / $rampslope * 10000 / $ogain;


# this is always 0 except for total power mode
$scanpos2 = 0;


# (relpos2 - relpos1) is what's important, so we might as well put this in
# the middle of its range
$relpos1 = 2048;


# the sign of stepoffset depends on the ramp direction
$stepoffset = sprintf "%0.0f", $sign * ($jump - $rate * $dcetime) *
   $ogain / $egain;


# this should give us back relpos1 for sparse maps.  for filled maps, the
# sign of the difference depends on the ramp direction.
$relpos2 = sprintf "%0.0f", $relpos1 + $stepoffset - $sign * ($jump2 -
   $rate * $dcetime) * $ogain / $egain;


# compute framenum and framecnt just for completeness
$framenum = $itime - 1;
$framecnt = $itime / 2;


# we're done - print out the results
print "Itime = $itime, Scan direction = $scandir, Map type = $maptype\n";
printf "DCE time = %0.4f seconds\n", $dcetime;
print "Average jump size is $jump\", second jump size is $jump2\"\n";
printf "Desired spacecraft scan rate is %0.2f arcsec/sec.\n", $slew_rate;
print "relpos1 = $relpos1\n";
print "relpos2 = $relpos2\n";
print "scanpos2 = $scanpos2\n";
print "rampslope = $rampslope\n";
print "rampdir = $rampdir\n";
print "stimcycle = $stimcycle\n";
print "stepoffset = $stepoffset\n";
print "framenum (CEMIPSUR) = $framenum, framecnt (CEMIPSRAW) = $framecnt\n";
