Пример #1
0
fitsfile* create_fits_file(const char* filename, int precision,
        int width, int height, int num_times, int num_channels,
        double centre_deg[2], double fov_deg[2], double start_time_mjd,
        double delta_time_sec, double start_freq_hz, double delta_freq_hz,
        int* status)
{
    long naxes[4];
    double delta;
    fitsfile* f = 0;
    FILE* t = 0;
    if (*status) return 0;

    /* Create a new FITS file and write the image headers. */
    t = fopen(filename, "rb");
    if (t)
    {
        fclose(t);
        remove(filename);
    }
    naxes[0]  = width;
    naxes[1]  = height;
    naxes[2]  = num_channels;
    naxes[3]  = num_times;
    fits_create_file(&f, filename, status);
    fits_create_img(f, (precision == OSKAR_DOUBLE ? DOUBLE_IMG : FLOAT_IMG),
            4, naxes, status);
    fits_write_date(f, status);

    /* Write axis headers. */
    delta = oskar_convert_fov_to_cellsize(fov_deg[0] * M_PI/180, width) * 180/M_PI;
    write_axis_header(f, 1, "RA---SIN", "Right Ascension",
            centre_deg[0], -delta, width / 2 + 1, 0.0, status);
    delta = oskar_convert_fov_to_cellsize(fov_deg[1] * M_PI/180, height) * 180/M_PI;
    write_axis_header(f, 2, "DEC--SIN", "Declination",
            centre_deg[1], delta, height / 2 + 1, 0.0, status);
    write_axis_header(f, 3, "FREQ", "Frequency",
            start_freq_hz, delta_freq_hz, 1.0, 0.0, status);
    write_axis_header(f, 4, "UTC", "Time",
            start_time_mjd, delta_time_sec, 1.0, 0.0, status);

    /* Write other headers. */
    fits_write_key_str(f, "BUNIT", "JY/BEAM", "Brightness units", status);
    fits_write_key_str(f, "TIMESYS", "UTC", NULL, status);
    fits_write_key_str(f, "TIMEUNIT", "s", "Time axis units", status);
    fits_write_key_dbl(f, "MJD-OBS", start_time_mjd, 10, "Start time", status);
    fits_write_key_dbl(f, "OBSRA", centre_deg[0], 10, "RA", status);
    fits_write_key_dbl(f, "OBSDEC", centre_deg[1], 10, "DEC", status);
    /*fits_flush_file(f, status);*/

    return f;
}
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 fitsfile* create_fits_file(const char* filename, int precision,
        int width, int height, int num_times, int num_channels,
        double centre_deg[2], double fov_deg[2], double start_time_mjd,
        double delta_time_sec, double start_freq_hz, double delta_freq_hz,
        int horizon_mode, const char* settings_log, size_t settings_log_length,
        int* status)
{
    int imagetype;
    long naxes[4], naxes_dummy[4] = {1l, 1l, 1l, 1l};
    double delta;
    const double deg2rad = M_PI / 180.0;
    const double rad2deg = 180.0 / M_PI;
    fitsfile* f = 0;
    const char* line;
    size_t length;
    if (*status) return 0;

    /* Create a new FITS file and write the image headers. */
    if (oskar_file_exists(filename)) remove(filename);
    imagetype = (precision == OSKAR_DOUBLE ? DOUBLE_IMG : FLOAT_IMG);
    naxes[0]  = width;
    naxes[1]  = height;
    naxes[2]  = num_channels;
    naxes[3]  = num_times;
    fits_create_file(&f, filename, status);
    fits_create_img(f, imagetype, 4, naxes_dummy, status);
    fits_write_date(f, status);
    fits_write_key_str(f, "TELESCOP", "OSKAR " OSKAR_VERSION_STR, 0, status);

    /* Write axis headers. */
    if (horizon_mode)
    {
        delta = oskar_convert_fov_to_cellsize(M_PI, width);
        write_axis(f, 1, "-----SIN", "Azimuthal angle",
                0.0, -delta * rad2deg, (width + 1) / 2.0, status);
        delta = oskar_convert_fov_to_cellsize(M_PI, height);
        write_axis(f, 2, "-----SIN", "Elevation",
                90.0, delta * rad2deg, (height + 1) / 2.0, status);
    }
    else
    {
        delta = oskar_convert_fov_to_cellsize(fov_deg[0] * deg2rad, width);
        write_axis(f, 1, "RA---SIN", "Right Ascension",
                centre_deg[0], -delta * rad2deg, (width + 1) / 2.0, status);
        delta = oskar_convert_fov_to_cellsize(fov_deg[1] * deg2rad, height);
        write_axis(f, 2, "DEC--SIN", "Declination",
                centre_deg[1], delta * rad2deg, (height + 1) / 2.0, status);
    }
    write_axis(f, 3, "FREQ", "Frequency",
            start_freq_hz, delta_freq_hz, 1.0, status);
    write_axis(f, 4, "UTC", "Time",
            start_time_mjd * 86400.0, delta_time_sec, 1.0, status);

    /* Write other headers. */
    fits_write_key_str(f, "TIMESYS", "UTC", NULL, status);
    fits_write_key_str(f, "TIMEUNIT", "s", "Time axis units", status);
    fits_write_key_dbl(f, "MJD-OBS", start_time_mjd, 10, "Start time", status);
    if (!horizon_mode)
    {
        fits_write_key_dbl(f, "OBSRA", centre_deg[0], 10, "RA", status);
        fits_write_key_dbl(f, "OBSDEC", centre_deg[1], 10, "DEC", status);
    }

    /* Write the settings log up to this point as HISTORY comments. */
    line = settings_log;
    length = settings_log_length;
    for (; settings_log_length > 0;)
    {
        const char* eol;
        fits_write_history(f, line, status);
        eol = (const char*) memchr(line, '\0', length);
        if (!eol) break;
        eol += 1;
        length -= (eol - line);
        line = eol;
    }

    /* Update header keywords with the correct axis lengths.
     * Needs to be done here because CFITSIO doesn't let us write only the
     * file header with the correct axis lengths to start with. This trick
     * allows us to create a small dummy image block to write only the headers,
     * and not waste effort moving a huge block of zeros within the file. */
    fits_update_key_lng(f, "NAXIS1", naxes[0], 0, status);
    fits_update_key_lng(f, "NAXIS2", naxes[1], 0, status);
    fits_update_key_lng(f, "NAXIS3", naxes[2], 0, status);
    fits_update_key_lng(f, "NAXIS4", naxes[3], 0, status);

    return f;
}
Пример #4
0
/// Saves the current image in the OpenCL memory buffer to the specified FITS file
/// If the OpenCL memory has not been initialzed, this function immediately returns
void   CLibOI::ExportImage(string filename)
{
	if(mImage_cl == NULL)
		return;

	// TODO: Adapt for multi-spectral images
	Normalize();

	// Create a storage buffer for the image and copoy the image to it:
	valarray<float> image(mImageWidth * mImageHeight * mImageDepth);
	ExportImage(&image[0], mImageWidth, mImageHeight, mImageDepth);

	// write out the FITS file:
	fitsfile *fptr;
	int status = 0;
	long fpixel = 1, naxis = 2, nelements;
	long naxes[2];

	/*Initialise storage*/
	naxes[0] = (long) mImageWidth;
	naxes[1] = (long) mImageHeight;
	nelements = mImageWidth * mImageWidth;

	/*Create new file*/
	if (status == 0)
		fits_create_file(&fptr, filename.c_str(), &status);

	/*Create primary array image*/
	if (status == 0)
		fits_create_img(fptr, FLOAT_IMG, naxis, naxes, &status);

	double RPMAS = (M_PI / 180.0) / 3600000.0;
	double image_scale_rad = mImageScale * RPMAS;

	// Write keywords to get WCS to work //
	fits_write_key_dbl(fptr, "CDELT1", -image_scale_rad, 3, "Radians per pixel", &status);
	fits_write_key_dbl(fptr, "CDELT2", image_scale_rad, 3, "Radians per pixel", &status);
	fits_write_key_dbl(fptr, "CRVAL1", 0.0, 3, "X-coordinate of reference pixel", &status);
	fits_write_key_dbl(fptr, "CRVAL2", 0.0, 3, "Y-coordinate of reference pixel", &status);
	fits_write_key_lng(fptr, "CRPIX1", naxes[0]/2, "reference pixel in X", &status);
	fits_write_key_lng(fptr, "CRPIX2", naxes[1]/2, "reference pixel in Y", &status);
	fits_write_key_str(fptr, "CTYPE1", "RA",  "Name of X-coordinate", &status);
	fits_write_key_str(fptr, "CTYPE2", "DEC", "Name of Y-coordinate", &status);
	fits_write_key_str(fptr, "CUNIT1", "rad", "Unit of X-coordinate", &status);
	fits_write_key_str(fptr, "CUNIT2", "rad", "Unit of Y-coordinate", &status);

	/*Write a keywords (datafile, target, image scale) */
//	if (status == 0)
//		fits_update_key(fptr, TSTRING, "DATAFILE", "FakeImage", "Data File Name", &status);
//	if (status == 0)
//		fits_update_key(fptr, TSTRING, "TARGET", "FakeImage", "Target Name", &status);
//	if (status == 0)
//		fits_update_key(fptr, TFLOAT, "SCALE", &mImageScale, "Scale (mas/pixel)", &status);


	/*Write image*/
	if (status == 0)
		fits_write_img(fptr, TFLOAT, fpixel, nelements, &image[0], &status);

	/*Close file*/
	if (status == 0)
		fits_close_file(fptr, &status);

	/*Report any errors*/
	fits_report_error(stderr, status);
}
Пример #5
0
int HPXhdr(fitsfile *fptr, struct healpix *hpxdat)

{
  char   comment[64], cval[16], *ctype1, *ctype2, *descr1, *descr2, *pcode;
  int    status;
  float  cos45, crpix1, crpix2, crval1, crval2, lonpole;
  double cdelt1, cdelt2;

  status = 0;

  fits_update_key_log(fptr, "EXTEND", 0,
    "No FITS extensions are present", &status);
  fits_write_date(fptr, &status);

  /* Set pixel transformation parameters. */
  if (hpxdat->layout == 0) {
    crpix1 = (5 * hpxdat->nside + 1) / 2.0f;
  } else {
    crpix1 = (4 * hpxdat->nside + 1) / 2.0f;
  }
  crpix2 = crpix1;

  fits_write_key(fptr, TFLOAT, "CRPIX1", &crpix1,
    "Coordinate reference pixel", &status);
  fits_write_key(fptr, TFLOAT, "CRPIX2", &crpix2,
    "Coordinate reference pixel", &status);

  cos45 = (float)sqrt(2.0) / 2.0f;
  if (hpxdat->layout == 0) {
    fits_write_key_flt(fptr, "PC1_1",  cos45, -8,
      "Transformation matrix element", &status);
    fits_write_key_flt(fptr, "PC1_2",  cos45, -8,
      "Transformation matrix element", &status);
    fits_write_key_flt(fptr, "PC2_1", -cos45, -8,
      "Transformation matrix element", &status);
    fits_write_key_flt(fptr, "PC2_2",  cos45, -8,
      "Transformation matrix element", &status);
  }

  cdelt1 = -90.0 / hpxdat->nside / sqrt(2.0);
  cdelt2 = -cdelt1;
  fits_write_key_dbl(fptr, "CDELT1", cdelt1, -8,
    "[deg] Coordinate increment", &status);
  fits_write_key_dbl(fptr, "CDELT2", cdelt2, -8,
    "[deg] Coordinate increment", &status);


  /* Celestial transformation parameters. */
  if (hpxdat->layout == 0) {
    pcode = "HPX";
  } else {
    pcode = "XPH";
  }

  if (hpxdat->crdsys == 'G') {
    /* Galactic. */
    ctype1 = "GLON";
    ctype2 = "GLAT";
    descr1 = "Galactic longitude";
    descr2 = "Galactic  latitude";
  } else if (hpxdat->crdsys == 'E') {
    /* Ecliptic, who-knows-what. */
    ctype1 = "ELON";
    ctype2 = "ELAT";
    descr1 = "Ecliptic longitude";
    descr2 = "Ecliptic  latitude";
  } else if (hpxdat->crdsys == 'Q') {
    /* Equatorial, who-knows-what. */
    ctype1 = "RA--";
    ctype2 = "DEC-";
    descr1 = "Right ascension";
    descr2 = "Declination";
  } else {
    /* Unknown. */
    ctype1 = "XLON";
    ctype2 = "XLAT";
    descr1 = "Longitude";
    descr2 = " Latitude";
  }

  sprintf(cval, "%s-%s", ctype1, pcode);
  sprintf(comment, "%s in an %s projection", descr1, pcode);
  fits_write_key_str(fptr, "CTYPE1", cval, comment, &status);
  sprintf(cval, "%s-%s", ctype2, pcode);
  sprintf(comment, "%s in an %s projection", descr2, pcode);
  fits_write_key_str(fptr, "CTYPE2", cval, comment, &status);


  crval1 = 0.0f + 90.0f * hpxdat->quad;
  if (hpxdat->layout == 0) {
    crval2 =   0.0f;
  } else if (hpxdat->layout == 1) {
    crval1 += 180.0f;
    crval2  =  90.0f;
  } else {
    crval1 += 180.0f;
    crval2  = -90.0f;
  }
  if (360.0f < crval1) crval1 -= 360.0f;

  sprintf(comment, "[deg] %s at the reference point", descr1);
  fits_write_key(fptr, TFLOAT, "CRVAL1", &crval1, comment, &status);
  sprintf(comment, "[deg] %s at the reference point", descr2);
  fits_write_key(fptr, TFLOAT, "CRVAL2", &crval2, comment, &status);

  if (hpxdat->layout) {
    lonpole = 180.0f;
    sprintf(comment, "[deg] Native longitude of the celestial pole");
    fits_write_key(fptr, TFLOAT, "LONPOLE", &lonpole, comment, &status);
  }

  if (hpxdat->layout == 0) {
    fits_write_key_lng(fptr, "PV2_1", (LONGLONG)4,
      "HPX H parameter (longitude)", &status);
    fits_write_key_lng(fptr, "PV2_2", (LONGLONG)3,
      "HPX K parameter  (latitude)", &status);
  }

  /* Commentary. */
  fits_write_record(fptr, " ", &status);
  if (hpxdat->layout == 0) {
    fits_write_comment(fptr,
      "Celestial map with FITS-standard HPX coordinate system generated by",
      &status);
  } else {
    fits_write_comment(fptr,
      "Celestial map with XPH coordinate system (polar HPX) generated by",
      &status);
  }

  fits_write_comment(fptr,
    "'HPXcvt' which reorganises HEALPix data without interpolation as",
    &status);
  fits_write_comment(fptr,
    "described in \"Mapping on the HEALPix grid\" by Mark Calabretta and",
    &status);
  fits_write_comment(fptr,
    "Boud Roukema.  See http://www.atnf.csiro.au/people/Mark.Calabretta",
    &status);

  return status;
}