*Table of Contents Previous Chapter Next Chapter

6.0 Simulated ACIS Telemetry

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.

6.1 fepCtlTest--simulate the ACIS front-end processor

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).

TABLE 23. fepCtlTest Command Syntax
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
  • FEP_BEP_CMD_BIAS start bias calibration
  • BEP_BEP_FEP_CMD_TIMED start timed exposure
  • BEP_FEP_CMD_CCLK start continuous clocking
  • BEP_FEP_CMD_STOP stop the run
  • BEP_FEP_CMD_PARAM read parameters
  • BEP_FEP_CMD_SUSPEND temporarily halt
  • BEP_FEP_CMD_RESUME resume after suspension
  • BEP_FEP_CMD_STATUS return FEP status
  • BEP_FEP_CMD_FIDPIX
  • define fiducial pixels1
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:
  • FEP_NO_PARM
  • FEP_TIMED_PARM_RAW
  • FEP_TIMED_PARM_HIST
  • FEP_TIMED_PARM_3x3
  • FEP_TIMED_PARM_5x5
  • FEP_CCLK_PARM_RAW
  • FEP_CCLK_PARM_1x3
nrows number of rows in a CCD frame
ncols number of pixels per row per node
quadcode node clocking code:
  • FEP_QUAD_ABCD
  • FEP_QUAD_AC
  • FEP_QUAD_BD
noclk number of overclocks per row per node
nhist number of frames per histogram
btype type of bias calibration to perform
  • FEP_NO_BIAS
  • FEP_BIAS_1
  • FEP_BIAS_2
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"
  1. this feature is not currently supported in the ACIS BEP detailed design, but has been included in the FEP software.
  2. see Table 45 and Table 46 of the ACIS Flight Software Detailed Design Specification (36-53200 Rev. 01+) for more details of bias parameters

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.

6.2 dumpring--display ring-buffer records

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.

6.3 tlmsim--create simulated telemetry packets

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://acis.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.

6.3.1 Bias Map

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.

6.3.2 Timing

The order of the science packets is as follows:

TABLE 24. Order of Science Packets from tlmsim
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.

  1. 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.

  2. 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.

  3. 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.

  4. 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.

  5. 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).

6.3.3 Miscellaneous

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.

6.4 Examples

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 
  }
	  

7.0 ACIS Timing Algorithms

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.

7.1 Determining the Start Time of an Exposure (single exposure time)

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.

  1. 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.

  2. 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.

  3. 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)
    	  

  4. 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
    	
  5. 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.

  6. 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.

  7. 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.)

7.2 Determining the Start Time of an Exposure (two exposure times)

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:

  1. Compute runStartTime + startupTicks, as above.

  2. 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.

  3. Compute the total number of primary exposures and exposure cycles.

        primaryCount = integer((dutyCycle + n) / (dutyCycle + 1))
        cycleCount = integer(n / (dutyCycle + 1))
    	  
  4. 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.

  5. Follow steps 4-7. of the preceding section to translate exposureStartTimen to UTC.


Table of Contents Previous Chapter Next Chapter
Peter G. Ford
Last modified: Mon Nov 25 18:04:52 EST