static void write_axis(fitsfile* fptr, int axis_id, const char* ctype, const char* ctype_comment, double crval, double cdelt, double crpix, int* status) { char key[FLEN_KEYWORD], value[FLEN_VALUE], comment[FLEN_COMMENT]; int decimals = 10; strncpy(comment, ctype_comment, FLEN_COMMENT-1); strncpy(value, ctype, FLEN_VALUE-1); fits_make_keyn("CTYPE", axis_id, key, status); fits_write_key_str(fptr, key, value, comment, status); fits_make_keyn("CRVAL", axis_id, key, status); fits_write_key_dbl(fptr, key, crval, decimals, NULL, status); fits_make_keyn("CDELT", axis_id, key, status); fits_write_key_dbl(fptr, key, cdelt, decimals, NULL, status); fits_make_keyn("CRPIX", axis_id, key, status); fits_write_key_dbl(fptr, key, crpix, decimals, NULL, status); fits_make_keyn("CROTA", axis_id, key, status); fits_write_key_dbl(fptr, key, 0.0, decimals, NULL, status); }
static gboolean get_real_and_offset(fitsfile *fptr, gint i, guint res, gdouble *real, gdouble *off) { char keyname[FLEN_KEYWORD]; gdouble delt, refval, refpix; gint status = 0; fits_make_keyn("CDELT", i, keyname, &status); gwy_debug("looking for %s", keyname); if (fits_read_key(fptr, TDOUBLE, keyname, &delt, NULL, &status)) return FALSE; gwy_debug("%s = %g", keyname, delt); if (!(delt != 0.0)) return FALSE; *real = res*delt; *off = 0.0; fits_make_keyn("CRPIX", i, keyname, &status); gwy_debug("looking for %s", keyname); if (fits_read_key(fptr, TDOUBLE, keyname, &refpix, NULL, &status)) return TRUE; gwy_debug("%s = %g", keyname, refpix); fits_make_keyn("CRVAL", i, keyname, &status); gwy_debug("looking for %s", keyname); if (fits_read_key(fptr, TDOUBLE, keyname, &refval, NULL, &status)) return TRUE; gwy_debug("%s = %g", keyname, refval); /* Not sure about their pixel numbering, so offset may be wrong. */ *off = refval + delt*(1.0 - refpix); return TRUE; }
/** * add FITS table to image structure */ FITStable *table_read(IMAGE *img, fitsfile *fp){ int ncols, i; long nrows; char extname[FLEN_VALUE]; #define TRYRET(f, ...) do{TRYFITS(f, fp, __VA_ARGS__); if(fitsstatus) goto ret;}while(0) TRYRET(fits_get_num_rows, &nrows); TRYRET(fits_get_num_cols, &ncols); TRYRET(fits_read_key, TSTRING, "EXTNAME", extname, NULL); DBG("Table named %s with %ld rows and %d columns", extname, nrows, ncols); FITStable *tbl = table_new(img, extname); if(!tbl) return NULL; for(i = 1; i <= ncols; ++i){ int typecode; long repeat, width; FITSFUN(fits_get_coltype, fp, i, &typecode, &repeat, &width); if(fitsstatus){ WARNX(_("Can't read column %d!"), i); continue; } DBG("typecode=%d, repeat=%ld, width=%ld", typecode, repeat, width); table_column col = {.repeat = repeat, .width = width, .coltype = typecode}; void *array = malloc(width*repeat); if(!array) ERRX("malloc"); int anynul; int64_t nullval = 0; int j; for(j = 0; j < repeat; ++j){ FITSFUN(fits_read_col, fp, typecode, i, j=1, 1, 1, (void*)nullval, array, &anynul); if(fitsstatus){ WARNX(_("Can't read column %d row %d!"), i, j); continue; } } DBG("done"); continue; col.contents = array; char keyword[FLEN_KEYWORD]; int stat = 0; fits_make_keyn("TTYPE", i, keyword, &stat); if(stat){WARNX("???"); stat = 0;} fits_read_key(fp, TSTRING, keyword, col.colname, NULL, &stat); if(stat){ sprintf(col.colname, "noname"); stat = 0;} fits_make_keyn("TUNIT", i, keyword, &stat); if(stat){WARNX("???"); stat = 0;} fits_read_key(fp, TSTRING, keyword, col.unit, NULL, &stat); if(stat) *col.unit = 0; DBG("Column, cont[2]=%d, type=%d, w=%ld, r=%ld, nm=%s, u=%s", ((int*)col.contents)[2], col.coltype, col.width, col.repeat, col.colname, col.unit); //table_addcolumn(tbl, &col); FREE(array); } // DBG("fits_create_tbl nrows=%zd, ncols=%zd, colnms[0]=%s, formats[0]=%s, " // "units[0]=%s, name=%s", tbl->nrows, cols, tbl->colnames[0], tbl->formats[0], tbl->units[0], tbl->tabname); #undef TRYRET ret: if(fitsstatus){ tablefree(&tbl); --img->tables->amount; } return tbl; }
int main(int argc, char *argv[]) { fitsfile *fptr = 0; /* FITS file pointer, defined in fitsio.h */ char keyname[FLEN_KEYWORD], colname[FLEN_VALUE], coltype[FLEN_VALUE]; int status = 0; /* CFITSIO status value MUST be initialized to zero! */ int single = 0, hdupos = 0, hdutype = 0, bitpix = 0, naxis = 0, ncols = 0, ii = 0; long naxes[10], nrows = 0; int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)); if (printhelp || argc != 2) { fprintf(stderr, "Usage: %s filename[ext] \n", argv[0]); fprintf(stderr, "\n"); fprintf(stderr, "List the structure of a single extension, or, if ext is \n"); fprintf(stderr, "not given, list the structure of the entire FITS file. \n"); fprintf(stderr, "\n"); fprintf(stderr, "Note that it may be necessary to enclose the input file\n"); fprintf(stderr, "name in single quote characters on the Unix command line.\n"); return (0); } FILE *fout = popen(PAGER, "w"); if (fout == NULL) { fprintf(stderr, "Could not execute '%s'\n", PAGER); return (1); } if (!fits_open_file(&fptr, argv[1], READONLY, &status)) { fits_get_hdu_num(fptr, &hdupos); /* Get the current HDU position */ /* List only a single structure if a specific extension was given */ if (strchr(argv[1], '[') || strchr(argv[1], '+')) { single++; } for (; !status; hdupos++) { /* Main loop for each HDU */ fits_get_hdu_type(fptr, &hdutype, &status); /* Get the HDU type */ fprintf(fout, "\nHDU #%d ", hdupos); if (hdutype == IMAGE_HDU) { /* primary array or image HDU */ fits_get_img_param(fptr, 10, &bitpix, &naxis, naxes, &status); fprintf(fout, "Array: NAXIS = %d, BITPIX = %d\n", naxis, bitpix); for (ii = 0; ii < naxis; ii++) { fprintf(fout, " NAXIS%d = %ld\n",ii+1, naxes[ii]); } } else { /* a table HDU */ fits_get_num_rows(fptr, &nrows, &status); fits_get_num_cols(fptr, &ncols, &status); if (hdutype == ASCII_TBL) { fprintf(fout, "ASCII Table: "); } else { fprintf(fout, "Binary Table: "); } fprintf(fout, "%d columns x %ld rows\n", ncols, nrows); fprintf(fout, " COL NAME FORMAT\n"); for (ii = 1; ii <= ncols; ii++) { fits_make_keyn("TTYPE", ii, keyname, &status); /* make keyword */ fits_read_key(fptr, TSTRING, keyname, colname, NULL, &status); fits_make_keyn("TFORM", ii, keyname, &status); /* make keyword */ fits_read_key(fptr, TSTRING, keyname, coltype, NULL, &status); fprintf(fout, " %3d %-16s %-16s\n", ii, colname, coltype); } } if (single) { break; /* quit if only listing a single HDU */ } fits_movrel_hdu(fptr, 1, NULL, &status); /* try move to next ext */ } if (status == END_OF_FILE) { status = 0; /* Reset normal error */ } fits_close_file(fptr, &status); } pclose(fout); if (status) { fits_report_error(stderr, status); /* print any error message */ } return (status); }
int get_header(fitsfile *fptr, struct uvf_header *header) { int status = 0; int error; int i, k, hdunum, hdutype, bitpix, naxis, group; long pcount, gcount, naxes[MAX_DIM]; char extname[68]; int extver; char object[FLEN_VALUE]; char telescop[FLEN_VALUE]; char instrume[FLEN_VALUE]; char ctype[FLEN_VALUE]; char datobs[FLEN_VALUE], bunit[FLEN_VALUE], radecsys[FLEN_VALUE]; char keyctype[FLEN_KEYWORD], keycrval[FLEN_KEYWORD]; char keycdelt[FLEN_KEYWORD], keycrpix[FLEN_KEYWORD]; char observer[FLEN_KEYWORD]; double crval, cdelt, crpix; double equinox, obsra, obsdec, ra, dec, freq, bw; double min_date, max_date; int stokes[MAX_STOKES], nstokes, delta_stokes; int nc, nif, nval; struct uvf_sample sample; /* Read the standard header keywords */ fits_read_imghdr(fptr, MAX_DIM, NULL, &bitpix, &naxis, naxes, &pcount, &gcount, NULL, &status); fprintf(stderr, " bitpix = %d, gcount=%ld\n", bitpix, gcount); fits_report_error(stderr, status); /* Check for UVF */ if (status || gcount <= 1 || naxes[0] != 0) { fprintf(stderr, "This is not UV-FITS file\n"); return 1; } /* Look for the keywords that we know about */ fits_read_key(fptr, TSTRING, "OBJECT", object, NULL, &status); if (status == 202) {status = 0; object[0] = '\0';} fits_read_key(fptr, TSTRING, "TELESCOP", telescop, NULL, &status); if (status == 202) {status = 0; telescop[0] = '\0';} fits_read_key(fptr, TSTRING, "INSTRUME", instrume, NULL, &status); if (status == 202) {status = 0; instrume[0] = '\0';} fits_read_key(fptr, TSTRING, "DATE-OBS", datobs, NULL, &status); if (status == 202) {status = 0; datobs[0] = '\0';} fits_read_key(fptr, TSTRING, "BUNIT", bunit, NULL, &status); if (status == 202) {status = 0; bunit[0] = '\0';} fits_read_key(fptr, TSTRING, "RADECSYS", radecsys, NULL, &status); if (status == 202) {status = 0; radecsys[0] = '\0';} fits_read_key(fptr, TSTRING, "OBSERVER", observer, NULL, &status); if (status == 202) {status = 0; observer[0] = '\0';} fits_read_key(fptr, TDOUBLE, "EQUINOX", &equinox, NULL, &status); if (status == 202) { /* EQUINOX not found; use EPOCH */ status = 0; /* fprintf(stderr, "Warning: EQUINOX keyword missing\n"); */ fits_read_key(fptr, TDOUBLE, "EPOCH", &equinox, NULL, &status); } fits_read_key(fptr, TDOUBLE, "OBSRA", &obsra, NULL, &status); if (status == 202) {status = 0; obsra = 0.0;} fits_read_key(fptr, TDOUBLE, "OBSDEC", &obsdec, NULL, &status); if (status == 202) {status = 0; obsdec = 0.0;} fprintf(stderr, " %s,%s,%s,%s,%s,%s,%s,%.2f,%s,%s\n", object, telescop, instrume, observer, datobs, bunit, radecsys, equinox, ra_string(obsra*RPDEG), dec_string(obsdec*RPDEG)); /* Look at the axis descriptions */ error = 0; nc = 0; nstokes = 0; nif = 0; ra = dec = freq = bw = 0.0; stokes[0] = 0; delta_stokes = 0; fprintf(stderr, " Axes (%d): ", naxis-1); for (i=1; i<naxis; i++) { status = 0; fits_make_keyn("CTYPE", i+1, keyctype, &status); fits_make_keyn("CRVAL", i+1, keycrval, &status); fits_make_keyn("CDELT", i+1, keycdelt, &status); fits_make_keyn("CRPIX", i+1, keycrpix, &status); fits_read_key(fptr, TSTRING, keyctype, ctype, NULL, &status); fits_read_key(fptr, TDOUBLE, keycrval, &crval, NULL, &status); fits_read_key(fptr, TDOUBLE, keycdelt, &cdelt, NULL, &status); fits_read_key(fptr, TDOUBLE, keycrpix, &crpix, NULL, &status); if (status) fits_report_error(stderr, status); if (i>1) fprintf(stderr, ","); fprintf(stderr, "%s(%ld)", ctype, naxes[i]); if (strcmp(ctype, "RA") == 0) { ra = crval; error += (naxes[i] != 1); } else if (strcmp(ctype, "DEC") == 0) { dec = crval; error += (naxes[i] != 1); } else if (strcmp(ctype, "COMPLEX") == 0) { nc = naxes[i]; error += (nc != 3); error += (crval != 1.0); } else if (strcmp(ctype, "STOKES") == 0) { nstokes = naxes[i]; error += (nstokes < 1 || nstokes > MAX_STOKES); delta_stokes = cdelt; for (k=0; k < MAX_STOKES; k++) { stokes[k] = crval + (1+k-crpix)*cdelt; } error += (nc == 0); /* COMPLEX must be an earlier axis than STOKES */ } else if (strcmp(ctype, "FREQ") == 0) { freq = crval; bw = cdelt; error += (naxes[i] != 1); } else if (strcmp(ctype, "IF") == 0) { nif = naxes[i]; error += (nif < 1); error += (crval != 1.0); error += (nstokes == 0); /* STOKES must be an earlier axis than IF */ error += (nc == 0); /* COMPLEX must be an earlier axis than IF */ } else { error += 1; } } fprintf(stderr, "\n"); if (error > 0) { fprintf(stderr, "This is not an acceptable UV-FITS file\n"); return 1; } fprintf(stderr, " RA=%s, Dec=%s, Stokes=", ra_string(ra*RPDEG), dec_string(dec*RPDEG)); for (k = 0; k < nstokes; k++) fprintf(stderr,"%s,", stokes_label(stokes[k])); fprintf(stderr, " Freq=%.6g, BW=%.6g\n", freq, bw); nval = nc*nif; /* Number of data values at each uv point */ /* Look at the parameter descriptions */ header->index_u = -1; header->index_v = -1; header->index_w = -1; header->index_baseline = -1; header->index_date1 = -1; header->index_date2 = -1; header->index_inttim = -1; fprintf(stderr, " Parameters (%ld): ", pcount); for (i=0; i<pcount; i++) { status = 0; fits_make_keyn("PTYPE", i+1, keyctype, &status); fits_read_key(fptr, TSTRING, keyctype, ctype, NULL, &status); fits_make_keyn("PSCAL", i+1, keyctype, &status); fits_read_key(fptr, TDOUBLE, keyctype, &header->pscal[i], NULL, &status); fits_make_keyn("PZERO", i+1, keyctype, &status); fits_read_key(fptr, TDOUBLE, keyctype, &header->pzero[i], NULL, &status); if (status) fits_report_error(stderr, status); if (i>0) fprintf(stderr, ","); fprintf(stderr, "%s", ctype); if (strcmp("UU---SIN", ctype) == 0 || strcmp("UU", ctype) == 0) header->index_u = i; else if (strcmp("VV---SIN", ctype) == 0 || strcmp("VV", ctype) == 0) header->index_v = i; else if (strcmp("WW---SIN", ctype) == 0 || strcmp("WW", ctype) == 0) header->index_w = i; else if (strcmp("BASELINE", ctype) == 0) header->index_baseline = i; else if (strcmp("INTTIM", ctype) == 0) header->index_inttim = i; /* optional */ else if (strcmp("DATE", ctype) == 0) { if (header->index_date1 == -1) header->index_date1 = i; else header->index_date2 = i; } else { fprintf(stderr, "\nIgnoring unknown parameter \"%s\"\n", ctype); } } fprintf(stderr, "\n"); if (header->index_u < 0 || header->index_v < 0 || header->index_w < 0 || header->index_baseline < 0 || header->index_date1 < 0) { fprintf(stderr, "A required parameter is missing\n"); return 1; } if (pcount > MAX_PAR) { fprintf(stderr, "Too many group parameters in UVF file\n"); return 1; } if (DEBUG) { for (i=0; i < pcount; i++) fprintf(stderr,"%g %g\n", header->pscal[i], header->pzero[i]); } /* Save header */ strcpy(header->object, object); strcpy(header->telescop, telescop); strcpy(header->instrume, instrume); strcpy(header->bunit, bunit); strcpy(header->radecsys, radecsys); strcpy(header->observer, observer); header->equinox = equinox; header->obsra = obsra; header->obsdec = obsdec; header->ra = ra; header->dec = dec; header->freq = freq; header->bw = bw; header->nstokes = nstokes; header->delta_stokes = delta_stokes; for (k = 0; k < nstokes; k++) header->stokes[k] = stokes[k]; header->nif = nif; header->nchan = nif*nstokes; header->nsamp = gcount; header->pcount = pcount; header->n_antennas = 0; /* Read the data to find the time range */ max_date = 0.0; min_date = 1e20; for (group=1; group <= gcount; group++) { get_sample(fptr, header, group, &sample); if (sample.date < min_date) min_date = sample.date; if (sample.date > max_date) max_date = sample.date; } header->start_jd = min_date; header->end_jd = max_date; fprintf(stderr, " Time range: MJD %.8f to %.8f\n", min_date, max_date); /* Find the extensions */ fits_get_num_hdus(fptr, &hdunum, &status); for (i=1; i < hdunum; i++) { fits_movabs_hdu(fptr, i+1, &hdutype, &status); if (hdutype == BINARY_TBL || hdutype == ASCII_TBL) { fits_read_key(fptr, TSTRING, "EXTNAME", extname, NULL, &status); fits_read_key(fptr, TINT, "EXTVER", &extver, NULL, &status); fprintf(stderr, " Extension %d is %s version %d (%s table)\n", i, extname, extver, hdutype == BINARY_TBL ? "binary" : "ascii"); if (hdutype == BINARY_TBL && strcmp(extname, "AIPS AN") == 0) get_antable(fptr, i+1, header); if (hdutype == BINARY_TBL && strcmp(extname, "AIPS FQ") == 0) get_fqtable(fptr, i+1, header); } else { fprintf(stderr, " Skipping unknown extension of type %d\n", hdutype); } } return status ? 1 : 0; }