int fitsNamesUnits( fitsfile *fp, int HDU, QStringList *names, QStringList *units ) { int nString = 0; // clear the lists names->clear(); units->clear(); // move to desired HDU int ret = 0; int hduType; if (fits_movabs_hdu(fp, HDU, &hduType, &ret)) { return nString; } // for each type of HDU, find the column names or assign // a generic image name (since images don't have names) QString curName; QString curUnits; int maxDim; long rowLen; long nRows; int nCols; long tbCol; char **fitsNames; char **fitsUnits; long *dimAxes = NULL; int nAxis; switch (hduType) { case IMAGE_HDU: // find the size of the image and include it in the // generic name. maxDim = 100; // no images should have > 100 dimensions... dimAxes = (long*)calloc(maxDim, sizeof(long)); if (fits_read_imghdr(fp, maxDim, NULL, NULL, &nAxis, dimAxes, NULL, NULL, NULL, &ret)) { return nString; } curName = "IMAGE ("; for (int i = 0; i < nAxis; i++) { curUnits.sprintf("%ld", dimAxes[i]); curName.append(curUnits); if (i != nAxis-1) { curName.append("x"); } } curName.append(")"); names->append(curName); units->append(QString()); nString++; free(dimAxes); break; case ASCII_TBL: maxDim = 2147483646; // 2^32/2 - 2 (i.e. a big positive integer) // find number of columns if (fits_read_atblhdr(fp, maxDim, &rowLen, &nRows, &nCols, NULL, &tbCol, NULL, NULL, NULL, &ret)) { return nString; } // allocate names and units fitsNames = fitsSarrayAlloc(nCols); fitsUnits = fitsSarrayAlloc(nCols); // read names and units if (fits_read_atblhdr(fp, maxDim, &rowLen, &nRows, &nCols, fitsNames, &tbCol, NULL, fitsUnits, NULL, &ret)) { return nString; } for (int i = 0; i < nCols; i++) { curName = fitsNames[i]; curUnits = fitsUnits[i]; names->append(curName); units->append(curUnits); nString++; } fitsSarrayFree(fitsNames, nCols); fitsSarrayFree(fitsUnits, nCols); break; case BINARY_TBL: maxDim = 2147483646; // 2^32/2 - 2 (i.e. a big positive integer) // find number of columns if (fits_read_btblhdr(fp, maxDim, &nRows, &nCols, NULL, NULL, NULL, NULL, NULL, &ret)) { return nString; } // allocate names and units fitsNames = fitsSarrayAlloc(nCols); fitsUnits = fitsSarrayAlloc(nCols); // read names and units if (fits_read_btblhdr(fp, maxDim, &nRows, &nCols, fitsNames, NULL, fitsUnits, NULL, NULL, &ret)) { return nString; } for (int i = 0; i < nCols; i++) { curName = fitsNames[i]; curUnits = fitsUnits[i]; names->append(curName); units->append(curUnits); nString++; } fitsSarrayFree(fitsNames, nCols); fitsSarrayFree(fitsUnits, nCols); break; default: return nString; break; } return nString; }
QValueList<int> fitsDim( fitsfile *fp, int HDU ) { QValueList<int> dims; // move to desired HDU int ret = 0; int hduType; if (fits_movabs_hdu(fp, HDU, &hduType, &ret)) { return dims; } // for each type of HDU, find the dimensions int maxDim; long rowLen; long nRows; int nCols; long tbCol; long *dimAxes = NULL; int nAxis; switch (hduType) { case IMAGE_HDU: // find the size of the image and include it in the // generic name. maxDim = 100; // no images should have > 100 dimensions... dimAxes = (long*)calloc(maxDim, sizeof(long)); if (fits_read_imghdr(fp, maxDim, NULL, NULL, &nAxis, dimAxes, NULL, NULL, NULL, &ret)) { return dims; } for (int i = 0; i < nAxis; i++) { dims.append((int)dimAxes[i]); } free(dimAxes); break; case ASCII_TBL: maxDim = 2147483646; // 2^32/2 - 2 (i.e. a big positive integer) // find number of columns if (fits_read_atblhdr(fp, maxDim, &rowLen, &nRows, &nCols, NULL, &tbCol, NULL, NULL, NULL, &ret)) { return dims; } dims.append((int)nCols); dims.append((int)nRows); break; case BINARY_TBL: maxDim = 2147483646; // 2^32/2 - 2 (i.e. a big positive integer) // find number of columns if (fits_read_btblhdr(fp, maxDim, &nRows, &nCols, NULL, NULL, NULL, NULL, NULL, &ret)) { return dims; } dims.append((int)nCols); dims.append((int)nRows); break; default: return dims; break; } return dims; }
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; }