Hello ACIS analysts,
I've just discovered that's it is very easy to misuse the CIAO tool
lightcurve and produce an INCORRECT LIGHT CURVE. The technical problem
and a solution are described below.
THE PROBLEM
To produce a source light curve, the CIAO program "lightcurve" must of
course normalize a histogram of the event arrival times by a histogram
of the exposure time the source received derived from a GTI table.
ACIS event files of course generally have a GTI table for each CCD. It
turns out that the program lightcurve does NOT have the ability to
choose which GTI table in your event file should be used -- instead it
seems to use whichever GTI table is referenced in the keyword DSREF8 in
the event table. The DSREF8 keyword seems to generally point to the
first GTI table in the event file. Thus, for ACIS datasets involving
multiple CCDs, all light curves will be normalized in the same way,
using the first GTI table, regardless of where the source is located on
the detector.
Obviously if you're working with only a single CCD and have applied a
[ccd_id=?] filter you will not have a problem. For multi-CCD observations
in which the GTI tables for all CCD's of interest are almost the same
there will not be a significant error. If however the
observation suffered significant telemetry loss (which occurs separately
for each CCD), or if you applied a time filter to only a subset of the
CCD's (e.g. to remove BI background
flaring), then the light curve could be significantly corrupted.
Neither the lightcurve man page
(http://asc.harvard.edu/ciao/ahelp/lightcurve.html) nor the CIAO thread
on light curves
(http://asc.harvard.edu/ciao/threads/filter_ltcrv.thread.html) mention
this crucial fact.
Note also that if the GTI table referenced by DSREF8 does not exist, the
lightcurve program seems to silently use a flat normalization.
THE SOLUTION
One must ensure that the DSREF8 keyword in the event list passed to
lightcurve corresponds to the (single) CCD that contains the source.
Generally one may achieve this by filtering by ccd_id,
e.g.
dmcopy "source.evt[ccd_id=2]" temp.evt
When a ccd_id filter is applied, CIAO generally removes the GTI tables
for all other CCD's and sets the DSREF8 keyword properly.
I have released within Penn State a new version of my own little perl
script
(/bulk/pkg/xray/bin/lightcurve.plx) which I use to make light curves,
and the script is attached to this email. This script is tailored to
the particular environment I've used in past reductions and may not be
directly useful to you, but it illustrates the technical points I've
described here.
*At line 118 the script makes sure the source lies on only 1 CCD. Note
that it is not possible to produce a light curve for a source that spans
CCDs.
*At line 123 the script filters by ccd_id to retain only the GTI table
we want and correctly set DSREF8.
*At line 128 the script double checks that DSREF8 has the proper value.
*At line 134 the script sorts the event list by time (not always
necessary).
*Finally at line 137 the script calls the lightcurve program.
NOTES
ACIS observers are reminded that the lightcurve program does NOT take
into account dead regions of the detector (e.g. CCD gaps or bad
columns) which dither across the source. A light curve should never be
used for absolute photometry; only the mkarf program understands how to
project the motion of a source across a map of the detector's QE to
produce an effective exposure*cm^2 suitable for absolute photometry.
Obviously any periodicity in your light curve at the frequency of the
dither is very likely to be a dead region moving across the source.
Regards,
Patrick Broos
UVOT Software Systems Engineer Tel: 814-865-5509
Penn State University Fax: 814-865-6854
2565 Park Center Blvd., Suite 200, E-mail: patb@astro.psu.edu
State College, PA 16801
#!/usr/local/bin/perl
#===============================================================================
#
# FILE NAME: @(#)lightcurve.plx 1.4
#
# DESCRIPTION: A Perl script that creates a series of lightcurves for a set
# of sources previously extracted by lightcurve.plx
#
# The extraction regions are specified in a simple ASCII table in the file
# "catalog" with one of these formats:
# x y radius
# OR
# x y radius source_name
#
# The fields x,y,&radius are in units of sky pixels.
#
# If the field "source_name" is omitted then the event list generated for that
# source will have a name derived from the source number.
# The source name is recorded in the FITS keyword OBJECT in the output event
# lists.
#
# The option --suffix can be used to add a suffix (e.g. the obsid) to the
# source names. The option --arf_suffix can be used to specify an additional
# suffix to add to ARF filenames (e.g. the temperature).
#
# Normally each extracted event list will be put in its own directory, but if
# the option --flat is used they will all go in the current directory.
#
#
# *** WARNING!!!
# If any of the output files already exist they are OVERWRITTEN!!!
# *** WARNING!!!
# AUTHOR: Patrick Broos (patb@astro.psu.edu)
# Copyright (C) 2000, Pennsylvania State University
#
#===============================================================================
sub USAGE {
printf "\n\nUsage: lightcurve.plx catalog -suffix=? -flat \n\n";
}
#===============================================================================
use File::Copy;
use Getopt::Long;
#-------------------------------------------------------------------------------
# Extract command line arguments
#-------------------------------------------------------------------------------
GetOptions("suffix=s", \$suffix, "flat");
$catalog = $ARGV[0] or die USAGE();
#-------------------------------------------------------------------------------
SpawnCommand("punlearn lightcurve");
#-------------------------------------------------------------------------------
# Prepare output files.
open(SOURCE_FILE, "${catalog}") || die "\ncannot open $catalog\n";
$temp_file = "lightcurve.temp";
#-------------------------------------------------------------------------------
# Process catalog file.
# Define field delimiters as spaces and tabs.
# We do NOT use \s because we do NOT want to include \n as a delimiter!
# We use * multiplier (zero or more) so that initial whitespace is optional.
$ws = "[ \t]*";
$source_num = 0;
while (<SOURCE_FILE>)
{
# Parse a line of the ASCII table.
# We use S* instead of S+ to keep the matching "greedy", i.e. to NOT split
# a single number into multiple tokens.
($xx, $yy, $radius, $source_name) = /$ws(\S*)$ws(\S*)$ws(\S*)$ws(\S*)/;
# The parsing statement above could be replaced by:
# s/^$ws//; remove leading whitespace
# ($xx, $yy, $radius, $source_name) = split(/$ws/);
# Create names for this source and for its event list.
if ($source_name EQ "")
{$source_name = sprintf("%4.4d",$source_num);}
printf( "\n\n%s\nSOURCE: %s at (%6.1f, %6.1f)\n", "-" x 80, $source_name, $xx, $yy );
if ($opt_flat)
{$path = "";}
else
{
$path = "$source_name/";
}
# Construct name of source event list.
$source_file = sprintf("%s%s%s.evt", $path, $source_name, $suffix);
$lightcurve_file = sprintf("%s%s%s.lc", $path, $source_name, $suffix);
# Count the events.
$_ = `dmlist ${source_file} blocks`;
/[.\n]*EVENTS.+x *(\d+)/;
$num_events = $1;
if ($num_events < 400)
{
$nbins = 10;
}
else
{
$nbins = 20;
}
if ($num_events > 0)
{
# If the source falls on one CCD only then we can make a light curve.
$_ = `dmstat \"${source_file}\[cols ccd_id\]\"`;
/[.\n]*min\D+(\d+).*\n.*max\D+(\d+)/;
if ($1 == $2)
{
# Because lightcurve tool uses whichever GTI table is referenced in DSREF?, we must
# filter by ccd_id so we have only one GTI table!!!!!
$ccd_id = $1;
SpawnCommand("dmcopy \"${source_file}\[ccd_id=$ccd_id\]\" ${temp_file} clobber=yes");
# Double check that DSREF? has the correct value.
$_ = `dmlist $temp_file header,raw | grep " DSREF"`;
/.*GTI(\d)/;
if ($1 EQ $ccd_id)
{
# Sort the events & compute a lightcurve.
SpawnCommand("fsort $temp_file TIME method=heap ascend=yes unique=no");
SpawnCommand("lightcurve infile=$temp_file bkgfile=NONE outfile=$lightcurve_file nbins=$nbins binlength=0 counts_per_bin=0 errtype=gaussian clobber=yes");
}
else
{
printf("\nERROR! Cannot find keyword DSREF* pointing to GTI${ccd_id}\n");
}
}
else
{
printf("\nSource %s spans multiple CCDs; no light curve produced!\n", $source_name);
}
}
$source_num++;
}
close(SOURCE_FILE);
unlink ${temp_file};
printf("\nlightcurve FINISHED\n");
exit;
#===============================================================================
sub SpawnCommand {
local $command = $_[0];
print " $command\n";
print `$command`;
}
This archive was generated by hypermail 2b29 : Thu Dec 13 2012 - 01:00:06 EST