Last modified: December 2013

Jump to: Description · Examples · Bugs · See Also

AHELP for CIAO 4.15


Context: concept


How to set a parameter to more than one value using a stack.


Normally tool parameters can only be set to one value at a time. However, multiple values can be specified for a parameter if is listed in the help file as accepting stacks. The most common use of stacks is to specify a set of file names - either input or output - to a tool, but they can be used for anything where multiple values are required.

As an example, consider dmstat: its infile parameter is marked as taking a stack, which means that it can handle multiple inputs in one go. These inputs can be different files or the same file but with different filters, or a combination of both.

The parameter list for a tool will tell you whether it can accept stacks and for which parameters: use "ahelp -b PARAM <toolname>" (or "ahelp -b PARAM -t <paramname> <toolname>") to quickly find this information.

Tools may treat stacks in two ways:

The modes that are supported depend on the function of the tool. Check each tool's help file to see how they are treated.

What is a stack?

There are several ways to specify a stack:

The Examples section below shows how to use these different methods.

Including a Data Model filter in a stack

When a Data Model filter (see "ahelp dm") is included as part of the filename, it must be contained within double quotes:

  unix% dmcopy "acis_evt2.fits[ccd_id=3,sky=region(ds9.reg)]" \

If that DM filter is within a stack, however, DO NOT include the quotes:

  unix% cat in.lis

Creating regularly-spaced grids

If any one of the following filters is used in a Data Model filter then the tool will actually see a stack of filters, rather than just one. As shown in the Examples section, the rectangular and polar grid forms can be used to create a grid of regularly-spaced regions whilst the linear grid can be used to select a subset of rows from a table. The igrid specification forces an integer grid.

The following grid specifications are available:

grid type grid syntax
rectangular grid rgrid(xmin:xmax:dx,ymin:ymax:dy)
polar grid pgrid(xcen,ycen,rmin:rmax:dr,thetamin:thetamax:dtheta)
linear grid lgrid(min:max:step)
integer grid igrid(min:max:step)

Creating and manipulating stacks

Whilst tools can accept stacks, it is also possible to create and manipulate stack files from the command line - by using the stk_build, stk_count, and stk_read_num tools. See the appropriate ahelp files - "ahelp tools /stk/" for a list of the command-line tools.

These tools/functions can be used to see how a stack expression is expanded. For instance, if in.lis contains

  unix% cat in.lis

then we can see how "@in.lis" and "@in.lis[cols sky]" are expanded by:

  unix% stk_build "@in.lis" stdout
  unix% stk_build "@in.lis[cols sky]" stdout
  evt2.fits[cols sky]
  evt2.fits[ccd_id=3,sky=region(ds9.reg)][cols sky]


Example 1

dmstat "img1.fits,img2.fits"

Explicitly listing all stack elements

The simplest stack is just a comma-separated list of values. For dmstat - which accepts stacks for the infile parameter - this means that the statistics of each file will be calculated separately.

Note that spaces and semi-colons are also valid stack separators, so the following forms are equivalent to the first one:

  unix% dmstat "img1.fits img2.fits"
  unix% dmstat "img1.fits;img2.fits"

When ' ', ',', and ';' do not mean a stack

Comments, spaces, and semi-colons are not treated as stack separators when they appear inside of "()", "[]", or "{}" pairs. So

"evt2.fits[cols time,sky]"

is not treated as a stack.

If a space, comma, or semi-colon is preceeded by a "\" then it is also not treated as a stack separator, i.e. the "\" character is not removed from the text:

  unix% stk_build "img1.fits\,img2.fits" stdout

Example 2

dmstat "img*fits"

Using UNIX wild-card substitutions

Most UNIX wild-card substitutions are supported, as long as they are protected from being expanded by the shell (which is why quotes are used around img*fits above). Thus if the current directory contained the files img1.fits and img2.fits, the stack expansion would be equivalent to "img1.fits,img2.fits". For this particular example the following would produce the same result:

  unix% dmstat "img?.fits"

Do not use [] as a wild-card expression

Since the "[]" characters are used to indicate a DM virtual-file specification (see "ahelp dm") they can not be used as a wild-card expression. This means that


will NOT select both the asol1 and osol1 files.

Example 3

dmstat "@imgs.lis"

Using an external file

The most common form of specifying a stack is to store the values in an ASCII file and then setting the parameter to "@<filename>".

Thus if imgs.lis contained

  unix% cat imgs.lis

then the parameter would be equivalent to "img1.fits,img2.fits".

Recursive expansion

By default, recursive stack expansion is not supported, so if the file contained something like


then more_images.lis would NOT be expanded.

As will be shown in a later example, the "@+" syntax can be used to turn on recursive expansion.

Ignoring lines in a stack file

Blank lines and those beginning with a '#' character are excluded from the stack expansion.

Writing a long expression over multiple lines

Stack items can be divided over several lines by ending each line with a '\' character. This feature can be useful to break up dmtcalc expressions:

  unix% cat expr.lis
  GPHASE=(time-TSTART)* \
  unix% dmtcalc evt2_bary.fits evt2_bary_phase.fits @expr.lis

(this expression is taken from the Create a Phase-binned Spectrum thread with example numbers filled in for the frequency and frequency derivative terms).

Example 4

dmstat "@imgs.lis[sky=region(src.reg)]"

Filtering a stack

The syntax "@<filename>[DM expression]" tells the tool to apply the DM expression (as discussed in "ahelp dm") to each file listed in the file.

So, if imgs.lis contains img1.fits and img2.fits then this syntax is a shortform for setting infile equal to


Example 5

dmstat "img*[sky=region(src.reg)]"

Filters can be applied to any form of stack

We can also apply a DM filter to a wild-card. If the current directory contained img1.fits and img2.fits then the above would be the same as setting infile equal to


Example 6

dmstat "@/tmp/img.lis"

Using stacks outside the current directory

If the stack file is in another directory - here /tmp/ - then this directory name will automatically be added onto each entry in the stack.

In this example, if /tmp/img.lis contained img1.fits and img2.fits, then the above syntax would be equivalent to setting infile to


This makes it easy to use stacks in different directories: for instance if you create a file called asol.lis in the directory containing all the asol files for an observation - eg

  unix ls -1 *asol*fits* > asol.lis

then you can use "@/full/path/to/asol.lis" whenever you need these files (such as the acaoffile parameter of acis_process_events).

As will be discussed in the following examples, this behaviour can be over-ridden.

Example 7

dmstat "@/tmp/img2.lis"

How to avoid the stack changing a file name

Two ways to avoid pre-pending "/tmp/" to the names in the stack file are:

So, if /tmp/img2.lis contained

  unix% cat/tmp/img2.lis

then the stack would be expanded to


Example 8

dmimghist @in.lis @out.lis @-/tmp/bins.lis

Ignoring the location of a stack file

The "@-" for the third parameter - the hist parameter - of dmimghist tells the stack library not to prepend "/tmp/" to each entry in /tmp/bins.lis. This is useful here because this hist parameter does not refer to a list of files but a list of binning specifications.

So, if the contents of the three stacks are:

  unix% cat in.lis
  unix% cat out.lis
  unix% cat /tmp/bins.lis

Then the example above is the equivalent to running

  unix% dmimghist img1.fits hist1.fits 1:10:0.2
  unix% dmimghist img2.fits hist2.fits -0.5:50:0.5

If we had used "@/tmp/bins.lis" instead, dmimghist would have seen the hist parameter set to "/tmp/1:10:0.2,/tmp/-0.5:50:0.5", which does not make sense.

This example also shows that stacks are not just used for input parameters - they can be used to determine the output names of files (here the contents of out.lis).

Example 9

dmstat "@+/tmp/in.lis"

Recursive stacks

The "@+" syntax tells the tool that any entries in the stack beginnning with a "@" should be treated as stacks, in other words to recursively expand the stack.

If the contents of /tmp/in.lis are:

  unix% cat /tmp/in.lis


  unix% cat /tmp/in2.lis
  evt2.fits[cols sky]

then the stack is expanded to

"/tmp/img1.fits,/tmp/evt2.fits[cols sky],img2.fits"

Note that here we are not just expanding the contents of in2.lis into the stack but are also prepending the directory name onto the entries (apart from when we explicitly stop this using the "!" syntax). This highlights the fact that the stack expansion rules are cumulative.

Example 10

dmextract \
"evt2.fits[sky=region(reg.fits[component=lgrid(1:5:1)])][bin pi=::1]" \

Using a linear grid

The lgrid option creates a linear stack of numbers: in this example the sequence 1,2,3,4,5. This stack is then used to filter the FITS region file - reg.fits - using the component column, which creates a stack of 5 regions corresponding to the first 5 entries in reg.fits. The result of this is that dmextract will extract 5 spectra - in PI space - and store the results in a single type II PHA file.

If a stack - of 5 files - had been used for the outfile parameter then dmextrat would instead have created 5 type I PHA files, one for each of the first 5 regions in reg.fits.

Example 11

dmstat "evt2.fits[ccd_id=3,chip=rgrid(1:1024:32,1:1024:256)][bin chip]"

Using a rectangular grid

Here we use the rgrid syntax to split the event file up into a stack of rectangular regions based on the chip coordinate system (as well as filtering to ensure that only ccd_id=3 is used). These regions are then binned into images and dmstat run on each image.

The stack expansion in this example comes out to:

evt2.fits[ccd_id=3,chip=rectangle(1,1,33,257)][bin chip]
evt2.fits[ccd_id=3,chip=rectangle(1,257,33,513)][bin chip]

Example 12

dmstat "img.fits[sky=pgrid(4123,3950,0:40:10,0:360:180)]"

Using a polar grid

Here we run dmstat on an image, using a polar grid of regions, which expands to:


Note that the x, y, and radial grids are in the units of the selected coordinate system whereas the theta units are in degrees.


Trailing '/' may be removed

The stack library will strip off the trailing '/' from a directory name, if that directory does not already exist. If the directory exists, the '/' is preserved.

See Also

coords, level, pileup, times
autoname, ciao, ciao-install, ciaorc, history, parameter, subspace
dm, dmascii, dmbinning, dmfiltering, dmmasks, dmopt, dmregions
stk_build, stk_count, stk_read_num, stk_where