aboutsummaryrefslogtreecommitdiff
path: root/src/fuv/cf_remove_motions.c
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-03-04 21:21:30 -0500
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-03-04 21:21:30 -0500
commitd54fe7c1f704a63824c5bfa0ece65245572e9b27 (patch)
treeafc52015ffc2c74e0266653eecef1c8ef8ba5d91 /src/fuv/cf_remove_motions.c
downloadcalfuse-d54fe7c1f704a63824c5bfa0ece65245572e9b27.tar.gz
Initial commit
Diffstat (limited to 'src/fuv/cf_remove_motions.c')
-rw-r--r--src/fuv/cf_remove_motions.c316
1 files changed, 316 insertions, 0 deletions
diff --git a/src/fuv/cf_remove_motions.c b/src/fuv/cf_remove_motions.c
new file mode 100644
index 0000000..ec2b332
--- /dev/null
+++ b/src/fuv/cf_remove_motions.c
@@ -0,0 +1,316 @@
+/*****************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *****************************************************************************
+ *
+ * Synopsis: cf_remove_motions options intermediate_file
+ *
+ * Description: Associates a photon with an aperture and corrects for grating,
+ * mirror, spacecraft (jitter) and focal plane assembly (FPA)
+ * motion. The position of the Y centroid is also determined
+ * both as a function of time (before correction for s/c motion)
+ * and for the entire exposure (after motion correction).
+ * The resulting coordinates represent the data obtained by a
+ * motionless instrument.
+ *
+ * By default, all corrections are performed. Command line
+ * options allow one or more corrections to be omitted.
+ *
+ * Arguments: input_file Intermediate data file
+ *
+ * Calibration files:
+ *
+ * Returns: 0 on successful completion
+ *
+ * Calls: cf_find_spectra, cf_calculate_ycent_motion,
+ * cf_grating_motion, cf_fpa_position, cf_mirror_motion,
+ * cf_satellite_jitter, cf_calculate_y_centroid
+ *
+ * History: 09/30/02 peb 1.1 Begin work
+ * 12/04/02 wvd 1.5 Install Y centroid routines.
+ * Modify call to cf_satellite_jitter
+ * 12/12/02 wvd 1.6 Change infits -> header throughout
+ * 03/04/03 peb 1.10 Minor code changes to remove gcc -Wall
+ * messages: unused j in main.
+ * Added unistd.h, so getopt is portable
+ * 03/05/03 wvd 1.11 Added cf_target_count_rate
+ * 03/10/03 peb 1.12 Added verbose_level, unistd.h for
+ * getopt portability, and changed
+ * locflags to unsigned char *.
+ * 03/13/03 rdr 1.13 corrected small error in tabulating
+ * count rate_sic
+ * 04/17/03 wvd 1.17 Add cf_find_spectra for initial
+ * assignment of photons to
+ * target apertures. Add last_call to
+ * cf_identify_channel, last_call and
+ * weight to cf_calculate_y_centroid
+ * 04/21/03 wvd 1.18 Pass tsunrise to cf_grating_motion,
+ * tsunset to cf_mirror_motion,
+ * channel to cf_satellite_jitter.
+ * 06/02/03 wvd 1.20 Don't modify count-rate arrays
+ * for HIST data.
+ * 06/11/03 wvd 1.21 Pass datatype to cf_read_col and
+ * cf_write_col.
+ * 08/01/03 wvd 1.23 Add cf_error_init after calls to
+ * subroutines.
+ * 08/06/03 wvd 1.24 Change channel to unsigned char.
+ * Remove GTI's from cf_satellite_jitter.
+ * 08/25/03 wvd 1.25 Change coltype from string to int in
+ * cf_read_col and cf_write_col.
+ * 09/18/03 wvd 1.26 Pass locflags to cf_identify_channel
+ * 10/21/03 wvd 1.27 For HIST data, don't write blank
+ * LiF and SiC count-rate arrays to IDF.
+ * 10/27/03 wvd 1.28 Pass pha array to cf_find_spectra.
+ * Delete last_call from argument list
+ * of cf_calculate_y_centroid.
+ * 10/31/03 wvd 1.29 Treat channel as unsigned char
+ * throughout.
+ * 04/06/04 bjg 1.30 Remove unused variables
+ * 05/03/04 wvd 1.31 Improve documentation.
+ * Move first call of cf_identify_channel
+ * from cf_find_spectra to this routine.
+ * 06/02/04 wvd 1.32 Copy/move cf_set_photon_flags(),
+ * cf_set_good_time_intervals(), and
+ * cf_modify_hist_times() from
+ * cf_screen_photons. Run them only if
+ * cf_satellite_jitter rejects some time
+ * AND if they were already run before.
+ * Pass timeflags to cf_find_spectra()
+ * and cf_calculate_y_centroid().
+ * Get exp_jitr from cf_satellite_jitter.
+ * 07/21/04 wvd 1.33 Add include file <string.h>
+ * 03/10/05 wvd 1.34 Change use of variable pad. Now add
+ * 10 to user_pad on first call to
+ * cf_identify_channel, 0 on second call.
+ * 03/22/05 wvd 1.35 Change TIME_SUNRISE and TIME_SUNSET
+ * from floats to shorts.
+ * 05/20/05 wvd 1.36 Clean up i/o.
+ * 09/09/05 wvd 1.37 Add -j to list of allowed options.
+ * 11/29/05 wvd 1.38 Separate cf_satellite_jitter into two
+ * routines. Screening is performed
+ * earlier, so we need not copy flags.
+ * 08/30/06 wvd 1.39 Add -a to list of allowed options.
+ * 12/29/06 wvd 1.40 Pass weights array and initial LiF
+ * and SiC counts arrays to
+ * cf_target_count_rate. Make arrays
+ * rate_lif and rate_sic floats. If
+ * they are too large to store as shorts,
+ * store as unsigned shorts.
+ * 02/02/07 wvd 1.41 If LiF or SiC count rate is too large
+ * for an unsigned int, set to zero.
+ *
+ ****************************************************************************/
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "calfuse.h"
+
+static char CF_PRGM_ID[] = "cf_remove_motions";
+static char CF_VER_NUM[] = "1.41";
+
+int
+main(int argc, char *argv[])
+{
+ unsigned char *channel=NULL, *timeflags=NULL, *locflags=NULL,
+ *statflag=NULL;
+ int grating_motion=1, fpa_position=1, mirror_motion=1, sat_jitter=1;
+ int last_call, set_times=FALSE, set_gtis=FALSE, airglow_centroid=FALSE;
+ int user_pad=0, status=0, set_rate=FALSE, optc;
+ long i, nevents, ntimes;
+ float *time=NULL, *ttime=NULL, *xfarf=NULL, *yfarf=NULL, *x, *y;
+ float *weight=NULL, *ycent_lif, *ycent_sic;
+ float max_rate_lif=0, max_rate_sic=0, *rate_lif=NULL, *rate_sic=NULL;
+ float tscale=1, tzero=32768;
+ short *tsunrise=NULL, *tsunset=NULL;
+ GTI gti;
+ fitsfile *header;
+
+ char opts[] = "hagfmjp:v:";
+ char usage[] =
+ "Usage:\n"
+ " cf_remove_motions [-hagfmj] [-p pad] [-v level] idf_file\n";
+ char option[] =
+ "Options:\n"
+ " -h: this help message\n"
+ " -v: verbose level (default is 1; 0 is silent)\n"
+ " -a: use airglow lines to determine spectral centroid\n"
+ " -p: aperture padding in pixels (default is 10)\n"
+ " -g: no grating motion correction\n"
+ " -f: no fpa position correction\n"
+ " -m: no mirror motion correction\n"
+ " -j: no satellite jitter correction\n";
+
+ verbose_level = 1;
+
+ while ((optc = getopt(argc, argv, opts)) != -1) {
+ switch(optc) {
+
+ case 'h':
+ printf("%s\n%s", usage, option);
+ return 0;
+ case 'v':
+ verbose_level = atoi(optarg);
+ break;
+ case 'p':
+ user_pad = atoi(optarg);
+ break;
+ case 'g':
+ grating_motion = 0;
+ break;
+ case 'f':
+ fpa_position = 0;
+ break;
+ case 'a':
+ airglow_centroid = TRUE;
+ break;
+ case 'm':
+ mirror_motion = 0;
+ break;
+ case 'j':
+ sat_jitter = 0;
+ break;
+ }
+ }
+ cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr);
+
+ if (argc <= optind) {
+ printf("%s", usage);
+ cf_if_error("Incorrect number of command-line arguments");
+ }
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing");
+
+ FITS_open_file(&header, argv[optind], READWRITE, &status);
+
+ FITS_movabs_hdu(header, 2, NULL, &status);
+ nevents = cf_read_col(header, TFLOAT, "TIME", (void **) &time);
+ nevents = cf_read_col(header, TFLOAT, "WEIGHT", (void **) &weight);
+ nevents = cf_read_col(header, TFLOAT, "XFARF", (void **) &xfarf);
+ nevents = cf_read_col(header, TFLOAT, "YFARF", (void **) &yfarf);
+ nevents = cf_read_col(header, TBYTE, "TIMEFLGS", (void **) &timeflags);
+ nevents = cf_read_col(header, TBYTE, "LOC_FLGS", (void **) &locflags);
+ channel = cf_calloc(nevents, sizeof(unsigned char));
+
+ FITS_movabs_hdu(header, 4, NULL, &status) ;
+ ntimes = cf_read_col(header, TFLOAT, "TIME", (void **) &ttime) ;
+ ntimes = cf_read_col(header, TBYTE, "STATUS_FLAGS", (void **) &statflag);
+ ntimes = cf_read_col(header, TSHORT, "TIME_SUNRISE", (void **) &tsunrise) ;
+ ntimes = cf_read_col(header, TSHORT, "TIME_SUNSET", (void **) &tsunset) ;
+ ntimes = cf_read_col(header, TFLOAT, "LIF_CNT_RATE", (void **) &rate_lif) ;
+ ntimes = cf_read_col(header, TFLOAT, "SIC_CNT_RATE", (void **) &rate_sic) ;
+ ycent_lif=(float *) cf_calloc(ntimes, sizeof(float)) ;
+ ycent_sic=(float *) cf_calloc(ntimes, sizeof(float)) ;
+
+ FITS_movabs_hdu(header, 1, NULL, &status);
+ x = xfarf;
+ y = yfarf;
+
+ /* Find all six spectra and compute centroids. */
+ cf_find_spectra(header, nevents, weight, x, y, channel, timeflags,
+ locflags, airglow_centroid);
+
+ /* Initial assignment of channel numbers to photons */
+ cf_identify_channel(header, nevents, xfarf, yfarf, channel, locflags,
+ user_pad+10, last_call=FALSE);
+
+ /* Track Y centroids of moving spectra. */
+ cf_calculate_ycent_motion(header, nevents, time, y, channel, locflags,
+ ntimes, ttime, ycent_lif, ycent_sic);
+
+ /* Correct for detector motion during exposure. */
+ if (grating_motion)
+ cf_grating_motion(header, nevents, time, x, y, channel,
+ ntimes, ttime, tsunrise);
+
+ /* Shift spectra in X to account for position of the FPA. */
+ if (fpa_position)
+ cf_fpa_position(header, nevents, x, channel);
+
+ /* Correct for mirror motion during exposure. */
+ if (mirror_motion)
+ cf_mirror_motion(header, nevents, time, x, y, channel,
+ ntimes, ttime, tsunset);
+
+ /* Correct for spacecraft motion during exposure. */
+ if (sat_jitter)
+ cf_satellite_jitter(header, nevents, time, x, y, channel,
+ ntimes, ttime, statflag);
+
+ /* Compute centroids of motion-corrected spectra. */
+ cf_calculate_y_centroid(header, nevents, weight, x, y, channel,
+ timeflags, locflags);
+
+ /* Final assignment of channel numbers to photons */
+ cf_identify_channel(header, nevents, x, y, channel, locflags,
+ user_pad, last_call=TRUE);
+
+ /* Compute count rates for TTAG target spectra. */
+ set_rate = !(cf_target_count_rate(header, nevents, time, weight,
+ channel, locflags, ntimes, ttime, rate_lif, rate_sic));
+
+ cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr);
+
+ cf_verbose(3, "Writing X, Y, CHANNEL to IDF");
+ FITS_movabs_hdu(header, 2, NULL, &status);
+ if (set_times)
+ cf_write_col(header, TFLOAT, "TIME", (void *) time, nevents);
+ cf_write_col(header, TFLOAT, "X", (void *) x, nevents);
+ cf_write_col(header, TFLOAT, "Y", (void *) y, nevents);
+ cf_write_col(header, TBYTE, "CHANNEL", (void *) channel, nevents);
+
+ if (set_gtis) {
+ cf_verbose(3, "Writing good-time intervals to IDF");
+ FITS_movabs_hdu(header, 3, NULL, &status);
+ cf_write_col(header, TDOUBLE, "START", (void *) gti.start, gti.ntimes);
+ cf_write_col(header, TDOUBLE, "STOP", (void *) gti.stop, gti.ntimes);
+ free(gti.stop);
+ free(gti.start);
+ }
+
+ FITS_movabs_hdu(header, 4, NULL, &status);
+ cf_verbose(3, "Writing timeline information to IDF");
+ if (set_rate) {
+ for (i = 0; i < ntimes; i++) {
+ if (rate_lif[i] > 65535) rate_lif[i] = 0;
+ if (rate_sic[i] > 65535) rate_sic[i] = 0;
+ if (max_rate_lif < rate_lif[i]) max_rate_lif = rate_lif[i];
+ if (max_rate_sic < rate_sic[i]) max_rate_sic = rate_sic[i];
+ }
+ cf_verbose(2, "max_rate_lif = %.0f", max_rate_lif);
+ cf_verbose(2, "max_rate_sic = %.0f", max_rate_sic);
+ if (max_rate_lif > 32767) {
+ FITS_update_key(header, TFLOAT, "TSCAL10", &tscale, NULL, &status);
+ FITS_update_key(header, TFLOAT, "TZERO10", &tzero, NULL, &status);
+ fits_set_tscale(header, 10, (double)tscale, (double)tzero, &status);
+ }
+ if (max_rate_sic > 32767) {
+ FITS_update_key(header, TFLOAT, "TSCAL11", &tscale, NULL, &status);
+ FITS_update_key(header, TFLOAT, "TZERO11", &tzero, NULL, &status);
+ fits_set_tscale(header, 11, (double)tscale, (double)tzero, &status);
+ }
+ FITS_write_col(header, TFLOAT, 10, 1, 1, ntimes, rate_lif, &status);
+ FITS_write_col(header, TFLOAT, 11, 1, 1, ntimes, rate_sic, &status);
+ }
+ cf_write_col(header, TFLOAT, "YCENT_LIF", (void *) ycent_lif, ntimes);
+ cf_write_col(header, TFLOAT, "YCENT_SIC", (void *) ycent_sic, ntimes);
+ cf_verbose(3, "IDF updates complete");
+
+ FITS_close_file(header, &status);
+
+ free(time);
+ free(weight);
+ free(xfarf);
+ free(yfarf);
+ free(locflags);
+ free(timeflags);
+ free(channel);
+ free(ttime);
+ free(rate_lif);
+ free(rate_sic);
+ free(ycent_lif);
+ free(ycent_sic);
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done processing");
+ return status;
+}