This chapter describes how to generate a simulated ACIS timed-exposure telemetry stream. It proceeds in two steps. First, the FEP simulator reads commands and input data in the form of 16-bit FITS images, creating one or more "ring-buffer" files and bias maps. In the second step, these files are used to produce the telemetry stream.
The simulator can read a command script from its standard input stream, stdin, or behave like a command shell, as in the following example of a timed-exposure science run. The first group of "set" commands specifies the location of the input FITS image files, and the location of pixels and overclocks within those images. The second group uses "param" commands to define FEP-to-BEP run-time parameters, followed by an "exec" command to store them in the FEP, another to compute the bias map, and a "dumpbias" command to copy the bias map to a disk file. The third group uses the "output" command to direct subsequent output to a disk file, and then executes the simulated timed-exposure run.
#! /acis/h3/tools/bin/fepCtlTest # # Test images use CCD image frames with fe55 and co60 # set input = /cdrom/ccid17-38-3/fe55co60/fe55+Co60_nowin_120.%04d.fits set rows = 2,1025 set pixels = 4,259,344,599,684,939,1024,1279 set overclocks = 260,336,600,676,940,1016,1280,1356 # fepTimedBias() full-frame bias, 4 nodes # param type = FEP_TIMED_PARM_3x3 param nrows = 1024 param ncols = 256 param quadcode = FEP_QUAD_ABCD param noclk = 16 param nhist = 0 param btype = FEP_BIAS_1 param thresh[0] = 100 param thresh[1] = 100 param thresh[2] = 100 param thresh[3] = 100 param bparm[0] = 5 param bparm[1] = 10 param bparm[2] = 0 param bparm[3] = 100 param bparm[4] = 70 param nskip = 0 param initskip = 0 # exec BEP_FEP_CMD_PARAM exec BEP_FEP_CMD_BIAS dumpbias feco.bias.te.fframe # fepSciTimed() in 3x3 event mode # set output = feco.ring.te.3x3 exec BEP_FEP_CMD_TIMED
This script causes two files to be written--"feco.bias.te.fframe" to contain the bias map and "feco.ring.te.3x3" to contain the events. The former can be viewed by any FITS image reader, the latter by the dumpring command (see 6.2).
Command | Description |
---|---|
dumpbias file
|
write an already-computed bias map to file in FITS format |
exec cmd
|
execute a BEP-to-FEP command--one of the following
|
fidpix = row col...
|
define one or more fiducial pixels1 |
param name = val
|
set a BEP-to-FEP parameter--one of the
following2
type of parameter block:
nrows number of rows in a CCD frame
ncols number of pixels per row per node
quadcode node clocking code:
noclk number of overclocks per row per node
nhist number of frames per histogram
btype type of bias calibration to perform
thresh[4] event detection thresholds for each node
bparm[5] bias calibration parameters
nskip timed exposure skip factor
|
reset ctr
|
reset an internal simulator counter. Currently, the only counter recognized is "wakeup". |
set buf [row,col] = val
|
set an element of the 2-dimensional buf array.
buf is either "bias" or "biasparity"
|
set input = file
|
subsequent bias calibrations or science runs will read pixel data
from file , a set of FITS images whose name
should contain a numeric "printf" format string, e.g. "%04d" which
will be replaced by the integers 1,2,3,... when the FEP simulator
opens successive input FITS files.
|
set output = file
|
subsequent "ring buffer" output will be written to
file.
See 6.2
for details of ring-buffer formats
|
set overclocks = p1,p2,p3,p4...
|
specify the ranges of overclock pixels in each raster of the input
file. Node A's overclocks will span columns p1
through p2 (indexing from 0), Node B's will
span p3 through p4 , etc.
|
set pixels = p1,p2,p3,p4,...
|
specify the ranges of data pixels in each raster of the input file.
Node A's pixels will span columns p1 through
p2 (indexing from 0), Node B's will span
p3 through p4 , etc.
|
set rows = r1,r2
|
specify the range of input image rows, indexed from 0. If omitted, the range will begin with the first row and will continue for the number of rows specified by the "param nrows" command. |
stuff param name = val
|
used in unit and coverage testing to force a BEP parameter to a
particular value, bypassing the normal range checking applied to a
BEP_FEP_CMD_PARAM command.
|
xor buf [row,col] = val
|
perform an exclusive OR of val with an element of the
2-dimensional buf array, storing the result
back into the array. buf is either "bias" or "biasparity"
|
fepCtlTest assumes that the input FITS files contain 16-bit pixels in big-endian format (most-significant byte first). Only the least significant 12 bits of each pixel will be used. The bias maps will also be written in 16-bit FITS format, but in little-endian format (least-significant byte first), irrespective of whether fepCtlTest is compiled for little- or big-endian machines. This is not the case with the ring-buffer output files--their byte ordering will depend on the architecture of the machine running fepCtlTest.
This is a perl script that converts the contents of a binary ring-buffer file to ASCII text. It recognizes only a single command-line argument, the name of the input file. If omitted, it reads from stdin. The formats of the various ring-buffer records are defined in 4.10 of the ACIS Flight Software Detailed Design Specification (36-53200 Rev. 01+). dumpring inspects the first few records to determine the byte-order, little- or big-endian. It writes a formatted ASCII listing on stdout, as in the following example:
FEPexpRec[1] = { expnum = 1 timestamp = 0x05234672 bias0 = 180 184 181 184 dOclk = 0 0 0 0 } FEPeventRec3x3[1,1] = { row = 2 col = 1017 p,b = { 227 602 619 } { 210 210 210 } = { 211 1014 936 } { 210 210 204 } = { 213 211 209 } { 209 209 203 } } FEPeventRec3x3[1,2] = { row = 4 col = 448 p,b = { 180 166 174 } { 166 164 164 } = { 190 1981 166 } { 166 722 160 } = { 171 658 168 } { 165 168 168 } } . . FEPexpEndRec[1] = { expnum = 1 thresholds = 3765 parityerrs = 0 } FEPexpRec[2] = { expnum = 2 timestamp = 0x0540f48b bias0 = 180 184 181 184 dOclk = 0 0 0 0 } . .
dumpring numbers the records consecutively, beginning
with 1. Note that the BEP numbers its exposures beginning with 0,
i.e. it subtracts 1 from the exposure numbers reported by the FEPs,
which use exposure number 0 to indicate their state before the first
exposure has been received. Thus, in the above example, the
start-of-exposure record FEPexpRec[1] is matched by the end-of-exposure
record FEPexpEndRec[1]
. In between, the event records are
FEPeventRec3x3[1,n], where the event index n also starts
at 1.
This command combines a pair of files created by fepCtlTest, a ring-buffer and a bias map, into a stream of ACIS test packets. In addition to these files, tlmsim must be provided with suitable parameter and window blocks to include in its output. It is described in detail in Section 10.31.
The output stream contains two sorts of packets--ACIS science packets and science frame pseudo-packets (SFPP). They share a common format, as described in Table 3, but serve different functions. Remember that all ACIS telemetry fields, including those in pseudo-packets, are recorded in little-endian order, with less significant bytes preceding more significant.
The science packets simulate the ACIS serial telemetry stream that would be written to the "science data" portion of each Format-2 AXAF telemetry frame, or into the next-in-line field in Format 1. Their contents are described in the ACIS IP&CL documents and in "http://acisweb.mit.edu/acis/ipcl". Inter-packet padding has been removed. However, the real ACIS instrument also inserts 4-byte time tags into its serial telemetry whenever it receives a science frame pulse. Since these tags could appear at any offset within a packet, it is inappropriate to include them in tlmsim's science packets. If users wishes to simulate them, they must specify the -p option, causing tlmsim to write them as pseudo-packets.
The size of the bias map is taken from the FITS header variables NAXIS1 and NAXIS2. It is usually 1024 rows and 1024 columns. tlmsim formats it into dataTeBiasMap packets, two rows per packet. This version of tlmsim is unable to compress the 12-bit data, so it reports the compressionTableSlotIndex as 255 (no compression).
The initialOverClocks fields in the dataTeBiasMap packets are copied from the ring-buffer file, so it is important that the ring-buffer and bias map files should have been generated from the same fepCtlTest input data.
The order of the science packets is as follows:
1 | bepStartupMessage |
simulating an ACIS commanded reset |
1 | CommandEcho |
executing a loadTeBlock command |
1 | CommandEcho |
executing a startScience command |
1 | CommandEcho |
reporting the current teBlock and window2d block |
many | dataTeFaintBias |
bias map packets interleaved with event and exposure packets |
many | exposureTeFaintBias |
|
many | dataTeBiasMap |
|
1 | commandEcho |
executing a stopScience command |
1 | scienceReport |
reporting the statistics of the run |
dataTeBiasMap |
remaining bias packets until the entire map is reported |
If the -p option is specified, a SFPP will be written inserted once per science frame, i.e. every 2.05 seconds of "real" instrument time, determined by counting the length of the science packets and assuming that they are filling the available telemetry bandwidth (512 bps in Format-1 and 24 kbps in Format-2). tlmsim normally simulates Format-2. Use the -f flag to create (48 times as many!) Format-1 pseudo-packets.
An AXAF/ACIS telemetry stream contains 5 types of timing information, each of which is simulated independently.
fepTimestamp
: the 25-bit value of the FEP's
megahertz counter which would be latched whenever the start of
a new frame were received (VSYNC from PRAM). The simulated value
is taken from the ring-buffer records created by
fepCtlTest, which currently uses the value of the
UNIX microsecond timer for this field.
bepTimestamp
: the 32-bit value of the BEP's
megahertz counter which would be latched (a) whenever a S/C
science pulse is received or (b) whenever the BEP sends a
"start processors" command to the DEA(s). The former would be
inserted synchronously into the telemetry, and is simulated by
tlmsim as the bepSciTime field in the SFPP;
the latter would be reported as biasStartTime and runStartTime in
science packets. They are simulated as the instantaneous value of
theUNIX microsecond timer, except that the biasStartTime is then
arbitrarily decreased by 120 seconds.
bepTickCounter
: the BEP also contains a
10 Hz counter whose value would be reported as the bepTickCounter
field in the bepStartupMessage packet and the arrival field of
commandEcho packets. tlmsim assigns an initial
value of 500 to this counter, and increments it within subsequent
packets according to the time elapsed as read from the UNIX
microsecond timer.
majorFrameId
and minorFrameId
:
these SFPP fields contain the VCDU fields that would occur
at the start of each AXAF telemetry minor frame.
They are simulated by keeping count of the telemetry mode (the
-f flag) and of the data volume being written.
minorFrameId
is incremented for every 750 bytes
of ACIS data (8 bytes in Format-1), and
majorFrameId
is incremented every 128 minor frames.
Both are initialized to zero at the start of the simulation.
IRIGB
: the day and second count in the SFPPs
are initialized from the UNIX system clock, and the milli- and
micro-second timers are initialized to zero. They are incremented
by 0.25625 seconds for each minor frame (750 bytes of ACIS data
in Format-2, 8 bytes in Format-1).
The tlmsim output always assigns correct lengths to telemetry packets and to encapsulated commands and parameter blocks. It numbers the science packets sequentially from zero (in the sequenceNumber fields), and computes correct checksums. All commands are executed successfully (CMDRESULT_OK in the result field of commandEcho packets), and all events in the ring-buffer file are copied to telemetry packets--none is removed by (simulated) BEP filters. The only errors that are simulated are instances of bias map corruption within the FEP. They are created by including "xor parity" or "xor parityplane" commands within the fepCtlTest script, and they result in errors being written to the ring-buffer file and thence to dataBiasErr packets in the tlmsim output stream.
In the simplest case, the output from tlmsim may be piped directly into ltlm, e.g.
tlmsim -c te.1 -p -w win.1 ring.1 bias.1 | ltlm | more
If you only want to inspect packets of a particular type, e.g. exposureTeFaintBias whose formatTag value is 22, invoke ltlm with the -p 22 option. If you also want to see dataTeFaintBias packets (formatTag 23), use -p22 -p23 together. If you forget a formatTag value, invoke ltlm -lt with no other arguments to list them all.
ltlm -v -p22 -p2 tlm.out11 | more dataTeFaintBias[0] = { synch = 0x736f4166 telemetryLength = 1021 formatTag = TTAG_SCI_TE_DAT_FAINTB (23) sequenceNumber = 11 ccdId = 6 fepId = 2 dataPacketNumber = 0 events = [138] } . . . dataTeFaintBias[36] = { synch = 0x736f4166 telemetryLength = 675 formatTag = TTAG_SCI_TE_DAT_FAINTB (23) sequenceNumber = 237 ccdId = 6 fepId = 2 dataPacketNumber = 10 events = [91] } exposureTeFaintBias[2] = { synch = 0x736f4166 telemetryLength = 20 formatTag = TTAG_SCI_TE_REC_FAINTB (22) sequenceNumber = 238 runStartTime = 0x619a9cf4 parameterBlockId = 0x00000fab windowBlockId = 0x00000baf biasStartTime = 0x5a75d31b biasParameterId = 0x00000fab ccdId = 6 fepId = 2 fepTimestamp = 0x015e661d exposureNumber = 2 eventsSent = 1471 thresholdPixels = 3672 discardEventAmplitude = 0 discardWindow = 0 discardGrade = 0 deltaOverclocks = 1 0 0 0 biasParityErrors = 0 initialOverclocks = 180 184 181 184 }
Note that, rather than listing the contents of a large array such as events, ltlm merely lists the number of elements within square brackets. If you wish to see the array values themselves, invoke ltlm with the -v flag, viz.
ltlm -v -p22 -p23 tlm.out11 | more dataTeFaintBias[0] = { synch = 0x736f4166 telemetryLength = 1021 formatTag = TTAG_SCI_TE_DAT_FAINTB (23) sequenceNumber = 11 ccdId = 6 fepId = 2 dataPacketNumber = 0 events[0] = { ccdRow = 2 ccdColumn = 1017 pulseHeights = 227 602 619 211 1014 936 213 211 209 biasValues = 210 210 210 210 210 204 209 209 203 } events[1] = { ccdRow = 4 ccdColumn = 448 pulseHeights = 180 166 174 190 1981 166 171 658 168 biasValues = 166 164 164 166 722 160 165 168 168 } events[2] = { ccdRow = 6 ccdColumn = 646 pulseHeights = 177 169 178 175 2525 172 176 177 171 biasValues = 170 167 167 169 165 165 173 168 168 }
This section provides a guide for producing algorithms which map
science run times to observatory time and hence to UTC and TDB. The BEP
and FEP counters are driven by the BEP's internal clock which will
drift relative to Spacecraft Event Time (SCET), i.e., any
counter that is driven by the spacecraft's ultra-stable 1024000 Hz
oscillator, and this drift must be modeled in order to assign accurate
SCETs to events within ACIS. In this section, ACIS telemetry packet
fields will appear in monotype
.
When ACIS receives a Science Frame Pulse from the spacecraft, it
preserves the 32-bit value of its internal 100 kHz timer and
immediately writes it to the serial telemetry stream, inserting
it into any telemetry packet that it might be writing at the time. The
first 4 bytes of ACIS science telemetry following a Science Frame Pulse
will always contain this timestamp, called refTime
in this
section. Since Science Frame Pulses occur every 2.05 seconds, and can
be related to UTC via the VCDU counters in the telemetry minor frame
headers, it is possible to relate refTime
itself, and
hence any arbitrary value of the BEP 100 kHz clock, to UTC.
Section 7.1 describes how to
determine the UTC timeline when ACIS is operating either in Continuous
Clocking mode (i.e. via a CMDOP_START_CC
command) or in
Timed Exposure Mode (CMDOP_START_TE
) with a single
exposure time (dutyCycle=0
in the current
teBlock
). When dutyCycle
is non-zero, a
single exposure of length primaryExposureTime
will be
followed by dutyCycle
exposures lasting
secondaryExposureTime
. This situation is covered in
Section 7.2.
Since it takes a finite time to move the image out of each CCD, the X-Ray integration time of a timed exposure is less than the time from one exposure to the next. The following describes the overall steps in determining the start time of a timed exposure (or of a particular image frame in continuous-clocking mode.) The method first computes the time in units of the BEP clock, and then relates that to observatory time through the synchronous science header timestamps.
Determine runStartTime
, the starting time of the
science run in BEP timer units. It is reported in the
scienceReport
packet that terminates the run, as well
as in each individual exposure
packet.
Add the DEA startup time, startupTicks
.
This is the initial delay, in BEP clock units, between the commanded start-of-run time and the start of the first CCD exposure period. It is a function based on the clocking parameters and method. This function will be provided as part of the AS-BUILT ACIS Software Detailed Design Specification, MIT 36-53200.
Inspect any pair of consecutive fepTimestamp
values
in exposure
packets.
If fepTimestampi-1
is less than
fepTimestampi
, exposure n
starts at
exposureStartTimen = runStartTime + startupTicks + n * (fepTimestampi - fepTimestampi-1)expressed in BEP timer units. Otherwise, if the FEP time-stamp of exposure
i
is less than that of exposure
i-1
, the counter has wrapped, and the start time
of exposure n
is
exposureStartTimen = runStartTime + startupTicks + n * (225 + fepTimestampi - fepTimestampi-1)
Now examine a pair of AXAF telemetry science frames generated during the run.
The first 4 bytes of ACIS science data in frame number
i
contain the science header timestamp
(refTimei
).
If refTimei+1
is greater than
refTimei
, the number of BEP clock ticks per
2.05 second science frame is
ticksPerFrame = refTimei+1 - refTimei
Otherwise, if refTimei+1
is less than
refTimei
,
ticksPerFrame = 232 + refTimei+1 - refTimei
Locate the science frame time-stamp nearest to
exposureStartTimen
.
This should occur at the science frame numbered nf
,
where
nf = i + integer((exposureStartTimen - refTimei)/ticksPerFrame)
The frame i
should be chosen close to the start of the
run. If refTimei
is less than
runStartTime
, use instead
nf = i + integer((exposureStartTimen - refTimei - 232)/ticksPerFrame)
Drift between the BEP clock and the observatory clock may be enough
to cause an error in calculating nf
, so a search should
be made through nearby science frames for the one with the
refTime
value closest to
exposureStartTimen
.
Extract or compute the Universal Time
(frameUTnf
)
corresponding to the start of the frame.
This operation is determined by the contents of the spacecraft science frame. It was originally planned to store the estimated UTC values directly into the header fields of each science telemetry frame. It is now proposed to store only the telemetry frame sequence number, and derive UTC during ground processing. The actual method chosen to relate the start of the telemetry frame to UTC is beyond the scope of this document.
Determine the precise observatory time of the start of exposure
n
:
exposureUTn = frameUTnf + 2.05 * (exposureStartTimen - refTimenf)/ticksPerFrame
where 2.05 represents the time in seconds between successive science frame pulses (corresponding to 8 minor frames of 1025 bytes each at a rate of 32,000 bits per second; actual telemetry rates may differ.)
The following describes the overall steps in determining the start time of a particular exposure in Timed-Exposure Mode when two exposure times are used:
Compute runStartTime + startupTicks
, as above.
Inspect several consecutive exposure
records and
compute three repetition intervals.
int1 = fepTimestampi - fepTimestampi-1 int2 = fepTimestampi+1 - fepTimestampi int3 = fepTimestampi+2 - fepTimestampi+1
where exposure number i
is evenly divisible by
(dutyCycle+1
). If any of these rates is negative,
increment it by 225.
Compute the total number of primary exposures and exposure cycles.
primaryCount = integer((dutyCycle + n) / (dutyCycle + 1)) cycleCount = integer(n / (dutyCycle + 1))
Compute the exposure starting time in BEP timer units.
exposureStartTimen = runStartTime + startupTicks + (n - primaryCount - cycleCount) * int1 + primaryCount * int2 + cycleCount * int3 + (cycleCount - primaryCount) * (E2 - E1)
where E1
and E2
are, respectively, the commanded primaryExposureTime
,
and secondaryExposureTime
from the timed exposure
parameter block, converted to BEP clock units.
Follow steps 4-7.
of the preceding section to translate
exposureStartTimen
to UTC.