Scripting with GoQat

From version 0.9.6b onwards, GoQat is able to execute arbitrary scripts that can interact with GoQat's task list. The scripts can be written in the language of your choice, to do anything that is permissible with a script. Since GoQat can modify its behaviour depending on the results of the scripts, the scripting capability makes GoQat extremely powerful and flexible.

Scripts are called from GoQat's task list, so let's see how to do that first.

Calling a script from the task list

The following is an example task list called DemoTasks.txt that shows how to call a script from GoQat. GoQat uses the script to control the camera's CCD temperature for a series of exposures. DemoTasks.txt is installed in the GoQat installation tree in the data folder (by default, this will be /usr/local/GoQat/data).

########################################################################
# This is an example task list that executes the DemoScript.pl
# script. Load this task list into GoQat and start the execution
# of the task list.
########################################################################


# Set some initial parameters...
# Parameter 0 is the amount by which the CCD chip temperature will be
# reduced after each exposure.
# Parameter 9 is the initial chip temperature.
# Parameter 1 is a control variable for the 'While' loop. Set it to 1
# initially to make sure the loop is executed.

SetParam 0 5
SetParam 9 15
SetParam 1 1

# Execute the 'While' loop as long as parameter 1 is non-zero.

While %1

# Make an exposure one hundred pixels square, at a chip temperature set
# by parameter 9.

Expose TARGET - 1 1 1 100 100 1 1 %9

# Execute the external script. This sets a new value for the chip
# temperature in parameter 9 by subtracting the value in parameter 0,
# and returns parameter 1 as zero if the new temperature is less than
# -5C.

Exec /usr/local/GoQat/data/DemoScript.pl

EndWhile

What does the task list do?

  • The first section intialises parameter 0 to '5', parameter 9 to '15' and parameter 1 to '1'. GoQat has ten parameters (called %0 to %9) that can take any value. GoQat passes these parameters to any script that it calls, and the script can return values for these parameters to GoQat. We'll see how they get used shortly.
  • After setting the parameter values, the task list starts a 'While' loop. This will repeatedly execute all the tasks between the 'While' and 'EndWhile' statements, unless parameter 1 (%1) equals zero. We've just set parameter 1 to '1', so the 'While' loop will be executed.
  • The next item in the list is an 'Expose' task. This instructs GoQat to make an exposure with the CCD camera. The filter setting is '-', so this works for a camera with or without a filter wheel. The area of the chip that is read is in the bottom left corner with coordinates (1,100), (1,100) and using horizontal and vertical binning of 1 pixel (i.e. no binning). Most importantly for us, the chip temperature is set to the value in parameter 9. One of the initial 'SetParam' tasks set parameter 9 to a value of 15, so the camera will cool the chip to 15C and then make the exposure.
  • Now comes the 'Exec' task. This executes an external script synchronously; in other words, GoQat waits for the script to finish and reads any results from it before continuing. There is also an 'ExecAsync' option that calls a script asynchronously; in that case, GoQat continues immediately with the next task without waiting or reading any results from the script. (The 'ExecAsync' option can be useful for queuing the latest acquired CCD image into a data reduction process). In our example, the DemoScript.pl script subtracts the value of parameter 0 (which we intialised to 5) from the current CCD temperature, and returns the value in parameter 9. If parameter 9 is less than -5C, the script returns a value of 0 for parameter 1. Otherwise, GoQat continues to use the existing value of 1 for parameter 1. Note that if you have installed GoQat in a non-standard location, the path to the script will be different from the one in the example above. (The path is configured automatically when you install GoQat).
  • The last item is the 'EndWhile' task. This causes GoQat to go back to the start of the 'While' loop and re-test the value of parameter 1. If it is still 1, the loop is repeated, making an exposure at the new CCD temperature. Otherwise GoQat skips to the task after the 'EndWhile' task. Since there isn't one, GoQat stops task execution. So when exposures have been made at chip temperatures of 15C, 10C, 5C, 0C and -5C, task execution will halt.

Now that we've seen how to call an external script, let's see what such a script looks like.

An example script

We'll have a look at the example script a small chunk at a time. You can find DemoScript.pl in /usr/local/GoQat/data, unless you have installed GoQat in a non-standard location. This is a Perl script, and here's the first part:

#! /usr/bin/perl -w

########################################################################
# An example Perl script to read values from GoQat, and pass back some
# parameters.
########################################################################



########################################################################
# Keep the following section in your scripts. This section obtains
# values from GoQat and assigns them to named variables. (Of course,
# you can change these variable names if you wish).
########################################################################

my $a = 0;

my $sync = $ARGV[$a++];
my $results_file = $ARGV[$a++];
my $done_file = $ARGV[$a++];
my $num_task_params = $ARGV[$a++];

my @task_params;
for (my $i = 0; $i < $num_task_params; $i++) {
push (@task_params, $ARGV[$a++]);
}

my $Expose_image_file = $ARGV[$a++];
my $Expose_exposure_type = $ARGV[$a++];
my $Expose_filter = $ARGV[$a++];
my $Expose_seconds = $ARGV[$a++];
my $Expose_H1 = $ARGV[$a++];
my $Expose_V1 = $ARGV[$a++];
my $Expose_H2 = $ARGV[$a++];
my $Expose_V2 = $ARGV[$a++];
my $Expose_Hbin = $ARGV[$a++];
my $Expose_Vbin = $ARGV[$a++];
my $Expose_degC = $ARGV[$a++];

my $Coords_RA = $ARGV[$a++];
my $Coords_Dec = $ARGV[$a++];

########################################################################
# END OF VARIABLE ASSIGNMENT SECTION
########################################################################

This first part receives all the values that GoQat passes to the script and assigns them to variables with convenient names. You should ensure that this part is at the beginning of all your scripts. Of course if you are using a different language from Perl, the variable assignment syntax will be slightly different. The variables are as follows:

  • $sync is 1 if the script is called synchronously, 0 otherwise.
  • If running synchronously, any results to be passed back to GoQat should be written to $results_file.
  • When the script has done executing, it should create a file called $done_file.
  • $num_task_params is the number of task parameters (%0...%9). These are assigned to the elements of the array @task_params.
  • $Expose_image_file is the name of the most recently saved CCD image file. The other '$Expose' items are the corresponding exposure parameters.
  • $Coords_RA and $Coords_Dec contain the current pointing position of the telescope.

Now that we've got all these data items from GoQat, we can do something useful with them. Here's the next bit of the script:

########################################################################
# Execute your own commands below. These can be anything that you can
# do in a Perl script.
########################################################################

# Here's an example command (subtract the value of parameter 0 from the
# current CCD temperature and assign the value to a new variable):

my $value = $Expose_degC - $task_params[0];

########################################################################
# END OF YOUR OWN COMMANDS
########################################################################

This is the part of the script where we do data processing. In this simple example, the value in task parameter 0 (%0) is subtracted from the current CCD chip temperature and assigned to the variable '$value'. (Of course if we are making the effort to write a script, we would probably want to do much more than this in practice).

Finally, we want to pass some parameters back to GoQat and tell GoQat that the script has finished. Here's how we do that:

########################################################################
# If the script is being run synchronously, you may pass the values of
# the task parameters back to GoQat. Do that below.
#
if ($sync) {
#
########################################################################

# Here is an example of passing a parameter back to GoQat.

open (RESULTS, '>', $results_file) or die "Can't open $results_file";

# The variable '$value' defined above is passed back as parameter 9.
# Note the line must be terminated by the new-line symbol '\n'.

print (RESULTS "%9 $value\n");

# If the new chip temperature '$value' is less than -5C, then exit the
# 'While' loop in the task list. Do this by passing back a value
# of '0' for parameter 1. (Otherwise, GoQat continues to use the
# existing value).

if ($value < -5) {print (RESULTS "%1 0\n");}

# Write a comment that will be displayed by GoQat in the log window when
# the script has finished. Note the hash '#' at the beginning of the
# line and the new-line symbol '\n' at the end.

print (RESULTS "#The current chip temperature is $Expose_degC\n");
print (RESULTS "#A value of $task_params[0] has been subtracted from this\n");
print (RESULTS "#and returned in parameter %9\n");

close (RESULTS);

########################################################################
# Finally, create the file that tells GoQat the script has finished.
#
open (DONE, '>', $done_file) or die "Can't open $done_file";
close (DONE);
}
#
########################################################################

exit 0;

The 'if ($sync)' code should be in all your scripts. It will be executed if the script is running synchronously, but not if it is running asynchronously. Here we want to pass back the new CCD temperature as parameter 9 (%9). To do that, we open the $results_file file, and write a line that appears like this (for the case where $value = 5, for example):

%9 5.000

If the new CCD temperature is less than -5C, we want to stop execution of the task list by returning a value of 0 for parameter 1, so we write:

%1 0

We can return some comments to be displayed by GoQat by prefacing lines with a hash '#':

#The current chip temperature is 10.0000

Finally, we tell GoQat that the script has finished by creating a file called $done_file. This code should be at the end of the 'if ($sync)' block in all your scripts. If you omit it and run the script synchronously, GoQat will wait forever.

You can see how it all works for yourself by selecting the Tasks tab in GoQat and clicking 'Edit tasks...'. Click 'Load tasks from file...' and open /usr/local/GoQat/data/DemoTasks.txt (assuming you have installed GoQat in the standard location). Then connect your camera and click 'Start' on the Tasks tab to begin execution of the task list. You may want to select 'CCD temperatures' from the Windows menu to see the temperature plot as the task list and script change the chip temperature and make each exposure.

If you prefer to write your scripts as shell scripts, there is a corresponding shell-script version in the GoQat data folder called DemoScript.sh, which you can use instead if you wish. Do note that this requires the 'bc' utility to do floating point maths, so make sure you have that installed first.

If you want to see the output from your own scripts for testing or debugging purposes, start GoQat from a terminal window, and any warnings or errors from the scripts will appear there.