Пример #1
0
int copy_history(fitsfile *infptr, fitsfile *outfptr, char *infile)
{
  int status = 0;
  int i, nkeys;
  char card[81];

  /* Position files at main HDU */

  fits_movabs_hdu(outfptr, 1, NULL, &status);
  fits_movabs_hdu(infptr,  1, NULL, &status);

  /* Find the number of cards in the input header */

  fits_get_hdrspace(infptr, &nkeys, NULL, &status);

  /* Write an optional separator in the output history */

  if (infile != NULL) {
    sprintf(card, "History from file %.40s:", infile);
    fits_write_history(outfptr, "-------------------------------------------------------------------", &status);
    fits_write_history(outfptr, card, &status);
  }

  /* Read all the input cards and copy those that are HISTORY */

  for (i = 0; i < nkeys; i++) {
    fits_read_record(infptr, i+1, card, &status);
    if (strncmp(card, "HISTORY", 7) == 0)
      fits_write_record(outfptr, card, &status);
  }

  return status;
}
Пример #2
0
int     ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode)
 { int		i, r, ib;
   char		buf[200];
   long		l;


   if (NULL == ngph) return(NGP_NUL_PTR);
   if (NULL == ffp) return(NGP_NUL_PTR);
   r = NGP_OK;
   
   for (i=0; i<ngph->tokcnt; i++)
    { if ((NGP_REALLY_ALL & mode) || (NGP_OK == ngp_keyword_is_write(&(ngph->tok[i]))))
        { switch (ngph->tok[i].type)
           { case NGP_TTYPE_BOOL:
			ib = ngph->tok[i].value.b;
			fits_write_key(ffp, TLOGICAL, ngph->tok[i].name, &ib, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_STRING:
			fits_write_key_longstr(ffp, ngph->tok[i].name, ngph->tok[i].value.s, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_INT:
			l = ngph->tok[i].value.i;	/* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */
			fits_write_key(ffp, TLONG, ngph->tok[i].name, &l, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_REAL:
			fits_write_key(ffp, TDOUBLE, ngph->tok[i].name, &(ngph->tok[i].value.d), ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_COMPLEX:
			fits_write_key(ffp, TDBLCOMPLEX, ngph->tok[i].name, &(ngph->tok[i].value.c), ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_NULL:
			fits_write_key_null(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_RAW:
			if (0 == strcmp("HISTORY", ngph->tok[i].name))
			  { fits_write_history(ffp, ngph->tok[i].comment, &r);
			    break;
			  }
			if (0 == strcmp("COMMENT", ngph->tok[i].name))
			  { fits_write_comment(ffp, ngph->tok[i].comment, &r);
			    break;
			  }
			sprintf(buf, "%-8.8s%s", ngph->tok[i].name, ngph->tok[i].comment);
			fits_write_record(ffp, buf, &r);
                        break;
           }
          if (r) return(r);
        }
    }
     
   fits_set_hdustruc(ffp, &r);				/* resync cfitsio */
   return(r);
 }
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;
}
int addkey(char *outfile, char *keyword, char *keyvalue)
{
	fitsfile *fptr;         /* FITS file pointer, defined in fitsio.h */
	char card[FLEN_CARD], newcard[FLEN_CARD], temp[FLEN_CARD];
	char oldvalue[FLEN_VALUE], comment[FLEN_COMMENT];
	int status = 0;   /*  CFITSIO status value MUST be initialized to zero!  */
	int keytype, i;

	if (!fits_open_file(&fptr, outfile, READWRITE, &status))
	{
		#ifdef DEBUG
			if (fits_read_card(fptr, keyword, card, &status))
			{
				printf("Keyword does not exist\n");
				card[0] = '\0';
				comment[0] = '\0';
				status = 0;  /* reset status after error */
			}
			else 
			{
				strcpy (temp, keyword);
				for (i=0; i<FLEN_CARD; i++) 
					temp[i]=toupper(temp[i]);
				if ( strcmp("COMMENT", temp) && strcmp("HISTORY", temp) )
					printf("%s\n",card);
			}
		#endif

		/* check if this is a protected keyword that must not be changed */
		if (*card && fits_get_keyclass(card) == TYP_STRUC_KEY)
		{
			#ifdef DEBUG
				printf("Protected keyword cannot be modified.\n");
			#endif
		}
		else
		{	
			strcpy (temp, keyword);
			for (i=0; i<FLEN_CARD; i++) 
				temp[i]=toupper(temp[i]);
			if ( !strcmp ("COMMENT", temp) )
			{	fits_write_comment ( fptr, keyvalue, &status );
				#ifdef DEBUG
					printf ("New comment added.\n");
				#endif
			}
			else if ( !strcmp ("HISTORY", temp) )
			{	fits_write_history ( fptr, keyvalue, &status );
				#ifdef DEBUG
					printf ("New history added.\n");
				#endif
			}
			else 
			{
				/* get the comment string */
				if (*card)fits_parse_value(card, oldvalue, comment, &status);
	
				/* construct template for new keyword */
				strcpy(newcard, keyword);     /* copy keyword name */
				strcat(newcard, " = ");       /* '=' value delimiter */
				strcat(newcard, keyvalue);    /* new value */
				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, keyword, card, &status);
				#ifdef DEBUG	
					printf("Keyword has been changed to:\n");
					printf("%s\n",card);
				#endif
			}
		}  
		fits_close_file(fptr, &status);
	}    /* open_file */

	/* if error occured, print out error message */
	if (status) fits_report_error(stderr, status);
	return(status);
}
Пример #5
0
int HPXout(struct healpix *hpxdat)

{
  /* Number of facets on a side of each layout. */
  const int NFACET[] = {5, 4, 4};

  /* Arrays that define the facet location and rotation for each recognised
   * layout.  Bear in mind that these appear to be upside-down, i.e. the top
   * line contains facet numbers for the bottom row of the output image.
   * Facets numbered -1 are blank. */

                              /* Equatorial (diagonal) facet layout. */
  const int FACETS[][5][5] = {{{ 6,  9, -1, -1, -1},
                               { 1,  5,  8, -1, -1},
                               {-1,  0,  4, 11, -1},
                               {-1, -1,  3,  7, 10},
                               {-1, -1, -1,  2,  6}},
                              /* North polar (X) facet layout. */
                              {{ 8,  4,  4, 11, -1},
                               { 5,  0,  3,  7, -1},
                               { 5,  1,  2,  7, -1},
                               { 9,  6,  6, 10, -1},
                               {-1, -1, -1, -1, -1}},
                              /* South polar (X) facet layout. */
                              {{ 1,  6,  6,  2, -1},
                               { 5,  9, 10,  7, -1},
                               { 5,  8, 11,  7, -1},
                               { 0,  4,  4,  3, -1},
                               {-1, -1, -1, -1, -1}}};

  /* All facets of the equatorial layout are rotated by +45 degrees with
   * respect to the normal orientation, i.e. that with the equator running
   * horizontally.  The rotation recorded for the polar facets is the number
   * of additional positive (anti-clockwise) 90 degree turns with respect to
   * the equatorial layout. */

                              /* Equatorial (diagonal), no facet rotation. */
  const int FROTAT[][5][5] = {{{ 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0}},
                              /* North polar (X) facet rotation. */
                              {{ 3,  3,  0,  0,  0},
                               { 3,  3,  0,  0,  0},
                               { 2,  2,  1,  1,  0},
                               { 2,  2,  1,  1,  0},
                               { 0,  0,  0,  0,  0}},
                              /* South polar (X) facet rotation. */
                              {{ 1,  1,  2,  2,  0},
                               { 1,  1,  2,  2,  0},
                               { 0,  0,  3,  3,  0},
                               { 0,  0,  3,  3,  0},
                               { 0,  0,  0,  0,  0}}};

  /* Facet halving codes.  0: the facet is whole (or wholly blank),
   * 1: blanked bottom-right, 2: top-right, 3: top-left, 4: bottom-left.
   * Positive values mean that the diagonal is included, otherwise not. */

                              /* Equatorial (diagonal), no facet halving. */
  const int FHALVE[][5][5] = {{{ 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0},
                               { 0,  0,  0,  0,  0}},
                              /* North polar (X) facet halving. */
                              {{ 0,  1, -4,  0,  0},
                               {-3,  0,  0,  2,  0},
                               { 4,  0,  0, -1,  0},
                               { 0, -2,  3,  0,  0},
                               { 0,  0,  0,  0,  0}},
                              /* South polar (X) facet halving. */
                              {{ 0,  1, -4,  0,  0},
                               {-3,  0,  0,  2,  0},
                               { 4,  0,  0, -1,  0},
                               { 0, -2,  3,  0,  0},
                               { 0,  0,  0,  0,  0}}};

  char  history[72];
  int   facet, halve, i1, i2, ifacet, j, jfacet, layout, nfacet, nside, rotn,
        status;
  long  *healidx = 0x0, *healp, naxes[2];
  float nulval = HEALPIX_NULLVAL, *row = 0x0, *rowp;
  LONGLONG fpixel, group, nelem;
  fitsfile *fptr;


  nside  = hpxdat->nside;
  layout = hpxdat->layout;
  nfacet = NFACET[layout];

  /* Create the output FITS file. */
  status = 0;
  naxes[0] = nfacet * nside;
  naxes[1] = naxes[0];
  if (fits_create_file(&fptr, hpxdat->outfile, &status)) goto fitserr;
  if (fits_create_img(fptr, FLOAT_IMG, 2, naxes, &status)) goto fitserr;

  /* Write WCS keyrecords. */
  if ((status = HPXhdr(fptr, hpxdat))) goto fitserr;


  /* Allocate arrays. */
  if ((healidx = malloc(nside * sizeof(long)))   == NULL ||
      (row     = malloc(nside * sizeof(float)))  == NULL) {
    perror("HPXcvt");
    goto cleanup;
  }

  /* Loop vertically facet-by-facet. */
  fpixel = 1;
  group  = 0;
  nelem  = nside;
  for (jfacet = 0; jfacet < nfacet; jfacet++) {
    /* Loop row-by-row. */
    for (j = 0; j < nside; j++) {
      /* Loop horizontally facet-by-facet. */
      for (ifacet = 0; ifacet < nfacet; ifacet++) {
        facet = FACETS[layout][jfacet][ifacet];
        rotn  = FROTAT[layout][jfacet][ifacet];
        halve = FHALVE[layout][jfacet][ifacet];

        /* Recentre longitude? */
        if (hpxdat->quad && facet >= 0) {
          if (facet <= 3) {
            facet += hpxdat->quad;
            if (facet > 3) facet -= 4;
          } else if (facet <= 7) {
            facet += hpxdat->quad;
            if (facet > 7) facet -= 4;
          } else {
            facet += hpxdat->quad;
            if (facet > 11) facet -= 4;
          }
        }

        /* Write out the data. */
        if (facet < 0) {
          /* A blank facet. */
          if (fits_write_img_null(fptr, group, fpixel, nelem, &status)) {
            goto fitserr;
          }

        } else {
          if (hpxdat->ordering == 'N') {
            /* Get nested indices. */
            status = NESTidx(nside, facet, rotn, j, healidx);
          } else {
            /* Get ring indices. */
            status = RINGidx(nside, facet, rotn, j, healidx);
          }

          /* Gather data into the output vector. */
          healp = healidx;
          for (rowp = row; rowp < row + nside; rowp++) {
            *rowp = hpxdat->data[*(healp++)];
          }

          /* Apply blanking to halved facets. */
          if (halve) {
            if (abs(halve) == 1) {
              /* Blank bottom-right. */
              i1 = j;
              i2 = nside;
              if (halve > 0) i1++;
            } else if (abs(halve) == 2) {
              /* Blank top-right. */
              i1 = nside - j;
              i2 = nside;
              if (halve < 0) i1--;
            } else if (abs(halve) == 3) {
              /* Blank top-left. */
              i1 = 0;
              i2 = j;
              if (halve < 0) i2++;
            } else {
              /* Blank bottom-left. */
              i1 = 0;
              i2 = nside - j;
              if (halve > 0) i2--;
            }

            for (rowp = row + i1; rowp < row + i2; rowp++) {
              *rowp = nulval;
            }
          }

          /* Write out this facet's contribution to this row of the map. */
          if (fits_write_imgnull_flt(fptr, group, fpixel, nelem, row, nulval,
                                     &status)) {
            goto fitserr;
          }
        }

        fpixel += nelem;
      }
    }
  }

  /* Write history. */
  sprintf(history, "Original input file: %s", hpxdat->infile);
  fits_write_history(fptr, history, &status);
  sprintf(history, "     Original NSIDE: %d", hpxdat->nside);
  fits_write_history(fptr, history, &status);
  sprintf(history, "  Original ordering: %s",
    (hpxdat->ordering == 'N') ? "NESTED" : "RING");
  if (hpxdat->ordering == 'r') strcat(history, " (assumed)");
  fits_write_history(fptr, history, &status);


  /* Clean up. */
  fits_close_file(fptr, &status);
  status = 0;
  return 0;

fitserr:
  fits_report_error(stderr, status);
cleanup:
  if (healidx) free(healidx);
  if (row)     free(row);
  return 1;
}
Пример #6
0
int FITSImage::saveFITS( const QString &newFilename )
{
    int status=0;
    long fpixel[2], nelements;
    fitsfile *new_fptr;

    nelements = stats.dim[0] * stats.dim[1];
    fpixel[0] = 1;
    fpixel[1] = 1;


    /* Create a new File, overwriting existing*/
    if (fits_create_file(&new_fptr, newFilename.toAscii(), &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    /* Copy ALL contents */
    if (fits_copy_file(fptr, new_fptr, 1, 1, 1, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    /* close current file */
    if (fits_close_file(fptr, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    if (tempFile)
    {
        QFile::remove(filename);
        tempFile = false;
    }

    filename = newFilename;

    fptr = new_fptr;

    /* Write Data */
    if (fits_write_pix(fptr, TFLOAT, fpixel, nelements, image_buffer, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    /* Write keywords */

    // Minimum
    if (fits_update_key(fptr, TDOUBLE, "DATAMIN", &(stats.min), "Minimum value", &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    // Maximum
    if (fits_update_key(fptr, TDOUBLE, "DATAMAX", &(stats.max), "Maximum value", &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    // ISO Date
    if (fits_write_date(fptr, &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    QString history = QString("Modified by KStars on %1").arg(QDateTime::currentDateTime().toString("yyyy-MM-ddThh:mm:ss"));
    // History
    if (fits_write_history(fptr, history.toAscii(), &status))
    {
        fits_report_error(stderr, status);
        return status;
    }

    return status;
}
Пример #7
0
int     ngp_keyword_all_write(NGP_HDU *ngph, fitsfile *ffp, int mode)
 { int		i, r, ib;
   char		buf[200];
   long		l;


   if (NULL == ngph) return(NGP_NUL_PTR);
   if (NULL == ffp) return(NGP_NUL_PTR);
   r = NGP_OK;
   
   for (i=0; i<ngph->tokcnt; i++)
    { r = ngp_keyword_is_write(&(ngph->tok[i]));
      if ((NGP_REALLY_ALL & mode) || (NGP_OK == r))
        { switch (ngph->tok[i].type)
           { case NGP_TTYPE_BOOL:
			ib = ngph->tok[i].value.b;
			fits_write_key(ffp, TLOGICAL, ngph->tok[i].name, &ib, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_STRING:
			fits_write_key_longstr(ffp, ngph->tok[i].name, ngph->tok[i].value.s, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_INT:
			l = ngph->tok[i].value.i;	/* bugfix - 22-Jan-99, BO - nonalignment of OSF/Alpha */
			fits_write_key(ffp, TLONG, ngph->tok[i].name, &l, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_REAL:
			fits_write_key(ffp, TDOUBLE, ngph->tok[i].name, &(ngph->tok[i].value.d), ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_COMPLEX:
			fits_write_key(ffp, TDBLCOMPLEX, ngph->tok[i].name, &(ngph->tok[i].value.c), ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_NULL:
			fits_write_key_null(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r);
			break;
             case NGP_TTYPE_RAW:
			if (0 == strcmp("HISTORY", ngph->tok[i].name))
			  { fits_write_history(ffp, ngph->tok[i].comment, &r);
			    break;
			  }
			if (0 == strcmp("COMMENT", ngph->tok[i].name))
			  { fits_write_comment(ffp, ngph->tok[i].comment, &r);
			    break;
			  }
			sprintf(buf, "%-8.8s%s", ngph->tok[i].name, ngph->tok[i].comment);
			fits_write_record(ffp, buf, &r);
                        break;
           }
        }
      else if (NGP_BAD_ARG == r) /* enhancement 10 dec 2003, James Peachey: template comments replace defaults */
        { r = NGP_OK;						/* update comments of special keywords like TFORM */
          if (ngph->tok[i].comment && *ngph->tok[i].comment)	/* do not update with a blank comment */
            { fits_modify_comment(ffp, ngph->tok[i].name, ngph->tok[i].comment, &r);
            }
        }
      else /* other problem, typically a blank token */
        { r = NGP_OK;						/* skip this token, but continue */
        }
      if (r) return(r);
    }
     
   fits_set_hdustruc(ffp, &r);				/* resync cfitsio */
   return(r);
 }