Processing ACA Monitor Window Data
CIAO 4.16 Science Threads
Overview
Synopsis:
The Aspect Camera Assembly (ACA) is capable of providing simultaneous optical monitoring of a target during an observation. This thread describes the steps involved in processing the ACA monitor data.
Purpose:
Generate a photometric light curve for a Chandra target which was observed using an ACA monitor window. This is accomplished by use of the monitor_photom script.
Related Links:
Last Update: 13 Feb 2023 - Updated thread with new default dither parameters after 01 October 2022.
Contents
- Background Information
- Get Started
- Merge the Data Files (if necessary)
- Run the monitor_photom script
- Examine the Results
- Problem Case: Lost faint star track
- Advanced Support
- History
-
Images
- Figure 1: Dark Current Histogram
- Figure 2: ACA Monitor Data: magnitude and count rate
- Figure 3: Power Spectrum of ACA Optical Monitor light curve
- Figure 4: Period Folded Light Curve
- Figure 5: ACA Monitor Data for Problematic OBS_ID 4924
- Figure 6: ACA Monitor Window readout coordinates
- Figure 7: ACA Monitor Data: magnitude and count rate (zoom)
Background Information
This thread assumes familiarity with the basic ACA operating principles as described in the Pointing Control and Aspect Determination System chapter of the Proposers' Observatory Guide (POG). This includes the concepts of image slots and readout windows.
The key challenge in deriving a photometric light curve from ACA monitor window data is determining the background dark current. Due to ionizing radiation in the space environment, more than 1/3 of the pixels on the ACA CCD have detectable damage as manifested by an elevated dark current, as shown in Figure 1.
Figure 1: Dark Current Histogram
The main Gaussian peak of the dark current distribution, representing undamaged pixels, dominates below about 30 e-/sec. Above that value the pixels have been damaged by cosmic radiation. In aspect pipeline processing a pixel with a dark current of more than 200 e-/sec is considered "warm" because at this level centroiding can be perturbed. A 15th magnitude source produces only about 500 e-/sec, so for faint sources the impact of these warm pixels is significant. To make matters worse, many warm pixels show time dependent flickering behavior in which the pixel dark current can abruptly change by a factor of two or more. This flickering occurs on time scales of thousands of seconds, making it essentially impossible to produce a reliable dark current map using the ACA calibration mode. Instead we use on-the-fly warm pixel detection.
The basic idea of the detection algorithm is to sample pixels from the outer edge of the 8x8 pixel readout window and look for values higher than a threshold. At the edge the contamination of the dark current measurement from the monitor star is minimized. Since the readout window moves with respect to the CCD due to dither, the edge pixels end up sampling much of the CCD region used for imaging. In this way one can build up a map of warm pixels.
There are three limitations to the algorithm:
-
Background pixel sampling is not complete nor uniform.
-
For brighter stars even the edge pixels have significant contribution from the star light so it is not possible to get a true dark current measurement. The dark_ratio tool parameter (see below) specifies that the warm pixel threshold be no less than dark_ratio * avg_source_counts.
-
The current algorithm in the monitor_photom script does not account for flickering, though this could be done with some effort.
Get Started
Download the sample data: 11022 (ACIS-S, HD119515)
unix% download_chandra_obsid 11022 adat
Only monitor window data processed with an ASCDSVER of DS 7.6.0 or higher should be used in this thread.
Note that monitor window data are only available if the observer has specified target photometry (Photometry=Y) in the observation setup. This can be determined by examining the Obscat parameters, available via Web Chaser for a specific ObsID.
Obtaining the ACA image data
The PCAD Level 1 ACA image data files (pcad...adat71.fits) are secondary data products. They can be retrieved using download_chandra_obsid They will be located in the secondary/aspect directory.
unix% /bin/ls -1 11022/secondary/aspect/pcad*adat71.fits.gz 11022/secondary/aspect/pcadf383724410N003_adat71.fits.gz
Or they can be retrieved via WebChaser by selecting the Secondary data products.
About the data files
These files contain the processed ACA telemetry and image data for the observation. The "7" in "adat71" refers to image slot 7, which is the slot where monitor window data always appear. While there may be many more files in the data package (i.e. adat01 - adat61), this thread will only be using the adat71.fits data.
The key data columns in this file are:
Name | Unit | Datatype | Description |
---|---|---|---|
time | sec | Real8 | Time at start of integration |
aca_comp_bkg_avg | count | Real4 | Image background level (e-) |
img_raw[8,8] | adu | Real4(8x8) | Raw image from ACA |
img_corr[8,8] | count | Real4(8x8) | Calibrated image (e-) |
fit_resid[8,8] | count | Real4(8x8) | Gaussian fit residuals (e-) |
img_row0 | pixel | Int2 | Row position of lower left pixel |
img_col0 | pixel | Int2 | Column position of lower left pixel |
img_excl[8,8] | Byte(8x8) | Exclude pixel flag |
Merge the Data Files (if necessary)
Typically the image data are split over a number of files, so the first step is to merge the ACA image data into a single file using dmmerge. This observation only has a single file so no merging is necessary. The steps below are shown as reference for other datasets that have multiple files:
unix% gunzip *adat71.fits.gz unix% ls -1 *adat71.fits > adat71.lis unix% cat adat71.lis pcadf383724410N003_adat71.fits unix% dmmerge infile=@adat71.lis outfile=pcad_adat71.fits
The ACA files are input to the tool as a stack; see ahelp stack for more information.
Run the monitor_photom script
The main processing steps of the monitor_photom script are:
-
Read the image data file.
-
Median filter image data in time on a pixel-by-pixel basis to remove cosmic rays.
-
Search for "warm" pixels that have a dark current well outside the normal distribution. These pixels can significantly affect photometry as they dither in and out of the 8x8 pixel image readout window.
-
Subtract the background from each image readout. For warm pixels the detected value for that pixel is used, while for all others the median background dark current reported by the ACA is used.
-
Produce light curves in counts, counts/sec, and mags.
This script has a parameter file associated with it:
unix% plist monitor_photom Parameters for /home/user/cxcds_param4/monitor_photom.par infile = ACA image data file outfile = Output light curve (dark_ratio = 0.005) Dark ratio (min_dark_limit = 80.0) Minimum warm pixel dark current (min_dark_meas = 10) Minimum warm pixel measurements (max_dither_motion = 10) Maximum possible dither motion (pixels) (verbose = 0) Amount of tool chatter (clobber = no) Remove output file if it already exists? (mode = ql)
The parameters dark_ratio, min_dark_limit, and min_dark_meas affect the way in which warm pixels are detected. The default values in the supplied parameter file are a good starting place, but it is often helpful to adjust the the dark_ratio and/or min_dark_limit to obtain better results.
Now run the script with the merged pcad_adat71.fits file as input:
unix% monitor_photom infile=pcad_adat71.fits outfile=monitor_lc.fits verbose=1 monitor_photom infile = pcad_adat71.fits outfile = monitor_lc.fits dark_ratio = 0.005 min_dark_limit = 80 min_dark_meas = 10 max_dither_motion = 10 verbose = 1 clobber = no mode = ql Filtering image data (cosmic ray removal)... Stacking dark current data... Average counts (e-) = 29882.9175202 Warm dark limit (e-) = 149.414587601 Warm pixel at CCD (row,col) = (-6,8) Dark current (e-) = 390.0 Warm pixel at CCD (row,col) = (-13,9) Dark current (e-) = 320.0 Warm pixel at CCD (row,col) = (-7,10) Dark current (e-) = 160.0 Warm pixel at CCD (row,col) = (-11,11) Dark current (e-) = 215.0 Warm pixel at CCD (row,col) = (-7,11) Dark current (e-) = 280.0 Warm pixel at CCD (row,col) = (-5,13) Dark current (e-) = 345.0 Warm pixel at CCD (row,col) = (-6,16) Dark current (e-) = 355.0 Warm pixel at CCD (row,col) = (-9,17) Dark current (e-) = 185.0 Warm pixel at CCD (row,col) = (-9,18) Dark current (e-) = 215.0
The script does cosmic ray removal, reports on the average image counts (in e- for the 1.696 second integration) and the minimum dark current for warm pixels, and then makes a dark current stack to detect warm pixels.
The light curve is written to the specified FITS file (monitor_lc.fits). It contains columns with the time, counts, count rate, magnitude, and background-subtracted image. The magnitude is defined as
\[ m_{ACA} = 10.32 - 2.5 * log_{10}\left( \frac{cnt\_rate}{5263.0} \right) \]An approximate formula relating B and V magnitude to mACA is given in the POG:
\[ m_{ACA} = V + 0.426 - 1.06*(B-V) + 0.617*(B-V)^2 - 0.307*(B-V)^3 \]This is based on the typical spectral energy distribution of bright main sequence stars.
Examine the Results
A series of python commands are used as a first step in examining the results from the script:
from pycrates import read_file import matplotlib.pylab as plt lc = read_file("monitor_lc.fits") mag = lc.get_column("mag").values toff = lc.get_column("time").values toff = (toff-toff[0])/1000.0 plt.subplots(2, 1, sharex='col') plt.subplots_adjust(hspace=0.0) plt.subplot(2,1,1) plt.plot(toff,mag, marker="None") plt.ylabel(r"Image magnitude ($\mathregular{m_{ACA}}$)") plt.title("ObsID 11022 Optical Monitor Data") plt.gca().invert_yaxis() plt.subplot(2,1,2) counts = lc.get_column("count_rate").values plt.plot(toff, counts, marker="None") plt.ylabel(r"Image count rate ($\mathregular{e^-/sec}$)") plt.xlabel("Time from Obs Start (ksec)") plt.show()
The plot results are shown in Figure 2
Figure 2: ACA Monitor Data: magnitude and count rate
The data clearly shows a periodicity with an amplitude of approximately 1000 e-/sec. To check whether the periodicity is the result of the star dithering across an unidentified warm pixel, the data can be period folded at the telescope dither frequencies. The default dither frequencies for ACIS and HRC are listed below (taken from the the Chandra Proposer's Guide).
Direction | ACIS, before October 2022 | ACIS, after 01 October 2022 | HRC |
---|---|---|---|
Pitch | 707.1 sec | 1414.2 sec | 768.6 sec |
Yaw | 1000.0 sec | 2000.0 sec | 1087.0 sec |
These values are standard for most observations. Users can check for non-standard dither frequencies by checking the Details page of Web Chaser. Users can check which is the dominant frequency by computing the power spectrum of the light curve. In the example below, the mean counts are subtracted off each light curve bin to remove the 0-frequency spike in the power spectrum.
unix% dmstat "monitor_lc.fits[cols counts]" counts min: 26455 @: 1776 max: 28362.5 @: 3111 mean: 27347.435057 sigma: 314.80082893 sum: 101458984.06 good: 3710 null: 0 unix% dmtcalc monitor_lc.fits lc0.fits expr='c0=counts-27347.435057' unix% apowerspectrum lc0.fits'[cols time,c0]' none powerspec.fits crop=yes clob+
Since the data are entirely real valued, the power spectrum is symmetric about the Nyquist frequency so the data can be crop'ed. The power spectrum can now be plotted and the expected frequencies identified
from pycrates import read_file import matplotlib.pyplot as plt psout = read_file("powerspec.fits") freq = psout.get_column("frequency").values pwr = psout.get_column("data").values plt.plot(freq,pwr, marker="None", linewidth=2, color="black") plt.xscale("log") plt.yscale("log") plt.ylim(bottom=100) plt.axvline( 1.0/707.1, color="red") plt.axvline( 1.0/1000.0, color="blue") plt.xlabel(r"Frequency [$\mathregular{s^{-1}}$]") plt.ylabel("Power") plt.title("Power Spectrum of Count Data") plt.show()
As shown in Figure 3, there are two peaks in the power spectrum that correspond exactly to the two dither frequencies, confirming that the periodicity is induced by dither.
Figure 3: Power Spectrum of ACA Optical Monitor light curve
The light curve data can now be folded at the 707.1 sec dither frequency. This is done using the NumPy mod (modulo) operation.
from pycrates import read_file import matplotlib.pylab as plt import numpy as np tab = read_file("monitor_lc.fits") tt = tab.get_column("time").values cc = tab.get_column("counts").values fold = np.mod( tt, 707.1 ) plt.plot(fold,cc,marker="o",linestyle="None",fillstyle="none") plt.xlabel("Time modulo 707.1 [sec]") plt.ylabel("Counts [e-]") plt.title("Period Folded Light Curve for ObsId 11022") plt.show()
The data after being folded are shown in Figure 4. The sinusoidal pattern is the indication that the period chosen to fold the data was correct.
Figure 4: Period Folded Light Curve
Problem Case: Lost faint star track
There are situations when the ACA cannot track the optical monitor star. When that happens the utility of the optical monitor data becomes limited. One such example is OBS_ID 4924.
Download the sample data: 4924 (ACIS-S, Mrk 590)
unix% download_chandra_obsid 4924 adat
When the monitor_photom script is run on the merged pcad_adat71.fits files, the results are shown in Figure 5
Figure 5: ACA Monitor Data for Problematic OBS_ID 4924
There is an obvious jump around 17 ksec into the observation which is due to a limitation of the ACA flight software. Because the source in a monitor window may not be bright enough for the ACA to independently track, the ACA relies on the motion of another "designated track star" to move the monitor window in lock step. However, if this designated track star is lost by the ACA, even momentarily, then the ACA stops moving the monitor window and leaves it fixed at its last position on the CCD. Instead of the monitor window tracking the motion of the source as Chandra dithers, the source now dithers within the fixed window, possibly going completely outside the readout window. This can be explicitly seen via manipulation of the image data file:
from pycrates import read_file import matplotlib.pylab as plt dat = read_file("pcad4924_adat71.fits") toff = dat.get_column("time").values row = dat.get_column("img_row0").values col = dat.get_column("img_col0").values toff = (toff-toff[0])/1000.0 plt.subplots(2, 1, sharex='col') plt.subplots_adjust(hspace=0.0) plt.subplot(2,1,1) plt.plot(toff,row, marker="None") plt.ylabel("Readout window row") plt.title("ObsID 4924 Optical Monitor Data") plt.xlim(12,22) plt.subplot(2,1,2) plt.plot(toff,col, marker="None") plt.ylabel("Readout window column") plt.xlabel("Time from Obs Start (ksec)") plt.xlim(12,22) plt.show()
These commands result in Figure 6
Figure 6: ACA Monitor Window readout coordinates
The impact to the photometry due to not tracking the source can be seen in Figure 7.
Figure 7: ACA Monitor Data: magnitude and count rate (zoom)
The dither pattern is no longer due to the source dithering across warm pixels, but instead is due to the stationary ACA monitor window dithering onto the source. The data after the loss of tracking is not generally useful.
Advanced Support
If the monitor photometry data indicate scientifically interesting results worthy of detailed study, users may wish to contact aspect_help@cfa.harvard.edu for further advice on possible techniques to reduce the systematic errors.
History
12 Jul 2005 | original version, new for CIAO 3.2 |
14 Dec 2005 | updated for CIAO 3.3: adat71.fits filenames updated to match results from ChaSeR |
01 Dec 2006 | updated for CIAO 3.4: adat71.fits filenames updated to match results from ChaSeR; ChIPS version |
21 Apr 2014 | Updated for CIAO 4.6; new version of script required. |
01 May 2014 | Replaced problematic obsid 4924 with 11022. |
22 Dec 2014 | Review for CIAO 4.7; modified equations to use mathjax. |
03 Apr 2019 | Updated to use matplotlib for plotting. |
09 Dec 2019 | Updated for matplotlib 3.1 |
31 Jan 2022 | Review for CIAO 4.14. Updated for Repro5 and CALDB 4.9.6. |
13 Feb 2023 | Updated thread with new default dither parameters after 01 October 2022. |