diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-03-04 21:21:30 -0500 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2015-03-04 21:21:30 -0500 |
commit | d54fe7c1f704a63824c5bfa0ece65245572e9b27 (patch) | |
tree | afc52015ffc2c74e0266653eecef1c8ef8ba5d91 /src/fuv/cf_countmap.c | |
download | calfuse-d54fe7c1f704a63824c5bfa0ece65245572e9b27.tar.gz |
Initial commit
Diffstat (limited to 'src/fuv/cf_countmap.c')
-rw-r--r-- | src/fuv/cf_countmap.c | 541 |
1 files changed, 541 insertions, 0 deletions
diff --git a/src/fuv/cf_countmap.c b/src/fuv/cf_countmap.c new file mode 100644 index 0000000..2d62b14 --- /dev/null +++ b/src/fuv/cf_countmap.c @@ -0,0 +1,541 @@ +/***************************************************************************** + * Johns Hopkins University + * Center For Astrophysical Sciences + * FUSE + ***************************************************************************** + * + * Synopsis: cf_countmap input_files + * + * Description: Adds the counts from a list of input idf files into + * the count map. The accumulated count map cube is + * determined by reading the COUNT_CAL keyword in the + * input file's header. To prevent multiple copies + * of reprocessed input files from being added to + * the total exposure map, if the input file has been + * previously added, it is skipped over and a message is + * printed out. + * + * + * Arguments: input_files Input initialized ttag FITS file names + * + * Calibration files required: None + * + * Returns: int 0 = successful completion + * + * Note: This routine requires significantly more memory than your + * average routine. Its design has not been optimized to + * reduce memory usage. + * + * History: 03/25/03 1.1 peb Begin and finish work. Based on + * cf_ttag_to_image + * 03/31/03 1.2 peb Removed filtering of photons and fixed + * exposure time bug when subtracting data + * 06/11/03 1.3 wvd Pass datatype to cf_read_col + * 08/25/03 1.4 wvd Change coltype from string to int in + * cf_read_col. + * 08/25/03 1.5 wvd Change CHIDCOR1 to CHID_COR + * 02/17/04 1.6 bjg Added scaling option + * Routine name changed from + * cf_ttag_countmap to cf_countmap. + * 02/26/04 1.7 bjg Added option to select coordinates + * to use: RAW, FARF (default), final + * 04/08/04 1.8 bjg Remove unused function get_xy_columns + * 04/27/04 1.9 bjg Change author name of countfile + * 08/25/04 1.10 bjg Added lower and upper limits option + * for PHA. In force mode, issue a warning + * if file already included. + * 03/02/05 1.11 wvd Don't write AUTHOR keyword to header. + * 08/24/07 1.12 bot Changed nx and ny to long and called + * as TLONG ; changed binx and biny to int + * and called as TINT. + * + ****************************************************************************/ + +#include <unistd.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include "calfuse.h" + +#define ROOT_LENGTH 13 +#define MAXCHARS 120 +#define MASTER_CAL_FILE "master_calib_file.dat" +#define IMAGE_EXT 1 +#define INDEX_EXT 2 + +static char CF_PRGM_ID[] = "cf_countmap"; +static char CF_VER_NUM[] = "1.12"; + + +static int +new_imagfile(char *newfile, char *detector, float effmjd, int binx, int biny) +{ + char date[FLEN_CARD]={'\0'}; + char *ttype[] = {"ROOTNAME", "OBSDATE", "COUNTS", "EXPTIME", "ADDDATE", "SCALE", "PHAMIN", "PHAMAX"}; + char *tform[] = {"13A" , "19A" , "1J" , "1E" , "19A" , "1E" , "1I" , "1I" }; + char *tunit[] = {" " , " " , "counts", "seconds", " " , " " , " " , " " }; + int status=0, version=1, tref = 0, tfields = 8; + long axis[2]; + float exptime=0.; + double nevents=0.; + fitsfile *imagfits; + + FITS_create_file(&imagfits, newfile, &status); + + axis[0] = NXMAX/binx; + axis[1] = NYMAX/biny; + + FITS_create_img(imagfits, FLOAT_IMG, 2, axis, &status); + FITS_write_key(imagfits, TINT, "SPECBINX", &binx, + "Binsize in detector X coordinate", &status); + FITS_write_key(imagfits, TINT, "SPECBINY", &biny, + "Binsize in detector Y coordinate", &status); + FITS_write_key(imagfits, TSTRING, "CALFTYPE", "COUNT", + "Calibration file type", &status); + FITS_write_key(imagfits, TINT, "CALFVERS", &version, + "Calibration file version", &status); + FITS_write_key(imagfits, TSTRING, "DETECTOR", detector, + "detector (1A, 1B, 2A, 2B)", &status); + FITS_write_key(imagfits, TFLOAT, "EFFMJD", &effmjd, + "Date on which file should be applied (MJD)", &status); + fits_get_system_time(date, &tref, &status); + FITS_write_key(imagfits, TSTRING, "DATE", date, + "file creation date (YYYY-MM-DDThh:mm:ss UTC)", &status); + FITS_write_key(imagfits, TDOUBLE, "NEVENTS", &nevents, + "Accumulated events", &status); + FITS_write_key(imagfits, TFLOAT, "EXPTIME", &exptime, + "Accumulated exposure time", &status); + + FITS_create_tbl(imagfits, BINARY_TBL, 0, tfields, ttype, tform, tunit, + "PROCESSED FILES", &status); + + FITS_close_file(imagfits, &status); + return status; +} + +static int +_check_index(fitsfile *imagfits, char *rootname, float *scale, int *phamin, int *phamax) +{ + int status=0, anynull=0, hdutype; + float *scal; + int *phami, *phama; + long j, nrows, frow=1, felem=1; + char **filename, strnull[] = " "; + + FITS_movabs_hdu(imagfits, INDEX_EXT, &hdutype, &status); + FITS_read_key(imagfits, TLONG, "NAXIS2", &nrows, NULL, &status); + + filename = (char **) cf_malloc(nrows * sizeof(char *)); + filename[0] = (char *) cf_malloc(nrows*(ROOT_LENGTH+1)*sizeof(char)); + scal = (float *) cf_malloc(nrows * sizeof(float)); + phami = (int *) cf_malloc(nrows * sizeof(int)); + phama = (int *) cf_malloc(nrows * sizeof(int)); + for (j=1; j<nrows; j++) + filename[j] = filename[j-1]+(ROOT_LENGTH+1); + + FITS_read_col(imagfits, TSTRING, 1, frow, felem, nrows, strnull, + filename, &anynull, &status); + FITS_read_col(imagfits, TFLOAT, 6, frow, felem, nrows, strnull, + scal, &anynull, &status); + FITS_read_col(imagfits, TINT, 7, frow, felem, nrows, strnull, + phami, &anynull, &status); + FITS_read_col(imagfits, TINT, 8, frow, felem, nrows, strnull, + phama, &anynull, &status); + + for (j=0; j<nrows; j++) { + if (strncmp(filename[j], rootname, strlen(rootname)) == 0) { + *scale = scal[j]; + *phamin = phami[j]; + *phamax = phama[j]; + free(filename[0]); + free(filename); + free(scal); + return j+1; + } + } + free(filename[0]); + free(filename); + free(scal); + free(phami); + free(phama); + return 0; +} + +static int +_update_index(fitsfile *imagfits, char *rootname, char *obsdate, + double nevents, float exptime, float scale, int phamin, int phamax) +{ + char *strptr[1], adddate[FLEN_CARD]={'\0'}; + int status=0, hdutype, tref=0; + long nrows; + + FITS_movabs_hdu(imagfits, INDEX_EXT, &hdutype, &status); + FITS_read_key(imagfits, TLONG, "NAXIS2", &nrows, NULL, &status); + + strptr[0] = rootname; + FITS_write_col(imagfits, TSTRING, 1, nrows+1, 1, 1, strptr, &status); + strptr[0] = obsdate; + FITS_write_col(imagfits, TSTRING, 2, nrows+1, 1, 1, strptr, &status); + FITS_write_col(imagfits, TDOUBLE, 3, nrows+1, 1, 1, &nevents, &status); + FITS_write_col(imagfits, TFLOAT, 4, nrows+1, 1, 1, &exptime, &status); + fits_get_system_time(adddate, &tref, &status); + strptr[0] = adddate; + fits_write_col(imagfits, TSTRING, 5, nrows+1, 1, 1, strptr, &status); + FITS_write_col(imagfits, TFLOAT, 6, nrows+1, 1, 1, &scale, &status); + FITS_write_col(imagfits, TINT, 7, nrows+1, 1, 1, &phamin, &status); + FITS_write_col(imagfits, TINT, 8, nrows+1, 1, 1, &phamax, &status); + return 0; +} + + + +static double +add_events(fitsfile *infits, char *xcolumn, char *ycolumn, float scale, + int phamin, int phamax, fitsfile *imagfits) +{ + int binx, biny, status=0, hdutype, anynull=0; + long nx, ny, nevents, j; + float *xpos, *ypos, *weight, *image; + char *pha; + double ncounts=0.; + + FITS_movabs_hdu(infits, 2, &hdutype, &status); + nevents = cf_read_col(infits, TFLOAT, xcolumn, (void **) &xpos); + nevents = cf_read_col(infits, TFLOAT, ycolumn, (void **) &ypos); + nevents = cf_read_col(infits, TFLOAT, "WEIGHT", (void **) &weight); + nevents = cf_read_col(infits, TBYTE, "PHA", (void **) &pha); + + FITS_movabs_hdu(imagfits, IMAGE_EXT, &hdutype, &status); + FITS_read_key(imagfits, TLONG, "NAXIS1", &nx, NULL, &status); + FITS_read_key(imagfits, TLONG, "NAXIS2", &ny, NULL, &status); + FITS_read_key(imagfits, TINT, "SPECBINX", &binx, NULL, &status); + FITS_read_key(imagfits, TINT, "SPECBINY", &biny, NULL, &status); + + image = (float *) cf_malloc(sizeof(float)*nx*ny); + FITS_read_img(imagfits, TFLOAT, 1, nx*ny, NULL, image, &anynull, &status); + + for (j=0; j<nevents; j++) { + if ((pha[j]>=phamin) && (pha[j]<=phamax)){ + int x, y; + x = xpos[j]; + y = ypos[j]; + if ((x >= 0) && (x < nx*binx) && (y >= 0) && (y < ny*biny)) { + image[(y/biny)*nx + (x/binx)] += weight[j]*scale; + ncounts += weight[j]*scale; + } + } + } + FITS_write_img(imagfits, TFLOAT, 1, nx*ny, image, &status); + + free(image); + free(weight); + free(ypos); + free(xpos); + return ncounts; +} + +static double +subtract_events(fitsfile *infits, char *xcolumn, char *ycolumn, + float scale, int phamin, int phamax, fitsfile *imagfits) +{ + int binx, biny, status=0, hdutype, anynull=0; + long nx, ny, nevents, j; + float *xpos, *ypos, *weight, *image; + double ncounts=0.; + char *pha; + + FITS_movabs_hdu(infits, 2, &hdutype, &status); + nevents = cf_read_col(infits, TFLOAT, xcolumn, (void **) &xpos); + nevents = cf_read_col(infits, TFLOAT, ycolumn, (void **) &ypos); + nevents = cf_read_col(infits, TFLOAT, "WEIGHT", (void **) &weight); + nevents = cf_read_col(infits, TBYTE, "PHA", (void **) &pha); + + FITS_movabs_hdu(imagfits, IMAGE_EXT, &hdutype, &status); + FITS_read_key(imagfits, TLONG, "NAXIS1", &nx, NULL, &status); + FITS_read_key(imagfits, TLONG, "NAXIS2", &ny, NULL, &status); + FITS_read_key(imagfits, TINT, "SPECBINX", &binx, NULL, &status); + FITS_read_key(imagfits, TINT, "SPECBINY", &biny, NULL, &status); + + image = (float *) cf_malloc(sizeof(float)*nx*ny); + FITS_read_img(imagfits, TFLOAT, 1, nx*ny, NULL, image, &anynull, &status); + + for (j=0; j<nevents; j++) { + if ((pha[j]>=phamin) && (pha[j]<=phamax)){ + int x, y; + x = xpos[j]; + y = ypos[j]; + if ((x >= 0) && (x < nx*binx) && (y >= 0) && (y < ny*biny)) { + image[(y/biny)*nx + (x/binx)] -= weight[j]*scale; + ncounts += weight[j]*scale; + } + } + } + FITS_write_img(imagfits, TFLOAT, 1, nx*ny, image, &status); + + free(image); + free(weight); + free(ypos); + free(xpos); + return ncounts; +} + + +int main(int argc, char *argv[]) +{ + char *newfile = NULL, *detector = NULL, buffer[FLEN_CARD]={'\0'}; + int subtract=0, force=0, newbinx=1, newbiny=1, status=0, optc; + float effmjd = 0.,scale=1.,old_scale; + int phamin=0, phamax=31; + int old_phamin, old_phamax; + + char xcolumn[FLEN_CARD]={'\0'}, ycolumn[FLEN_CARD]={'\0'}; + + char opts[] = "hv:fsrcn:d:j:w:x:y:l:u:"; + char usage[] = + "Usage:\n" + " cf_countmap [-hfsrc] [-v level] [-n filename] [-d segment]\n" + " [-w scale] [-j effmjd] [-x xbin] [-y ybin] \n" + " [-l phamin] [-u phamax] idffiles\n"; + char option[] = + "Options:\n" + " -h: this help message\n" + " -v: verbosity level (=1; 0 is silent)\n" + " -f: force processing\n" + " -s: subtract files\n" + " -n: image map file\n" + " -d: image map segment (no default for new file)\n" + " -j: effective MJD (=0.0)\n" + " -w: weighting factor for image (=1.0)\n" + " -x: X-bin size (=1)\n" + " -y: Y-bin size (=1)\n" + " -r: use raw XY coordinates instead of farf\n" + " -c: use final XY coordinates instead of farf\n" + " -l: lower limit for pha (=0) \n" + " -u: upper limit for pha (=31) \n"; + + verbose_level = 1; + + strcpy(xcolumn, "XFARF"); + strcpy(ycolumn, "YFARF"); + + /* 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; + case 'f': + force = 1; + break; + case 's': + subtract = 1; + break; + case 'n': + newfile = optarg; + break; + case 'd': + detector = optarg; + break; + case 'j': + effmjd = atof(optarg); + break; + case 'w': + scale = atof(optarg); + break; + case 'x': + newbinx = atoi(optarg); + break; + case 'y': + newbiny = atoi(optarg); + break; + case 'r': + strcpy(xcolumn, "XRAW"); + strcpy(ycolumn, "YRAW"); + break; + case 'c': + strcpy(xcolumn, "X"); + strcpy(ycolumn, "Y"); + break; + case 'l': + phamin = atoi(optarg); + break; + case 'u': + phamax = atoi(optarg); + break; + } + } + cf_error_init(CF_PRGM_ID, CF_VER_NUM, stderr); + if (argc <= optind) { + cf_if_error("%s\nIncorrect number of program arguments", usage); + } + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Begin processing"); + + while (optind < argc) { + + char imagfile[FLEN_CARD], rootname[FLEN_CARD]={'\0'}; + char segment[FLEN_CARD] = {'\0'}; + int hdutype; + FILE *fptr; + fitsfile *infits, *imagfits; + + FITS_open_file(&infits, argv[optind], READONLY, &status); + FITS_movabs_hdu(infits, 1, &hdutype, &status); + + if (newfile) { + strcpy(imagfile, newfile); + + if ((fptr = fopen(imagfile, "r"))) + fclose(fptr); + else { + if (!detector) + cf_if_error("No detector segment specified: " + "1A, 1B, 2A, 2B"); + status = new_imagfile(imagfile, detector, effmjd, + newbinx, newbiny); + } + FITS_open_file(&imagfits, imagfile, READWRITE, &status); + FITS_movabs_hdu(imagfits, IMAGE_EXT, &hdutype, &status); + detector = buffer; + FITS_read_key(imagfits, TSTRING, "DETECTOR", detector, NULL, + &status); + } + else { + FITS_read_key(infits, TSTRING, "TCNT_MAP", imagfile, NULL, + &status); + detector = buffer; + FITS_read_key(infits, TSTRING, "DETECTOR", detector, NULL, + &status); + + if ((fptr = fopen(cf_hist_file(imagfile), "r"))) { + fclose(fptr); + } else { + char keyword[FLEN_CARD]={'\0'}, segment[FLEN_CARD]={'\n'}; + char linin[MAXCHARS]={'\0'}, filename[FLEN_CARD]={'\0'}; + int interp; + float aftermjd; + FILE *master; + /* + * Get the effective MJD from the master calibration file + */ + master = fopen(cf_parm_file(MASTER_CAL_FILE), "r"); + if (master == NULL) + cf_if_error("Master calibration database file not found"); + while (fgets(linin, MAXCHARS, master) != NULL) { + /* + * Check for comment lines + */ + if ((linin[0] != '#') && (linin[0] != '\n')) { + sscanf(linin, "%4c%*2c%2c%*2c%13c%*2c%9f%*2c%1d", + keyword, segment, filename, &aftermjd, &interp); + if (strcmp(filename, imagfile) == 0) { + effmjd = aftermjd; + break; + } + } + } + fclose(master); + + status = new_imagfile(cf_hist_file(imagfile), detector, + effmjd, newbinx, newbiny); + } + FITS_open_file(&imagfits, cf_hist_file(imagfile), READWRITE, + &status); + } + + strncpy(rootname, argv[optind], ROOT_LENGTH); + FITS_read_key(infits, TSTRING, "DETECTOR", segment, NULL, + &status); + if (strcmp(detector, segment) != 0) { + cf_if_warning("%s segment is not the same as %s.", + argv[optind], imagfile); + } + else if (subtract) { + int index; + if ((index = _check_index(imagfits, rootname, &scale, &phamin, &phamax))) { + + int hdutype; + float exptime=0., acctime=0.; + double nevents, accevnt=0.; + + FITS_read_key(infits, TFLOAT, "EXPTIME", &exptime, NULL, + &status); + + + nevents = subtract_events(infits, xcolumn, ycolumn, scale, phamin, phamax, imagfits); + + FITS_movabs_hdu(imagfits, IMAGE_EXT, &hdutype, &status); + FITS_read_key(imagfits, TDOUBLE, "NEVENTS", &accevnt, + NULL, &status); + FITS_read_key(imagfits, TFLOAT, "EXPTIME", &acctime, + NULL, &status); + accevnt -= nevents; + acctime -= exptime; + FITS_update_key(imagfits, TDOUBLE, "NEVENTS", &accevnt, + NULL, &status); + FITS_update_key(imagfits, TFLOAT, "EXPTIME", &acctime, + NULL, &status); + + FITS_movabs_hdu(imagfits, INDEX_EXT, &hdutype, &status); + FITS_delete_rows(imagfits, index, 1, &status); + cf_verbose(1, "%s is subtracted from %s", + argv[optind], imagfile); + } else { + cf_if_warning("%s is not in %s.", argv[optind], imagfile); + } + } else { + if (!force && _check_index(imagfits, rootname, &old_scale, &old_phamin, &old_phamax)) { + cf_if_warning("%s is already in %s with scale = %f, phamin = %d, phamax=%d.", + argv[optind], imagfile, old_scale, old_phamin, old_phamax); + } else { + char obsdate[FLEN_CARD]={'\0'}, dateobs[FLEN_CARD]={'\0'}; + char timeobs[FLEN_CARD]={'\0'}; + + float exptime=0., acctime=0.; + double nevents, accevnt=0; + + FITS_movabs_hdu(imagfits, IMAGE_EXT, &hdutype, &status); + FITS_read_key(infits, TSTRING, "DATEOBS", dateobs, NULL, + &status); + FITS_read_key(infits, TSTRING, "TIMEOBS", timeobs, NULL, + &status); + obsdate[0] = '\0'; + sprintf(obsdate, "%s%s%s", dateobs, "T", timeobs); + FITS_read_key(infits, TFLOAT, "EXPTIME", &exptime, NULL, + &status); + + if ((force) && _check_index(imagfits, rootname, &old_scale, &old_phamin, &old_phamax)) + cf_if_warning("FORCE MODE - %s is already in %s with scale = %f, phamin = %d, phamax=%d.", + argv[optind], imagfile, old_scale, old_phamin, old_phamax); + + nevents = add_events(infits, xcolumn, ycolumn, scale, phamin, phamax, imagfits); + + FITS_movabs_hdu(imagfits, IMAGE_EXT, &hdutype, &status); + FITS_read_key(imagfits, TDOUBLE, "NEVENTS", &accevnt, + NULL, &status); + FITS_read_key(imagfits, TFLOAT, "EXPTIME", &acctime, + NULL, &status); + accevnt += nevents; + acctime += exptime; + FITS_update_key(imagfits, TDOUBLE, "NEVENTS", &accevnt, + NULL, &status); + FITS_update_key(imagfits, TFLOAT, "EXPTIME", &acctime, + NULL, &status); + + status = _update_index(imagfits, rootname, obsdate, nevents, + exptime, scale, phamin, phamax); + cf_verbose(1, "%s is added to %s", argv[optind], imagfile); + } + } + FITS_close_file(imagfits, &status); + FITS_close_file(infits, &status); + optind ++; + } + + cf_timestamp(CF_PRGM_ID, CF_VER_NUM, "Finished processing"); + return 0; +} |