aboutsummaryrefslogtreecommitdiff
path: root/src/libcf/cf_fifo_dead_time.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/libcf/cf_fifo_dead_time.c
downloadcalfuse-d54fe7c1f704a63824c5bfa0ece65245572e9b27.tar.gz
Initial commit
Diffstat (limited to 'src/libcf/cf_fifo_dead_time.c')
-rw-r--r--src/libcf/cf_fifo_dead_time.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/libcf/cf_fifo_dead_time.c b/src/libcf/cf_fifo_dead_time.c
new file mode 100644
index 0000000..67ac065
--- /dev/null
+++ b/src/libcf/cf_fifo_dead_time.c
@@ -0,0 +1,164 @@
+/*****************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *****************************************************************************
+ *
+ * Synopsis: cf_fifo_dead_time(fitsfile *header, long nevents,
+ * float *ptime, long nseconds, float *ttime, float *aic_rate,
+ * float *ids_dtc)
+ *
+ * Description: Searches high-count-rate observations for data drop-outs
+ * due to FIFO overflows. If found, calculates time-dependent
+ * scale factor to correct for lost photon events.
+ *
+ * Arguments: fitsfile *header Pointer to FITS file containing the
+ * header of the intermediate data file
+ * long nevents Number of photon events in the file
+ * float *ptime Detection time for each photon
+ * long nseconds The number of timeline values
+ * float *ttime Tabulated times in the timeline
+ * float *aic_rate Active Image Counter array
+ * float *ids_dtc IDS dead-time correction array
+ * (modified)
+ *
+ * Calls:
+ *
+ * Return: 0 on success
+ *
+ * History of cf_screen_fifo_overflow:
+ *
+ * 02/10/04 1.1 wvd Begin work
+ * 02/17/05 1.2 wvd Place parentheses around assignment
+ * used as truth value.
+ * 11/09/05 1.3 wvd In the current scheme, the rate_lif
+ * and rate_sic arrays contain values
+ * from the housekeeping file and do
+ * not reflect data loss due to FIFO
+ * overflows. Now we calculate the
+ * count-rate array directly from the
+ * photon time array.
+ * 02/23/06 1.4 wvd Change length of data_rate array
+ * from nevents to nseconds.
+ *
+ * History: 12/29/06 1.1 wvd Derived from cf_screen_fifo_overflow.
+ * 01/15/07 1.2 wvd When count rate is zero, correct one
+ * second before to two seconds after.
+ * 02/08/07 1.3 wvd If TTPERIOD = 0, set it to 1.
+ * 04/07/07 1.4 wvd Clean up compiler warnings.
+ *
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include "calfuse.h"
+
+int
+compute_count_rate(long nevents, float *ptime, long nseconds,
+ float *ttime, long **data_rate)
+{
+ float delta_max = 1.0 + FRAME_TOLERANCE;
+ long j,k;
+
+ *data_rate = (long *) cf_calloc(nseconds, sizeof(long));
+ for (j=k=0; j<nevents; j++) {
+ while(ttime[k+1]-FRAME_TOLERANCE < ptime[j] && k+1 < nseconds) k++;
+ if ((ptime[j] - ttime[k]) < delta_max) (*data_rate)[k]++;
+ }
+ return 0;
+}
+
+int
+cf_fifo_dead_time(fitsfile *header, long nevents, float *ptime,
+ long nseconds, float *ttime, float *aic_rate, float *ids_dtc)
+{
+ char CF_PRGM_ID[] = "cf_fifo_dead_time";
+ char CF_VER_NUM[] = "1.4";
+
+ char elecfile[FLEN_VALUE];
+ int errflg=0, status=0;
+ int fifo_drain_rate;
+ int *flag_array, found_drop_out = FALSE;
+ long *data_rate, k;
+ float mean_ids_rate, ttperiod;
+ float mean_ids_dtc;
+ fitsfile *elecfits;
+
+ /* Exit if data were obtained in HIST mode. */
+ cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr);
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing");
+ if ((errflg = cf_proc_check(header, CF_PRGM_ID))) return errflg;
+
+ /* Read IDS drain rate from calibration file. */
+ FITS_read_key(header, TSTRING, "ELEC_CAL", elecfile, NULL, &status);
+ FITS_open_file(&elecfits, cf_cal_file(elecfile), READONLY, &status);
+ FITS_read_key(elecfits, TINT, "FIFO_DRN", &fifo_drain_rate, NULL, &status);
+ FITS_close_file(elecfits, &status);
+ cf_verbose(4, "fifo_drain_rate = %d", fifo_drain_rate);
+
+ /* Read interval between time stamps. */
+ FITS_read_key(header, TFLOAT, "TTPERIOD", &ttperiod, NULL, &status);
+ if (ttperiod < 1E-6) ttperiod = 1.0;
+
+ /* Compute mean IDS count rate. */
+ mean_ids_rate = 0.;
+ for (k=0; k<nseconds; k++)
+ mean_ids_rate += aic_rate[k];
+ mean_ids_rate /= nseconds;
+ mean_ids_rate += 1./ttperiod;
+ cf_verbose(4, "mean_ids_rate = %f", mean_ids_rate);
+
+ /* If mean IDS count rate > 3200, look for data drop-outs. */
+ if (mean_ids_rate > 3200 && nseconds > 4) {
+ compute_count_rate(nevents, ptime, nseconds, ttime, &data_rate);
+ flag_array = (int *) cf_calloc(nseconds, sizeof(int));
+
+ /* If count rate goes to zero, set flag_array. Where possible,
+ set flags from one second before to two seconds after. */
+ for (k=0; k<1; k++) if (data_rate[k] == 0)
+ flag_array[k] = flag_array[k+1] = flag_array[k+2] = TRUE;
+
+ for ( ; k<nseconds-2; k++) if (data_rate[k] == 0)
+ flag_array[k-1] = flag_array[k] = flag_array[k+1] =
+ flag_array[k+2] = TRUE;
+
+ for ( ; k<nseconds-1; k++) if (data_rate[k] == 0)
+ flag_array[k-1] = flag_array[k] = flag_array[k+1] = TRUE;
+
+ for ( ; k<nseconds; k++) if (data_rate[k] == 0)
+ flag_array[k-1] = flag_array[k] = TRUE;
+
+ for (k=0; k<nseconds; k++) if (data_rate[k] == 0) {
+ found_drop_out = TRUE;
+ break;
+ }
+
+ /* If there are any drop-outs, modify IDS dead-time correction. */
+ if (found_drop_out)
+ for ( ; k < nseconds; k++) if (flag_array[k])
+ ids_dtc[k] = (aic_rate[k] - 1./ttperiod) / fifo_drain_rate;
+
+ free(data_rate);
+ free(flag_array);
+ }
+
+ /*
+ * Calculate mean dead-time correction. Write to file header.
+ */
+ if (found_drop_out) {
+ mean_ids_dtc = 0;
+ for (k = 0; k < nseconds; k++) mean_ids_dtc += ids_dtc[k];
+ mean_ids_dtc /= nseconds;
+ cf_verbose(1, "IDS FIFO overflow detected.");
+ cf_verbose(2, "Modified mean IDS dead-time correction: %f",
+ mean_ids_dtc);
+ FITS_update_key(header, TFLOAT, "IDS_DEAD", &mean_ids_dtc, NULL,
+ &status);
+ }
+
+ /*
+ * Clean up and go home.
+ */
+ cf_proc_update(header, CF_PRGM_ID, "COMPLETE");
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done processing");
+ return 0;
+}