diff options
Diffstat (limited to 'src/analysis')
34 files changed, 12053 insertions, 0 deletions
diff --git a/src/analysis/Makefile.Linux.orig b/src/analysis/Makefile.Linux.orig new file mode 100644 index 0000000..b1786ef --- /dev/null +++ b/src/analysis/Makefile.Linux.orig @@ -0,0 +1,142 @@ + +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= -L/opt/SUNWspro/lib +FUSELIBS= -lsla -lcfitsio-${FITSVER} -lcf +LIBS= -lc -lm -lnsl -ldl -lgfortran +LDFLAGS= -Wl,-R${CALFUSEDIR}/lib + +# Binaries to be made + +BINS= cf_ttag_to_hist get_shift mjd2hjd cf_reflux \ + idf_screen extract_jitter modhead \ + cf_arith cf_combine cf_nvo cf_pack cf_xcorr \ + idf_combine bpm_combine ttag_combine \ + cf_coadd cf_make_all_exp \ + remove_target_orbital_motion idf_cut \ + ttag_lightcurve \ + ttag_lightcurve_channel_sum \ + ttag_lightcurve_mjd2hmjd \ + ttag_lightcurve_combine \ + ttag_lightcurve_periodogram + +all: ${BINS} + chmod g+rw ${BINS} + +install: all + /bin/cp ${BINS} cf_make_all_obs.csh cf_make_900_obs.csh ${FUSEBINDIR} + +clean: + /bin/rm -f *.o ${BINS} + +distclean: + /bin/rm -f *.o ${BINS} + cd ../../bin; /bin/rm -f ${BINS} + +cf_arith: cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c + ${CC} ${CFLAGS} -o cf_arith cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c\ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_coadd: cf_coadd.c + ${CC} ${CFLAGS} -o cf_coadd cf_coadd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_combine: cf_combine.c cf_wrspec7.c + ${CC} ${CFLAGS} -o cf_combine cf_combine.c cf_wrspec7.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_make_all_exp: + ${CC} ${CFLAGS} -o cf_make_all_exp cf_make_all_exp.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_ttag_to_hist: + ${CC} ${CFLAGS} -o cf_ttag_to_hist cf_ttag_to_hist.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_combine: + ${CC} ${CFLAGS} -o ttag_combine ttag_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_combine: + ${CC} ${CFLAGS} -o idf_combine idf_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +bpm_combine: + ${CC} ${CFLAGS} -o bpm_combine bpm_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +get_shift: + ${CC} ${CFLAGS} -o get_shift get_shift.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_pack: + ${CC} ${CFLAGS} -o cf_pack cf_pack.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_nvo: + ${CC} ${CFLAGS} -o cf_nvo cf_nvo.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_reflux: + ${CC} ${CFLAGS} -o cf_reflux cf_reflux.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_xcorr: + ${CC} ${CFLAGS} -o cf_xcorr cf_xcorr.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +modhead: + ${CC} ${CFLAGS} -o modhead modhead.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve: + ${CC} ${CFLAGS} -o ttag_lightcurve ttag_lightcurve.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_periodogram: + ${CC} ${CFLAGS} -o ttag_lightcurve_periodogram ttag_lightcurve_periodogram.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +mjd2hjd: mjd2hjd.c gethmjd.c + ${CC} ${CFLAGS} -o mjd2hjd mjd2hjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_channel_sum: + ${CC} ${CFLAGS} -o ttag_lightcurve_channel_sum ttag_lightcurve_channel_sum.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_mjd2hmjd : ttag_lightcurve_mjd2hmjd.c gethmjd.c + ${CC} ${CFLAGS} -o ttag_lightcurve_mjd2hmjd ttag_lightcurve_mjd2hmjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_combine: + ${CC} ${CFLAGS} -o ttag_lightcurve_combine ttag_lightcurve_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_screen: + ${CC} ${CFLAGS} -o idf_screen idf_screen.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +remove_target_orbital_motion: remove_target_orbital_motion.c gethmjd.c + ${CC} ${CFLAGS} -o remove_target_orbital_motion remove_target_orbital_motion.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_cut: + ${CC} ${CFLAGS} -o idf_cut idf_cut.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +extract_jitter: + ${CC} ${CFLAGS} -o extract_jitter extract_jitter.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} diff --git a/src/analysis/Makefile.Linux64.orig b/src/analysis/Makefile.Linux64.orig new file mode 100644 index 0000000..2ef8094 --- /dev/null +++ b/src/analysis/Makefile.Linux64.orig @@ -0,0 +1,141 @@ + +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= -L/opt/SUNWspro/lib +FUSELIBS= -lsla -lcf +LIBS= -lc -lm -lnsl -ldl -lgfortran -lcfitsio +LDFLAGS= -Wl,-R${CALFUSEDIR}/lib + +# Binaries to be made + +BINS= cf_ttag_to_hist get_shift mjd2hjd cf_reflux \ + idf_screen extract_jitter modhead \ + cf_arith cf_combine cf_nvo cf_pack cf_xcorr \ + idf_combine bpm_combine ttag_combine \ + cf_coadd cf_make_all_exp \ + remove_target_orbital_motion idf_cut \ + ttag_lightcurve \ + ttag_lightcurve_channel_sum \ + ttag_lightcurve_mjd2hmjd \ + ttag_lightcurve_combine \ + ttag_lightcurve_periodogram + +all: ${BINS} + chmod g+rw ${BINS} + +install: all + /bin/cp ${BINS} cf_make_all_obs.csh cf_make_900_obs.csh ${FUSEBINDIR} + +clean: + /bin/rm -f *.o ${BINS} + +distclean: + /bin/rm -f *.o ${BINS} + cd ../../bin; /bin/rm -f ${BINS} + +cf_arith: cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c + ${CC} ${CFLAGS} -o cf_arith cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c\ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_coadd: cf_coadd.c + ${CC} ${CFLAGS} -o cf_coadd cf_coadd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_combine: cf_combine.c cf_wrspec7.c + ${CC} ${CFLAGS} -o cf_combine cf_combine.c cf_wrspec7.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_make_all_exp: + ${CC} ${CFLAGS} -o cf_make_all_exp cf_make_all_exp.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_ttag_to_hist: + ${CC} ${CFLAGS} -o cf_ttag_to_hist cf_ttag_to_hist.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_combine: + ${CC} ${CFLAGS} -o ttag_combine ttag_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_combine: + ${CC} ${CFLAGS} -o idf_combine idf_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +bpm_combine: + ${CC} ${CFLAGS} -o bpm_combine bpm_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +get_shift: + ${CC} ${CFLAGS} -o get_shift get_shift.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_pack: + ${CC} ${CFLAGS} -o cf_pack cf_pack.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_nvo: + ${CC} ${CFLAGS} -o cf_nvo cf_nvo.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_reflux: + ${CC} ${CFLAGS} -o cf_reflux cf_reflux.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_xcorr: + ${CC} ${CFLAGS} -o cf_xcorr cf_xcorr.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +modhead: + ${CC} ${CFLAGS} -o modhead modhead.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve: + ${CC} ${CFLAGS} -o ttag_lightcurve ttag_lightcurve.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_periodogram: + ${CC} ${CFLAGS} -o ttag_lightcurve_periodogram ttag_lightcurve_periodogram.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +mjd2hjd: mjd2hjd.c gethmjd.c + ${CC} ${CFLAGS} -o mjd2hjd mjd2hjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_channel_sum: + ${CC} ${CFLAGS} -o ttag_lightcurve_channel_sum ttag_lightcurve_channel_sum.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_mjd2hmjd : ttag_lightcurve_mjd2hmjd.c gethmjd.c + ${CC} ${CFLAGS} -o ttag_lightcurve_mjd2hmjd ttag_lightcurve_mjd2hmjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_combine: + ${CC} ${CFLAGS} -o ttag_lightcurve_combine ttag_lightcurve_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_screen: + ${CC} ${CFLAGS} -o idf_screen idf_screen.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +remove_target_orbital_motion: remove_target_orbital_motion.c gethmjd.c + ${CC} ${CFLAGS} -o remove_target_orbital_motion remove_target_orbital_motion.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_cut: + ${CC} ${CFLAGS} -o idf_cut idf_cut.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +extract_jitter: + ${CC} ${CFLAGS} -o extract_jitter extract_jitter.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} diff --git a/src/analysis/Makefile.MacOSX.orig b/src/analysis/Makefile.MacOSX.orig new file mode 100644 index 0000000..5e40b35 --- /dev/null +++ b/src/analysis/Makefile.MacOSX.orig @@ -0,0 +1,145 @@ + +FITSVER= 2.470 +CALFUSEDIR= ${PWD}/../.. +MACOSX_DEPLOYMENT_TARGET= 10.2 + +# Symbols for include directories +FUSEINCLDIR= -I${CALFUSEDIR}/include + +# Symbols used for compiling +CC= cc +OPT= -O3 -Wall -DCFORTRAN -Dg77Fortran -Df2cFortran +CFLAGS= ${OPT} ${FUSEINCLDIR} + +# Symbols used for creating shared binaries +FUSEBINDIR= ${CALFUSEDIR}/bin +FUSELIBDIR= -L${CALFUSEDIR}/lib +# FUSELIBS= -lsla -lcfitsio-${FITSVER} -lcf +FUSELIBS= -lsla -lcfitsio -lcf +LIBS= -lc -lm -ldl -L/sw/lib/ -lgfortran + +# Binaries to be made + +BINS= cf_ttag_to_hist get_shift mjd2hjd cf_reflux \ + idf_screen extract_jitter modhead \ + cf_arith cf_combine cf_nvo cf_pack cf_xcorr \ + idf_combine bpm_combine ttag_combine \ + cf_coadd cf_make_all_exp \ + remove_target_orbital_motion idf_cut \ + ttag_lightcurve \ + ttag_lightcurve_channel_sum \ + ttag_lightcurve_mjd2hmjd \ + ttag_lightcurve_combine \ + ttag_lightcurve_periodogram + +all: ${BINS} + chmod g+rw ${BINS} + +install: + MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET}"; \ + export MACOSX_DEPLOYMENT_TARGET; \ + make all + /bin/cp ${BINS} cf_make_all_obs.csh cf_make_900_obs.csh ${FUSEBINDIR} + +clean: + /bin/rm -f *.o ${BINS} + +distclean: + /bin/rm -f *.o ${BINS} + cd ../../bin; /bin/rm -f ${BINS} + +cf_arith: cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c + ${CC} ${CFLAGS} -o cf_arith cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c\ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_coadd: cf_coadd.c + ${CC} ${CFLAGS} -o cf_coadd cf_coadd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_combine: cf_combine.c cf_wrspec7.c + ${CC} ${CFLAGS} -o cf_combine cf_combine.c cf_wrspec7.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_make_all_exp: + ${CC} ${CFLAGS} -o cf_make_all_exp cf_make_all_exp.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_ttag_to_hist: + ${CC} ${CFLAGS} -o cf_ttag_to_hist cf_ttag_to_hist.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_combine: + ${CC} ${CFLAGS} -o ttag_combine ttag_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_combine: + ${CC} ${CFLAGS} -o idf_combine idf_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +bpm_combine: + ${CC} ${CFLAGS} -o bpm_combine bpm_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +get_shift: + ${CC} ${CFLAGS} -o get_shift get_shift.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_pack: + ${CC} ${CFLAGS} -o cf_pack cf_pack.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_nvo: + ${CC} ${CFLAGS} -o cf_nvo cf_nvo.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_reflux: + ${CC} ${CFLAGS} -o cf_reflux cf_reflux.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_xcorr: + ${CC} ${CFLAGS} -o cf_xcorr cf_xcorr.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +modhead: + ${CC} ${CFLAGS} -o modhead modhead.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve: + ${CC} ${CFLAGS} -o ttag_lightcurve ttag_lightcurve.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_periodogram: + ${CC} ${CFLAGS} -o ttag_lightcurve_periodogram ttag_lightcurve_periodogram.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +mjd2hjd: mjd2hjd.c gethmjd.c + ${CC} ${CFLAGS} -o mjd2hjd mjd2hjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_channel_sum: + ${CC} ${CFLAGS} -o ttag_lightcurve_channel_sum ttag_lightcurve_channel_sum.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_mjd2hmjd : ttag_lightcurve_mjd2hmjd.c gethmjd.c + ${CC} ${CFLAGS} -o ttag_lightcurve_mjd2hmjd ttag_lightcurve_mjd2hmjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_combine: + ${CC} ${CFLAGS} -o ttag_lightcurve_combine ttag_lightcurve_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_screen: + ${CC} ${CFLAGS} -o idf_screen idf_screen.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +remove_target_orbital_motion: remove_target_orbital_motion.c gethmjd.c + ${CC} ${CFLAGS} -o remove_target_orbital_motion remove_target_orbital_motion.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_cut: + ${CC} ${CFLAGS} -o idf_cut idf_cut.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +extract_jitter: + ${CC} ${CFLAGS} -o extract_jitter extract_jitter.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} diff --git a/src/analysis/Makefile.Solaris.orig b/src/analysis/Makefile.Solaris.orig new file mode 100644 index 0000000..52fb31b --- /dev/null +++ b/src/analysis/Makefile.Solaris.orig @@ -0,0 +1,147 @@ + +FITSVER= 2.470 +CALFUSEDIR= ${PWD}/../.. + +# Symbols for include directories +FUSEINCLDIR= -I${CALFUSEDIR}/include + +# Symbols used for compiling +CC= cc +# Romelfanger's optimizations +# OPT= -fast -xO5 -xtarget=ultra2 -xarch=v8plusa +# +# SunWorld's optimizations +# OPT= -p -v -xO2 -xdepend -xchip=ultra -xarch=generic +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 + +# Binaries to be made + +BINS= cf_ttag_to_hist get_shift mjd2hjd cf_reflux \ + idf_screen extract_jitter modhead \ + cf_arith cf_combine cf_nvo cf_pack cf_xcorr \ + idf_combine bpm_combine ttag_combine \ + cf_coadd cf_make_all_exp \ + remove_target_orbital_motion idf_cut \ + ttag_lightcurve \ + ttag_lightcurve_channel_sum \ + ttag_lightcurve_mjd2hmjd \ + ttag_lightcurve_combine \ + ttag_lightcurve_periodogram + +all: ${BINS} + chmod g+rw ${BINS} + +install: all + /bin/cp ${BINS} cf_make_all_obs.csh cf_make_900_obs.csh ${FUSEBINDIR} + +clean: + /bin/rm -f *.o ${BINS} + +distclean: + /bin/rm -f *.o ${BINS} + cd ../../bin; /bin/rm -f ${BINS} + +cf_arith: cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c + ${CC} ${CFLAGS} -o cf_arith cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c\ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_coadd: cf_coadd.c + ${CC} ${CFLAGS} -o cf_coadd cf_coadd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_combine: cf_combine.c cf_wrspec7.c + ${CC} ${CFLAGS} -o cf_combine cf_combine.c cf_wrspec7.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_make_all_exp: + ${CC} ${CFLAGS} -o cf_make_all_exp cf_make_all_exp.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_ttag_to_hist: + ${CC} ${CFLAGS} -o cf_ttag_to_hist cf_ttag_to_hist.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_combine: + ${CC} ${CFLAGS} -o ttag_combine ttag_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_combine: + ${CC} ${CFLAGS} -o idf_combine idf_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +bpm_combine: + ${CC} ${CFLAGS} -o bpm_combine bpm_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +get_shift: + ${CC} ${CFLAGS} -o get_shift get_shift.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_pack: + ${CC} ${CFLAGS} -o cf_pack cf_pack.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_nvo: + ${CC} ${CFLAGS} -o cf_nvo cf_nvo.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_reflux: + ${CC} ${CFLAGS} -o cf_reflux cf_reflux.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_xcorr: + ${CC} ${CFLAGS} -o cf_xcorr cf_xcorr.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +modhead: + ${CC} ${CFLAGS} -o modhead modhead.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve: + ${CC} ${CFLAGS} -o ttag_lightcurve ttag_lightcurve.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_periodogram: + ${CC} ${CFLAGS} -o ttag_lightcurve_periodogram ttag_lightcurve_periodogram.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +mjd2hjd: mjd2hjd.c gethmjd.c + ${CC} ${CFLAGS} -o mjd2hjd mjd2hjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_channel_sum: + ${CC} ${CFLAGS} -o ttag_lightcurve_channel_sum ttag_lightcurve_channel_sum.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_mjd2hmjd : ttag_lightcurve_mjd2hmjd.c gethmjd.c + ${CC} ${CFLAGS} -o ttag_lightcurve_mjd2hmjd ttag_lightcurve_mjd2hmjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_combine: + ${CC} ${CFLAGS} -o ttag_lightcurve_combine ttag_lightcurve_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_screen: + ${CC} ${CFLAGS} -o idf_screen idf_screen.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +remove_target_orbital_motion: remove_target_orbital_motion.c gethmjd.c + ${CC} ${CFLAGS} -o remove_target_orbital_motion remove_target_orbital_motion.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_cut: + ${CC} ${CFLAGS} -o idf_cut idf_cut.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +extract_jitter: + ${CC} ${CFLAGS} -o extract_jitter extract_jitter.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} diff --git a/src/analysis/Makefile.orig.orig b/src/analysis/Makefile.orig.orig new file mode 100644 index 0000000..52fb31b --- /dev/null +++ b/src/analysis/Makefile.orig.orig @@ -0,0 +1,147 @@ + +FITSVER= 2.470 +CALFUSEDIR= ${PWD}/../.. + +# Symbols for include directories +FUSEINCLDIR= -I${CALFUSEDIR}/include + +# Symbols used for compiling +CC= cc +# Romelfanger's optimizations +# OPT= -fast -xO5 -xtarget=ultra2 -xarch=v8plusa +# +# SunWorld's optimizations +# OPT= -p -v -xO2 -xdepend -xchip=ultra -xarch=generic +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 + +# Binaries to be made + +BINS= cf_ttag_to_hist get_shift mjd2hjd cf_reflux \ + idf_screen extract_jitter modhead \ + cf_arith cf_combine cf_nvo cf_pack cf_xcorr \ + idf_combine bpm_combine ttag_combine \ + cf_coadd cf_make_all_exp \ + remove_target_orbital_motion idf_cut \ + ttag_lightcurve \ + ttag_lightcurve_channel_sum \ + ttag_lightcurve_mjd2hmjd \ + ttag_lightcurve_combine \ + ttag_lightcurve_periodogram + +all: ${BINS} + chmod g+rw ${BINS} + +install: all + /bin/cp ${BINS} cf_make_all_obs.csh cf_make_900_obs.csh ${FUSEBINDIR} + +clean: + /bin/rm -f *.o ${BINS} + +distclean: + /bin/rm -f *.o ${BINS} + cd ../../bin; /bin/rm -f ${BINS} + +cf_arith: cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c + ${CC} ${CFLAGS} -o cf_arith cf_arith.c cf_wrspec7.c cf_wrspec_cf2.c\ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_coadd: cf_coadd.c + ${CC} ${CFLAGS} -o cf_coadd cf_coadd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_combine: cf_combine.c cf_wrspec7.c + ${CC} ${CFLAGS} -o cf_combine cf_combine.c cf_wrspec7.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_make_all_exp: + ${CC} ${CFLAGS} -o cf_make_all_exp cf_make_all_exp.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_ttag_to_hist: + ${CC} ${CFLAGS} -o cf_ttag_to_hist cf_ttag_to_hist.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_combine: + ${CC} ${CFLAGS} -o ttag_combine ttag_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_combine: + ${CC} ${CFLAGS} -o idf_combine idf_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +bpm_combine: + ${CC} ${CFLAGS} -o bpm_combine bpm_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +get_shift: + ${CC} ${CFLAGS} -o get_shift get_shift.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_pack: + ${CC} ${CFLAGS} -o cf_pack cf_pack.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_nvo: + ${CC} ${CFLAGS} -o cf_nvo cf_nvo.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_reflux: + ${CC} ${CFLAGS} -o cf_reflux cf_reflux.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +cf_xcorr: + ${CC} ${CFLAGS} -o cf_xcorr cf_xcorr.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +modhead: + ${CC} ${CFLAGS} -o modhead modhead.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve: + ${CC} ${CFLAGS} -o ttag_lightcurve ttag_lightcurve.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_periodogram: + ${CC} ${CFLAGS} -o ttag_lightcurve_periodogram ttag_lightcurve_periodogram.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +mjd2hjd: mjd2hjd.c gethmjd.c + ${CC} ${CFLAGS} -o mjd2hjd mjd2hjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_channel_sum: + ${CC} ${CFLAGS} -o ttag_lightcurve_channel_sum ttag_lightcurve_channel_sum.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_mjd2hmjd : ttag_lightcurve_mjd2hmjd.c gethmjd.c + ${CC} ${CFLAGS} -o ttag_lightcurve_mjd2hmjd ttag_lightcurve_mjd2hmjd.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +ttag_lightcurve_combine: + ${CC} ${CFLAGS} -o ttag_lightcurve_combine ttag_lightcurve_combine.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_screen: + ${CC} ${CFLAGS} -o idf_screen idf_screen.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +remove_target_orbital_motion: remove_target_orbital_motion.c gethmjd.c + ${CC} ${CFLAGS} -o remove_target_orbital_motion remove_target_orbital_motion.c gethmjd.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +idf_cut: + ${CC} ${CFLAGS} -o idf_cut idf_cut.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} + +extract_jitter: + ${CC} ${CFLAGS} -o extract_jitter extract_jitter.c \ + ${FUSELIBDIR} ${LIBDIR} ${FUSELIBS} ${LIBS} ${LDFLAGS} diff --git a/src/analysis/bpm_combine.c b/src/analysis/bpm_combine.c new file mode 100644 index 0000000..86ec7d0 --- /dev/null +++ b/src/analysis/bpm_combine.c @@ -0,0 +1,548 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSEbpm_combine + ***************************************************************************** + * + * Synopsis: bpm_combine output_bpm_file combined_idf_file + * + * + * Description: Creates a bpm file associated with a combined idf file + * It gets the names of the idf files from the combined idf + * file header. It gets the name of the bpm files from the idf + * files header. These bpm files are then combined using the + * offset information provided in the combined idf file header. + * The BPM_CAL keyword is updated in the combined idf file + * header. + * + * WARNING: all the single exposure IDF files (who took part in + * the creation of the idf_file) and their associated BPM files + * must be in the working directory. + * + * + * History: 12/03/03 bjg v1.0 Begin work. + * 12/05/03 bjg First version that compiles + * + * 12/10/03 bjg Accept now only idf as parameter + * Updated NSPEC keyword and + * SPECxxx, WOFFLxxx, WOFFSxxx + * keywords + * Removed paths in filenames + * written into header. + * 04/05/04 bjg Remove unused variables + * Change formats to match arg + * types in printf + * 05/25/04 bjg Skip when BPM_CAL unpopulated + * or not present. + * 04/13/05 wvd v2.0 combined_idf_file may be + * replaced by a file containing + * a list of BPM files. The first + * line of this file must contain + * the number of entries that + * follow. + * + ****************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include "calfuse.h" + +typedef char filename[FLEN_CARD]; + + + +static char CF_PRGM_ID[]= "bpm_combine"; +static char CF_VER_NUM[]= "2.0"; + +int main(int argc,char *argv[]){ + + char date[FLEN_CARD]={'\0'}; + char rootname[FLEN_CARD]; + char *corrected_filename; + char *string_pointer; + + int felem_hdu2; + + char stime[FLEN_CARD],keyword[FLEN_CARD]; + + + + time_t vtime; + + fitsfile *infits,*outfits,*idffits; + char *has_bpm_list; + filename *filelist; + double *expstartlist; + double *expendlist; + long *neventslist; + double *sicshiftlist; + double *lifshiftlist; + double *exptimelist; + + double delta_t; + + filename tempstring,tempstring2; + double tempdouble; + long templong; + float tempfloat; + char tempchar; + + double minexpstart; + int minindex; + + int nfiles; + + int intnull=0,anynull; + int ncol; + + int status=0; + int hdutype=0; + int tref = 0; + + long nevents=0; + long n_real_events=0; + long i,j,istart; + + + float * xfield,*yfield,*weightfield,*lambdafield; + char *channelfield; + + char fmt_byte[FLEN_CARD],fmt_float[FLEN_CARD],fmt_short[FLEN_CARD]; + + double totalexptime=0, rawtime=0; + long neventscreened=0, neventscreenedpha=0; + float timescreened=0, timesaa=0, timelowlimbangle=0, timeburst=0, timejitter=0,timenight=0; + + + + int hdu2_tfields=5; + + char hdu2_extname[]="POTHOLE_DATA"; /* Name of this extension */ + + char *hdu2_ttype[]={"X", "Y", "CHANNEL", "WEIGHT", "LAMBDA"}; + + char *hdu2_tform[5]; /* We'll assign values when we know + the number of elements in the data set. */ + + + char *hdu2_tunit[]={"PIXELS", "PIXELS", "UNITLESS", "UNITLESS", "ANGSTROMS"}; + + + FILE *fp=NULL; + char line[FLEN_FILENAME]; + int maxline=FLEN_FILENAME; + + + if (argc != 3) { + printf("Incorrect number of arguments.\n"); + printf("Calling sequence:bpm_combine bpm_file combined_idf_file\n"); + printf("Final argument may be the name of a file containing a list of BPM files.\n"); + printf("First line must be number of BPM files in list.\n"); + exit(1); + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + /* get and display time */ + vtime = time(NULL) ; + strcpy(stime,ctime(&vtime)); + + fits_open_file(&idffits,argv[2],READONLY,&status); + if (status) { + status = 0; + if ((fp = fopen(argv[2], "r")) == NULL) { + printf("Can't open file %s\n", argv[2]); + return 1; + } + if ((fgets(line, maxline, fp)) == NULL) { + printf("Error reading file %s\n", argv[2]); + return 1; + } + sscanf(line,"%d",&nfiles); + } + else FITS_read_key(idffits,TINT,"NSPEC",&nfiles,NULL,&status); + + filelist = (filename *)malloc(nfiles*sizeof(filename)); + neventslist = (long *)malloc(nfiles*sizeof(long)); + sicshiftlist = (double *)calloc((size_t)nfiles,sizeof(double)); + lifshiftlist = (double *)calloc((size_t)nfiles,sizeof(double)); + expstartlist = (double *)malloc(nfiles*sizeof(double)); + expendlist = (double *)malloc(nfiles*sizeof(double)); + exptimelist = (double *)malloc(nfiles*sizeof(double)); + has_bpm_list = (char *)malloc(nfiles*sizeof(char)); + + for (i=0; i<nfiles;i++) { + + has_bpm_list[i]=1; + + if (fp != NULL) { + if((fgets(line, maxline, fp)) == NULL) { + printf("Error reading %s\n", argv[2]); + return 1; + } + sscanf(line, "%s", filelist[i]); + } + else { + /* Read name of individual IDF file from combined file header. */ + sprintf(tempstring, "SPEC%.3ld", i+1); + FITS_read_key(idffits,TSTRING,tempstring,tempstring2,NULL,&status); + /* Open individual IDF file and read name of associated BPM file. */ + FITS_open_file(&infits,tempstring2,READONLY,&status); + fits_read_key(infits,TSTRING,"BPM_CAL",filelist[i],NULL,&status); + if (status) { + status=0; + FITS_close_file(infits,&status); + printf("BPM_CAL keyword not found in IDF %s; skipping.\n",tempstring2); + has_bpm_list[i]=0; + filelist[i][0]='\0'; + continue; + } + /* Close individual IDF file. */ + FITS_close_file(infits,&status); + + /* These keywords don't apply to a user-provided list of BPM files. */ + sprintf(tempstring, "WOFFL%.3ld", i+1); + FITS_read_key(idffits,TDOUBLE,tempstring,&lifshiftlist[i],NULL,&status); + + sprintf(tempstring, "WOFFS%.3ld", i+1); + FITS_read_key(idffits,TDOUBLE,tempstring,&sicshiftlist[i],NULL,&status); + } + + /* Open individual BPM file. */ + fits_open_file(&infits,filelist[i],READONLY,&status); + if (status) { + status=0; + printf("Could not open BPM %s for IDF %s; BPM_CAL keyword may be incorrectly populated; skipping.\n",filelist[i],tempstring2); + has_bpm_list[i]=0; + filelist[i][0]='\0'; + continue; + } + + FITS_read_key(infits,TDOUBLE,"EXPSTART",&(expstartlist[i]),NULL,&status); + FITS_read_key(infits,TDOUBLE,"EXPEND",&(expendlist[i]),NULL,&status); + + FITS_read_key(infits,TDOUBLE,"EXPTIME",&(exptimelist[i]),NULL,&status); + totalexptime+=exptimelist[i]; + + FITS_read_key(infits,TDOUBLE,"RAWTIME",&(tempdouble),NULL,&status); + rawtime+=tempdouble; + + FITS_read_key(infits,TLONG,"NBADEVNT",&templong,NULL,&status); + neventscreened+=templong; + FITS_read_key(infits,TLONG,"NBADPHA",&templong,NULL,&status); + neventscreenedpha+=templong; + + FITS_read_key(infits,TFLOAT,"EXP_BAD",&tempfloat,NULL,&status); + timescreened+=tempfloat; + FITS_read_key(infits,TFLOAT,"EXP_SAA",&tempfloat,NULL,&status); + timesaa+=tempfloat; + FITS_read_key(infits,TFLOAT,"EXP_LIM",&tempfloat,NULL,&status); + timelowlimbangle+=tempfloat; + FITS_read_key(infits,TFLOAT,"EXP_BRST",&tempfloat,NULL,&status); + timeburst+=tempfloat; + FITS_read_key(infits,TFLOAT,"EXP_JITR",&tempfloat,NULL,&status); + timejitter+=tempfloat; + FITS_read_key(infits,TFLOAT,"EXPNIGHT",&tempfloat,NULL,&status); + timenight+=tempfloat; + + FITS_read_key(infits,TFLOAT,"NEVENTS",&templong,NULL,&status); + n_real_events+=templong; + + + FITS_movabs_hdu(infits,2,&hdutype,&status); + + FITS_read_key(infits,TSTRING,"TFORM1",&tempstring,NULL,&status); + sscanf(tempstring,"%ld%c",&neventslist[i],&tempchar); + nevents+=neventslist[i]; + + FITS_close_file(infits,&status); + + } + + if (fp != NULL) fclose(fp); + else FITS_close_file(idffits,&status); + + + + + + + printf("---SORTING INPUT FILES IN TIME ORDER---\n") ; + + for (i=0; i<nfiles-1;i++) { + if (!(has_bpm_list[i])) continue; + minexpstart=expstartlist[i]; + minindex=i; + for (j=i+1; j<nfiles;j++) { + if (!(has_bpm_list[j])) continue; + if (expstartlist[j]<minexpstart){ + minexpstart=expstartlist[j]; + minindex=j; + } + } + + strcpy(tempstring,filelist[minindex]); + strcpy(filelist[minindex],filelist[i]); + strcpy(filelist[i],tempstring); + + tempdouble=expstartlist[minindex]; + expstartlist[minindex]=expstartlist[i]; + expstartlist[i]=tempdouble; + + tempdouble=expendlist[minindex]; + expendlist[minindex]=expendlist[i]; + expendlist[i]=tempdouble; + + tempdouble=exptimelist[minindex]; + exptimelist[minindex]=exptimelist[i]; + exptimelist[i]=tempdouble; + + templong=neventslist[minindex]; + neventslist[minindex]=neventslist[i]; + neventslist[i]=templong; + + tempdouble=lifshiftlist[minindex]; + lifshiftlist[minindex]=lifshiftlist[i]; + lifshiftlist[i]=tempdouble; + + tempdouble=sicshiftlist[minindex]; + sicshiftlist[minindex]=sicshiftlist[i]; + sicshiftlist[i]=tempdouble; + + } + + istart=-1; + + for (i=0; i<nfiles;i++) { + if (!(has_bpm_list[i])) continue; + printf("%s %7.1f %7.1f %4ld %f %f\n",filelist[i],expstartlist[i],expendlist[i],neventslist[i],lifshiftlist[i],sicshiftlist[i]); + if (istart==-1) istart=i; + } + printf("\n"); + + if (istart==-1) { + printf("No BPM files found. Exiting\n"); + exit(0); + } + + + + + printf("--------CREATING OUTPUT FILE-----\n"); + + FITS_open_file(&infits,filelist[istart],READONLY,&status); + FITS_create_file(&outfits,argv[1],&status); + + + + + printf("--------WRITING MAIN HEADER-----\n"); + + FITS_copy_hdu(infits,outfits,0,&status); + + FITS_read_key(infits,TSTRING,"ROOTNAME",rootname,NULL,&status); + + rootname[8]='9'; + rootname[9]='9'; + rootname[10]='9'; + + FITS_update_key(outfits,TSTRING,"ROOTNAME",rootname,NULL,&status); + + string_pointer=strrchr(argv[1],'/'); + if (string_pointer==NULL) corrected_filename=argv[1]; + else corrected_filename=&(string_pointer[1]); + + FITS_update_key(outfits,TSTRING,"FILENAME",corrected_filename,NULL,&status); + + FITS_update_key(outfits,TSTRING,"EXP_ID","999",NULL,&status); + + string_pointer=strrchr(argv[2],'/'); + if (string_pointer==NULL) corrected_filename=argv[2]; + else corrected_filename=&(string_pointer[1]); + + + if (fp == NULL) + FITS_update_key(outfits,TSTRING,"IDF_FILE",corrected_filename,NULL,&status); + + + + + fits_get_system_time(date, &tref, &status); + + FITS_update_key(outfits,TSTRING,"DATE",date,NULL,&status); + + FITS_update_key(outfits,TDOUBLE,"EXPEND",&expendlist[nfiles-1],NULL,&status); + FITS_update_key(outfits,TDOUBLE,"EXPTIME",&totalexptime,NULL,&status); + FITS_update_key(outfits,TDOUBLE,"RAWTIME",&rawtime,NULL,&status); + FITS_update_key(outfits,TLONG,"NEVENTS",&n_real_events,NULL,&status); + FITS_update_key(outfits,TLONG,"NBADEVNT",&neventscreened,NULL,&status); + FITS_update_key(outfits,TLONG,"NBADPHA",&neventscreenedpha,NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXP_BAD",&(timescreened),NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXP_SAA",&(timesaa),NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXP_LIM",&(timelowlimbangle),NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXP_BRST",&(timeburst),NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXP_JITR",&(timejitter),NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXPNIGHT",&(timenight),NULL,&status); + + fits_write_history(outfits," COMBINED WITH BPM_COMBINE ",&status); + + FITS_update_key(outfits,TINT,"NSPEC",&nfiles,NULL,&status); + + for (i=0;i<nfiles;i++){ + + if (!(has_bpm_list[i])) continue; + + string_pointer=strrchr(filelist[i],'/'); + if (string_pointer==NULL) corrected_filename=filelist[i]; + else corrected_filename=&(string_pointer[1]); + + sprintf(keyword, "SPEC%.3ld", i+1); + FITS_update_key(outfits,TSTRING,keyword,corrected_filename,NULL,&status); + sprintf(keyword, "WOFFL%.3ld", i+1); + FITS_update_key(outfits,TFLOAT,keyword,&lifshiftlist[i],NULL,&status); + sprintf(keyword, "WOFFS%.3ld", i+1); + FITS_update_key(outfits,TFLOAT,keyword,&sicshiftlist[i],NULL,&status); + + + + } + + + + + FITS_close_file(infits,&status); + + printf("--------PREPARING EVENTS LIST HDU-----\n"); + + /* Generate the tform array */ + sprintf(fmt_byte, "%ldB", nevents); + sprintf(fmt_float, "%ldE", nevents); + sprintf(fmt_short, "%ldI", nevents); + + hdu2_tform[0] = fmt_float; + hdu2_tform[1] = fmt_float; + hdu2_tform[2] = fmt_byte; + hdu2_tform[3] = fmt_float; + hdu2_tform[4] = fmt_float; + + + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, 1, hdu2_tfields, hdu2_ttype, hdu2_tform, + hdu2_tunit, hdu2_extname, &status); + + + + + + + + printf("--------COMBINING HDU-----\n"); + felem_hdu2=1; + for (i=0;i<nfiles;i++){ + if (!(has_bpm_list[i])) continue; + + + delta_t=(expstartlist[i]-expstartlist[0])*3600*24; + + FITS_open_file(&infits,filelist[i],READONLY,&status); + + + FITS_movabs_hdu(infits, 2, &hdutype, &status); + FITS_movabs_hdu(outfits, 2, &hdutype, &status); + printf("Processing file %s\n",filelist[i]); + + xfield=(float *)malloc(neventslist[i]*sizeof(float)); + yfield=(float *)malloc(neventslist[i]*sizeof(float)); + channelfield=(char *)malloc(neventslist[i]*sizeof(char)); + weightfield=(float *)malloc(neventslist[i]*sizeof(float)); + lambdafield=(float *)malloc(neventslist[i]*sizeof(float)); + + + FITS_get_colnum(infits, TRUE, "X", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + xfield, &anynull, &status); + + + FITS_get_colnum(infits, TRUE, "Y", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + yfield, &anynull, &status); + + + FITS_get_colnum(infits, TRUE, "CHANNEL", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, neventslist[i], &intnull, + channelfield, &anynull, &status); + + + FITS_get_colnum(infits, TRUE, "WEIGHT", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + weightfield, &anynull, &status); + + + FITS_get_colnum(infits, TRUE, "LAMBDA", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + lambdafield, &anynull, &status); + + + + + for (j=0;j<neventslist[i];j++){ + if (channelfield[j]<5) lambdafield[j]=lambdafield[j]+lifshiftlist[i]; + if (channelfield[j]>4) lambdafield[j]=lambdafield[j]+sicshiftlist[i]; + weightfield[j]=weightfield[j]*exptimelist[i]/totalexptime; + } + + + + FITS_write_col(outfits, TFLOAT, 1, 1, felem_hdu2, neventslist[i], xfield, &status); + FITS_write_col(outfits, TFLOAT, 2, 1, felem_hdu2, neventslist[i], yfield, &status); + FITS_write_col(outfits, TBYTE, 3, 1, felem_hdu2, neventslist[i], channelfield, &status); + FITS_write_col(outfits, TFLOAT, 4, 1, felem_hdu2, neventslist[i], weightfield, &status); + FITS_write_col(outfits, TFLOAT, 5, 1, felem_hdu2, neventslist[i], lambdafield, &status); + + + free(xfield); + free(yfield); + free(channelfield); + free(weightfield); + free(lambdafield); + + felem_hdu2+=neventslist[i]; + + FITS_close_file(infits,&status); + + + } + + printf("--------CLOSING OUTPUT FILE-----\n"); + + + FITS_close_file(outfits,&status); + + + if (fp == NULL) { + FITS_open_file(&idffits,argv[2],READWRITE,&status); + + string_pointer=strrchr(argv[1],'/'); + if (string_pointer==NULL) corrected_filename=argv[1]; + else corrected_filename=&(string_pointer[1]); + + FITS_update_key(idffits,TSTRING,"BPM_CAL",corrected_filename,NULL,&status); + FITS_close_file(idffits,&status); + } + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + diff --git a/src/analysis/cf_arith.c b/src/analysis/cf_arith.c new file mode 100644 index 0000000..94e40e9 --- /dev/null +++ b/src/analysis/cf_arith.c @@ -0,0 +1,2154 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: cf_arith infile1 op infile2 outfile + * + * Description: This is a generic utility program that performs arithmetic + * operations on two FUSE FITS files. The files must + * contain extracted FUSE spectra. + * Input files are assumed to have 6 columns in a binary + * table in the first extension (wavelength, flux, error, quality, + * counts, counts_error). Files with 4 columns (no counts or + * counts_error) are also handled for compatibility with + * pipeline output written prior to 12/1/99. + * + * (The next paragraph is included for completeness, but is + * not expected to be applicable to most users). + * If infile1 and infile2 have the same number of extensions, + * the specified operation is performed for each extension + * (outfile_ext_i = infile1_ext_i op infile2_ext_i). + * If infile2 has a single extension, the operation is performed + * for each extension in infile1 with the extension in infile2 + * (outfile_ext_i = infile1_ext_i op infile2_ext_1). + * + * infile1 and infile2 must have the same number of elements + * in each binary table (ie. binned by the same factor). + * infile2 may be a numeric string instead of a file. + * The header in outfile will be the same as for infile1, + * plus some HISTORY lines. + * No check is performed that the wavelengths in infile2 match + * those in infile1. + * It is assumed that error arrays contain errors, not variances. + * + * If infile2 is the string "EXPTIME" (without the quotes) + * operand 2 is set to the exposure time in the header of infile1. + * + * valid choices for the operation "op" are: + * +, -, *, /, avg_t, avg_s, repl_d, repl_e, boxcar, delta, + * min, max, shift, bin, deriv, addnoise + * + * avg_t = average weighted by exposure time + * avg_s = average weighted by sigma (errors) + * avg_t, avg_s valid only if infile2 is a fits file. + * repl_d = replace data in operand1 with data from operand2 + * repl_e = replace errors in operand1 with errors from operand2 + * boxcar = smooth data in operand1 with moving boxcar + * of width operand2. If operand2 is a FITS file, + * the "FLUX" column is used as the width. This + * permits application of variable smoothing. + * delta = adds delta functions to operand 1 every 100 pixels; + * height is equal to operand 2 (must be a scalar). + * Used only for creating test spectra. + * shift = shift data by the specified number of pixels. Operand2 + * must be an integer. A positive shift moves the data + * to higher pixel numbers. + * bin = bin data by the specified number of pixels. Operand2 + * must be an integer. The flux column is averaged, the + * counts column is summed. + * deriv = take derivative of input: out[i] = in[i+1] - in[i] + * operand 2 is ignored for this! + * addnoise = a uniformly distributed random number in the range + * +/-operand2 is added pixel-by-pixel to the flux + * Used only for creating test spectra. + * + * If op = "+" and the second operand is a file (not a scalar), + * or if op = "avg_t" or if op = "avg_s", the exposure + * time in the output is the sum of the exposure times + * in the input files. + * + * For op1 min op2 out: op1 is replaced by op2 if op1 < op2. + * (op2 sets a min value for the flux) + * For op1 max op2 out: op1 is replaced by op2 if op1 > op2. + * (op2 sets a max value for the flux) + * + * The same operations are performed on the counts/countserr + * columns as on the flux/fluxerr columns. In most cases this + * leads to reasonable results. However, in a few cases, such + * as addition or subtraction of a scalar, the result is likely + * to be meaningless for either the flux or counts columns. + * Exceptions: MIN, MAX, REPL_D, REPL_E, DELTA, only affect + * the flux and fluxerr columns. The counts and countserror + * columns are unaffected. + * + * Note that avg_t and avg_s also average the counts; in some + * cases the user may have really wanted the counts to be summed! + * + * NOTE: Must enclose * in quotes (ie. "*") or the shell + * will expand it into filenames in the pwd! + * + * + * History: 08/15/99 jwk started work + * 10/25/99 v1.1 jwk avg_t,_s sum exp times in output + * 11/30/99 jwk handle either 4 or 6-column files + * 01/06/00 v1.2 jwk add bin option + * 05/01/00 v1.3 jwk handle byte or short quality flags + * 09/20/00 v1.4 jwk add derivative operation + * 10/11/00 v1.5 jwk update FILENAME keyword in output file + * 12/11/00 v1.6 jwk improve numeric accuracy of error prop. + * 01/23/01 v1.7 jwk smooth quality rather than sum when + * doing BOXCAR, to avoid overflow of + * short datasize. + * 10/10/01 v1.8 jwk add handling of eff area files + * 05/30/03 v1.9 jwk change timeval from long to time_t; put + * ifdef SOLARIS/endif around ieee_retro + * spec field width for final timestamp + * (make consistent with calfuse version) + * 02/04/04 v2.0 jwk implement addnoise option + * 02/25/04 v2.1 jwk check for zero errors in avg_s code + * 03/06/04 v3.0 jwk add support for calfuse 3.0 files + * 04/05/04 v3.1 bjg Declarations for cf_wrspec7 and + * cf_wrspec_cf2 + * Include ctype.h + * Correct formats to match argument + * types in printf + * Remove unused variable long npix + * Casting to char * arg of setstate + * Remove local definitions of + * initstate() and setstate() + * Correct use of cf_wrspec7 + * 08/26/05 v3.2 wvd Change name from cf_arith3 to cf_arith. + * If no arguments, don't return error. + * Just print message and exit.\ + * 08/27/07 v3.3 bot Added L to long l.399 and 537 + * + ****************************************************************************/ + +#include <time.h> +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include "calfuse.h" +#include <ctype.h> + +#define PLUS 1 +#define MINUS 2 +#define MULT 3 +#define DIV 4 +#define AVG_T 5 +#define AVG_S 6 +#define REPL_D 7 +#define REPL_E 8 +#define BOXCAR 9 +#define DELTA 10 +#define MIN 11 +#define MAX 12 +#define SHIFT 13 +#define BIN 14 +#define DERIV 15 +#define ADDNOISE 16 + +/* arbitrary value for error when no data is present */ +#define DEF_ERROR 1.e-3 + +#define MAX_RAND 0x7fffffff + +static char CF_PRGM_ID[] = "cf_arith"; +static char CF_VER_NUM[] = "3.3"; + + +void cf_wrspec7(fitsfile *outfits, long npts, float *wave, float *flux, + float *error, long *counts, float *weights, + float *bkgd,short *pothole); +void cf_wrspec_cf2(fitsfile *outfits, int npts, float *wave, + float *spec, float *errs, short *qual, + float *counts, float *cntserr, int ncol, + int areaflag); + + + + +int main(int argc, char *argv[]) +{ + char *timestr; + time_t timeval; + char infile1[80], infile2[80], outfile[80]; + char comment[FLEN_CARD]; + char expt_comment[FLEN_CARD]; + char errstr[80]; + char datatype[20]; + int areaflag; + int nbin; + int next_1, next_2; + int status=0, anynull=0, intnull=0; + int hdutype_1, hdutype_2, hdutype_o; + int hdunum_1, hdunum_2, hdunum_o; + long npix_1, npix_2, npix_o; + long naxis2_1, naxis2_2; + int fluxcol, wavecol, errorcol, qualcol, cntscol, cntserrcol; + int bkgdcol, wgtscol; + int tfields_1, tfields_2; + int opcode; + int cf_version; + long i, j, k, k1, k2; + int arg2_scalar; + int p_shift; + float arg2_val; + float swave, sflux, sferr, scnts, scerr, spix; + float sbkgd, swgts; + long lqual, slcts; + short squal; + short *qual1, *qual2, *qual_o; + float *wave1, *flux1, *flxerr1, *cnts1, *cntserr1; + float *flux2, *flxerr2, *cnts2, *cntserr2; + float *flux_o, *flxerr_o, *cnts_o, *cntserr_o; + float *wave_o; + float *wgts1, *wgts2, *wgts_o; + float *bkgd1, *bkgd2, *bkgd_o; + long *lcts1, *lcts2, *lcts_o; + char tformstr[FLEN_CARD]; + char key_str[FLEN_CARD]; + char qual_lbl[FLEN_CARD]; + float f1, f2, fn; + float tmp1, tmp2, tmp3, tmp4; + float exptime_1, exptime_2, exptime_o; + fitsfile *infits_1, *infits_2, *outfits; + int chkop(); + int check_num(); + void padstr(); + /* following items used by random number generator */ + clock_t clock(); /* system clock function */ + int ns; /* used by random # generator */ + unsigned long seed; /* random # generator seed */ + /* char *initstate(), *setstate(); */ + double rand1(); + +/* Initialize random number generator state array. */ + static unsigned long state1[32] = { 3, 0x9a319039, + 0x32d9c024, 0x9b663182, 0x5da1f342, 0x7449e56b, + 0xbeb1dbb0, 0xab5c5918, 0x946554fd, 0x8c2e680f, + 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, + 0x1588ca88, 0xe369735d, 0x904f35f7, 0xd7158fd6, + 0x6fa6f051, 0x616e6b96, 0xac94efdc, 0xde3b81e0, + 0xdf0a6fb5, 0xf103bc02, 0x48f340fb, 0x36413f93, + 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, + 0x8999220b, 0x27fb47b9 }; + + + /* perform an initial call to clock() - clock() returns the elapsed time + * since the first call, so in order to use it for a random # generator + * seed later we have to get it started here. Subsequent calls follow + * opening of the first file, so that should provide some run-to-run + * variations. + */ + seed = clock(); + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing"); + + /* Initialize error checking */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + + /* check command line */ + if (argc != 5) { + printf("Usage: cf_arith infile1 op infile2 outfile\n"); + return 1; + } + + strcpy (infile1, argv[1]); + strcpy (infile2, argv[3]); + strcpy (outfile, argv[4]); + + if ((opcode = chkop (argv[2])) == 0) + { + sprintf (comment,"Undefined operation: %s\n", argv[2]); + cf_if_error (comment); + } + + /* Open input file(s) */ + + FITS_open_file(&infits_1, infile1, READONLY, &status); + + /* get number of extensions in operand1 */ + FITS_get_num_hdus (infits_1, &next_1, &status); + next_1--; + + /* get exposure time in case we need it later. */ + ffgky(infits_1, TFLOAT, "EXPTIME", &exptime_1, expt_comment, &status); + if (status) + { + fprintf (stderr, "Keyword EXPTIME not found; set exptime_1=1.0\n"); + exptime_1 = 1.0; + status = 0; + } + exptime_o = exptime_1; + + /* check nature of second operand: is it a number? */ + /* can have leading sign, and may contain E,e,D,d and additional sign */ + arg2_scalar = check_num (argv[3]); + if (arg2_scalar) + arg2_val = atof (argv[3]); + + /* Also allow the possibility of having argv[3] = "EXPTIME": */ + if (!strcmp (argv[3], "EXPTIME")) + { + arg2_scalar = TRUE; + arg2_val = exptime_1; + } + + /* check for valid operand if operation is SHIFT: */ + p_shift = 0; + if (opcode == SHIFT) + { + if (!arg2_scalar) + cf_if_error ("SHIFT requires scalar argument!\n"); + + /* convert argument to an integer */ + p_shift = (int) strtol (argv[3], (char **)NULL, 10); + } + + /* check for valid operand if operation is BIN: */ + nbin = 1; + if (opcode == BIN) + { + if (!arg2_scalar) + cf_if_error ("BIN requires scalar argument!\n"); + + /* convert argument to an integer */ + nbin = (int) strtol (argv[3], (char **)NULL, 10); + if (nbin < 1) + { + sprintf (errstr, "bin factor = %d; must be >0!\n", nbin); + cf_if_error (errstr); + } + } + + /* Check for valid operand if operation is ADDNOISE: + * I suppose we could relax this and take a pixel-by-pixel amplitude + * from a spectrum, but let's keep it simple for now. + * Also initialize random number generator. + */ + if (opcode == ADDNOISE) + { + if (!arg2_scalar) + cf_if_error ("ADDNOISE requires scalar argument!\n"); + + /* initialize random number generator */ + /* the local clock function doesn't change rapidly enough to be + * useful, even though it is nominally at microsecond resolution */ + /* seed = 2 * (clock() & 0x0ffff) + 1; */ + time (&timeval); + seed = 2 * timeval + 1; + + ns = 128; + initstate (seed, (char *) state1, ns); + setstate ((char *)state1); + } + + /* bypass operand2 if op= derivative; we ignore op2 in this case*/ + if (opcode == DERIV) + arg2_scalar = TRUE; + + if (!arg2_scalar) + { + FITS_open_file (&infits_2, infile2, READONLY, &status); + FITS_get_num_hdus (infits_2, &next_2, &status); + next_2--; + + if ((next_2 != next_1) && (next_2 != 1)) + { + fprintf (stderr, "file %s has %d extensions.\n", infile1, next_1); + fprintf (stderr, "file %s has %d extensions.\n", infile2, next_2); + cf_if_error ("Illegal combination, aborting!\n"); + } + ffgky(infits_2, TFLOAT, "EXPTIME", &exptime_2, expt_comment, &status); + if (status) + { + fprintf (stderr, "Keyword EXPTIME not found; set exptime_2=1.0\n"); + exptime_2 = 1.0; + status = 0; + } + } + + /* open output file */ + + remove(outfile); /*In case the old file name exists*/ + FITS_create_file (&outfits, outfile, &status); + + /* Copy header from first operand. The output file will have the same + * number of extensions as operand1. + */ + /* cf_cp_hdr(infits_1, 1, outfits, 1); */ + FITS_copy_header (infits_1, outfits, &status); + + /* Loop over extensions */ + for ( i = 1; i <= next_1; i++ ) + { + hdunum_1=i+1; + + FITS_movabs_hdu(infits_1, hdunum_1, &hdutype_1, &status); + /* for Calfuse 2 and before, array length is specified by NAXIS2. + * For Calfuse 3, need to get it from TFORM1. + */ + FITS_read_key(infits_1, TLONG, "NAXIS2", &naxis2_1, NULL, &status); + if (naxis2_1 > 1L) + npix_1 = naxis2_1; + else + { + FITS_read_key(infits_1, TSTRING, "TFORM1", tformstr, NULL, &status); + sscanf (tformstr, "%ldE", &npix_1); + } + + + /* need to figure out what kind of data we have. + * tfields=4 implies very old calfuse files, or effective area files; + * tfields=6 implies calfuse 1.8 or 2.x + * tfields=7 implies calfuse 3.x + * Each has different types of data columns. + */ + FITS_read_key(infits_1, TINT, "TFIELDS", &tfields_1, NULL, &status); + + if ((tfields_1 == 4) || (tfields_1 == 6)) + cf_version = 2; + else if (tfields_1 == 7) + cf_version = 3; + else + { + sprintf (errstr, "Expecting 4,6 or 7 cols, found %d\n", tfields_1); + cf_if_error (errstr); + } + + /* Allocate data arrays */ + wave1 = (float *) cf_malloc(sizeof(float) * npix_1); + flux1 = (float *) cf_malloc(sizeof(float) * npix_1); + flxerr1 = (float *) cf_malloc(sizeof(float) * npix_1); + qual1 = (short *) cf_malloc(sizeof(short) * npix_1); + + if (cf_version == 2) + { + cnts1 = (float *) cf_malloc(sizeof(float) * npix_1); + cntserr1 = (float *) cf_malloc(sizeof(float) * npix_1); + } + else + { + lcts1 = (long *) cf_malloc(sizeof(long) * npix_1); + bkgd1 = (float *) cf_malloc(sizeof(float) * npix_1); + wgts1 = (float *) cf_malloc(sizeof(float) * npix_1); + } + + /* Get the column numbers from file 1 */ + FITS_read_key(infits_1, TSTRING, "TTYPE2", datatype, NULL, &status); + if (!strcmp(datatype, "FLUX")) + { + areaflag = FALSE; + FITS_get_colnum(infits_1, TRUE, "FLUX", &fluxcol, &status); + } + else + { + areaflag = TRUE; + FITS_get_colnum(infits_1, TRUE, "AREA", &fluxcol, &status); + } + + FITS_get_colnum(infits_1, TRUE, "WAVE", &wavecol, &status); + FITS_get_colnum(infits_1, TRUE, "ERROR", &errorcol, &status); + + /* don't know at present if calfuse 3.x will use "QUALITY" or + * "POTHOLE", so check both. + */ + if (cf_version == 2) + FITS_get_colnum(infits_1, TRUE, "QUALITY", &qualcol, &status); + else + { + qualcol = 0; + for (j=1; j<=tfields_1; j++) + { + sprintf (key_str, "TTYPE%1ld", j); + FITS_read_key(infits_1, TSTRING, key_str,datatype, NULL, &status); + if (!strcmp (datatype, "QUALITY") || !strcmp(datatype,"POTHOLE")) + { + strcpy (qual_lbl, datatype); + qualcol = j; + } + } + if (qualcol == 0) + cf_if_error ("QUALITY column not found!"); + } + + if (tfields_1 == 6) + { + FITS_get_colnum(infits_1, TRUE, "COUNTS", &cntscol, &status); + FITS_get_colnum(infits_1, TRUE, "CNTSERR", &cntserrcol, &status); + } + + if (tfields_1 == 7) + { + FITS_get_colnum(infits_1, TRUE, "COUNTS", &cntscol, &status); + FITS_get_colnum(infits_1, TRUE, "WEIGHTS", &wgtscol, &status); + FITS_get_colnum(infits_1, TRUE, "BKGD", &bkgdcol, &status); + } + + FITS_read_col(infits_1, TFLOAT, fluxcol, 1L, 1L, npix_1, + &intnull, flux1, &anynull, &status); + FITS_read_col(infits_1, TFLOAT, wavecol, 1L, 1L, npix_1, + &intnull, wave1, &anynull, &status); + FITS_read_col(infits_1, TFLOAT, errorcol, 1L, 1L, npix_1, + &intnull, flxerr1, &anynull, &status); + FITS_read_col(infits_1, TSHORT, qualcol, 1L, 1L, npix_1, + &intnull, qual1, &anynull, &status); + + if (tfields_1 == 6) + { + FITS_read_col(infits_1, TFLOAT, cntscol, 1L, 1L, npix_1, + &intnull, cnts1, &anynull, &status); + FITS_read_col(infits_1, TFLOAT, cntserrcol, 1L, 1L, npix_1, + &intnull, cntserr1, &anynull, &status); + } + else if (tfields_1 == 7) + { + FITS_read_col(infits_1, TLONG, cntscol, 1L, 1L, npix_1, + &intnull, lcts1, &anynull, &status); + FITS_read_col(infits_1, TFLOAT, wgtscol, 1L, 1L, npix_1, + &intnull, wgts1, &anynull, &status); + FITS_read_col(infits_1, TFLOAT, bkgdcol, 1L, 1L, npix_1, + &intnull, bkgd1, &anynull, &status); + } + else + { + for (j=0; j<npix_1; j++) + { + cnts1[j] = 0.; + cntserr1[j] = 0.001; + } + } + + if (!arg2_scalar) + { + /* for file2, stop at first extension if that is all there is */ + if (i <= next_2) + { + hdunum_2 = i + 1; + FITS_movabs_hdu(infits_2, hdunum_2, &hdutype_2, &status); + FITS_read_key(infits_2, TLONG,"NAXIS2",&naxis2_2,NULL,&status); + if (naxis2_2 > 1L) + npix_2 = naxis2_2; + else + { + FITS_read_key(infits_2, TSTRING, "TFORM1", tformstr, NULL, + &status); + sscanf (tformstr, "%ldE", &npix_2); + } + + FITS_read_key(infits_2, TINT, "TFIELDS", &tfields_2, NULL, + &status); + + if (tfields_2 != tfields_1) + { + sprintf (errstr, "File1 has %d cols; File 2 has %d cols!\n", + tfields_1, tfields_2); + cf_if_error (errstr); + } + + if (npix_2 != npix_1) + { + fprintf (stderr, "npix1 = %ld, npix2 = %ld\n", npix_1, npix_2); + cf_if_error ("Aborting"); + } + + /* Allocate data arrays */ + flux2 = (float *) cf_malloc(sizeof(float) * npix_2); + flxerr2 = (float *) cf_malloc(sizeof(float) * npix_2); + qual2 = (short *) cf_malloc(sizeof(short) * npix_2); + if (cf_version == 2) + { + cnts2 = (float *) cf_malloc(sizeof(float) * npix_2); + cntserr2 = (float *) cf_malloc(sizeof(float) * npix_2); + } + else + { + lcts2 = (long *) cf_malloc(sizeof(long) * npix_2); + wgts2 = (float *) cf_malloc(sizeof(float) * npix_2); + bkgd2 = (float *) cf_malloc(sizeof(float) * npix_2); + } + + /* Read the data from file 2 */ + + if (areaflag) + FITS_get_colnum(infits_2, TRUE, "AREA", &fluxcol, &status); + else + FITS_get_colnum(infits_2, TRUE, "FLUX", &fluxcol, &status); + + FITS_get_colnum(infits_2, TRUE, "ERROR", &errorcol, &status); + + /* don't know at present if calfuse 3.x will use "QUALITY" or + * "POTHOLE", so check both. + * (there may also be a mix of files present!) + */ + if (cf_version == 2) + FITS_get_colnum(infits_2, TRUE, "QUALITY", &qualcol,&status); + else + { + qualcol = 0; + for (j=1; j<=tfields_2; j++) + { + sprintf (key_str, "TTYPE%1ld", j); + FITS_read_key(infits_2, TSTRING, key_str,datatype, NULL, + &status); + if (!strcmp (datatype, "QUALITY") || + !strcmp(datatype,"POTHOLE")) + { + strcpy (qual_lbl, datatype); + qualcol = j; + } + } + if (qualcol == 0) + cf_if_error ("QUALITY column not found!"); + } + + if (tfields_2 == 6) + { + FITS_get_colnum(infits_2, TRUE, "COUNTS", &cntscol, &status); + FITS_get_colnum(infits_2, TRUE, "CNTSERR", &cntserrcol, + &status); + } + + if (tfields_2 == 7) + { + FITS_get_colnum(infits_2,TRUE, "COUNTS", &cntscol, &status); + FITS_get_colnum(infits_2,TRUE, "WEIGHTS", &wgtscol, &status); + FITS_get_colnum(infits_2,TRUE, "BKGD", &bkgdcol, &status); + } + + FITS_read_col(infits_2, TFLOAT, fluxcol, 1L, 1L, npix_2, + &intnull, flux2, &anynull, &status); + FITS_read_col(infits_2, TFLOAT, errorcol, 1L, 1L, npix_2, + &intnull, flxerr2, &anynull, &status); + FITS_read_col(infits_2, TSHORT, qualcol, 1L, 1L, npix_2, + &intnull, qual2, &anynull, &status); + + if (tfields_2 == 6) + { + FITS_read_col(infits_2, TFLOAT, cntscol, 1L, 1L, npix_2, + &intnull, cnts2, &anynull, &status); + FITS_read_col(infits_2, TFLOAT, cntserrcol, 1L, 1L, npix_2, + &intnull, cntserr2, &anynull, &status); + } + else if (tfields_1 == 7) + { + FITS_read_col(infits_2, TLONG, cntscol, 1L, 1L, npix_2, + &intnull, lcts2, &anynull, &status); + FITS_read_col(infits_2, TFLOAT, wgtscol, 1L, 1L, npix_2, + &intnull, wgts2, &anynull, &status); + FITS_read_col(infits_2, TFLOAT, bkgdcol, 1L, 1L, npix_2, + &intnull, bkgd2, &anynull, &status); + } + else + { + for (j=0; j<npix_2; j++) + { + cnts2[j] = 0.; + cntserr2[j] = 0.001; + } + } + + } /* end of if (i<=next_2) */ + } /* end of if(!arg2_scalar) */ + + if ((opcode == BIN) && (nbin > 1)) + { + if (nbin > npix_1) + { + sprintf (errstr, "bin factor = %d; must be < npix!\n", nbin); + cf_if_error (errstr); + } + npix_o = npix_1 / nbin; + } + else + npix_o = npix_1; + + /* make space for output arrays */ + flux_o = (float *) cf_malloc(sizeof(float) * npix_o); + flxerr_o = (float *) cf_malloc(sizeof(float) * npix_o); + qual_o = (short *) cf_malloc(sizeof(short) * npix_o); + + if (cf_version == 2) + { + cnts_o = (float *) cf_malloc(sizeof(float) * npix_o); + cntserr_o = (float *) cf_malloc(sizeof(float) * npix_o); + } + else + { + lcts_o = (long *) cf_malloc(sizeof(long) * npix_o); + wgts_o = (float *) cf_malloc(sizeof(float) * npix_o); + bkgd_o = (float *) cf_malloc(sizeof(float) * npix_o); + } + + if (opcode == BIN) + wave_o = (float *) cf_malloc(sizeof(float) * npix_o); + else + wave_o = wave1; + + /********* perform arithmetic operations here *********/ + switch (opcode) + { + case PLUS: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] + arg2_val; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] + arg2_val; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + bkgd_o[j] = bkgd1[j]; + wgts_o[j] = wgts1[j]; + } + } + } /* end if(arg2_scalar) */ + else + { + exptime_o = exptime_1 + exptime_2; + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] + flux2[j]; + tmp1 = flxerr1[j]*flxerr1[j]; + tmp2 = flxerr2[j]*flxerr2[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + cnts_o[j] = cnts1[j] + cnts2[j]; + tmp1 = cntserr1[j]*cntserr1[j]; + tmp2 = cntserr2[j]*cntserr2[j]; + cntserr_o[j] = sqrt (tmp1 + tmp2); + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] + flux2[j]; + tmp1 = flxerr1[j]*flxerr1[j]; + tmp2 = flxerr2[j]*flxerr2[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + lcts_o[j] = lcts1[j] + lcts2[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = (qual1[j] + qual2[j])/2; + bkgd_o[j] = bkgd1[j] + bkgd2[j]; + wgts_o[j] = wgts1[j] + wgts2[j]; + } + } + } + break; + + case MINUS: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] - arg2_val; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] - arg2_val; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + bkgd_o[j] = bkgd1[j]; + wgts_o[j] = wgts1[j]; + } + } + } + else + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] - flux2[j]; + tmp1 = flxerr1[j]*flxerr1[j]; + tmp2 = flxerr2[j]*flxerr2[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + cnts_o[j] = cnts1[j] - cnts2[j]; + tmp1 = cntserr1[j]*cntserr1[j]; + tmp2 = cntserr2[j]*cntserr2[j]; + cntserr_o[j] = sqrt (tmp1 + tmp2); + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] - flux2[j]; + tmp1 = flxerr1[j]*flxerr1[j]; + tmp2 = flxerr2[j]*flxerr2[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + lcts_o[j] = lcts1[j] - lcts2[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = (qual1[j] + qual2[j])/2; + bkgd_o[j] = bkgd1[j] - bkgd2[j]; + wgts_o[j] = wgts1[j] - wgts2[j]; + } + } + } + break; + + case MULT: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] * arg2_val; + flxerr_o[j] = flxerr1[j] * arg2_val; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] * arg2_val; + flxerr_o[j] = flxerr1[j] * arg2_val; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + bkgd_o[j] = bkgd1[j]; + wgts_o[j] = wgts1[j]; + } + } /* end cf_version == 3 */ + } /* end if arg2_scalar */ + else + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] * flux2[j]; + if (flux1[j] == 0.) + { + flxerr_o[j] = fabs (flux2[j] * flxerr1[j]); + } + else if (flux2[j] == 0.) + { + flxerr_o[j] = fabs (flux1[j] * flxerr2[j]); + } + else + { + tmp1 = flxerr1[j] / flux1[j]; + tmp2 = flxerr2[j] / flux2[j]; + tmp3 = tmp1 * tmp1 + tmp2 * tmp2; + flxerr_o[j] = fabs (flux_o[j]) * sqrt (tmp3); + } + cnts_o[j] = cnts1[j] * cnts2[j]; + tmp1 = cnts2[j] * cnts2[j] * cntserr1[j]*cntserr1[j]; + tmp2 = cnts1[j] * cnts1[j] * cntserr2[j]*cntserr2[j]; + cntserr_o[j] = sqrt (tmp1 + tmp2); + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } /* end loop over j */ + } /* end cf_version == 2 */ + else + { /* start cf_version == 3 */ + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] * flux2[j]; + if (flux1[j] == 0.) + { + flxerr_o[j] = fabs (flux2[j] * flxerr1[j]); + } + else if (flux2[j] == 0.) + { + flxerr_o[j] = fabs (flux1[j] * flxerr2[j]); + } + else + { + tmp1 = flxerr1[j] / flux1[j]; + tmp2 = flxerr2[j] / flux2[j]; + tmp3 = tmp1 * tmp1 + tmp2 * tmp2; + flxerr_o[j] = fabs (flux_o[j]) * sqrt (tmp3); + } + lcts_o[j] = lcts1[j] * lcts2[j]; + wgts_o[j] = wgts1[j] * wgts2[j]; + bkgd_o[j] = bkgd1[j] * bkgd2[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = (qual1[j] + qual2[j])/2; + } /* end loop over j */ + } /* end cf_version == 3 */ + } /* end !arg2_scalar */ + break; + + case DIV: + if (arg2_scalar) + { + if (arg2_val == 0.) + cf_if_error ("Commanded division by 0!"); + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] / arg2_val; + flxerr_o[j] = flxerr1[j] / arg2_val; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] / arg2_val; + flxerr_o[j] = flxerr1[j] / arg2_val; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + bkgd_o[j] = bkgd1[j]; + wgts_o[j] = wgts1[j]; + } + } + } + else + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + if (flux2[j] !=0.) + { + flux_o[j] = flux1[j] / flux2[j]; + if (flux1[j] != 0.) + { + tmp1 = flxerr1[j] / flux1[j]; + tmp2 = flxerr2[j] / flux2[j]; + tmp3 = tmp1 * tmp1; + tmp4 = tmp2 * tmp2; + flxerr_o[j] = fabs (flux_o[j]) * sqrt (tmp3 + tmp4); + } + else + flxerr_o[j] = flxerr1[j] / flux2[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + else + { + flux_o[j] = 0.; + flxerr_o[j] = flxerr1[j]; + qual_o[j] = 0; + } + if (cnts2[j] != 0.) + { + cnts_o[j] = cnts1[j] / cnts2[j]; + if (cnts1[j] != 0.) + tmp1 = cntserr1[j] / cnts1[j]; + else + tmp1 = 0.; + tmp2 = cntserr2[j] / cnts2[j]; + tmp3 = tmp1 * tmp1; + tmp4 = tmp2 * tmp2; + cntserr_o[j] = fabs (cnts_o[j]) * sqrt (tmp3 + tmp4); + } + else + { + cnts_o[j] = 0.; + cntserr_o[j] = cntserr1[j]; + } + } /* end loop over j */ + } /* end cf_version == 2 */ + else + { + for (j=0; j<npix_1; j++) + { + if (flux2[j] !=0.) + { + flux_o[j] = flux1[j] / flux2[j]; + if (flux1[j] != 0.) + { + tmp1 = flxerr1[j] / flux1[j]; + tmp2 = flxerr2[j] / flux2[j]; + tmp3 = tmp1 * tmp1; + tmp4 = tmp2 * tmp2; + flxerr_o[j] = fabs (flux_o[j]) * sqrt (tmp3 + tmp4); + } + else + flxerr_o[j] = flxerr1[j] / flux2[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = (qual1[j] + qual2[j])/2; + } + else + { + flux_o[j] = 0.; + flxerr_o[j] = flxerr1[j]; + qual_o[j] = 0; + } + + if (lcts2[j] != 0.) + lcts_o[j] = lcts1[j] / lcts2[j]; + else + lcts_o[j] = 0.; + + if (wgts2[j] != 0.) + wgts_o[j] = wgts1[j] / wgts2[j]; + else + wgts_o[j] = 0.; + + if (bkgd2[j] != 0.) + bkgd_o[j] = bkgd1[j] / bkgd2[j]; + else + bkgd_o[j] = 0.; + + } /* end loop over j */ + } /* end cf_version == 3 */ + } /* end !arg2_scalar */ + break; + + case AVG_T: + if (arg2_scalar) + { + cf_if_error ("Illegal operation with scalar operand!"); + } + else + { + if (cf_version == 2) + { + f1 = exptime_1 / (exptime_1 + exptime_2); + f2 = exptime_2 / (exptime_1 + exptime_2); + exptime_o = exptime_1 + exptime_2; + for (j=0; j<npix_1; j++) + { + flux_o[j] = f1 * flux1[j] + f2 * flux2[j]; + tmp1 = f1 * f1 * flxerr1[j]*flxerr1[j]; + tmp2 = f2 * f2 * flxerr2[j]*flxerr2[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + cnts_o[j] = f1 * cnts1[j] + f2 * cnts2[j]; + tmp1 = f1 * f1 * cntserr1[j]*cntserr1[j]; + tmp2 = f2 * f2 * cntserr2[j]*cntserr2[j]; + cntserr_o[j] = sqrt (tmp1 + tmp2); + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + else + { + f1 = exptime_1 / (exptime_1 + exptime_2); + f2 = exptime_2 / (exptime_1 + exptime_2); + exptime_o = exptime_1 + exptime_2; + for (j=0; j<npix_1; j++) + { + flux_o[j] = f1 * flux1[j] + f2 * flux2[j]; + tmp1 = f1 * f1 * flxerr1[j]*flxerr1[j]; + tmp2 = f2 * f2 * flxerr2[j]*flxerr2[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + lcts_o[j] = lcts1[j] + lcts2[j]; + wgts_o[j] = wgts1[j] + wgts2[j]; + bkgd_o[j] = bkgd1[j] + bkgd2[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = (qual1[j] + qual2[j])/2; + } + } + } + break; + + case AVG_S: + if (arg2_scalar) + { + cf_if_error ("Illegal operation with scalar operand!"); + } + else + { + exptime_o = exptime_1 + exptime_2; + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + if ((flxerr1[j] > 0.) && (flxerr2[j] > 0.)) + { + f1 = 1. / (flxerr1[j] * flxerr1[j]); + f2 = 1. / (flxerr2[j] * flxerr2[j]); + } + else + f1 = f2 = 1.; + fn = f1 + f2; + flux_o[j] = (f1 * flux1[j] + f2 * flux2[j]) / fn; + flxerr_o[j] = sqrt (1./fn); + if ((cntserr1[j] > 0.) && (cntserr2[j] > 0.)) + { + f1 = 1. / (cntserr1[j] * cntserr1[j]); + f2 = 1. / (cntserr2[j] * cntserr2[j]); + } + else + f1 = f2 = 1.; + fn = f1 + f2; + cnts_o[j] = (f1 * cnts1[j] + f2 * cnts2[j]) / fn; + cntserr_o[j] = sqrt (1./fn); + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } /* end if cf_version == 2 */ + else + { + for (j=0; j<npix_1; j++) + { + if ((flxerr1[j] > 0.) && (flxerr2[j] > 0.)) + { + f1 = 1. / (flxerr1[j] * flxerr1[j]); + f2 = 1. / (flxerr2[j] * flxerr2[j]); + } + else + f1 = f2 = 1.; + fn = f1 + f2; + flux_o[j] = (f1 * flux1[j] + f2 * flux2[j]) / fn; + flxerr_o[j] = sqrt (1./fn); + lcts_o[j] = (f1 * lcts1[j] + f2 * lcts2[j]) / fn; + wgts_o[j] = (f1 * wgts1[j] + f2 * wgts2[j]) / fn; + bkgd_o[j] = (f1 * bkgd1[j] + f2 * bkgd2[j]) / fn; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = (f1*qual1[j] + f2*qual2[j]) / fn; + } + } + } + break; + + case REPL_D: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = arg2_val; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = arg2_val; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + } + } + else + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux2[j]; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux2[j]; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + } + break; + + case REPL_E: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = arg2_val; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = arg2_val; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + } + } + else + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr2[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr2[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + } + } + break; + + case DELTA: + /* start by copying input file to output */ + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + } + if (arg2_scalar) + { + for (j=100; j<npix_1; j+=100) + { + flux_o[j] += arg2_val; + if (flux1[j] != 0) + { + flxerr_o[j] *= fabs (flux_o[j] / flux1[j]); + } + else + { + flxerr_o[j] += 0.1 * fabs (flux_o[j]); + } + } + } + else + { + for (j=100; j<npix_1; j+=100) + { + flux_o[j] += flux2[j]; + if (flux1[j] != 0) + { + flxerr_o[j] *= fabs (flux_o[j] / flux1[j]); + } + else + { + flxerr_o[j] += 0.1 * fabs (flux_o[j]); + } + } + } + break; + + case BOXCAR: + if (arg2_scalar) + { + /* if width is <= 1, just copy input to output */ + if (arg2_val <= 1.) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j];; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } /* end if_cf_version == 2 */ + else + { /* cf_version == 3 */ + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j];; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + qual_o[j] = qual1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + } /* end if cf_version == 3 */ + } /* end if arg2_val <=1 */ + else + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + k1 = j - arg2_val / 2. + 0.5; + k2 = j + arg2_val / 2. + 0.5; + if (k1 < 0) + k1 = 0; + if (k2 > npix_1-1) + k2 = npix_1-1; + sflux = 0.; + sferr = 0.; + scnts = 0.; + scerr = 0.; + lqual = 0; + for (k=k1; k<=k2; k++) + { + sflux += flux1[k]; + sferr += flxerr1[k] * flxerr1[k]; + scnts += cnts1[k]; + scerr += cntserr1[k] * cntserr1[k]; + lqual += (long) qual1[k]; + } + spix = (float)(k2 - k1 + 1); + flux_o[j] = sflux / spix; + flxerr_o[j] = sqrt (sferr) / spix; + cnts_o[j] = scnts / spix; + cntserr_o[j] = sqrt (scerr) / spix; + qual_o[j] = (short) (lqual / spix); + } /* end of for j... */ + } /* end if cf_version == 2 */ + else + { /* start cf_version == 3 for scalar smoothing > 1 */ + for (j=0; j<npix_1; j++) + { + k1 = j - arg2_val / 2. + 0.5; + k2 = j + arg2_val / 2. + 0.5; + if (k1 < 0) + k1 = 0; + if (k2 > npix_1-1) + k2 = npix_1-1; + sflux = 0.; + sferr = 0.; + slcts = 0; + sbkgd = 0.; + swgts = 0.; + lqual = 0; + for (k=k1; k<=k2; k++) + { + sflux += flux1[k]; + sferr += flxerr1[k] * flxerr1[k]; + slcts += lcts1[k]; + swgts += wgts1[k]; + sbkgd += bkgd1[k]; + lqual += (long) qual1[k]; + } + spix = (float)(k2 - k1 + 1); + flux_o[j] = sflux / spix; + flxerr_o[j] = sqrt (sferr) / spix; + lcts_o[j] = slcts / spix; + bkgd_o[j] = sbkgd / spix; + wgts_o[j] = swgts / spix; + qual_o[j] = (short) (lqual / spix); + } /* end of for j... */ + } /* end cf_version == 3 */ + } /* end of arg2_scalar > 1 */ + } /* end of if (arg2_scalar) */ + else + { + /* allow the smoothing width to vary pixel-by-pixel */ + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + arg2_val = flux2[j]; + if (arg2_val < 1.) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + else + { + k1 = j - arg2_val / 2. + 0.5; + k2 = j + arg2_val / 2. + 0.5; + if (k1 < 0) + k1 = 0; + if (k2 > npix_1-1) + k2 = npix_1-1; + sflux = 0.; + sferr = 0.; + scnts = 0.; + scerr = 0.; + lqual = 0; + for (k=k1; k<=k2; k++) + { + sflux += flux1[k]; + sferr += flxerr1[k] * flxerr1[k]; + scnts += cnts1[k]; + scerr += cntserr1[k] * cntserr1[k]; + lqual += (long) qual1[k]; + } + spix = (float)(k2 - k1 + 1); + flux_o[j] = sflux / spix; + flxerr_o[j] = sqrt (sferr) / spix; + cnts_o[j] = scnts / spix; + cntserr_o[j] = sqrt (scerr) / spix; + qual_o[j] = (short) (lqual / spix); + } /* end of arg2_val > 1 */ + } /* end of for j... */ + } /* end if cf_version == 2 */ + else + { /* cf_version == 3 */ + for (j=0; j<npix_1; j++) + { + arg2_val = flux2[j]; + if (arg2_val < 1.) + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + qual_o[j] = qual1[j]; + } + else + { + k1 = j - arg2_val / 2. + 0.5; + k2 = j + arg2_val / 2. + 0.5; + if (k1 < 0) + k1 = 0; + if (k2 > npix_1-1) + k2 = npix_1-1; + sflux = 0.; + sferr = 0.; + slcts = 0; + sbkgd = 0.; + swgts = 0.; + lqual = 0; + for (k=k1; k<=k2; k++) + { + sflux += flux1[k]; + sferr += flxerr1[k] * flxerr1[k]; + slcts += lcts1[k]; + swgts += wgts1[k]; + sbkgd += bkgd1[k]; + lqual += (long) qual1[k]; + } + spix = (float)(k2 - k1 + 1); + flux_o[j] = sflux / spix; + flxerr_o[j] = sqrt (sferr) / spix; + lcts_o[j] = slcts / spix; + wgts_o[j] = swgts / spix; + bkgd_o[j] = sbkgd / spix; + qual_o[j] = (short) (lqual / spix); + } /* end of arg2_val > 1 */ + } /* end of for j... */ + } /* end if cf_version == 3 */ + } /* end of if (!arg2_scalar) */ + break; /* end of case BOXCAR */ + + case MIN: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + if (flux1[j] < arg2_val) + flux_o[j] = arg2_val; + else + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + if (flux1[j] < arg2_val) + flux_o[j] = arg2_val; + else + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + qual_o[j] = qual1[j]; + } + } + } + else + { + for (j=0; j<npix_1; j++) + { + if (flux1[j] < flux2[j]) + { + flux_o[j] = flux2[j]; + flxerr_o[j] = flxerr2[j]; + } + else + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + } + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + } + } + break; + + case MAX: + if (arg2_scalar) + { + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + if (flux1[j] > arg2_val) + flux_o[j] = arg2_val; + else + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + if (flux1[j] > arg2_val) + flux_o[j] = arg2_val; + else + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + qual_o[j] = qual1[j]; + } + } + } + else + { + for (j=0; j<npix_1; j++) + { + if (flux1[j] > flux2[j]) + { + flux_o[j] = flux2[j]; + flxerr_o[j] = flxerr2[j]; + } + else + { + flux_o[j] = flux1[j]; + flxerr_o[j] = flxerr1[j]; + } + if ((qual1[j] == 0) || (qual2[j] == 0)) + qual_o[j] = 0; + else + qual_o[j] = qual1[j]; + } + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + } + } + break; + + case SHIFT: + if (cf_version == 2) + { + if (p_shift > 0) + { + for (j=0; j<p_shift; j++) + { + flux_o[j] = 0.; + flxerr_o[j] = DEF_ERROR; + cnts_o[j] = 0.; + cntserr_o[j] = DEF_ERROR; + qual_o[j] = 0; + } + for (j=p_shift; j<npix_1; j++) + { + k = j - p_shift; + flux_o[j] = flux1[k]; + flxerr_o[j] = flxerr1[k]; + cnts_o[j] = cnts1[k]; + cntserr_o[j] = cntserr1[k]; + qual_o[j] = qual1[k]; + } + } + if (p_shift <= 0) + { + for (j=npix_1+p_shift; j<npix_1; j++) + { + flux_o[j] = 0.; + flxerr_o[j] = DEF_ERROR; + cnts_o[j] = 0.; + cntserr_o[j] = DEF_ERROR; + qual_o[j] = 0; + } + for (j=0; j<npix_1+p_shift; j++) + { + k = j - p_shift; + flux_o[j] = flux1[k]; + flxerr_o[j] = flxerr1[k]; + cnts_o[j] = cnts1[k]; + cntserr_o[j] = cntserr1[k]; + qual_o[j] = qual1[k]; + } + } + } /* end if cf_version == 2 */ + else + { + if (p_shift > 0) + { + for (j=0; j<p_shift; j++) + { + flux_o[j] = 0.; + flxerr_o[j] = DEF_ERROR; + lcts_o[j] = 0; + qual_o[j] = 0; + wgts_o[j] = 0.; + bkgd_o[j] = 0.; + } + for (j=p_shift; j<npix_1; j++) + { + k = j - p_shift; + flux_o[j] = flux1[k]; + flxerr_o[j] = flxerr1[k]; + lcts_o[j] = lcts1[k]; + wgts_o[j] = wgts1[k]; + bkgd_o[j] = bkgd1[k]; + qual_o[j] = qual1[k]; + } + } + if (p_shift <= 0) + { + for (j=npix_1+p_shift; j<npix_1; j++) + { + flux_o[j] = 0.; + flxerr_o[j] = DEF_ERROR; + lcts_o[j] = 0; + wgts_o[j] = 0.; + bkgd_o[j] = 0.; + qual_o[j] = 0; + } + for (j=0; j<npix_1+p_shift; j++) + { + k = j - p_shift; + flux_o[j] = flux1[k]; + flxerr_o[j] = flxerr1[k]; + lcts_o[j] = lcts1[k]; + wgts_o[j] = wgts1[k]; + bkgd_o[j] = bkgd1[k]; + qual_o[j] = qual1[k]; + } + } + } + break; + + case BIN: + /* if nbin = 1, just copy input to output */ + if (nbin == 1) + { + if (cf_version == 2) + { + for (j=0; j<npix_o; j++) + { + wave_o[j] = wave1[j]; + flux_o[j] = flux1[j];; + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_o; j++) + { + wave_o[j] = wave1[j]; + flux_o[j] = flux1[j];; + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + qual_o[j] = qual1[j]; + } + } /* end cf_version == 3 */ + } /* end nbin == 1 */ + else + { + if (cf_version == 2) + { + for (j=0; j<npix_o; j++) + { + k1 = j * nbin; + k2 = k1 + nbin; + if (k2 > npix_1) + k2 = npix_1; + swave = 0.; + sflux = 0.; + sferr = 0.; + scnts = 0.; + scerr = 0.; + squal = 0; + spix = 0; + for (k=k1; k<k2; k++) + { + swave += wave1[k]; + if (qual1[k] > 0) + { + sflux += flux1[k]; + sferr += flxerr1[k] * flxerr1[k]; + scnts += cnts1[k]; + scerr += cntserr1[k] * cntserr1[k]; + squal += qual1[k]; + spix++; + } + } + if (spix == 0) + spix = 1; + wave_o[j] = swave / (float)(k2 - k1); + flux_o[j] = sflux / spix; + flxerr_o[j] = sqrt (sferr) / spix; + cnts_o[j] = scnts; + cntserr_o[j] = sqrt (scerr); + qual_o[j] = squal; + } /* end of for j... */ + } /* end cf_version == 2 */ + else + { + for (j=0; j<npix_o; j++) + { + k1 = j * nbin; + k2 = k1 + nbin; + if (k2 > npix_1) + k2 = npix_1; + swave = 0.; + sflux = 0.; + sferr = 0.; + slcts = 0; + swgts = 0.; + sbkgd = 0.; + squal = 0; + spix = 0; + for (k=k1; k<k2; k++) + { + swave += wave1[k]; + if (qual1[k] > 0) + { + sflux += flux1[k]; + sferr += flxerr1[k] * flxerr1[k]; + slcts += lcts1[k]; + swgts += wgts1[k]; + sbkgd += bkgd1[k]; + squal += qual1[k]; + spix++; + } + } + if (spix == 0) + spix = 1; + wave_o[j] = swave / (float)(k2 - k1); + flux_o[j] = sflux / spix; + flxerr_o[j] = sqrt (sferr) / spix; + lcts_o[j] = slcts; + qual_o[j] = squal / spix; + wgts_o[j] = swgts / spix; + bkgd_o[j] = sbkgd; + } /* end of for j... */ + } /* end cf_version == 3 */ + } /* end of nbin > 1 */ + break; + + case DERIV: + if (cf_version == 2) + { + for (j=0; j<npix_1-1; j++) + { + flux_o[j] = flux1[j+1] - flux1[j]; + tmp1 = flxerr1[j+1]*flxerr1[j+1]; + tmp2 = flxerr1[j]*flxerr1[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + tmp1 = cntserr1[j+1]*cntserr1[j+1]; + tmp2 = cntserr1[j]*cntserr1[j]; + cnts_o[j] = cnts1[j+1] - cnts1[j]; + cntserr_o[j] = sqrt (tmp1 + tmp2); + qual_o[j] = qual1[j]; + } + flux_o[npix_1-1] = flux_o[npix_1-2]; + flxerr_o[npix_1-1] = flxerr_o[npix_1-2]; + cnts_o[npix_1-1] = cnts_o[npix_1-2]; + cntserr_o[npix_1-1] = cntserr_o[npix_1-2]; + } /* end cf_version == 2 */ + else + { + for (j=0; j<npix_1-1; j++) + { + flux_o[j] = flux1[j+1] - flux1[j]; + tmp1 = flxerr1[j+1]*flxerr1[j+1]; + tmp2 = flxerr1[j]*flxerr1[j]; + flxerr_o[j] = sqrt (tmp1 + tmp2); + lcts_o[j] = lcts1[j+1] - lcts1[j]; + qual_o[j] = qual1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + } + flux_o[npix_1-1] = flux_o[npix_1-2]; + flxerr_o[npix_1-1] = flxerr_o[npix_1-2]; + lcts_o[npix_1-1] = lcts_o[npix_1-2]; + } /* end cf_version == 3 */ + break; + + case ADDNOISE: + if (cf_version == 2) + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] + arg2_val * rand1(); + flxerr_o[j] = flxerr1[j]; + cnts_o[j] = cnts1[j]; + cntserr_o[j] = cntserr1[j]; + qual_o[j] = qual1[j]; + } + } + else + { + for (j=0; j<npix_1; j++) + { + flux_o[j] = flux1[j] + arg2_val * rand1(); + flxerr_o[j] = flxerr1[j]; + lcts_o[j] = lcts1[j]; + wgts_o[j] = wgts1[j]; + bkgd_o[j] = bkgd1[j]; + qual_o[j] = qual1[j]; + } + } + break; + + default: + cf_if_error ("Illegal opcode; should never get here!"); + break; + + } /* end switch (opcode) */ + + /* write the extension containing the results as a binary table */ + hdunum_o=i+1; + + /* cf_write_spec creates the new extension and sets the pointer + * to it. + */ + if (tfields_1 < 7) + cf_wrspec_cf2 (outfits, npix_o, wave_o, flux_o, flxerr_o, qual_o, + cnts_o, cntserr_o, tfields_1, areaflag); + else + cf_wrspec7 (outfits, npix_o, wave_o, flux_o, flxerr_o, + lcts_o, wgts_o, bkgd_o, qual_o); + + + if (wave_o != wave1) + free(wave_o); + free(wave1); + free(flux1); + free(flxerr1); + free(qual1); + free(flux_o); + free(flxerr_o); + free(qual_o); + if (cf_version == 2) + { + free(cnts1); + free(cntserr1); + free(cnts_o); + free(cntserr_o); + } + else + { + free(lcts1); + free(bkgd1); + free(wgts1); + free(lcts_o); + free(bkgd_o); + free(wgts_o); + } + + /* is there only 1 extension in operand 2, so that we need to keep + * the data we've read in, or do we need to make space to read the + * next extension? + */ + if (!arg2_scalar && (i < next_2)) + { + free(flux2); + free(flxerr2); + free(qual2); + if (cf_version == 2) + { + free(cnts2); + free(cntserr2); + } + else + { + free(lcts2); + free(wgts2); + free(bkgd2); + } + } + + } /* end of loop over next_1 */ + + /* add HISTORY lines to output file */ + hdunum_o = 1; + FITS_movabs_hdu (outfits, hdunum_o, &hdutype_o, &status); + + sprintf (comment, "cf_arith: operation = %s", argv[2]); + FITS_write_history (outfits, comment, &status); + sprintf (comment, "cf_arith: operand1 = %s", infile1); + FITS_write_history (outfits, comment, &status); + sprintf (comment, "cf_arith: operand2 = %s", infile2); + FITS_write_history (outfits, comment, &status); + + /* update exposure time in output header if necessary */ + if (exptime_o != exptime_1) + { + FITS_update_key (outfits, TFLOAT, "EXPTIME", &exptime_o, expt_comment, + &status); + sprintf (comment, "cf_arith: EXPTIME = EXPTIME1 + EXPTIME2"); + FITS_write_history (outfits, comment, &status); + } + + /* update FILENAME keyword in output file */ + FITS_update_key (outfits, TSTRING, "FILENAME", outfile, NULL, &status); + + time (&timeval); + timestr = ctime (&timeval); + sprintf (comment, "cf_arith: completed at %.24s", timestr); + /* over-write the trailing \n in timestr */ +/* following not needed when field width is specified as 24 above + comment[strlen(comment)-1] = '\0'; + padstr (comment, FLEN_CARD); +*/ + FITS_write_history (outfits, comment, &status); + + /* Close the files. */ + + FITS_close_file(infits_1, &status); + if (!arg2_scalar) + FITS_close_file(infits_2, &status); + FITS_close_file(outfits, &status); + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done processing"); +#ifdef SOLARIS + ieee_retrospective(stdout); +#endif + return 0; +} + +int chkop (opstr) +char *opstr; +{ + if (!strcmp (opstr, "+")) + return (PLUS); + else if (!strcmp (opstr, "-")) + return (MINUS); + else if (!strcmp (opstr, "*")) + return (MULT); + else if (!strcmp (opstr, "/")) + return (DIV); + else if (!strcmp (opstr, "avg_t")) + return (AVG_T); + else if (!strcmp (opstr, "avg_s")) + return (AVG_S); + else if (!strcmp (opstr, "repl_d")) + return (REPL_D); + else if (!strcmp (opstr, "repl_e")) + return (REPL_E); + else if (!strcmp (opstr, "boxcar")) + return (BOXCAR); + else if (!strcmp (opstr, "delta")) + return (DELTA); + else if (!strcmp (opstr, "min")) + return (MIN); + else if (!strcmp (opstr, "max")) + return (MAX); + else if (!strcmp (opstr, "shift")) + return (SHIFT); + else if (!strcmp (opstr, "bin")) + return (BIN); + else if (!strcmp (opstr, "deriv")) + return (DERIV); + else if (!strcmp (opstr, "addnoise")) + return (ADDNOISE); + else + return (0); +} + +/* check_num (in_str) returns TRUE if in_str is a string representation of + * a valid number, FALSE otherwise. + * This is a simple-minded check: just see if first char is +,-,digit. + */ +int check_num (in_str) +char *in_str; +{ + if ((in_str[0] == '+') || (in_str[0] == '-')) + { + if (isdigit (in_str[1])) + return (TRUE); + else + return (FALSE); + } + if (isdigit (in_str[0])) + return (TRUE); + + return (FALSE); +} + +void padstr (pstr, len) +char *pstr; +int len; +{ + int i, slen; + + slen = strlen (pstr); + for (i=slen; i<len; i++) + *(pstr + i) = ' '; + + return; +} +/* return a random number in range -1 -> 1 */ +double rand1 () +{ + long random(); + double r; + + r = 2. * (double) random() / (double)MAX_RAND - 1.; + return (r); +} + diff --git a/src/analysis/cf_coadd.c b/src/analysis/cf_coadd.c new file mode 100644 index 0000000..eaa5fe2 --- /dev/null +++ b/src/analysis/cf_coadd.c @@ -0,0 +1,192 @@ +/****************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ****************************************************************************** + * + * Synopsis: cf_coadd root_name + * + * This program calls the routines that produce the exposure-level + * all files and the observation-level all, ano, and nvo files. + * + * 03/29/04 v0.1 bjg Begin work. + * 04/05/04 v0.2 bjg Remove unused variables + * Include unistd.h + * 06/07/04 v0.3 bjg Updated some keywords + * 08/12/04 v0.4 bjg Keywords QIK_COR and COMB_COR + * now set to COMPLETE. + * 08/26/04 v0.5 bjg Handle case aperture=RFPT + * 03/17/05 v0.6 tc Rename EXPTIME to OBSTIME in all extensions + * 08/22/05 v1.0 wvd Completely re-write for CalFUSE v3.1.7. + * Calls cf_make_all_exp for each exposure and + * cf_make_all_obs.csh only once. + * 08/27/07 v1.1 bot Changed i from int to long to match n + * Added L to corresponding values + * + *****************************************************************************/ + + + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "calfuse.h" + +static char CF_PRGM_ID[] = "cf_coadd"; +static char CF_VER_NUM[] = "1.1"; + + +/*********************************************************************/ + +int main(int argc, char *argv[]) +{ + + char asnf_file[120], filename[120], instmode[100], aper_string[100], aper_num[100]; + fitsfile *asnf_fits_ptr, *infits; + long n; + int status = 0; + long i; + int anynull; + FILE * ffile; + + + char command0[256]; + + + char memname[120], *memname_ptr; + char memtype[120], *memtype_ptr; + char ** memname_ptr2; + char ** memtype_ptr2; + + char NULL_STR[] = {'\0'}; + + char file_present; + char expo_num_string[10]; + int expo_num; + + char know=0; + + /* 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, stderr); + + + memname_ptr=memname; + memtype_ptr=memtype; + + memname_ptr2=&memname_ptr; + memtype_ptr2=&memtype_ptr; + + + /* Input Parameters */ + if (argc != 2) + cf_if_error("Usage: cf_coadd rootname"); + + /*Open association file*/ + + strcpy(asnf_file, argv[1]); + strcat(asnf_file, "asnf.fit"); + FITS_open_file(&asnf_fits_ptr, asnf_file, READONLY, &status); + FITS_movabs_hdu(asnf_fits_ptr, 2, NULL, &status); + + + FITS_read_key(asnf_fits_ptr, TLONG, "NAXIS2", &n, NULL, &status); + + + for (i=0L;i<n;i++){ + + cf_if_fits_error(fits_read_col_str(asnf_fits_ptr, 1, i+1L, 1,1, NULL_STR, + memname_ptr2, &anynull, &status)); + + cf_if_fits_error(fits_read_col_str(asnf_fits_ptr, 2, i+1L, 1,1, NULL_STR, + memtype_ptr2, &anynull, &status)); + + cf_if_fits_error(fits_read_col_log(asnf_fits_ptr, 3, i+1L, 1, 1, 0, + &file_present, &anynull, &status)); + + if (file_present == FALSE) continue; + if (strncasecmp(memtype,"EXPOSURE",8)) continue; + + strncpy(expo_num_string,&memname[8],3); + expo_num=atoi(expo_num_string); + + if (expo_num==701) continue; + + strcpy(filename,memname); + strcat(filename,"1ahistfraw.fit"); + strcpy(instmode,"hist"); + ffile=fopen(filename,"r"); + if (ffile == NULL) { + strcpy(instmode,"ttag"); + strcpy(filename,memname); + strcat(filename,"1attagfraw.fit"); + ffile=fopen(filename,"r"); + if (ffile == NULL) { + printf("Warning: Expo %s not present\n",expo_num_string); + continue; + } + fclose(ffile); + } + else { + fclose(ffile); + } + + + if (!know) { + + FITS_open_file(&infits, filename, READONLY, &status); + FITS_read_key(infits, TSTRING, "APERTURE", aper_string, NULL, &status); + + if (!strncasecmp(aper_string,"LWRS",4)) strcpy(aper_num,"4"); + if (!strncasecmp(aper_string,"MDRS",4)) strcpy(aper_num,"2"); + if (!strncasecmp(aper_string,"HIRS",4)) strcpy(aper_num,"3"); + if (!strncasecmp(aper_string,"PINH",4)) strcpy(aper_num,"1"); + if (!strncasecmp(aper_string,"RFPT",4)) strcpy(aper_num,"4"); + + FITS_close_file(infits, &status); + know=1; + } + + + strcpy(command0,"cf_make_all_exp "); + strcat(command0,memname); + strcat(command0,"00all"); + strcat(command0,aper_num); + strcat(command0,instmode); + strcat(command0,"fcal.fit "); + strcat(command0,memname); + strcat(command0,"1alif"); + strcat(command0,aper_num); + strcat(command0,instmode); + strcat(command0,"fcal.fit "); + strcat(command0,memname); + strcat(command0,"1blif"); + strcat(command0,aper_num); + strcat(command0,instmode); + strcat(command0,"fcal.fit "); + strcat(command0,memname); + strcat(command0,"2alif"); + strcat(command0,aper_num); + strcat(command0,instmode); + strcat(command0,"fcal.fit "); + strcat(command0,memname); + strcat(command0,"2blif"); + strcat(command0,aper_num); + strcat(command0,instmode); + strcat(command0,"fcal.fit "); + + system(command0); + + } + + FITS_close_file(asnf_fits_ptr,&status); + + sprintf(command0,"cf_make_all_obs.csh %s", asnf_file); + system(command0); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done Processing"); + + return(EXIT_SUCCESS); + +} diff --git a/src/analysis/cf_combine.c b/src/analysis/cf_combine.c new file mode 100644 index 0000000..0b91009 --- /dev/null +++ b/src/analysis/cf_combine.c @@ -0,0 +1,544 @@ +/******************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: cf_combine [-ahk] [-v level] file_list output_idf_file + * + * Description: This is a utility program that combines a series of + * FUSE spectra in the form of FITS binary tables as produced + * by the CalFUSE pipeline. The files are combined by taking + * the exposure-weighted mean of the fluxes and flux errors + * and summing the counts. + * It is assumed that the error arrays contain standard + * deviations, not variances. + * + * + * History: 01/04/00 jwk started work + * 05/01/00 v1.2 jwk handle SHORT qual arrays + * 09/11/00 v1.3 jwk remove include <sunmath.h> + * 10/11/00 v1.4 jwk update FILENAME keyword in output file + * 10/27/00 v1.5 peb #ifdef ieee_retrospective + * 04/18/01 v1.6 wvd Change declaration of timeval from + * long to time_t + * 10/29/02 v1.7 wvd Correct error in history line. + * 05/19/03 v1.8 wvd Two updates from jwk: + * Close each input file in initial loop; + * without this cfitsio crashes upon + * opening the 60th file. + * Weight each pixel by exposure time + * after excluding 'bad' pixels. + * 12/15/03 v1.9 bjg Changed to work on CalFUSE 3 spectrum + * data format + * 01/12/04 v1.10 bjg npix_1 is now correct + * copy header of 1st file instead of 2nd + * Updated the name of some FITS cols that + * were still using 2.4 format + * 03/09/04 v1.11 wvd Change POTHOLE to QUALITY throughout. + * 04/05/04 - bjg Declarations for cf_wrspec7 and + * cf_wrspec_cf2 + * Remove unused variables + * 06/07/04 v1.12 bjg Update some keywords (plantime, + * rawtime, exp_saa, nbadevnt ...) + * 04/07/05 v1.13 tc Read 1D|2D spectrum format. Clean unused + * variables. Allows one to shift a 2D + * spectrum (2nd column in the filelist). + * Use calloc rather than malloc. The + * quality value is now the nearest short. + * Update ROOTNAME keyword. Change EXP to + * OBS if "-k" (optional). Proper use of + * fclose() and rewind() + * 04/16/05 v1.14 tc Use cf_read_col() + * 05/02/05 v1.15 wvd Write NSPEC, SPEC###, WOFF### to + * output file header (primary HDU). + * 06/03/05 v1.16 wvd Delete unused variables. + * 07/06/05 v1.17 wvd Use fgets to read input file. + * Change pix_shift to type int. + * 07/21/05 v1.18 wvd Adopt the sign convention for spectral + * shifts used by FUSE_REGISTER. + * 08/26/05 v1.19 wvd Without arguments, don't return an + * error. Just print help and exit. + * 08/29/05 v1.20 wvd If input list contains only file + * names, assume shifts are zero. + * 01/31/06 v1.21 wvd Revise creation date of output file. + * 05/19/06 v1.22 wvd Use same options as idf_combine. + * Ignore spectra with EXP_STAT != 0. + * Override with -a option. + * 05/22/06 v1.23 wvd Rewrite program using a single while + * loop. + * 05/23/06 v1.24 wvd Properly normalize quality array. + * 05/26/06 v1.25 wvd Include unistd.h + * 07/12/06 v1.26 wvd Clean up i/o. + * 08/14/06 v1.27 wvd Count SPEC### and WAVE### using ngood, + * not nfiles. + * 05/04/07 v1.28 wvd If the input file list contains a + * blank line, skip to the next line. + * 08/27/07 v1.29 bot Changed TINT to TLONG l.412 + * Added L to long l.125 to 136, 351, 378 + * 04/04/08 v1.30 wvd If -a flag is set, include files with + * positive values of EXP_STAT, but not + * those with negative values. + * 07/25/08 v1.31 wvd Set output EXP_STAT keyword to lowest + * non-negative value among input files. + * + ****************************************************************************/ + +#include <time.h> +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "calfuse.h" + +void cf_wrspec7(fitsfile *outfits, long npts, float *wave, float *flux, + float *error, long *counts, float *weights, + float *bkgd,short *quality); +void cf_wrspec_cf2(fitsfile *outfits, int npts, float *wave, + float *spec, float *errs, short *qual, + float *counts, float *cntserr, int ncol, + int areaflag); + +static char CF_PRGM_ID[] = "cf_combine"; +static char CF_VER_NUM[] = "1.31"; + +int main(int argc, char *argv[]) +{ + char *timestr; + time_t timeval; + char flist[80], infile[80], line[FLEN_CARD], outfile[80], string0[100]; + char comment[FLEN_CARD]; + char errstr[80]; + int nargs, nfiles, ngood; + int status=0; + int hdutype_1, hdutype_o; + int hdunum_1, hdunum_o; + long npix_1; + int tfields_1, delta = 0; + long j; + short *quality1; + float *wave1, *flux1, *error1, *weights1, *bkgd1; + + double *flux_o, *error_o, *quality_o; + float *weights_o, *bkgd_o; + long *counts_o, *counts1; + float *exptime_p; + float f1, shift, wpc; + + float exptime_1, exptime_o = 0.; + float rawtime_1, rawtime_o = 0.; + long plantime_1, plantime_o = 0L; + long nbadevnt_1, nbadevnt_o = 0L; + long nbadpha_1 , nbadpha_o = 0L; + long exp_bad_1 , exp_bad_o = 0L; + long exp_brst_1, exp_brst_o = 0L; + long exp_hv_1, exp_hv_o = 0L; + long exp_jitr_1, exp_jitr_o = 0L; + long exp_lim_1 , exp_lim_o = 0L; + long exp_saa_1 , exp_saa_o = 0L; + long expnight_1, expnight_o = 0L; + + long nevents_1, nevents_o = 0L; + long exp_stat, exp_stat_out=999; + + double mjd_start, mjd_end; + double mjd_start_o = 99999., mjd_end_o = 0.; + fitsfile *infits_1, *outfits; + FILE *ifp; + char keyword[FLEN_KEYWORD], root_name[32]; + int k_flag = 0; + + float *temp_float; + short *temp_short; + long *temp_long; + + /* Function prototypes*/ + void getnshift_float(float*, float*, long, int); + void getnshift_short(short*, short*, long, int); + void getnshift_long(long*, long*, long, int); + + int optc; + int ignore_exp_stat=TRUE; + + char opts[] = "ahkv:"; + char usage[] = + "Usage:\n" + " cf_combine [-ahk] [-v level] file_list output_idf_file\n"; + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n" + " -a: ignore EXP_STAT keyword\n" + " -k: Change EXP keywords to OBS\n"; + + verbose_level = 1; + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + + case 'h': + printf("%s\n%s", usage, option); + return 0; + case 'a': + ignore_exp_stat=FALSE; + break; + case 'v': + verbose_level = atoi(optarg); + break; + case 'k': + k_flag=1; + break; + } + } + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing"); + + /* Initialize error checking */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + if (argc < optind+2) { + printf("%s", usage); + return 1; + } + + strcpy (flist, argv[optind]); + strcpy (outfile, argv[optind+1]); + + if ((ifp = fopen (flist, "r")) == NULL) + { + sprintf (errstr, "Unable to open file %s\n", flist); + cf_if_error (errstr); + } + + if (ignore_exp_stat) + cf_verbose(1,"Will include only files with EXP_STAT=0") ; + else + cf_verbose(1,"Will include only files with EXP_STAT >= 0") ; + + nfiles = ngood = 0; + + /* BIG LOOP THROUGH INPUT FILES */ + while (fgets(line, FLEN_CARD, ifp) != NULL) { + nargs = sscanf(line, "%s %d", infile, &delta); + if (nargs == EOF) continue; + if (nargs == 1) delta = 0; + nfiles++; + cf_verbose (3, "Input file loop: nfiles = %d, file = %s", nfiles, infile); + + /* Open input file */ + FITS_open_file(&infits_1, infile, READONLY, &status); + FITS_read_key(infits_1, TLONG, "EXP_STAT", &exp_stat, NULL, &status); + FITS_read_key(infits_1, TDOUBLE, "EXPSTART", &mjd_start, NULL, &status); + FITS_read_key(infits_1, TDOUBLE, "EXPEND" , &mjd_end , NULL, &status); + FITS_read_key(infits_1, TFLOAT, "EXPTIME" , &exptime_1 , NULL, &status); + FITS_read_key(infits_1, TLONG, "NEVENTS", &nevents_1, NULL, &status); + FITS_read_key(infits_1, TFLOAT, "RAWTIME" , &rawtime_1 , NULL, &status); + FITS_read_key(infits_1, TLONG, "PLANTIME", &plantime_1, NULL, &status); + nevents_o += nevents_1; + rawtime_o += rawtime_1; + plantime_o += plantime_1; + + if (mjd_start < mjd_start_o) mjd_start_o = mjd_start; + if (mjd_end > mjd_end_o) mjd_end_o = mjd_end; + + /* Create output file, copy the header from the input file */ + if (nfiles==1) + { + /* open output file */ + remove(outfile); /* In case the old file name exists */ + FITS_create_file (&outfits, outfile, &status); + FITS_copy_header(infits_1, outfits, &status); + FITS_write_date(outfits, &status); + + FITS_read_key(infits_1, TFLOAT, "WPC" , &wpc , NULL, &status); + + /* Now go to the second HDU and figure out how long the arrays are. */ + hdunum_1 = 2; + FITS_movabs_hdu(infits_1, hdunum_1, &hdutype_1, &status); + FITS_read_key(infits_1, TINT, "TFIELDS", &tfields_1, NULL, &status); + + if (tfields_1 != 7) + { + sprintf (errstr, "Expecting 7 cols, found %d\n", tfields_1); + cf_if_error (errstr); + } + + npix_1 = cf_read_col(infits_1, TFLOAT, "WAVE", (void **) &wave1); + + /* Allocate data arrays (calloc initializes to 0 by default). */ + exptime_p = (float *) cf_calloc(npix_1, sizeof(float)); + + flux1 = (float *) cf_calloc(npix_1, sizeof(float)); + error1 = (float *) cf_calloc(npix_1, sizeof(float)); + counts1 = (long *) cf_calloc(npix_1, sizeof(long)); + weights1 = (float *) cf_calloc(npix_1, sizeof(float)); + bkgd1 = (float *) cf_calloc(npix_1, sizeof(float)); + quality1 = (short *) cf_calloc(npix_1, sizeof(short)); + + flux_o = (double *) cf_calloc(npix_1, sizeof(double)); + error_o = (double *) cf_calloc(npix_1, sizeof(double)); + counts_o = (long *) cf_calloc(npix_1, sizeof(long)); + weights_o = (float *) cf_calloc(npix_1, sizeof(float)); + bkgd_o = (float *) cf_calloc(npix_1, sizeof(float)); + quality_o = (double *) cf_calloc(npix_1, sizeof(double)); + + hdunum_1 = 1; + FITS_movabs_hdu(infits_1, hdunum_1, &hdutype_1, &status); + + } /* end of if(nfiles==1) */ + + /* Set EXP_STAT to lowest non-negative value in input files. */ + if (exp_stat_out > exp_stat && exp_stat >= 0) exp_stat_out = exp_stat; + + /* Skip files with EXP_TIME = 0 or EXP_STAT != 0. */ + if (ignore_exp_stat && exp_stat != 0) { + cf_if_warning("File %s rejected. EXP_STAT not equal to zero. Use -a flag to override.", + infile) ; + FITS_close_file(infits_1,&status); + continue; + } + + /* Never include files with negative values of EXP_STAT. */ + else if (exp_stat < 0) { + cf_if_warning("File %s rejected. EXP_STAT less than zero.", infile) ; + FITS_close_file(infits_1,&status); + continue; + } + + if (exptime_1 < 1.) { + cf_verbose (3, "Rejecting file %s: EXPTIME = %f", infile, exptime_1); + FITS_close_file(infits_1,&status); + continue; + } + ngood++; + + FITS_read_key(infits_1, TLONG, "NBADEVNT", &nbadevnt_1, NULL, &status); + FITS_read_key(infits_1, TLONG, "NBADPHA" , &nbadpha_1 , NULL, &status); + FITS_read_key(infits_1, TLONG, "EXP_BAD" , &exp_bad_1 , NULL, &status); + FITS_read_key(infits_1, TLONG, "EXP_BRST", &exp_brst_1, NULL, &status); + FITS_read_key(infits_1, TLONG, "EXP_HV", &exp_hv_1, NULL, &status); + FITS_read_key(infits_1, TLONG, "EXP_JITR", &exp_jitr_1, NULL, &status); + FITS_read_key(infits_1, TLONG, "EXP_LIM" , &exp_lim_1 , NULL, &status); + FITS_read_key(infits_1, TLONG, "EXP_SAA" , &exp_saa_1 , NULL, &status); + FITS_read_key(infits_1, TLONG, "EXPNIGHT", &expnight_1, NULL, &status); + + exptime_o += exptime_1; + nbadevnt_o += nbadevnt_1; + nbadpha_o += nbadpha_1; + exp_bad_o += exp_bad_1; + exp_saa_o += exp_saa_1; + exp_lim_o += exp_lim_1; + exp_brst_o += exp_brst_1; + exp_hv_o += exp_hv_1; + exp_jitr_o += exp_jitr_1; + expnight_o += expnight_1; + + /* Read the data from input file (HDU 2) */ + hdunum_1 = 2; + FITS_movabs_hdu(infits_1, hdunum_1, &hdutype_1, &status); + + (void) cf_read_col(infits_1, TFLOAT, "FLUX", (void **) &temp_float); + getnshift_float(flux1, temp_float, npix_1, delta); + free(temp_float); + + (void) cf_read_col(infits_1, TFLOAT, "ERROR", (void **) &temp_float); + getnshift_float(error1, temp_float, npix_1, delta); + free(temp_float); + + (void) cf_read_col(infits_1, TSHORT, "QUALITY", (void **) &temp_short); + getnshift_short(quality1, temp_short, npix_1, delta); + free(temp_short); + + (void) cf_read_col(infits_1, TLONG, "COUNTS", (void **) &temp_long); + getnshift_long(counts1, temp_long, npix_1, delta); + free(temp_long); + + (void) cf_read_col(infits_1, TFLOAT, "WEIGHTS", (void **) &temp_float); + getnshift_float(weights1, temp_float, npix_1, delta); + free(temp_float); + + (void) cf_read_col(infits_1, TFLOAT, "BKGD", (void **) &temp_float); + getnshift_float(bkgd1, temp_float, npix_1, delta); + free(temp_float); + + /* Average fluxes, weighting by exposure time; add counts. */ + /* Include only pixels with non-zero quality flags. */ + for (j=0L; j<npix_1; j++) { + if (quality1[j] > 0) { + f1 = exptime_1; + exptime_p[j] += f1; + flux_o[j] += f1 * flux1[j]; + error_o[j] += f1 * f1 * (double) error1[j]*error1[j]; + counts_o[j] += counts1[j]; + weights_o[j] += weights1[j]; + bkgd_o[j] += bkgd1[j]; + quality_o[j] += f1 * (double) quality1[j]; + } + } + + FITS_close_file(infits_1, &status); + + /* Write input file name and spectral shift to output file header. */ + sprintf(keyword, "SPEC%03d", ngood); + FITS_update_key(outfits, TSTRING, keyword, infile, NULL, &status); + sprintf(keyword, "WOFF%03d", ngood); + shift = delta * wpc; + FITS_update_key(outfits, TFLOAT, keyword, &shift, "[A]", &status); + + + } /* end of loop over input files */ + + /* Convert variances back to sigma. Normalize flux, error, and quality by EXPTIME. + Convert from doubles to floats. */ + for (j=0L; j<npix_1; j++) if (exptime_p[j] > 0.) { + flux1[j] = flux_o[j] / exptime_p[j]; + error1[j] = sqrt(error_o[j]) / exptime_p[j]; + quality1[j] = cf_nint(quality_o[j] / exptime_p[j]); + } + else { + flux1[j] = error1[j] = 0.; + quality1[j] = 0; + } + + /* Write the output file (in multi-row format). */ + cf_wrspec7 (outfits, npix_1, wave1, flux1, error1, counts_o, weights_o, bkgd_o, quality1); + + free(exptime_p); + free(wave1); + free(flux1); + free(error1); + free(bkgd1); + free(counts1); + free(weights1); + free(quality1); + free(flux_o); + free(error_o); + free(quality_o); + free(bkgd_o); + free(counts_o); + free(weights_o); + + hdunum_o = 1; + FITS_movabs_hdu (outfits, hdunum_o, &hdutype_o, &status); + + /* update output header keywords*/ + + FITS_update_key(outfits, TLONG, "EXP_STAT", &exp_stat_out, NULL, &status); + FITS_update_key(outfits, TDOUBLE, "EXPSTART", &mjd_start_o, NULL, &status); + FITS_update_key(outfits, TDOUBLE, "EXPEND", &mjd_end_o , NULL, &status); + FITS_update_key(outfits, TFLOAT, "EXPTIME", &exptime_o , NULL, &status); + FITS_update_key(outfits, TLONG, "NEVENTS", &nevents_o, NULL, &status); + FITS_update_key(outfits, TFLOAT, "RAWTIME", &rawtime_o , NULL, &status); + FITS_update_key(outfits, TLONG, "PLANTIME", &plantime_o, NULL, &status); + FITS_update_key(outfits, TLONG, "NBADEVNT", &nbadevnt_o, NULL, &status); + FITS_update_key(outfits, TLONG, "NBADPHA" , &nbadpha_o , NULL, &status); + FITS_update_key(outfits, TLONG, "EXP_BAD" , &exp_bad_o , NULL, &status); + FITS_update_key(outfits, TLONG, "EXP_BRST", &exp_brst_o, NULL, &status); + FITS_update_key(outfits, TLONG, "EXP_HV", &exp_hv_o, NULL, &status); + FITS_update_key(outfits, TLONG, "EXP_JITR", &exp_jitr_o, NULL, &status); + FITS_update_key(outfits, TLONG, "EXP_LIM" , &exp_lim_o , NULL, &status); + FITS_update_key(outfits, TLONG, "EXP_SAA" , &exp_saa_o , NULL, &status); + FITS_update_key(outfits, TLONG, "EXPNIGHT", &expnight_o, NULL, &status); + + /* update FILENAME keyword in output file */ + FITS_update_key(outfits, TSTRING, "FILENAME", outfile, NULL, &status); + + strcpy(string0, "COMBINED SPECTRA"); + FITS_update_key(outfits, TSTRING, "FILETYPE", string0, NULL, &status); + + sprintf(string0, "000"); + FITS_update_key(outfits, TSTRING, "EXP_ID", string0, NULL, &status); + + FITS_read_key(outfits, TSTRING, "ROOTNAME", root_name, NULL, &status); + sprintf(string0, "%.8s000", root_name); + FITS_update_key(outfits, TSTRING, "ROOTNAME", string0, NULL, &status); + + FITS_update_key(outfits, TINT, "NSPEC", &ngood, + "Number of combined spectral files", &status); + + if (k_flag) + { + cf_if_fits_error(fits_modify_name(outfits, "EXP_STAT", "OBS_STAT", &status)); + cf_if_fits_error(fits_modify_name(outfits, "EXPSTART", "OBSSTART", &status)); + cf_if_fits_error(fits_modify_name(outfits, "EXPEND", "OBSEND", &status)); + cf_if_fits_error(fits_modify_name(outfits, "EXPTIME", "OBSTIME", &status)); + cf_if_fits_error(fits_modify_name(outfits, "EXPNIGHT", "OBSNIGHT", &status)); + } + else { + /* Add HISTORY lines to output file */ + if (ignore_exp_stat) { + sprintf (comment, "cf_combine: Including only files with EXP_STAT=0"); + FITS_write_history (outfits, comment, &status); + } + + else { + sprintf (comment, "cf_combine: Including only files with EXP_STAT >= 0"); + FITS_write_history (outfits, comment, &status); + } + + sprintf (comment, "cf_combine: File list = %s", flist); + FITS_write_history (outfits, comment, &status); + + time (&timeval); + timestr = ctime (&timeval); + sprintf (comment, "cf_combine: Completed on %.24s", timestr); + FITS_write_history (outfits, comment, &status); + } + + /* Close the files. */ + fclose(ifp); + FITS_close_file(outfits, &status); + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done processing"); +#ifdef SOLARIS + ieee_retrospective(stdout); +#endif + return 0; +} + + +void getnshift_float (float *out_vect, float *in_vect, long n, int delta) +{ + long k, ind; + + for (k = 0; k < n; k++) + { + ind = k - delta; + if((ind >= 0) && (ind < n)) + out_vect[k] = in_vect[ind]; + else + out_vect[k] = 0; + } +} + +void getnshift_short (short *out_vect, short *in_vect, long n, int delta) +{ + long k, ind; + + for (k = 0; k < n; k++) + { + ind = k - delta; + if((ind >= 0) && (ind < n)) + out_vect[k] = in_vect[ind]; + else + out_vect[k] = 0; + } +} + +void getnshift_long (long *out_vect, long *in_vect, long n, int delta) +{ + long k, ind; + + for (k = 0; k < n; k++) + { + ind = k - delta; + if((ind >= 0) && (ind < n)) + out_vect[k] = in_vect[ind]; + else + out_vect[k] = 0; + } +} diff --git a/src/analysis/cf_make_900_obs.csh b/src/analysis/cf_make_900_obs.csh new file mode 100755 index 0000000..9edbc70 --- /dev/null +++ b/src/analysis/cf_make_900_obs.csh @@ -0,0 +1,193 @@ +#!/usr/local/bin/tcsh -f + +#****************************************************************************** +#* Johns Hopkins University +#* Center For Astrophysical Sciences +#* FUSE +#****************************************************************************** +#* +#* Synopsis: cf_make_900_obs.csh association_file +#* +#* Description: This routine is derived from cf_make_all_obs.csh, but modified +#* to consider only 900+ (airglow) files. Output is a single +#* quick-look image of the airglow spactrum. +#* +#* Extracted spectra are combined, not IDF files. +#* +#* When an expected data set is missing, the script stops, cleans +#* the directory, and returns 1. +#* +#* History: 08/08/08 1.00 wvd Create separate quick-look image +#* for 900+ (airglow) exposures. +#* Always combine extracted spectra. If +#* cf_xcorr fails, combine with no shift. +#* 08/08/08 1.01 wvd Rename airglow quick-look file to +#* M112580100000airgttagf.gif +#* +#*****************************************************************************/ + +# Delete files after processing? (Default is no.) +#set DELETE_IDF # Delete intermediate data files +set DELETE_BPM # Delete bad-pixel map files + +# Set program path +set rm = "/bin/rm -f" + +set cf_xcorr = cf_xcorr +set cf_combine = cf_combine +set cf_pack = cf_pack +set cf_nvo = cf_nvo +set idl_obsplot = idl_obsplot.pl +set modhead = modhead + +# Init var list +set detector = (1a 2b) +set channel = (lif sic) +set resolution = (2 3 4) +set obsmod = (hist ttag) + +# Determine the root name and the program ID +set asnf = $1 +set rn = ${asnf:s/000asnf.fit//} +set pid = `echo $rn | awk '{print substr($1, 1, 4)}'` + +# Determine the object class +set tmp_file = `ls ${rn}*fcal.fit | awk '{if (NR == 1) print}'` +set tmp_buf = `$modhead $tmp_file OBJCLASS` +set objclass = $tmp_buf[2] + +# Clean tmp files that the script will create (safe) +$rm tmp_xcorr.res tmp_combine.lis +$rm tmp_good_exp.lis tmp_exp.lis tmp_seg_dn.lis +$rm DN_${rn}*.fit + +foreach om ($obsmod) + foreach res ($resolution) + foreach chan ($channel) + foreach det ($detector) + + set ignore_exp_stat = '' + if ($om == hist) set ignore_exp_stat = -a + if ($pid == S100) set ignore_exp_stat = -a + if ($pid == M106) set ignore_exp_stat = -a + + # Find exposures that match the current segment + set seg = $det$chan$res$om + set readfiles = 0 + ls ${rn}9[0-9][0-9]${seg}fcal.fit |& grep -v 000${seg} > tmp_exp.lis # Keep only "9xx" exposures + if ($? == 0) then + set readfiles = 2 + set ignore_exp_stat = -a + endif + + if ($readfiles >= 1) then # There are one or more exposures + + echo " " + echo "*** Processing: $seg ***" + # [1a][lif] -> [1b][lif], [2b][lif] -> [2a][lif] etc... + if ($det == 1a) set det2 = 1b + if ($det == 2b) set det2 = 2a + set seg2 = $det2$chan$res$om + + echo "----- cf_xcorr input -----" + cat tmp_exp.lis + echo "----------------------------" + $cf_xcorr tmp_exp.lis tmp_xcorr.res # Compute shift and sigma_shift + echo "----- cf_xcorr results -----" + cat tmp_xcorr.res + echo "----------------------------" + + awk '{if ($3 >= 0) {print $6, $2} else {print $6}}' tmp_xcorr.res > tmp_good_exp.lis + + # + # --- Path 1: Optimize resolution --- + # + + echo "Optimize resolution..." + set n_good = `cat tmp_good_exp.lis | wc -l` + + # Extract [Day + Night] spectra + set s = DN_${rn}900${seg}fcal.fit + awk '{print "'$rn'"$1"'$seg'fcal.fit",$2}' tmp_good_exp.lis > tmp_combine.lis # Combine $seg [dn] + # echo "----- Combining Files ----- " + # cat tmp_combine.lis + # echo "Output: " $s + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + # $modhead "${s}[1]" NUM_EXP $n_good + $modhead "${s}[1]" COMBMETH XCORR + echo $s >> tmp_seg_dn.lis + + set s = DN_${rn}900${seg2}fcal.fit + awk '{print "'$rn'"$1"'$seg2'fcal.fit",$2}' tmp_good_exp.lis > tmp_combine.lis # Combine $seg2 [dn] + # echo "----- Combining Files ----- " + # cat tmp_combine.lis + # echo "Output: " $s + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + # $modhead "${s}[1]" NUM_EXP $n_good + $modhead "${s}[1]" COMBMETH XCORR + echo $s >> tmp_seg_dn.lis + + endif + end + + $rm tmp_xcorr.res tmp_combine.lis + $rm tmp_good_exp.lis tmp_exp.lis + + end + + # Pack the 8 [detector][channel] pairs together + if (-e tmp_seg_dn.lis) then + + set fcal_all = ${rn}00900all$res${om}fcal.fit # Final output name + $rm $fcal_all # Clean (safe) + set n_segs = `cat tmp_seg_dn.lis | wc -l` + + if (!($n_segs == 8)) then + + @ mseg = 8 - $n_segs + echo "ERROR: $mseg (day + night) segments are missing" + $rm tmp_seg_dn.lis + goto crash + + else + + $cf_pack tmp_seg_dn.lis $fcal_all + $rm tmp_seg_dn.lis + + # Plot figures, delete unwanted files + $idl_obsplot {$rn} airglow + mv ${rn}00900spec${om}f.gif ${rn}00000airg${om}f.gif + $rm ${rn}00900lif*.gif ${rn}00900sic*.gif + $rm $fcal_all + + endif + endif + end +end + +# Clean [dn] files. +$rm DN_${rn}*.fit + +# Delete IDF files +if $?DELETE_IDF then + echo "NOTE: Deleting intermediate data files." + $rm ${rn}*idf.fit +endif + +# Delete bad-pixel-map (bpm) files +if $?DELETE_BPM then + echo "NOTE: Deleting bad pixel map (bpm) files." + $rm ${rn}*bpm.fit +endif + +exit(0) + +crash: # Procedure when script crashes + +# Clean directory +$rm tmp_xcorr.res tmp_combine.lis +$rm tmp_good_exp.lis tmp_exp.lis tmp_seg_dn.lis +$rm DN_*.fit + +# Return 1 +exit(1) diff --git a/src/analysis/cf_make_all_exp.c b/src/analysis/cf_make_all_exp.c new file mode 100644 index 0000000..926ac2c --- /dev/null +++ b/src/analysis/cf_make_all_exp.c @@ -0,0 +1,91 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: cf_make_all_exp output_filename input1 input2 input3 input4 + * + * Description: For a single exposure, copies header of channel with largest + * value of EXPTIME into an otherwise empty "all" file. + * Input files should represent each of the four FUSE channels. + * + * + * History: 08/11/05 wvd v1.0 Based on cf_quicklook. + * + ****************************************************************************/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "calfuse.h" + +static char CF_PRGM_ID[]= "cf_make_all_exp"; +static char CF_VER_NUM[]= "1.0"; + +int main(int argc,char *argv[]){ + + char *corrected_filename, *string_pointer; + char comment[FLEN_CARD], datestr[FLEN_CARD]; + int i, nextend=0, ref_file=2, timeref; + int status=0; + float exptime, max_exptime; + + fitsfile *infits,*outfits; + + if (argc != 6) { + printf("Incorrect number of arguments.\n"); + printf("Calling sequence: cf_make_all_exp output_filename " + "input1 input2 input3 input4\n"); + exit(1); + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + /* Determine the channel with the longest exposure time */ + + max_exptime = 0; + for (i = 0; i < 4; i++) { + FITS_open_file(&infits, argv[2+i], READONLY, &status); + FITS_read_key(infits, TFLOAT, "EXPTIME", &exptime, NULL, &status); + if (exptime >= max_exptime) { + ref_file = 2 + i; + max_exptime = exptime; + } + FITS_close_file(infits, &status); + } + + /* Copy header from the reference file to the exposure-level "all" file. */ + + FITS_open_file(&infits, argv[ref_file], READONLY, &status); + FITS_create_file(&outfits, argv[1], &status); + FITS_copy_hdu(infits, outfits, 0, &status); + + /* Modify a few header keywords. */ + string_pointer = strrchr(argv[1],'/'); + if (string_pointer == NULL) corrected_filename = argv[1]; + else corrected_filename = &(string_pointer[1]); + FITS_update_key(outfits, TINT, "NEXTEND", &nextend, NULL, &status); + FITS_write_date(outfits, &status); + FITS_update_key(outfits, TSTRING, "FILENAME", corrected_filename, NULL, &status); + FITS_update_key(outfits, TSTRING, "FILETYPE", "EXPOSURE-LEVEL STATUS FILE", NULL, &status); + + /* Add a note warning that this file contains no data. */ + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, + "This file contains no data.", &status); + FITS_write_comment(outfits, + "Its header keywords are used by the DADS cataloging software.", &status); + fits_get_system_time(datestr, &timeref, &status); + sprintf(comment, "CalFUSE v%s %.10s", CALFUSE_VERSION, datestr); + FITS_write_comment(outfits, comment, &status); + FITS_write_comment(outfits, " ", &status); + + + FITS_close_file(infits, &status); + FITS_close_file(outfits,&status); + + return EXIT_SUCCESS; +} diff --git a/src/analysis/cf_make_all_obs.csh b/src/analysis/cf_make_all_obs.csh new file mode 100755 index 0000000..2a97247 --- /dev/null +++ b/src/analysis/cf_make_all_obs.csh @@ -0,0 +1,555 @@ +#!/usr/local/bin/tcsh -f + +#****************************************************************************** +#* Johns Hopkins University +#* Center For Astrophysical Sciences +#* FUSE +#****************************************************************************** +#* +#* Synopsis: cf_make_all_obs.csh association_file +#* +#* Description: Creates 3 files from Calfuse output (properly run): +#* +#* 1) An "all" file containing 1 extension per detector (= 8). +#* Each extension contains a combined spectrum from the set +#* of exposures, using "Xcorr" or "Background" method. +#* 2) In the case of TTAG data, creates an "ano" file. Same as +#* the "all" file but considering "night only" exposure time. +#* 3) A National Virtual Observatory "nvo" file. One extension +#* containing wavelengths that span the whole FUSE range. +#* +#* The Xcorr method consists of co-adding spectra, the latter +#* being corrected for a possible shift. The Background method +#* consists of combining all the IDF files. +#* +#* The Xcorr test is performed on 4 (detector, channel) pairs, the +#* method of other pairs are given by them: +#* LiF 1a -> Lif 1b +#* LiF 2b -> LiF 2a +#* SiC 1a -> Sic 1b +#* Sic 2b -> Sic 2a +#* In the script, the left segments are referred as to $seg (or +#* $det) and the right segments are referred as to $seg2 (or +#* $det2). +#* +#* When an expected data set is missing, the script stops, cleans +#* the directory, and returns 1. +#* +#* History: 04/15/05 1.0 tc First release +#* 08/22/05 1.1 wvd Argument is name of association file. +#* 10/20/05 1.2 wvd Use idl_obsplot.pl to call cf_obsplot. +#* 10/25/05 1.3 wvd Add option to delete BPM or IDF files. +#* 03/21/06 1.4 wvd If there's only one exposure, always +#* follow the cross-correlation path. +#* Don't check the number of night-only +#* spectra before calling cf_pack. +#* 03/28/06 1.5 wvd If there's no good time in any exposure, +#* follow the cross-correlation path. +#* 04/27/06 1.6 wvd Be smarter when discarding 000 files. +#* Always use cross-corr for HIST data. +#* 05/23/06 1.7 wvd Move -k to proper spot after cf_combine. +#* 06/02/06 1.8 wvd If OBJCLASS = 7 (Sky Background) +#* always combine IDF files. +#* 06/22/06 1.9 wvd Call idf_combine with -z flag. +#* 05/24/07 1.10 bot If only 900+ spectra are available, +#* use them. +#* 04/04/08 1.11 bot Ignore EXP_STAT in cf_combine for HIST +#* data. +#* 07/25/08 1.12 wvd Ignore EXP_STAT in cf_combine and +#* idf_combine for BR-EARTH observations +#* (S100, M106, and 900+ exposures). +#* 08/08/08 1.13 wvd Don't ignore EXP_STAT for 900+ exposures. +#* 08/15/08 1.14 wvd Call cf_make_900_obs.csh +#* to make quick-look airglow plot. +#* +#*****************************************************************************/ + +# Delete files after processing? (Default is no.) +#set DELETE_IDF # Delete intermediate data files +#set DELETE_BPM # Delete bad-pixel map files + +# Set program path +set rm = "/bin/rm -f" + +set cf_xcorr = cf_xcorr +set cf_combine = cf_combine +set cf_pack = cf_pack +set cf_nvo = cf_nvo +set idl_obsplot = idl_obsplot.pl +set modhead = modhead + +#set cf_xcorr = /home/vela/civeit/Work/CalFuse/Xcorr/New/cf_xcorr +#set cf_combine = /home/vela/civeit/Work/CalFuse/Shiftexp/cf_combine +#set cf_pack = /home/vela/civeit/Work/CalFuse/Pack/cf_pack +#set cf_nvo = /home/vela/civeit/Work/CalFuse/Nvo/cf_nvo +#set modhead = /home/vela/civeit/local/bin/modhead + +#set cf_obsplot = /data1/fuse/calfuse/v3.1/idl/cf_obsplot.pro + +# Init var list +set detector = (1a 2b) +set channel = (lif sic) +set resolution = (2 3 4) +set obsmod = (hist ttag) + +# Determine the root name and the program ID +set asnf = $1 +set rn = ${asnf:s/000asnf.fit//} +set pid = `echo $rn | awk '{print substr($1, 1, 4)}'` + +# Determine the object class +set tmp_file = `ls ${rn}*fcal.fit | awk '{if (NR == 1) print}'` +set tmp_buf = `$modhead $tmp_file OBJCLASS` +set objclass = $tmp_buf[2] + +# Clean tmp files that the script will create (safe) +$rm tmp_xcorr.res tmp_bpm1.lis tmp_bpm2.lis tmp_combine.lis tmp_night_exp.lis +$rm tmp_all_night_exp.lis tmp_good_exp.lis tmp_exp.lis tmp_seg_dn.lis tmp_seg_no.lis +$rm DN_${rn}*.fit NO_${rn}*.fit + +foreach om ($obsmod) + foreach res ($resolution) + foreach chan ($channel) + foreach det ($detector) + + set ignore_exp_stat = '' + if ($om == hist) set ignore_exp_stat = -a + if ($pid == S100) set ignore_exp_stat = -a + if ($pid == M106) set ignore_exp_stat = -a + + # Find exposures that match the current segment + set seg = $det$chan$res$om + set readfiles = 0 + ls ${rn}[0-8][0-9][0-9]${seg}fcal.fit |& grep -v 000${seg} > tmp_exp.lis # Reject EXP "9xx" and "000" + + if ($? == 0) then + set readfiles = 1 + else + ls ${rn}9[0-9][0-9]${seg}fcal.fit |& grep -v 000${seg} > tmp_exp.lis # Keep only "9xx" exposures + if ($? == 0) set readfiles = 2 + endif + + if ($readfiles >= 1) then # There are one or more exposures + + echo " " + echo "*** Processing: $seg ***" + # [1a][lif] -> [1b][lif], [2b][lif] -> [2a][lif] etc... + if ($det == 1a) set det2 = 1b + if ($det == 2b) set det2 = 2a + set seg2 = $det2$chan$res$om + + echo "----- cf_xcorr input -----" + cat tmp_exp.lis + echo "----------------------------" + $cf_xcorr tmp_exp.lis tmp_xcorr.res # Compute shift and sigma_shift + echo "----- cf_xcorr results -----" + cat tmp_xcorr.res + echo "----------------------------" + + awk '{if ($5 > 0) print $6, $4, $5}' tmp_xcorr.res > tmp_all_night_exp.lis + awk '{if ($3 >= 0) print $6, $2}' tmp_xcorr.res > tmp_good_exp.lis + awk '{if (($3 >= 0) && ($5 > 0)) print $6, $2, $4, $5}' tmp_xcorr.res > tmp_night_exp.lis + set time_good = `awk 'BEGIN{$t = 0} {if ($3 >= 0) $t = $t + $4} END{print $t}' tmp_xcorr.res` + set time_bad = `awk 'BEGIN{$t = 0} {if ($3 < 0) $t = $t + $4} END{print $t}' tmp_xcorr.res` + echo "Xcorr time: $time_good - Background time: $time_bad" + set n_exp = `cat tmp_xcorr.res | wc -l` + + if (($time_good > 2 * $time_bad && $objclass != 7) || ($time_good == 0 && $time_bad == 0) || $n_exp == 1 || $om == hist) then + + # + # --- Path 1: Optimize resolution --- + # + + echo "Optimize resolution..." + set n_good = `cat tmp_good_exp.lis | wc -l` + + # Extract [Day + Night] spectra + set s = DN_${rn}000${seg}fcal.fit + awk '{print "'$rn'"$1"'$seg'fcal.fit",$2}' tmp_good_exp.lis > tmp_combine.lis # Combine $seg [dn] + # echo "----- Combining Files ----- " + # cat tmp_combine.lis + # echo "Output: " $s + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + # $modhead "${s}[1]" NUM_EXP $n_good + $modhead "${s}[1]" COMBMETH XCORR + echo $s >> tmp_seg_dn.lis + + set s = DN_${rn}000${seg2}fcal.fit + awk '{print "'$rn'"$1"'$seg2'fcal.fit",$2}' tmp_good_exp.lis > tmp_combine.lis # Combine $seg2 [dn] + # echo "----- Combining Files ----- " + # cat tmp_combine.lis + # echo "Output: " $s + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + # $modhead "${s}[1]" NUM_EXP $n_good + $modhead "${s}[1]" COMBMETH XCORR + echo $s >> tmp_seg_dn.lis + + set n_night = `cat tmp_night_exp.lis | wc -l` + if ($om == ttag && $n_night > 0) then # Create and combine night only files + + echo "*** Creating night only files ***" + set exp_nums = `awk '{print $1}' tmp_night_exp.lis` + + foreach exp ($exp_nums) + + # Create night-only BPM and FCAL files if they do not already exist. + set bno1 = NO_$rn$exp$det${om}fbpm.fit # Bad-pixel maps + set bno2 = NO_$rn$exp$det2${om}fbpm.fit + set cno1 = NO_$rn$exp${seg}fcal.fit # Extracted spectra + set cno2 = NO_$rn$exp${seg2}fcal.fit + + set etime = `egrep "^$exp" tmp_night_exp.lis | awk '{print $3}'` + set ntime = `egrep "^$exp" tmp_night_exp.lis | awk '{print $4}'` + set ratio = `egrep "^$exp" tmp_night_exp.lis | awk '{printf "%.0f", 0.5+$4/$3*10.}'` + + if (!(-e $cno1)) then + if ($etime == $ntime) then + echo "$cno1 is a symbolic link to $rn$exp${seg}fcal.fit" + ln -s $rn$exp${seg}fcal.fit $cno1 + else + + set idf_file = $rn$exp$det${om}fidf.fit + if (!(-e $bno1)) then + if ($ratio > 9) then + echo "$bno1 is a symbolic link to $rn$exp$det${om}fbpm.fit" + ln -s $rn$exp$det${om}fbpm.fit $bno1 + else + echo "Creating BPM: $bno1 ..." + cf_bad_pixels -n $bno1 $idf_file + endif + endif + + echo "Creating (LiF + SiC) FCAL: $cno1 ..." + cf_extract_spectra -n $bno1 -r NO_$rn$exp $idf_file # Existence of $bno1 is not required + endif + endif + + if (!(-e $cno2)) then + if ($etime == $ntime) then + echo "Using a symbolic link to $cno2" + ln -s $rn$exp${seg2}fcal.fit NO_$rn$exp${seg2}fcal.fit + else + + set idf_file = $rn$exp$det2${om}fidf.fit + if (!(-e $bno2)) then + if ($ratio > 9) then + echo "Using a symbolic link to $bno2" + ln -s $rn$exp$det2${om}fbpm.fit NO_$rn$exp$det2${om}fbpm.fit + else + echo "Creating BPM: $bno2 ..." + cf_bad_pixels -n $bno2 $idf_file + endif + endif + + echo "Creating (LiF + SiC) FCAL: $cno2 ..." + cf_extract_spectra -n $bno2 -r NO_$rn$exp $idf_file # Existence of $bno2 is not required + endif + endif + + end + + # Combine exposures into a single spectrum. + set s = NO_${rn}000${seg}fcal.fit + awk '{print "NO_'$rn'"$1"'$seg'fcal.fit",$2}' tmp_night_exp.lis > tmp_combine.lis # Combine $seg [no] + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + # $modhead "${s}[1]" NUM_EXP $n_night + $modhead "${s}[0]" DAYNIGHT NIGHT + $modhead "${s}[1]" COMBMETH XCORR + echo $s >> tmp_seg_no.lis + + set s = NO_${rn}000${seg2}fcal.fit + awk '{print "NO_'$rn'"$1"'$seg2'fcal.fit",$2}' tmp_night_exp.lis > tmp_combine.lis # Combine $seg2 [no] + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + # $modhead "${s}[1]" NUM_EXP $n_night + $modhead "${s}[0]" DAYNIGHT NIGHT + $modhead "${s}[1]" COMBMETH XCORR + echo $s >> tmp_seg_no.lis + + endif + + else + + # + # --- Path 2: Optimize background --- + # + + echo "Optimize background..." + + # Combine IDF files + set idf1_all = DN_${rn}000$det${om}fidf.fit # Same for [dn] and [no] + set idf2_all = DN_${rn}000$det2${om}fidf.fit + + if (!(-e $idf1_all)) then + echo "Creating IDF: $idf1_all ..." + if ($readfiles == 1) then + ls ${rn}[0-8][0-9][0-9]$det${om}fidf.fit |& grep -v 000${det} > tmp_idf.lis # Reject EXP "9xx" and "000" + else + ls ${rn}9[0-9][0-9]$det${om}fidf.fit |& grep -v 000${det} > tmp_idf.lis # Consider only airglow + endif + if ($? == 0) then # IDF files exist + + set idf_lis = `awk '{printf "%s ",$1}' tmp_idf.lis` + # echo "Combining IDF files: " $idf_lis + idf_combine -cz $ignore_exp_stat $idf1_all $idf_lis # Create combined IDF file for $seg + $rm tmp_idf.lis + + else + + echo "ERROR: IDF files are missing" + $rm tmp_idf.lis + goto crash + + endif + endif + + if (!(-e $idf2_all)) then + echo "Creating IDF: $idf2_all ..." + if ($readfiles == 1) then + ls ${rn}[0-8][0-9][0-9]$det2${om}fidf.fit |& grep -v 000${det2} > tmp_idf.lis # Reject EXP "9xx" and "000" + else + ls ${rn}9[0-9][0-9]$det2${om}fidf.fit |& grep -v 000${det2} > tmp_idf.lis # Consider only airglow + endif + if ($? == 0) then # IDF files exist + + set idf_lis = `awk '{printf "%s ",$1}' tmp_idf.lis` + # echo "Combining IDF files: " $idf_lis + idf_combine -cz $ignore_exp_stat $idf2_all $idf_lis # Create combined IDF file for $seg2 + $rm tmp_idf.lis + + else + + echo "ERROR: IDF files are missing" + $rm tmp_idf.lis + goto crash + + endif + endif + + # Get the number of (valid) combined IDF files + set tmp_buf = `$modhead $idf1_all NSPEC` + set n_comb1 = $tmp_buf[3] + set tmp_buf = `$modhead $idf1_all SPEC001` + set idf1_1 = $tmp_buf[3] + set tmp_buf = `$modhead $idf2_all NSPEC` + set n_comb2 = $tmp_buf[3] + set tmp_buf = `$modhead $idf2_all SPEC001` + set idf2_1 = $tmp_buf[3] + + # Combine BPM files + set bpm1_all = DN_${rn}000$det${om}fbpm.fit + set bpm2_all = DN_${rn}000$det2${om}fbpm.fit + + if (!(-e $bpm1_all)) then + echo "Combine all BPM (from IDF): $bpm1_all ..." + bpm_combine $bpm1_all $idf1_all # Create combined BPM file [dn] for $seg + endif + + if (!(-e $bpm2_all)) then + echo "Combine all BPM (from IDF): $bpm2_all ..." + bpm_combine $bpm2_all $idf2_all # Idem for $seg2 + endif + + # Extract [Day + Night] spectra + set s = DN_${rn}000${seg}fcal.fit + set xxx = DN_${rn}xxx${seg}fcal.fit + if (!(-e $xxx)) cf_extract_spectra -r DN_${rn}xxx $idf1_all # Avoid overwrite LiF | SiC + echo $xxx > tmp_combine.lis + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + $modhead "${s}[0]" NSPEC $n_comb1 + $modhead "${s}[0]" SPEC001 $idf1_1 + $modhead "${s}[1]" COMBMETH BACKGRND + echo $s >> tmp_seg_dn.lis + + set s = DN_${rn}000${seg2}fcal.fit + set xxx = DN_${rn}xxx${seg2}fcal.fit + if (!(-e $xxx)) cf_extract_spectra -r DN_${rn}xxx $idf2_all # Avoid overwrite LiF | SiC + echo $xxx > tmp_combine.lis + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + $modhead "${s}[0]" NSPEC $n_comb2 + $modhead "${s}[0]" SPEC001 $idf2_1 + $modhead "${s}[1]" COMBMETH BACKGRND + echo $s >> tmp_seg_dn.lis + + set n_night = `cat tmp_all_night_exp.lis | wc -l` + if ($om == ttag && $n_night > 0) then # Create and combine night only files + + echo "*** Creating night only files ***" + set exp_nums = `awk '{print $1}' tmp_all_night_exp.lis` + $rm tmp_bpm1.lis tmp_bpm2.lis + + foreach exp ($exp_nums) + + # Create bpm night only files (if they do not exist yet) + set bno1 = NO_$rn$exp$det${om}fbpm.fit + set bno2 = NO_$rn$exp$det2${om}fbpm.fit + + set idf_file = $rn$exp$det${om}fidf.fit + if (!(-e $bno1)) then + echo "Creating BPM: $bno1 ..." + cf_bad_pixels -n $bno1 $idf_file + endif + if (-e $bno1) echo $bno1 >> tmp_bpm1.lis # If valid, add in $seg list + + set idf_file = $rn$exp$det2${om}fidf.fit + if (!(-e $bno2)) then + echo "Creating BPM: $bno2 ..." + cf_bad_pixels -n $bno2 $idf_file + endif + if (-e $bno2) echo $bno2 >> tmp_bpm2.lis # If valid, add in $seg2 list + + end + + + # Combine BPM for $seg and extract spectra + + set bpm1_all = NO_${rn}000$det${om}fbpm.fit + set n_bpm = `cat tmp_bpm1.lis | wc -l` + echo "Number of valid BPM files: $n_bpm" + + if ($n_bpm > 0) then + + echo $n_bpm > tmp_bpm.lis + cat tmp_bpm1.lis >> tmp_bpm.lis + + if (!(-e $bpm1_all)) then + echo "Combine all BPM (from list): $bpm1_all ..." + bpm_combine $bpm1_all tmp_bpm.lis # Create combined BPM file [no] for $seg + endif + $rm tmp_bpm.lis + + endif + + # Extract [Night only] spectra. The existence of $bpm1_all is not required + set s = NO_${rn}000${seg}fcal.fit + set xxx = NO_${rn}xxx${seg}fcal.fit + if (!(-e $xxx)) cf_extract_spectra -n $bpm1_all -r NO_${rn}xxx $idf1_all # Avoid overwrite LiF | SiC + echo $xxx > tmp_combine.lis + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + $modhead "${s}[0]" NSPEC $n_comb1 + $modhead "${s}[0]" SPEC001 $idf1_1 + $modhead "${s}[1]" COMBMETH BACKGRND + echo $s >> tmp_seg_no.lis + + + # Combine BPM for $seg2 and extract spectra + + set bpm2_all = NO_${rn}000$det2${om}fbpm.fit + set n_bpm = `cat tmp_bpm2.lis | wc -l` + echo "Number of valid BPM files: $n_bpm" + + if ($n_bpm > 0) then + + echo $n_bpm > tmp_bpm.lis + cat tmp_bpm2.lis >> tmp_bpm.lis + + if (!(-e $bpm2_all)) then + echo "Combine all BPM (from list): $bpm2_all ..." + bpm_combine $bpm2_all tmp_bpm.lis # Create combined BPM file [no] for $seg2 + endif + $rm tmp_bpm.lis + + endif + + # Extract [Night only] spectra. The existence of $bpm2_all is not required + set s = NO_${rn}000${seg2}fcal.fit + set xxx = NO_${rn}xxx${seg2}fcal.fit + if (!(-e $xxx)) cf_extract_spectra -n $bpm2_all -r NO_${rn}xxx $idf2_all # Avoid overwrite LiF | SiC + echo $xxx > tmp_combine.lis + $cf_combine -k $ignore_exp_stat tmp_combine.lis $s + $modhead "${s}[0]" NSPEC $n_comb2 + $modhead "${s}[0]" SPEC001 $idf2_1 + $modhead "${s}[1]" COMBMETH BACKGRND + echo $s >> tmp_seg_no.lis + + endif + endif + endif + end + + $rm tmp_xcorr.res tmp_bpm1.lis tmp_bpm2.lis tmp_combine.lis + $rm tmp_all_night_exp.lis tmp_good_exp.lis tmp_exp.lis tmp_night_exp.lis + + end + + # Pack the 8 [detector][channel] pairs together ([dn] and [no] for ttag) + if (-e tmp_seg_dn.lis) then + + set fcal_all = ${rn}00000all$res${om}fcal.fit # Final output name + $rm $fcal_all # Clean (safe) + set n_segs = `cat tmp_seg_dn.lis | wc -l` + + if (!($n_segs == 8)) then + + @ mseg = 8 - $n_segs + echo "ERROR: $mseg (day + night) segments are missing" + $rm tmp_seg_dn.lis + goto crash + + else + + $cf_pack tmp_seg_dn.lis $fcal_all + $rm tmp_seg_dn.lis + + # Plot figures + $idl_obsplot {$rn} + + # Create National Virtual Observatory file + set nvo_file = ${rn}00000nvo$res${om}fcal.fit + $rm $nvo_file # Clean (safe) + $cf_nvo $fcal_all $nvo_file # Create file + + if (-e tmp_seg_no.lis) then + + set fcal_all = ${rn}00000ano$res${om}fcal.fit # Final output name + $rm $fcal_all # Clean (safe) + set n_segs = `cat tmp_seg_no.lis | wc -l` + + # if (!($n_segs == 8)) then + # + # @ mseg = 8 - $n_segs + # echo "ERROR: $mseg (night only) segments are missing" + # $rm tmp_seg_no.lis + # # goto crash + # + # else + + $cf_pack tmp_seg_no.lis $fcal_all + $rm tmp_seg_no.lis + + # endif + + endif + endif + endif + end +end + +# Clean [dn] and [no] files. Just keep all, (ano) and nvo +$rm DN_${rn}*.fit NO_${rn}*.fit + +# Delete IDF files +if $?DELETE_IDF then + echo "NOTE: Deleting intermediate data files." + $rm ${rn}*idf.fit +endif + +# Delete bad-pixel-map (bpm) files +if $?DELETE_BPM then + echo "NOTE: Deleting bad pixel map (bpm) files." + $rm ${rn}*bpm.fit +endif + +# Call routine to make quick-look airglow plot. +cf_make_900_obs.csh $1 + +exit(0) + +crash: # Procedure when script crashes + +# Clean directory +$rm tmp_xcorr.res tmp_bpm1.lis tmp_bpm2.lis tmp_combine.lis tmp_night_exp.lis +$rm tmp_all_night_exp.lis tmp_good_exp.lis tmp_exp.lis tmp_seg_dn.lis tmp_seg_no.lis +$rm DN_*.fit NO_*.fit + +# Return 1 +exit(1) diff --git a/src/analysis/cf_nvo.c b/src/analysis/cf_nvo.c new file mode 100644 index 0000000..4dd9771 --- /dev/null +++ b/src/analysis/cf_nvo.c @@ -0,0 +1,497 @@ +/******************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ******************************************************************************* + * + * Usage: cf_nvo all_segments.fit nvo_file.fit + * + * Description: Write a National Virtual Observatory (nvo) file. The program + * uses the file created by cf_pack, which contains one spectrum + * per extension, each corresponding to a detector channel. + * + * History: 04/11/05 tc v1.0 First release + * 05/16/2005 wvd v1.1 Check mean flux of each segment. + * If preferred channel is missing, + * replace it with another. + * 05/19/2005 wvd v1.2 Shift each channel to match + * LiF1A between 1045 and 1070 A. + * 05/20/2005 wvd v1.3 For emission-line sources, + * cross-correlate on O VI lines. + * 05/23/2005 wvd v1.4 Don't assume that sides A and B + * have the same shift. + * 06/01/2005 wvd v1.5 Do assume that sides A and B + * have the same shift. + * 06/03/2005 wvd v1.6 Delete unused variables. + * 06/08/2005 wvd v1.7 Define MAXFLOAT if needed. + * 06/16/2005 wvd v1.8 Include values.h + * 07/06/2005 wvd v1.9 If FESCENT = FES B, use LiF 2B + * as wavelength standard. + * 07/12/2005 wvd v1.10 Give up on use of MAXFLOAT. + * 08/11/2005 wvd v1.11 Set keyword NEXTEND = 1. + * 03/22/2006 wvd v1.12 Allow use of SiC data for + * 1000-1100 A region. + * Don't cross-correlate segments + * with OBSTIME = 0. + * 05/16/2006 wvd v1.13 Use Lyman beta to align + * background exposures. + * Use O VI and C II to align WD's. + * 05/19/2006 wvd v1.14 In copy_spec(), test index to + * prevent extending past the edge. + * For BKGD targets, omit flux + * comparison when deciding which + * regions to use. + * Delete index to the file + * extensions from the primary HDU. + * Compute mean flux over same + * wavelength region for each band. + * 05/24/2006 wvd v1.16 For PC targets, don't include + * O VI in calculation of mean flux + * 12/19/2006 wvd v1.17 Reject segments with + * OBSTIME < 10 seconds when full + * exposure is longer than 100 s. + * 02/19/2008 bot v1.18 Fixed indexing problem in + * copy_spec due to shift and n_copy + * + ******************************************************************************/ + +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +#define MAXSHIFT 30 +#define N_SHIFT 61 +#define NVO_MIN 900 +#define NVO_MAX 1190 + +static char CF_PRGM_ID[] = "cf_nvo"; +static char CF_VER_NUM[] = "1.18"; + +static int +compute_shift(fitsfile *pt_fits, int hdu_ref, int hdu, float wmin, float wdelta, + float wpc, int *shift, int *quality) +{ + char comb[FLEN_VALUE], ref_comb[FLEN_VALUE]; + int hdutype, status = 0; + int ind_chi2_min, nchi; + long i, k, n_rows, ref_start, start, n_pix; + float *error, *flux, *wave, *ref_error, *ref_flux, *ref_wave; + float chi_square[N_SHIFT], chi_square_min, chi_square_max; + float ref_obstime, obstime; + double scale, sum, var1, var2; + + /* Don't need to shift reference spectrum. */ + if (hdu_ref == hdu) { + *shift = 0; + *quality = TRUE; + return(0); + } + + /* Read data for reference and data channels. */ + FITS_movabs_hdu(pt_fits, hdu_ref, &hdutype, &status); + FITS_read_key(pt_fits, TSTRING, "COMBMETH", &ref_comb, NULL, &status); + FITS_read_key(pt_fits, TFLOAT, "OBSTIME", &ref_obstime, NULL, &status); + n_rows = cf_read_col(pt_fits, TFLOAT, "WAVE", (void **) &ref_wave); + n_rows = cf_read_col(pt_fits, TFLOAT, "FLUX", (void **) &ref_flux); + n_rows = cf_read_col(pt_fits, TFLOAT, "ERROR", (void **) &ref_error); + + FITS_movabs_hdu(pt_fits, hdu, &hdutype, &status); + FITS_read_key(pt_fits, TSTRING, "COMBMETH", &comb, NULL, &status); + FITS_read_key(pt_fits, TFLOAT, "OBSTIME", &obstime, NULL, &status); + n_rows = cf_read_col(pt_fits, TFLOAT, "WAVE", (void **) &wave); + n_rows = cf_read_col(pt_fits, TFLOAT, "FLUX", (void **) &flux); + n_rows = cf_read_col(pt_fits, TFLOAT, "ERROR", (void **) &error); + + /* If either channel was not constructed using cross-correlation, + * return a shift of 0. */ + if (strncmp(ref_comb,"X",1) || strncmp(comb,"X",1)) { + *shift = 0; + *quality = FALSE; + printf("hdu = %d, hdu_ref = %d, COMBMETH != XCORR\n", + hdu, hdu_ref); + return(0); + } + + /* If either channel has OBSTIME = 0, return a shift of 0. */ + if (ref_obstime < 1 || obstime < 1) { + *shift = 0; + *quality = FALSE; + if (ref_obstime < 1) + printf("hdu_ref = %d, OBSTIME = %f\n", hdu_ref, ref_obstime); + if (obstime < 1) printf("hdu = %d, OBSTIME = %f\n", hdu, obstime); + return(0); + } + + /* Compute chi-squared for shifts between +/- MAXSHIFT pixels. */ + ref_start = cf_nlong((wmin - ref_wave[0]) / wpc) + MAXSHIFT; + start = cf_nlong((wmin - wave[0]) / wpc); + n_pix = cf_nlong(wdelta / wpc) - (N_SHIFT - 1); + + for (k = 0; k < N_SHIFT; k++) { + nchi = 0; + sum = 0; + for (i = 0; i < n_pix; i++) { + var1 = ref_error[ref_start + i] * ref_error[ref_start + i]; + var2 = error[start + i + k] * error[start + i + k]; + if ((var1 + var2) > 0.) { + sum += (ref_flux[ref_start + i] - flux[start + i + k]) * + (ref_flux[ref_start + i] - flux[start + i + k]) / + (var1 + var2); + nchi++; + } + } + scale = (double) nchi / n_pix; + chi_square[k] = sum / scale; + } + + /* If chi-squared changes by less than 20% over range of shifts, abort. + * Otherwise, return shift corresponding to lowest value of chi-square. + */ + ind_chi2_min = 0; + chi_square_min = 1E5; + chi_square_max = -1E5; + for (k = 0; k < N_SHIFT; k++) { + if (chi_square[k] < chi_square_min) + { + chi_square_min = chi_square[k]; + ind_chi2_min = k; + } + else if (chi_square[k] > chi_square_max) + chi_square_max = chi_square[k]; + } + + if (chi_square_max / chi_square_min < 1.2) { + *shift = 0; + *quality = FALSE; + printf("hdu = %d, hdu_ref = %d. Chi-square dist is flat.\n", + hdu, hdu_ref); + } + else { + *shift = ind_chi2_min - MAXSHIFT; + *quality = TRUE; + } + + free(ref_error); + free(ref_flux); + free(ref_wave); + free(error); + free(flux); + free(wave); + + return(0); +} + + +static int +copy_spec(fitsfile *pt_fits, int hdu, float w_min, float w_max, float wpc, + int shift, float *flux_nvo, float *error_nvo, long n_nvo) +{ + int hdutype, status = 0; + long i, i0, n_rows, nvo_start, start, n_copy, n_copy0; + float *error, *flux, w0; + + FITS_movabs_hdu(pt_fits, hdu, &hdutype, &status); + FITS_read_key(pt_fits, TFLOAT, "W0", &w0, NULL, &status); + n_rows = cf_read_col(pt_fits, TFLOAT, "FLUX", (void **) &flux); + n_rows = cf_read_col(pt_fits, TFLOAT, "ERROR", (void **) &error); + + nvo_start = cf_nlong(((double) w_min - NVO_MIN) / wpc); + start = cf_nlong(((double) w_min - w0) / wpc); + n_copy = cf_nlong(((double) w_max - w_min) / wpc) + 1; + if (nvo_start + n_copy > n_nvo) { + printf ("HDU = %d, w_min = %.1f, w_max = %.1f, wpc = %5.3f\n", + hdu, w_min, w_max, wpc); + printf ("n_nvo = %ld, nvo_start = %ld, start = %ld, n_copy = %ld\n", + n_nvo, nvo_start, start, n_copy); + cf_if_error("Can't create NVO array."); + } + + n_copy0 = n_copy; + if (start + shift + n_copy > n_rows) { + n_copy = n_rows - (start + shift); + if (hdu == 3) for (i = n_copy; i < n_copy0; i++) { + flux_nvo[i+nvo_start] = 0.0; + error_nvo[i+nvo_start] = 0.0; + } + } + + i0 = 0; + if (start + shift < 0) { + i0 = -(start + shift); + for (i = 0; i < i0; i++) { + flux_nvo[i+nvo_start] = 0.0; + error_nvo[i+nvo_start] = 0.0; + } + } + + for (i = i0; i < n_copy; i++) { + flux_nvo[i+nvo_start] = flux[i+start+shift]; + error_nvo[i+nvo_start] = error[i+start+shift]; + } + + free(error); + free(flux); + return(0); +} + + +int main(int argc, char *argv[]) +{ + /* Variables */ + char program[FLEN_VALUE]; + double mean_flux[8], sum_flux; + float *wave, *flux, w0, wpc, hdu_wpc; + float *wave_nvo, *flux_nvo, *error_nvo; + float max_obstime, wmin, wdelta; + long n_rows, n_nvo; + int ref, i, nextend=1, n_hdus, shift[8], quality[8]; + int bkgd_obs=FALSE, objclass; + int nkeys, morekeys=0; + long k, n_elem; + + char *ttype[] = { "WAVE", "FLUX", "ERROR" }; + char *tform[] = { "1E", "1E", "1E" }; + char *tunit[] = { "ANGSTROMS", "ERG/CM2/S/A", "ERG/CM2/S/A" }; + + /* HDU numbers must be consistent with output of cf_pack. */ + char *extname[] = { "1ASIC", "2BSIC", "1ALIF", "2BLIF", "1BSIC", "2ASIC", "1BLIF", "2ALIF" }; + int hdu[] = { 6, 8, 2, 4, 7, 9, 3 , 5 }; + float w_min[] = { 997, 1010, 990, 990, 904, 917.5, 1094 , 1090 }; + float w_max[] = { 1090, 1104, 1080, 1074, 992, 998, 1190 , 1180 }; + + /* Regions to use when computing mean flux. */ + float *region; + float region_array[8][6] = { + {0, 0, 1030, 1039, 1045, 1070}, /* 1ASIC */ + {0, 0, 1030, 1039, 1045, 1070}, /* 2BSIC */ + {0, 0, 1030, 1039, 1045, 1070}, /* 1ALIF */ + {0, 0, 1030, 1039, 1045, 1070}, /* 2BLIF */ + {912, 935, 955, 970, 980, 985}, /* 1BSIC */ + {912, 935, 955, 970, 980, 985}, /* 2ASIC */ + {1095, 1130, 1140, 1165, 1170, 1180}, /* 1BLIF */ + {1095, 1130, 1140, 1165, 1170, 1180} /* 2ALIF */ + }; + + char in_name[80], out_name[80]; + char extname_key[80], src_type[FLEN_VALUE], sp_type[FLEN_VALUE], fescent[FLEN_VALUE]; + fitsfile *pt_fits, *pt_fits_out; + int status = 0, hdutype; + + + /*********************************** + ** 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, stderr); + + + /*********************************************************** + ** Check for proper command-line usage and read arguments ** + ***********************************************************/ + if (argc != 3) + cf_if_error("Usage: cf_nvo all_segments.fit nvo_file.fit"); + + strcpy(in_name, argv[1]); + strcpy(out_name, "!"); + strcat(out_name, argv[2]); /* Force overwrite */ + + /******************************************* + ** Open input file, read header keywords. ** + *******************************************/ + FITS_open_file(&pt_fits, in_name, READONLY, &status); + FITS_read_key(pt_fits, TSTRING, "PRGRM_ID", &program, NULL, &status); + FITS_read_key(pt_fits, TINT, "OBJCLASS", &objclass, NULL, &status); + FITS_read_key(pt_fits, TSTRING, "SP_TYPE", &sp_type, NULL, &status); + FITS_read_key(pt_fits, TSTRING, "SRC_TYPE", &src_type, NULL, &status); + FITS_read_key(pt_fits, TFLOAT, "OBSTIME", &max_obstime, NULL, &status); + FITS_read_key(pt_fits, TFLOAT, "WPC", &wpc, NULL, &status); + FITS_read_key(pt_fits, TSTRING, "FESCENT", &fescent, NULL, &status); + ref = 2; /* LiF 1A */ + if (!strncmp(fescent, "FES B", 5)) ref = 3; /* LiF 2B */ + + /**************************************************************** + ** If SRC_TYPE = PC, exclude O VI in calculation of mean flux. ** + ****************************************************************/ + if (!strncmp(src_type, "PC", 2)) + for (i = 0; i < 4; i++) + region_array[i][2] = region_array[i][3] = 0; + + /*************************************** + ** Compute mean flux in each channel. ** + ***************************************/ + FITS_get_num_hdus(pt_fits, &n_hdus, &status); + if (n_hdus != 9) + cf_if_error("Input file must have 9 extensions (%d found)", n_hdus); + + for (i = 0; i < 8; i++) { + float obstime; + FITS_movabs_hdu(pt_fits, hdu[i], &hdutype, &status); + FITS_read_key(pt_fits, TSTRING, "EXTNAME", extname_key, NULL, &status); + if (strcmp(extname_key, extname[i])) + cf_if_error("Extension %d's name does not match (%s)", + hdu[i], extname[i]); + FITS_read_key(pt_fits, TFLOAT, "WPC", &hdu_wpc, NULL, &status); + if (hdu_wpc != wpc) + cf_if_error("Extension %d's WPC does not match primary HDU", + hdu[i]); + FITS_read_key(pt_fits, TFLOAT, "OBSTIME", &obstime, NULL, &status); + if (obstime < 1. || (obstime < 10 && max_obstime > 100)) + mean_flux[i] = -1; + else { + n_rows = cf_read_col(pt_fits, TFLOAT, "WAVE", (void **) &wave); + n_rows = cf_read_col(pt_fits, TFLOAT, "FLUX", (void **) &flux); + + sum_flux = n_elem = 0; + region = region_array[i]; + for (k = 0; k < n_rows; k++) + { + if ((wave[k] > region[0] && wave[k] < region[1]) || + (wave[k] > region[2] && wave[k] < region[3]) || + (wave[k] > region[4] && wave[k] < region[5])) { + sum_flux += flux[k]; + n_elem ++; + } + } + + mean_flux[i] = sum_flux / n_elem; + free(wave); + free(flux); + } + + printf("%s\tmean_flux = %g\n", extname_key, mean_flux[i]); + } + + /******************************************************************* + * If FESCENT = FES A, compute shifts relative to LiF 1A. + * If FESCENT = FES B, use LiF 2B. + * For background targets, compare Lyman beta lines. + * For other emission-line targets, compare O VI lines. + * For white dwarfs, use O VI and C II. + * For other continuum sources, use the region between 1045 and 1070 A + * for the four 1000-1100 A channels. + ******************************************************************/ + + if (src_type[1] == 'E') { /* Emission-line source */ + /* Use Lyman beta to align background observations. */ + if (objclass == 7 || (program[0] == 'S' && program[2] == '0' && program[3] == '5')) { + printf("Assuming background observation.\n"); + wmin = 1024.; + wdelta = 6.; + } else { /* Use O VI emission for everything else. */ + printf("SRC_TYPE = %s. Emission-line target.\n", src_type); + wmin = 1030.; + wdelta = 9.; + } + } + /* Continuum source */ + else if (objclass == 17 || objclass == 29 || objclass == 37) { + /* Use O VI and C II to align white dwarf spectra. */ + printf("OBJCLASS = %d. Assuming nearby white dwarf.\n", objclass); + wmin = 1030.; + wdelta = 9.; + } + else { /* Use 1045-1070 A region for all other continuum sources. */ + printf("SRC_TYPE = %s. Continuum target.\n", src_type); + wmin = 1045.; + wdelta = 25.; + } + + for (i = 0; i < 4; i++) { + if (mean_flux[i] > -1) + compute_shift(pt_fits, hdu[ref], hdu[i], wmin, wdelta, wpc, shift+i, quality+i); + else + shift[i] = 0; + shift[i+4] = shift[i]; + printf("hdu = %d, hdu_ref = %d, shift = %d\n", hdu[i], hdu[ref], shift[i]); + } + + /************************** + ** Set up output arrays. ** + **************************/ + n_nvo = cf_nlong((double) (NVO_MAX - NVO_MIN) / wpc) + 1; + wave_nvo = (float *) cf_calloc(n_nvo, sizeof(float)); + for (i = 0; i < n_nvo; i++) wave_nvo[i] = NVO_MIN + (double) wpc * i; + flux_nvo = (float *) cf_calloc(n_nvo, sizeof(float)); + error_nvo = (float *) cf_calloc(n_nvo, sizeof(float)); + + for (i = 0; i < n_nvo; i++) { + flux_nvo[i] = 0.0; + error_nvo[i] = 0.0; + } + + /************************************************************** + ** In each wave band, copy best data set into output arrays. ** + **************************************************************/ + /* For BKGD targets, omit flux comparison when selecting which + regions to use. */ + if (objclass == 7 || !strncmp(sp_type, "BKGD", 4)) bkgd_obs = TRUE; + + /* First fill in the 1010-1104 A region with SiC 2B. */ + copy_spec(pt_fits, hdu[1], w_min[1], w_max[1], wpc, shift[1], flux_nvo, error_nvo, n_nvo); + + /* Replace with SiC 1A if possible. It has a higher S/N, but extends only to 1090 A. */ + if ((bkgd_obs && mean_flux[0] > -1) || (mean_flux[0] > 0.9 * mean_flux[1])) + copy_spec(pt_fits, hdu[0], w_min[0], w_max[0], wpc, shift[0], flux_nvo, error_nvo, n_nvo); + + /* Next overlay the region between 990 and 1080 A with LiF 1A or LiF 2B, if available. */ + if ((bkgd_obs && mean_flux[2] > -1) || ((mean_flux[2] > 0.9 * mean_flux[3]) && + (mean_flux[2] > 0.7 * mean_flux[0]) && (mean_flux[2] > 0.7 * mean_flux[1]))) + copy_spec(pt_fits, hdu[2], w_min[2], w_max[2], wpc, shift[2], flux_nvo, error_nvo, n_nvo); + else if ((bkgd_obs && mean_flux[3] > -1) || + ((mean_flux[3] > 0.7 * mean_flux[0]) && (mean_flux[3] > 0.7 * mean_flux[1]))) + copy_spec(pt_fits, hdu[3], w_min[3], w_max[3], wpc, shift[3], flux_nvo, error_nvo, n_nvo); + else + w_max[5] = 1010, w_min[6] = w_min[7] = 1104; + /* If no LiF data, adopt limits of SiC spectra. */ + + /* Use SiC 1B to populate the shortest wavelengths. */ + copy_spec(pt_fits, hdu[4], w_min[4], w_max[4], wpc, shift[4], flux_nvo, error_nvo, n_nvo); + + /* If SiC 2A is good, use it for the main part of 900 - 1000 A. */ + if ((bkgd_obs && mean_flux[5] > -1) || (mean_flux[5] > 0.9 * mean_flux[4])) + copy_spec(pt_fits, hdu[5], w_min[5], w_max[5], wpc, shift[5], flux_nvo, error_nvo, n_nvo); + + /* Use LiF 1B to populate the longest wavelengths. */ + copy_spec(pt_fits, hdu[6], w_min[6], w_max[6], wpc, shift[6], flux_nvo, error_nvo, n_nvo); + + /* If LiF 2A is good, use it for the main part of 1100 - 1180 A. */ + if ((bkgd_obs && mean_flux[7] > -1) || (mean_flux[7] > 0.9 * mean_flux[6])) + copy_spec(pt_fits, hdu[7], w_min[7], w_max[7], wpc, shift[7], flux_nvo, error_nvo, n_nvo); + + + for (i = 0; i < n_nvo; i++) { + if (flux_nvo[i] >= 1 || error_nvo[i] >= 1) cf_if_error("Bad values in NVO array."); + } + + /********************* + ** Create NVO file. ** + *********************/ + FITS_create_file(&pt_fits_out, out_name, &status); + FITS_movabs_hdu(pt_fits, 1, &hdutype, &status); + FITS_copy_header(pt_fits, pt_fits_out, &status); + FITS_update_key(pt_fits_out, TINT, "NEXTEND", &nextend, NULL, &status); + FITS_update_key(pt_fits_out, TSTRING, "FILENAME", (out_name + 1), NULL, &status); + FITS_update_key(pt_fits_out, TSTRING, "FILETYPE", "NVO SPECTRUM", NULL, &status); + w0 = NVO_MIN; + FITS_update_key(pt_fits_out, TFLOAT, "W0", &w0, NULL, &status); + + /* Delete index to file extensions from the primary HDU. */ + fits_get_hdrspace(pt_fits_out, &nkeys, &morekeys, &status); + for (i = nkeys; i > nkeys-12; i--) fits_delete_record(pt_fits_out, i, &status); + + FITS_create_tbl(pt_fits_out, BINARY_TBL, n_nvo, 3, ttype, tform, tunit, "FUSE_SPECTRUM", &status); + FITS_write_col(pt_fits_out, TFLOAT, 1, 1L, 1L, n_nvo, wave_nvo, &status); + FITS_write_col(pt_fits_out, TFLOAT, 2, 1L, 1L, n_nvo, flux_nvo, &status); + FITS_write_col(pt_fits_out, TFLOAT, 3, 1L, 1L, n_nvo, error_nvo, &status); + + free(wave_nvo); + free(flux_nvo); + free(error_nvo); + + FITS_close_file(pt_fits_out, &status); + FITS_close_file(pt_fits, &status); + + return(0); +} diff --git a/src/analysis/cf_pack.c b/src/analysis/cf_pack.c new file mode 100644 index 0000000..a823c22 --- /dev/null +++ b/src/analysis/cf_pack.c @@ -0,0 +1,270 @@ +/******************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ******************************************************************************* + * + * Usage: cf_pack combined_exposure_list out_file_name.fit + * + * Description: Write the 8 segments (1alif, 1blif etc...) into a single fits + * file with 8 extensions (in addition to the primary array). + * + * History: 04/08/05 tc v1.0 First release + * 05/02/05 wvd v1.1 Copy SPEC and WOFF keywords to + * output file. + * 06/03/05 wvd v1.2 Delete unused variables. + * 06/29/05 wvd v1.3 Set keyword COMB_COR = COMPLETE. + * 09/30/05 wvd v1.4 Update archive search keywords. + * 03/23/06 wvd v1.5 If a segment is missing, write + * an empty image extension. + * 05/19/06 wvd v1.6 Write an index to the file + * extensions to the primary HDU. + * 05/24/06 wvd v1.7 Remove SPEC* keywords from + * primary HDU. + * 05/29/06 wvd v1.8 Use while construction to + * delete WOFF* keywords. + * 06/22/06 wvd v1.9 Truncate APER_ACT from (for + * example) MDRS_LIF to MDRS. + * 08/14/06 wvd v1.10 Tinker with code to copy SPEC + * keywords to new file header. + * 04/07/07 wvd v1.11 Clean up compiler warnings. + * 08/27/07 bot v1.12 Changed TINT to TLONG l.163,214, + * and 215 ; added L to every number + * occurence related to i and j ; + * Changed i to k l.123 to 131 to + * keep an int in this case + * + ******************************************************************************/ + +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +/* Calfuse variables */ +static char CF_PRGM_ID[] = "cf_pack"; +static char CF_VER_NUM[] = "1.12"; + +int main(int argc, char *argv[]) +{ + /* Variables */ + float obstime, obstime_max, woffset; + float w0, wpc; + int wave_cnum, flux_cnum, error_cnum; + int n_spec, n_best_spec; + long i, j, num_exp, n_rows; + int k; + + char *ttype[] = { "WAVE", "FLUX", "ERROR" }; + char *tform[] = { "1E", "1E", "1E" }; + char *tunit[] = { "ANGSTROMS", "ERG/CM2/S/A", "ERG/CM2/S/A" }; + char *extname[] = { "1ALIF", "1BLIF", "2BLIF", "2ALIF", "1ASIC", "1BSIC", "2BSIC", "2ASIC" }; + char spec_list[][80] = { "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL", "NULL" }; + + /* New values for archive search keywords */ + float bandwid = 285.; + float centrwv = 1046.; + float wavemin = 904.; + float wavemax = 1189.; + + FILE *pt_file; + char comment[FLEN_COMMENT], spec_lis[80], out_name[80], spec_name[80]; + char aper_act[80], detector[80], segment[80]; + char err_str[80], aper_key[8], combmeth_key[9]; + char keyname[FLEN_KEYWORD], keyvalue[FLEN_VALUE]; + fitsfile *pt_fits, *pt_fits_out; + int status = 0, hdutype = 0; + int nextend_key = 8; + float obstime_key = 0; + + + /*********************************** + ** 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, stderr); + + + /*********************************************************** + ** Check for proper command-line usage and read arguments ** + ***********************************************************/ + if (argc != 3) + cf_if_error("Usage: cf_pack combined_exposure_list out_file_name.fit\n"); + + strcpy(spec_lis, argv[1]); + strcpy(out_name, "!"); + strcat(out_name, argv[2]); /* Force overwrite */ + + /******************** + ** Open input list ** + ********************/ + if ((pt_file = fopen(spec_lis, "r")) == NULL) + { + sprintf(err_str, "Unable to open file %s\n", spec_lis); + cf_if_error(err_str); + } + + /* *********************************************** + ** Determine which spectrum has maximum OBSTIME ** + ** Write input file list to spec_list array. ** + *************************************************/ + n_best_spec = -1; + n_spec = 0; + obstime_max = -1; + + while (fscanf(pt_file, "%80s", spec_name) != EOF) + { + FITS_open_file(&pt_fits, spec_name, READONLY, &status); + FITS_read_key(pt_fits, TFLOAT, "OBSTIME" , &obstime, NULL, &status); + FITS_read_key(pt_fits, TSTRING, "DETECTOR" , &detector, NULL, &status); + FITS_read_key(pt_fits, TSTRING, "APER_ACT" , &aper_act, NULL, &status); + FITS_close_file(pt_fits, &status); + + sprintf(segment, "%2s%3s", detector, aper_act+5); + for (k=0; k<8; k++) + if (!strcmp(segment, extname[k])) { + strcpy(spec_list[k], spec_name); + break; + } + if (obstime_max < obstime) { + n_best_spec = k; + obstime_max = obstime; + } + n_spec++; + } + fclose(pt_file); + if (n_spec == 0) cf_if_error("No valid segments provided"); + if (n_spec != 8) cf_if_warning("Combining fewer than 8 segments"); + + /* *************************************************** + ** Copy header of reference spectrum to output file ** + ** Update a few header keywords. ** + *****************************************************/ + + FITS_open_file(&pt_fits, spec_list[n_best_spec], READONLY, &status); + FITS_create_file(&pt_fits_out, out_name, &status); + FITS_copy_header(pt_fits, pt_fits_out, &status); + FITS_close_file(pt_fits, &status); + + FITS_update_key(pt_fits_out, TSTRING, "FILENAME", (out_name + 1), NULL, &status); + FITS_update_key(pt_fits_out, TSTRING, "DETECTOR", "ALL", NULL, &status); + FITS_update_key(pt_fits_out, TSTRING, "COMB_COR", "COMPLETE", NULL, &status); + + sprintf(aper_key, "%4s", aper_act); + FITS_update_key(pt_fits_out, TSTRING, "APER_ACT", aper_key, NULL, &status); + FITS_update_key(pt_fits_out, TINT, "NEXTEND", &nextend_key, NULL, &status); + + FITS_update_key(pt_fits_out, TFLOAT, "BANDWID", &bandwid, NULL, &status); + FITS_update_key(pt_fits_out, TFLOAT, "CENTRWV", ¢rwv, NULL, &status); + FITS_update_key(pt_fits_out, TFLOAT, "WAVEMIN", &wavemin, NULL, &status); + FITS_update_key(pt_fits_out, TFLOAT, "WAVEMAX", &wavemax, NULL, &status); + + FITS_read_key(pt_fits_out, TLONG, "NSPEC", &num_exp, NULL, &status); + FITS_delete_key(pt_fits_out, "NSPEC", &status); + for (i = 0L; i < num_exp; i++) { + sprintf(keyname, "SPEC%03ld", i+1L); + FITS_delete_key(pt_fits_out, keyname, &status); + sprintf(keyname, "WOFF*%03ld", i+1L); + FITS_delete_key(pt_fits_out, keyname, &status); + fits_delete_key(pt_fits_out, keyname, &status); + if (status != 0) status = 0; + } + + + /* *************************************************** + ** Step through detector segments. + ** Copy spectra into extensions of output file. + *****************************************************/ + for (i = 0L; i < 8L; i++) { + + if (!strncmp(spec_list[i], "NULL", 4)) { + n_rows = 0L; + FITS_create_tbl(pt_fits_out, BINARY_TBL, n_rows, 3, ttype, tform, + tunit, extname[i], &status); + FITS_write_comment(pt_fits_out, "Extension is empty. No data available.", &status); + } + else { + FITS_open_file(&pt_fits, spec_list[i], READONLY, &status); + + FITS_movabs_hdu(pt_fits, 2, &hdutype, &status); + FITS_get_colnum(pt_fits, TRUE, "WAVE", &wave_cnum, &status); + FITS_get_colnum(pt_fits, TRUE, "FLUX", &flux_cnum, &status); + FITS_get_colnum(pt_fits, TRUE, "ERROR", &error_cnum, &status); + FITS_get_num_rows(pt_fits, &n_rows, &status); + + FITS_create_tbl(pt_fits_out, BINARY_TBL, n_rows, 3, ttype, tform, + tunit, extname[i], &status); + + FITS_copy_col(pt_fits, pt_fits_out, wave_cnum, 1, FALSE, &status); + FITS_copy_col(pt_fits, pt_fits_out, flux_cnum, 2, FALSE, &status); + FITS_copy_col(pt_fits, pt_fits_out, error_cnum, 3, FALSE, &status); + + /* Copy various header keywords */ + FITS_read_key(pt_fits, TSTRING, "COMBMETH", combmeth_key, NULL, &status); + FITS_update_key(pt_fits_out, TSTRING, "COMBMETH", combmeth_key, NULL, &status); + + FITS_movabs_hdu(pt_fits, 1, &hdutype, &status); + FITS_read_key(pt_fits, TFLOAT, "W0", &w0, NULL, &status); + FITS_update_key(pt_fits_out, TFLOAT, "W0", &w0, NULL, &status); + FITS_read_key(pt_fits, TFLOAT, "WPC", &wpc, NULL, &status); + FITS_update_key(pt_fits_out, TFLOAT, "WPC", &wpc, NULL, &status); + FITS_read_key(pt_fits, TFLOAT, "OBSTIME", &obstime_key, NULL, &status); + FITS_update_key(pt_fits_out, TFLOAT, "OBSTIME", &obstime_key, NULL, &status); + FITS_read_key(pt_fits, TLONG, "NSPEC", &num_exp, NULL, &status); + FITS_update_key(pt_fits_out, TLONG, "NSPEC", &num_exp, NULL, &status); + + for (j = 0L; j < num_exp; j++) { + sprintf(keyname, "SPEC%03ld", j+1L); + FITS_read_key(pt_fits, TSTRING, keyname, keyvalue, NULL, &status); + FITS_update_key(pt_fits_out, TSTRING, keyname, keyvalue, NULL, &status); + sprintf(keyname, "WOFF%03ld", j+1L); + fits_read_key(pt_fits, TFLOAT, keyname, &woffset, comment, &status); + if (status) { + status = 0; + woffset = 0.; + sprintf(comment, "[A]"); + } + FITS_update_key(pt_fits_out, TFLOAT, keyname, &woffset, comment, &status); + } + FITS_close_file(pt_fits, &status); + } + } + if (n_spec != 8) { + char datestr[FLEN_CARD]; + int timeref; + FITS_movabs_hdu(pt_fits_out, 1, &hdutype, &status); + FITS_write_comment(pt_fits_out, " ", &status); + sprintf(comment, "Segments"); + for (i=0L; i<8L; i++) if (!strncmp(spec_list[i], "NULL", 4)) + sprintf(comment, "%s %s", comment, extname[i]); + sprintf(comment, "%s are missing.", comment); + FITS_write_comment(pt_fits_out, comment, &status); + sprintf(comment, "Extensions"); + for (i=0L; i<8L; i++) if (!strncmp(spec_list[i], "NULL", 4)) + sprintf(comment, "%s %ld", comment, i+1L); + sprintf(comment, "%s of this file contain no data.", comment); + FITS_write_comment(pt_fits_out, comment, &status); + fits_get_system_time(datestr, &timeref, &status); + sprintf(comment, "CalFUSE v%s %.10s", CALFUSE_VERSION, datestr); + FITS_write_comment(pt_fits_out, comment, &status); + FITS_write_comment(pt_fits_out, " ", &status); + } + + /* Add an index to the file extensions. */ + FITS_movabs_hdu(pt_fits_out, 1, &hdutype, &status); + FITS_write_comment(pt_fits_out, " ", &status); + sprintf(comment, "Index to file extensions:"); + FITS_write_comment(pt_fits_out, comment, &status); + sprintf(comment, "Extension 0 This Header"); + FITS_write_comment(pt_fits_out, comment, &status); + for (i=0L; i<8L; i++) { + sprintf(comment, "Extension %ld %s", i+1L, extname[i]); + FITS_write_comment(pt_fits_out, comment, &status); + } + FITS_write_comment(pt_fits_out, " ", &status); + + FITS_close_file(pt_fits_out, &status); + + return(0); +} diff --git a/src/analysis/cf_reflux.c b/src/analysis/cf_reflux.c new file mode 100644 index 0000000..1a2511f --- /dev/null +++ b/src/analysis/cf_reflux.c @@ -0,0 +1,148 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + * + * Synopsis: cf_reflux input_file output_file aeff_cal1 [aeff_cal2] + * + * Description: Program applies a new flux calibration to an extracted + * spectral file. If two effective-area files are given, + * program interpolates between them based on the MDJ + * of the exposure. + * Program writes a history line to output file header. + * + * Arguments: input_file FUSE extracted spectral file (fcal.fit) + * output_file Copy of input file with modified flux cal. + * aeff_cal1 Effective-area curve + * aeff_cal2 Optional effective-area curve, needed only + * if you wish to interpolate. + * + * Returns: none + * + * History: 06/02/05 1.1 wvd Based on programs cf_uninterp and + * cf_extract_spectra. + * + ****************************************************************************/ + +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +static char CF_PRGM_ID[] = "cf_reflux"; +static char CF_VER_NUM[] = "1.1"; + +int main(int argc, char *argv[]) +{ + char aper_act[FLEN_VALUE], datestr[FLEN_VALUE]; + int status=0, hdutype; + int aperture, timeref; + long i, frow=1, felement=1, nout; + float exptime, wpc; + float *wave, *flux, *error, *weights, *bkgd; + unsigned char *channel; + fitsfile *infits, *outfits; + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing"); + + /* Initialize error checking */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + if (argc < 4) { + printf("Usage: cf_reflux input_file output_file aeff_cal1 [aeff_cal2]\n"); + return 0; + } + + /* Copy input spectral file to output. Close input file. */ + FITS_open_file(&infits, argv[1], READONLY, &status); + FITS_create_file(&outfits, argv[2], &status); + FITS_copy_hdu(infits, outfits, 0, &status); + FITS_movrel_hdu(infits, 1, &hdutype, &status); + FITS_copy_hdu(infits, outfits, 0, &status); + FITS_close_file(infits, &status); + + /* Modify output file keywords. */ + FITS_movabs_hdu(outfits, 1, &hdutype, &status); + FITS_update_key(outfits, TSTRING, "FILENAME", argv[2], NULL, &status); + FITS_update_key(outfits, TSTRING, "AEFF1CAL", argv[3], NULL, &status); + if (argc == 5) + FITS_update_key(outfits, TSTRING, "AEFF2CAL", argv[4], NULL, &status); + else + FITS_update_key(outfits, TSTRING, "AEFF2CAL", argv[3], NULL, &status); + + /* Add HISTORY lines to the output file */ + fits_get_system_time(datestr, &timeref, &status); + strcat(datestr, " File recalibrated using cf_reflux"); + FITS_write_history(outfits, datestr, &status); + + /* Through which aperture was this spectrum obtained? */ + FITS_read_key(outfits, TSTRING, "APER_ACT", aper_act, NULL, &status); + if (!strcmp(aper_act, "HIRS_LIF")) aperture = 1; + else if (!strcmp(aper_act, "MDRS_LIF")) aperture = 2; + else if (!strcmp(aper_act, "LWRS_LIF")) aperture = 3; + else if (!strcmp(aper_act, "HIRS_SIC")) aperture = 5; + else if (!strcmp(aper_act, "MDRS_SIC")) aperture = 6; + else if (!strcmp(aper_act, "LWRS_SIC")) aperture = 7; + else { + printf("Unable to interpret header keyword APER_ACT = %s\n", aper_act); + FITS_close_file(outfits, &status); + return 0; + } + + /* Read WAVE, FLUX, ERROR, WEIGHTS, and BKGD arrays */ + FITS_movabs_hdu(outfits, 2, &hdutype, &status); + nout = cf_read_col(outfits, TFLOAT, "WAVE", (void **) &wave); + nout = cf_read_col(outfits, TFLOAT, "FLUX", (void **) &flux); + nout = cf_read_col(outfits, TFLOAT, "ERROR", (void **) &error); + nout = cf_read_col(outfits, TFLOAT, "WEIGHTS", (void **) &weights); + nout = cf_read_col(outfits, TFLOAT, "BKGD", (void **) &bkgd); + channel = (unsigned char *) cf_malloc(sizeof(unsigned char) * nout); + + /* Compute inputs to flux-calibration routine */ + for (i = 0; i < nout; i++) { + channel[i] = (unsigned char) aperture; + if (flux[i] != 0.) error[i] /= flux[i]; /* Relative error */ + flux[i] = weights[i] - bkgd[i]; /* Units are counts */ + } + + /* Apply flux calibration */ + FITS_movabs_hdu(outfits, 1, &hdutype, &status); + FITS_update_key(outfits, TSTRING, "FLUX_COR", "PERFORM", NULL, &status) ; + cf_convert_to_ergs(outfits, nout, flux, flux, channel, wave); + + /* Convert flux and error arrays to units of erg/cm2/s/A. */ + FITS_movabs_hdu(outfits, 1, &hdutype, &status); + FITS_read_key(outfits, TFLOAT, "EXPTIME", &exptime, NULL, &status); + FITS_read_key(outfits, TFLOAT, "WPC", &wpc, NULL, &status); + if (exptime < 1) { + printf ("EXPTIME = %g. Exiting.\n", exptime); + FITS_close_file(outfits, &status); + return 0; + } + for (i = 0; i < nout; i++) { + flux[i] /= exptime * wpc; + error[i] *= flux[i]; + } + + /* Write new flux and error arrays to the output file. */ + FITS_movabs_hdu(outfits, 2, &hdutype, &status); + FITS_write_col(outfits, TFLOAT, 2, frow, felement, nout, flux, &status); + FITS_write_col(outfits, TFLOAT, 3, frow, felement, nout, error, &status); + + /* Close output file. */ + FITS_close_file(outfits, &status); + + /* Free memory. */ + free(wave); + free(flux); + free(error); + free(weights); + free(bkgd); + free(channel); + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done processing"); + return 0; +} diff --git a/src/analysis/cf_ttag_to_hist.c b/src/analysis/cf_ttag_to_hist.c new file mode 100644 index 0000000..070a1a6 --- /dev/null +++ b/src/analysis/cf_ttag_to_hist.c @@ -0,0 +1,463 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: cf_ttag_to_hist input_file output_file + * + * Description: Creates a FITS 2D image from a time-tagged data file (FITS + * binary table of photon address data). The 2D SIA table is + * written to the first extension (HDU=1) and the other four + * extensions contain the two apertures and stim-lamp pulses. + * + * + * Arguments: input_file Input raw time-tagged FITS file name + * output_file Output raw histogram FITS file name + * + * Returns: none + * + * History: 03/28/00 1.01 peb Begin work + * 12/21/00 1.03 peb Fixed type mismatched in cfitsio + * calls + * + ****************************************************************************/ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +#define STIMX 2048 + +static char CF_PRGM_ID[] = "cf_ttag_to_hist"; +static char CF_VER_NUM[] = "1.03"; + +int main(int argc, char *argv[]) +{ + fitsfile *infits, *outfits; + char buffer[FLEN_CARD], *siabuf; + int status = 0, intnull, anynull, hdutype, fcol, begkey=5, endkey; + int j, k1, kx1, ky1, k2, kx2, ky2, k3, kx3, ky3, k4, kx4, ky4; + int naxis, naxis1, naxis2, naxis3, naxis4; + int *posx, *posy, npixel, fpixel=1, frow, felem, nrow; + int begx1, begy1, begx2, begy2, begx3, begy3, begx4, begy4; + int rcnt1, rcnt2, rcnt3, rcnt4, min1, min2, min3, min4; + int max1, max2, max3, max4, binx, biny; + int keynum, nextend=4, extver=0, bzero=32768, bscale=1; + short *outbuf1, *outbuf2, *outbuf3, *outbuf4; + long naxes[2], naxes1[2], naxes2[2], naxes3[2], naxes4[2]; + float fzero=0.0; + double ra_targ, dec_targ, pa_aper, equinox; + + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + /* + * Open input ttag data file and create output file. + */ + FITS_open_file(&infits, argv[1], READONLY, &status); + FITS_create_file(&outfits, argv[2], &status); + /* + * Create primary image header + */ + naxis = 2; naxes[0] = 8; naxes[1] = 64; + FITS_create_img(outfits, BYTE_IMG, naxis, naxes, &status); + /* + * Copy header from primary HDU of the input file to the output file, + * but leave the primary HDU data array empty. + */ + FITS_read_key(infits, TINT, "SPECBINX", &binx, buffer, &status); + FITS_read_key(infits, TINT, "SPECBINY", &biny, buffer, &status); + FITS_get_hdrpos(infits, &endkey, &keynum, &status); + for (j = begkey; j <= endkey; j++) { + FITS_read_record(infits, j, buffer, &status); + FITS_write_record(outfits, buffer, &status); + } + FITS_update_key(outfits, TINT, "NEXTEND", &nextend, NULL, &status); + FITS_update_key(outfits, TSTRING, "FILETYPE", "RAW HISTOGRAM", + NULL, &status); + FITS_update_key(outfits, TSTRING, "INSTMODE", "HIST", NULL, &status); + /* + * Populate primary data or SIA table. + */ + npixel = naxes[0]*naxes[1]; + siabuf = cf_malloc(npixel); + memset(siabuf, 1, npixel); + FITS_write_img(outfits, TBYTE, fpixel, npixel, siabuf, &status); + free(siabuf); + /* + * Move to the 1st HDU of the input file and read the binary table. + */ + FITS_movabs_hdu(infits, 2, &hdutype, &status); + if(hdutype != BINARY_TBL) { + cf_if_error("Error: This HDU is not a binary table!"); + } + FITS_read_key(infits, TINT, "NAXIS2", &nrow, buffer, &status); + FITS_read_key(infits, TDOUBLE, "RA_TARG", &ra_targ, buffer, &status); + FITS_read_key(infits, TDOUBLE, "DEC_TARG", &dec_targ, buffer, &status); + FITS_read_key(infits, TDOUBLE, "PA_APER", &pa_aper, buffer, &status); + FITS_read_key(infits, TDOUBLE, "EQUINOX", &equinox, buffer, &status); + /* + * Allocate memory for X, Y photon event arrays + */ + posx = cf_malloc(sizeof(int) * nrow); + posy = cf_malloc(sizeof(int) * nrow); + /* + * Read X and Y from table + */ + frow = felem = 1; intnull = anynull = 0; + + FITS_get_colnum(infits, TRUE, "X", &fcol, &status); + FITS_read_col(infits, TINT, fcol, frow, felem, nrow, &intnull, + posx, &anynull, &status); + FITS_get_colnum(infits, TRUE, "Y", &fcol, &status); + FITS_read_col(infits, TINT, fcol, frow, felem, nrow, &intnull, + posy, &anynull, &status); + /* + * Create buffers (outbufn) to hold binned images, and + * initialize them. + */ + naxis1 = 2; naxes1[0] = NXMAX; naxes1[1] = 20; + begx1 = 0; begy1 = 48; rcnt1 = 56; min1 = max1 = 0; + outbuf1 = cf_calloc(naxes1[0]*naxes1[1], sizeof(short)); + + naxis2 = 2; naxes2[0] = NXMAX; naxes2[1] = 20; + begx2 = 0; begy2 = 76; rcnt2 = 57; min2 = max2 = 0; + outbuf2 = cf_calloc(naxes2[0]*naxes2[1], sizeof(short)); + + naxis3 = 2; naxes3[0] = STIMX; naxes3[1] = 2; + begx3 = 0; begy3 = 76; rcnt3 = 1; min3 = max3 = 0; + outbuf3 = cf_calloc(naxes3[0]*naxes3[1], sizeof(short)); + + naxis4 = 2; naxes4[0] = STIMX; naxes4[1] = 2; + begx4 = 14336; begy4 = 78; rcnt4 = 1; min4 = max4 = 0; + outbuf4 = cf_calloc(naxes4[0]*naxes4[1], sizeof(short)); + + for(j = 0; j < nrow; j++) { + kx1 = posx[j]/binx-begx1; + ky1 = posy[j]/biny-begy1; + if (kx1 >= 0 && kx1 < naxes1[0] && ky1 >= 0 && ky1 < naxes1[1]) { + k1 = naxes1[0]*ky1 + kx1; + outbuf1[k1] += 1; + if (outbuf1[k1] < min1) + min1 = outbuf1[k1]; + if (outbuf1[k1] > max1) + max1 = outbuf1[k1]; + } + kx2 = posx[j]/binx-begx2; + ky2 = posy[j]/biny-begy2; + if (kx2 >= 0 && kx2 < naxes2[0] && ky2 >= 0 && ky2 < naxes2[1]) { + k2 = naxes2[0]*ky2 + kx2; + outbuf2[k2] += 1; + if (outbuf2[k2] < min2) + min2 = outbuf2[k2]; + if (outbuf2[k2] > max2) + max2 = outbuf2[k2]; + } + kx3 = posx[j]/binx-begx3; + ky3 = posy[j]/biny-begy3; + if (kx3 >= 0 && kx3 < naxes3[0] && ky3 >= 0 && ky3 < naxes3[1]) { + k3 = naxes3[0]*ky3 + kx3; + outbuf3[k3] += 1; + if (outbuf3[k3] < min3) + min3 = outbuf3[k3]; + if (outbuf3[k3] > max3) + max3 = outbuf3[k3]; + } + kx4 = posx[j]/binx-begx4; + ky4 = posy[j]/biny-begy4; + if (kx4 >= 0 && kx4 < naxes4[0] && ky4 >= 0 && ky4 < naxes4[1]) { + k4 = naxes4[0]*ky4 + kx4; + outbuf4[k4] += 1; + if (outbuf4[k4] < min4) + min4 = outbuf4[k4]; + if (outbuf4[k4] > max4) + max4 = outbuf4[k4]; + } + } + /* + * Extension 1 + */ + FITS_create_img(outfits, SHORT_IMG, naxis1, naxes1, &status); + extver = 1; + + FITS_write_key(outfits, TSTRING, "EXTNAME", "HISTOGRAM", + "name of this extension", &status); + FITS_write_key(outfits, TINT, "EXTVER" , &extver, + "extension version number", &status); + FITS_write_key(outfits, TINT, "BZERO" , &bzero, + "image brightness offset", &status); + FITS_write_key(outfits, TINT, "BSCALE" , &bscale, + "image brightness scale", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, + " World Coordinate System and Related Parameters", + &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TFLOAT, "CRPIX1", &fzero, + "x-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRPIX2", &fzero, + "y-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL1", &fzero, + "first axis value at reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL2", &fzero, + "second axis value at reference pixel", &status); + FITS_write_key(outfits, TSTRING, "CTYPE1", "LAMBDA", + "the coordinate type for the first axis", &status); + FITS_write_key(outfits, TSTRING, "CYTPE2", "ANGLE", + "the coordinate type for the second axis", &status); + FITS_write_key(outfits, TFLOAT, "CD1_1", &fzero, + "partial of first axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD1_2", &fzero, + "partial of first axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TFLOAT, "CD2_1", &fzero, + "partial of second axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD2_2", &fzero, + "partial of second axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TDOUBLE, "RA_TARG", &ra_targ, + "RA of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "DEC_TARG", &dec_targ, + "Declination of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "PA_APER", &pa_aper, + "Position Angle of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "EQUINOX", &equinox, + "equinox of celestial coord. system", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " HISTOGRAM REGION PARAMETERS", &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TINT, "XORIGIN", &begx1, + "offset of this region in the x dimension", &status); + FITS_write_key(outfits, TINT, "YORIGIN", &begy1, + "offset of this region in the y dimension", &status); + FITS_write_key(outfits, TINT, "RCOUNT", &rcnt1, + "count of rectangles in this region", &status); + FITS_write_key(outfits, TINT, "MINVAL", &min1, + "minimum value within rectangles", &status); + FITS_write_key(outfits, TINT, "MAXVAL", &max1, + "maximum value within rectangles", &status); + + FITS_write_img(outfits, TSHORT, fpixel, naxes1[0]*naxes1[1], + outbuf1, &status); + /* + * Extension 2 + */ + FITS_create_img(outfits, SHORT_IMG, naxis2, naxes2, &status); + extver = 2; + + FITS_write_key(outfits, TSTRING, "EXTNAME", "HISTOGRAM", + "name of this extension", &status); + FITS_write_key(outfits, TINT, "EXTVER" , &extver, + "extension version number", &status); + FITS_write_key(outfits, TINT, "BZERO" , &bzero, + "image brightness offset", &status); + FITS_write_key(outfits, TINT, "BSCALE" , &bscale, + "image brightness scale", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, + " World Coordinate System and Related Parameters", + &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TFLOAT, "CRPIX1", &fzero, + "x-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRPIX2", &fzero, + "y-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL1", &fzero, + "first axis value at reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL2", &fzero, + "second axis value at reference pixel", &status); + FITS_write_key(outfits, TSTRING, "CTYPE1", "LAMBDA", + "the coordinate type for the first axis", &status); + FITS_write_key(outfits, TSTRING, "CYTPE2", "ANGLE", + "the coordinate type for the second axis", &status); + FITS_write_key(outfits, TFLOAT, "CD1_1", &fzero, + "partial of first axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD1_2", &fzero, + "partial of first axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TFLOAT, "CD2_1", &fzero, + "partial of second axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD2_2", &fzero, + "partial of second axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TDOUBLE, "RA_TARG", &ra_targ, + "RA of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "DEC_TARG", &dec_targ, + "Declination of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "PA_APER", &pa_aper, + "Position Angle of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "EQUINOX", &equinox, + "equinox of celestial coord. system", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " HISTOGRAM REGION PARAMETERS", &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TINT, "XORIGIN", &begx2, + "offset of this region in the x dimension", &status); + FITS_write_key(outfits, TINT, "YORIGIN", &begy2, + "offset of this region in the y dimension", &status); + FITS_write_key(outfits, TINT, "RCOUNT", &rcnt2, + "count of rectangles in this region", &status); + FITS_write_key(outfits, TINT, "MINVAL", &min2, + "minimum value within rectangles", &status); + FITS_write_key(outfits, TINT, "MAXVAL", &max2, + "maximum value within rectangles", &status); + + FITS_write_img(outfits, TSHORT, fpixel, naxes2[0]*naxes2[1], + outbuf2, &status); + /* + * Extension 3 + */ + FITS_create_img(outfits, SHORT_IMG, naxis3, naxes3, &status); + extver = 3; + + FITS_write_key(outfits, TSTRING, "EXTNAME", "HISTOGRAM", + "name of this extension", &status); + FITS_write_key(outfits, TINT, "EXTVER" , &extver, + "extension version number", &status); + FITS_write_key(outfits, TINT, "BZERO" , &bzero, + "image brightness offset", &status); + FITS_write_key(outfits, TINT, "BSCALE" , &bscale, + "image brightness scale", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, + " World Coordinate System and Related Parameters", + &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TFLOAT, "CRPIX1", &fzero, + "x-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRPIX2", &fzero, + "y-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL1", &fzero, + "first axis value at reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL2", &fzero, + "second axis value at reference pixel", &status); + FITS_write_key(outfits, TSTRING, "CTYPE1", "LAMBDA", + "the coordinate type for the first axis", &status); + FITS_write_key(outfits, TSTRING, "CYTPE2", "ANGLE", + "the coordinate type for the second axis", &status); + FITS_write_key(outfits, TFLOAT, "CD1_1", &fzero, + "partial of first axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD1_2", &fzero, + "partial of first axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TFLOAT, "CD2_1", &fzero, + "partial of second axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD2_2", &fzero, + "partial of second axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TDOUBLE, "RA_TARG", &ra_targ, + "RA of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "DEC_TARG", &dec_targ, + "Declination of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "PA_APER", &pa_aper, + "Position Angle of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "EQUINOX", &equinox, + "equinox of celestial coord. system", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " HISTOGRAM REGION PARAMETERS", &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TINT, "XORIGIN", &begx3, + "offset of this region in the x dimension", &status); + FITS_write_key(outfits, TINT, "YORIGIN", &begy3, + "offset of this region in the y dimension", &status); + FITS_write_key(outfits, TINT, "RCOUNT", &rcnt3, + "count of rectangles in this region", &status); + FITS_write_key(outfits, TINT, "MINVAL", &min3, + "minimum value within rectangles", &status); + FITS_write_key(outfits, TINT, "MAXVAL", &max3, + "maximum value within rectangles", &status); + + FITS_write_img(outfits, TSHORT, fpixel, naxes3[0]*naxes3[1], + outbuf3, &status); + /* + * Extension 4 + */ + FITS_create_img(outfits, SHORT_IMG, naxis4, naxes4, &status); + extver = 4; + + FITS_write_key(outfits, TSTRING, "EXTNAME", "HISTOGRAM", + "name of this extension", &status); + FITS_write_key(outfits, TINT, "EXTVER" , &extver, + "extension version number", &status); + FITS_write_key(outfits, TINT, "BZERO" , &bzero, + "image brightness offset", &status); + FITS_write_key(outfits, TINT, "BSCALE" , &bscale, + "image brightness scale", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, + " World Coordinate System and Related Parameters", + &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TFLOAT, "CRPIX1", &fzero, + "x-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRPIX2", &fzero, + "y-coordinate of reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL1", &fzero, + "first axis value at reference pixel", &status); + FITS_write_key(outfits, TFLOAT, "CRVAL2", &fzero, + "second axis value at reference pixel", &status); + FITS_write_key(outfits, TSTRING, "CTYPE1", "LAMBDA", + "the coordinate type for the first axis", &status); + FITS_write_key(outfits, TSTRING, "CYTPE2", "ANGLE", + "the coordinate type for the second axis", &status); + FITS_write_key(outfits, TFLOAT, "CD1_1", &fzero, + "partial of first axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD1_2", &fzero, + "partial of first axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TFLOAT, "CD2_1", &fzero, + "partial of second axis coordinate w.r.t. x", &status); + FITS_write_key(outfits, TFLOAT, "CD2_2", &fzero, + "partial of second axis coordinate w.r.t. y", &status); + FITS_write_key(outfits, TDOUBLE, "RA_TARG", &ra_targ, + "RA of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "DEC_TARG", &dec_targ, + "Declination of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "PA_APER", &pa_aper, + "Position Angle of reference aperture center", &status); + FITS_write_key(outfits, TDOUBLE, "EQUINOX", &equinox, + "equinox of celestial coord. system", &status); + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, " HISTOGRAM REGION PARAMETERS", &status); + FITS_write_comment(outfits, " ", &status); + + FITS_write_key(outfits, TINT, "XORIGIN", &begx4, + "offset of this region in the x dimension", &status); + FITS_write_key(outfits, TINT, "YORIGIN", &begy4, + "offset of this region in the y dimension", &status); + FITS_write_key(outfits, TINT, "RCOUNT", &rcnt4, + "count of rectangles in this region", &status); + FITS_write_key(outfits, TINT, "MINVAL", &min4, + "minimum value within rectangles", &status); + FITS_write_key(outfits, TINT, "MAXVAL", &max4, + "maximum value within rectangles", &status); + + FITS_write_img(outfits, TSHORT, fpixel, naxes4[0]*naxes4[1], + outbuf4, &status); + /* + * Free memory and close the input and output files + */ + free(outbuf1); + free(outbuf2); + free(outbuf3); + free(outbuf4); + free(posx); + free(posy); + + FITS_close_file(outfits, &status); + FITS_close_file(infits, &status); + + return 0; +} diff --git a/src/analysis/cf_wrspec7.c b/src/analysis/cf_wrspec7.c new file mode 100644 index 0000000..979046b --- /dev/null +++ b/src/analysis/cf_wrspec7.c @@ -0,0 +1,58 @@ +/******************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ******************************************************************************* + * + * Synopsis: cf_wrspec7(fitsfile *outfits, long npts, float *wave, float *flux, + * float *error, long *counts, float *weights, + * float *bkgd,short *pothole) + * + * Description: Write a file containing a FUSE 2D spectrum. + * + * Arguments: fitsfile *fname Output FITS file structure + * + * Returns: none + * + * History: 12/15/03 bjg Begin work from cf_wrspec4. + * 01/12/04 bjg Call to fits_create_tbl with nrow=1 + * instead of npts + * 03/22/04 bjg Change POTHOLE to QUALITY + * 03/25/04 bjg Moved time stamp writing to beginning + * of routine + * 04/07/05 v1.1 tc Create a multi-rows table rather than + * a unique vector in a cell + * + ******************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +static char CF_PRGM_ID[] = "cf_wrspec7"; +static char CF_VER_NUM[] = "1.1"; + +void cf_wrspec7(fitsfile *outfits, long npts, float *wave, float *flux, + float *error, long *counts, float *weights,float *bkgd,short *pothole) +{ + char *ttype[] = {"WAVE", "FLUX", "ERROR", "COUNTS", "WEIGHTS", "BKGD", "QUALITY" }; + char *tform[] = {"1E", "1E", "1E", "1J", "1E", "1E", "1I"}; + char *tunit[] = {"ANGSTROMS", "ERG/CM2/S/A", "ERG/CM2/S/A", "COUNTS", "COUNTS", "COUNTS", "UNITLESS"}; + char extname[] = "FUSE 2D Spectrum"; + int tfields = 7, status = 0; + + /* Write time stamp to log file. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, ""); + + fits_create_tbl(outfits, BINARY_TBL, 1, tfields, ttype, tform, tunit, extname, &status); + + /* Write out the data. */ + FITS_write_col(outfits, TFLOAT, 1, 1L, 1L, npts, wave, &status); + FITS_write_col(outfits, TFLOAT, 2, 1L, 1L, npts, flux, &status); + FITS_write_col(outfits, TFLOAT, 3, 1L, 1L, npts, error, &status ); + FITS_write_col(outfits, TLONG, 4, 1L, 1L, npts, counts, &status); + FITS_write_col(outfits, TFLOAT, 5, 1L, 1L, npts, weights, &status); + FITS_write_col(outfits, TFLOAT, 6, 1L, 1L, npts, bkgd, &status); + FITS_write_col(outfits, TSHORT, 7, 1L, 1L, npts, pothole, &status); + +} diff --git a/src/analysis/cf_wrspec_cf2.c b/src/analysis/cf_wrspec_cf2.c new file mode 100644 index 0000000..883c3d5 --- /dev/null +++ b/src/analysis/cf_wrspec_cf2.c @@ -0,0 +1,120 @@ +/******************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ******************************************************************************* + * + * Synopsis: cf_wrspec_cf2(fitsfile *outfits, int npts, float *wave, + * float *spec, float *errs, short *qual, + * float *counts, float *cntserr, int ncol, + * int areaflag); + * + * Description: Write a file containing a FUSE 1D spectrum, in a format + * compatible with Calfuse 2.4 and earlier. + * + * Arguments: char *fname Output file name + * float *wave wavelengths + * float *spec spectrum + * float *errs associated 1-sigma error bars + * short *qual associated quality flags + * float *counts total counts in column + * float *cntserr 1-sigma error bar on total counts + * int ncol specifies 4 or 6 column format + * int areaflag 0 if spectrum column is FLUX + * 1 if spectrum column is AREA + * + * Returns: none + * + * History: 05/04/98 gak Begin work. + * 04/20/99 emm Added FITS_ error checking routines, + * converted qual flags to BYTE. + * 06/07/99 1.2 peb Added reporting of version number. + * 10/22/99 1.3 emm Added total counts column. + * 10/22/99 1.4 emm Added total counts errors column. + * 10/22/99 1.5 emm totcnts and errors are just duplicates + * of flux and error for now + * 10/29/99 1.6 emm counts and cntserr are now read in + * from calling program. + * 12/21/99 1.7 emm Quality flags now short (1I) instead + * of byte char (1B). + * 11/30/01 1.8 wvd Don't write timestamp to log file. + * 03/08/04 1.9 jwk allow tfields=4 or 6, and option to + * change "FLUX" col to "AREA"; for use + * with cf_arith + * 04/05/04 bjg Include string.h + * Write timestamp + * + ******************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "calfuse.h" + +static char CF_PRGM_ID[] = "cf_wrspec_cf2"; +static char CF_VER_NUM[] = "1.9"; + +void cf_wrspec_cf2(fitsfile *outfits, int npts, float *wave, float *spec, + float *errs, short *qual, float *counts, float *cntserr, + int ncol, int areaflag) +{ + char *ttype[] = {"WAVE", "FLUX", "ERROR", "QUALITY", "COUNTS","CNTSERR"}; + char *tform[] = {"1E", "1E", "1E", "1I", "1E", "1E"}; + char *tunit[] = {"ANGSTROMS", "ERG/CM2/S/A", "ERG/CM2/S/A", " ","COUNTS","COUNTS"}; + char extname[] = "FUSE 1D Spectrum"; + int tfields = 6, + status = 0; + long felem = 1, + frow = 1; + +/* Write time stamp to log file. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, ""); + + +/* Create the extension for the data in the output file. + Columns will be + WAVE 1E + FLUX 1E + ERROR 1E + QUALITY 1B + TOTAL COUNTS 1E Same as FLUX column for now + COUNTS ERRORS 1E Same as ERROR column for now +*/ + + if (ncol == 4) + { + tfields = 4; + if (areaflag) + { + strcpy(ttype[1], "AREA"); + strcpy(tunit[1], "CM^2"); + strcpy(tunit[2], "CM^2"); + } + } + + fits_create_tbl (outfits, BINARY_TBL, (long)npts, tfields, ttype, + tform, tunit, extname, &status); + +/* Write out the data. */ + FITS_write_col(outfits, TFLOAT, 1, frow, felem, (long)npts, + wave, &status); + + FITS_write_col(outfits, TFLOAT, 2, frow, felem, (long)npts, + spec, &status); + + FITS_write_col(outfits, TFLOAT, 3, frow, felem, (long)npts, + errs, &status ); + + FITS_write_col(outfits, TSHORT, 4, frow, felem, (long)npts, + qual, &status); + + if (tfields == 6) + { + FITS_write_col(outfits, TFLOAT, 5, frow, felem, (long)npts, + counts, &status); + + FITS_write_col(outfits, TFLOAT, 6, frow, felem, (long)npts, + cntserr, &status); + } + +} diff --git a/src/analysis/cf_xcorr.c b/src/analysis/cf_xcorr.c new file mode 100644 index 0000000..383f281 --- /dev/null +++ b/src/analysis/cf_xcorr.c @@ -0,0 +1,303 @@ +/******************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ******************************************************************************* + * + * Usage: cf_xcorr exposure_list exp_shift_list + * + * Description: Determine pixel shifts between exposures. The + * reference spectrum is the one having the longest exposure + * time. The input list (ASCII) is the set of exposures to process, + * the output list (ASCII) has 3 columns: exposure name, shift and + * sigma_shift. Sigma_shift = -1 corresponds to non-detected shift. + * Sigma_shift = 1 indicates a valid shift value. + * The reference exposure always has shift and sigma_shift of 0. + * + * History: 04/07/05 tc v1.0 First release + * 04/15/05 tc v1.1 Use cf_read_col + * 04/27/05 wvd v1.2 Use variance arrays properly. + * Use QUALITY array to identify + * bad data. + * Change spec array to type INT. + * Use chi2, not reduced chi2, + * to set error bars. + * 05/20/05 wvd v1.3 For continuum spectra, use + * single region between 1045 and + * 1070 A. For emission-line + * targets, use O VI lines. + * 06/03/05 wvd v1.4 Delete unused variables. + * 07/21/05 wvd v1.5 Adopt the sign convention for + * spectral shifts used by + * FUSE_REGISTER. + * 08/01/05 wvd v1.6 Store EXPNIGHT of reference + * spectrum in ref_expnight. + * 09/13/05 wvd v1.7 If called with no arguments, + * return calling info, not error. + * 04/27/06 wvd v1.8 Scale each spectrum to match + * mean of reference spectrum. + * 05/16/06 wvd v1.9 Use Lyman beta to align + * background exposures. + * Use O VI and C II to align WD's. + * 03/28/08 wvd v1.10 Write value of NORM to output. + * For HIST data only: if XCORRR + * fails, but NORM > 0.5, then + * set shift and sigma to 0. + * 08/15/08 wvd v1.11 If EXP_STAT = 2, treat as + * background observation. + * + ******************************************************************************/ + +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +/* Calfuse variables */ +static char CF_PRGM_ID[] = "cf_xcorr"; +static char CF_VER_NUM[] = "1.11"; + +/* Parameters */ +#define MAXSHIFT 20 +#define N_SHIFT 41 + +int main(int argc, char *argv[]) +{ + /* Variables */ + char *spec_lis, *out_name, src_type[FLEN_VALUE]; + char spec_name[FLEN_FILENAME], ref_spec_name[FLEN_FILENAME]; + char program[FLEN_VALUE]; + char instmode[FLEN_CARD] ; + double *ref_flux, *ref_error, *flux, *error; + double scale, sum, variance, norm, ref_tot, total; + float chi_square[N_SHIFT], chi_square_min, chi_square_max; + float exptime, exptime_max; + float *wave, w0, wpc, wmin, wdelta; + int ly_beta=FALSE, exp_stat, objclass, shift, sigma; + int ind_chi2_min, N, N_tmp, nchi, n_spec, ind_ref_spec=0; + long expnight, ref_expnight, i, k, n_pix, ref_start, start; + + FILE *pt_file, *pt_file_out; + fitsfile *in_fits; + int status = 0, hdutype = 0; + + /*********************************** + ** 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, stderr); + + + /*********************************************************** + ** Check for proper command-line usage and read arguments ** + ***********************************************************/ + if (argc != 3) { + printf("Usage: cf_xcorr exposure_list exp_shift_list\n"); + return(0); + } + + spec_lis = argv[1]; + out_name = argv[2]; + + /******************************************** + ** Open input list and create output file ** + ********************************************/ + if ((pt_file = fopen(spec_lis, "r")) == NULL) + { + cf_if_error("Unable to open file %s", spec_lis); + } + pt_file_out = fopen(out_name, "w"); + + /******************************************************************** + ** Set the reference spectrum to the one which has maximum EXPTIME ** + ********************************************************************/ + n_spec = 0; + exptime_max = -1; + + while (fscanf(pt_file, "%80s", spec_name) != EOF) + { + FITS_open_file(&in_fits, spec_name, READONLY, &status); + FITS_read_key(in_fits, TFLOAT, "EXPTIME", &exptime, NULL, &status); + FITS_read_key(in_fits, TLONG, "EXPNIGHT", &expnight, NULL, &status); + FITS_close_file(in_fits, &status); + if (exptime > exptime_max) + { + exptime_max = exptime; + ind_ref_spec = n_spec; + strcpy(ref_spec_name, spec_name); + } + n_spec++; + } + + if (n_spec == 0) cf_if_error("At least one spectrum is required"); + + if (n_spec == 1) + { + fprintf(pt_file_out, "%s %2d %2d %5.0f %5ld %c%c%c 1.0\n", ref_spec_name, 0, 0, + exptime_max, expnight, ref_spec_name[8], ref_spec_name[9], ref_spec_name[10]); + fclose(pt_file_out); + return(0); + } + printf("n_spec: %d, max exptime: %g, ind_ref: %d, ref_name: %s\n", + n_spec, exptime_max, ind_ref_spec, ref_spec_name); + + /* Read source type and set XCORR limits accordingly. */ + FITS_open_file(&in_fits, ref_spec_name, READONLY, &status); + FITS_read_key(in_fits, TINT, "EXP_STAT", &exp_stat, NULL, &status); + FITS_read_key(in_fits, TSTRING, "PRGRM_ID", &program, NULL, &status); + FITS_read_key(in_fits, TINT, "OBJCLASS", &objclass, NULL, &status); + FITS_read_key(in_fits, TSTRING, "SRC_TYPE", &src_type, NULL, &status); + FITS_read_key(in_fits, TSTRING, "INSTMODE", instmode, NULL, &status) ; + FITS_read_key(in_fits, TFLOAT, "W0", &w0, NULL, &status); + FITS_read_key(in_fits, TFLOAT, "WPC", &wpc, NULL, &status); + if (src_type[1] == 'E') { /* Emission-line source */ + /* Use Lyman beta to align background observations. */ + if (exp_stat == (int) TEMPORAL_LIMB || + objclass == 1 || objclass == 7 || objclass == 90) { + printf("Assuming background observation.\n"); + wmin = 1024.; + wdelta = 6.; + ly_beta = TRUE; + } else { /* Use O VI emission for everything else. */ + printf("SRC_TYPE = %s. Emission-line target.\n", src_type); + wmin = 1030.; + wdelta = 9.; + } + } + else if (objclass == 17 || objclass == 29 || objclass == 37) { + /* Use O VI and C II to align white dwarf spectra. */ + printf("OBJCLASS = %d. Assuming nearby white dwarf.\n", objclass); + wmin = 1030.; + wdelta = 9.; + } + else { /* Use 1045-1070 A region for all other continuum sources. */ + printf("SRC_TYPE = %s. Assuming continuum target.\n", src_type); + wmin = 1045.; + wdelta = 25.; + } + start = cf_nlong((wmin - w0) / wpc); + ref_start = start + MAXSHIFT; + n_pix = cf_nlong(wdelta / wpc) - (N_SHIFT - 1); + + /* Read wave, flux, and error arrays from reference exposure. */ + FITS_read_key(in_fits, TLONG, "EXPNIGHT" , &ref_expnight, NULL, &status); + FITS_movabs_hdu(in_fits, 2, &hdutype, &status); + if (hdutype != BINARY_TBL) cf_if_error("FITS files must contain BINARY TABLE in HDU #2"); + N = cf_read_col(in_fits, TFLOAT, "WAVE", (void **) &wave); + N = cf_read_col(in_fits, TDOUBLE, "FLUX", (void **) &ref_flux); + N = cf_read_col(in_fits, TDOUBLE, "ERROR", (void **) &ref_error); + FITS_close_file(in_fits, &status); + + /* Compute total flux of reference spectrum in region of interest. */ + ref_tot = 0.; + for (i = 0; i < n_pix; i++) ref_tot += ref_flux[start+i]; + + /***************************************************************** + ** Compute the shift of each spectrum relative to the reference ** + ******************************************************************/ + n_spec = 0; + rewind(pt_file); + + while (fscanf(pt_file, "%80s", spec_name) != EOF) + { + /* Do nothing if the current spectrum is the reference. */ + if (n_spec++ == ind_ref_spec) { + fprintf(pt_file_out, "%s %3d %2d %5.0f %5ld %c%c%c 1.0\n", + ref_spec_name, 0, 0, exptime_max, ref_expnight, + ref_spec_name[8], ref_spec_name[9], ref_spec_name[10]); + continue; + } + + /* Read the next spectrum */ + FITS_open_file(&in_fits, spec_name, READONLY, &status); + FITS_read_key(in_fits, TFLOAT, "EXPTIME", &exptime, NULL, &status); + FITS_read_key(in_fits, TLONG, "EXPNIGHT", &expnight, NULL, &status); + FITS_movabs_hdu(in_fits, 2, &hdutype, &status); + if (hdutype != BINARY_TBL) cf_if_error("FITS files must contain BINARY TABLE in HDU #2"); + N_tmp = cf_read_col(in_fits, TDOUBLE, "FLUX", (void **) &flux); + N_tmp = cf_read_col(in_fits, TDOUBLE, "ERROR", (void **) &error); + if (N_tmp != N) cf_if_error("Tables must have the same number of elements"); + FITS_close_file(in_fits, &status); + + /* If EXPTIME < 1, move on to the next data file. */ + if (exptime < 1) { + fprintf(pt_file_out, "%s %3d %2d %5.0f %5ld %c%c%c 0.0\n", + spec_name, 0, -1, exptime, expnight, + spec_name[8], spec_name[9], spec_name[10]); + continue; + } + + /* Compute total flux of data spectrum in region of interest. */ + norm = 1.; + if (!ly_beta) { /* Don't rescale if aligning on airglow. */ + total = 0.; + for (i = 0; i < n_pix; i++) total += flux[start+i]; + norm = ref_tot / total; + } + + /* Compute chi-squared for shifts between +/- MAXSHIFT pixels. */ + for (k = 0; k < N_SHIFT; k++) { + nchi = 0; + sum = 0; + for (i = 0; i < n_pix; i++) { + variance = ref_error[ref_start + i] * ref_error[ref_start + i] + + norm * norm * error[start + i + k] * error[start + i + k]; + if (variance > 0) { + sum += (ref_flux[ref_start + i] - norm * flux[start + i + k]) * + (ref_flux[ref_start + i] - norm * flux[start + i + k]) / variance; + nchi++; + } + } + scale = (double) nchi / n_pix; + chi_square[k] = sum / scale; + } + + /* Compute min and max values of chi-squared. */ + ind_chi2_min = 0; + chi_square_min = 1E5; + chi_square_max = -1E5; + for (k = 0; k < N_SHIFT; k++) { + if (chi_square[k] < chi_square_min) + { + chi_square_min = chi_square[k]; + ind_chi2_min = k; + } + else if (chi_square[k] > chi_square_max) + chi_square_max = chi_square[k]; + } + shift = MAXSHIFT - ind_chi2_min; + + /* If chi-squared changes by less than 20% over range of shifts, bail out. + * Otherwise, return shift corresponding to lowest value of chi-square. */ + if (chi_square_max / chi_square_min < 1.2) + sigma = -1; + else + sigma = 1; + + + /* If we're in HIST mode and sigma = -1 and NORM < 2, + * then set shift = sigma = 0. */ + if (!(strncasecmp(instmode, "HIST", 4)) && sigma == -1 && norm < 2.0) + shift = sigma = 0; + + /* printf ("shift = %d\tchi_square_max / chi_square_min = %g\n", + ind_chi2_min - MAXSHIFT, chi_square_max / chi_square_min); */ + + fprintf(pt_file_out, "%s %3d %2d %5.0f %5ld %c%c%c %f\n", + spec_name, shift, sigma, exptime, expnight, + spec_name[8], spec_name[9], spec_name[10], norm); + + free(flux); + free(error); + } + + free(wave); + free(ref_flux); + free(ref_error); + + fclose(pt_file); + fclose(pt_file_out); + + return(0); +} diff --git a/src/analysis/extract_jitter.c b/src/analysis/extract_jitter.c new file mode 100644 index 0000000..a4ceb4d --- /dev/null +++ b/src/analysis/extract_jitter.c @@ -0,0 +1,198 @@ + +/************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ************************************************************************* + * + * + * Usage: + * extract_jitter [-h] [-v level] input_file + * + * + * + * Arguments: + * input_file : jitter file + * + * + * + * + * + * + * Options: + * -h: this help message + * -v: verbosity level (=1; 0 is silent) + * + * + * + * + * History: 11/04/2004 v1.0 bjg + * 06/03/2005 v1.1 wvd Fix bug that set expstart=expend. + * Delete unused variables. + * + ***************************************************************************/ + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#include "calfuse.h" + + +static char CF_PRGM_ID[]= "extract_jitter"; +static char CF_VER_NUM[]= "1.0"; + + +int main(int argc,char *argv[]){ + + + + char input_filename[FLEN_CARD]; + char output_filename_x[FLEN_CARD]; + char output_filename_y[FLEN_CARD]; + + FILE * output_file_x; + FILE * output_file_y; + + fitsfile * infits; + + + + int intnull=0,anynull; + int status=0; + int hdutype=0; + + long i, N; + int ncol; + + double * hdu2_time; + double * hdu2_dx; + double * hdu2_dy; + int * hdu2_trkflg; + + + + double mjd,dx,dy; + + int trkflg; + + double expstart, expend; + + int optc; + + char opts[] = "hfv:"; + char usage[] = + "Usage:\n" + " extract_jitter [-h] [-v level] input_file\n\n" + "Arguments:\n" + " input_file : jitter file (FITS)\n\n"; + char option[] = + "Options:\n" + " -h: this help message \n" + " -v: verbosity level (=1; 0 is silent) \n"; + + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s", usage, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc != optind+1) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + strcpy(input_filename,argv[optind]); + + + + strcpy(output_filename_x,input_filename); + strcpy(output_filename_y,input_filename); + strcat(output_filename_x,".jtx"); + strcat(output_filename_y,".jty"); + + + /* Create the output file */ + output_file_x = fopen(output_filename_x,"w"); + output_file_y = fopen(output_filename_y,"w"); + + + + FITS_open_file(&infits,input_filename,READONLY,&status); + + FITS_read_key(infits,TDOUBLE,"EXPSTART",&expstart,NULL,&status); + FITS_read_key(infits,TDOUBLE,"EXPEND",&expend,NULL,&status); + + FITS_movabs_hdu(infits,2,&hdutype,&status); + + FITS_read_key(infits,TLONG,"NAXIS2",&N,NULL,&status); + + hdu2_time=(double *)malloc(N*sizeof(double)); + hdu2_dx=(double *)malloc(N*sizeof(double)); + hdu2_dy=(double *)malloc(N*sizeof(double)); + hdu2_trkflg=(int *)malloc(N*sizeof(int)); + + FITS_get_colnum(infits, TRUE, "TIME", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, N, &intnull, + hdu2_time, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "DX", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, N, &intnull, + hdu2_dx, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "DY", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, N, &intnull, + hdu2_dy, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "TRKFLG", &ncol, &status); + FITS_read_col(infits, TINT, ncol, 1, 1, N, &intnull, + hdu2_trkflg, &anynull, &status); + + + for (i=0;i<N-100;i++){ + mjd=expstart+(hdu2_time[i])/(3600.0*24.0); + dx=hdu2_dx[i]; + dy=hdu2_dy[i]; + trkflg=hdu2_trkflg[i]; + + if ((mjd>=expstart) && (mjd<=expend) && (trkflg==5)){ + fprintf(output_file_x,"%15lf %15lf\n",mjd,dx); + fprintf(output_file_y,"%15lf %15lf\n",mjd,dy); + } + } + + + + free(hdu2_time); + free(hdu2_dx); + free(hdu2_dy); + free(hdu2_trkflg); + + + + FITS_close_file(infits,&status); + + fclose(output_file_x); + fclose(output_file_y); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} diff --git a/src/analysis/get_shift.c b/src/analysis/get_shift.c new file mode 100644 index 0000000..a4c2b70 --- /dev/null +++ b/src/analysis/get_shift.c @@ -0,0 +1,164 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: getshift spec1 spec2 w1 w2 + * + * Description: Computes the wavelength shift between the spectra from two + * different exposures spec1 and spec2 using a cross-correlation + * in the wavelength window defined by w1 and w2 + * + * + * History: 01/08/04 bjg 1.0 begin work + * 04/05/04 bjg 1.1 Return EXIT_SUCCESS + * Correct formats to match + * argument types in printf + * 08/26/05 wvd 1.2 If given no arguments, don't return error. + * Just print message and exit. + * + ****************************************************************************/ + +#include <time.h> +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + + +#define MAXSHIFT 25 +#define SMOOTH_PAR 4 + + +static char CF_PRGM_ID[] = "get_shift"; +static char CF_VER_NUM[] = "1.2"; + + +int wave_search(float *table, int i, int j, float elmt){ + + int k; + + if (i>=j) return i; + if (elmt==table[i]) return i; + if (elmt==table[j]) return j; + k=(i+j)/2; + if (elmt==table[k]) return k; + if ((elmt-table[i])*(elmt-table[k])<0) return wave_search(table,i,k,elmt); + return wave_search(table,k+1,j,elmt); +} + +int main(int argc, char *argv[]) +{ + + int status=0; + int hdutype=0; + + long n,n1,n2,laux,i,j,k; + + float *wave, *flux1, *flux2, *flux1s, *flux2s; + + float w1,w2; + + fitsfile *infits1, *infits2; + + float correl[2*MAXSHIFT+1]; + + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin Processing"); + + /* Initialize error checking */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + + /* check command line */ + if (argc != 5) { + printf("Usage: getshift spec1 spec2 w1 w2 \n"); + return 1; + } + + + FITS_open_file(&infits1, argv[1], READONLY, &status); + FITS_open_file(&infits2, argv[2], READONLY, &status); + + sscanf(argv[3],"%f",&w1); + sscanf(argv[4],"%f",&w2); + + + FITS_movabs_hdu(infits1, 2, &hdutype, &status); + FITS_movabs_hdu(infits2, 2, &hdutype, &status); + + + n=cf_read_col(infits1,TFLOAT,"WAVE",(void **) &wave); + n=cf_read_col(infits1,TFLOAT,"FLUX",(void **) &flux1); + n=cf_read_col(infits2,TFLOAT,"FLUX",(void **) &flux2); + + + flux1s=(float*)malloc(n*sizeof(float)); + flux2s=(float*)malloc(n*sizeof(float)); + + + for (i=0;i<n;i++){ + flux1s[i]=0; + flux2s[i]=0; + k=0; + for (j=i-SMOOTH_PAR;j<=i+SMOOTH_PAR;j++){ + if ((j>=0)&&(j<n)) { + flux1s[i]+=flux1[j]; + flux2s[i]+=flux2[j]; + k=k+1; + } + } + flux1s[i]/=k; + flux2s[i]/=k; + + + } + + + + if ((w1-wave[0])*(w1-wave[n-1])>0) + cf_if_error("Wavelength parameters out of range\n"); + + if ((w2-wave[0])*(w2-wave[n-1])>0) + cf_if_error("Wavelength parameters out of range\n"); + + n1=wave_search(wave,0,n-1,w1); + n2=wave_search(wave,0,n-1,w2); + + + if (n1>n2) { + laux=n2; + n2=n1; + n1=laux; + } + + if ((n1-MAXSHIFT<0)||(n2+MAXSHIFT>=n)) + cf_if_error("Wavelength parameters too close to bounds\n"); + + k=0; + + for (i=0;i<=2*MAXSHIFT;i++){ + correl[i]=0; + for (j=n1;j<=n2;j++){ + correl[i]=correl[i]+flux1s[j]*flux2s[j+i-MAXSHIFT]; + } + if (correl[i]>correl[k]) k=i; + } + + + + FITS_close_file(infits1, &status); + FITS_close_file(infits2, &status); + + /* Enter a timestamp into the log. */ + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Done processing"); + + printf("Shift is %ld steps.\n",k-MAXSHIFT); + + return EXIT_SUCCESS; + + +} diff --git a/src/analysis/gethmjd.c b/src/analysis/gethmjd.c new file mode 100644 index 0000000..dcb3cdb --- /dev/null +++ b/src/analysis/gethmjd.c @@ -0,0 +1,98 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * + * From Modified Julian Day and RA,DEC of target, + * computes Heliocentic Modified Julian Day + * + * Uses slalib to compute the light time delay along the target direction. + * + * + * History: 10/06/04 bjg + * + ****************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#ifdef CFORTRAN +#include "cfortran.h" + +PROTOCCALLSFSUB6(SLA_DJCL, sla_djcl, DOUBLE, PINT, PINT, PINT, PDOUBLE, \ + PINT) +#define slaDjcl(DJM, IY, IM, ID, FD, J) \ + CCALLSFSUB6(SLA_DJCL, sla_djcl, DOUBLE, PINT, PINT, PINT, PDOUBLE, \ + PINT, DJM, IY, IM, ID, FD, J) + + +PROTOCCALLSFSUB6(SLA_CALYD, sla_calyd, INT, INT, INT, PINT, PINT, \ + PINT) +#define slaCalyd(IY, IM, ID, NY, ND, J) \ + CCALLSFSUB6(SLA_CALYD, sla_calyd, INT, INT, INT, PINT, PINT, \ + PINT, IY, IM, ID, NY, ND, J) + +PROTOCCALLSFSUB7(SLA_ECOR, sla_ecor, FLOAT, FLOAT, INT, INT, FLOAT, PFLOAT, \ + PFLOAT) +#define slaEcor(RM, DM, IY, ID, FD, RV, TL) \ + CCALLSFSUB7(SLA_ECOR, sla_ecor, FLOAT, FLOAT, INT, INT, FLOAT, PFLOAT, \ + PFLOAT, RM, DM, IY, ID, FD, RV, TL) + +#else +#include "slalib.h" +#include "slamac.h" +#endif + + +#include "calfuse.h" + + +#define DEG2RAD (M_PI/180.0f) + +double gethmjd(double mjd, int ra_h, int ra_m, float ra_s, int dec_d, int dec_m, float dec_s){ + + + int status; + + int year, month, day; + int jyear, jday; + double frac; + + + float ra, dec; + float lt, v; + + ra = ( ra_h + ra_m/60.0 + ra_s/3600.0 ) * 15.0 * DEG2RAD; + dec = ( dec_d + dec_m/60.0 + dec_s/3600.0 ) * DEG2RAD; + + +#ifdef CFORTRAN + slaDjcl(mjd, year, month, day, frac, status); +#else + slaDjcl(mjd, &year, &month, &day, &frac, &status); +#endif + +#ifdef CFORTRAN + slaCalyd(year, month, day, jyear, jday, status); +#else + slaCalyd(year, month, day, &jyear, &jday, &status); +#endif + +#ifdef CFORTRAN + slaEcor(ra, dec, jyear, jday, (float) frac, v, lt); +#else + slaEcor(ra, dec, jyear, jday, (float) frac, &v, <); +#endif + + return (double) (mjd+lt/(3600.0*24.0)); + +} diff --git a/src/analysis/idf_combine.c b/src/analysis/idf_combine.c new file mode 100644 index 0000000..3f1a678 --- /dev/null +++ b/src/analysis/idf_combine.c @@ -0,0 +1,945 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: idf_combine outfile file1 file2 file3 file4 file5 ... + * + * Description: Reads multiple contiguous idf files and concatenates them + * into a single file. + * + * History: 08/11/03 bjg Begin work from ttag_combine.c + * sort the input files in time order + * 08/12/03 bjg v1.0 First usable version + * 08/13/03 bjg Some minor changes + * 08/14/03 bjg Fixed some important keywords + * in the main HDU + * 08/20/03 bjg v1.1 Changed the way the binary tables + * are read, created and written + * (same as cf_ttag_init) + * 09/09/03 bjg v1.2 Fixed some keywords + * 10/29/03 bjg Changed the scaling format for + * output timeline to conform the + * new IDF formatting. + * 11/17/03 bjg v1.3 Now warns users if the Focal + * Plane Assembly has moved between + * exposures. + * 11/22/03 bjg Now prints the name of the + * included files in the main + * header. + * 12/10/03 bjg Updated NSPEC keyword and + * SPECxxx, WOFFLxxx, WOFFSxxx keywords + * Removed path in filenames written + * into header. + * 02/25/04 bjg Bug fix + * 03/25/04 bjg Added TZERO and TSCALE values for + * AIC and FEC countrates + * 04/05/04 bjg Remove unused variables + * Change formats to match arg types + * in printf + * Remove static keyword in struct key + * definition + * Add braces in TSCAL and TZERO + * definitions + * 06/08/04 bjg Changes to handle EXP_STAT keyword + * 08/13/04 bjg v1.4 Recalculates Y centroid on demand + * 10/06/04 bjg v1.5 Added option -b to store + * ORBITAL_VEL in a float + * 10/26/04 bjg v1.6 Cosmetic change + * 01/28/2005 bjg v1.7 Fixed crash within CFITSIO with + * with IDF files having empty tables + * 02/16/2005 wvd v1.8 Double TSCALE and TZERO + * for the AIC_CNT_RATE array. + * 03/22/2005 wvd v1.9 Read and write TIME_SUNRISE + * and TIME_SUNSET as shorts. + * 04/15/2005 tc v1.10 Update PLANTIME keyword + * 06/08/2005 tc v1.11 Comment out warning if FPA has + * shifted. Pipeline corrects for this. + * 09/19/2005 wvd v1.12 Don't even read FPA positions. + * 05/22/2006 wvd v1.13 Change most header keyword + * types from float to long. + * 06/22/2006 wvd v1.14 Add -z flag to force creation of + * an output file, even if empty. + * 11/10/2006 wvd v1.15 Add comment fields to WOFFS and + * WOFFL keywords. + * 08/27/2007 bot v1.16 Changed long for int l.138 + * 07/25/2008 wvd v1.17 Set output EXP_STAT keyword to lowest + * non-negative value among input files. + * 08/22/2008 wvd v1.18 If -a flag is set, include files with + * positive values of EXP_STAT, but not + * those with negative values. + * + ****************************************************************************/ + + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include "calfuse.h" + +typedef char filename[FLEN_CARD]; + +struct key { + char keyword[FLEN_KEYWORD]; + float value; +}; + +static char CF_PRGM_ID[]= "idf_combine"; +static char CF_VER_NUM[]= "1.18"; + +int main(int argc,char *argv[]){ + + char date[FLEN_CARD]={'\0'}; + char rootname[FLEN_CARD]; + char comment[FLEN_COMMENT]; + + int felem_hdu2,felem_hdu4,frow_hdu3; + + char stime[FLEN_CARD],keyword[FLEN_CARD],card[FLEN_CARD]; + + char fmt_byte[FLEN_CARD],fmt_float[FLEN_CARD],fmt_short[FLEN_CARD]; + + char *corrected_filename; + char *string_pointer; + char string0[100], string1[100]; + + time_t vtime; + + fitsfile *infits,*outfits; + + filename *filelist; + double *expstartlist; + double *expendlist; + long *neventslist; + long *nrecordslist; + long *ngtislist; + + double delta_t; + + float zero=0.0; + + filename tempstring; + double tempdouble; + long templong; + float tempfloat; + char tempchar; + + double minexpstart; + int minindex; + + int nfiles; + + int intnull=0,anynull; + int ncol; + + int status=0; + int hdutype=0; + int tref = 0; + + int n2; + + int exp_stat, exp_stat_out=99; + + long nevents=0, nrecords=0, ngtis=0; + long n_real_events=0; + + long i,j; + + float *floatlist; + short *shortlist; + char *charlist; + double *doublelist; + + float exptime=0, rawtime=0; + long neventscreened=0, neventscreenedpha=0, plantime=0, timehv=0; + long timescreened=0, timesaa=0, timelowlimbangle=0, timeburst=0, + timejitter=0,timenight=0; + + /* float fpasx0, fpasx, fpalx0, fpalx, dfpasx, dfpalx ; */ + /* int fpa_split = FALSE; */ + + int hdu2_tfields=14; + + char hdu2_extname[]="TTAG DATA"; /* Name of this extension */ + + char *hdu2_ttype[]={"TIME", "XRAW", "YRAW", "PHA", "WEIGHT", "XFARF", + "YFARF", "X", "Y", "CHANNEL", "TIMEFLGS", + "LOC_FLGS", "LAMBDA", "ERGCM2" }; + + char *hdu2_tform[14]; /* We'll assign values when we know + the number of elements in the data set. */ + + + char *hdu2_tunit[]={"SECONDS", "PIXELS", "PIXELS", "UNITLESS", "UNITLESS", + "PIXELS", "PIXELS", "PIXELS", "PIXELS", "UNITLESS", + "UNITLESS", "UNITLESS", "ANGSTROMS", "ERG CM^-2"}; + + struct key hdu2_tscal[] = {{"TSCAL6", 0.25}, {"TSCAL7", 0.1}, + {"TSCAL8", 0.25}, {"TSCAL9", 0.1}}; + + struct key hdu2_tzero[] = {{"TZERO6", 8192.}, {"TZERO7", 0.}, + {"TZERO8", 8192.}, {"TZERO9", 0.}}; + + + + + int hdu3_tfields=2; + + char hdu3_extname[]="GTI"; /* Name of this extension */ + + char *hdu3_ttype[]={"START", "STOP" }; + + char *hdu3_tform[2]={"1D", "1D" }; /* We'll assign values when we know + the number of elements in the data set. */ + + + char *hdu3_tunit[]={"seconds", "seconds"}; + + struct key hdu4_tscal[16]; + struct key hdu4_tzero[16]; + + char hdu4_extname[]="TIMELINE"; + int hdu4_tfields=16; /* output table will have 16 columns */ + char *hdu4_ttype[]={"TIME", "STATUS_FLAGS", "TIME_SUNRISE", "TIME_SUNSET", + "LIMB_ANGLE", "LONGITUDE", "LATITUDE", "ORBITAL_VEL", + "HIGH_VOLTAGE", "LIF_CNT_RATE", "SIC_CNT_RATE", + "FEC_CNT_RATE", "AIC_CNT_RATE", "BKGD_CNT_RATE", + "YCENT_LIF","YCENT_SIC"}; + + char *hdu4_tform[16]; /* we will define tform later, when the number + of photons is known */ + + char *hdu4_tunit[]={"seconds", "unitless", "seconds", "seconds", "degrees", + "degrees", "degrees", "km/s", "unitless", "counts/sec", + "counts/sec", "counts/sec", "counts/sec", "counts/sec", + "pixels","pixels" }; + + + int ignore_exp_stat=0; + int do_ycent=0; + int big_vel=0; + int do_empty=FALSE, empty_output=FALSE; + + float *x=NULL, *y=NULL, *weight=NULL; + unsigned char *channel=NULL, *timeflags=NULL, *locflags=NULL; + + int optc; + + char opts[] = "hacbv:z"; + char usage[] = + "Usage:\n" + " idf_combine [-ahbcz] [-v level] output_idf_file input_idf_files\n"; + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n" + " -a: ignore EXP_STAT keyword \n" + " -c: recalculates Y centroids (use target events) \n" + " -b: store ORBITAL_VEL in a float \n" + " -z: if no good data, generate empty output file\n"; + + verbose_level = 1; + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + + case 'h': + printf("%s\n%s", usage, option); + return 0; + case 'a': + ignore_exp_stat=1; + break; + case 'v': + verbose_level = atoi(optarg); + break; + case 'c': + do_ycent=1; + break; + case 'b': + big_vel=1; + break; + case 'z': + do_empty=TRUE; + break; + } + } + + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + if (argc < optind+2) { + printf("%s", usage); + return 1; + } + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + /* get and display time */ + vtime = time(NULL) ; + strcpy(stime,ctime(&vtime)); + + + nfiles=argc-optind-1; + + filelist = (filename *)cf_calloc(nfiles, sizeof(filename)); + expstartlist = (double *)cf_calloc(nfiles, sizeof(double)); + expendlist = (double *)cf_calloc(nfiles, sizeof(double)); + neventslist = (long *)cf_calloc(nfiles, sizeof(long)); + nrecordslist = (long *)cf_calloc(nfiles, sizeof(long)); + ngtislist = (long *)cf_calloc(nfiles, sizeof(long)); + + if (!ignore_exp_stat) + cf_verbose(1,"Will include only files with EXP_STAT=0") ; + else + cf_verbose(1,"Will include only files with EXP_STAT >= 0") ; + + cf_verbose(1,"GETTING INFORMATION ON INPUT FILES") ; + + n2=0; + + for (i=0; i<nfiles;i++) { + + FITS_open_file(&infits,argv[optind+i+1],READONLY,&status); + + FITS_read_key(infits,TINT,"EXP_STAT",&exp_stat,NULL,&status); + + strcpy(filelist[n2],argv[optind+i+1]); + FITS_read_key(infits,TDOUBLE,"EXPSTART",&(expstartlist[n2]),NULL,&status); + FITS_read_key(infits,TDOUBLE,"EXPEND",&(expendlist[n2]),NULL,&status); + + /* Set EXP_STAT to lowest non-negative value in input files. */ + if (exp_stat_out > exp_stat && exp_stat >= 0) exp_stat_out = exp_stat; + + /* Skip files with bad values of EXP_STAT. */ + if (!ignore_exp_stat && exp_stat != 0) { + cf_if_warning("File %s rejected. EXP_STAT not equal to zero. Use -a flag to override.", + argv[optind+i+1]) ; + FITS_close_file(infits,&status); + continue; + } + /* Never include files with negative values of EXP_STAT. */ + else if (exp_stat < 0) { + cf_if_warning("File %s rejected. EXP_STAT less than zero.", argv[optind+i+1]) ; + FITS_close_file(infits,&status); + continue; + } + + FITS_read_key(infits,TFLOAT,"EXPTIME",&(tempfloat),NULL,&status); + exptime+=tempfloat; + FITS_read_key(infits,TLONG,"NEVENTS",&templong,NULL,&status); + n_real_events+=templong; + FITS_read_key(infits,TFLOAT,"RAWTIME",&(tempfloat),NULL,&status); + rawtime+=tempfloat; + FITS_read_key(infits,TLONG,"PLANTIME",&(templong),NULL,&status); + plantime+=tempfloat; + + FITS_read_key(infits,TLONG,"NBADEVNT",&templong,NULL,&status); + neventscreened+=templong; + FITS_read_key(infits,TLONG,"NBADPHA",&templong,NULL,&status); + neventscreenedpha+=templong; + + FITS_read_key(infits,TLONG,"EXP_BAD",&templong,NULL,&status); + timescreened+=templong; + FITS_read_key(infits,TLONG,"EXP_BRST",&templong,NULL,&status); + timeburst+=templong; + FITS_read_key(infits,TLONG,"EXP_HV",&templong,NULL,&status); + timehv+=templong; + FITS_read_key(infits,TLONG,"EXP_JITR",&templong,NULL,&status); + timejitter+=templong; + FITS_read_key(infits,TLONG,"EXP_LIM",&templong,NULL,&status); + timelowlimbangle+=templong; + FITS_read_key(infits,TLONG,"EXP_SAA",&templong,NULL,&status); + timesaa+=templong; + FITS_read_key(infits,TLONG,"EXPNIGHT",&templong,NULL,&status); + timenight+=templong; + + FITS_movabs_hdu(infits,2,&hdutype,&status); + FITS_read_key(infits,TSTRING,"TFORM1",&tempstring,NULL,&status); + sscanf(tempstring,"%ld%c",&neventslist[n2],&tempchar); + nevents+=neventslist[n2]; + + FITS_movabs_hdu(infits,3,&hdutype,&status); + FITS_read_key(infits,TLONG,"NAXIS2",&(ngtislist[n2]),NULL,&status); + ngtis+=ngtislist[n2]; + + FITS_movabs_hdu(infits,4,&hdutype,&status); + FITS_read_key(infits,TSTRING,"TFORM1",&tempstring,NULL,&status); + sscanf(tempstring,"%ld%c",&nrecordslist[n2],&tempchar); + nrecords+=nrecordslist[n2]; + + FITS_close_file(infits,&status); + + n2++; + } + + nfiles=n2; + + if (nfiles==0){ + if (do_empty) { + cf_verbose(1,"No files to combine. Generating empty output file."); + do_ycent = FALSE; + empty_output = TRUE; + expendlist[0]=expstartlist[0]; + nfiles = 1; + } + else { + cf_verbose(1,"No files to combine. Exiting."); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + exit(0); + } + } + + cf_verbose(1,"SORTING INPUT FILES IN TIME ORDER") ; + + for (i=0; i<nfiles-1;i++) { + minexpstart=expstartlist[i]; + minindex=i; + for (j=i+1; j<nfiles;j++) { + if (expstartlist[j]<minexpstart){ + minexpstart=expstartlist[j]; + minindex=j; + } + } + + strcpy(tempstring,filelist[minindex]); + strcpy(filelist[minindex],filelist[i]); + strcpy(filelist[i],tempstring); + + tempdouble=expstartlist[minindex]; + expstartlist[minindex]=expstartlist[i]; + expstartlist[i]=tempdouble; + + tempdouble=expendlist[minindex]; + expendlist[minindex]=expendlist[i]; + expendlist[i]=tempdouble; + + templong=neventslist[minindex]; + neventslist[minindex]=neventslist[i]; + neventslist[i]=templong; + + templong=nrecordslist[minindex]; + nrecordslist[minindex]=nrecordslist[i]; + nrecordslist[i]=templong; + + templong=ngtislist[minindex]; + ngtislist[minindex]=ngtislist[i]; + ngtislist[i]=templong; + } + + cf_verbose(2, + "N: Filename ExpStart ExpEnd NEvents NGTIs NSeconds"); + + for (i=0; i<nfiles;i++) { + cf_verbose(2,"%ld: %s %7.1f %7.1f %4ld %2ld %5ld",i,filelist[i], + expstartlist[i],expendlist[i],neventslist[i],ngtislist[i], + nrecordslist[i]); + + } + + cf_verbose(1,"CREATING OUTPUT FILE"); + + FITS_open_file(&infits,filelist[0],READONLY,&status); + FITS_create_file(&outfits,argv[optind],&status); + + + cf_verbose(1,"WRITING MAIN HEADER"); + + FITS_copy_hdu(infits,outfits,0,&status); + + FITS_read_key(infits,TSTRING,"ROOTNAME",rootname,NULL,&status); + + rootname[8]='9'; + rootname[9]='9'; + rootname[10]='9'; + + FITS_update_key(outfits,TSTRING,"ROOTNAME",rootname,NULL,&status); + + string_pointer=strrchr(argv[optind],'/'); + if (string_pointer==NULL) corrected_filename=argv[optind]; + else corrected_filename=&(string_pointer[1]); + + FITS_update_key(outfits,TINT,"EXP_STAT",&exp_stat_out,NULL,&status); + + FITS_update_key(outfits,TSTRING,"FILENAME",corrected_filename,NULL,&status); + + FITS_update_key(outfits,TSTRING,"EXP_ID","999",NULL,&status); + + fits_get_system_time(date, &tref, &status); + + FITS_update_key(outfits,TSTRING,"DATE",date,NULL,&status); + + FITS_update_key(outfits,TDOUBLE,"EXPEND",&expendlist[nfiles-1],NULL,&status); + FITS_update_key(outfits,TFLOAT,"EXPTIME",&exptime,NULL,&status); + FITS_update_key(outfits,TLONG,"NEVENTS",&n_real_events,NULL,&status); + FITS_update_key(outfits,TFLOAT,"RAWTIME",&rawtime,NULL,&status); + FITS_update_key(outfits,TLONG,"PLANTIME",&plantime,NULL,&status); + FITS_update_key(outfits,TLONG,"NBADEVNT",&neventscreened,NULL,&status); + FITS_update_key(outfits,TLONG,"NBADPHA",&neventscreenedpha,NULL,&status); + FITS_update_key(outfits,TLONG,"EXP_BAD",&(timescreened),NULL,&status); + FITS_update_key(outfits,TLONG,"EXP_BRST",&(timeburst),NULL,&status); + FITS_update_key(outfits,TLONG,"EXP_HV",&(timehv),NULL,&status); + FITS_update_key(outfits,TLONG,"EXP_JITR",&(timejitter),NULL,&status); + FITS_update_key(outfits,TLONG,"EXP_LIM",&(timelowlimbangle),NULL,&status); + FITS_update_key(outfits,TLONG,"EXP_SAA",&(timesaa),NULL,&status); + FITS_update_key(outfits,TLONG,"EXPNIGHT",&(timenight),NULL,&status); + + if (do_ycent) { + strcpy(string0,"PERFORM"); + FITS_update_key(outfits, TSTRING, "YCNT_COR", string0, NULL, &status); + + for (i = 1; i < 8; i++) { + if (i == 4) continue; + sprintf(string1, "YQUAL%1ld", i); + strcpy(string0,"HIGH"); + FITS_update_key(outfits, TSTRING, string1, string0, NULL, &status); + } + } + + /* reset BPM_CAL */ + fits_read_key(outfits,TSTRING,"BPM_CAL",string0,NULL,&status); + if (status!=0) { + status = 0; + } + else { + strcpy(string0,""); + FITS_update_key(outfits,TSTRING,"BPM_CAL",string0,NULL,&status); + } + + + if (empty_output) { + fits_write_history(outfits,"FILE CONTAINS NO DATA.",&status); + n2=0; + FITS_update_key(outfits,TINT,"NSPEC",&n2,NULL,&status); + } + else + FITS_update_key(outfits,TINT,"NSPEC",&nfiles,NULL,&status); + + fits_write_history(outfits," COMBINED WITH IDF_COMBINE ",&status); + + for (i=0;i<nfiles;i++){ + + string_pointer=strrchr(filelist[i],'/'); + if (string_pointer==NULL) corrected_filename=filelist[i]; + else corrected_filename=&(string_pointer[1]); + + + sprintf(keyword, "SPEC%.3ld", i+1); + FITS_update_key(outfits,TSTRING,keyword,corrected_filename,NULL,&status); + sprintf(keyword, "WOFFL%.3ld", i+1); + sprintf(comment, "[Angstroms] Shift applied to LiF spectrum"); + FITS_update_key(outfits,TFLOAT,keyword,&zero,comment,&status); + sprintf(keyword, "WOFFS%.3ld", i+1); + sprintf(comment, "[Angstroms] Shift applied to SiC spectrum"); + FITS_update_key(outfits,TFLOAT,keyword,&zero,comment,&status); + } + + FITS_close_file(infits,&status); + + cf_verbose(1,"PREPARING EVENTS LIST HDU"); + + /* Generate the tform array */ + sprintf(fmt_byte, "%ldB", nevents); + sprintf(fmt_float, "%ldE", nevents); + sprintf(fmt_short, "%ldI", nevents); + + hdu2_tform[0] = fmt_float; + hdu2_tform[1] = fmt_short; + hdu2_tform[2] = fmt_short; + hdu2_tform[3] = fmt_byte; + hdu2_tform[4] = fmt_float; + for (i=5; i<9; i++) + hdu2_tform[i] = fmt_short; + for ( ; i<12; i++) + hdu2_tform[i] = fmt_byte; + hdu2_tform[12] = fmt_float; + hdu2_tform[13] = fmt_float; + + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, 1, hdu2_tfields, hdu2_ttype, hdu2_tform, + hdu2_tunit, hdu2_extname, &status); + + /* Write TSCALE and TZERO entries to header */ + for (i=0; i<4; i++) { + sprintf(keyword, "TUNIT%ld", i+6); + if (fits_read_keyword(outfits, keyword, card, NULL, &status)) + cf_if_fits_error(status); + FITS_insert_key_flt(outfits, hdu2_tscal[i].keyword, hdu2_tscal[i].value, + -2, NULL, &status); + FITS_insert_key_flt(outfits, hdu2_tzero[i].keyword, hdu2_tzero[i].value, + -4, NULL, &status); + } + + + + cf_verbose(1,"PREPARING GTIs LIST HDU"); + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, ngtis, hdu3_tfields, hdu3_ttype, hdu3_tform, + hdu3_tunit, hdu3_extname, &status); + + + cf_verbose(1,"PREPARING TIMELINE HDU"); + + /* Generate the tform array */ + sprintf(fmt_byte, "%ldB", nrecords); + sprintf(fmt_float, "%ldE", nrecords); + sprintf(fmt_short, "%ldI", nrecords); + + + + hdu4_tform[0] = fmt_float; + hdu4_tform[1] = fmt_byte; + + for (i=2; i<hdu4_tfields; i++) hdu4_tform[i] = fmt_short; + + /* Set TSCALE and TZERO values */ + /* Not all of these will be used; see below. */ + for (i=2; i<hdu4_tfields; i++) { + sprintf(hdu4_tscal[i].keyword, "TSCAL%ld", i+1); + hdu4_tscal[i].value = 0.1; + sprintf(hdu4_tzero[i].keyword, "TZERO%ld", i+1); + hdu4_tzero[i].value = 0.; + } + + /* Let's keep three significant figures for vorb. */ + hdu4_tscal[7].value = 0.01; + + /* FEC_CNT_RATE and AIC_CNT_RATE can get big, so we + use TZERO AND TSCALE to compress them. */ + hdu4_tscal[11].value = 1; + hdu4_tscal[12].value = 2; + hdu4_tzero[11].value = 32768; + hdu4_tzero[12].value = 65536; + + if (big_vel) hdu4_tform[7]=fmt_float; + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, 1, hdu4_tfields, hdu4_ttype, hdu4_tform, + hdu4_tunit, hdu4_extname, &status); + + + /* Write TSCALE and TZERO entries to header */ + for (i=2; i<hdu4_tfields; i++) { + + if ((i==7)&&(big_vel)) continue; + + /* Omit TSCALE and TZERO for these six arrays. */ + if (i == 2) continue; /* TIME_SUNRISE */ + if (i == 3) continue; /* TIME_SUNSET */ + if (i == 8) continue; /* HIGH_VOLTAGE */ + if (i == 9) continue; /* LIF_CNT_RATE */ + if (i == 10) continue; /* SIC_CNT_RATE */ + if (i == 13) continue; /* BKGD_CNT_RATE */ + + + sprintf(keyword, "TUNIT%ld", i+1); + if (fits_read_keyword(outfits, keyword, card, NULL, &status)) + cf_if_fits_error(status); + FITS_insert_key_flt(outfits, hdu4_tscal[i].keyword, hdu4_tscal[i].value, + -1, NULL, &status); + FITS_insert_key_flt(outfits, hdu4_tzero[i].keyword, hdu4_tzero[i].value, + -5, NULL, &status); + + } + + + + + + + felem_hdu2=1; frow_hdu3=1; felem_hdu4=1; + + + cf_verbose(1,"COMBINING HDU"); + + for (i=0;i<nfiles;i++){ + + cf_verbose(2,"PROCESSING FILE %ld EVENTS LIST",i); + + delta_t=(expstartlist[i]-expstartlist[0])*3600*24; + + FITS_open_file(&infits,filelist[i],READONLY,&status); + + FITS_movabs_hdu(infits, 2, &hdutype, &status); + FITS_movabs_hdu(outfits, 2, &hdutype, &status); + + if (neventslist[i]>0){ + floatlist=(float *)malloc(neventslist[i]*sizeof(float)); + shortlist=(short *)malloc(neventslist[i]*sizeof(short)); + charlist=(char *)malloc(neventslist[i]*sizeof(char)); + + FITS_get_colnum(infits, TRUE, "TIME", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + for (j=0;j<neventslist[i];j++) floatlist[j]+=delta_t; + FITS_write_col(outfits, TFLOAT, 1, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "XRAW", &ncol, &status); + FITS_read_col(infits, TSHORT, ncol, 1, 1, neventslist[i], &intnull, + shortlist, &anynull, &status); + FITS_write_col(outfits, TSHORT, 2, 1, felem_hdu2, neventslist[i], shortlist, &status); + + + + FITS_get_colnum(infits, TRUE, "YRAW", &ncol, &status); + FITS_read_col(infits, TSHORT, ncol, 1, 1, neventslist[i], &intnull, + shortlist, &anynull, &status); + FITS_write_col(outfits, TSHORT, 3, 1, felem_hdu2, neventslist[i], shortlist, &status); + + + + FITS_get_colnum(infits, TRUE, "PHA", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, neventslist[i], &intnull, + charlist, &anynull, &status); + FITS_write_col(outfits, TBYTE, 4, 1, felem_hdu2, neventslist[i], charlist, &status); + + + + FITS_get_colnum(infits, TRUE, "WEIGHT", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 5, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "XFARF", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 6, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "YFARF", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 7, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "X", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 8, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "Y", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 9, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "CHANNEL", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, neventslist[i], &intnull, + charlist, &anynull, &status); + FITS_write_col(outfits, TBYTE, 10, 1, felem_hdu2, neventslist[i], charlist, &status); + + + + FITS_get_colnum(infits, TRUE, "TIMEFLGS", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, neventslist[i], &intnull, + charlist, &anynull, &status); + FITS_write_col(outfits, TBYTE, 11, 1, felem_hdu2, neventslist[i], charlist, &status); + + + + FITS_get_colnum(infits, TRUE, "LOC_FLGS", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, neventslist[i], &intnull, + charlist, &anynull, &status); + FITS_write_col(outfits, TBYTE, 12, 1, felem_hdu2, neventslist[i], charlist, &status); + + + + FITS_get_colnum(infits, TRUE, "LAMBDA", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 13, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + + FITS_get_colnum(infits, TRUE, "ERGCM2", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, neventslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 14, 1, felem_hdu2, neventslist[i], floatlist, &status); + + + free(floatlist); + free(charlist); + free(shortlist); + } + + cf_verbose(2,"PROCESSING FILE %ld GTIs LIST",i); + + FITS_movabs_hdu(infits, 3, &hdutype, &status); + FITS_movabs_hdu(outfits, 3, &hdutype, &status); + + if (ngtislist[i]>0){ + doublelist=(double *)malloc(ngtislist[i]*sizeof(double)); + + FITS_get_colnum(infits, TRUE, "START", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, ngtislist[i], &intnull, + doublelist, &anynull, &status); + for (j=0;j<ngtislist[i];j++) doublelist[j]+=delta_t; + FITS_write_col(outfits, TDOUBLE, 1, frow_hdu3, 1, ngtislist[i], doublelist, &status); + + FITS_get_colnum(infits, TRUE, "STOP", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, ngtislist[i], &intnull, + doublelist, &anynull, &status); + for (j=0;j<ngtislist[i];j++) doublelist[j]+=delta_t; + FITS_write_col(outfits, TDOUBLE, 2, frow_hdu3, 1, ngtislist[i], doublelist, &status); + + + free(doublelist); + } + + cf_verbose(2,"PROCESSING FILE %ld TIMELINE",i); + + FITS_movabs_hdu(infits, 4, &hdutype, &status); + FITS_movabs_hdu(outfits, 4, &hdutype, &status); + + if (nrecordslist[i]>0){ + floatlist=(float *)malloc(nrecordslist[i]*sizeof(float)); + shortlist=(short *)malloc(nrecordslist[i]*sizeof(short)); + charlist=(char *)malloc(nrecordslist[i]*sizeof(char)); + + + FITS_get_colnum(infits, TRUE, "TIME", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + for (j=0;j<nrecordslist[i];j++) floatlist[j]+=delta_t; + FITS_write_col(outfits, TFLOAT, 1, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "STATUS_FLAGS", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, nrecordslist[i], &intnull, + charlist, &anynull, &status); + FITS_write_col(outfits, TBYTE, 2, 1, felem_hdu4, nrecordslist[i], charlist, &status); + + FITS_get_colnum(infits, TRUE, "TIME_SUNRISE", &ncol, &status); + FITS_read_col(infits, TSHORT, ncol, 1, 1, nrecordslist[i], &intnull, + shortlist, &anynull, &status); + FITS_write_col(outfits, TSHORT, 3, 1, felem_hdu4, nrecordslist[i], shortlist, &status); + + FITS_get_colnum(infits, TRUE, "TIME_SUNSET", &ncol, &status); + FITS_read_col(infits, TSHORT, ncol, 1, 1, nrecordslist[i], &intnull, + shortlist, &anynull, &status); + FITS_write_col(outfits, TSHORT, 4, 1, felem_hdu4, nrecordslist[i], shortlist, &status); + + FITS_get_colnum(infits, TRUE, "LIMB_ANGLE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 5, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LONGITUDE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 6, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LATITUDE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 7, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "ORBITAL_VEL", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 8, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "HIGH_VOLTAGE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 9, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LIF_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 10, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "SIC_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 11, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "FEC_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 12, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "AIC_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 13, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "BKGD_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 14, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "YCENT_LIF", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 15, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + FITS_get_colnum(infits, TRUE, "YCENT_SIC", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecordslist[i], &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 16, 1, felem_hdu4, nrecordslist[i], floatlist, &status); + + + + + free(floatlist); + free(charlist); + free(shortlist); + } + + + felem_hdu2+=neventslist[i]; + frow_hdu3+=ngtislist[i]; + felem_hdu4+=nrecordslist[i]; + FITS_close_file(infits,&status); + + + } + +/* + if (fpa_split) + cf_if_warning("FPA motion detected. Resolution may be compromised."); +*/ + + if (do_ycent){ + FITS_movabs_hdu(outfits, 2, &hdutype, &status); + nevents = cf_read_col(outfits, TFLOAT, "X", (void **) &x); + nevents = cf_read_col(outfits, TFLOAT, "Y", (void **) &y); + nevents = cf_read_col(outfits, TFLOAT, "WEIGHT", (void **) &weight); + nevents = cf_read_col(outfits, TBYTE, "TIMEFLGS", (void **) &timeflags); + nevents = cf_read_col(outfits, TBYTE, "LOC_FLGS", (void **) &locflags); + nevents = cf_read_col(outfits, TBYTE, "CHANNEL", (void **) &channel); + + FITS_movabs_hdu(outfits, 1, &hdutype, &status); + + /* Compute centroids. */ + cf_calculate_y_centroid(outfits, nevents, weight, x, y, channel, + timeflags, locflags); + } + + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + cf_verbose(1,"CLOSING OUTPUT FILE"); + + FITS_close_file(outfits,&status); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + diff --git a/src/analysis/idf_cut.c b/src/analysis/idf_cut.c new file mode 100644 index 0000000..b302c60 --- /dev/null +++ b/src/analysis/idf_cut.c @@ -0,0 +1,977 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Usage: + * idf_cut [-hm] [-v level] idf_file RefTime Period Nout + * Arguments: + * RefTime : Reference Time in seconds since EXPSTART + * Period : Period in seconds + * Nout : Number of output files. + * Options: + * -m : interprets RefTime as MJD + * -h : this help message + * -v : verbosity level (=1; 0 is silent) + * + * Description: + * + * Cuts the IDF file into several smaller IDF files, sorting the + * events according to their phase. The GTIs table and timeline get + * also cut. + * From the input IDF file, idf_cut generates Nout IDF files named + * {input_idf_filename}.p{X}.fit with X=0..Nout-1. An event in the + * input file is sorted in output file X if it happens in the interval + * [RefTime+(k+X/Nout)*Period,RefTime+(k+(X+1)/Nout)*Period[ + * with k an integer. + * + * History: 10/08/04 bjg v1.0 + * 10/26/04 bjg v1.1 Now updates the GTIs table + * Fixed EXPNIGHT computation + * Added -m switch. + * + some cosmetic changes + * 12/01/04 bjg v1.2 Free allocated memory in the + * subroutines + * 12/02/04 bjg v1.3 Fixed bug in make_gtitab + * 06/03/05 wvd v1.4 Change nevents and nseconds to longs. + * 01/18/06 wvd v1.5 Read arrays with cf_read_col. + * + ****************************************************************************/ + + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <math.h> + +#include "calfuse.h" + +#define _MIN(a,b) (((a)<(b))?(a):(b)) + +typedef char filename[FLEN_CARD]; + +struct key { + char keyword[FLEN_KEYWORD]; + float value; +}; + +static char CF_PRGM_ID[]= "idf_cut"; +static char CF_VER_NUM[]= "1.1"; + + +static int _isinphase(double t, double RefTime, double Period, double vinf, double vsup){ + + float v; + + v=fmod(t-RefTime,Period); + if (v<0) v+=Period; + + return ((v>=vinf)&&(v<vsup)); +} + +static double _getphasenextstart(double t, double RefTime, double Period, double vinf, double vsup){ + + float v; + + v=fmod(t-RefTime,Period); + if (v<0) v+=Period; + + if (v>vinf) return t-v+vinf+Period; + else return t-v+vinf; + +} +static double _getphasenextstop(double t, double RefTime, double Period, double vinf, double vsup){ + + float v; + + v=fmod(t-RefTime,Period); + if (v<0) v+=Period; + + if (v>vsup) return t-v+vsup+Period; + else return t-v+vsup; +} + +struct _gti{ + double start; + double stop; + struct _gti *next; +}; + +typedef struct{ + struct _gti * gtilist; + long N; +} _tempgtis; + +static void _pushgti(double a, double b, _tempgtis * tempgtis){ + struct _gti *aux; + + aux=tempgtis->gtilist; + + tempgtis->gtilist=malloc(sizeof(struct _gti)); + tempgtis->N++; + tempgtis->gtilist->start=a; + tempgtis->gtilist->stop=b; + tempgtis->gtilist->next=aux; +} + +static void _popgti(double * a, double * b, _tempgtis * tempgtis){ + struct _gti *aux; + + *a=tempgtis->gtilist->start; + *b=tempgtis->gtilist->stop; + + aux=tempgtis->gtilist; + tempgtis->gtilist=tempgtis->gtilist->next; + free(aux); + tempgtis->N--; +} + +static _tempgtis * _makegtis(){ + _tempgtis * tempgtis; + + tempgtis=malloc(sizeof(_tempgtis)); + tempgtis->gtilist=NULL; + tempgtis->N=0; + return tempgtis; +} + +static void _deletegtis(_tempgtis * tempgtis){ + double a,b; + while (tempgtis->gtilist!=NULL) _popgti(&a,&b,tempgtis); + free(tempgtis); + tempgtis=NULL; +} + +static long _ngtis(_tempgtis * tempgtis){ + return tempgtis->N; +} + + +/****************************************************************************/ + +long make_evlist(fitsfile *infits,fitsfile *outfits, + double RefTime,double Period, long Nout, + long phase,char * daynight, + long * nbadevnt,long * nbadpha){ + + + int status=0; + + char pha; + char loc_flgs; + char timeflgs; + char time_test; + + char keyword[FLEN_CARD],card[FLEN_CARD]; + + char fmt_byte[FLEN_CARD],fmt_float[FLEN_CARD],fmt_short[FLEN_CARD]; + + int tfields=14; + + char extname[]="TTAG DATA"; /* Name of this extension */ + + char *ttype[]={"TIME", "XRAW", "YRAW", "PHA", "WEIGHT", "XFARF", + "YFARF", "X", "Y", "CHANNEL", "TIMEFLGS", + "LOC_FLGS", "LAMBDA", "ERGCM2" }; + + char *tform[14]; /* We'll assign values when we know + the number of elements in the data set. */ + + + char *tunit[]={"SECONDS", "PIXELS", "PIXELS", "UNITLESS", "UNITLESS", + "PIXELS", "PIXELS", "PIXELS", "PIXELS", "UNITLESS", + "UNITLESS", "UNITLESS", "ANGSTROMS", "ERG CM^-2"}; + + struct key tscal[] = {{"TSCAL6", 0.25}, {"TSCAL7", 0.1}, + {"TSCAL8", 0.25}, {"TSCAL9", 0.1}}; + + struct key tzero[] = {{"TZERO6", 8192.}, {"TZERO7", 0.}, + {"TZERO8", 8192.}, {"TZERO9", 0.}}; + + float *i_time; + short *i_xraw; + short *i_yraw; + char *i_pha; + float *i_weight; + float *i_xfarf; + float *i_yfarf; + float *i_x; + float *i_y; + char *i_channel; + char *i_timeflgs; + char *i_loc_flgs; + float *i_lambda; + float *i_ergcm2; + + + float *o_time; + short *o_xraw; + short *o_yraw; + char *o_pha; + float *o_weight; + float *o_xfarf; + float *o_yfarf; + float *o_x; + float *o_y; + char *o_channel; + char *o_timeflgs; + char *o_loc_flgs; + float *o_lambda; + float *o_ergcm2; + + long npts; + + long i; + + float vinf,vsup; + + long nevents=0; + + *nbadevnt=0; + *nbadpha=0; + + + npts = cf_read_col(infits, TFLOAT, "TIME", (void **) &i_time); + npts = cf_read_col(infits, TSHORT, "XRAW", (void **) &i_xraw); + npts = cf_read_col(infits, TSHORT, "YRAW", (void **) &i_yraw); + npts = cf_read_col(infits, TBYTE, "PHA", (void **) &i_pha); + npts = cf_read_col(infits, TFLOAT, "WEIGHT", (void **) &i_weight); + npts = cf_read_col(infits, TFLOAT, "XFARF", (void **) &i_xfarf); + npts = cf_read_col(infits, TFLOAT, "YFARF", (void **) &i_yfarf); + npts = cf_read_col(infits, TFLOAT, "X", (void **) &i_x); + npts = cf_read_col(infits, TFLOAT, "Y", (void **) &i_y); + npts = cf_read_col(infits, TBYTE, "CHANNEL", (void **) &i_channel); + npts = cf_read_col(infits, TBYTE, "TIMEFLGS", (void **) &i_timeflgs); + npts = cf_read_col(infits, TBYTE, "LOC_FLGS", (void **) &i_loc_flgs); + npts = cf_read_col(infits, TFLOAT, "LAMBDA", (void **) &i_lambda); + npts = cf_read_col(infits, TFLOAT, "ERGCM2", (void **) &i_ergcm2); + + + o_time = (float *) malloc(npts*sizeof(float)); + o_xraw = (short *) malloc(npts*sizeof(short)); + o_yraw = (short *) malloc(npts*sizeof(short)); + o_pha = (char *) malloc(npts*sizeof(char)); + o_weight = (float *) malloc(npts*sizeof(float)); + o_xfarf = (float *) malloc(npts*sizeof(float)); + o_yfarf = (float *) malloc(npts*sizeof(float)); + o_x = (float *) malloc(npts*sizeof(float)); + o_y = (float *) malloc(npts*sizeof(float)); + o_channel = (char *) malloc(npts*sizeof(char)); + o_timeflgs = (char *) malloc(npts*sizeof(char)); + o_loc_flgs = (char *) malloc(npts*sizeof(char)); + o_lambda = (float *) malloc(npts*sizeof(float)); + o_ergcm2 = (float *) malloc(npts*sizeof(float)); + + vinf=(phase*Period)/((float)Nout); + vsup=((phase+1)*Period)/((float)Nout); + + + for (i=0;i<npts;i++){ + + if (_isinphase(i_time[i], RefTime, Period, vinf, vsup)) { + + o_time[nevents] = i_time[i]; + o_xraw[nevents] = i_xraw[i]; + o_yraw[nevents] = i_yraw[i]; + o_pha[nevents] = i_pha[i]; + o_weight[nevents] = i_weight[i]; + o_xfarf[nevents] = i_xfarf[i]; + o_yfarf[nevents] = i_yfarf[i]; + o_x[nevents] = i_x[i]; + o_y[nevents] = i_y[i]; + o_channel[nevents] = i_channel[i]; + o_timeflgs[nevents] = i_timeflgs[i]; + o_loc_flgs[nevents] = i_loc_flgs[i]; + o_lambda[nevents] = i_lambda[i]; + o_ergcm2[nevents] = i_ergcm2[i]; + + pha=i_pha[i]; + loc_flgs=i_loc_flgs[i]; + timeflgs=i_timeflgs[i]; + + switch(daynight[0]) { + case 'D': + time_test=timeflgs^TEMPORAL_DAY; + break; + case 'N': + time_test=timeflgs; + break; + default: + time_test=timeflgs&(~TEMPORAL_DAY); + } + + if (loc_flgs&LOCATION_PHA){ + *nbadpha++; + } + + if ((loc_flgs&~LOCATION_AIR) || (time_test)) { + *nbadevnt++; + } + + + nevents++; + + } + + + } + + + + + /* Generate the tform array */ + sprintf(fmt_byte, "%ldB", nevents); + sprintf(fmt_float, "%ldE", nevents); + sprintf(fmt_short, "%ldI", nevents); + + tform[0] = fmt_float; + tform[1] = fmt_short; + tform[2] = fmt_short; + tform[3] = fmt_byte; + tform[4] = fmt_float; + for (i=5; i<9; i++) + tform[i] = fmt_short; + for ( ; i<12; i++) + tform[i] = fmt_byte; + tform[12] = fmt_float; + tform[13] = fmt_float; + + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, 1, tfields, ttype, tform, + tunit, extname, &status); + + /* Write TSCALE and TZERO entries to header */ + for (i=0; i<4; i++) { + sprintf(keyword, "TUNIT%ld", i+6); + if (fits_read_keyword(outfits, keyword, card, NULL, &status)) + cf_if_fits_error(status); + FITS_insert_key_flt(outfits, tscal[i].keyword, tscal[i].value, + -2, NULL, &status); + FITS_insert_key_flt(outfits, tzero[i].keyword, tzero[i].value, + -4, NULL, &status); + } + + if (nevents > 0) { + + FITS_write_col(outfits, TFLOAT, 1, 1, 1, nevents, o_time, &status); + FITS_write_col(outfits, TSHORT, 2, 1, 1, nevents, o_xraw, &status); + FITS_write_col(outfits, TSHORT, 3, 1, 1, nevents, o_yraw, &status); + FITS_write_col(outfits, TBYTE , 4, 1, 1, nevents, o_pha, &status); + FITS_write_col(outfits, TFLOAT, 5, 1, 1, nevents, o_weight, &status); + FITS_write_col(outfits, TFLOAT, 6, 1, 1, nevents, o_xfarf, &status); + FITS_write_col(outfits, TFLOAT, 7, 1, 1, nevents, o_yfarf, &status); + FITS_write_col(outfits, TFLOAT, 8, 1, 1, nevents, o_x, &status); + FITS_write_col(outfits, TFLOAT, 9, 1, 1, nevents, o_y, &status); + FITS_write_col(outfits, TBYTE , 10, 1, 1, nevents, o_channel, &status); + FITS_write_col(outfits, TBYTE , 11, 1, 1, nevents, o_timeflgs, &status); + FITS_write_col(outfits, TBYTE , 12, 1, 1, nevents, o_loc_flgs, &status); + FITS_write_col(outfits, TFLOAT, 13, 1, 1, nevents, o_lambda, &status); + FITS_write_col(outfits, TFLOAT, 14, 1, 1, nevents, o_ergcm2, &status); + } + + free(o_time); + free(o_xraw ); + free(o_yraw); + free(o_pha); + free(o_weight); + free(o_xfarf); + free(o_yfarf); + free(o_x); + free(o_y); + free(o_channel); + free(o_timeflgs); + free(o_loc_flgs); + free(o_lambda); + free(o_ergcm2); + + free(i_time); + free(i_xraw ); + free(i_yraw); + free(i_pha); + free(i_weight); + free(i_xfarf); + free(i_yfarf); + free(i_x); + free(i_y); + free(i_channel); + free(i_timeflgs); + free(i_loc_flgs); + free(i_lambda); + free(i_ergcm2); + + return nevents; +} + +/****************************************************************************/ +long make_gtitab(fitsfile * infits, fitsfile * outfits, + double RefTime, double Period, long Nout, + long phase){ + + + + int status=0; + + int tfields=2; + char extname[]="GTI"; /* Name of this extension */ + char *ttype[]={"START", "STOP" }; + char *tform[2]={"1D", "1D" }; + char *tunit[]={"seconds", "seconds"}; + + double *i_start; + double *i_stop; + double *o_start; + double *o_stop; + + _tempgtis * tempgtis; + + long npts=0; + long ngtis=0; + long i; + + float vinf,vsup; + + double a,b; + double _start, _stop; + + npts = cf_read_col(infits, TDOUBLE, "START", (void **) &i_start); + npts = cf_read_col(infits, TDOUBLE, "STOP", (void **) &i_stop); + + vinf=(phase*Period)/((float)Nout); + vsup=((phase+1)*Period)/((float)Nout); + + tempgtis=_makegtis(); + for (i=0;i<npts;i++){ + cf_verbose(4,"Input GTI %ld = %lf/%lf",i,i_start[i],i_stop[i]); + a=i_start[i]; + b=i_stop[i]; + if (_isinphase(a,RefTime, Period, vinf, vsup)) _start=a; + else _start=_MIN(b,_getphasenextstart(a,RefTime, Period, vinf, vsup)); + + while (_start<b){ + _stop=_MIN(b,_getphasenextstop(_start,RefTime, Period, vinf, vsup)); + _pushgti(_start,_stop,tempgtis); + cf_verbose(4,"Output GTI = %lf,%lf",_start,_stop); + _start=_getphasenextstart(_stop,RefTime, Period, vinf, vsup); + } + } + + ngtis=_ngtis(tempgtis); + + o_start=(double *)malloc(ngtis*sizeof(double)); + o_stop=(double *)malloc(ngtis*sizeof(double)); + + for (i=ngtis-1;i>=0;i--){ + _popgti(&o_start[i],&o_stop[i],tempgtis); + } + + _deletegtis(tempgtis); + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, ngtis, tfields, ttype, tform, + tunit, extname, &status); + + + if (ngtis>0){ + FITS_write_col(outfits, TDOUBLE, 1, 1, 1, ngtis, o_start, &status); + FITS_write_col(outfits, TDOUBLE, 2, 1, 1, ngtis, o_stop, &status); + } + + return ngtis; + +} +/****************************************************************************/ +long make_timeline(fitsfile *infits, fitsfile *outfits, + double RefTime, double Period, long Nout, long phase, + char *daynight, + double *exptime, double *exp_bad, double *exp_brst, double *exp_hv, + double *exp_jitr, double *exp_lim, double *exp_saa, double *expnight){ + + char timeflgs; + char time_test; + int status=0; + + int bigtime=1; + int big_vel=1; + + char keyword[FLEN_CARD],card[FLEN_CARD]; + + char fmt_byte[FLEN_CARD],fmt_float[FLEN_CARD],fmt_short[FLEN_CARD]; + + struct key tscal[16]; + struct key tzero[16]; + + char extname[]="TIMELINE"; + + int tfields=16; /* output table will have 16 columns */ + + char *ttype[]={"TIME", "STATUS_FLAGS", "TIME_SUNRISE", "TIME_SUNSET", + "LIMB_ANGLE", "LONGITUDE", "LATITUDE", "ORBITAL_VEL", + "HIGH_VOLTAGE", "LIF_CNT_RATE", "SIC_CNT_RATE", + "FEC_CNT_RATE", "AIC_CNT_RATE", "BKGD_CNT_RATE", + "YCENT_LIF","YCENT_SIC"}; + + char *tform[16]; /* we will define tform later, when the number + of photons is known */ + + char *tunit[]={"seconds", "unitless", "seconds", "seconds", "degrees", + "degrees", "degrees", "km/s", "unitless", "counts/sec", + "counts/sec", "counts/sec", "counts/sec", "counts/sec", + "pixels","pixels" }; + + float *i_time; + char *i_status_flags; + float *i_time_sunrise; + float *i_time_sunset; + float *i_limb_angle; + float *i_longitude; + float *i_latitude; + float *i_orbital_vel; + short *i_high_voltage; + short *i_lif_cnt_rate; + short *i_sic_cnt_rate; + short *i_fec_cnt_rate; + short *i_aic_cnt_rate; + short *i_bkgd_cnt_rate; + float *i_ycent_lif; + float *i_ycent_sic; + + float *o_time; + char *o_status_flags; + float *o_time_sunrise; + float *o_time_sunset; + float *o_limb_angle; + float *o_longitude; + float *o_latitude; + float *o_orbital_vel; + short *o_high_voltage; + short *o_lif_cnt_rate; + short *o_sic_cnt_rate; + short *o_fec_cnt_rate; + short *o_aic_cnt_rate; + short *o_bkgd_cnt_rate; + float *o_ycent_lif; + float *o_ycent_sic; + + long npts; + + long i; + + float vinf,vsup; + + long nseconds=0; + + *exptime=0; + *expnight=0; + *exp_bad=0; + *exp_brst=0; + *exp_hv=0; + *exp_jitr=0; + *exp_lim=0; + *exp_saa=0; + *expnight=0; + + + + npts = cf_read_col(infits, TFLOAT, "TIME" , (void **) &i_time); + npts = cf_read_col(infits, TBYTE , "STATUS_FLAGS" , (void **) &i_status_flags); + npts = cf_read_col(infits, TFLOAT, "TIME_SUNRISE" , (void **) &i_time_sunrise); + npts = cf_read_col(infits, TFLOAT, "TIME_SUNSET" , (void **) &i_time_sunset); + npts = cf_read_col(infits, TFLOAT, "LIMB_ANGLE" , (void **) &i_limb_angle); + npts = cf_read_col(infits, TFLOAT, "LONGITUDE" , (void **) &i_longitude); + npts = cf_read_col(infits, TFLOAT, "LATITUDE" , (void **) &i_latitude); + npts = cf_read_col(infits, TFLOAT, "ORBITAL_VEL" , (void **) &i_orbital_vel); + npts = cf_read_col(infits, TSHORT, "HIGH_VOLTAGE" , (void **) &i_high_voltage); + npts = cf_read_col(infits, TSHORT, "LIF_CNT_RATE" , (void **) &i_lif_cnt_rate); + npts = cf_read_col(infits, TSHORT, "SIC_CNT_RATE" , (void **) &i_sic_cnt_rate); + npts = cf_read_col(infits, TSHORT, "FEC_CNT_RATE" , (void **) &i_fec_cnt_rate); + npts = cf_read_col(infits, TSHORT, "AIC_CNT_RATE" , (void **) &i_aic_cnt_rate); + npts = cf_read_col(infits, TSHORT, "BKGD_CNT_RATE" , (void **) &i_bkgd_cnt_rate); + npts = cf_read_col(infits, TFLOAT, "YCENT_LIF" , (void **) &i_ycent_lif); + npts = cf_read_col(infits, TFLOAT, "YCENT_SIC" , (void **) &i_ycent_sic); + + + o_time = (float *) malloc(npts*sizeof(float)); + o_status_flags = (char *) malloc(npts*sizeof(char)); + o_time_sunrise = (float *) malloc(npts*sizeof(float)); + o_time_sunset = (float *) malloc(npts*sizeof(float)); + o_limb_angle = (float *) malloc(npts*sizeof(float)); + o_longitude = (float *) malloc(npts*sizeof(float)); + o_latitude = (float *) malloc(npts*sizeof(float)); + o_orbital_vel = (float *) malloc(npts*sizeof(float)); + o_high_voltage = (short *) malloc(npts*sizeof(short)); + o_lif_cnt_rate = (short *) malloc(npts*sizeof(short)); + o_sic_cnt_rate = (short *) malloc(npts*sizeof(short)); + o_fec_cnt_rate = (short *) malloc(npts*sizeof(short)); + o_aic_cnt_rate = (short *) malloc(npts*sizeof(short)); + o_bkgd_cnt_rate = (short *) malloc(npts*sizeof(short)); + o_ycent_lif = (float *) malloc(npts*sizeof(float)); + o_ycent_sic = (float *) malloc(npts*sizeof(float)); + + + vinf=(phase*Period)/((float)Nout); + vsup=((phase+1)*Period)/((float)Nout); + + + for (i=0;i<npts;i++){ + + if (_isinphase(i_time[i], RefTime, Period, vinf, vsup)) { + + o_time[nseconds] = i_time[i]; + o_status_flags[nseconds] = i_status_flags[i]; + o_time_sunrise[nseconds] = i_time_sunrise[i]; + o_time_sunset[nseconds] = i_time_sunset[i]; + o_limb_angle[nseconds] = i_limb_angle[i]; + o_longitude[nseconds] = i_longitude[i]; + o_latitude[nseconds] = i_latitude[i]; + o_orbital_vel[nseconds] = i_orbital_vel[i]; + o_high_voltage[nseconds] = i_high_voltage[i]; + o_lif_cnt_rate[nseconds] = i_lif_cnt_rate[i]; + o_sic_cnt_rate[nseconds] = i_sic_cnt_rate[i]; + o_fec_cnt_rate[nseconds] = i_fec_cnt_rate[i]; + o_aic_cnt_rate[nseconds] = i_aic_cnt_rate[i]; + o_bkgd_cnt_rate[nseconds] = i_bkgd_cnt_rate[i]; + o_ycent_lif[nseconds] = i_ycent_lif[i]; + o_ycent_sic[nseconds] = i_ycent_sic[i]; + + timeflgs=i_status_flags[i]; + + switch(daynight[0]) { + case 'D': + time_test=timeflgs^TEMPORAL_DAY; + break; + case 'N': + time_test=timeflgs; + break; + default: + time_test=timeflgs&(~TEMPORAL_DAY); + } + + + if (time_test==0) { + + *exptime+=1.0; + + if (!(timeflgs & TEMPORAL_DAY)) + *expnight+=1.0; + + } else { + + *exp_bad+=1.0; + + if (timeflgs & TEMPORAL_BRST) + *exp_brst+=1.0; + + if (timeflgs & TEMPORAL_HV) + *exp_hv=+1.0; + + if (timeflgs & TEMPORAL_JITR) + *exp_jitr=+1.0; + + if (timeflgs & TEMPORAL_LIMB) + *exp_lim=+1.0; + + if (timeflgs & TEMPORAL_SAA) + *exp_saa=+1.0; + + } + + nseconds++; + } + } + + /* Generate the tform array */ + sprintf(fmt_byte, "%ldB", nseconds); + sprintf(fmt_float, "%ldE", nseconds); + sprintf(fmt_short, "%ldI", nseconds); + + + tform[0] = fmt_float; + tform[1] = fmt_byte; + + for (i=2; i<tfields; i++) tform[i] = fmt_short; + + /* Set TSCALE and TZERO values */ + /* Not all of these will be used; see below. */ + for (i=2; i<tfields; i++) { + sprintf(tscal[i].keyword, "TSCAL%ld", i+1); + tscal[i].value = 0.1; + sprintf(tzero[i].keyword, "TZERO%ld", i+1); + tzero[i].value = 0.; + } + + /* Need TZEROn = 3000. for tsunrise and tsunset. */ + tzero[2].value = tzero[3].value = 3000.; + + /* Let's keep three significant figures for vorb. */ + tscal[7].value = 0.01; + + /* FEC_CNT_RATE and AIC_CNT_RATE can get big, so we + (essentially) store them as unsigned shorts. */ + tscal[11].value = 1; + tscal[12].value = 1; + tzero[11].value = 32768; + tzero[12].value = 32768; + + + if (bigtime) { + tform[2]=tform[3]=fmt_float; + } + + if (big_vel) tform[7]=fmt_float; + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, 1, tfields, ttype, tform, + tunit, extname, &status); + + + + /* Write TSCALE and TZERO entries to header */ + for (i=2; i<tfields; i++) { + + /* If bigtime is TRUE, store tsunrise and tsunset as floats.*/ + if ((i == 2 || i == 3) && bigtime) continue; + + if ((i==7)&&(big_vel)) continue; + + /* Omit TSCALE and TZERO for these four arrays. */ + if (i == 8) continue; /* HIGH_VOLTAGE */ + if (i == 9) continue; /* LIF_CNT_RATE */ + if (i == 10) continue; /* SIC_CNT_RATE */ + if (i == 13) continue; /* BKGD_CNT_RATE */ + + + sprintf(keyword, "TUNIT%ld", i+1); + if (fits_read_keyword(outfits, keyword, card, NULL, &status)) + cf_if_fits_error(status); + FITS_insert_key_flt(outfits, tscal[i].keyword, tscal[i].value, + -1, NULL, &status); + FITS_insert_key_flt(outfits, tzero[i].keyword, tzero[i].value, + -5, NULL, &status); + } + + if (nseconds > 0) { + + FITS_write_col(outfits, TFLOAT, 1, 1, 1, nseconds, o_time , &status); + FITS_write_col(outfits, TBYTE , 2, 1, 1, nseconds, o_status_flags , &status); + FITS_write_col(outfits, TFLOAT, 3, 1, 1, nseconds, o_time_sunrise , &status); + FITS_write_col(outfits, TFLOAT, 4, 1, 1, nseconds, o_time_sunset , &status); + FITS_write_col(outfits, TFLOAT, 5, 1, 1, nseconds, o_limb_angle , &status); + FITS_write_col(outfits, TFLOAT, 6, 1, 1, nseconds, o_longitude , &status); + FITS_write_col(outfits, TFLOAT, 7, 1, 1, nseconds, o_latitude , &status); + FITS_write_col(outfits, TFLOAT, 8, 1, 1, nseconds, o_orbital_vel , &status); + FITS_write_col(outfits, TSHORT, 9, 1, 1, nseconds, o_high_voltage , &status); + FITS_write_col(outfits, TSHORT, 10, 1, 1, nseconds, o_lif_cnt_rate , &status); + FITS_write_col(outfits, TSHORT, 11, 1, 1, nseconds, o_sic_cnt_rate , &status); + FITS_write_col(outfits, TSHORT, 12, 1, 1, nseconds, o_fec_cnt_rate , &status); + FITS_write_col(outfits, TSHORT, 13, 1, 1, nseconds, o_aic_cnt_rate , &status); + FITS_write_col(outfits, TSHORT, 14, 1, 1, nseconds, o_bkgd_cnt_rate , &status); + FITS_write_col(outfits, TFLOAT, 15, 1, 1, nseconds, o_ycent_lif , &status); + FITS_write_col(outfits, TFLOAT, 16, 1, 1, nseconds, o_ycent_sic , &status); + + } + + free(o_time); + free(o_status_flags); + free(o_time_sunrise); + free(o_time_sunset); + free(o_limb_angle); + free(o_longitude); + free(o_latitude); + free(o_orbital_vel); + free(o_high_voltage); + free(o_lif_cnt_rate); + free(o_sic_cnt_rate); + free(o_fec_cnt_rate); + free(o_aic_cnt_rate); + free(o_bkgd_cnt_rate); + free(o_ycent_lif); + free(o_ycent_sic); + + free(i_time); + free(i_status_flags); + free(i_time_sunrise); + free(i_time_sunset); + free(i_limb_angle); + free(i_longitude); + free(i_latitude); + free(i_orbital_vel); + free(i_high_voltage); + free(i_lif_cnt_rate); + free(i_sic_cnt_rate); + free(i_fec_cnt_rate); + free(i_aic_cnt_rate); + free(i_bkgd_cnt_rate); + free(i_ycent_lif); + free(i_ycent_sic); + + return nseconds; +} +/****************************************************************************/ + + +int main(int argc,char *argv[]){ + time_t vtime; + char stime[FLEN_CARD]; + + fitsfile * infits; + fitsfile * outfits; + + filename input_filename,output_filename, ifname; + + char string0[FLEN_CARD], daynight[FLEN_CARD]; + + + + long nevents; + long nseconds; + long ngtis; + + long nbadevnt; + long nbadpha; + + double exptime; + double exp_bad; + double exp_brst; + double exp_hv; + double exp_jitr; + double exp_lim; + double exp_saa; + double expnight; + + double RefTime; + double Period; + long Nout; + + double expstart; + + long i; + + int optc; + + char opts[] = "hmv:"; + char usage[] = + "Usage:\n" + " idf_cut [-hm] [-v level] idf_file RefTime Period Nout\n"; + char argument[] = + "Arguments:\n" + " RefTime : Reference Time in seconds since EXPSTART\n" + " Period : Period in seconds\n" + " Nout : Number of output files.\n"; + char option[] = + "Options:\n" + " -m: interprets RefTime as MJD\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n"; + + int hdutype=0; + int status=0; + int rtime_mjd=0; + verbose_level = 1; + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s\n%s", usage, argument, option); + return 0; + case 'v': + verbose_level = atoi(optarg); + break; + case 'm': + rtime_mjd=1; + break; + } + } + + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + if (argc != optind+4) { + printf("%s", usage); + cf_if_error("Incorrect number of arguments"); + } + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + /* get and display time */ + vtime = time(NULL) ; + strcpy(stime,ctime(&vtime)); + + strcpy(input_filename,argv[optind]); + + sscanf(argv[optind+1],"%lf",&RefTime); + sscanf(argv[optind+2],"%lf",&Period); + sscanf(argv[optind+3],"%ld",&Nout); + + FITS_open_file(&infits,input_filename,READONLY,&status); + FITS_read_key(infits,TSTRING,"DAYNIGHT",daynight,NULL,&status); + FITS_read_key(infits,TSTRING,"FILENAME",ifname,NULL,&status); + + if (rtime_mjd){ + FITS_read_key(infits,TDOUBLE,"EXPSTART",&expstart,NULL,&status); + RefTime=(RefTime-expstart)*3600.0*24.0; + } + + for (i=0;i<Nout;i++){ + FITS_movabs_hdu(infits,1,&hdutype,&status); + + + strcpy(output_filename,ifname); + sprintf(string0,".p%ld.fit",i); + strcat(output_filename,string0); + + FITS_create_file(&outfits,output_filename,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + FITS_update_key(outfits,TSTRING,"FILENAME",output_filename,NULL,&status); + + cf_verbose(1,"Phase: %ld/%ld",i+1,Nout); + + cf_verbose(2,"Creating Events List"); + /* Create Events List */ + FITS_movabs_hdu(infits,2,&hdutype,&status); + nevents=make_evlist(infits, outfits, RefTime, Period, Nout, i, daynight, + &nbadevnt, &nbadpha); + cf_verbose(2,"Number of Events: %ld",nevents); + + cf_verbose(2,"Creating GTI table"); + /* Create GTIs Table */ + FITS_movabs_hdu(infits,3,&hdutype,&status); + ngtis=make_gtitab(infits, outfits, RefTime, Period, Nout, i); + cf_verbose(2,"Number of GTIs: %ld",ngtis); + + cf_verbose(2,"Creating Timeline"); + /* Create Timeline */ + FITS_movabs_hdu(infits,4,&hdutype,&status); + nseconds=make_timeline(infits, outfits, RefTime, Period, Nout, i, daynight, + &exptime, &exp_bad, &exp_brst, &exp_hv, &exp_jitr, + &exp_lim, &exp_saa, &expnight); + cf_verbose(2,"Number of records in timeline: %ld",nseconds); + + + /* Update Main Header Keyword */ + FITS_movabs_hdu(outfits,1,&hdutype,&status); + + + FITS_update_key(outfits,TDOUBLE ,"EXPTIME" ,&exptime ,NULL,&status); + FITS_update_key(outfits,TLONG ,"RAWTIME" ,&nseconds ,NULL,&status); + FITS_update_key(outfits,TLONG ,"NEVENTS" ,&nevents ,NULL,&status); + FITS_update_key(outfits,TLONG ,"NBADEVNT" ,&nbadevnt ,NULL,&status); + FITS_update_key(outfits,TLONG ,"NBADPHA" ,&nbadpha ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_BAD" ,&exp_bad ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_SAA" ,&exp_saa ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_LIM" ,&exp_lim ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_BRST" ,&exp_brst ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_JITR" ,&exp_jitr ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXPNIGHT" ,&expnight ,NULL,&status); + + FITS_close_file(outfits,&status); + } + FITS_close_file(infits,&status); + + return (status); +} diff --git a/src/analysis/idf_screen.c b/src/analysis/idf_screen.c new file mode 100644 index 0000000..31aa022 --- /dev/null +++ b/src/analysis/idf_screen.c @@ -0,0 +1,339 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: idf_screen infits outfits timeflag value + * + * + * + * History: 10/05/04 bjg 1.0 Begin work. + * 10/26/04 bjg 1.1 Updates important header + * keywords. + * + ****************************************************************************/ + + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include "calfuse.h" + + +typedef char filename[FLEN_CARD]; + +struct key { + char keyword[FLEN_KEYWORD]; + float value; +}; + +static char CF_PRGM_ID[]= "idf_screen"; +static char CF_VER_NUM[]= "1.1"; + +int main(int argc,char *argv[]){ + + char tempstring[FLEN_CARD]; + char daynight[FLEN_CARD]; + char * corrected_filename; + char * string_pointer; + + char time_test; + + int status=0; + int hdutype=0; + + long i, npts; + + char * tflags, * lflags; + + fitsfile *infits , *outfits; + + filename input_fname , output_fname; + + char selstr1[FLEN_CARD]; + char selstr2[FLEN_CARD]; + + char sel1; + int sel2; + + long nbadevnt=0; + long nbadpha=0; + + double exptime=0.0; + double exp_bad=0.0; + double exp_brst=0.0; + double exp_hv=0.0; + double exp_jitr=0.0; + double exp_lim=0.0; + double exp_saa=0.0; + double expnight=0.0; + + int optc; + + char opts[] = "hv:"; + char usage[] = + "Usage:\n" + " idf_screen [-h] [-v level] input_idf_file output_idf_file \n" + " timeflag value\n"; + char argument[] = + "Arguments :\n" + " timeflag : USER/JITR/OPUS/BRST/HV/SAA/LIMB/DAY \n" + " value : GOOD/BAD/EITHER \n"; + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n"; + + verbose_level = 1; + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s\n%s", usage, argument, option); + return 0; + case 'v': + verbose_level = atoi(optarg); + break; + } + } + + + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + if (argc != optind+4) { + printf("%s", usage); + cf_if_error("Incorrect number of arguments"); + } + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + + strcpy(input_fname,argv[optind]); + strcpy(output_fname,argv[optind+1]); + strcpy(selstr1,argv[optind+2]); + strcpy(selstr2,argv[optind+3]); + + + + if (!strcasecmp(selstr2,"GOOD")) { + sel2=0; + } else if (!strcasecmp(selstr2,"BAD")) { + sel2=1; + } else if (!strcasecmp(selstr2,"EITHER")) { + sel2=2; + } else { + printf("%s", usage); + cf_if_error("VALUE not recognized."); + } + + + if (!strcasecmp(selstr1,"USER")) { + sel1=TEMPORAL_USER; + } else if (!strcasecmp(selstr1,"JITR")) { + sel1=TEMPORAL_JITR; + } else if (!strcasecmp(selstr1,"OPUS")) { + sel1=TEMPORAL_OPUS; + } else if (!strcasecmp(selstr1,"BRST")) { + sel1=TEMPORAL_BRST; + } else if (!strcasecmp(selstr1,"HV")) { + sel1=TEMPORAL_HV; + } else if (!strcasecmp(selstr1,"SAA")) { + sel1=TEMPORAL_SAA; + } else if (!strcasecmp(selstr1,"LIMB")) { + sel1=TEMPORAL_LIMB; + } else if (!strcasecmp(selstr1,"DAY")) { + sel1=TEMPORAL_DAY; + } else { + printf("%s", usage); + cf_if_error("TIMEFLAG not recognized."); + } + + cf_verbose(1,"Input Filename : %s",input_fname); + cf_verbose(1,"Output Filename : %s",output_fname); + cf_verbose(1,"FLAG : %s - %d",selstr1,sel1); + cf_verbose(1,"VALUE : %s - %d",selstr2,sel2); + + if ((sel1>1)&&(sel2==0)){ + cf_verbose(1,"Nothing to do."); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + } + + cf_verbose(1,"OPENING INPUT FILE"); + FITS_open_file(&infits,input_fname,READONLY,&status); + + cf_verbose(1,"CREATING OUTPUT FILE"); + FITS_create_file(&outfits,output_fname,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + string_pointer=strrchr(output_fname,'/'); + if (string_pointer==NULL) corrected_filename=output_fname; + else corrected_filename=&(string_pointer[1]); + + FITS_update_key(outfits,TSTRING,"FILENAME",corrected_filename,NULL,&status); + + strcpy(tempstring,""); + + FITS_update_key(outfits,TSTRING,"BPM_CAL",tempstring,NULL,&status); + + if (sel1 == 1) { + switch(sel2) { + case 0: + strcpy(daynight,"NIGHT"); + break; + case 1: + strcpy(daynight,"DAY"); + break; + case 2: + strcpy(daynight,"BOTH"); + break; + } + FITS_update_key(outfits,TSTRING,"DAYNIGHT",daynight,NULL,&status); + } else { + FITS_read_key(infits,TSTRING,"DAYNIGHT",daynight,NULL,&status); + } + + + FITS_movabs_hdu(infits,2,&hdutype,&status); + FITS_create_hdu(outfits,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + + npts = cf_read_col(outfits, TBYTE, "TIMEFLGS", (void **) &tflags); + npts = cf_read_col(outfits, TBYTE, "LOC_FLGS", (void **) &lflags); + for (i=0;i<npts;i++){ + if (sel1>1){ + if (sel2==1){ + tflags[i]=(tflags[i])^sel1; + } else if (sel2==2){ + tflags[i]=(tflags[i])&(~sel1); + } + } + + switch(daynight[0]) { + case 'D': + time_test=tflags[i]^TEMPORAL_DAY; + break; + case 'N': + time_test=tflags[i]; + break; + default: + time_test=tflags[i]&(~TEMPORAL_DAY); + } + + if (lflags[i]&LOCATION_PHA){ + nbadpha++; + } + + if ((lflags[i]&~LOCATION_AIR) || (time_test)) { + nbadevnt++; + } + } + + if ((sel1>1)&&(sel2>0)){ + cf_write_col(outfits, TBYTE, "TIMEFLGS", (void *) tflags, npts); + } + + free(tflags); + free(lflags); + + + FITS_movabs_hdu(infits,3,&hdutype,&status); + FITS_create_hdu(outfits,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + + FITS_movabs_hdu(infits,4,&hdutype,&status); + FITS_create_hdu(outfits,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + + npts = cf_read_col(outfits, TBYTE, "STATUS_FLAGS", (void **) &tflags); + + for (i=0;i<npts;i++){ + if (sel1>1){ + if (sel2==1){ + tflags[i]=(tflags[i])^sel1; + } else if (sel2==2){ + tflags[i]=(tflags[i])&(~sel1); + } + } + + switch(daynight[0]) { + case 'D': + time_test=tflags[i]^TEMPORAL_DAY; + break; + case 'N': + time_test=tflags[i]; + break; + default: + time_test=tflags[i]&(~TEMPORAL_DAY); + } + + + if (time_test==0) { + + exptime+=1.0; + + if (!(tflags[i] & TEMPORAL_DAY)) + expnight+=1.0; + + } else { + + exp_bad+=1.0; + + if (tflags[i] & TEMPORAL_BRST) + exp_brst+=1.0; + + if (tflags[i] & TEMPORAL_HV) + exp_hv=+1.0; + + if (tflags[i] & TEMPORAL_JITR) + exp_jitr=+1.0; + + if (tflags[i] & TEMPORAL_LIMB) + exp_lim=+1.0; + + if (tflags[i] & TEMPORAL_SAA) + exp_saa=+1.0; + } + + } + + if ((sel1>1)&&(sel2>0)){ + cf_write_col(outfits, TBYTE, "STATUS_FLAGS", (void *) tflags, npts); + } + + free(tflags); + + /* Update Main Header Keyword */ + FITS_movabs_hdu(outfits,1,&hdutype,&status); + + FITS_update_key(outfits,TDOUBLE ,"EXPTIME" ,&exptime ,NULL,&status); + FITS_update_key(outfits,TLONG ,"NBADEVNT" ,&nbadevnt ,NULL,&status); + FITS_update_key(outfits,TLONG ,"NBADPHA" ,&nbadpha ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_BAD" ,&exp_bad ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_SAA" ,&exp_saa ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_LIM" ,&exp_lim ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_BRST" ,&exp_brst ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXP_JITR" ,&exp_jitr ,NULL,&status); + FITS_update_key(outfits,TDOUBLE ,"EXPNIGHT" ,&expnight ,NULL,&status); + + cf_verbose(1,"CLOSING INPUT FILE"); + FITS_close_file(infits,&status); + + cf_verbose(1,"CLOSING OUTPUT FILE"); + FITS_close_file(outfits,&status); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + diff --git a/src/analysis/mjd2hjd.c b/src/analysis/mjd2hjd.c new file mode 100644 index 0000000..e0ecd18 --- /dev/null +++ b/src/analysis/mjd2hjd.c @@ -0,0 +1,129 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * + * + * Usage: + * mjd2hjd [-h] [-v level] mjd ra_h ra_m ra_s dec_d dec_m dec_s + * + * + * Arguments: + * mjd : Modified Julian Day + * ra_h ra_m ra_s dec_d dec_m dec_s : RA and DEC of target : hh mm ss.s dd mm ss.s + * + * + * Options: + * -h: this help message + * -v: verbosity level (=1; 0 is silent) + * + * + * + * + * + * History: 10/06/04 bjg v1.0 + * 10/26/04 bjg v1.1 Cosmetic change + * + ****************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#include "calfuse.h" + + + +#define SECONDS_PER_DAY (24.0*3600.0) + +static char CF_PRGM_ID[]= "mjd2hjd"; +static char CF_VER_NUM[]= "1.1"; + + +double gethmjd(double, int, int, float, int, int, float); + +int main(int argc,char *argv[]){ + + int optc; + + + + double lighttime; + double jd, mjd, hjd, hmjd; + + int rah,ram,decd,decm; + float ras,decs; + + + char opts[] = "hv:"; + char usage[] = + "Usage:\n" + " mjd2hjd [-h] [-v level] mjd ra_h ra_m ra_s dec_d dec_m dec_s\n"; + char argument[] = + "Arguments:\n" + " mjd : Modified Julian Day.\n" + " ra_h ra_m ra_s dec_d dec_m dec_s : RA and DEC of target.\n"; + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n"; + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + + case 'h': + printf("%s\n%s\n%s", usage, argument, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc != optind+7) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + sscanf(argv[optind],"%lf",&mjd); + sscanf(argv[optind+1],"%d",&rah); + sscanf(argv[optind+2],"%d",&ram); + sscanf(argv[optind+3],"%f",&ras); + sscanf(argv[optind+4],"%d",&decd); + sscanf(argv[optind+5],"%d",&decm); + sscanf(argv[optind+6],"%f",&decs); + + + hmjd=gethmjd(mjd,rah,ram,ras,decd,decs,decm); + + jd = mjd + 2400000.5; + hjd = hmjd + 2400000.5; + + lighttime=(hmjd-mjd)*SECONDS_PER_DAY; + + cf_verbose(1,"Right Ascension of target: %d h %d m %f s",rah,ram,ras); + cf_verbose(1,"Declination of target: %d deg %d m %f s",decd,decm,decs); + cf_verbose(1,"jd= %lf",jd); + cf_verbose(1,"mjd= %lf",mjd); + cf_verbose(1,"hjd= %lf",hjd); + cf_verbose(1,"hmjd= %lf",hmjd); + cf_verbose(1,"heliocentric light time correction = %lf s",lighttime); + cf_verbose(1,"---positive when Earth is closer to target than Sun"); + return EXIT_SUCCESS; + +} + diff --git a/src/analysis/modhead.c b/src/analysis/modhead.c new file mode 100644 index 0000000..0ffc40b --- /dev/null +++ b/src/analysis/modhead.c @@ -0,0 +1,114 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: modhead file.fit[ext] KEYWORD NEW_VALUE + * + * Description: Returns or modifies the value of a header keyword. + * If NEW_VALUE is not specified, current value of KEYWORD is + * returned. If KEYWORD is not found and NEW_VALUE is given, + * KEYWORD is added to header. If an extension beyond the + * primary HDU is requested, file name must be given in + * parentheses: "file.fit[3]" or an alternate construction + * used: file.fit+3 Note that the primary HDU is extension 0. + * + * History: 05/15/05 tc started work + * 08/30/05 wvd Allow multi-word strings. + * + ****************************************************************************/ + +#include <string.h> +#include <stdio.h> +#include "fitsio.h" + +int main(int argc, char *argv[]) +{ + fitsfile *fptr; /* FITS file pointer, defined in fitsio.h */ + char card[FLEN_CARD], newcard[FLEN_CARD]; + char oldvalue[FLEN_VALUE], comment[FLEN_COMMENT]; + int status = 0; /* CFITSIO status value MUST be initialized to zero! */ + int i, iomode, keytype; + + if (argc == 3) + iomode = READONLY; + else if (argc >= 4) + iomode = READWRITE; + else if (argc < 3) { + printf("Usage: modhead filename[ext] keyword new_value\n"); + printf("\n"); + printf("Write or modify the value of a header keyword.\n"); + printf("If 'newvalue' is not specified, then just print \n"); + printf("the current value. \n"); + printf("\n"); + printf("Examples: \n"); + printf(" modhead file.fits dec - list the DEC keyword \n"); + printf(" modhead file.fits dec 30.0 - set DEC = 30.0 \n"); + printf("\n"); + printf(" modhead \"file.fits[2]\" OBSTIME - list OBSTIME from extention 2 \n"); + printf(" modhead file.fits+2 OBSTIME - list OBSTIME from extention 2\n"); + return(0); + } + + if (!fits_open_file(&fptr, argv[1], iomode, &status)) + { + if (fits_read_card(fptr,argv[2], card, &status)) + { + printf("Keyword does not exist\n"); + card[0] = '\0'; + comment[0] = '\0'; + status = 0; /* reset status after error */ + } + else + printf("%s\n",card); + + if (argc >= 4) /* write or overwrite the keyword */ + { + /* check if this is a protected keyword that must not be changed */ + if (*card && fits_get_keyclass(card) == TYP_STRUC_KEY) + { + printf("Protected keyword cannot be modified.\n"); + } + else + { + /* get the comment string */ + if (*card)fits_parse_value(card, oldvalue, comment, &status); + + /* construct template for new keyword */ + strcpy(newcard, argv[2]); /* copy keyword name */ + strcat(newcard, " = "); /* '=' value delimiter */ + if (argc == 4) strcat(newcard, argv[3]); /* new value */ + else { + strcat(newcard, "'"); + for (i = 3; i < argc-1; i++) { + strcat(newcard, argv[i]); /* new value */ + strcat(newcard, " "); + } + strcat(newcard, argv[i]); /* new value */ + strcat(newcard, "'"); + } + + if (*comment) { + strcat(newcard, " / "); /* comment delimiter */ + strcat(newcard, comment); /* append the comment */ + } + + /* reformat the keyword string to conform to FITS rules */ + fits_parse_template(newcard, card, &keytype, &status); + + /* overwrite the keyword with the new value */ + fits_update_card(fptr, argv[2], card, &status); + + printf("Keyword has been changed to:\n"); + printf("%s\n",card); + } + } /* if argc == 4 */ + fits_close_file(fptr, &status); + } /* open_file */ + + /* if error occured, print out error message */ + if (status) fits_report_error(stderr, status); + return(status); +} + diff --git a/src/analysis/remove_target_orbital_motion.c b/src/analysis/remove_target_orbital_motion.c new file mode 100644 index 0000000..d104b0d --- /dev/null +++ b/src/analysis/remove_target_orbital_motion.c @@ -0,0 +1,503 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * + * + * Usage: + * remove_target_orbital_motion [-hb] [-v level] + * input_idf_file output_idf_file + * hjd0 period vrmax + * [ra_h ra_m ra_s dec_d dec_m dec_s] + * + * Arguments: + * mjd0 : Heliocentric or Geocentric + * Julian Day + * of closest approch on orbit. + * period : Period in seconds. + * vrmax : Maximum radial velocity in km/s + * ra_h ra_m ra_s dec_d dec_m dec_s : (Optional) RA and DEC of target. + * If present mjd0 is interpreted + * as Heliocentric. + * + * Options: + * -h: this help message + * -v: verbosity level (=1; 0 is silent) + * -b: update timeline doppler information (required for BPM) + * + * + * History: 12/01/03 bjg v1.0 Begin work. + * 12/02/03 bjg Changed calling + * parameters format. + * 12/04/03 bjg Number of elements in HDU2 + * is now determined from HDU2 + * header instead of HDU1 + * header NEVENTS keyword + * 12/10/03 bjg Updated header. + * 04/05/04 bjg Remove unused variables + * 06/10/04 bjg Some code cleaning + * 10/07/04 bjg v1.1 Added heliocentric + * time correction (optional) + * Added timeline doppler + * correction information + * (optional) for cf_bad_pixels + * 10/26/04 bjg v1.2 Cosmetic change + * + ****************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#include "calfuse.h" + + + + +#define LIGHT_SPEED 299792.458 /* speed of light in kilometers per second */ +#define SECONDS_PER_DAY (24.0*3600.0) + +static char CF_PRGM_ID[]= "remove_target_orbital_motion"; +static char CF_VER_NUM[]= "1.2"; + +struct key { + char keyword[FLEN_KEYWORD]; + float value; +}; + + +double gethmjd(double, int, int, float, int, int, float); + +int main(int argc,char *argv[]){ + + + char fmt_byte[FLEN_CARD],fmt_float[FLEN_CARD],fmt_short[FLEN_CARD]; + + fitsfile * infits; + fitsfile * outfits; + + char input_filename[FLEN_CARD],output_filename[FLEN_CARD]; + char * corrected_filename; + char * string_pointer; + + int intnull=0,anynull; + int status=0; + int hdutype=0; + int ncol; + char tempstring[FLEN_CARD]; + char tempchar; + char keyword[FLEN_CARD],card[FLEN_CARD]; + + + struct key hdu4_tscal[16]; + struct key hdu4_tzero[16]; + + char hdu4_extname[]="TIMELINE"; + int hdu4_tfields=16; /* output table will have 16 columns */ + char *hdu4_ttype[]={"TIME", "STATUS_FLAGS", "TIME_SUNRISE", "TIME_SUNSET", + "LIMB_ANGLE", "LONGITUDE", "LATITUDE", "ORBITAL_VEL", + "HIGH_VOLTAGE", "LIF_CNT_RATE", "SIC_CNT_RATE", + "FEC_CNT_RATE", "AIC_CNT_RATE", "BKGD_CNT_RATE", + "YCENT_LIF","YCENT_SIC"}; + + char *hdu4_tform[16]; /* we will define tform later, when the number + of photons is known */ + + char *hdu4_tunit[]={"seconds", "unitless", "seconds", "seconds", "degrees", + "degrees", "degrees", "km/s", "unitless", "counts/sec", + "counts/sec", "counts/sec", "counts/sec", "counts/sec", + "pixels","pixels" }; + + + long nevents, nrecords; + long i; + + float * floatlist; + short * shortlist; + char * charlist; + + double * hdu4_time; + double * hdu4_orbvel; + + double * hdu2_time; + double * hdu2_lambda; + + double delta_t; + double period, vrmax, mjd0; + double expstart, mjd; + + int rah,ram,decd,decm; + float ras,decs; + + int optc; + + char opts[] = "hbv:"; + + char usage[] = + "Usage:\n" + " remove_target_orbital_motion [-hb] [-v level] \n" + " input_idf_file output_idf_file\n" + " mjd0 period vrmax\n" + " [ra_h ra_m ra_s dec_d dec_m dec_s]\n"; + char argument[] = + "Arguments:\n" + " mjd0 : (Geocentric or Heliocentric) Modified Julian Day\n" + " of closest approch on orbit.\n" + " period : Period in seconds.\n" + " vrmax : Maximum radial velocity in km/s\n" + " ra_h ra_m ra_s dec_d dec_m dec_s : Optional RA and DEC of target.\n" + " If present mjd0 is interpreted\n" + " as Heliocentric. \n"; + + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n" + " -b: update timeline doppler information (required for BPM)\n"; + + + + int bigtime=1; /* How to store TSUNRISE and TSUNSET" */ + int do_timeline=0; + int helio_corr=0; + + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s\n%s", usage, argument, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + case 'b': + do_timeline=1; + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if ((argc != optind+11)&&(argc != optind+5)) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + if (argc==optind+11) helio_corr=1; + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + strcpy(input_filename,argv[optind]); + strcpy(output_filename,argv[optind+1]); + + sscanf(argv[optind+2],"%lf",&mjd0); + sscanf(argv[optind+3],"%lf",&period); + sscanf(argv[optind+4],"%lf",&vrmax); + + cf_verbose(1,"Target Orbital Motion Doppler Correction"); + cf_verbose(1,"Processing file %s",input_filename); + + if (helio_corr) { + sscanf(argv[optind+5],"%d",&rah); + sscanf(argv[optind+6],"%d",&ram); + sscanf(argv[optind+7],"%f",&ras); + sscanf(argv[optind+8],"%d",&decd); + sscanf(argv[optind+9],"%d",&decm); + sscanf(argv[optind+10],"%f",&decs); + cf_verbose(1,"Right Ascension of target: %d h %d m %f s",rah,ram,ras); + cf_verbose(1,"Declination of target: %d deg %d m %f s",decd,decm,decs); + cf_verbose(1,"Heliocentric Modified Julian Day of closest approch on orbit: %lf",mjd0); + } else { + cf_verbose(1,"Geocentric Modified Julian Day of closest approch on orbit: %lf",mjd0); + } + + cf_verbose(1,"Period in seconds: %lf",period); + cf_verbose(1,"Maximum radial velocity in kilometers per second: %lf",vrmax); + + + + FITS_open_file(&infits,input_filename,READONLY,&status); + FITS_read_key(infits,TDOUBLE,"EXPSTART",&(expstart),NULL,&status); + + FITS_create_file(&outfits,output_filename,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + string_pointer=strrchr(output_filename,'/'); + if (string_pointer==NULL) corrected_filename=output_filename; + else corrected_filename=&(string_pointer[1]); + + FITS_update_key(outfits,TSTRING,"FILENAME",corrected_filename,NULL,&status); + + strcpy(tempstring,""); + + FITS_update_key(outfits,TSTRING,"BPM_CAL",tempstring,NULL,&status); + + + + FITS_movabs_hdu(infits,2,&hdutype,&status); + FITS_read_key(infits,TSTRING,"TFORM1",tempstring,NULL,&status); + sscanf(tempstring,"%ld%c",&nevents,&tempchar); + + FITS_create_hdu(outfits,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + + hdu2_time=(double *)malloc(nevents*sizeof(double)); + hdu2_lambda=(double *)malloc(nevents*sizeof(double)); + + + + FITS_get_colnum(infits, TRUE, "TIME", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nevents, &intnull, + hdu2_time, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "LAMBDA", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nevents, &intnull, + hdu2_lambda, &anynull, &status); + + + + + cf_verbose(1,"Geocentric Modified Julian Day of start of observation/exposure is: %f",expstart); + if (helio_corr) { + mjd=gethmjd(expstart,rah,ram,ras,decd,decm,decs); + cf_verbose(1,"Heliocentric Modified Julian Day of start of observation/exposure is: %f",mjd); + } + + for (i=0;i<nevents;i++){ + + mjd=expstart+(hdu2_time[i])/SECONDS_PER_DAY; + + if (helio_corr) mjd=gethmjd(mjd,rah,ram,ras,decd,decm,decs); + + delta_t=(mjd-mjd0)*SECONDS_PER_DAY; + + hdu2_lambda[i]=hdu2_lambda[i]*(1-(vrmax/LIGHT_SPEED)*sin(2*M_PI*delta_t/period)); + + } + + FITS_get_colnum(outfits, TRUE, "LAMBDA", &ncol, &status); + FITS_write_col(outfits, TDOUBLE, ncol, 1, 1, nevents, hdu2_lambda, &status); + + + free(hdu2_time); + free(hdu2_lambda); + + + FITS_movabs_hdu(infits,3,&hdutype,&status); + FITS_create_hdu(outfits,&status); + FITS_copy_hdu(infits,outfits,0,&status); + + + FITS_movabs_hdu(infits,4,&hdutype,&status); + + if (do_timeline) { + + FITS_read_key(infits,TSTRING,"TFORM1",tempstring,NULL,&status); + sscanf(tempstring,"%ld%c",&nrecords,&tempchar); + + /* Generate the tform array */ + sprintf(fmt_byte, "%ldB", nrecords); + sprintf(fmt_float, "%ldE", nrecords); + sprintf(fmt_short, "%ldI", nrecords); + + + + hdu4_tform[0] = fmt_float; + hdu4_tform[1] = fmt_byte; + + for (i=2; i<hdu4_tfields; i++) hdu4_tform[i] = fmt_short; + + /* Set TSCALE and TZERO values */ + /* Not all of these will be used; see below. */ + for (i=2; i<hdu4_tfields; i++) { + sprintf(hdu4_tscal[i].keyword, "TSCAL%ld", i+1); + hdu4_tscal[i].value = 0.1; + sprintf(hdu4_tzero[i].keyword, "TZERO%ld", i+1); + hdu4_tzero[i].value = 0.; + } + + /* Need TZEROn = 3000. for tsunrise and tsunset. */ + hdu4_tzero[2].value = hdu4_tzero[3].value = 3000.; + + /* Let's keep three significant figures for vorb. */ + hdu4_tscal[7].value = 0.01; + + /* FEC_CNT_RATE and AIC_CNT_RATE can get big, so we + (essentially) store them as unsigned shorts. */ + hdu4_tscal[11].value = 1; + hdu4_tscal[12].value = 1; + hdu4_tzero[11].value = 32768; + hdu4_tzero[12].value = 32768; + + + if (bigtime) { + hdu4_tform[2]=hdu4_tform[3]=fmt_float; + } + + hdu4_tform[7]=fmt_float; + + /* Append a new empty binary table to the output file */ + FITS_create_tbl(outfits, BINARY_TBL, 1, hdu4_tfields, hdu4_ttype, hdu4_tform, + hdu4_tunit, hdu4_extname, &status); + + + + /* Write TSCALE and TZERO entries to header */ + for (i=2; i<hdu4_tfields; i++) { + + /* If bigtime is TRUE, store tsunrise and tsunset as floats.*/ + if ((i == 2 || i == 3) && bigtime) continue; + + /* Omit TSCALE and TZERO for these four arrays. */ + if (i == 8) continue; /* HIGH_VOLTAGE */ + if (i == 9) continue; /* LIF_CNT_RATE */ + if (i == 10) continue; /* SIC_CNT_RATE */ + if (i == 13) continue; /* BKGD_CNT_RATE */ + + + /* Store ORBITAL_VEL as float */ + if (i == 7) continue; + + + sprintf(keyword, "TUNIT%ld", i+1); + if (fits_read_keyword(outfits, keyword, card, NULL, &status)) + cf_if_fits_error(status); + FITS_insert_key_flt(outfits, hdu4_tscal[i].keyword, hdu4_tscal[i].value, + -1, NULL, &status); + FITS_insert_key_flt(outfits, hdu4_tzero[i].keyword, hdu4_tzero[i].value, + -5, NULL, &status); + + } + + floatlist=(float *)malloc(nrecords*sizeof(float)); + shortlist=(short *)malloc(nrecords*sizeof(short)); + charlist=(char *)malloc(nrecords*sizeof(char)); + hdu4_time=(double *)malloc(nevents*sizeof(double)); + hdu4_orbvel=(double *)malloc(nevents*sizeof(double)); + + FITS_get_colnum(infits, TRUE, "TIME", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nrecords, &intnull, + hdu4_time, &anynull, &status); + FITS_write_col(outfits, TDOUBLE, 1, 1, 1, nrecords, hdu4_time, &status); + + FITS_get_colnum(infits, TRUE, "STATUS_FLAGS", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, nrecords, &intnull, + charlist, &anynull, &status); + FITS_write_col(outfits, TBYTE, 2, 1, 1, nrecords, charlist, &status); + + FITS_get_colnum(infits, TRUE, "TIME_SUNRISE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 3, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "TIME_SUNSET", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 4, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LIMB_ANGLE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 5, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LONGITUDE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 6, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LATITUDE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 7, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "ORBITAL_VEL", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nrecords, &intnull, + hdu4_orbvel, &anynull, &status); + + for (i=0;i<nrecords;i++){ + + mjd=expstart+(hdu4_time[i])/SECONDS_PER_DAY; + + if (helio_corr) mjd=gethmjd(mjd,rah,ram,ras,decd,decm,decs); + + delta_t=(mjd-mjd0)*SECONDS_PER_DAY; + + hdu4_orbvel[i]=hdu4_orbvel[i]-vrmax*sin(2*M_PI*delta_t/period); + + } + + + FITS_write_col(outfits, TDOUBLE, 8, 1, 1, nrecords, hdu4_orbvel, &status); + + FITS_get_colnum(infits, TRUE, "HIGH_VOLTAGE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 9, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "LIF_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 10, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "SIC_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 11, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "FEC_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 12, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "AIC_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 13, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "BKGD_CNT_RATE", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 14, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "YCENT_LIF", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 15, 1, 1, nrecords, floatlist, &status); + + FITS_get_colnum(infits, TRUE, "YCENT_SIC", &ncol, &status); + FITS_read_col(infits, TFLOAT, ncol, 1, 1, nrecords, &intnull, + floatlist, &anynull, &status); + FITS_write_col(outfits, TFLOAT, 16, 1, 1, nrecords, floatlist, &status); + + + free(hdu4_time); + free(hdu4_orbvel); + + free(floatlist); + free(charlist); + free(shortlist); + + } else { + FITS_create_hdu(outfits,&status); + FITS_copy_hdu(infits,outfits,0,&status); + } + + FITS_close_file(infits,&status); + FITS_close_file(outfits,&status); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + diff --git a/src/analysis/ttag_combine.c b/src/analysis/ttag_combine.c new file mode 100644 index 0000000..77da230 --- /dev/null +++ b/src/analysis/ttag_combine.c @@ -0,0 +1,520 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: ttag_combine outfile file1 file2 file3 file4 file5 ... + * + * Description: Reads multiple contiguous ttag files and concatenates them + * into a single file. For now, the input files should be + * listed in time order. + * + * History: 08/16/99 emurphy Begin work + * 08/27/99 emurphy Added comments. Good time intervals + * now match observing times. + * 10/09/99 emurphy exptime now sum of individual exptimes + * 08/20/01 v1.2 wvd Complain if FPA moves between exposures. + * Set MAXGTI = 2000. + * 10/01/01 v1.3 RDR Update all segment and active image counters + * DATE keyword now contains the date + * NEVENTS reflects total number of events in + * combined file + * EXP_ID defaults to 999 to signify combined + * data + * Print warning if FPA x position changes + * by more than 30 microns + * PLANTIME now reflects total planned exposure + * Will transfer DX, DY and DNFLG columns + * if available + * 10/09/01 v1.4 wvd Delete redundant check for FPA splits. + * Program complains if input files not in + * time order. + * 01/15/02 v1.5 wvd Update keyword EXPNIGHT. + * 02/13/02 v1.6 wvd Respond gracefully if EXPNIGHT does not exist. + * 02/20/02 wvd Update keyword RAWTIME, if it exists. + * 04/26/02 v1.7 wvd Change vtime to type time_t + * 12/11/02 v1.8 wvd Change EXPNIGHT to type long + * 02/20/03 v1.9 wvd Correct errors in pointer use. + * Change abs() to fabs(). + * 03/22/04 v1.10 bjg Change cf_fpa_pos() to cf_read_fpa_pos() + * 04/05/04 v1.11 bjg Include math.h + * Remove unused variables + * Change formats to match arg type + * in printf + * + * + ****************************************************************************/ + +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <math.h> +#include "calfuse.h" + +static char CF_PRGM_ID[] = "ttag_combine"; +static char CF_VER_NUM[] = "1.11"; + +#define MAXGTI 2000 /* Maximum number of good time intervals */ + +static int +cf_dtcor_read_counters(fitsfile *infits, long *de, long *fe, long *ai1a, + long *ai1b, long *ai2a, long *ai2b, long *sic, long *lif, long *as, + double *ctm ) +{ + char cntstr[FLEN_CARD], detstr[FLEN_CARD]; + long de_b, de_e, fe_b, fe_e; + long ai1a_b, ai1a_e, ai1b_b, ai1b_e, ai2a_b, ai2a_e, ai2b_b, ai2b_e ; + long sic_b, sic_e, lif_b, lif_e, as_b, as_e ; + double ctm_b, ctm_e ; + int status=0; + + FITS_read_key(infits, TSTRING, "DETECTOR", detstr, NULL, &status); + + /* Segment 1A Counters */ + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"DE_B"); + FITS_read_key(infits, TLONG, cntstr, &de_b, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"DE_E"); + FITS_read_key(infits, TLONG, cntstr, &de_e, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"FE_B"); + FITS_read_key(infits, TLONG, cntstr, &fe_b, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"FE_E"); + FITS_read_key(infits, TLONG, cntstr, &fe_e, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"SIC_B"); + FITS_read_key(infits, TLONG, cntstr, &sic_b, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"SIC_E"); + FITS_read_key(infits, TLONG, cntstr, &sic_e, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"LIF_B"); + FITS_read_key(infits, TLONG, cntstr, &lif_b, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"LIF_E"); + FITS_read_key(infits, TLONG, cntstr, &lif_e, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"AS_B"); + FITS_read_key(infits, TLONG, cntstr, &as_b, NULL, &status); + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"AS_E"); + FITS_read_key(infits, TLONG, cntstr, &as_e, NULL, &status); + + /* Active Image Counters */ + FITS_read_key(infits, TLONG, "C1AAI_B", &ai1a_b, NULL, &status); + FITS_read_key(infits, TLONG, "C1AAI_E", &ai1a_e, NULL, &status); + FITS_read_key(infits, TLONG, "C1BAI_B", &ai1b_b, NULL, &status); + FITS_read_key(infits, TLONG, "C1BAI_E", &ai1b_e, NULL, &status); + FITS_read_key(infits, TLONG, "C2AAI_B", &ai2a_b, NULL, &status); + FITS_read_key(infits, TLONG, "C2AAI_E", &ai2a_e, NULL, &status); + FITS_read_key(infits, TLONG, "C2BAI_B", &ai2b_b, NULL, &status); + FITS_read_key(infits, TLONG, "C2BAI_E", &ai2b_e, NULL, &status); + FITS_read_key(infits, TDOUBLE, "CTIME_B", &ctm_b, NULL, &status); + FITS_read_key(infits, TDOUBLE, "CTIME_E", &ctm_e, NULL, &status); + + + *de = de_e - de_b; + *fe= fe_e - fe_b; + *ai1a = ai1a_e - ai1a_b ; + *ai1b = ai1b_e - ai1b_b ; + *ai2a = ai2a_e - ai2a_b ; + *ai2b = ai2b_e - ai2b_b ; + *sic = sic_e - sic_b ; + *lif = lif_e - lif_b ; + *as = as_e - as_b ; + *ctm = ctm_e - ctm_b ; + + return 0; +} + +int main(int argc, char *argv[]) +{ + int i, j, k; + char buffer[FLEN_CARD], comment[FLEN_CARD], stime[FLEN_CARD]; + char cntstr[FLEN_CARD], detstr[FLEN_CARD]; + char expid[FLEN_CARD], procstep[FLEN_CARD] ; + long de, fe, de_tot, fe_tot, fe_b, de_b, fe_e, de_e; + long ai1a, ai1b, ai2a, ai2b, ai1a_tot, ai1b_tot, ai2a_tot; + long ai2b_tot,ai1a_b, ai1a_e, ai1b_b, ai1b_e, ai2a_b ; + long ai2a_e, ai2b_b, ai2b_e, sic_b, sic_e, sic_tot, sic ; + long lif_b, lif_e, lif_tot, lif, as_b, as_e, as_tot, as ; + long expnight, indnight; + int status=0, nfiles=0, hdutype=0, nkeys, keynum, anynull; + fitsfile *infits, *outfits; + long nevents, jrow, ngti, ngti_in; + char *pha_in, *dnflg ; + short *x_in, *y_in; + float *time_in, *gti_start, *gti_stop; + float *gti_start_in, *gti_stop_in, *dx, *dy ; + float fpasx0, fpasx, fpalx0, fpalx, dfpasx, dfpalx ; + double mjd_init, mjd_start, mjd_end, exptime, mjd_last=0, indtime; + double rawtime, trawtime; + double ctm, ctm_b, ctm_e, ctm_tot ; + int plantime, procflg ; + long tplantime ; + int tcol_in, xcol_in, ycol_in, phacol_in, startcol ,stopcol; + int tcol_out, xcol_out, ycol_out, phacol_out; + int dxcol_in, dxcol_out, dycol_in, dycol_out,dnflgcol_in; + int dnflgcol_out ; + int fpa_split = FALSE; + time_t vtime; + + + if (argc < 3) { + printf("Incorrect number of arguments.\n"); + printf("Calling sequence:ttag_combine output_file input_file1 input_file2 input_file3 ...\n"); + exit(1); + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + /* get and display time */ + vtime = time(NULL) ; + strcpy(stime,ctime(&vtime)) ; + + jrow=1; + de_tot=0 ; + fe_tot=0 ; + ai1a_tot=0 ; + ai1b_tot=0 ; + ai2a_tot=0 ; + ai2b_tot=0 ; + sic_tot=0 ; + lif_tot=0 ; + as_tot=0 ; + ctm_tot=0. ; + procflg=-1 ; + gti_start = (float *) cf_malloc(sizeof(float) * 1000); + gti_stop = (float *) cf_malloc(sizeof(float) * 1000); + + gti_start[0] = 0.0; + gti_stop[0] = 0.0; + + nfiles = argc-1; + + exptime=0.0; + expnight=0; + trawtime=0.0; + tplantime=0; + + ngti=0; /* is the number of new good time intervals */ + + for (i=2; i<=nfiles; i++) { + printf("Processing %-60.60s\n",argv[i]); + FITS_open_file(&infits, argv[i], READONLY, &status); + + if (i==2) { + FITS_read_key(infits, TDOUBLE, "EXPSTART", &mjd_init, + NULL, &status); + mjd_last=mjd_start=mjd_init; + FITS_read_key(infits, TDOUBLE, "EXPEND", &mjd_end, + NULL, &status); + FITS_read_key(infits, TSTRING, "INIT_COR", procstep, + NULL, &status) ; + cf_read_fpa_pos (infits, &fpasx0, &fpalx0); + FITS_create_file(&outfits, argv[1], &status); + FITS_copy_hdu(infits, outfits, 0, &status); + FITS_create_hdu(outfits, &status); + FITS_movabs_hdu(infits,2,&hdutype,&status); + FITS_get_hdrpos(infits, &nkeys, &keynum, &status); + for (j=1; j<=nkeys; j++) { + FITS_read_record(infits, j, buffer, &status); + FITS_write_record(outfits, buffer, &status); + } + /* adjust some initial keywords */ + nevents=0; + FITS_update_key(outfits, TLONG, "NAXIS2", &nevents, + NULL, &status); + /* set a flag (procflg) if the file is processed in any way */ + if ( strncmp(procstep, "COMP", 4) == 0) { + printf("file has been processed - setting flag \n") ; + procflg = 1 ; } + else printf("These are raw data files \n") ; + } else { + FITS_read_key(infits, TDOUBLE, "EXPSTART", &mjd_start, + NULL, &status); + if (mjd_start < mjd_last) + cf_if_error("Files must be in time order, first to last."); + mjd_last=mjd_start; + FITS_read_key(infits, TDOUBLE, "EXPEND", &mjd_end, + NULL, &status); + cf_read_fpa_pos (infits, &fpasx, &fpalx); + dfpasx = fpasx - fpasx0 ; + dfpalx = fpalx - fpalx0 ; + if (fabs((double)dfpasx) > 30.) { + printf("\nLarge change in SIC FPA X position: %f \n",dfpasx) ; + fpa_split = TRUE; + } + if (fabs((double)dfpalx) > 30.) { + printf("\nLarge change in LIF FPA X position: %f \n",dfpalx) ; + fpa_split = TRUE; + } + } + + FITS_movabs_hdu(infits,1,&hdutype,&status); + + FITS_read_key(infits, TDOUBLE, "EXPTIME", &indtime, + NULL, &status); + exptime+=indtime; + + fits_read_key(infits, TDOUBLE, "RAWTIME", &rawtime, + NULL, &status); + if (status) + status = 0; + else + trawtime+=rawtime; + + FITS_read_key(infits, TINT, "PLANTIME", &plantime, + NULL, &status); + tplantime+=plantime ; + + fits_read_key(infits, TLONG, "EXPNIGHT", &indnight, + NULL, &status); + if (status) + status = 0; + else + expnight+=indnight; + + cf_dtcor_read_counters(infits,&de,&fe,&ai1a,&ai1b,&ai2a,&ai2b, + &sic,&lif,&as,&ctm) ; + + de_tot += de; + fe_tot += fe; + ai1a_tot += ai1a ; + ai1b_tot += ai1b ; + ai2a_tot += ai2a ; + ai2b_tot += ai2b ; + sic_tot += sic ; + lif_tot += lif ; + as_tot += as ; + ctm_tot += ctm ; + + FITS_movabs_hdu(infits,2,&hdutype,&status); + /* Get the number of events in the input file. */ + FITS_read_key(infits, TLONG, "NAXIS2", &nevents, NULL, &status); + + printf(" EXPTIME=%10.3f NEVENTS=%10ld\n",indtime,nevents); + + /* Allocate space for the input and output times, coords, + pha */ + time_in = (float *) cf_malloc(sizeof(float) * nevents); + x_in = (short *) cf_malloc(sizeof(short) * nevents); + y_in = (short *) cf_malloc(sizeof(short) * nevents); + pha_in = (char *) cf_malloc(sizeof(char) * nevents); + dx = (float *) cf_malloc(sizeof(float) * nevents); + dy = (float *) cf_malloc(sizeof(float) * nevents); + dnflg = (char *) cf_malloc(sizeof(char) * nevents); + + FITS_get_colnum(infits, TRUE, "TIME", &tcol_in, &status); + FITS_get_colnum(infits, TRUE, "X", &xcol_in, &status); + FITS_get_colnum(infits, TRUE, "Y", &ycol_in, &status); + FITS_get_colnum(infits, TRUE, "PHA", &phacol_in, &status); + if(procflg > 0) { + FITS_get_colnum(infits, TRUE, "DX", &dxcol_in, &status); + FITS_get_colnum(infits, TRUE, "DY", &dycol_in, &status); + FITS_get_colnum(infits, TRUE, "DNFLG",&dnflgcol_in, &status); } + + FITS_get_colnum(outfits, TRUE, "TIME", &tcol_out, &status); + FITS_get_colnum(outfits, TRUE, "X", &xcol_out, &status); + FITS_get_colnum(outfits, TRUE, "Y", &ycol_out, &status); + FITS_get_colnum(outfits, TRUE, "PHA", &phacol_out, &status); + if (procflg > 0 ) { + FITS_get_colnum(outfits, TRUE, "DX", &dxcol_out, &status); + FITS_get_colnum(outfits, TRUE, "DY", &dycol_out, &status); + FITS_get_colnum(outfits, TRUE, "DNFLG",&dnflgcol_out, &status);} + + FITS_read_col(infits, TFLOAT, tcol_in, 1, 1, nevents, NULL, + time_in, &anynull, &status); + FITS_read_col(infits, TSHORT, xcol_in, 1, 1, nevents, NULL, + x_in, &anynull, &status); + FITS_read_col(infits, TSHORT, ycol_in, 1, 1, nevents, NULL, + y_in, &anynull, &status); + FITS_read_col(infits, TBYTE, phacol_in, 1, 1, nevents, NULL, + pha_in, &anynull, &status); + if(procflg > 0) { + FITS_read_col(infits, TFLOAT, dxcol_in, 1, 1, nevents, NULL, + dx, &anynull, &status); + FITS_read_col(infits, TFLOAT, dycol_in, 1, 1, nevents, NULL, + dy, &anynull, &status); + FITS_read_col(infits, TBYTE, dnflgcol_in, 1, 1, nevents, NULL, + dnflg, &anynull, &status);} + + for (j=0; j<nevents; j++){ + time_in[j]+=(float) ((mjd_start-mjd_init)*86400.0); + } + + FITS_write_col(outfits, TFLOAT, tcol_out, jrow, 1, + nevents, time_in, &status); + FITS_write_col(outfits, TSHORT, xcol_out, jrow, 1, + nevents, x_in, &status); + FITS_write_col(outfits, TSHORT, ycol_out, jrow, 1, + nevents, y_in, &status); + FITS_write_col(outfits, TBYTE, phacol_out, jrow, 1, + nevents, pha_in, &status); + if (procflg > 0) { + FITS_write_col(outfits, TFLOAT, dxcol_out, jrow, 1, + nevents, dx, &status); + FITS_write_col(outfits, TFLOAT, dycol_out, jrow, 1, + nevents, dy, &status); + FITS_write_col(outfits, TBYTE, dnflgcol_out, jrow, 1, + nevents, dnflg, &status); } + jrow+=nevents; + + free(time_in); + free(x_in); + free(y_in); + free(pha_in); + free(dx) ; + free(dy) ; + free(dnflg) ; + + + /* Copy GTI from input to output */ + FITS_movabs_hdu(infits, 3, &hdutype, &status); + FITS_read_key(infits, TLONG, "NAXIS2", &ngti_in, NULL, &status); + gti_start_in = (float *) cf_malloc(sizeof(float) * ngti_in); + gti_stop_in = (float *) cf_malloc(sizeof(float) * ngti_in); + FITS_get_colnum(infits, TRUE, "START", &startcol, &status); + FITS_get_colnum(infits, TRUE, "STOP", &stopcol, &status); + FITS_read_col(infits, TFLOAT, startcol, 1, 1, ngti_in, 0, + gti_start_in, &anynull, &status); + FITS_read_col(infits, TFLOAT, stopcol, 1, 1, ngti_in, 0, + gti_stop_in, &anynull, &status); + for (k=0; k<ngti_in; k++) { + gti_start[ngti]=gti_start_in[k]+ + (float) ((mjd_start-mjd_init)*86400.0);; + gti_stop[ngti]=gti_stop_in[k]+ + (float) ((mjd_start-mjd_init)*86400.0);; + ngti++; + if (ngti >= MAXGTI) { + sprintf(buffer, "More than %d good time intervals.",MAXGTI) ; + cf_if_error(buffer); + } + } + free(gti_start_in); + free(gti_stop_in); + + FITS_close_file(infits, &status); + } + + FITS_flush_file(outfits, &status); + + FITS_movabs_hdu(outfits, 1, &hdutype, &status); + jrow=jrow-1 ; + FITS_update_key(outfits, TLONG, "NEVENTS", &jrow, 0, &status) ; + FITS_update_key(outfits, TDOUBLE, "EXPTIME", &exptime, 0, &status); + FITS_update_key(outfits, TDOUBLE, "EXPEND", &mjd_end, 0, &status); + FITS_update_key(outfits, TLONG, "PLANTIME", &tplantime, 0, &status) ; + + if (expnight < 0) + expnight = 0; + FITS_update_key(outfits, TLONG, "EXPNIGHT", &expnight, 0, &status); + + if (trawtime - exptime > -1.) + FITS_update_key(outfits, TDOUBLE, "RAWTIME", &trawtime, 0, &status); + + FITS_read_key(outfits, TSTRING, "DETECTOR", detstr, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"FE_B"); + FITS_read_key(outfits, TLONG, cntstr, &fe_b, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"DE_B"); + FITS_read_key(outfits, TLONG, cntstr, &de_b, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"SIC_B"); + FITS_read_key(outfits, TLONG, cntstr, &sic_b, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"LIF_B"); + FITS_read_key(outfits, TLONG, cntstr, &lif_b, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"AS_B"); + FITS_read_key(outfits, TLONG, cntstr, &as_b, NULL, &status); + + FITS_read_key(outfits, TLONG, "C1AAI_B", &ai1a_b, NULL, &status); + FITS_read_key(outfits, TLONG, "C1BAI_B", &ai1b_b, NULL, &status); + FITS_read_key(outfits, TLONG, "C2AAI_B", &ai2a_b, NULL, &status); + FITS_read_key(outfits, TLONG, "C2BAI_B", &ai2b_b, NULL, &status); + FITS_read_key(outfits, TDOUBLE, "CTIME_B", &ctm_b, NULL, &status); + + sprintf(comment, "New ID for combined data") ; + strncpy(expid,"999 ",18) ; + expid[18]='\0' ; + FITS_update_key(outfits, TSTRING, "EXP_ID", expid, comment, &status); + + sprintf(comment, "Date and time file was created") ; + stime[24]='\0' ; + FITS_update_key(outfits, TSTRING, "DATE", stime, comment, &status) ; + + de_e = de_tot + de_b; + fe_e = fe_tot + fe_b; + lif_e = lif_tot + lif_b ; + sic_e = sic_tot + sic_b ; + as_e = as_tot + as_b ; + ctm_e = ctm_tot + ctm_b ; + ai1a_e = ai1a_tot + ai1a_b ; + ai1b_e = ai1b_tot + ai1b_b ; + ai2a_e = ai2a_tot + ai2a_b ; + ai2b_e = ai2b_tot + ai2b_b ; + + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"DE_E"); + FITS_update_key(outfits, TLONG, cntstr, &de_e, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"FE_E"); + FITS_update_key(outfits, TLONG, cntstr, &fe_e, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"SIC_E"); + FITS_update_key(outfits, TLONG, cntstr, &sic_e, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%5.5s","C",detstr,"LIF_E"); + FITS_update_key(outfits, TLONG, cntstr, &lif_e, NULL, &status); + sprintf(cntstr, "%1.1s%2.2s%4.4s","C",detstr,"AS_E"); + FITS_update_key(outfits, TLONG, cntstr, &as_e, NULL, &status); + + FITS_update_key(outfits, TLONG, "C1AAI_E", &ai1a_e, NULL, &status); + FITS_update_key(outfits, TLONG, "C1BAI_E", &ai1b_e, NULL, &status); + FITS_update_key(outfits, TLONG, "C2AAI_E", &ai2a_e, NULL, &status); + FITS_update_key(outfits, TLONG, "C2BAI_E", &ai2b_e, NULL, &status); + FITS_update_key(outfits, TDOUBLE, "CTIME_E", &ctm_e, NULL, &status); + + + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, "CF_TTAG_COMBINE", &status); + FITS_write_comment(outfits, " ", &status); + FITS_write_comment(outfits, "This file is a concatenation of:", &status); + for (i=2; i<=nfiles; i++) { + FITS_write_comment(outfits, argv[i], &status); + } + + + FITS_open_file(&infits, argv[2], READONLY, &status); + + /* Move to the second extension which contains the goof time intervals. */ + FITS_movabs_hdu(infits, 3, &hdutype, &status); + + /* Create the second extension in the output file. */ + FITS_create_hdu(outfits, &status); + + /* Copy the header of the input file to the output file. */ + FITS_get_hdrpos(infits, &nkeys, &keynum, &status); + for (i=1; i<=nkeys; i++) { + FITS_read_record(infits, i, buffer, &status); + FITS_write_record(outfits, buffer, &status); + } + + FITS_get_colnum(outfits,TRUE,"START",&startcol,&status); + FITS_get_colnum(outfits,TRUE,"STOP",&stopcol,&status); + + FITS_write_col(outfits, TFLOAT, startcol, 1, 1, ngti, gti_start, &status); + FITS_write_col(outfits, TFLOAT, stopcol, 1, 1, ngti, gti_stop, &status); + + free(gti_start); + free(gti_stop); + + FITS_close_file(infits, &status); + FITS_close_file(outfits, &status); + + if (fpa_split) + cf_if_warning("FPA motion detected. Resolution may be compromised.\n"); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return 0; +} diff --git a/src/analysis/ttag_lightcurve.c b/src/analysis/ttag_lightcurve.c new file mode 100644 index 0000000..f1a14fa --- /dev/null +++ b/src/analysis/ttag_lightcurve.c @@ -0,0 +1,398 @@ + +/************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ************************************************************************* + * + * + * Usage: + * ttag_lightcurve [-hf] [-v level] input_file output_file windows_file + * bins LiForSiC + * + * + * Arguments: + * input_file : ttag IDF file + * output_file : ASCII file with 2 columns : + * - time (MJD) + * - countrate + * + * windows_file : input ASCII file with 2 columns : + * - start of spectral windows + * - stop of spectral windows + * + * bins : bin size in seconds + * LiForSiC : 1=LiF, 2=SiC + * + * + * + * + * Options: + * -h: this help message + * -f: output calibrated flux (erg/cm2/s) instead of countrate + * -v: verbosity level (=1; 0 is silent) + * + * + * + * + * History: 10/06/04 bjg v1.0 + * 06/03/05 wvd v1.1 Delete unused variables. + * + ***************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#include "calfuse.h" + + + + +#define N_MAX_WIN 100 /* Maximum number of spectral windows */ + +typedef struct { + float start; + float stop; +} interval; /* type to store a spectral window */ + + +int is_inside(float val,interval * interval_ptr, int nintervals); +int is_good_time(char timeflag,char * daynight); +int is_in_lif_channel(char channel, char * aperture); +int is_in_sic_channel(char channel, char * aperture); + + + + + +static char CF_PRGM_ID[]= "ttag_lightcurve"; +static char CF_VER_NUM[]= "1.1"; + + + + +int main(int argc,char *argv[]){ + + + + char input_filename[FLEN_CARD]; + char output_filename[FLEN_CARD]; + char windefs_filename[FLEN_CARD]; + + FILE * output_file; + FILE * windefs_file; + + fitsfile * infits; + + interval swindows[N_MAX_WIN]; /* the spectral windows are stored + in an array of intervals */ + int nwindows = 0; /* number of spectral windows TBD */ + + float bins; + + int intnull=0,anynull; + int status=0; + int hdutype=0; + + long nevents; + long i; + int ncol; + + char tempchar; + char tempstring[FLEN_CARD]; + + char daynight[FLEN_CARD]; + char instmode[FLEN_CARD]; + char aperture[FLEN_CARD]; + + double * hdu2_time; + double * hdu2_lambda; + double * hdu2_weight; + char * hdu2_channel; + char * hdu2_timeflgs; + char * hdu2_loc_flgs; + + float * gti_start; + float * gti_stop; + int ngtis; + + interval * gtis; + + double t, tmax, ctot; + + double expstart; + + int badtime; + + int LiForSiC; + + + int optc; + + int do_flux=0; + + char opts[] = "hfv:"; + char usage[] = + "Usage:\n" + " ttag_lightcurve [-hf] [-v level] input_file output_file windows_file\n" + " bins LiForSiC\n\n" + "Arguments:\n" + " input_file : ttag IDF file\n\n" + " output_file : ASCII file with 2 columns:\n" + " - time (MJD)\n" + " - countrate corrected for deadtime\n\n" + " windows_file : input ASCII file with 2 columns :\n" + " - start of spectral windows\n" + " - stop of spectral windows\n\n" + " bins : bin size in seconds\n" + " LiForSiC : 1=LiF, 2=SiC\n"; + char option[] = + "Options:\n" + " -h: this help message \n" + " -f: output calibrated flux (erg/cm2/s) instead of countrate \n" + " -v: verbosity level (=1; 0 is silent) \n"; + + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s", usage, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + case 'f': + do_flux=1; + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc != optind+5) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + strcpy(input_filename,argv[optind]); + strcpy(output_filename,argv[optind+1]); + strcpy(windefs_filename,argv[optind+2]); + sscanf(argv[optind+3],"%f",&bins); + sscanf(argv[optind+4],"%d",&LiForSiC); + + if ((LiForSiC>2)||(LiForSiC<1)) { + cf_if_error("%s\nLiForSiC value must be 1 (LiF) or 2 (SiC)", usage); + } + + + if (bins<=0) { + cf_if_error("Time interval is less than or equal to zero."); + } + + + /* Open the spectral windows definition file */ + if ((windefs_file = fopen (windefs_filename, "r")) == NULL){ + cf_if_error ("Unable to open file %s\n", windefs_filename); + } + + + /* Read the spectral windows definition file and store the spectral windows */ + while (fscanf(windefs_file,"%f %f",&((swindows[nwindows]).start), + &((swindows[nwindows]).stop))!=EOF) + { + nwindows++; + } + + + + + for (i=0;i<nwindows;i++){ + printf("Window %ld : %f - %f\n",i+1,swindows[i].start,swindows[i].stop); + } + + + + /* Create the output file */ + if ((output_file = fopen(output_filename,"w")) == NULL){ + fclose(windefs_file); + cf_if_error ("Unable to create file %s\n", output_filename); + } + + + + FITS_open_file(&infits,input_filename,READONLY,&status); + + FITS_read_key(infits,TSTRING,"INSTMODE",instmode,NULL,&status); + + if (strncasecmp(instmode,"TTAG",4)){ + FITS_close_file(infits,&status); + fclose(windefs_file); + fclose(output_file); + cf_if_error("Input file is not TTAG."); + } + + FITS_read_key(infits,TDOUBLE,"EXPSTART",&expstart,NULL,&status); + + FITS_read_key(infits,TSTRING,"DAYNIGHT",daynight,NULL,&status); + + FITS_read_key(infits,TSTRING,"APERTURE",aperture,NULL,&status); + + + FITS_movabs_hdu(infits,2,&hdutype,&status); + FITS_read_key(infits,TSTRING,"TFORM1",tempstring,NULL,&status); + sscanf(tempstring,"%ld%c",&nevents,&tempchar); + + + + + hdu2_time=(double *)malloc(nevents*sizeof(double)); + hdu2_lambda=(double *)malloc(nevents*sizeof(double)); + hdu2_weight=(double *)malloc(nevents*sizeof(double)); + hdu2_channel=(char *)malloc(nevents*sizeof(char)); + hdu2_timeflgs=(char *)malloc(nevents*sizeof(char)); + hdu2_loc_flgs=(char *)malloc(nevents*sizeof(char)); + + FITS_get_colnum(infits, TRUE, "TIME", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nevents, &intnull, + hdu2_time, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "LAMBDA", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nevents, &intnull, + hdu2_lambda, &anynull, &status); + + if (do_flux) { + FITS_get_colnum(infits, TRUE, "ERGCM2", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nevents, &intnull, + hdu2_weight, &anynull, &status); + } else { + FITS_get_colnum(infits, TRUE, "WEIGHT", &ncol, &status); + FITS_read_col(infits, TDOUBLE, ncol, 1, 1, nevents, &intnull, + hdu2_weight, &anynull, &status); + } + + FITS_get_colnum(infits, TRUE, "CHANNEL", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, nevents, &intnull, + hdu2_channel, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "TIMEFLGS", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, nevents, &intnull, + hdu2_timeflgs, &anynull, &status); + + FITS_get_colnum(infits, TRUE, "LOC_FLGS", &ncol, &status); + FITS_read_col(infits, TBYTE, ncol, 1, 1, nevents, &intnull, + hdu2_loc_flgs, &anynull, &status); + + + FITS_movabs_hdu(infits,3,&hdutype,&status); + + ngtis=cf_read_col(infits,TFLOAT,"START",(void **) >i_start); + ngtis=cf_read_col(infits,TFLOAT,"STOP",(void **) >i_stop); + + gtis=(interval *)malloc(ngtis*sizeof(interval)); + + for (i=0;i<ngtis;i++){ + gtis[i].start=gti_start[i]; + gtis[i].stop=gti_stop[i]; + } + + + + t=0.0; + tmax=bins; + i=0; + ctot=0.0; + badtime=0; + while (i<nevents){ + + while (hdu2_time[i]>=tmax) { + if (!(is_inside(t,gtis,ngtis))) badtime=1; + if (!(is_inside(tmax,gtis,ngtis))) badtime=1; + if (!badtime) fprintf(output_file,"%15lf %15lf\n",expstart+t/(3600.0*24.0),ctot/bins); + t=tmax; + tmax=t+bins; + ctot=0.0; + badtime=0; + } + + if (!(is_good_time(hdu2_timeflgs[i],daynight))) badtime=1; + + if (is_inside(hdu2_lambda[i],swindows,nwindows)){ + if (hdu2_loc_flgs[i]==0){ + if (LiForSiC==1){ + if (is_in_lif_channel(hdu2_channel[i],aperture)){ + ctot+=hdu2_weight[i]; + } + } + else { + if (is_in_sic_channel(hdu2_channel[i],aperture)){ + ctot+=hdu2_weight[i]; + } + } + } + } + + i++; + } + + free(hdu2_time); + free(hdu2_lambda); + free(hdu2_weight); + free(hdu2_channel); + free(hdu2_timeflgs); + free(hdu2_loc_flgs); + + + + FITS_close_file(infits,&status); + fclose(windefs_file); + fclose(output_file); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + +int is_inside(float val,interval * interval_ptr, int nintervals){ + int i; + i=0; + while (i<nintervals){ + if ((val<=interval_ptr[i].stop)&&(val>=interval_ptr[i].start)){ + return 1; + } + i++; + } + return 0; +} + +int is_good_time(char timeflag,char * daynight){ + + if (!(strncasecmp(daynight,"DAY" ,3))) return (timeflag == 1); + if (!(strncasecmp(daynight,"NIGHT",5))) return (timeflag == 0); + + return ((timeflag&254) == 0); + +} + +int is_in_lif_channel(char channel, char * aperture){ + if (!strncasecmp(aperture,"LWRS",4)) return (channel == 3); + if (!strncasecmp(aperture,"MDRS",4)) return (channel == 2); + if (!strncasecmp(aperture,"HIRS",4)) return (channel == 1); + return 0; +} + +int is_in_sic_channel(char channel, char * aperture){ + if (!strncasecmp(aperture,"LWRS",4)) return (channel == 7); + if (!strncasecmp(aperture,"MDRS",4)) return (channel == 6); + if (!strncasecmp(aperture,"HIRS",4)) return (channel == 5); + return 0; +} diff --git a/src/analysis/ttag_lightcurve_channel_sum.c b/src/analysis/ttag_lightcurve_channel_sum.c new file mode 100644 index 0000000..9f76c37 --- /dev/null +++ b/src/analysis/ttag_lightcurve_channel_sum.c @@ -0,0 +1,183 @@ + +/************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ************************************************************************* + * + * + * Usage: + * ttag_lightcurve_channel_sum [-h] [-v level] output_file + * input_file1 input_file2 + * + * + * Arguments: + * input_files : ASCII files with 2 columns : + * - time + * - signal + * + * output_file : ASCII file with 2 columns : + * - time + * - signal + * + * + * + * + * + * + * Options: + * -h: this help message + * -v: verbosity level (=1; 0 is silent) + * + * + * + * + * History: 10/06/04 bjg v1.0 + * 11/04/04 bjg v1.1 time equality criteria changed + * + ***************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#include "calfuse.h" + + +#define MAX_INPUT_FILE 20 + +static char CF_PRGM_ID[]= "ttag_lightcurve_channel_sum"; +static char CF_VER_NUM[]= "1.1"; + + +int is_equal(double a, double b, double delta){ + + return ( ((a-b) <= delta) && ((a-b) > -delta) ); + +} + + +int main(int argc,char *argv[]){ + + + + char input_filename1[FLEN_CARD]; + char input_filename2[FLEN_CARD]; + char output_filename[FLEN_CARD]; + + + FILE * output_file; + FILE * input_file1; + FILE * input_file2; + + double t1,v1,t2,v2, delta_t; + + int end_of_file; + + int optc; + + char opts[] = "hv:"; + char usage[] = + "Usage:\n" + " ttag_lightcurve_channel_sum [-h] [-v level] output_file\n" + " input_file1 input_file2\n\n" + "Arguments:\n" + " input_files : ASCII files with 2 columns :\n" + " - time\n" + " - signal\n\n" + " output_file : ASCII file with 2 columns : \n" + " - time \n" + " - signal\n"; + char option[] = + "Options:\n" + " -h: this help message \n" + " -v: verbosity level (=1; 0 is silent) \n"; + + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s", usage, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc != optind+3) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + strcpy(output_filename,argv[optind]); + strcpy(input_filename1,argv[optind+1]); + strcpy(input_filename2,argv[optind+2]); + + + + if ((input_file1 = fopen(input_filename1,"r")) == NULL){ + cf_if_error ("Unable to open file %s\n", input_filename1); + } + + if ((input_file2 = fopen(input_filename2,"r")) == NULL){ + fclose(input_file1); + cf_if_error ("Unable to open file %s\n", input_filename2); + } + + + /* Create the output file */ + if ((output_file = fopen(output_filename,"w")) == NULL){ + fclose(input_file1); + fclose(input_file2); + cf_if_error ("Unable to create file %s\n", output_filename); + } + + fscanf(input_file1,"%lf %lf",&t1,&v1); + fscanf(input_file1,"%lf %lf",&t2,&v2); + delta_t=t2-t1; + + fseek(input_file1,0,SEEK_SET); + + + end_of_file=(fscanf(input_file2,"%lf %lf",&t2,&v2)==EOF)||(fscanf(input_file1,"%lf %lf",&t1,&v1)==EOF); + + + while (!end_of_file){ + if (is_equal(t2,t1,delta_t/2)){ + fprintf(output_file,"%15lf %15lf\n",t1,v1+v2); + end_of_file=(fscanf(input_file2,"%lf %lf",&t2,&v2)==EOF)||(fscanf(input_file1,"%lf %lf",&t1,&v1)==EOF); + } + else if (t2<t1) { + end_of_file=(fscanf(input_file2,"%lf %lf",&t2,&v2)==EOF); + } + else { + end_of_file=(fscanf(input_file1,"%lf %lf",&t1,&v1)==EOF); + } + + + + } + + + fclose(input_file1); + fclose(input_file2); + fclose(output_file); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + diff --git a/src/analysis/ttag_lightcurve_combine.c b/src/analysis/ttag_lightcurve_combine.c new file mode 100644 index 0000000..9947f69 --- /dev/null +++ b/src/analysis/ttag_lightcurve_combine.c @@ -0,0 +1,182 @@ + +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: ttag_lightcurve_combine outfile file1 file2 file3 file4 ... + * + * + * History: 09/07/04 bjg v1.0 + * + * + ****************************************************************************/ + + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include "calfuse.h" + + +typedef char filename[FLEN_CARD]; + +static char CF_PRGM_ID[]= "ttag_lightcurve_combine"; +static char CF_VER_NUM[]= "1.0"; + +int main(int argc,char *argv[]){ + + char stime[FLEN_CARD]; + time_t vtime; + + + filename *filelist; + double *expstartlist; + + filename tempstring; + double tempdouble; + + double minexpstart; + int minindex; + + long nfiles, n2; + long i,j; + + double t,v; + FILE * fin; + FILE * fout; + + int optc; + + char opts[] = "hv:"; + char usage[] = + "Usage:\n" + " ttag_lightcurve_combine [-h] [-v level] output_file input_files\n"; + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n"; + + verbose_level = 1; + + /* Check number of options and arguments */ + 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; + } + } + + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + + if (argc < optind+2) { + printf("%s", usage); + cf_if_error("Incorrect number of arguments"); + } + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + /* get and display time */ + vtime = time(NULL) ; + strcpy(stime,ctime(&vtime)); + + + nfiles=argc-optind-1; + + filelist = (filename *)malloc(nfiles*sizeof(filename)); + expstartlist = (double *)malloc(nfiles*sizeof(double)); + + + cf_verbose(1,"GETTING INFORMATION ON INPUT FILES") ; + + n2=0; + + for (i=0; i<nfiles;i++) { + + fin=fopen(argv[optind+i+1],"r"); + + if (fin==NULL){ + cf_if_warning("Could not open file %s. Skipped.",argv[optind+i+1]); + continue; + } + + fscanf(fin,"%lf %lf",&t,&v); + + expstartlist[n2]=t; + strcpy(filelist[n2],argv[optind+i+1]); + + fclose(fin); + + n2++; + } + + nfiles=n2; + + if (nfiles==0){ + cf_verbose(1,"No files to combine. Exiting."); + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + exit(0); + } + + cf_verbose(1,"SORTING INPUT FILES IN TIME ORDER") ; + + for (i=0; i<nfiles-1;i++) { + minexpstart=expstartlist[i]; + minindex=i; + for (j=i+1; j<nfiles;j++) { + if (expstartlist[j]<minexpstart){ + minexpstart=expstartlist[j]; + minindex=j; + } + } + + strcpy(tempstring,filelist[minindex]); + strcpy(filelist[minindex],filelist[i]); + strcpy(filelist[i],tempstring); + + tempdouble=expstartlist[minindex]; + expstartlist[minindex]=expstartlist[i]; + expstartlist[i]=tempdouble; + + } + + cf_verbose(2,"N: Filename ExpStart "); + + for (i=0; i<nfiles;i++) { + cf_verbose(2,"%ld: %s %7.1f",i,filelist[i],expstartlist[i]); + } + + + cf_verbose(1,"CREATING OUTPUT FILE"); + if ((fout = fopen(argv[optind],"w")) == NULL){ + cf_if_error ("Unable to create file %s\n", argv[optind]); + } + + + + for (i=0; i<nfiles;i++) { + fin=fopen(filelist[i],"r"); + while (fscanf(fin, "%lf %lf", &t, &v)!=EOF){ + fprintf(fout, "%15lf %15lf\n", t, v); + } + fclose(fin); + } + + + + fclose(fout); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + diff --git a/src/analysis/ttag_lightcurve_mjd2hmjd.c b/src/analysis/ttag_lightcurve_mjd2hmjd.c new file mode 100644 index 0000000..def1978 --- /dev/null +++ b/src/analysis/ttag_lightcurve_mjd2hmjd.c @@ -0,0 +1,151 @@ + +/************************************************************************* + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ************************************************************************* + * + * + * Usage: + * ttag_lightcurve_mjd2hmjd [-h] [-v level] output_file input_file + * hh mm ss dd mm ss + * + * + * Arguments: + * input_file : ASCII file with 2 columns : + * - time (MJD) + * - signal + * + * output_file : ASCII file with 2 columns : + * - time (HMJD) + * - signal + * + * hh mm ss dd mm ss : RA and DEC of target + * + * + * + * + * Options: + * -h: this help message + * -v: verbosity level (=1; 0 is silent) + * + * + * + * + * History: 10/06/04 bjg v1.0 + * 06/03/05 wvd v1.1 Delete unused variables. + * + ***************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + +#include "calfuse.h" + +double gethmjd(double, int, int, float, int, int, float); + +static char CF_PRGM_ID[]= "ttag_lightcurve_mjd2hmjd"; +static char CF_VER_NUM[]= "1.1"; + + +int main(int argc,char *argv[]){ + + + + char input_filename[FLEN_CARD]; + char output_filename[FLEN_CARD]; + + + FILE * output_file; + FILE * input_file; + + + double t,t2,v; + int rah, ram, decd, decm; + float ras, decs; + + + int optc; + + char opts[] = "hv:"; + char usage[] = + "Usage:\n" + " ttag_lightcurve_mjd2hmjd [-h] [-v level] output_file input_file\n" + " hh mm ss dd mm ss\n\n" + "Arguments:\n" + " input_file : ASCII file with 2 columns :\n" + " - time (MJD) \n" + " - signal\n\n" + " output_file : ASCII file with 2 columns : \n" + " - time (HMJD) \n" + " - signal \n\n" + " hh mm ss dd mm ss : RA and DEC of target\n"; + char option[] = + "Options:\n" + " -h: this help message \n" + " -v: verbosity level (=1; 0 is silent) \n"; + + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s", usage, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc != optind+8) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + strcpy(output_filename,argv[optind]); + strcpy(input_filename,argv[optind+1]); + sscanf(argv[optind+2],"%d",&rah); + sscanf(argv[optind+3],"%d",&ram); + sscanf(argv[optind+4],"%f",&ras); + sscanf(argv[optind+5],"%d",&decd); + sscanf(argv[optind+6],"%d",&decm); + sscanf(argv[optind+7],"%f",&decs); + + + if ((input_file = fopen(input_filename,"r")) == NULL){ + cf_if_error ("Unable to open file %s\n", input_filename); + } + + /* Create the output file */ + if ((output_file = fopen(output_filename,"w")) == NULL){ + fclose(input_file); + cf_if_error ("Unable to create file %s\n", output_filename); + } + + while(fscanf(input_file,"%lf %lf",&t,&v)!=EOF) { + t2=gethmjd(t, rah, ram, ras, decd, decm, decs); + + fprintf(output_file,"%15lf %15lf\n",t2,v); + } + + fclose(input_file); + fclose(output_file); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + diff --git a/src/analysis/ttag_lightcurve_periodogram.c b/src/analysis/ttag_lightcurve_periodogram.c new file mode 100644 index 0000000..939a1ec --- /dev/null +++ b/src/analysis/ttag_lightcurve_periodogram.c @@ -0,0 +1,294 @@ + +/**************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + **************************************************************************** + * + * + * Usage: + * ttag_lightcurve_periodogram [-hs] [-v level] input_file output_file + * minf maxf stepf + * + * + * Arguments: + * input_file : an ASCII file with 2 columns : + * - time (days) + * - countrate + * + * output_file : an ASCII file with 2 columns : + * - frequency (Hz) + * - normalized estimated power spectral density + * + * minf : start frequency (Hz) + * maxf : end frequency (Hz) + * stepf : frequency step (Hz) + * + * + * + * Options: + * -h: this help message + * -v: verbosity level (=1; 0 is silent) + * -s: time is in seconds instead of days + * + * + ************************************************************************** + * + * + * + * Description: + * + * Computes the Lomb periodogram of signal h + * from samples (hj) j=1..N at times (tj) j=1..N + * + * + * w=2*pi*f + * + * + * + * 1 / (sum_j[(hj-H)*cos(w(tj-tau))])^2 + * Pn(w) = ----------- | --------------------------------- + * 2*sigma2 \ sum_j[(cos(w(tj-tau)))^2] + * + * + * (sum_j[(hj-H)*sin(w(tj-tau))])^2 \ + * + --------------------------------- | + * sum_j[(cos(w(tj-tau)))^2] / + * + * + * + * + * H=sum_i[hi]/N sigma2=sum_i[(hi-H)^2]/(N-1) + * + * + * sum_j[sin(2*w*tj)] + * tan (2*w*tau) = ------------------ + * sum_j[cos(2*w*tj)] + * + * + * PAINFULLY SLOW + * NEED TO BE REWRITTEN TO DO A FAST TRANSFORM (RECURSIVE) + * + * + * + ***************************************************************************** + * + * History: 10/07/04 bjg v1.0 + * 11/04/04 bjg v1.1 + * + * ----v1.1 CHANGES WERE CANCELLED --- + * 12/06/04 bjg v1.2 + * 12/13/04 bjg v1.3 Changed N and i to long + * Initialize N to 0 + * 06/03/05 wvd v1.4 Delete unused variables. + * + * + ***************************************************************************/ + + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <unistd.h> +#include <math.h> + + +#include "calfuse.h" + + +static char CF_PRGM_ID[]= "ttag_lightcurve_periodogram"; +static char CF_VER_NUM[]= "1.1"; + + + +int main(int argc,char *argv[]){ + + + + char input_filename[FLEN_CARD],output_filename[FLEN_CARD]; + + FILE * output_file; + FILE * input_file; + + float minf,maxf; + float stepf; + + + double H; + double sigma2; + double tau; + + + double val1,val2; + double * t; + double * h; + double total1,total2,total3,total4; + double aux; + double Pn; + double f; + double j0=0; + + long i, N; + long ndx; + + int time_unit=0; + + int optc; + + char opts[] = "hsv:"; + + char usage[] = + "Usage:\n" + " ttag_lightcurve_periodogram [-hs] [-v level] input_file output_file\n" + " minf, maxf, stepf\n" + "Arguments:\n" + " input_file : an ASCII file with 2 columns :\n" + " - time (JD or MJD, Helio- or Geo-centric)\n" + " - countrate\n\n" + " output_file : an ASCII file with 2 columns :\n" + " - frequency (Hz)\n" + " - normalized estimated power spectral density\n\n" + " minf : start frequency (Hz)\n" + " maxf : end frequency (Hz)\n" + " stepf : frequency step (Hz)\n"; + + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n" + " -s: time is in seconds instead of days\n"; + + verbose_level = 1; + + + /* Check number of options and arguments */ + while ((optc = getopt(argc, argv, opts)) != -1) { + switch(optc) { + case 'h': + printf("%s\n%s", usage, option); + return EXIT_SUCCESS; + case 'v': + verbose_level = atoi(optarg); + break; + case 's': + time_unit=1; + break; + } + } + + /* Initialize error checking. */ + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc != optind+5) + cf_if_error("%s\nIncorrect number of program arguments", usage); + + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Started execution."); + + strcpy(input_filename,argv[optind]); + strcpy(output_filename,argv[optind+1]); + sscanf(argv[optind+2],"%f",&minf); + sscanf(argv[optind+3],"%f",&maxf); + sscanf(argv[optind+4],"%f",&stepf); + + + + if ((input_file = fopen (input_filename, "r")) == NULL){ + cf_if_error ("Unable to open file %s\n", input_filename); + } + + + N=0; + while (fscanf(input_file,"%lf %lf",&val1,&val2)!=EOF){ + N++; + } + + t=(double *)malloc(N*sizeof(double)); + h=(double *)malloc(N*sizeof(double)); + + + fseek(input_file,0,SEEK_SET); + + i=0; + total1=0; + while (fscanf(input_file,"%lf %lf",&val1,&val2)!=EOF){ + if (i==0) { + t[i]=0.0; j0=val1; + } + else { + if (time_unit) t[i]=val1-j0; + else t[i]=(val1-j0)*3600.0*24; + } + + h[i]=val2; + + total1+=h[i]; + + i++; + + } + + H=total1/N; + + total1=0; + for (i=0;i<N;i++){ + aux=(h[i]-H); + total1+=aux*aux; + } + + sigma2=total1/(N-1); + + + + if ((output_file = fopen(output_filename,"w")) == NULL){ + fclose(input_file); + cf_if_error ("Unable to create file %s\n", output_filename); + } + + ndx=0; + for (f=minf; f<=maxf; f+=stepf){ + cf_verbose(4,"n=%ld;minf=%f;maxf=%f;freq=%lf",ndx,minf,maxf,f); + ndx++; + total1=0; + total2=0; + for (i=0;i<N;i++){ + total1+=sin(4*M_PI*f*t[i]); + total2+=cos(4*M_PI*f*t[i]); + } + + + tau=atan(total1/total2)/(4*M_PI*f); + + + + total1=0; + total2=0; + total3=0; + total4=0; + + for (i=0;i<N;i++){ + aux=cos(2*M_PI*f*(t[i]-tau)); + total1+=(h[i]-H)*aux; + total2+=aux*aux; + aux=sin(2*M_PI*f*(t[i]-tau)); + total3+=(h[i]-H)*aux; + total4+=aux*aux; + } + + Pn=(total1*total1/total2+total3*total3/total4)/(2*sigma2); + + + fprintf(output_file,"%10lf %10lf\n",f,Pn); + + } + + fclose(input_file); + fclose(output_file); + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished execution."); + return EXIT_SUCCESS; + +} + + |