chandra_aca.maude_decom¶
Classes and functions to help fetching ACA telemetry data using MAUDE.
Telemetry Specification¶
Aspect telemetry is described in chapter 5 of the User’s Manual. This module deals mostly with Aspect telemetry, specified in section 5.3 of the user’s manual and section 3.2.1.15.12 of the ACA specification document EQ7-278 F.
In general, the telemetry data is specified in the following documents (available on the Aspect Twiki page):
MSFC-STD-1274B. MSFC HOSC Telemetry Format Standard
MSFC-DOC-1949. MSFC HOSC Database Definitions
Timing¶
Timing in MAUDE Telemetry¶
What follows is a summary from the user’s guide section 6, and EQ7-278 F section 3.2.1.7. Check there for more details, especially Figures 6-1 to 6-4 in the user’s manual and Figure 7 in EQ7-278 F.
The ACA updates its output in regular 1.025 second periods that either begin or end at the time of an RCTU science header pulse (which occur every 2.05 seconds). These are called update periods, following the convention in the user manual section 6.1.
The ACA CCD operating cycle starts with a flush of charge from the CCD, followed by CCD integration, CCD readout, and ends with an idle period. The start/end of the update period does not coincide with the start/end of the CCD cycle. Instead, the end of the integration coincides with the start/end of the update period. This is accomplished by adjusting the idle period.
The data from and integration period is available to the OBC at the end of the following update period (EQ7-278 F Figure 7). That is 1.025 sec after the end of integration. This is the VCDU time seen in MAUDE telemetry:
TIME = END_INTEG_TIME + 1.025
In the case of 6x6 and 8x8 images, the entire image cannot be updated in a single update period, because Aspect pixel telemetry contains only eight pixels per update. 6x6 images take two update periods, and 8x8 images take four. The end of the integration interval is the same for all the sub-images, and corresponds to:
END_INTEG_TIME = TIME - 1.025
When the choice of integration time causes the CCD cycle to last longer than the time it takes to update a full image (1.025 seconds for a 4x4 image, 2.05 seconds for a 6x6 image or 4.1 seconds for an 8x8 image) the most recent image is repeated until new pixel data is available.
Timing in level0 Data Products¶
The times for pixel telemetry in level0 data products is adjusted to coincide with the middle of the integration interval:
TIME = END_INTEG_TIME - INTEG / 2
This means that the difference between the time in telemetry and the time in the level0 data products is:
TIME<telem> - TIME<l0> = 1.025 + INTEG / 2
Global variables in this module¶
These include the following global variables
MAX_VCDU: the maximum possible VCDU frame counter value
MAX_MJF: the maximum possible major frame counter value
MAX_MNF: the maximum possible minor frame counter value
PIXEL_MAP: dict of np.array, with values mapping integer pixel indices to pixel string ID
PIXEL_MAP_INV: dict of dict, with values mapping pixel string ID to integer pixel indices.
PIXEL_MASK: dict of np.array. Values are boolean masks that apply to images of different sizes
ACA_MSID_LIST: dictionary of commonly-used ACA telemetry MSIDs.
ACA_SLOT_MSID_LIST: dictionary of ACA image telemetry MSIDs.
PIXEL_MAP contains maps between pixel indices and pixel IDm depending on the image size. In the following tables, column index increases to the right and row index increases to the top (c.f. ACA User Manual Figs 1.8 and 1.9 ):
- Size 4X41:
-----------------------------------------
| -- | -- | -- | -- | -- | -- | -- | -- |
-----------------------------------------
| -- | -- | -- | -- | -- | -- | -- | -- |
-----------------------------------------
| -- | -- | D1 | H1 | L1 | P1 | -- | -- |
-----------------------------------------
| -- | -- | C1 | G1 | K1 | O1 | -- | -- |
-----------------------------------------
| -- | -- | B1 | F1 | J1 | N1 | -- | -- |
-----------------------------------------
| -- | -- | A1 | E1 | I1 | M1 | -- | -- |
-----------------------------------------
| -- | -- | -- | -- | -- | -- | -- | -- |
-----------------------------------------
| -- | -- | -- | -- | -- | -- | -- | -- |
-----------------------------------------
- Size 6X61 or 6X62:
-----------------------------------------
| -- | -- | -- | -- | -- | -- | -- | -- |
-----------------------------------------
| -- | -- | E2 | F2 | G2 | H2 | -- | -- |
-----------------------------------------
| -- | D2 | D1 | H1 | L1 | P1 | I2 | -- |
-----------------------------------------
| -- | C2 | C1 | G1 | K1 | O1 | J2 | -- |
-----------------------------------------
| -- | B2 | B1 | F1 | J1 | N1 | K2 | -- |
-----------------------------------------
| -- | A2 | A1 | E1 | I1 | M1 | L2 | -- |
-----------------------------------------
| -- | -- | P2 | O2 | N2 | M2 | -- | -- |
-----------------------------------------
| -- | -- | -- | -- | -- | -- | -- | -- |
-----------------------------------------
- Size 8X81, 8X82, 8X83 or 8X84:
-----------------------------------------
| H1 | P1 | H2 | P2 | H3 | P3 | H4 | P4 |
-----------------------------------------
| G1 | O1 | G2 | O2 | G3 | O3 | G4 | O4 |
-----------------------------------------
| F1 | N1 | F2 | N2 | F3 | N3 | F4 | N4 |
-----------------------------------------
| E1 | M1 | E2 | M2 | E3 | M3 | E4 | M4 |
-----------------------------------------
| D1 | L1 | D2 | L2 | D3 | L3 | D4 | L4 |
-----------------------------------------
| C1 | K1 | C2 | K2 | C3 | K3 | C4 | K4 |
-----------------------------------------
| B1 | J1 | B2 | J2 | B3 | J3 | B4 | J4 |
-----------------------------------------
| A1 | I1 | A2 | I2 | A3 | I3 | A4 | I4 |
-----------------------------------------
- chandra_aca.maude_decom.blob_to_aca_image_dict(blob, imgnum, pea=1)[source]¶
Assemble ACA image MSIDs from a blob into a dictionary.
This does to blobs what unpack_aca_telemetry does to frames, but for a single image.
- Parameters:
- blob
- imgnum
- pea
- Returns:
- chandra_aca.maude_decom.filter_vcdu_jumps(vcdu_counters)[source]¶
Return a boolean mask to filter VCDU counters that are not continuous.
The returned mask ensures that:
- VCDU counters are a strictly monotonic sequence. - VCDU counters come in packets of four, with each group starting with a multiple of 4.
- chandra_aca.maude_decom.get_aca_images(start, stop, **kwargs)[source]¶
Fetch ACA image telemetry
Fetch ACA image telemetry from MAUDE and return it as an astropy Table. With the default settings and no additional kwargs, this calls get_aca_packets() in a configuration that uses MAUDE frames, combines image data, and sets the TIME associated with each image to the midpoint of the integration time during which that pixel data was collected (matches CXC L0 times). See get_aca_packets().
The ‘IMG’ column is always Nx8x8 and masked, where the mask is a per-pixel mask that indicates missing data for 4x4 or 6x6 images. The units of ‘IMG’ are DN.
For queries including 4x4 data, the ‘BGDRMS’, ‘TEMPCCD’, ‘TEMPHOUS’, ‘TEMPPRIM’, ‘TEMPSEC’, and ‘BGDSTAT’ columns will be masked since they are not present in the 4x4 image data.
There are three different specifiers of the image row/col location: - IMGROW0_8x8/IMGCOL0_8x8: the row/col of the lower-left pixel of the 8x8 masked
image. This is generally the most useful.
- IMGROW0/IMGCOL0: the row/col of the lower-left pixel of the actual 4x4, 6x6, or
8x8 image data. For 6x6 this corresponds to the mouse-bitten corner pixel.
IMGROW_A1/IMGCOL_A1: the row/col of the A1 pixel in telemetry (see ACA EQ-spec).
The full list of columns is:
name dtype unit --------------------- ------- ----------- TIME float64 CXC seconds VCDUCTR uint32 MJF uint32 MNF uint32 IMGNUM uint32 COMMCNT uint8 COMMPROG uint8 GLBSTAT uint8 IMGFUNC uint32 IMGTYPE uint8 IMGSCALE uint16 IMGROW0 int16 IMGCOL0 int16 INTEG float64 s BGDAVG uint16 DN BGDRMS uint16 DN TEMPCCD float32 degC TEMPHOUS float32 degC TEMPPRIM float32 degC TEMPSEC float32 degC BGDSTAT uint8 HIGH_BGD bool RAM_FAIL bool ROM_FAIL bool POWER_FAIL bool CAL_FAIL bool COMM_CHECKSUM_FAIL bool RESET bool SYNTAX_ERROR bool COMMCNT_SYNTAX_ERROR bool COMMCNT_CHECKSUM_FAIL bool COMMPROG_REPEAT uint8 IMGFID bool IMGSTAT uint8 SAT_PIXEL bool DEF_PIXEL bool QUAD_BOUND bool COMMON_COL bool MULTI_STAR bool ION_RAD bool IMGROW_A1 int16 IMGCOL_A1 int16 IMGROW0_8X8 int16 IMGCOL0_8X8 int16 END_INTEG_TIME float64 AAPIXTLM str4 AABGDTYP str4 IMG float64 DN IMG_VCDUCTR int64
This function can be used to fetch up to 5 days of ACA image telemetry at a time. If more is needed, you can set the module variable
MAUDE_FETCH_LIMIT
to a larger value. Internally, this function will fetch the data in intervals ofMAUDE_SINGLE_FETCH_LIMIT
.- Parameters:
- start
timestamp, CxoTimeLike
- stop
timestamp, CxoTimeLike. stop - start cannot be greater than MAUDE_FETCH_LIMIT
- kwargs
keyword args passed to get_aca_packets
- Returns:
- astropy.table.Table
- chandra_aca.maude_decom.get_aca_packets(start, stop, level0=False, combine=False, adjust_time=False, calibrate=False, blobs=None, frames=None, dtype=None, **maude_kwargs)[source]¶
Fetch VCDU 1025-byte frames, extract ACA packets, unpack them and store them in a table.
Incomplete ACA packets (if there is a minor frame missing) can be combined or not into records with complete ACA telemetry. Compare these to calls to the function:
>>> from chandra_aca import maude_decom >>> img = maude_decom.get_aca_packets(684089000, 684089016, combine=True) >>> img = img[img['IMGNUM'] == 0] >>> img['TIME', 'MJF', 'MNF', 'COMMCNT', 'GLBSTAT', 'IMGTYPE', 'IMGROW0', 'IMGCOL0', >>> 'TEMPCCD', 'TEMPHOUS'] <Table masked=True length=4> TIME MJF MNF COMMCNT GLBSTAT IMGTYPE IMGROW0 IMGCOL0 TEMPCCD TEMPHOUS float64 uint32 uint32 uint8 uint8 uint8 int16 int16 int16 int16 ------------- ------ ------ ------- ------- ------- ------- ------- ------- -------- 684089001.869 78006 32 0 0 4 469 -332 -20 83 684089005.969 78006 48 0 0 4 469 -332 -20 83 684089010.069 78006 64 0 0 4 469 -332 -20 83 684089014.169 78006 80 0 0 4 469 -332 -20 83
Using combined=False, results in records with incomplete images. In this case, data can be missing from some records. For example, with 8X8 images, IMGROW0 and IMGCOL0 are present in the first ACA packet (image type 4) while the temperature is present in the second (image type 5):
>>> from chandra_aca import maude_decom >>> img = maude_decom.get_aca_packets(684089000, 684089016, combine=False) >>> img = img[img['IMGNUM'] == 0] >>> img['TIME', 'MJF', 'MNF', 'COMMCNT', 'GLBSTAT', 'IMGTYPE', 'IMGROW0', 'IMGCOL0', >>> 'TEMPCCD', 'TEMPHOUS'] <Table masked=True length=15> TIME MJF MNF COMMCNT GLBSTAT IMGTYPE IMGROW0 IMGCOL0 TEMPCCD TEMPHOUS float64 uint32 uint32 uint8 uint8 uint8 int16 int16 int16 int16 ------------- ------ ------ ------- ------- ------- ------- ------- ------- -------- 684089000.844 78006 28 0 0 7 -- -- -- -- 684089001.869 78006 32 0 0 4 469 -332 -- -- 684089002.894 78006 36 0 0 5 -- -- -20 83 684089003.919 78006 40 0 0 6 -- -- -- -- 684089004.944 78006 44 0 0 7 -- -- -- -- 684089005.969 78006 48 0 0 4 469 -332 -- -- 684089006.994 78006 52 0 0 5 -- -- -20 83 684089008.019 78006 56 0 0 6 -- -- -- -- 684089009.044 78006 60 0 0 7 -- -- -- -- 684089010.069 78006 64 0 0 4 469 -332 -- -- 684089011.094 78006 68 0 0 5 -- -- -20 83 684089012.119 78006 72 0 0 6 -- -- -- -- 684089013.144 78006 76 0 0 7 -- -- -- -- 684089014.169 78006 80 0 0 4 469 -332 -- -- 684089015.194 78006 84 0 0 5 -- -- -20 83
>>> img['IMG'].data[1] masked_BaseColumn(data = [[60.0 97.0 70.0 120.0 74.0 111.0 103.0 108.0] [67.0 90.0 144.0 96.0 88.0 306.0 82.0 67.0] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --]], mask = [[False False False False False False False False] [False False False False False False False False] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True]], fill_value = 1e+20)
>>> img['IMG'].data[2] masked_BaseColumn(data = [[-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [76.0 81.0 160.0 486.0 449.0 215.0 88.0 156.0] [68.0 91.0 539.0 483.0 619.0 412.0 105.0 77.0] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --]], mask = [[ True True True True True True True True] [ True True True True True True True True] [False False False False False False False False] [False False False False False False False False] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True]], fill_value = 1e+20)
>>> img['IMG'].data[3] masked_BaseColumn(data = [[-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [86.0 101.0 408.0 344.0 556.0 343.0 122.0 67.0] [196.0 195.0 114.0 321.0 386.0 115.0 69.0 189.0] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --]], mask = [[ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [False False False False False False False False] [False False False False False False False False] [ True True True True True True True True] [ True True True True True True True True]], fill_value = 1e+20)
>>> img['IMG'].data[4] Out[10]: masked_BaseColumn(data = [[-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [-- -- -- -- -- -- -- --] [67.0 61.0 67.0 176.0 99.0 72.0 79.0 88.0] [70.0 62.0 101.0 149.0 163.0 89.0 60.0 76.0]], mask = [[ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [ True True True True True True True True] [False False False False False False False False] [False False False False False False False False]], fill_value = 1e+20)
- Parameters:
- startCxoTimeLike
Start time for the ACA packets
- stopCxoTimeLike
Stop time for the ACA packets
- level0bool.
Implies combine=True, adjust_time=True, calibrate=True
- combinebool.
If True, ACA subimages are combined to form a full image (depending on size), If False, ACA subimages are not combined, resulting in multiple rows for 6x6 and 8x8 images.
- adjust_timebool
If True, TIME is at the middle of the integration window. If False, TIME is the VCDU time in telemetry of the packet frame (combine=False) or the VCDU time of the first sub-image of the combined image (combine=True).
- calibratebool
If True, pixel values will be ‘value * imgscale / 32 - 50’ and temperature values will be: 0.4 * value + 273.15
- blobsbool or dict
If set, data is assembled from MAUDE blobs. If it is a dictionary, it must be the output of maude.get_blobs ({‘blobs’: … }).
- framesbool or dict
If set, data is assembled from MAUDE frames. If it is a dictionary, it must be the output of maude.get_frames ({‘data’: … }).
- dtypenp.dtype. Optional.
the dtype to use when creating the resulting table. This is useful to add columns including MSIDs that are present in blobs. If used with frames, most probably you will get and empty column. This option is intended to augment the default dtype. If a more restrictive dtype is used, a KeyError can be raised.
- **maude_kwargs
Keyword args passed to maude
- Returns:
- astropy.table.Table
- chandra_aca.maude_decom.get_raw_aca_blobs(start, stop, maude_result=None, **maude_kwargs)[source]¶
Fetch MAUDE blobs and group them according to the underlying 225-byte ACA packets.
If the first minor frame in a group of four ACA packets is within (start, stop), the three following minor frames are included if present.
Returns a dictionary with keys [‘TIME’, ‘MNF’, ‘MJF’, ‘packets’, ‘flags’]. These correspond to the minor frame time, minor frame count, major frame count, the list of packets, and flags returned by MAUDE respectively.
This is to blobs what get_raw_aca_packets is to frames.
- Parameters:
- startCxoTimeLike
Start time for the ACA blobs
- stopCxoTimeLike
Stop time for the ACA blobs
- maude_result
the result of calling maude.get_blobs. Optional.
- **maude_kwargs
keyword args passed to maude.get_frames()
- Returns:
- dict
- {‘blobs’: [], ‘names’: np.array([]), ‘types’: np.array([])}
- chandra_aca.maude_decom.get_raw_aca_packets(start, stop, maude_result=None, **maude_kwargs)[source]¶
Fetch 1025-byte VCDU frames using MAUDE and extract a list of 225-byte ACA packets.
If the first minor frame in a group of four ACA packets is within (start, stop), the three following minor frames are included if present.
returns a dictionary with keys [‘TIME’, ‘MNF’, ‘MJF’, ‘packets’, ‘flags’]. These correspond to the minor frame time, minor frame count, major frame count, the list of packets, and flags returned by MAUDE respectively.
This function raises an exception if the VCDU frames in maude_result are not contiguous, which can also happen if the frames are corrupted in some way.
- Parameters:
- startCxoTimeLike
Start time for packets
- stopCxoTimeLike
Stop time for packets
- maude_result
the result of calling maude.get_frames. Optional.
- **maude_kwargs
keyword args passed to maude.get_frames()
- Returns:
- dict
- {‘flags’: int, ‘packets’: [],
- ‘TIME’: np.array([]), ‘MNF’: np.array([]), ‘MJF’: np.array([])}