aboutsummaryrefslogtreecommitdiff
path: root/src/fes
diff options
context:
space:
mode:
Diffstat (limited to 'src/fes')
-rw-r--r--src/fes/Makefile.Linux.orig44
-rw-r--r--src/fes/Makefile.Linux64.orig43
-rw-r--r--src/fes/Makefile.Solaris.orig44
-rw-r--r--src/fes/Makefile.orig.orig44
-rw-r--r--src/fes/cf_calfes.c151
-rw-r--r--src/fes/cf_calfes.h10
-rw-r--r--src/fes/cf_cp_hdr.c71
-rw-r--r--src/fes/cf_fes_apply_bias.c98
-rw-r--r--src/fes/cf_fes_apply_flat.c67
-rw-r--r--src/fes/cf_fes_apply_mask.c56
-rw-r--r--src/fes/cf_fes_cal.c115
-rw-r--r--src/fes/cf_fes_get_cal_image.c71
-rw-r--r--src/fes/cf_fes_init.c294
-rw-r--r--src/fes/cf_fes_read.c76
-rw-r--r--src/fes/cf_fes_write.c60
-rw-r--r--src/fes/cf_limbang.c100
16 files changed, 1344 insertions, 0 deletions
diff --git a/src/fes/Makefile.Linux.orig b/src/fes/Makefile.Linux.orig
new file mode 100644
index 0000000..af548ac
--- /dev/null
+++ b/src/fes/Makefile.Linux.orig
@@ -0,0 +1,44 @@
+
+SHARED= -shared
+FITSVER= 2.470
+CALFUSEDIR= ${PWD}/../..
+
+# Symbols for include directories
+FUSEINCLDIR= -I${CALFUSEDIR}/include
+
+# Symbols used for compiling
+CC= cc
+OPT= -g -Wall -DCFORTRAN -Dg77Fortran -Df2cFortran
+CFLAGS = ${OPT} ${FUSEINCLDIR}
+
+# Symbols used for creating shared binaries
+FUSEBINDIR= ${CALFUSEDIR}/bin
+FUSELIBDIR= -L${CALFUSEDIR}/lib
+LIBDIR=
+FUSELIBS= -lsla -lcfitsio-${FITSVER} -lcf
+LIBS= -lc -lm -lnsl -ldl -lgfortran
+LDFLAGS= -Wl,-R${CALFUSEDIR}/lib
+
+OBJECTS= cf_calfes.o cf_fes_init.o cf_fes_read.o cf_fes_write.o \
+ cf_fes_cal.o cf_fes_get_cal_image.o cf_limbang.o \
+ cf_fes_apply_bias.o cf_fes_apply_flat.o cf_fes_apply_mask.o
+
+all: cf_calfes
+
+cf_calfes: ${OBJECTS}
+ ${CC} ${CFLAGS} -o cf_calfes ${OBJECTS} \
+ ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS}
+ chmod g+rw cf_calfes
+
+install: cf_calfes
+ /bin/cp cf_calfes ${FUSEBINDIR}
+
+clean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+
+distclean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+ cd ../../bin; /bin/rm -f cf_calfes
+
+lint: ${SOURCES}
+ lint ${SOURCES}
diff --git a/src/fes/Makefile.Linux64.orig b/src/fes/Makefile.Linux64.orig
new file mode 100644
index 0000000..87e47c2
--- /dev/null
+++ b/src/fes/Makefile.Linux64.orig
@@ -0,0 +1,43 @@
+
+SHARED= -shared
+CALFUSEDIR= ${PWD}/../..
+
+# Symbols for include directories
+FUSEINCLDIR= -I${CALFUSEDIR}/include
+
+# Symbols used for compiling
+CC= cc
+OPT= -g -Wall -DCFORTRAN -Dg77Fortran -Df2cFortran
+CFLAGS = ${OPT} ${FUSEINCLDIR}
+
+# Symbols used for creating shared binaries
+FUSEBINDIR= ${CALFUSEDIR}/bin
+FUSELIBDIR= -L${CALFUSEDIR}/lib
+LIBDIR=
+FUSELIBS= -lsla -lcf
+LIBS= -lc -lm -lnsl -ldl -lgfortran -lcfitsio
+LDFLAGS= -Wl,-R${CALFUSEDIR}/lib
+
+OBJECTS= cf_calfes.o cf_fes_init.o cf_fes_read.o cf_fes_write.o \
+ cf_fes_cal.o cf_fes_get_cal_image.o cf_limbang.o \
+ cf_fes_apply_bias.o cf_fes_apply_flat.o cf_fes_apply_mask.o
+
+all: cf_calfes
+
+cf_calfes: ${OBJECTS}
+ ${CC} ${CFLAGS} -o cf_calfes ${OBJECTS} \
+ ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS}
+ chmod g+rw cf_calfes
+
+install: cf_calfes
+ /bin/cp cf_calfes ${FUSEBINDIR}
+
+clean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+
+distclean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+ cd ../../bin; /bin/rm -f cf_calfes
+
+lint: ${SOURCES}
+ lint ${SOURCES}
diff --git a/src/fes/Makefile.Solaris.orig b/src/fes/Makefile.Solaris.orig
new file mode 100644
index 0000000..23f189b
--- /dev/null
+++ b/src/fes/Makefile.Solaris.orig
@@ -0,0 +1,44 @@
+
+SHARED= -shared
+FITSVER= 2.470
+CALFUSEDIR= ${PWD}/../..
+
+# Symbols for include directories
+FUSEINCLDIR= -I${CALFUSEDIR}/include
+
+# Symbols used for compiling
+CC= cc
+OPT= -O -DCFORTRAN -KPIC -DSOLARIS
+CFLAGS = ${OPT} ${FUSEINCLDIR}
+
+# Symbols used for creating shared binaries
+FUSEBINDIR= ${CALFUSEDIR}/bin
+FUSELIBDIR= -L${CALFUSEDIR}/lib
+LIBDIR= -L/opt/SUNWspro/lib
+FUSELIBS= -lsla -lcfitsio-${FITSVER} -lcf
+LIBS= -lc -lm -lnsl -ldl -lsocket -lsunmath -lM77 -lF77
+LDFLAGS= -Wl,-R${CALFUSEDIR}/lib
+
+OBJECTS= cf_calfes.o cf_fes_init.o cf_fes_read.o cf_fes_write.o \
+ cf_fes_cal.o cf_fes_get_cal_image.o cf_limbang.o \
+ cf_fes_apply_bias.o cf_fes_apply_flat.o cf_fes_apply_mask.o
+
+all: cf_calfes
+
+cf_calfes: ${OBJECTS}
+ ${CC} ${CFLAGS} -o cf_calfes ${OBJECTS} \
+ ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS}
+ chmod g+rw cf_calfes
+
+install: cf_calfes
+ /bin/cp cf_calfes ${FUSEBINDIR}
+
+clean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+
+distclean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+ cd ../../bin; /bin/rm -f cf_calfes
+
+lint: ${SOURCES}
+ lint ${SOURCES}
diff --git a/src/fes/Makefile.orig.orig b/src/fes/Makefile.orig.orig
new file mode 100644
index 0000000..23f189b
--- /dev/null
+++ b/src/fes/Makefile.orig.orig
@@ -0,0 +1,44 @@
+
+SHARED= -shared
+FITSVER= 2.470
+CALFUSEDIR= ${PWD}/../..
+
+# Symbols for include directories
+FUSEINCLDIR= -I${CALFUSEDIR}/include
+
+# Symbols used for compiling
+CC= cc
+OPT= -O -DCFORTRAN -KPIC -DSOLARIS
+CFLAGS = ${OPT} ${FUSEINCLDIR}
+
+# Symbols used for creating shared binaries
+FUSEBINDIR= ${CALFUSEDIR}/bin
+FUSELIBDIR= -L${CALFUSEDIR}/lib
+LIBDIR= -L/opt/SUNWspro/lib
+FUSELIBS= -lsla -lcfitsio-${FITSVER} -lcf
+LIBS= -lc -lm -lnsl -ldl -lsocket -lsunmath -lM77 -lF77
+LDFLAGS= -Wl,-R${CALFUSEDIR}/lib
+
+OBJECTS= cf_calfes.o cf_fes_init.o cf_fes_read.o cf_fes_write.o \
+ cf_fes_cal.o cf_fes_get_cal_image.o cf_limbang.o \
+ cf_fes_apply_bias.o cf_fes_apply_flat.o cf_fes_apply_mask.o
+
+all: cf_calfes
+
+cf_calfes: ${OBJECTS}
+ ${CC} ${CFLAGS} -o cf_calfes ${OBJECTS} \
+ ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS}
+ chmod g+rw cf_calfes
+
+install: cf_calfes
+ /bin/cp cf_calfes ${FUSEBINDIR}
+
+clean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+
+distclean:
+ /bin/rm -f ${OBJECTS} cf_calfes
+ cd ../../bin; /bin/rm -f cf_calfes
+
+lint: ${SOURCES}
+ lint ${SOURCES}
diff --git a/src/fes/cf_calfes.c b/src/fes/cf_calfes.c
new file mode 100644
index 0000000..43e913c
--- /dev/null
+++ b/src/fes/cf_calfes.c
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_calfes rootname
+ * where rootname is the exposure root name
+ *
+ * Description:
+ * This main program calls all the routines below to apply
+ * FES processing steps. It
+ * 1) Opens the input and output FES FITS files;
+ * 2) Loops through all images present:
+ * a) Calls the procedures listed below to process all the images;
+ * b) Writes the current processed image out to the
+ * current output HDU.
+ * 3) Closes the input and output files.
+ *
+ * Arguments: rootname exposure_root_name
+ *
+ * Returns: 0 upon successful completion
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/15/98 mlr begin work
+ * 04/12/99 mlr modified to only write each image only
+ * once - now passing the image in addition
+ * to the fits hdu to each subroutine.
+ * 04/19/99 mlr finished modifications to utilize
+ * libcf and FITSIO.h(error handling).
+ * 08/23/04 wvd Change cf_velang_calc to cf_velang.
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include "calfuse.h"
+#include "cf_calfes.h"
+
+#define CF_PRGM_ID "cf_calfes"
+#define CF_VER_NUM "1.4"
+#define RAW_FES "RAW FES "
+#define CAL_FES "CALIBRATED FES "
+
+int main(int argc, char *argv[])
+{
+ fitsfile *infits, *outfits;
+ int i, status;
+ int hdu, hdutype, num_of_hdus;
+ int naxes1, naxes2;
+ long bitpix;
+ float bscale, bzero;
+ double mjd_start, mjd_end;
+
+ char infilename[30], outfilename[30];
+ char file_type[20];
+ float *image;
+
+ /* Enter a timestamp into the log. */
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing");
+ cf_error_init(CF_PRGM_ID,CF_VER_NUM, stdout);
+
+ if (argc != 2)
+ cf_if_error("Usage: cf_calfes filerootname ");
+
+ /* determine file names of the input file and the output file */
+ strcpy(infilename, argv[1]);
+ strcat(infilename, "raw.fit");
+
+ strcpy(outfilename, argv[1]);
+ strcat(outfilename, "cal.fit");
+
+ status=0;
+
+ /* open the input FES FITS file and verify that it is a RAW FES file*/
+ FITS_open_file(&infits, infilename, READONLY, &status);
+
+ FITS_read_key(infits, TSTRING, "FILETYPE", &file_type, NULL, &status);
+
+ if (strncmp(file_type, RAW_FES, 7) != 0)
+ cf_if_error("The input file is not a RAW FES file.");
+
+ /* open the output file for calibrated FES data, copy the primary
+ header from the input FES file to the output FES file, then
+ modify keywords as needed.
+ */
+ FITS_create_file(&outfits, outfilename, &status);
+ FITS_copy_header(infits, outfits, &status);
+
+ bitpix = FLOAT_IMG;
+ FITS_update_key(outfits, TLONG, "BITPIX", &bitpix, NULL, &status);
+ FITS_update_key(outfits, TSTRING, "FILETYPE", CAL_FES, NULL, &status);
+
+ read_tle(outfits);
+
+ /* Determine how many extensions there are in this file.
+ There is 1 FES image in each extension. So this tells us how
+ many images there are in this file and controls the loop that
+ processes each one.
+ */
+
+ FITS_read_key(infits, TINT, "NEXTEND ", &num_of_hdus, NULL, &status);
+
+ printf("This file %s has %d FES image(s).\n", infilename, num_of_hdus);
+ hdutype = -1;
+
+ for (i=1 ; i <= num_of_hdus; i++)
+ {
+ hdu = i + 1;
+
+ FITS_create_hdu(outfits, &status);
+ FITS_movabs_hdu(infits, hdu, &hdutype, &status);
+ FITS_copy_header(infits, outfits, &status);
+
+ bitpix = FLOAT_IMG;
+ bzero = 0.0;
+ bscale = 1.0;
+ FITS_update_key(outfits, TLONG, "BITPIX", &bitpix, NULL, &status);
+ FITS_update_key(outfits, TFLOAT, "BZERO", &bzero, NULL, &status);
+ FITS_update_key(outfits, TFLOAT, "BSCALE", &bscale, NULL, &status);
+
+ FITS_read_key(outfits,TDOUBLE,"EXPSTART",&mjd_start,NULL, &status);
+ FITS_read_key(outfits,TDOUBLE,"EXPEND", &mjd_end, NULL, &status);
+ cf_velang(outfits, (mjd_start+mjd_end)/2.0 );
+ cf_min_limbang(outfits, mjd_start, mjd_end);
+
+ status =+ cf_fes_read(infits, &image, &naxes1, &naxes2);
+ status =+ cf_fes_init(outfits);
+ status =+ cf_fes_write(outfits, hdu, image);
+
+ status =+ cf_fes_cal(FES_MASK, outfits, &image, naxes1, naxes2);
+ status =+ cf_fes_cal(FES_BIAS, outfits, &image, naxes1, naxes2);
+ status =+ cf_fes_cal(FES_FLAT, outfits, &image, naxes1, naxes2);
+ status =+ cf_fes_write(outfits, hdu, image);
+
+
+ free(image);
+
+ if (status != 0)
+ cf_if_error("cf_calfes failed.");
+ }
+
+ /* close the FES FITS files */
+ FITS_close_file(infits, &status);
+ FITS_close_file(outfits, &status);
+
+
+ /* Enter a timestamp into the log. */
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done Processing");
+
+ return(status);
+}
diff --git a/src/fes/cf_calfes.h b/src/fes/cf_calfes.h
new file mode 100644
index 0000000..d4944fa
--- /dev/null
+++ b/src/fes/cf_calfes.h
@@ -0,0 +1,10 @@
+#define FES_GOOD_PIX 0.0
+#define FES_BAD_PIX -20.0
+#define FES_FLAT 1
+#define FES_MASK 2
+#define FES_BIAS 3
+
+int cf_fes_apply_flat(fitsfile *, float **, float *, int, int);
+int cf_fes_apply_mask(fitsfile *, float **, float *, int, int);
+int cf_fes_apply_bias(fitsfile *, float **, float *, int, int);
+
diff --git a/src/fes/cf_cp_hdr.c b/src/fes/cf_cp_hdr.c
new file mode 100644
index 0000000..7642f05
--- /dev/null
+++ b/src/fes/cf_cp_hdr.c
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_cp_hdr(fitsfile *infits, int inhdu, fitsfile *outfits,
+ * int outhdu)
+ *
+ * Description: Copies the header, with no changes, from HDU inhdu of the
+ * input FITS file infits to HDU outhdu of the output FITS file
+ * outfits.
+ *
+ * Arguments: fitsfile *infits Input FITS file pointer
+ * int inhdu HDU to be copied from
+ * fitsfile *outfits Output FITS file pointer
+ * int outhdu HDU to be copied to
+ *
+ * Returns: none
+ *
+ * History: 04/02/98 gak Begin work
+ * 08/27/98 gak Initialized status, hdutype;
+ * return status
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "calfuse.h"
+
+#define CF_PRGM_ID "cf_cp_hdr"
+#define CF_VER_NUM "1.1"
+
+int cf_cp_hdr(fitsfile *infits, int inhdu, fitsfile *outfits, int outhdu)
+{
+ char buffer[FLEN_CARD];
+ int status, hdutype;
+ int nkeys, keynum;
+ int i;
+
+ status = 0;
+ hdutype = 0;
+
+ if ( fits_movabs_hdu(infits, inhdu, &hdutype, &status) ) {
+ cf_if_error(status);
+ exit(status);
+ }
+ if ( fits_movabs_hdu(outfits, outhdu, &hdutype, &status) ) {
+ cf_if_error(status);
+ exit(status);
+ }
+
+ /* Get number of keywords in the input header, loop & copy. */
+ if ( fits_get_hdrpos(infits, &nkeys, &keynum, &status) ) {
+ cf_if_error(status);
+ exit(status);
+ }
+ for ( i = 1; i <= nkeys; i++) {
+ if ( fits_read_record(infits, i, buffer, &status) ) {
+ cf_if_error(status);
+ exit(status);
+ }
+ if ( fits_write_record(outfits, buffer, &status) ) {
+ cf_if_error(status);
+ exit(status);
+ }
+ }
+
+ return status;
+}
diff --git a/src/fes/cf_fes_apply_bias.c b/src/fes/cf_fes_apply_bias.c
new file mode 100644
index 0000000..7591757
--- /dev/null
+++ b/src/fes/cf_fes_apply_bias.c
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_apply_fes_bias(fitsfile *fesfits, float **image,
+ * float *bias, int axis1, int axis2)
+ *
+ * Description: Apply FES bias in *bias to the raw FES image in **image
+ * To apply the bias, I simply loop through the
+ * bias image pixel by pixel and subtract that
+ * value from the given FES image.
+ *
+ * Arguments: fitsfile *fesfits fits file for image so that we can add
+ * history/comment lines to the HDU
+ * float **image FES image
+ * float *bias FES bias image
+ * int axis1, axis2 size of each axis of the images.
+ * This presumes that both images are
+ * the same size when they get here.
+ *
+ * Returns: 0 upon successful completion
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/22/98 mlr started work
+ * 04/06/99 mlr Broke this actual subroutine out
+ * from cf_fes_bias.c
+ * 08/10/99 mlr added fesfits to the argument list
+ * 04/25/02 wvd initialize status to zero
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "calfuse.h"
+#include "cf_calfes.h"
+
+#define CF_PRGM_ID "cf_fes_apply_bias"
+#define CF_VER_NUM "1.4"
+
+int cf_fes_apply_bias(fitsfile *fesfits, float **image,
+ float *bias, int naxis1, int naxis2)
+{
+ int i, j; /*loop counters */
+ int status=0;
+ float os_bias, os_data;
+ float factor;
+ char buffer[80];
+
+ cf_timestamp(CF_PRGM_ID,CF_VER_NUM, "Applying FES bias");
+
+ os_bias=0.;
+ os_data=0.;
+
+ if (naxis1 == 520) /* 1x1 binning */
+ {
+ for (j=0; j<520; j++)
+ for (i=512; i<520; i++)
+ {
+ os_bias += bias[j*naxis1+i];
+ os_data += (*image)[j*naxis1+1];
+ }
+ }
+ else if (naxis1 == 260) /* 2x2 binning */
+ {
+ for (j=0; j<260; j++)
+ for (i=256; i<260; i++)
+ {
+ os_bias += bias[j*naxis1+i];
+ os_data += (*image)[j*naxis1+1];
+ }
+ }
+ else /*bail out -- unsupported image size or binning */
+ exit(-1);
+
+ factor = os_data / os_bias;
+ sprintf(buffer, "FES BIAS FACTOR = %lf",factor);
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, buffer);
+
+/* FITS_write_history(fesfits, buffer, &status); */
+
+ for (j=0; j<naxis2; j++)
+ for (i=0; i<naxis1; i++)
+ {
+/* printf("pixel[%d, %d] = %lf\n",i,j, (*image)[j*naxis1+i]); */
+ if ( (*image)[j*naxis1+i] != FES_BAD_PIX )
+ (*image)[j*naxis1+i] -= bias[j*naxis1+i] * factor;
+ else
+ printf("bad pixel[%d, %d]\n",i,j);
+ }
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished FES bias");
+
+ return(status);
+
+}
diff --git a/src/fes/cf_fes_apply_flat.c b/src/fes/cf_fes_apply_flat.c
new file mode 100644
index 0000000..21d8ddc
--- /dev/null
+++ b/src/fes/cf_fes_apply_flat.c
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_apply_fes_flat(fitsfile *fesfits, float **image,
+ * float *flat, int axis1, int axis2)
+ *
+ * Description: Apply FES flatfield in *flat to the raw FES image in **image
+ * To apply the flatfield, I simply loop through the
+ * flatfield image pixel by pixel and
+ * If the flatfield pixel value != 0.0
+ * then fes image[] pixel value = image[]pixel value/mask[]pixel value.
+ * else (If the flatfield pixel value == 0.0)
+ * then fes image[] pixel value = FES_BAD_PIX.
+ *
+ * Arguments: fitsfile *fesfits fits file for image.. so that we can add
+ * history/comment lines to the HDU
+ * float **image FES image
+ * float *mask FES mask
+ * int axis1, axis2 size of each axis of the images.
+ * This presumes that both images are
+ * the same size before they get here.
+ *
+ * Returns: 0 upon successful completion
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/22/98 mlr started work
+ * 04/06/99 mlr Broke this actual subroutine out
+ * from cf_fes_mask.c
+ * 04/20/99 mlr instead of calculating the image row
+ * size each time -- pass it in
+ * 08/10/99 mlr added fesfits to argument list
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "calfuse.h"
+#include "cf_calfes.h"
+
+#define CF_PRGM_ID "cf_fes_apply_flat"
+#define CF_VER_NUM "1.4"
+
+int cf_fes_apply_flat(fitsfile *fesfits, float **image,
+ float *flat, int naxis1, int naxis2)
+{
+ int i, j; /*loop counters */
+ int pixel;
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Applying FES flatfield");
+ for (j=0; j < naxis2; j++)
+ for (i=0; i < naxis1; i++)
+ {
+ pixel = j* naxis1+ i;
+ if ((*image)[pixel] != FES_BAD_PIX)
+ if (flat[pixel] != 0.0 )
+ (*image)[pixel] /= flat[pixel];
+ else
+ (*image)[pixel] = FES_BAD_PIX;
+ }
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done applying FES flat");
+
+ return(0);
+}
diff --git a/src/fes/cf_fes_apply_mask.c b/src/fes/cf_fes_apply_mask.c
new file mode 100644
index 0000000..c083121
--- /dev/null
+++ b/src/fes/cf_fes_apply_mask.c
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_apply_fes_mask(fitsfile *fesfits, float **image,
+ * float *mask, int axis1, int axis2)
+ *
+ * Description: Apply FES mask in *mask to the raw FES image in **image
+ * To apply the mask I simply loop through the
+ * mask image pixel by pixel and
+ * If the mask pixel value != 0.0
+ * then fes image pixel value = mask pixel value.
+ *
+ * Arguments: fitsfile *fesfits fits file for image, so that we can add
+ * history/comment lines to the HDU
+ * float **image FES image
+ * float *mask FES mask
+ * int axis1, axis2 size of each axis of the images.
+ * This presumes that both images are
+ * the same size when they get here.
+ *
+ * Returns: 0 upon successful completion
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/22/98 mlr started work
+ * 04/06/99 mlr Broke subroutine out from cf_fes_mask.c
+ * 08/10/99 mlr added fesfits to the argument list
+ *
+ *
+ ******************************************************************************/
+
+#include "calfuse.h"
+#include "cf_calfes.h"
+
+#define CF_PRGM_ID "cf_fes_apply_mask"
+#define CF_VER_NUM "1.4"
+
+int cf_fes_apply_mask(fitsfile *fesfits, float **image,
+ float *mask, int naxis1, int naxis2)
+{
+ int i, j; /*loop counters */
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Applying FES pixel mask");
+
+ for (j=0; j < naxis2; j++)
+ for (i=0; i < naxis1; i++)
+ if (mask[j*naxis1+i] != FES_GOOD_PIX )
+ (*image)[j*naxis1+i] = mask[j*naxis1+i];
+
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done applying FES mask");
+
+ return(0);
+}
diff --git a/src/fes/cf_fes_cal.c b/src/fes/cf_fes_cal.c
new file mode 100644
index 0000000..0f08bbd
--- /dev/null
+++ b/src/fes/cf_fes_cal.c
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: int cf_fes_cal(int cal_type, fitsfile *fesfits, float **image,
+ * int inaxis1, int inaxis2)
+ *
+ * Description: Get bias calibration filename for the raw FES image in
+ * the current hdu pointed at by *infits.
+ * Call cf_fes_get_cal_image() to open the cal file and get
+ * the calibration image.
+ * Call cf_fes_apply_flat();
+ * return the modified image to the calling routine.
+ * 4/10/99 MLR removed int inhdu as an argument and removed
+ * the call to fits_movabs_hdu. This requires any
+ * user of this subroutine to do these steps before
+ * calling cf_fes_flat.
+ * 4/10/99 MLR removed (fitsfile *outfits, int outhdu) from
+ * the argument list. We will leave writing the image
+ * out to the calling routine.
+ *
+ *
+ * Arguments: fitsfile *infits Input FITS file pointer
+ * float **image already read in FES image
+ * int inaxis1 image size of the input image
+ * int inaxis2
+ *
+ * Returns: none
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/22/98 mlr started work
+ * 04/10/99 mlt pulled the actual work out of this
+ * routine and into cf_fes_apply_flat
+ * 04/12/99 mlr modified the input arguments(see above)
+ * use the now generic cf_fes_read to
+ * get the calibration image.
+ * 04/14/99 mlr pulled the reading out and put it
+ * into cf_fes_get_cal_image.c
+ * 04/16/99 mlr finished modifications to utilize
+ * libcf and FITSIO.h(error handling).
+ *
+ * ToDo: 4/12/99 I have added the naxis1 and naxis2 parameters to the
+ * argument list. I need to use them to compare binning
+ * factors in the two images.
+ * I should combine cf_fes_mask, cf_fes_bias, cf_fes_flat
+ * into one generic cf_fes_do_cal("cf_fes_mask", *fesfits,...etc)
+ *
+ ******************************************************************************/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "calfuse.h"
+#include "cf_calfes.h"
+
+#define CF_VER_NUM "1.4"
+
+int cf_fes_cal(int cal_type, fitsfile *fesfits, float **image,
+ int inaxis1, int inaxis2)
+{
+ char buffer[FLEN_CARD];
+ char calfilename[30];
+ fitsfile *calfile;
+ int status;
+ float *calimage;
+ char *prog_id, *msg, *keyword, *msg2;
+
+ int (*func)(fitsfile *, float **, float *, int, int);
+
+ status = 0;
+
+ switch (cal_type) {
+ case FES_FLAT:
+ prog_id = "cf_fes_flat";
+ msg = "Begin FES flatfield";
+ msg2 = "Done FES flatfield";
+ keyword = "FFLT1FCL";
+ func = cf_fes_apply_flat;
+ break;
+ case FES_MASK:
+ prog_id = "cf_fes_mask";
+ msg = "Begin FES mask";
+ msg2 = "Done FES mask";
+ keyword = "MASK_FCL";
+ func = cf_fes_apply_mask;
+ break;
+ case FES_BIAS:
+ prog_id = "cf_fes_bias";
+ msg = "Begin FES bias";
+ msg2 = "Done FES bias";
+ keyword = "BIAS1FCL";
+ func = cf_fes_apply_bias;
+ break;
+ }
+
+
+ cf_timestamp(prog_id, CF_VER_NUM, msg);
+
+ FITS_read_key(fesfits, TSTRING, keyword, calfilename, buffer, &status);
+
+ if (cf_fes_get_cal_image(calfilename, &calimage, inaxis1, inaxis2) == -1)
+ return (-1);
+
+ (*func)(fesfits, image, calimage, inaxis1, inaxis2);
+
+ cf_fes_proc_update(fesfits, prog_id, "COMPLETE");
+
+ free(calimage);
+
+ cf_timestamp(prog_id, CF_VER_NUM, msg2);
+
+ return(status);
+}
diff --git a/src/fes/cf_fes_get_cal_image.c b/src/fes/cf_fes_get_cal_image.c
new file mode 100644
index 0000000..2e5e8f0
--- /dev/null
+++ b/src/fes/cf_fes_get_cal_image.c
@@ -0,0 +1,71 @@
+ /*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis:int cf_fes_get_cal_image(char cal_file_name[], float **cal_image,
+ * int naxis1, int naxis2)
+ *
+ * Description: open the specified calibration file for an FES image
+ * loop through each extension in the calibration file
+ * until you find the one that has the same size naxis1 and
+ * naxis2 as the input image.
+ * read the image in that extention into *cal_image
+ * close the calibration file
+ *
+ * Arguments: char cal_file_name[],
+ * float **cal_image,
+ * int naxis1, int naxis2
+ *
+ * Returns: none
+ *
+ * History: 04/14/99 mlr started work
+ * 04/16/99 mlr modified to use libcf and FITSIO.h
+ *
+ ******************************************************************************/
+
+#include "calfuse.h"
+
+#define CF_PRGM_ID "cf_fes_get_cal_image"
+#define CF_VER_NUM "1.4"
+
+int cf_fes_get_cal_image(char cal_file_name[], float **cal_image,
+ int naxis1, int naxis2)
+{
+ fitsfile *fes_cal_file;
+ int status;
+ int i, hdu, hdutype, num_exts;
+ int cal_axis1, cal_axis2;
+ char buffer[FLEN_CARD];
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin getting Cal image");
+
+ status = 0;
+
+ /* open the input FES CALIBRATION file */
+
+ FITS_open_file(&fes_cal_file,cf_cal_file(cal_file_name),READONLY,&status);
+
+ FITS_read_key(fes_cal_file, TINT, "NEXTEND", &num_exts, buffer, &status);
+
+ for (i = 1; i<= num_exts; i++)
+ {
+ hdu = i + 1;
+ FITS_movabs_hdu(fes_cal_file, hdu, &hdutype, &status);
+ cf_fes_read(fes_cal_file, cal_image, &cal_axis1, &cal_axis2);
+ if ((cal_axis1 == naxis1) && (cal_axis2 == naxis2))
+ break;
+ }
+ FITS_close_file(fes_cal_file, &status);
+
+ if (i>num_exts)
+ {
+ *cal_image=NULL;
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "No Cal image of requested size");
+ return(-1);
+ }
+
+ cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done getting Cal image");
+ return(status);
+}
diff --git a/src/fes/cf_fes_init.c b/src/fes/cf_fes_init.c
new file mode 100644
index 0000000..fcbb34c
--- /dev/null
+++ b/src/fes/cf_fes_init.c
@@ -0,0 +1,294 @@
+
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_fes_init(fitsfile *fptr)
+ *
+ * Description: cf_fes_init performs two functions. First, populates the
+ * data processing step keywords based upon the type of
+ * data (FESA or FESB). Second, it populates the calibration
+ * file keywords based on the time and date of observation,
+ * the detector segment, and the interpolation status of the
+ * calibration file.
+ *
+ * Arguments: fitsfile *fptr Pointer to input file
+ *
+ * History: 05/21/98 emm Begin work.
+ * 06/17/98 emm Modified keywords to reflect updated
+ * calfuse design
+ * 07/15/98 mlr copied from emm
+ * 08/23/04 wvd Change from fits_modify_key_str to
+ * FITS_update_key throughout.
+ ******************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include "calfuse.h"
+
+#define MAXCHARS 120
+#define MASTER_CAL_FILE "master_fes_calib_file.dat"
+#define CF_PRGM_ID "cf_fes_init"
+#define CF_VER_NUM "1.4"
+
+int cf_fes_init(fitsfile *fptr)
+{
+int i,j,k,l,flg;
+char comment[FLEN_CARD], instmode[FLEN_CARD], detector[FLEN_CARD];
+char fes[2];
+char keyword_in[9], segment_in[3];
+char filename_in[19]=" \0";
+char keyword_out1[9], keyword_out2[9];
+char complete[19], error[19], blank[19];
+char linin[120];
+int status, interp_in;
+float expstart, aftermjd_in;
+
+struct fes_keyword_tab keytab[NUM_FES_PROC_STEPS]=FES_CALIBRATION_STEP_KEYS;
+struct cal_file_tab calkey[NUM_FES_CAL_KEYS]=FES_CALIBRATION_FILE_KEYS;
+FILE *fpin;
+
+cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin initializing header");
+cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr);
+
+status=0;
+
+ strncpy(complete,"COMPLETE \0",19);
+ strncpy(error, "ERROR \0",19);
+ strncpy(blank, " \0",19);
+
+/* Populate data processing keywords. */
+
+ for (i=0; i<NUM_FES_PROC_STEPS; i++)
+ FITS_update_key(fptr,TSTRING,keytab[i].name,
+ keytab[i].value,NULL,&status);
+
+
+/* Populate calibration file keywords based on the date of the
+ * observation and the segment/channel number. */
+
+ FITS_read_key(fptr, TFLOAT, "EXPSTART", &expstart, comment, &status);
+ FITS_read_key(fptr, TSTRING, "FES_ID", instmode, comment, &status);
+ sscanf(instmode,"%*3c %1c",fes);
+
+/* Open the Master calibration database file. */
+
+ fpin=NULL;
+ fpin=fopen(cf_cal_file(MASTER_CAL_FILE),"r");
+ if (fpin == NULL)
+ cf_if_warning("Master calibration database file not found");
+
+ /* Cycle through the master cal file until we run out of lines. */
+
+ /* Here's how this section works. We need to keep track of 3 calibration
+ * files for each keyword: the cal file which immediately preceedes the
+ * date of observation, the cal file which immediately preceedes the cal
+ * file which immediately preceedes the observation, and the cal file
+ * immediately after the observation. These are stored in strut calkey
+ * in:
+ * calkey[i].filenames[0] => second cal file preceeding observation
+ * calkey[i].filenames[1] => cal file immediately preceeding observation
+ * calkey[i].filenames[2] => cal file immediately after observation
+ *
+ * Here is the plan. Cycle through the master cal file, reading each
+ * line. Determine the keyword for each line, and use that to determine
+ * the appropriate index [i] for calkey. Then, if the detector segment
+ * is correct, determine where the new file fits into the structure above.
+ * If it is more recent than one or both of the preceeding cal files,
+ * but is older than the observation (expstart) replace either
+ * filenames[0] or filenames[1]. If filenames[1] is replaced, shift
+ * the old value down into filenames[0]. If the file is more recent
+ * than the observation, and closer to the observation than the file
+ * in filenames[2], replace filenames[2]. The values
+ * calkey[i].aftermjd[] and calkey[i].interp[] store the date and
+ * interpolation status of the best files. This organization allows
+ * the master calibration database file to be written in any order.
+ */
+
+ while (fgets(linin, MAXCHARS, fpin) != NULL) {
+
+ /* Check for comment lines */
+
+ if ((linin[0] != '#') && (linin[0] != '\n')) {
+ sscanf(linin, "%4c %1c %12c %9f %1d",keyword_in,
+ segment_in,filename_in,&aftermjd_in,&interp_in);
+
+ /* Determine which keyword we just read in. */
+ i=0;
+ while ((strncmp(calkey[i].name,keyword_in,4) != 0) &&
+ (i < NUM_FES_CAL_KEYS)) i++;
+
+ if (i >= NUM_FES_CAL_KEYS) {
+ cf_if_warning("Unrecognized keyword in master calibration file");
+ } else {
+ if ((strncmp(segment_in," ",1) == 0) ||
+ (strncmp(segment_in,fes,1) == 0)) {
+ j=0;
+ if ((aftermjd_in < expstart) &&
+ (aftermjd_in > calkey[i].aftermjd[0]) &&
+ (aftermjd_in > calkey[i].aftermjd[1])) {
+ strncpy(calkey[i].filenames[0],
+ calkey[i].filenames[1],18);
+ calkey[i].aftermjd[0]=calkey[i].aftermjd[1];
+ calkey[i].interp[0]=calkey[i].interp[1];
+ strncpy(calkey[i].filenames[1],
+ filename_in,18);
+ calkey[i].aftermjd[1]=aftermjd_in;
+ calkey[i].interp[1]=interp_in;
+ } else if ((aftermjd_in < expstart) &&
+ (aftermjd_in > calkey[i].aftermjd[0])) {
+ strncpy(calkey[i].filenames[0],
+ filename_in,18);
+ calkey[i].aftermjd[0]=aftermjd_in;
+ calkey[i].interp[0]=interp_in;
+ }
+
+ if ((aftermjd_in > expstart) &&
+ (aftermjd_in < calkey[i].aftermjd[2])) {
+ strncpy(calkey[i].filenames[2],
+ filename_in,18);
+ calkey[i].aftermjd[2]=aftermjd_in;
+ calkey[i].interp[2]=interp_in;
+ }
+ } /* Endif segment match */
+ } /* end else unrecognized keyword */
+ } /* end while linin not comment */
+ } /* end while(linin != NULL) */
+
+ fclose(fpin);
+
+ /* OK, now that we have identified the closest two files before
+ * the observation, and the file after the observation, we can
+ * decide what to do with them. First, the easy part: if
+ * calkey[i].numfiles=1, no interpolation is possible, so we
+ * write out calkey[i].filenames[1], which is the file immediately
+ * preceeding the observation. If calkey[i].numfiles=2, interpolation
+ * is possible, and we will have to write two keywords into the header.
+ * The decision as to which two keywords to write follows these rules:
+ * Rule 1: If an observation occurs between two files which can be
+ * interpolated, then an interpolation must be done.
+ * Rule 2: If the calibration file immediately preceeding an
+ * observation is to be used in a stepwise manner, then said
+ * file shall be used in stepwise manner.
+ * Rule 3: If the two calibration files immediately preceeding an
+ * observation can be interpolated, but the following file
+ * cannot, then the two previous files will be extrapolated
+ * forward in time.
+ * Rule 4: If the closest preceeding calibration file has an interpolation
+ * flag, but the file preceeding it has a stepwise flag, the the
+ * closest preceeding file will be used in a sterpwise manner.
+ * Rule 5: Never interpolate backward in time.
+ *
+ * In fact, there are only 8 possible cases:
+ *
+ * Remember, the files were sorted such that the observation
+ * always occurs between [1] and [2]. Also remember that
+ * interp[i]=0 => stepwise):
+ *
+ * Case Action
+ *
+ * interp[0] = 0
+ * interp[1] = 0 filenames[1] will be used in a stepwise manner
+ * interp[2] = 0
+ *
+ * interp[0] = 0
+ * interp[1] = 0 filenames[1] will be used in a stepwise manner
+ * interp[2] = 1
+ *
+ * interp[0] = 0
+ * interp[1] = 1 filenames[1] will be used in a stepwise manner
+ * interp[2] = 0
+ *
+ * interp[0] = 1
+ * interp[1] = 0 filenames[1] will be used in a stepwise manner
+ * interp[2] = 0
+ *
+ * interp[0] = 1
+ * interp[1] = 0 filenames[1] will be used in a stepwise manner
+ * interp[2] = 1
+ *
+ * interp[0] = 0
+ * interp[1] = 1 filenames[1] and filenames[2] will be interpolated
+ * interp[2] = 1
+ *
+ * interp[0] = 1
+ * interp[1] = 1 filenames[0] and filenames[1] will be extrapolated
+ * interp[2] = 0
+ *
+ * interp[0] = 1
+ * interp[1] = 1 filenames[1] and filenames[2] will be interpolated
+ * interp[2] = 1
+ *
+ */
+
+ /* Write the calibration files into the header keywords. */
+ /* Cycle through the keywords. */
+ for (i=0; i<NUM_FES_CAL_KEYS; i++) {
+
+ if (calkey[i].numfiles == 1) {
+
+ /* This is the easy case, no interpolation is possible. */
+
+ sprintf(keyword_out1,"%4.4s%1.1s%3.3s",calkey[i].name,"_",
+ calkey[i].extension);
+ FITS_update_key(fptr,TSTRING,keyword_out1,calkey[i].filenames[1],
+ NULL,&status);
+ } else {
+
+ /* OK, interpolation is possible, now decide which two files
+ * to write out. */
+
+ /* Create the two output keywords */
+ sprintf(keyword_out1,"%4.4s%1.1s%3.3s",calkey[i].name,"1",
+ calkey[i].extension);
+ sprintf(keyword_out2,"%4.4s%1.1s%3.3s",calkey[i].name,"2",
+ calkey[i].extension);
+
+ if (calkey[i].interp[1] == 0) {
+
+ /* Easy, preceeding file is a 0, so write filenames[1] to
+ * both keywords. Takes care of cases 000, 001, 100, 101.
+ */
+ FITS_update_key(fptr,TSTRING,keyword_out1,calkey[i].filenames[1],
+ NULL,&status);
+ FITS_update_key(fptr,TSTRING,keyword_out2,calkey[i].filenames[1],
+ NULL,&status);
+ } else if ((calkey[i].interp[1] == 1) && (calkey[i].interp[2] == 1)) {
+ /* Case 011 and 111 */
+ FITS_update_key(fptr,TSTRING,keyword_out1,calkey[i].filenames[1],
+ NULL,&status);
+ FITS_update_key(fptr,TSTRING,keyword_out2,calkey[i].filenames[2],
+ NULL,&status);
+ } else if ((calkey[i].interp[0] == 1) && (calkey[i].interp[1] == 1)
+ && (calkey[i].interp[2] == 0)){
+ /* Case 110 */
+ FITS_update_key(fptr,TSTRING,keyword_out1,calkey[i].filenames[0],
+ NULL,&status);
+ FITS_update_key(fptr,TSTRING,keyword_out2,calkey[i].filenames[1],
+ NULL,&status);
+
+ } else if ((calkey[i].interp[0] == 0) && (calkey[i].interp[1] == 1)
+ && (calkey[i].interp[2] == 0)){
+ /* Case 010 */
+ FITS_update_key(fptr,TSTRING,keyword_out1,calkey[i].filenames[1],
+ NULL,&status);
+ FITS_update_key(fptr,TSTRING,keyword_out2,calkey[i].filenames[1],
+ NULL,&status);
+
+ } else cf_if_warning("The interpolation/stepwise logic has failed. I am confused.");
+
+ } /* end else calkey.numfiles == 1 */
+
+ } /* end for i=0; i<NUMCALKEYS */
+
+
+FITS_update_key(fptr,TSTRING,"INIT_FES",complete,NULL,&status);
+
+cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done initializing header");
+
+return status;
+}
+
+
diff --git a/src/fes/cf_fes_read.c b/src/fes/cf_fes_read.c
new file mode 100644
index 0000000..47fbf20
--- /dev/null
+++ b/src/fes/cf_fes_read.c
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_fes_read(fitsfile *infits, float **image,
+ * int *naxis1, int *naxis2);
+ *
+ * Description: reads an FES image from the current hdu in the FITS file
+ * pointed to by *infits and stores it in the array pointed
+ * to by *image.
+ * *infits may contain an FES image where each pixel is
+ * stored as unsigned shorts or as floats. cf_fes_read
+ * determines this from BITPIX in the current hdu and proceeds
+ * accordingly.
+ * cf_fes_read also takes care of any binning by determining
+ * the image size from NAXIS1 and NAXIS2 in the current hdu.
+ * 4/12/99 MLR These two values are now returned to the
+ * calling routine for reference.
+ * 4/10/99 MLR removed int inhdu as an argument and removed
+ * the call to fits_movabs_hdu. This requires any
+ * user of this subroutine to do these steps before
+ * calling cf_fes_read.
+ *
+ * Arguments: fitsfile *infits Input FITS file pointer
+ * float **image Pointer to array holding FES image
+ * int *naxis1 Image size parameters
+ * int *naxis2
+ *
+ * Returns: 0 upon successfule completion
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/16/98 mlr started work
+ * 04/12/99 mlr modified the input arguments(see above)
+ * 04/16/99 mlr finished modifications to utilize
+ * libcf and FITSIO.h(error handling).
+ ******************************************************************************/
+
+#include "calfuse.h"
+
+#define CF_PRGM_ID "cf_fes_read"
+#define CF_VER_NUM "1.4"
+
+int cf_fes_read(fitsfile *infits, float**image, int *naxis1, int *naxis2)
+{
+ char buffer[FLEN_CARD];
+ int status;
+ int bitpix, nullval, anynull, npixels;
+ int i, j, hdutype;
+ short *short_image;
+
+ status = 0;
+ hdutype=-1;
+
+ FITS_read_key(infits, TINT, "NAXIS1", naxis1, buffer, &status);
+
+ FITS_read_key(infits, TINT, "NAXIS2", naxis2, buffer, &status);
+
+ npixels = (*naxis1) * (*naxis2);
+
+ cf_if_memory_error(*image = (float *) malloc(sizeof(float) * npixels));
+
+ FITS_read_key(infits, TINT, "BITPIX", &bitpix, buffer, &status);
+
+ nullval = 0;
+ if (bitpix == 16 || bitpix == -32)
+
+ FITS_read_img(infits, TFLOAT, 1, npixels,
+ &nullval, *image, &anynull, &status);
+
+ else
+ cf_if_error("INVALID data type for FES image. ");
+
+ return(status);
+}
diff --git a/src/fes/cf_fes_write.c b/src/fes/cf_fes_write.c
new file mode 100644
index 0000000..baa678b
--- /dev/null
+++ b/src/fes/cf_fes_write.c
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *******************************************************************************
+ *
+ * Synopsis: cf_fes_write(fitsfile *outfits, int hdu, float *image);
+ *
+ * Description: writes an FES image into HDU number hdu in the FITS file
+ * pointed to by *fptr. Currently cf_fes_write extracts
+ * BITPIX, NAXIS1, and NAXIS2 from the specified HDU and
+ * uses those values to write the image.
+ *
+ * Arguments: fitsfile *outfits output FITS file pointer
+ * int hdu HDU to be written to
+ * float *image Pointer to array holding FES image
+ *
+ * Returns: none
+ *
+ * History: 07/08/98 gak calfes_design.070898 design documented
+ * 07/20/98 mlr started work
+ * 04/19/99 mlr finished modifications to utilize
+ * libcf and FITSIO.h(error handling).
+ * ToDO: I may at somepoint modify this subroutine to pass in the image
+ * type and size in as parameters... I already have the information
+ * I shouldn't read it in... or perhaps I should just verify that
+ * they match???
+ * ToDo: I should check bitpix and write out the requested size. At the
+ * moment I only write float.
+ *
+ ******************************************************************************/
+
+#include "calfuse.h"
+
+#define CF_PRGM_ID "cf_fes_write"
+
+int cf_fes_write(fitsfile *outfits, int hdu, float *image)
+{
+ char buffer[FLEN_CARD];
+ int status, hdutype;
+ int naxis, naxis1, naxis2;
+ int fpixel, npixels, bitpix;
+ short *short_image;
+
+ hdutype = -1;
+ status = 0;
+
+ FITS_movabs_hdu(outfits, hdu, &hdutype, &status);
+
+ FITS_read_key(outfits, TINT, "NAXIS1", &naxis1, buffer, &status);
+ FITS_read_key(outfits, TINT, "NAXIS2", &naxis2, buffer, &status);
+ FITS_read_key(outfits, TINT, "BITPIX", &bitpix, buffer, &status);
+
+ fpixel = 1;
+ npixels = naxis1 * naxis2;
+
+ FITS_write_img(outfits, TFLOAT, fpixel, npixels, image, &status);
+
+ return(status);
+}
diff --git a/src/fes/cf_limbang.c b/src/fes/cf_limbang.c
new file mode 100644
index 0000000..8bd230f
--- /dev/null
+++ b/src/fes/cf_limbang.c
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Johns Hopkins University
+ * Center For Astrophysical Sciences
+ * FUSE
+ *****************************************************************************
+ *
+ * Synopsis: cf_limbang_calc(fitsfile *outfits, double mjd)
+ * cf_min_limbang(fitsfile *outfits,
+ * double mjd_start, double mjd_end)
+ * Description: cf_limbang_calc - Calculates the limb angle at a given mjd
+ * cf_min_limbang - determines the minimum limb angle between
+ * the start and end times. The limb angle is
+ * calculated every 8.6 seconds( .0001 MJD)
+ *
+ * Arguments: fitsfile *outfits Pointer to FITS file containing the
+ * input data and orbital elements
+ * double mjd The limb angle calculation is done for
+ * this time. The time is given as
+ * a Modified Julian Date.
+ * double mjd_start The range of times for which the minimum
+ * double mjd_end limb angle should be determined.
+ * Both are given as Modified Julian Dates.
+ *
+ * History: 08/09/99 mlr copied cf_velang.c to start
+ * 08/09/99 mlr removed excess calls then made the
+ * limb_ang calls - same as cf_check_point
+ *
+ ****************************************************************************/
+
+#include <stdio.h>
+#include "calfuse.h"
+#include "sgp4.h"
+static char CF_PRGM_ID[] = "cf_limbang";
+
+SGP4 set_orbit_parms(fitsfile *);
+
+double cf_limbang_calc(fitsfile *outfits, double mjd)
+{
+ int status=0, isday_dummy;
+ char comment[FLEN_CARD];
+ double ra, dec, pos[3], vel[3];
+ double lim_ang, zdist_dummy;
+ SGP4 sgp4;
+
+ sgp4 = set_orbit_parms(outfits);
+
+ /* get the state vector at time mjd */
+ SGP4_getStateVector(sgp4, mjd, pos, vel);
+ SGP4_precess(pos, mjd, MJD2000); SGP4_precess(vel, mjd, MJD2000);
+
+ FITS_read_key(outfits, TDOUBLE, "RA_TARG", &ra, comment, &status);
+ FITS_read_key(outfits, TDOUBLE, "DEC_TARG", &dec, comment, &status);
+
+ lim_ang = state_limb(pos, mjd, ra, dec, &zdist_dummy, &isday_dummy);
+
+ return(lim_ang);
+}
+
+void cf_min_limbang(fitsfile *outfits, double mjd_start, double mjd_end)
+{
+
+ int status = 0;
+ double lim_ang, min_lim;
+ double mjd;
+
+ mjd = mjd_start;
+ min_lim = cf_limbang_calc(outfits, mjd);
+
+#ifdef DEBUG
+ printf("mjd: %lf mjd_end = %lf minlim = %lf\n", mjd, mjd_end, min_lim);
+#endif
+ /* .0001 = 8.6 seconds */
+ while ( (mjd_end - mjd) > .0001 )
+ {
+ mjd = mjd + .0001;
+ lim_ang = cf_limbang_calc(outfits, mjd);
+#ifdef DEBUG
+ printf("mjd: %lf mjd_end = %lf minlim = %lf, limang = %lf\n",
+ mjd, mjd_end, min_lim, lim_ang);
+#endif
+ if (lim_ang < min_lim) min_lim = lim_ang;
+ }
+
+ mjd = mjd_end;
+ lim_ang = cf_limbang_calc(outfits, mjd);
+
+#ifdef DEBUG
+ printf("mjd: %lf mjd_end = %lf minlim = %lf, limang = %lf\n",
+ mjd, mjd_end, min_lim, lim_ang);
+#endif
+
+ if (lim_ang < min_lim) min_lim = lim_ang;
+
+#ifdef DEBUG
+ printf("mjd: %lf mjd_end = %lf minlim = %lf\n", mjd, mjd_end, min_lim);
+#endif
+
+ FITS_update_key(outfits, TDOUBLE, "MIN_LIMB", &min_lim, NULL, &status);
+
+}