From d54fe7c1f704a63824c5bfa0ece65245572e9b27 Mon Sep 17 00:00:00 2001 From: Joseph Hunkeler Date: Wed, 4 Mar 2015 21:21:30 -0500 Subject: Initial commit --- src/libcf/cf_screen_jitter.c | 246 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 246 insertions(+) create mode 100644 src/libcf/cf_screen_jitter.c (limited to 'src/libcf/cf_screen_jitter.c') diff --git a/src/libcf/cf_screen_jitter.c b/src/libcf/cf_screen_jitter.c new file mode 100644 index 0000000..68327a0 --- /dev/null +++ b/src/libcf/cf_screen_jitter.c @@ -0,0 +1,246 @@ +/***************************************************************************** + * Johns Hopkins University + * Center for Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: cf_screen_jitter (infile, nsec, ttime, status_flag) + * + * Description: Flag times when target is out of the aperture or pointing + * is known to be bad. Read the minimum trustworthy TRKFLG + * value and aperture limits from the parameter file. + * + * Key to new TRKFLG values: + * 5 = dx, dy from known FPDs and q_cmd from telemetry + * 4 = good dx, dy from ACS q_est and q_cmd from telemetry + * 3 = maybe good dx, dy from ACS q_est + * 2 = dx, dy from known FPDs, q_cmd from FITS header coordinates + * 1 = dx, dy from ACS q_est, q_cmd from FITS header coordinates + * 0 = no pointing information (missing telemetry) + * -1 = Pointing is assumed to be bad (never achieved known track) + * + * Arguments: fitsfile infile Pointer to the IDF + * long nsec Number of seconds in the timeline + * long *ttime time (sec) of each point in the timeline + * unsigned char *status_flag Timeline status flags + * + * Returns: 0 upon success + * + * History: 11/29/05 v1.1 wvd Adapted from cf_satellite_jitter + * 03/28/06 1.2 wvd Test both dx and dy. + * 05/09/06 1.3 wvd Apply jitter screening to RFPT obs. + * 06/12/06 1.4 wvd Call cf_verbose when jitter file not + * found. + * 08/21/06 1.5 wvd Use EXPSTART in jitter and data + * headers to correct jitter time array. + * 08/25/06 1.6 wvd Change meaning of TRKFLG values. + * TRKFLG = 3 is only used internally. + * 11/06/06 1.7 wvd Change meaning of TRKFLG values. + * Read minimum TRKFLG value and + * aperture limits from parmfile. + * Require jitter file version >= 3.0. + * Don't screen moving targets. + * Bail out only if JIT_STAT = 1. + * 12/29/06 1.8 wvd Exit if JIT_VERS < 3.0. + * 03/23/07 1.9 wvd Store offset between the jitter and + * data values of EXPSTART in variable + * time_diff. + * 04/07/07 1.10 wvd Clean up compiler warnings. + * 08/16/07 1.11 wvd Don't apply jitter correction to + * observations taken after the + * spacecraft lost pointing control. + * 07/25/08 1.12 wvd Use EXP_STAT keyword, rather than + * file name, to check for bright-earth + * or airglow observations. + * 11/21/08 1.13 wvd Don't apply jitter correction to + * ERO observations of Jupiter. + * + ****************************************************************************/ + +#include +#include +#include +#include +#include "calfuse.h" + +#define JIT_VERS_MIN 3.0 +#define BAD_TRKFLG -1 +#define LAST_MJD 54300. + +int +cf_screen_jitter(fitsfile *infits, long nsec, float *ttime, + unsigned char *status_flag) +{ + char CF_PRGM_ID[] = "cf_screen_jitter"; + char CF_VER_NUM[] = "1.13"; + + char jitr_cal[FLEN_VALUE], parmfile[FLEN_VALUE]; + char comment[FLEN_COMMENT], hkexists[FLEN_VALUE], jit_vers[FLEN_VALUE]; + char mov_targ[FLEN_VALUE], program[FLEN_VALUE]; + int errflg=0, status=0, expstat, jitter_status, hdutype; + long j, k, njitr, *time_jit, time_diff; + short *trkflg, trkflg_min; + double data_expstart, jitr_expstart; + float *dx_jit, *dy_jit, dx_max, dy_max; + fitsfile *jitfits, *parmfits; + + /* Initialize error checking */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + /* Enter a time stamp into the log */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing"); + + /* Read exposure start time from IDF header */ + FITS_read_key(infits, TDOUBLE, "EXPSTART", &data_expstart, NULL, &status); + + /* Check whether program is appropriate for this data set. */ + if ((errflg = cf_proc_check(infits, CF_PRGM_ID))) return errflg; + + /* Don't apply jitter screening to bright-earth or airglow observations. */ + FITS_read_key(infits, TINT, "EXP_STAT", &expstat, NULL, &status); + if (expstat == (int) TEMPORAL_LIMB) { + cf_verbose(1, "Bright-earth or airglow observation. ", + "No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Don't apply jitter screening to moving targets. */ + FITS_read_key(infits, TSTRING, "MOV_TARG", mov_targ, NULL, &status); + if (!strncmp(mov_targ, "M", 1)) { + cf_verbose(1, "Moving-target observation. No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Don't apply jitter screening to ERO observations of Jupiter. */ + FITS_read_key(infits, TSTRING, "PRGRM_ID", program, NULL, &status); + if (!strncmp(program, "X006", 4)) { + cf_verbose(1, "Moving-target observation. No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Don't apply jitter screening after pointing control is lost. */ + if (data_expstart > LAST_MJD) { + cf_verbose(1, "No pointing control. No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Check HKEXISTS before looking for jitter file. */ + FITS_read_key(infits, TSTRING, "HKEXISTS", hkexists, NULL, &status); + if(!strncasecmp(hkexists, "N", 1) || !strncasecmp(hkexists, "n", 1)) { + cf_verbose(1, "HKEXISTS = %s. No jitter correction.", hkexists); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Try to open the jitter file. */ + FITS_read_key(infits, TSTRING, "JITR_CAL", jitr_cal, NULL, &status); + fits_open_file(&jitfits, jitr_cal, READONLY, &status); + + /* If the jitter file is not found, try a lower-case filename. */ + if (status != 0) { + status = 0; + jitr_cal[0] = (char) tolower(jitr_cal[0]); + fits_open_file(&jitfits, jitr_cal, READONLY, &status); + } + + /* If the jitter file is still not found, exit the program */ + if (status != 0) { + cf_verbose(1, "Jitter file not found. No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + cf_verbose(3, "Jitter calibration file = %s", jitr_cal); + + /* Check status keyword in jitter file. Exit if missing or non-zero. */ + fits_read_key(jitfits, TINT, "JIT_STAT", &jitter_status, comment, &status); + if (status != 0) { + status = 0; + cf_verbose(1, "Keyword JIT_STAT not found. No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + if (jitter_status == 1) { + cf_verbose(1, "Keyword JIT_STAT = %d. No jitter correction.", + jitter_status) ; + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Read exposure start time from jitter file header */ + FITS_read_key(jitfits, TDOUBLE, "EXPSTART", &jitr_expstart, NULL, &status); + + /* Check JIT_VERS keyword. Exit if missing or value too low. */ + fits_read_key(jitfits, TSTRING, "JIT_VERS", jit_vers, NULL, &status); + if (status != 0 || atof(jit_vers) < JIT_VERS_MIN) { + status = 0; + cf_verbose(1, "Jitter file format is out of date. No jitter correction."); + cf_proc_update(infits, CF_PRGM_ID, "SKIPPED"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; + } + + /* Read the jitter file. */ + FITS_movabs_hdu(jitfits, 2, &hdutype, &status); + njitr=cf_read_col(jitfits, TLONG, "TIME", (void **) &time_jit); + njitr=cf_read_col(jitfits, TFLOAT, "DX", (void **) &dx_jit); + njitr=cf_read_col(jitfits, TFLOAT, "DY", (void **) &dy_jit); + njitr=cf_read_col(jitfits, TSHORT, "TRKFLG", (void **) &trkflg); + FITS_close_file(jitfits, &status); + + /* Correct for difference in data and jitter EXPSTART times */ + time_diff = cf_nlong((data_expstart - jitr_expstart) * 86400.); + cf_verbose(2, "Offset between IDF and jitter EXPSTART values: %d sec", + time_diff); + for (j=0; j< njitr; j++) time_jit[j] -= time_diff; + + /* Read minimum TRKFLG value and aperture boundaries from PARM_CAL file */ + FITS_read_key(infits, TSTRING, "PARM_CAL", parmfile, NULL, &status); + FITS_open_file(&parmfits, cf_parm_file(parmfile), READONLY, &status); + FITS_read_key(parmfits, TSHORT, "TRKFLG", &trkflg_min, NULL, &status); + FITS_read_key(parmfits, TFLOAT, "DX_MAX", &dx_max, NULL, &status); + FITS_read_key(parmfits, TFLOAT, "DY_MAX", &dy_max, NULL, &status); + FITS_close_file(parmfits, &status); + + /* Reject times when tracking is good, but target is out of aperture. */ + for (j=0; j< njitr; j++) { + if (trkflg[j] >= trkflg_min && + (dx_jit[j] < -dx_max || dx_jit[j] > dx_max || + dy_jit[j] < -dy_max || dy_jit[j] > dy_max)) { + trkflg[j] = BAD_TRKFLG; + } + } + + /* + * Map times in the jitter file to times in the timeline table. + * If trkflg[j] = BAD_TRKFLG, set the jitter flag in the timeline + * status array. + */ + for (j=k=0; k < nsec; k++) { + while ((float) time_jit[j+1] < ttime[k] && j+1 < njitr) j++; + if (trkflg[j] == BAD_TRKFLG) { + status_flag[k] |= TEMPORAL_JITR; + } + } + + /* Deallocate storage space */ + free(time_jit); + free(dy_jit); + free(trkflg); + + cf_proc_update(infits, CF_PRGM_ID, "COMPLETE"); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + + return (status); +} -- cgit