API quick start¶
Your best start for developing scripts which use the HiPERCAM API is probably
to look at whichever one of the existing scripts seems closest to your
task. Hunt out the location of hipercam.scripts
. But to give a bit
more background, here are some basic concepts to get you going.
HiPERCAM hcm files and hipercam.MCCD
objects¶
The pipeline stores individual multi-CCD exposures as hipercam.MCCD
objects in
memory. These contain all the windows of all the CCDs, along with header
information. e.g. for HiPERCAM itself, there will be 5 CCDs, each with 4 or
more windows of data. They quickly allow access to the data. Thus given an
hipercam.MCCD
object called ‘mccd’, the following lines return first a single hipercam.CCD
labelled ‘2’, then a hipercam.Window
of that CCD labelled ‘E1’, then a 2D numpy array
containing the data of that hipercam.Window
:
ccd = mccd['2']
wind = ccd['E1']
data = wind.data
At this point you have direct access to the data. e.g. The value of the pixel at (x,y) = (10,20) from the lower-left corner of the pixel can be printed and set equal to 150 with:
print(data[20,10])
data[20,10] = 150.
Note the C-style ordering, with Y coming first, and that the pixel indices are
C-style 0-offset, i.e. (0,0) is the lower-left pixel itself; apologies to
FORTRAN devotees. hipercam.MCCD
objects are derived from
collections.OrderedDict
objects, and are keyed by string labels
assigned to the CCDs they contain. In HiPERCAM data the CCDs are labelled ‘1’,
‘2’, ‘3’, ‘4’ and ‘5’ for the ugriz arms. A statement such as ccd =
mccd['2']
returns CCD ‘2’ as a hipercam.CCD
object which is also dictionary-like so
that ccd['E1']
returns window ‘E1’ as a hipercam.Window
object. It is worth
perusing the methods of all of these classes.
How does one get an hipercam.MCCD
in the first place? One way, probably the usual
way, is to read it in from a file using the class method
hipercam.MCCD.read()
as follows:
import hipercam as hcam
mccd = hcam.MCCD.read('myfile.hcm')
assuming that there is some pre-written file myfile.hcm
, as generated by
e.g. grab
. If we do something to ‘mccd’ and want to save it then:
mccd.write('mynewfile.hcm')
or:
mccd.write('mynewfile.hcm',True)
if we don’t mind over-writing pre-existing files in the latter case, will do
the job. “hcm” is the standard extension the pipeline uses when saving
hipercam.MCCD
objects to disk, but these files are in fact FITS files and can
be looked at with standard tools such as “fv”. The extension highlights that
they are a particular style of FITS files and keeps them separate from the raw
data that comes with the extension ‘.fits’ (see below). Here is a script to
subtract two files and save the result:
import hipercam as hcam
# input the two frames
mccd1 = hcam.MCCD.read('input1.hcm')
mccd2 = hcam.MCCD.read('input2.hcm')
# subtract in place
mccd1 -= mccd2
# output the result
mccd1.write('output.hcm')
If the two hipercam.MCCD
objects are compatible, this will subtract them
CCD by CCD, and window by window.
Dealing with raw data files¶
Sometimes you may prefer to deal directly with the raw data files. These have
names like run0034.fits
. They are FITS files, but are not directly
usable as the data is scrambled within a 3D FITS “cube” owing to the
constraints of continually adding to FITS during data acquisition. To minimize
risk to the data, the pipeline has no mechanism to write raw files, and does
not use the extension ‘.fits’ for any of the various files it produces. If you
want to modify data, you need to write out lists of hcm files.
Here is an example of subtracting the median values from all the windows of all CCDs of a run, writing out the results in a series of hcm files:
1 2 3 4 5 6 7 8 9 10 11 12 13 | from hipercam.hcam import Rdata
input_name = 'run0034'
for n, mccd in enumerate(Rdata(input_name)):
# subtract median from each window of each CCD
for ccd in mccd.values():
for wind in ccd.values():
wind -= wind.median()
output_name = '{:s}_{:03d}.hcm'.format(input_name,n+1)
mccd.write(output_name)
|
Line 1 imports the pipeline software. Line 5 creates a
hipercam.hcam.Rdata
object which can deliver each frame one-by-one
in the form of what is known as “iterator” in Python-speak. Any iterator
can be called in a for-loop as in line 5. The successive frames are returned
as hipercam.MCCD
objects labelled mccd in line 5. After the median is subtracted
from each :They are written to files which
will have names like run0034_001.hcm
, run0034_002.hcm
, etc.
The code above loads frames from a raw data file assumed to be in the
directory the script is run in. If instead you want to load from the server,
then line 5 would be replaced by
for n, mccd in enumerate(Rdata(input_name,True)):
A similar construction serves for ULTRACAM files, with the difference that
Rdata
is loaded from the hipercam.ucam
sub-module:
from hipercam.ucam import Rdata
input_name = 'run0034'
for mccd in Rdata(input_name):
.
.
.
The resource that produces the file can also be called as a “context manager” with the with statement
import hipercam as hcam
with hcam.HcamDiskSpool(input_name) as spool:
for mccd in spool:
# do something
.
.
The advantage of this is that the input file will be closed as soon at the
with is exited. HcamDiskSpool
is one of 5 similar iterable context
managers to return data. Another useful one is HcamListSpool
which
can be attached to a file list to return each file as an MCCD
. Others
source data from servers for both HiPERCAM and ULTRA(CAM|SPEC). Several of the
standard HiPERCAM scripts (rtplot, reduce, grab for example) use a special
method data_source()
to return any one of these 5 types. For instance
these lines are extracted from ‘rtplot’:
import hipercam as hcam
.
.
.
with hcam.data_source(source, resource, first) as spool:
for mccd in spool:
‘source’ here takes values one of 5 values: ‘hl’ for a local HiPERCAM file, ‘hs’ for the HiPERCAM server, ‘hf’ for an hcm file list, ‘ul’ for a local ULTRA[CAM|SPEC] file, or ‘us’ for the ULTRA[CAM|SPEC] server. ‘resource’ is the run or in the case of a file list, the file name, while ‘first’ is the number of the first frame to return. This provides uniform access code to the different types of data.
Command line inputs¶
The pipeline uses a style of command-line inputs derived from STARLINK
routines that is distinct from the usual UNIX-style command-line options. See
the Parameter specification section for details of this. This has great
benefits in reducing the amount of typing. If you want to write scripts that
follow the same convention then you should look at
hipercam.cline.Cline
. Here is an example taken from a stripped-down
version of the stats
script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def stats(args=None):
command, args = hcam.script_args(args)
# get input section
with Cline('HIPERCAM_ENV', '.hipercam', command, args) as cl:
# register parameters
cl.register('input', Cline.LOCAL, Cline.PROMPT)
cl.register('format', Cline.LOCAL, Cline.HIDE)
# get inputs
frame = cl.get_value('input', 'frame to lists stats of',
cline.Fname('hcam', hcam.HCAM))
mccd = hcam.MCCD.read(frame)
cl.set_default('format','9.3f')
form = cl.get_value('format', 'output format for numbers', '9.3f')
|
A Cline
object ‘cl’ is called as a context manager (with statement
again, line 6). The command name and any arguments are passed to it along with
parameters to determine the location of any default file. Two parameter names
are registered, namely ‘input’ and ‘format’ (lines 9 and 10). The second of
these is not prompted for by default (‘Cline.HIDE’). Following the ‘register’
lines, the inputs themselves are obtained (lines 13-14 and 18). Once the
‘with’ statement is exited, any values entered will be saved to disk in a
directory whose location is specified by the first two arguments to ‘Cline’
and whose name is determined by the command name, e.g. ‘stats.def’. In this
way, previously entered values can be retrieved. In a script like rtplot
these input sections rival the “doing stuff” part of the script for
length. Your best place to start is very probably one of the existing scripts
where you can see how to deal with input of existing files, versus output of
new one, getting floating point, integer or string input and other details.