Adding a new instrument to orac-dr requires a number of steps, the complexity of which will depend on how close the instrument is to an instrument that is already supported by the pipeline.
This section describes the areas that must be modified to support a new instrument. It assumes
knowledge of the following Perl concepts: writing object-oriented modules, lexical variables, Perl
data structures and eval. Message system interfaces will also require a knowledge of Perl
XS.
An ORAC::Frame class is responsible for filename conventions and handling of sub-frames. The most
common methods that need to be sub-classed are:
The object constructor should be modified to set the default behaviour for
rawfixedpart(), (the part of the filename that does not change with UT date of
observation number), rawsuffix(), (the file suffix of the raw data file), rawformat() (the
input format of the data: FITS, NDF etc.) and format() (the data format required by the
algorithm engines).
The base constructor (SUPER::new()) should be invoked to instantiate the object.
This method is used to translate instrument specific headers to those required by the pipeline. Currently this method must insert the following keywords into the frame header.
This should be the UT date of the observation in YYYYMMDD format.
This should be the UT date and time of the observation in YYYYMMDD.frac format (i.e. UT date plus fraction of day). This is used by the calibration system to ensure that a guaranteed time stamp can be used for comparison in index files.
Given a UT date and an observation number, return the name of the raw data file. This is used by the pipeline to look for the file on disk.
Given a UT date and an observation number, return the name of the flag file. This is used by the
pipeline to search for a completion flag on disk associated with the current observation file. Only
required if it is intended for the pipeline to be used in conjunction with the -loop flag
option.
Translates the header values into a group name and updates the frame.
Translates the header values into a recipe name and updates the frame.
Modifies the current filename so that it matches the filename that you would have had at an
earlier point in the reduction when the supplied template was valid. This is used for jumping to
earlier steps in the reduction when performing group operations. Currently this method is
generally implemented by replacing the suffix with the supplied value. It could also
be implemented by accessing the list of prior file names with the intermediates()
method.
Given a suffix and sub-frame number provide a recommended name for the output file. Does not update the frame object. In general, this can either simply append the suffix or replace the last suffix. The latter is normal practice.
In addition to those listed above, some methods need to know something about the file format and
should be modified (most UKIRT and JCMT instruments inherit from the ORAC::Frame::NDF class
rather than ORAC::Frame since that class knows how to read from NDF files). The automatic format
conversion will have occurred before these methods need to be run (for example if the input format is
FITS but the processing format is NDF, then the methods should be written assuming NDF files).
These methods are as follows.
Reads the file header and stores the resulting hash reference in the object. Also forces the ORAC headers to be calculated.
A method to delete the file currently associated with the frame. This is effectively and
unlink() but for NDF files the .sdf is appended. The base class implementation can be
used in most cases.
Checks to see if the data file exists. There is a special case for NDF format since the .sdf
extension is not present in the file name.
Strips the extension from the filename. The base class does nothing to the filename.
Finally, any extra methods not present in the base class but required by an instrument should also be added. These can cover translation of wavelengths to sub-frame filename, for example (used by the SCUBA class).
There are a number of internal headers that ORAC primitives rely on to correctly reduce data. These
headers are retrieved from the files and translated to be used by oracdr. These headers can be
used in recipes through the ORAC::Frame::uhdr() method and prepending ORAC_ to
each header. For example, to refer to the INSTRUMENT header in a primitive, you would
use
New internal headers can always be created, if necessary, to define some ancillary data needed by a recipe, in an instrument-independent fashion.
The following headers currently exist. Note that not all headers are defined for each instrument or recipe.
Airmass at start of the observation (for a mosaic) or integration (for a raw frame).
Airmass at end of the observation (for a mosaic) or integration (for a raw frame).
Position angle of the chop (in degrees).
Throw of the chop with respect to the middle position (in arcseconds).
Configuration index. Increments when an instrument’s hardware configuration changes.
Declination (ORAC_EQUINOX equinox) at the reference position at zero offset (in degrees). The reference position is normally at the array centre, but may be displaced, for example, to avoid the intersections of abutted detector sub-arrays.
Pixel increment along declination axis (in arcsec).
Telescope declination offset with respect to the base position given by DEC_BASE (in arcseconds).
Detector bias voltage (in volts)
Position number in detector scan.
Observing mode, such as STARE, NDSTARE, CHOP.
Equinox of object position (in years). It should be 2000.
Integration time per exposure (in seconds).
Combined filter name.
Detector gain (in electrons/ADU).
Grating dispersion (in microns/pixel).
Grating name.
Grating order.
Grating wavelength (in microns).
Instrument name.
Number of scan positions in scan.
Number of exposures in integration.
Number of jitter offset positions in an observation.
Number of reads per exposure.
Object name from telescope.
Camera mode, such as imaging or spectroscopy. Used for multi-mode instruments like
Michelle.
Observation number. Observation numbers normally commence at 1 for each night.
Observation type. Used to determine whether observation is of the OBJECT, DARK, or ARC,
for example.
Whether or not polarimetry observations are being done. True (1) if so, false (0) otherwise.
Right Ascension (ORAC_EQUINOX equinox) at the reference position at zero offset (in degrees). See DEC_SCALE.
Pixel increment along right-ascension axis (in arcsec).
Telescope right-ascension offset with respect to the base position given by RA_BASE (in arcseconds).
Angle of declination axis with respect to the second () axis, measured counterclockwise (in degrees).
Increment between scan positions (in pixels).
Position angle of slit (in degrees)
Name of slit.
Readout speed. The default is Normal.
Is the target a standard-star observation?
UTC date when the observation was made.
End time of integration (for raw data) or the observation (for a mosaic).
Start time of integration (for raw data) or the observation (for a mosaic).
Polarimeter waveplate position angle (in degrees).
Number of detectors in a readout column (in pixels).
Number of detectors in a readout row (in pixels).
Start column of array readout.
End column of array readout.
Start row of array readout.
End row of array readout.
An ORAC::Group class is responsible for dealing with groups of frame objects and with an
output group data file. The most common methods that need to be sub-classed are given
below.
The constructor must be overridden to specify the type fixed part and file suffix of the output group file. The base constructor should be used from the subclass to instantiate the object.
Similar to the frame implementations.
For specialized applications it may also be necessary to implement the coaddswrite()/coaddsread()
methods. These will be used by the CGS4/MICHELLE instrument classes to allow coadds to be
combined part way through a group without having to re-reduce earlier observations. Not all
instruments require support for this.
For a new instrument all that is required is to specify a new set of rules and work out what to do with the ‘best’ calibration that is returned. For UFTI this simply means that the name is returned to the primitive for use. For SCUBA more complex routines are required for sky opacity calibration since the number returned by the index file is sometimes modified for different filters before being returned to the user (the SCUBA calibration system never returns a file name).
For every type of calibration, the calibration object (ORAC::Calib and sub-classes) must provide the
following methods:
ORAC::Index object associated with the relevant index file.
The name of this method should be related to the name of the index file (e.g. skydipindex
will access the file index.skydip).
darknoupdate(). Orac-dr assumes that the method is of this form since this
method will be called whenever a user makes use of the -calib switch,
Each instrument requires its own implementation of an ORAC::Inst module. This module is
responsible for implementing the commands for starting the messaging layer (if required) and
launching external tasks ready for use by the pipeline. It may be possible for future releases to launch
external tasks on demand the first time an obeyw is issued but this depends on the implementation of
the messaging class and still requires that an object for each class is instantiated in the ORAC::Inst
module at startup.
Currently, this module is not object-oriented. This may change in the future.
Another factor related to the algorithm engines is the implementation of the messaging interface. The current interface is to the ADAM messaging system used by Starlink. An additional interface is provided to run ADAM tasks via the Unix shell as a proof of concept. Interfaces to Glish and IRAF will be needed to talk to aips++ and Iraf tasks. A Perl-to-DRAMA interface exists and it should be fairly simple to write an orac-dr interface for DRAMA tasks. A shell interface should be used as a last resort and only if valid exit status can be returned to the pipeline.
Once the instrument classes have been written, Orac-dr needs to be modified so that it can interpret a
new value for ORAC_INSTRUMENT and configure the frame, group and calibration objects
correctly.
In the future this configuration may be moved into an external data file so that the core Orac-dr routine need not be modified by people porting the system to a new instrument.
Once orac-dr has been configured to recognise the new instrument, the final step is to write the recipes and associated primitives to deal with the new data and possibly new algorithm engines. At its simplest, for example for an infrared image, this may simply require copying pre-written primitives from an existing instrument11. At its most complex, completely new primitives will have to be written.
11Plans are ongoing to allow multiple search paths for recipes and primitives so that single copies can be used by multiple instruments without having to copy the files to separate locations