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; }
static void image_keywords_from_fits(image_str *image, fitsfile *fits) { char card[FLEN_CARD]; int status = 0; fits_read_record(fits, 0, card, &status); while(TRUE){ char key[FLEN_KEYWORD]; char value[FLEN_VALUE]; char comment[FLEN_COMMENT]; int length = 0; image_keyword_str *kw = NULL; status = 0; fits_find_nextkey(fits, include_list, include_length, exclude_list, exclude_length, card, &status); if(status == KEY_NO_EXIST) break; fits_get_keyname(card, key, &length, &status); fits_parse_value(card, value, comment, &status); if(key[0] != '_'){ kw = image_keyword_add(image, key, value, comment); fits_get_keytype(value, &kw->type, &status); } } }
int main(int argc, char *argv[]) { fitsfile *fitsFilePtr; char card[FLEN_CARD]; int status, numKey, numHDU, curKey, curHDU, hduType; status = 0; /* Must initialize status before use */ if(argc < 2) { printf("ERROR\n"); exit(11); } /* Open the fits file */ fits_open_file(&fitsFilePtr, argv[1], READONLY, &status); reportAndExitOnFITSerror(status); /* Get the number of HDUs -- usually only one */ fits_get_num_hdus(fitsFilePtr, &numHDU, &status); reportAndExitOnFITSerror(status); printf("Number of headers in file: %d\n", numHDU); /* Get the current HDU number. This first one is '1', not '0'. */ fits_get_hdu_num(fitsFilePtr, &curHDU); reportAndExitOnFITSerror(status); printf("Working on header number: %d\n", curHDU); fits_get_hdu_type(fitsFilePtr, &hduType, &status); reportAndExitOnFITSerror(status); switch(hduType) { case IMAGE_HDU : printf("HDU Type: IMAGE\n"); break; case ASCII_TBL : printf("HDU Type: ASCII Table\n"); break; case BINARY_TBL: printf("HDU Type: Binary Table\n"); break; default : printf("HDU Type: UNKNOWN\n"); break; } /* Get the size (number of keys) of the header space */ fits_get_hdrspace(fitsFilePtr, &numKey, NULL, &status); reportAndExitOnFITSerror(status); printf("Number of keys in current HDU: %d\n", numKey); /* One can traverse all the lines like this: */ for(curKey = 1; curKey <= numKey; curKey++) { /* read the current keyword */ fits_read_record(fitsFilePtr, curKey, card, &status); reportAndExitOnFITSerror(status); printf("%5d: %s\n", curKey, card); } printf("END\n\n"); /* We are done. Close the file. */ fits_close_file(fitsFilePtr, &status); reportAndExitOnFITSerror(status); /* If we get here, everything worked! */ return 0; }
/** * Function: get_fits_header * Returns the header of extension hdunum from a fits file filename * * Parameters: * @param filename The name of the FITS file * @param hdunum the number of the HDU to access * * Returns: * @return a pointer to a newly allocated string containing the entire header */ char * get_fits_header (char filename[], int hdunum) { fitsfile *input; int f_status = 0, hdutype; int nkeys, i; char card[FLEN_CARD]; char *header, *p; // Open the file for creating/appending fits_open_file (&input, filename, READONLY, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_fits_header: Could not open" " file:", filename); } fits_movabs_hdu (input, hdunum, &hdutype, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_fits_header: " "Could not read extention %d from file: %s", hdunum, filename); } fits_get_hdrspace (input, &nkeys, NULL, &f_status); /* get # of keywords */ header = (char *) malloc ((nkeys + 1) * FLEN_CARD * sizeof (char)); p = header; for (i = 0; i < nkeys; i++) { /* Read and print each keywords */ if (fits_read_record (input, i + 1, card, &f_status)) break; sprintf(p,"%-80s", card); p = p + 80; } /* Add END keyword */ sprintf (card, "END"); sprintf(p,"%-80s", card); return header; }
int main(int argc, char *argv[]) { fitsfile *fptr; /* pointer to the FITS file, defined in fitsio.h */ int status, nkeys, keypos, hdutype, ii, jj; char filename[FLEN_FILENAME]; /* input FITS file */ char card[FLEN_CARD]; /* standard string lengths defined in fitsioc.h */ status = 0; if (argc == 1) strcpy(filename, "-"); /* no command line name, so assume stdin */ else strcpy(filename, argv[1] ); /* name of file to list */ if ( fits_open_file(&fptr, filename, READONLY, &status) ) printerror( status ); /* get the current HDU number */ fits_get_hdu_num(fptr, &ii); /* attempt to move to next HDU, until we get an EOF error */ for (; !(fits_movabs_hdu(fptr, ii, &hdutype, &status) ); ii++) { /* get no. of keywords */ if (fits_get_hdrpos(fptr, &nkeys, &keypos, &status) ) printerror( status ); printf("Header listing for HDU #%d:\n", ii); for (jj = 1; jj <= nkeys; jj++) { if ( fits_read_record(fptr, jj, card, &status) ) printerror( status ); printf("%s\n", card); /* print the keyword card */ } printf("END\n\n"); /* terminate listing with END */ } if (status == END_OF_FILE) /* status values are defined in fitsio.h */ status = 0; /* got the expected EOF error; reset = 0 */ else printerror( status ); /* got an unexpected error */ if ( fits_close_file(fptr, &status) ) printerror( status ); return(0); }
void FitsReader::readHistory() { int status = 0; int npos, moreKeys; fits_get_hdrspace(_fitsPtr, &npos, &moreKeys, &status); checkStatus(status, _filename); char keyCard[256]; for(int pos=1; pos<=npos; ++pos) { fits_read_record(_fitsPtr, pos, keyCard, &status); keyCard[7] = 0; if(std::string("HISTORY") == keyCard) { _history.push_back(&keyCard[8]); } } }
int appendheader ( char *outfile, char *infile ) { fitsfile *infptr, *outfptr; /* FITS file pointer, defined in fitsio.h */ char card[FLEN_CARD]; /* Standard string lengths defined in fitsio.h */ int status = 0; /* CFITSIO status value MUST be initialized to zero! */ int nkeys, ii; char keyword[FLEN_KEYWORD], keyvalue[FLEN_VALUE], keycomment[FLEN_COMMENT]; char temp[FLEN_KEYWORD]; strcpy(temp,"COMMENT"); if (!fits_open_file(&infptr, infile, READONLY, &status)) { if (!fits_open_file(&outfptr, outfile, READWRITE, &status)) { fits_get_hdrspace(infptr, &nkeys, NULL, &status); /* get # of keywords */ for (ii = 1; ii <= nkeys; ii++) { /* Read and write each keywords */ if (fits_read_record(infptr, ii, card, &status))break; fits_read_keyn(infptr, ii, keyword, keyvalue, keycomment, &status); /* check if this is a protected keyword that must not be changed */ if (*card && fits_get_keyclass(card) == TYP_STRUC_KEY) printf("%s - Protected keyword cannot be modified.\n", keyword); else { if (!strcmp(temp, keyword)) { /* do not overwrite COMMENTs */ fits_write_record(outfptr, card, &status); } else { fits_update_card(outfptr, keyword, card, &status); } printf("Writing - %s\n", card); } } fits_close_file(outfptr, &status); } if (status == END_OF_FILE) status = 0; /* Reset after normal error */ fits_close_file(infptr, &status); } }
void readheader( char *filename ) /**********************************************************************/ /* Print out all the header keywords in all extensions of a FITS file */ /**********************************************************************/ { fitsfile *fptr; /* pointer to the FITS file, defined in fitsio.h */ int status, nkeys, keypos, hdutype, ii, jj; char card[FLEN_CARD]; /* standard string lengths defined in fitsioc.h */ status = 0; if ( fits_open_file(&fptr, filename, READONLY, &status) ) printerror( status, __LINE__ ); /* attempt to move to next HDU, until we get an EOF error */ for (ii = 1; !(fits_movabs_hdu(fptr, ii, &hdutype, &status) ); ii++) { /* get no. of keywords */ if (fits_get_hdrpos(fptr, &nkeys, &keypos, &status) ) printerror( status, __LINE__ ); printf("Header listing for HDU #%d:\n", ii); for (jj = 1; jj <= nkeys; jj++) { if ( fits_read_record(fptr, jj, card, &status) ) printerror( status, __LINE__ ); printf("%s\n", card); /* print the keyword card */ } printf("END\n\n"); /* terminate listing with END */ } if (status == END_OF_FILE) /* status values are defined in fitsioc.h */ status = 0; /* got the expected EOF error; reset = 0 */ else printerror( status, __LINE__ ); /* got an unexpected error */ if ( fits_close_file(fptr, &status) ) printerror( status, __LINE__ ); return; }
QMap<QString, QString> fitsKeys( fitsfile *fp, int HDU ) { QMap<QString, QString> keyMap; int ret = 0; int nHDU; int hduType; // try to seek to the desired HDU if (fits_get_num_hdus(fp, &nHDU, &ret)) { return keyMap; } if (HDU > nHDU) { return keyMap; } else { if (fits_movabs_hdu(fp, HDU, &hduType, &ret)) { return keyMap; } } // reset keyword pointer to beginning of HDU int rec = 0; char card[FLEN_CARD]; if (fits_read_record(fp, rec, card, &ret)) { return keyMap; } // go through all keys and add to the QMap QString theKey; QString theVal; char keyval[FLEN_VALUE]; char keycom[FLEN_COMMENT]; char keyname[FLEN_KEYWORD]; int keylen; while (!fits_find_nextkey(fp, NULL, 1, NULL, 0, card, &ret)) { fits_get_keyname(card, keyname, &keylen, &ret); fits_parse_value(card, keyval, keycom, &ret); theKey = keyname; theVal = keyval; keyMap.insert(theKey, theVal); } return keyMap; }
int showkey(char *filename, char *keyword) { /* function showkey displays keyword and value if keyword is COMMENT or HISTORY, it displays all respective lines. */ fitsfile *fptr; /* FITS file pointer, defined in fitsio.h */ char card[FLEN_CARD]; int status = 0, nkeys, i; /* CFITSIO status value MUST be initialized to zero! */ if (!fits_open_file(&fptr, filename, READONLY, &status)) { for (i=0; i<FLEN_CARD; i++) keyword[i]=toupper(keyword[i]); if ( !strcmp(keyword, "COMMENT") || !strcmp(keyword, "HISTORY")) { fits_get_hdrspace(fptr, &nkeys, NULL, &status); /* get # of keywords */ for (i = 1; i <= nkeys; i++) { /* Read and print each keywords */ if (fits_read_record(fptr, i, card, &status)) break; if ( !strncmp(card, keyword, 7) ) printf("%s\n", card); } } else { if (fits_read_card(fptr, keyword, card, &status)) { printf("Keyword does not exist\n"); status = 0; /* reset status after error */ } else printf("%s\n",card); } fits_close_file(fptr, &status); } /* open_file */ /* if error occured, print out error message */ if (status) fits_report_error(stderr, status); return(status); }
int main(int argc, char *argv[]) { (void)argc; fitsfile *fptr; char card[FLEN_CARD]; int status = 0, nkeys, ii; /* MUST initialize status */ fits_open_file(&fptr, argv[1], READONLY, &status); fits_get_hdrspace(fptr, &nkeys, NULL, &status); for (ii = 1; ii <= nkeys; ii++) { fits_read_record(fptr, ii, card, &status); /* read keyword */ printf("%s\n", card); } printf("END\n\n"); /* terminate listing with END */ fits_close_file(fptr, &status); if (status) /* print any error messages */ fits_report_error(stderr, status); return(status); }
int fits_print_header(fitsfile* fptr, int* status) { /* get # of keywords */ int nkeys = 0; fits_get_hdrspace(fptr, &nkeys, 0, status); if (*status && nkeys == 0) return *status; /* Standard string lengths defined in fitsio.h */ static char card[FLEN_CARD]; int i; /* Read and print each keywords */ for (i=1; i<=nkeys; i++) { if (fits_read_record(fptr, i, card, status)) break; printf("%s\n", card); } /* terminate listing with END */ printf("END\n"); fits_print_error(*status); return *status; }
/* copy image section from input to putput, with binning */ int copyImageSection(fitsfile *ifptr, fitsfile *ofptr, int *dims, double *cens, int bin, char *slice, int *status) { void *buf; char card[FLEN_CARD]; char tbuf[SZ_LINE]; int numkeys, nkey, bitpix, dtype; int start[2]; int end[2]; int naxis = 2; long nelements; long naxes[2]; long fpixel[2] = {1,1}; buf = getImageToArray(ifptr, dims, cens, bin, slice, start, end, &bitpix, status); if( !buf || *status ){ fits_get_errstatus(*status, tbuf); fprintf(stderr, "ERROR: could not create section for output image: %s\n", tbuf); return *status; } /* get image size and total number of elements */ naxes[0] = (int)((end[0] - start[0] + 1) / bin); naxes[1] = (int)((end[1] - start[1] + 1) / bin); nelements = naxes[0] * naxes[1]; /* convert bitpix to cfitio data type */ switch(bitpix){ case 8: dtype = TBYTE; break; case 16: dtype = TSHORT; break; case -16: dtype = TUSHORT; break; case 32: dtype = TINT; break; case 64: dtype = TLONGLONG; break; case -32: dtype = TFLOAT; break; case -64: dtype = TDOUBLE; break; default: fprintf(stderr, "ERROR: unknown data type for image section\n"); return -1; } /* this code is modeled after cfitsio/cfileio.c/fits_copy_image_section() */ fits_create_img(ofptr, bitpix, naxis, naxes, status); /* copy all other non-structural keywords from the input to output file */ fits_get_hdrspace(ifptr, &numkeys, NULL, status); for(nkey=4; nkey<=numkeys; nkey++) { fits_read_record(ifptr, nkey, card, status); if (fits_get_keyclass(card) > TYP_CMPRS_KEY){ /* write the record to the output file */ fits_write_record(ofptr, card, status); } } if( *status > 0 ){ fprintf(stderr, "ERROR: can't copy header from input image to output section"); return(*status); } /* write image to FITS file */ fits_write_pix(ofptr, dtype, fpixel, nelements, buf, status); /* update LTM/TLV values in header */ updateLTM(ifptr, ofptr, (int)((end[0] + start[0]) / 2), (int)((end[1] + start[1]) / 2), (int)(end[0] - start[0] + 1), (int)(end[1] - start[1] + 1), bin, 1); /* free up space */ if( buf ){ free(buf); } /* return status */ return *status; }
int main(int argc, char *argv[]) { fitsfile *infptr, *outfptr; /* FITS file pointers defined in fitsio.h */ int status = 0, ii = 1, iteration = 0, single = 0, hdupos; int hdutype, bitpix, bytepix, naxis = 0, nkeys, datatype = 0, anynul; long naxes[9] = {1, 1, 1, 1, 1, 1, 1, 1, 1}; long first, totpix = 0, npix; double *array, bscale = 1.0, bzero = 0.0, nulval = 0.; char card[81]; if (argc != 3) { printf("\n"); printf("Usage: imcopy inputImage outputImage[compress]\n"); printf("\n"); printf("Copy an input image to an output image, optionally compressing\n"); printf("or uncompressing the image in the process. If the [compress]\n"); printf("qualifier is appended to the output file name then the input image\n"); printf("will be compressed using the tile-compressed format. In this format,\n"); printf("the image is divided into rectangular tiles and each tile of pixels\n"); printf("is compressed and stored in a variable-length row of a binary table.\n"); printf("If the [compress] qualifier is omitted, and the input image is\n"); printf("in tile-compressed format, then the output image will be uncompressed.\n"); printf("\n"); printf("If an extension name or number is appended to the input file name, \n"); printf("enclosed in square brackets, then only that single extension will be\n"); printf("copied to the output file. Otherwise, every extension in the input file\n"); printf("will be processed in turn and copied to the output file.\n"); printf("\n"); printf("Examples:\n"); printf("\n"); printf("1) imcopy image.fit 'cimage.fit[compress]'\n"); printf("\n"); printf(" This compresses the input image using the default parameters, i.e.,\n"); printf(" using the Rice compression algorithm and using row by row tiles.\n"); printf("\n"); printf("2) imcopy cimage.fit image2.fit\n"); printf("\n"); printf(" This uncompress the image created in the first example.\n"); printf(" image2.fit should be identical to image.fit if the image\n"); printf(" has an integer datatype. There will be small differences\n"); printf(" in the pixel values if it is a floating point image.\n"); printf("\n"); printf("3) imcopy image.fit 'cimage.fit[compress GZIP 100,100;4]'\n"); printf("\n"); printf(" This compresses the input image using the following parameters:\n"); printf(" GZIP compression algorithm;\n"); printf(" 100 X 100 pixel compression tiles;\n"); printf(" noise_bits = 4 (only used with floating point images)\n"); printf("\n"); printf("The full syntax of the compression qualifier is:\n"); printf(" [compress ALGORITHM TDIM1,TDIM2,...; NOISE_BITS]\n"); printf("where the allowed ALGORITHM values are Rice, GZIP, PLIO, \n"); printf("and TDIMn is the size of the compression tile in each dimension,\n"); printf("and NOISE_BITS = 1, 2, 3, or 4 and controls the amount of noise\n"); printf("suppression when compressing floating point images. \n"); printf("\n"); printf("Note that it may be necessary to enclose the file names\n"); printf("in single quote characters on the Unix command line.\n"); return(0); } /* Open the input file and create output file */ fits_open_file(&infptr, argv[1], READONLY, &status); fits_create_file(&outfptr, argv[2], &status); if (status != 0) { fits_report_error(stderr, status); return(status); } fits_get_hdu_num(infptr, &hdupos); /* Get the current HDU position */ /* Copy only a single HDU if a specific extension was given */ if (hdupos != 1 || strchr(argv[1], '[')) single = 1; for (; !status; hdupos++) /* Main loop through each extension */ { fits_get_hdu_type(infptr, &hdutype, &status); if (hdutype == IMAGE_HDU) { /* get image dimensions and total number of pixels in image */ for (ii = 0; ii < 9; ii++) naxes[ii] = 1; fits_get_img_param(infptr, 9, &bitpix, &naxis, naxes, &status); totpix = naxes[0] * naxes[1] * naxes[2] * naxes[3] * naxes[4] * naxes[5] * naxes[6] * naxes[7] * naxes[8]; } if (hdutype != IMAGE_HDU || naxis == 0 || totpix == 0) { /* just copy tables and null images */ fits_copy_hdu(infptr, outfptr, 0, &status); } else { /* Explicitly create new image, to support compression */ fits_create_img(outfptr, bitpix, naxis, naxes, &status); if (status) { fits_report_error(stderr, status); return(status); } /* copy all the user keywords (not the structural keywords) */ fits_get_hdrspace(infptr, &nkeys, NULL, &status); for (ii = 1; ii <= nkeys; ii++) { fits_read_record(infptr, ii, card, &status); if (fits_get_keyclass(card) > TYP_CMPRS_KEY) fits_write_record(outfptr, card, &status); } switch(bitpix) { case BYTE_IMG: datatype = TBYTE; break; case SHORT_IMG: datatype = TSHORT; break; case LONG_IMG: datatype = TINT; break; case FLOAT_IMG: datatype = TFLOAT; break; case DOUBLE_IMG: datatype = TDOUBLE; break; } bytepix = abs(bitpix) / 8; npix = totpix; iteration = 0; /* try to allocate memory for the entire image */ /* use double type to force memory alignment */ array = (double *) calloc(npix, bytepix); /* if allocation failed, divide size by 2 and try again */ while (!array && iteration < 10) { iteration++; npix = npix / 2; array = (double *) calloc(npix, bytepix); } if (!array) { printf("Memory allocation error\n"); return(0); } /* turn off any scaling so that we copy the raw pixel values */ fits_set_bscale(infptr, bscale, bzero, &status); fits_set_bscale(outfptr, bscale, bzero, &status); first = 1; while (totpix > 0 && !status) { /* read all or part of image then write it back to the output file */ fits_read_img(infptr, datatype, first, npix, &nulval, array, &anynul, &status); fits_write_img(outfptr, datatype, first, npix, array, &status); totpix = totpix - npix; first = first + npix; } free(array); } if (single) break; /* quit if only copying a single HDU */ fits_movrel_hdu(infptr, 1, NULL, &status); /* try to move to next HDU */ } if (status == END_OF_FILE) status = 0; /* Reset after normal error */ fits_close_file(outfptr, &status); fits_close_file(infptr, &status); /* if error occurred, print out error message */ if (status) fits_report_error(stderr, status); return(status); }
int read_kpvt( char *input_file_name, char *aux_file, int verbose_flag, int minmax_flag) { int status = 0; /* * If the Compiler macro FITS is not defined, that means the makefile * determined that libcfitsio.a was not available. Instead of shutting down * the entire converter Lets just disable any read routines thatt depend on * the FITS library * */ #ifdef FITS extern int linear_minmax_search(float *, int, float *, float *); fitsfile *fits_filePtr; char header_buffer[FLEN_CARD ]; float operand1; int i, j; int number_of_fits_header_keys; int number_of_fits_hdus; int hdu_type; int bit_pix; long naxes[10]; int maxdim = 10; long fpixel[10]; float missing_val = 256*256*256; int anynul; float net_flux_2d_static[180][360]; float net_flux_2d_static_flat[64800]; float total_flux_2d_static[180][360]; float total_flux_2d_static_flat[64800]; float weights_2d_static[180][360]; float weights_2d_static_flat[64800]; /** open fits file **/ fits_open_file( &fits_filePtr, input_file_name, READONLY, &status); /** get number_of_fits_header_keys **/ fits_get_hdrspace(fits_filePtr, &number_of_fits_header_keys, NULL, &status); /** get the number of hdu's in the current file **/ fits_get_num_hdus(fits_filePtr, &number_of_fits_hdus, &status); printf("FITS File: %s has %d hdu's\n", input_file_name, number_of_fits_hdus); /** for every hdu **/ for (i=0; i<number_of_fits_hdus; i++) { /** select hdu by number **/ fits_movabs_hdu(fits_filePtr, number_of_fits_hdus, &hdu_type, &status); /** there are three type of hdu's * IMAGE_HDU * ACSII_TBL * BINARY_TBL * ********************************/ if (hdu_type == IMAGE_HDU) { printf("Current HDU Type is IMAGE\n"); /*** get general info about the current image file ***/ fits_get_img_param( fits_filePtr, maxdim, &bit_pix, &naxis, naxes, &status); printf("bitpix = %d\nnaxis = %d\n", bit_pix, naxis); if (DEBUG_FLAG) { for (i = 0; i<naxis; i++) printf("naxis[%d] = %ld\n", i, naxes[i]); } naxis1 = naxes[0]; naxis2 = naxes[1]; number_of_elements = naxis1 * naxis2; /** dynamically allocate space for the image grid **/ carrington_longitiude = malloc(naxis1 * sizeof(float)); carrington_sine_latitude = malloc(naxis2 * sizeof(float)); /** dynamically allocate space for the flat variable arrays **/ net_flux = malloc(number_of_elements * sizeof(float)); total_flux = malloc(number_of_elements * sizeof(float)); weights = malloc(number_of_elements * sizeof(float)); /** manually insert sequential grid values from 1 - naxes[*] **/ operand1 = 2.0 / naxis2; if (DEBUG_FLAG) { printf( "\n\n\n\n\n\nWTF: operand1 = %f\nnaxis2 = %d\n", operand1, naxis2); } for (i=0; i < naxis2; i++) { /** convert to sine latidude **/ /* carrington_sine_latitude[i] = i+1; */ carrington_sine_latitude[i] = (-1.0) + (operand1 * ( (i + 1 ) - .5 ) ); if (DEBUG_FLAG) printf("%d deg = %f\n", i+1, carrington_sine_latitude[i]); } for (i=0; i < naxis1; i++) { carrington_longitiude[i] = i+1; if (DEBUG_FLAG) printf("%d deg = %f deg\n", i+1, carrington_longitiude[i]); } /** print position values **/ for (i=0; i<naxis2; i+=30) { for (j=0; j<naxis1; j+=30) { if (DEBUG_FLAG) { printf( "position[%f][%f]\n", carrington_sine_latitude[i], carrington_longitiude[j]); } } } /** print c_lon values **/ for (i=0; i<naxis1; i++) { if( DEBUG_FLAG ) printf("c_lon[%d] = %f ", i, carrington_longitiude[i]); } /** print c_sine_lat values **/ for (i=0; i<naxis2; i++) { if( DEBUG_FLAG ) printf("c_sine_lat[%d] = %f ", i, carrington_sine_latitude[i]); } /** dynamically allocate memory for the three image slices that we * expect - we must reverse the majority since the fits api expects * array[column][row] **/ net_flux_2d = malloc(naxis1 * sizeof(float *)); for (i=0; i< naxis1; i++) { net_flux_2d[i] = malloc(naxis2 * sizeof(float)); } total_flux_2d = malloc(naxis2 * sizeof(float *)); for (i=0; i< naxis2; i++) { total_flux_2d[i] = malloc(naxis1 * sizeof(float)); } weights_2d = malloc(naxis2 * sizeof(float *)); for (i=0; i< naxis2; i++) { weights_2d[i] = malloc(naxis1 * sizeof(float)); } /*** read in the image data ***/ /** this is the starting point for the read - slice one - net flux **/ fpixel[0] = fpixel[1] = fpixel[2]= 1; if( DEBUG_FLAG ) printf( "\nfpixel[0] = %ld\nfpixel[1] = %ld\nfpixel[2] = %ld\nnumber_of_elements = %ld\n\n", fpixel[0], fpixel[1], fpixel[2], number_of_elements); /* fits_read_pix( fits_filePtr, TFLOAT, fpixel, number_of_elements, &missing_val, *net_flux_2d, &anynul, &status ); */ fits_read_pix( fits_filePtr, TFLOAT, fpixel, number_of_elements, &missing_val, net_flux_2d_static, &anynul, &status); /** this is the starting point for the read - slice two - total flux */ fpixel[2] = 2; if( DEBUG_FLAG ) printf( "fpixel[0] = %ld\nfpixel[1] = %ld\nfpixel[2] = %ld\nnumber_of_elements = %ld\n\n", fpixel[0], fpixel[1], fpixel[2], number_of_elements); /* * fits_read_pix( fits_filePtr, TFLOAT, fpixel, number_of_elements, * &missing_val, *total_flux_2d, &anynul, &status ); * */ fits_read_pix( fits_filePtr, TFLOAT, fpixel, number_of_elements, &missing_val, total_flux_2d_static, &anynul, &status); /** this is the starting point for the read - slice three - weights **/ fpixel[2] = 3; if( DEBUG_FLAG )printf( "fpixel[0] = %ld\nfpixel[1] = %ld\nfpixel[2] = %ld\nnumber_of_elements = %ld\n\n", fpixel[0], fpixel[1], fpixel[2], number_of_elements); /* * fits_read_pix( fits_filePtr, TFLOAT, fpixel, number_of_elements, * &missing_val, *weights_2d, &anynul, &status ); * */ fits_read_pix( fits_filePtr, TFLOAT, fpixel, number_of_elements, &missing_val, weights_2d_static, &anynul, &status); /** flatten out arrays **/ for (i=0; i<naxis2; i++) { for (j=0; j<naxis1; j++) { /* net_flux[ i * naxis1 + j] = net_flux_2d_static[i][j]; total_flux[ i * naxis1 + j] = total_flux_2d[i][j]; weights[ i * naxis1 + j] = weights_2d[i][j]; */ net_flux[ i * naxis1 + j] = net_flux_2d_static[i][j]; total_flux[ i * naxis1 + j] = total_flux_2d_static[i][j]; weights[ i * naxis1 + j] = weights_2d_static[i][j]; } } /*** DEBUG PRINT OUT OF VALUES ***/ /* for( i=0;i<naxis2;i+=20) { for( j=0;j<naxis1;j+=20) { printf( "net_flux[%d][%d] = %f\n", i,j, net_flux[i * naxis1 + j] ); printf( "net_flux_2d[%d][%d] = %f\n", i,j, net_flux_2d[i][j] ); printf( "net_flux_2d_static[%d][%d] = %f\n", i,j, net_flux_2d_static[i][j] ); printf( "net_flux_2d_static_flat[%d][%d] = %f\n", i,j, net_flux_2d_static_flat[i * naxis1 + j] ); printf( "total_flux[%d][%d] = %f\n", i,j, total_flux[i * naxis1 + j] ); printf( "total_flux_2d[%d][%d] = %f\n", i,j, total_flux_2d[i][j] ); printf( "weights[%d][%d] = %f\n", i,j, weights[i * naxis1 + j] ); printf( "weights_2d[%d][%d] = %f\n\n", i,j, weights_2d[i][j] ); } } */ } else if (hdu_type == ASCII_TBL) { printf("Current HDU Type is ACSII TABLE\n"); } else if (hdu_type == BINARY_TBL) { printf("Current HDU Type is BINARY TABLE\n"); } /*** get the header info for the current hdu ***/ for (i = 0; i < number_of_fits_header_keys; i++) { fits_read_record(fits_filePtr, i, header_buffer, &status); printf("%s\n", header_buffer); } } /** close fits file **/ fits_close_file(fits_filePtr, &status); if (status) { fits_report_error( stderr, status); } /* * calcluate actual min/max values for each ariable unless -nominmax flag was * specified * */ /** add more error handling for each linear_minmax_search function call **/ /*** if -nominmax option was NOT specified ***/ if ( !minmax_flag) { if (verbose_flag) { printf("\ncalculating actual minimum & maximum values for each variable ...\n"); } if (verbose_flag) { printf("%-25s%-25s%-25s\n", "", "min", "max"); } linear_minmax_search( carrington_longitiude, naxis1, &carrington_longitiude_actual_min, &carrington_longitiude_actual_max); if (verbose_flag) { printf( "%-25s%-25g%-25g\n", "c_lon", carrington_longitiude_actual_min, carrington_longitiude_actual_max); } linear_minmax_search( carrington_sine_latitude, naxis2, &carrington_sine_latitude_actual_min, &carrington_sine_latitude_actual_max); if (verbose_flag) { printf( "%-25s%-25g%-25g\n", "c_sine_lat", carrington_sine_latitude_actual_min, carrington_sine_latitude_actual_max); } linear_minmax_search( net_flux, number_of_elements, &net_flux_actual_min, &net_flux_actual_max); if (verbose_flag) { printf( "%-25s%-25g%-25g\n", "net_flux", net_flux_actual_min, net_flux_actual_max); } linear_minmax_search( total_flux, number_of_elements, &total_flux_actual_min, &total_flux_actual_max); if (verbose_flag) { printf( "%-25s%-25g%-25g\n", "total_flux", total_flux_actual_min, total_flux_actual_max); } linear_minmax_search( weights, number_of_elements, &weights_actual_min, &weights_actual_max); if (verbose_flag) { printf( "%-25s%-25g%-25g\n", "weights", weights_actual_min, weights_actual_max); } } #endif #ifndef FITS printf("\n\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf("!! WARNING: from %s line [%d]. Conversion Software was not compiled and linked with netCDF libraries ( libcfitsio.a ). No .fts FITS files will be ingested... \n", __FILE__, __LINE__ ); return EXIT_FAILURE; #endif return status; }
//--------------------------------------------------------------------------- //--------------------------------------------------------------------------- void __fastcall TForm1::BAbrirClick(TObject *Sender) { fitsfile *fptr = 0; /* pointer to the FITS file, defined in fitsio.h */ int status, nkeys, keypos, hdutype, ii, jj; char filename[FLEN_FILENAME]; /* input FITS file */ char card[FLEN_CARD]; /* standard string lengths defined in fitsioc.h */ char aux[300]; int ejes = 0; long ajes[4] = {0,0,0,0}; int tipo; if(fptr != 0) { status = 0; if ( fits_close_file(fptr, &status) ) { printerror( status ); return; } } if(OD1->Execute()) { status = 0; if ( fits_open_file(&fptr, OD1->FileName.c_str(), READWRITE, &status) ) { printerror(status); return; } } else return; fits_get_hdu_num(fptr, &ii); // get the current HDU number Memo1->Lines->Add("HDU NUMBER: " + AnsiString(ii)); // attempt to move to next HDU, until we get an EOF error status = 0; for (; !(fits_movabs_hdu(fptr, ii, &hdutype, &status) ); ii++) { status = 0; if (fits_get_hdrpos(fptr, &nkeys, &keypos, &status) )// get no. of keywords { printerror( status ); return; } wsprintf(aux, "Header listing for HDU #%d:", ii); Memo1->Lines->Add(aux); for (jj = 1; jj <= nkeys; jj++) { status = 0; if ( fits_read_record(fptr, jj, card, &status) ) { printerror( status ); return; } Memo1->Lines->Add(card); // print the keyword card } printf("END\n\n"); /* terminate listing with END */ } if (status == END_OF_FILE) /* status values are defined in fitsio.h */ status = 0; /* got the expected EOF error; reset = 0 */ else { printerror( status ); /* got an unexpected error */ return; } status = 0; if(ffgipr(fptr, 2, &tipo, &ejes, ajes, &status)) { printerror( status ); return; } Memo1->Lines->Add("------"); Memo1->Lines->Add("Tipo : " + AnsiString(tipo)); Memo1->Lines->Add("EJES : " + AnsiString(ejes)); Memo1->Lines->Add("AJES0: " + AnsiString(ajes[0])); Memo1->Lines->Add("AJES1: " + AnsiString(ajes[1])); ejex = ajes[0]; ejey = ajes[1]; ////////////////////////////////////////////////////// NumeroColumnas = ejex/* / Binin*/; NumeroFilas = ejey /*/ Binin*/; X1 = X1F = 0; Y1 = Y1F = 0; X2 = X2F = NumeroColumnas; Y2 = Y2F = NumeroFilas; PB1->Width = X2 + 4; PB1->Height = Y2 + 4; PX1->Caption = X1; PX2->Caption = X2; PY1->Caption = Y1; PY2->Caption = Y2; PFil->Caption = NumeroFilas; PCol->Caption = NumeroColumnas; delete BM1; BM1 = new Graphics::TBitmap(); BM1->Height = NumeroFilas; BM1->Width = NumeroColumnas; BM1->PixelFormat = pf8bit; BM1->Palette = CreatePalette(&SysPal.lpal); for (int y = 0; y < NumeroFilas; y++) { for (int x = 0; x < NumeroColumnas; x++) { Foto[y][x] = 0; } } long primer_elemento = 1; long numelem = ejex*ejey; int cualquiernull = 0; Byte *ptr; short sust = 0; unsigned short *datos; datos = new unsigned short [ejex*ejey]; memset(datos, 0, ejex*ejey*2); status = 0; if(fits_read_img(fptr, TSHORT, primer_elemento, numelem, &sust, //valor por el que se sustituira los indefinidos &datos[primer_elemento], &cualquiernull, // 1 si hay alguna sustitucion &status)) { printerror( status ); } long n = numelem; for(int py = 0; py < ejey; py++) { for (int px = ejex; px > 0; px--) { Foto[py][px] = datos[n--]; } } delete datos; PB1->Repaint(); }
int main(int argc, char *argv[]) { fitsfile *fptr; /* FITS file pointer, defined in fitsio.h */ char card[FLEN_CARD]; /* Standard string lengths defined in fitsio.h */ int status = 0; /* CFITSIO status value MUST be initialized to zero! */ int single = 0, hdupos = 0, nkeys = 0, ii = 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 FITS header keywords in a single extension, or, if \n"); fprintf(stderr, "ext is not given, list the keywords in all the extensions. \n"); fprintf(stderr, "\n"); fprintf(stderr, "Examples: \n"); fprintf(stderr, " %s file.fits - list every header in the file \n", argv[0]); fprintf(stderr, " %s file.fits[0] - list primary array header \n", argv[0]); fprintf(stderr, " %s file.fits[2] - list header of 2nd extension \n", argv[0]); fprintf(stderr, " %s file.fits+2 - same as above \n", argv[0]); fprintf(stderr, " %s file.fits[GTI] - list header of GTI extension\n", argv[0]); 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); } #if defined(PAGER) && defined(HAVE_POPEN) && defined(HAVE_PCLOSE) FILE *fout = popen(PAGER, "w"); if (fout == NULL) { fprintf(stderr, "Could not execute '%s'\n", PAGER); return (1); } #else FILE *fout = stdout; #endif if (!fits_open_file(&fptr, argv[1], READONLY, &status)) { fits_get_hdu_num(fptr, &hdupos); /* Get the current HDU position */ /* List only a single header if a specific extension was given */ if (hdupos != 1 || strchr(argv[1], '[')) { single = 1; } for (; !status; hdupos++) { /* Main loop through each extension */ fits_get_hdrspace(fptr, &nkeys, NULL, &status); /* get # of keywords */ fprintf(fout, "Header listing for HDU #%d:\n", hdupos); for (ii = 1; ii <= nkeys; ii++) { /* Read and print each keywords */ if (fits_read_record(fptr, ii, card, &status)) { break; } fprintf(fout, "%s\n", card); } fprintf(fout, "END\n\n"); /* terminate listing with END */ if (single) { break; /* quit if only listing a single header */ } fits_movrel_hdu(fptr, 1, NULL, &status); /* try to move to next HDU */ } if (status == END_OF_FILE) { status = 0; /* Reset after normal error */ } fits_close_file(fptr, &status); } #if defined(PAGER) && defined(HAVE_POPEN) && defined(HAVE_PCLOSE) pclose(fout); #endif if (status) { fits_report_error(stderr, status); /* print any error message */ } return (status); }
static int vips_fits_get_header( VipsFits *fits, VipsImage *out ) { int status; int bitpix; int width, height, bands, format, type; int keysexist; int i; status = 0; if( fits_get_img_paramll( fits->fptr, 10, &bitpix, &fits->naxis, fits->naxes, &status ) ) { vips_fits_error( status ); return( -1 ); } #ifdef VIPS_DEBUG VIPS_DEBUG_MSG( "naxis = %d\n", fits->naxis ); for( i = 0; i < fits->naxis; i++ ) VIPS_DEBUG_MSG( "%d) %lld\n", i, fits->naxes[i] ); #endif /*VIPS_DEBUG*/ height = 1; bands = 1; switch( fits->naxis ) { /* If you add more dimensions here, adjust data read below. See also * the definition of MAX_DIMENSIONS above. */ case 10: case 9: case 8: case 7: case 6: case 5: case 4: for( i = fits->naxis; i > 3; i-- ) if( fits->naxes[i - 1] != 1 ) { vips_error( "fits", "%s", _( "dimensions above 3 " "must be size 1" ) ); return( -1 ); } case 3: bands = fits->naxes[2]; case 2: height = fits->naxes[1]; case 1: width = fits->naxes[0]; break; default: vips_error( "fits", _( "bad number of axis %d" ), fits->naxis ); return( -1 ); } /* Are we in one-band mode? */ if( fits->band_select != -1 ) bands = 1; /* Get image format. We want the 'raw' format of the image, our caller * can convert using the meta info if they want. */ for( i = 0; i < VIPS_NUMBER( fits2vips_formats ); i++ ) if( fits2vips_formats[i][0] == bitpix ) break; if( i == VIPS_NUMBER( fits2vips_formats ) ) { vips_error( "fits", _( "unsupported bitpix %d\n" ), bitpix ); return( -1 ); } format = fits2vips_formats[i][1]; fits->datatype = fits2vips_formats[i][2]; if( bands == 1 ) { if( format == VIPS_FORMAT_USHORT ) type = VIPS_INTERPRETATION_GREY16; else type = VIPS_INTERPRETATION_B_W; } else if( bands == 3 ) { if( format == VIPS_FORMAT_USHORT ) type = VIPS_INTERPRETATION_RGB16; else type = VIPS_INTERPRETATION_RGB; } else type = VIPS_INTERPRETATION_MULTIBAND; vips_image_pipelinev( out, VIPS_DEMAND_STYLE_SMALLTILE, NULL ); vips_image_init_fields( out, width, height, bands, format, VIPS_CODING_NONE, type, 1.0, 1.0 ); /* Read all keys into meta. */ if( fits_get_hdrspace( fits->fptr, &keysexist, NULL, &status ) ) { vips_fits_error( status ); return( -1 ); } for( i = 0; i < keysexist; i++ ) { char record[81]; char vipsname[100]; if( fits_read_record( fits->fptr, i + 1, record, &status ) ) { vips_fits_error( status ); return( -1 ); } VIPS_DEBUG_MSG( "fits2vips: setting meta on vips image:\n" ); VIPS_DEBUG_MSG( " record == \"%s\"\n", record ); /* FITS lets keys repeat. For example, HISTORY appears many * times, each time with a fresh line of history attached. We * have to include the key index in the vips name we assign. */ vips_snprintf( vipsname, 100, "fits-%d", i ); vips_image_set_string( out, vipsname, record ); } return( 0 ); }
image_str *image_create_from_fits(char *filename) { fitsfile *fits; char buf[FLEN_CARD]; image_str *image = NULL; int status = 0; /* Error code for CFITSIO library */ int Ndims = 0; int bitpix = 0; long Npixels = 0; long firstpix[2] = {1, 1}; long fits_dims[2] = {1, 1}; if(!filename || !file_exists_and_normal(filename)) return NULL; fits_open_file(&fits, filename, READONLY, &status); do { /* read dimensions */ fits_get_img_dim(fits, &Ndims, &status); fits_get_img_size(fits, 2, fits_dims, &status); fits_get_img_type(fits, &bitpix, &status); if(Ndims < 2){ int Nhdus = 0; int hdu = 0; int type = 0; fits_get_num_hdus(fits, &Nhdus, &status); fits_get_hdu_num(fits, &hdu); if(hdu < Nhdus){ /* dprintf("Moving to HDU %d of %d\n", hdu + 1, Nhdus); */ fits_movabs_hdu(fits, hdu + 1, &type, &status); } else { /* dprintf("Error: FITS images with less than 2 dimensions are not supported\n"); */ /* fits_close_file(fits, &status); */ /* return NULL; */ break; } } } while(Ndims < 2); if(status || Ndims > 2){ if(Ndims > 2) dprintf("Error: FITS images with more than 2 dimensions are not supported\n"); fits_close_file(fits, &status); return image; } Npixels = fits_dims[0]*fits_dims[1]; if(bitpix == DOUBLE_IMG || bitpix == FLOAT_IMG){ double *data = (double *) malloc(Npixels * sizeof(double)); fits_read_pix(fits, TDOUBLE, firstpix, Npixels, NULL, data, NULL, &status); image = image_create_with_data(fits_dims[0], fits_dims[1], (u_int16_t *)data); image->type = IMAGE_DOUBLE; } else { u_int16_t *data = (u_int16_t *) malloc(Npixels * sizeof(u_int16_t)); fits_read_pix(fits, TUSHORT, firstpix, Npixels, NULL, data, NULL, &status); image = image_create_with_data(fits_dims[0], fits_dims[1], data); } /* Read all keywords we may need */ image_keywords_from_fits(image, fits); /* Rewind the header */ fits_read_record(fits, 0, buf, &status); image->coords = image_keyword_get_coords(image); if(image->coords.ra0 == 0 && image->coords.dec0 == 0){ image->coords.ra0 = 15.0*image_keyword_get_sexagesimal(image, "RA"); image->coords.dec0 = image_keyword_get_sexagesimal(image, "DEC"); } image->time = time_str_from_date_time(image_keyword_get_string(image, "TIME")); fits_close_file(fits, &status); return image; }
/*--------------------------------------------------------------------------*/ int ffhist(fitsfile **fptr, /* IO - pointer to table with X and Y cols; */ /* on output, points to histogram image */ char *outfile, /* I - name for the output histogram file */ int imagetype, /* I - datatype for image: TINT, TSHORT, etc */ int naxis, /* I - number of axes in the histogram image */ char colname[4][FLEN_VALUE], /* I - column names */ double *minin, /* I - minimum histogram value, for each axis */ double *maxin, /* I - maximum histogram value, for each axis */ double *binsizein, /* I - bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ double weightin, /* I - binning weighting factor */ char wtcol[FLEN_VALUE], /* I - optional keyword or col for weight*/ int recip, /* I - use reciprocal of the weight? */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will*/ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow*/ /* is equal to NULL. */ int *status) { int ii, datatype, repeat, imin, imax, ibin, bitpix, tstatus, use_datamax = 0; long haxes[4]; fitsfile *histptr; char errmsg[FLEN_ERRMSG], keyname[FLEN_KEYWORD], card[FLEN_CARD]; tcolumn *colptr; iteratorCol imagepars[1]; int n_cols = 1, nkeys; long offset = 0; long n_per_loop = -1; /* force whole array to be passed at one time */ histType histData; /* Structure holding histogram info for iterator */ float amin[4], amax[4], binsize[4], maxbin[4]; float datamin = FLOATNULLVALUE, datamax = FLOATNULLVALUE; char svalue[FLEN_VALUE]; double dvalue; char cpref[4][FLEN_VALUE]; char *cptr; if (*status > 0) return(*status); if (naxis > 4) { ffpmsg("histogram has more than 4 dimensions"); return(*status = BAD_DIMEN); } /* reset position to the correct HDU if necessary */ if ((*fptr)->HDUposition != ((*fptr)->Fptr)->curhdu) ffmahd(*fptr, ((*fptr)->HDUposition) + 1, NULL, status); histData.tblptr = *fptr; histData.himagetype = imagetype; histData.haxis = naxis; histData.rowselector = selectrow; if (imagetype == TBYTE) bitpix = BYTE_IMG; else if (imagetype == TSHORT) bitpix = SHORT_IMG; else if (imagetype == TINT) bitpix = LONG_IMG; else if (imagetype == TFLOAT) bitpix = FLOAT_IMG; else if (imagetype == TDOUBLE) bitpix = DOUBLE_IMG; else return(*status = BAD_DATATYPE); /* The CPREF keyword, if it exists, gives the preferred columns. */ /* Otherwise, assume "X", "Y", "Z", and "T" */ tstatus = 0; ffgky(*fptr, TSTRING, "CPREF", cpref[0], NULL, &tstatus); if (!tstatus) { /* Preferred column names are given; separate them */ cptr = cpref[0]; /* the first preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[1], cptr); cptr = cpref[1]; /* the second preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[2], cptr); cptr = cpref[2]; /* the third preferred axis... */ while (*cptr != ',' && *cptr != '\0') cptr++; if (*cptr != '\0') { *cptr = '\0'; cptr++; while (*cptr == ' ') cptr++; strcpy(cpref[3], cptr); } } } } for (ii = 0; ii < naxis; ii++) { /* get the min, max, and binsize values from keywords, if specified */ if (*minname[ii]) { if (ffgky(*fptr, TDOUBLE, minname[ii], &minin[ii], NULL, status) ) { ffpmsg("error reading histogramming minimum keyword"); ffpmsg(minname[ii]); return(*status); } } if (*maxname[ii]) { if (ffgky(*fptr, TDOUBLE, maxname[ii], &maxin[ii], NULL, status) ) { ffpmsg("error reading histogramming maximum keyword"); ffpmsg(maxname[ii]); return(*status); } } if (*binname[ii]) { if (ffgky(*fptr, TDOUBLE, binname[ii], &binsizein[ii], NULL, status) ) { ffpmsg("error reading histogramming binsize keyword"); ffpmsg(binname[ii]); return(*status); } } if (binsizein[ii] == 0.) { ffpmsg("error: histogram binsize = 0"); return(*status = ZERO_SCALE); } if (*colname[ii] == '\0') { strcpy(colname[ii], cpref[ii]); /* try using the preferred column */ if (*colname[ii] == '\0') { if (ii == 0) strcpy(colname[ii], "X"); else if (ii == 1) strcpy(colname[ii], "Y"); else if (ii == 2) strcpy(colname[ii], "Z"); else if (ii == 3) strcpy(colname[ii], "T"); } } /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, colname[ii], histData.hcolnum+ii, status) > 0) { strcpy(errmsg, "column for histogram axis doesn't exist: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } colptr = ((*fptr)->Fptr)->tableptr; colptr += (histData.hcolnum[ii] - 1); repeat = (int) colptr->trepeat; /* vector repeat factor of the column */ if (repeat > 1) { strcpy(errmsg, "Can't bin a vector column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* get the datatype of the column */ fits_get_coltype(*fptr, histData.hcolnum[ii], &datatype, NULL, NULL, status); if (datatype < 0 || datatype == TSTRING) { strcpy(errmsg, "Inappropriate datatype; can't bin this column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status = BAD_DATATYPE); } /* use TLMINn and TLMAXn keyword values if min and max were not given */ /* else use actual data min and max if TLMINn and TLMAXn don't exist */ if (minin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMIN", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TFLOAT, keyname, amin+ii, NULL, status) > 0) { /* use actual data minimum value for the histogram minimum */ *status = 0; if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], amin+ii, &datamax, status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } } } else { amin[ii] = (float) minin[ii]; } if (maxin[ii] == DOUBLENULLVALUE) { ffkeyn("TLMAX", histData.hcolnum[ii], keyname, status); if (ffgky(*fptr, TFLOAT, keyname, &amax[ii], NULL, status) > 0) { *status = 0; if(datamax != FLOATNULLVALUE) /* already computed max value */ { amax[ii] = datamax; } else { /* use actual data maximum value for the histogram maximum */ if (fits_get_col_minmax(*fptr, histData.hcolnum[ii], &datamin, &amax[ii], status) > 0) { strcpy(errmsg, "Error calculating datamin and datamax for column: "); strcat(errmsg, colname[ii]); ffpmsg(errmsg); return(*status); } } } use_datamax = 1; /* flag that the max was determined by the data values */ /* and not specifically set by the calling program */ } else { amax[ii] = (float) maxin[ii]; } /* use TDBINn keyword or else 1 if bin size is not given */ if (binsizein[ii] == DOUBLENULLVALUE) { tstatus = 0; ffkeyn("TDBIN", histData.hcolnum[ii], keyname, &tstatus); if (ffgky(*fptr, TDOUBLE, keyname, binsizein + ii, NULL, &tstatus) > 0) { /* make at least 10 bins */ binsizein[ii] = (amax[ii] - amin[ii]) / 10. ; if (binsizein[ii] > 1.) binsizein[ii] = 1.; /* use default bin size */ } } if ( (amin[ii] > amax[ii] && binsizein[ii] > 0. ) || (amin[ii] < amax[ii] && binsizein[ii] < 0. ) ) binsize[ii] = (float) -binsizein[ii]; /* reverse the sign of binsize */ else binsize[ii] = (float) binsizein[ii]; /* binsize has the correct sign */ ibin = (int) binsize[ii]; imin = (int) amin[ii]; imax = (int) amax[ii]; /* Determine the range and number of bins in the histogram. This */ /* depends on whether the input columns are integer or floats, so */ /* treat each case separately. */ if (datatype <= TLONG && (float) imin == amin[ii] && (float) imax == amax[ii] && (float) ibin == binsize[ii] ) { /* This is an integer column and integer limits were entered. */ /* Shift the lower and upper histogramming limits by 0.5, so that */ /* the values fall in the center of the bin, not on the edge. */ haxes[ii] = (imax - imin) / ibin + 1; /* last bin may only */ /* be partially full */ maxbin[ii] = (float) (haxes[ii] + 1.); /* add 1. instead of .5 to avoid roundoff */ if (amin[ii] < amax[ii]) { amin[ii] = (float) (amin[ii] - 0.5); amax[ii] = (float) (amax[ii] + 0.5); } else { amin[ii] = (float) (amin[ii] + 0.5); amax[ii] = (float) (amax[ii] - 0.5); } } else if (use_datamax) { /* Either the column datatype and/or the limits are floating point, */ /* and the histogram limits are being defined by the min and max */ /* values of the array. Add 1 to the number of histogram bins to */ /* make sure that pixels that are equal to the maximum or are */ /* in the last partial bin are included. */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) (maxbin[ii] + 1); } else { /* float datatype column and/or limits, and the maximum value to */ /* include in the histogram is specified by the calling program. */ /* The lower limit is inclusive, but upper limit is exclusive */ maxbin[ii] = (amax[ii] - amin[ii]) / binsize[ii]; haxes[ii] = (long) maxbin[ii]; if (amin[ii] < amax[ii]) { if (amin[ii] + (haxes[ii] * binsize[ii]) < amax[ii]) haxes[ii]++; /* need to include another partial bin */ } else { if (amin[ii] + (haxes[ii] * binsize[ii]) > amax[ii]) haxes[ii]++; /* need to include another partial bin */ } } } /* get the histogramming weighting factor */ if (*wtcol) { /* first, look for a keyword with the weight value */ if (ffgky(*fptr, TFLOAT, wtcol, &histData.weight, NULL, status) ) { /* not a keyword, so look for column with this name */ *status = 0; /* get the column number in the table */ if (ffgcno(*fptr, CASEINSEN, wtcol, &histData.wtcolnum, status) > 0) { ffpmsg( "keyword or column for histogram weights doesn't exist: "); ffpmsg(wtcol); return(*status); } histData.weight = FLOATNULLVALUE; } } else histData.weight = (float) weightin; if (histData.weight <= 0. && histData.weight != FLOATNULLVALUE) { ffpmsg("Illegal histogramming weighting factor <= 0."); return(*status = URL_PARSE_ERROR); } if (recip && histData.weight != FLOATNULLVALUE) /* take reciprocal of weight */ histData.weight = (float) (1.0 / histData.weight); histData.wtrecip = recip; /* size of histogram is now known, so create temp output file */ if (ffinit(&histptr, outfile, status) > 0) { ffpmsg("failed to create temp output file for histogram"); return(*status); } if (ffcrim(histptr, bitpix, histData.haxis, haxes, status) > 0) { ffpmsg("failed to create primary array histogram in temp file"); ffclos(histptr, status); return(*status); } /* copy all non-structural keywords from the table to the image */ fits_get_hdrspace(*fptr, &nkeys, NULL, status); for (ii = 1; ii <= nkeys; ii++) { fits_read_record(*fptr, ii, card, status); if (fits_get_keyclass(card) >= 120) fits_write_record(histptr, card, status); } /* Set global variables with histogram parameter values. */ /* Use separate scalar variables rather than arrays because */ /* it is more efficient when computing the histogram. */ histData.amin1 = amin[0]; histData.maxbin1 = maxbin[0]; histData.binsize1 = binsize[0]; histData.haxis1 = haxes[0]; if (histData.haxis > 1) { histData.amin2 = amin[1]; histData.maxbin2 = maxbin[1]; histData.binsize2 = binsize[1]; histData.haxis2 = haxes[1]; if (histData.haxis > 2) { histData.amin3 = amin[2]; histData.maxbin3 = maxbin[2]; histData.binsize3 = binsize[2]; histData.haxis3 = haxes[2]; if (histData.haxis > 3) { histData.amin4 = amin[3]; histData.maxbin4 = maxbin[3]; histData.binsize4 = binsize[3]; histData.haxis4 = haxes[3]; } } } /* define parameters of image for the iterator function */ fits_iter_set_file(imagepars, histptr); /* pointer to image */ fits_iter_set_datatype(imagepars, imagetype); /* image datatype */ fits_iter_set_iotype(imagepars, OutputCol); /* image is output */ /* call the iterator function to write out the histogram image */ if (fits_iterate_data(n_cols, imagepars, offset, n_per_loop, ffwritehisto, (void*)&histData, status) ) return(*status); /* write the World Coordinate System (WCS) keywords */ /* create default values if WCS keywords are not present in the table */ for (ii = 0; ii < histData.haxis; ii++) { /* CTYPEn */ tstatus = 0; ffkeyn("TCTYP", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* just use column name as the type */ tstatus = 0; ffkeyn("TTYPE", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CTYPE", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Type", &tstatus); } else tstatus = 0; /* CUNITn */ ffkeyn("TCUNI", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); if (tstatus) { /* use the column units */ tstatus = 0; ffkeyn("TUNIT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TSTRING, keyname, svalue, NULL, &tstatus); } if (!tstatus) { ffkeyn("CUNIT", ii + 1, keyname, &tstatus); ffpky(histptr, TSTRING, keyname, svalue, "Coordinate Units", &tstatus); } else tstatus = 0; /* CRPIXn - Reference Pixel */ ffkeyn("TCRPX", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* choose first pixel in new image as ref. pix. */ tstatus = 0; } else { /* calculate locate of the ref. pix. in the new image */ dvalue = (dvalue - amin[ii]) / binsize[ii] + .5; } ffkeyn("CRPIX", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Pixel", &tstatus); /* CRVALn - Value at the location of the reference pixel */ ffkeyn("TCRVL", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { /* calculate value at ref. pix. location (at center of 1st pixel) */ dvalue = amin[ii] + binsize[ii]/2.; tstatus = 0; } ffkeyn("CRVAL", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Reference Value", &tstatus); /* CDELTn - unit size of pixels */ ffkeyn("TCDLT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (tstatus) { dvalue = 1.0; /* use default pixel size */ tstatus = 0; } dvalue = dvalue * binsize[ii]; ffkeyn("CDELT", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Pixel size", &tstatus); /* CROTAn - Rotation angle (degrees CCW) */ /* There should only be a CROTA2 keyword, and only for 2+ D images */ if (ii == 1) { ffkeyn("TCROT", histData.hcolnum[ii], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } else { /* didn't find CROTA for the 2nd axis, so look for one */ /* on the first axis */ tstatus = 0; ffkeyn("TCROT", histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, NULL, &tstatus); if (!tstatus && dvalue != 0.) /* only write keyword if angle != 0 */ { dvalue *= -1.; /* negate the value, because mirror image */ ffkeyn("CROTA", ii + 1, keyname, &tstatus); ffpky(histptr, TDOUBLE, keyname, &dvalue, "Rotation angle", &tstatus); } } } } /* convert any TPn_k keywords to PCi_j; the value remains unchanged */ /* also convert any TCn_k to CDi_j; the value is modified by n binning size */ /* This is a bit of a kludge, and only works for 2D WCS */ if (histData.haxis == 2) { /* PC1_1 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[0], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC1_1", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[0]; ffpky(histptr, TDOUBLE, "CD1_1", &dvalue, card, &tstatus); } /* PC1_2 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[0], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[1], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC1_2", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[0]; ffpky(histptr, TDOUBLE, "CD1_2", &dvalue, card, &tstatus); } /* PC2_1 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[1], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[0], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC2_1", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[1]; ffpky(histptr, TDOUBLE, "CD2_1", &dvalue, card, &tstatus); } /* PC2_2 */ tstatus = 0; ffkeyn("TP", histData.hcolnum[1], card, &tstatus); strcat(card,"_"); ffkeyn(card, histData.hcolnum[1], keyname, &tstatus); ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) ffpky(histptr, TDOUBLE, "PC2_2", &dvalue, card, &tstatus); tstatus = 0; keyname[1] = 'C'; ffgky(*fptr, TDOUBLE, keyname, &dvalue, card, &tstatus); if (!tstatus) { dvalue *= binsize[1]; ffpky(histptr, TDOUBLE, "CD2_2", &dvalue, card, &tstatus); } } /* finally, close the original file and return ptr to the new image */ ffclos(*fptr, status); *fptr = histptr; return(*status); }
void avtFITSFileFormat::Initialize(avtDatabaseMetaData *md) { const char *mName = "avtFITSFileFormat::Initialize: "; if(fits == 0) { debug4 << mName << "Opening " << filename << endl; int status = 0; if(fits_open_file(&fits, filename, 0, &status)) { PrintError(status); EXCEPTION1(InvalidFilesException, filename); } char card[FLEN_CARD], tmp[100]; std::string fileComment; int hdutype = 0; // Iterate over the HDU's for(int hdu = 1; !(fits_movabs_hdu(fits, hdu, &hdutype, &status)); hdu++) { debug4 << mName << "Looking at HDU " << hdu << endl; // Get no. of keywords int nkeys = 0, keypos = 0; if(fits_get_hdrpos(fits, &nkeys, &keypos, &status)) PrintError(status); if(hdutype == IMAGE_HDU) { debug4 << mName << "HDU " << hdu << " contains an image" << endl; //int status2 = 0; char value[FLEN_VALUE]; std::string objname, bunit, xlabel, ylabel, zlabel; // Try and get the key value for BUNIT if(GetKeywordValue("BUNIT", value)) { bunit = std::string(value); debug4 << "\tBUNIT=" << value << endl; } // Try and get the key value for OBJECT if(GetKeywordValue("OBJECT", value)) { objname = std::string(value); debug4 << "\tOBJECT=" << value << endl; } #if 0 // // Re-enable these someday when we read the mesh coordinates from the file // and use them to construct a sensible mesh. // // Try and get the key value for CTYPE1 if(GetKeywordValue("CTYPE1", value)) { xlabel = std::string(value); debug4 << "\tCTYPE1=" << value << endl; } // Try and get the key value for CTYPE2 if(GetKeywordValue("CTYPE2", value)) { ylabel = std::string(value); debug4 << "\tCTYPE2=" << value << endl; } // Try and get the key value for CTYPE3 if(GetKeywordValue("CTYPE3", value)) { zlabel = std::string(value); debug4 << "\tCTYPE3=" << value << endl; } #endif // Use the keywords to create a comment. SNPRINTF(tmp, 100, "Header listing for HDU #%d:\n", hdu); fileComment += tmp; for(int jj = 1; jj <= nkeys; jj++) { if(fits_read_record(fits, jj, card, &status)) PrintError(status); std::string cs(card); fileComment += cs; if(cs.size() > 0 && cs[cs.size()-1] != '\n') fileComment += "\n"; } fileComment += "\n\n"; // // Get the image's dimensions. // int ndims = 0; if(fits_get_img_dim(fits, &ndims, &status)) PrintError(status); debug4 << mName << "Num dimensions: " << ndims << ", status=" << status << endl; long *dims = new long[ndims]; if(fits_get_img_size(fits, ndims, dims, &status)) PrintError(status); if(ndims == 0) { debug4 << mName << "The image has no dimensions. Skip it." << endl; continue; } // // Create a mesh name for the image. // intVector mdims; std::string meshName("image"); debug4 << mName << "Image dimensions: "; bool dimensionsNonZero = false; for(int i = 0; i < ndims; ++i) { char num[20]; if(i > 0) SNPRINTF(num, 20, "x%d", (int)dims[i]); else SNPRINTF(num, 20, "%d", (int)dims[i]); meshName += num; mdims.push_back((int)dims[i]); dimensionsNonZero |= (dims[i] != 0); debug4 << dims[i] << ", "; } debug4 << endl; if(!dimensionsNonZero) { debug4 << mName << "All dimensions were zero. skip." << endl; continue; } if(ndims == 1 && objname != "") meshName = objname; if(meshDimensions.find(meshName) == meshDimensions.end()) { meshDimensions[meshName] = mdims; // Create metadata if necessary. if(md != 0) { if(ndims == 1) { debug4 << mName << "Adding a curve called " << meshName.c_str() << " for HDU " << hdu << endl; avtCurveMetaData *cmd = new avtCurveMetaData; cmd->name = meshName; if(xlabel != "") cmd->xLabel = xlabel; if(ylabel != "") cmd->yLabel = ylabel; md->Add(cmd); // Do this because we use GetVar to read the data // that we use to create the curve. varToHDU[meshName] = hdu; varToMesh[meshName] = meshName; } else { int sdims, tdims; int nrealdims = (ndims <= 3) ? ndims : 3; #define VECTOR_SUPPORT #ifdef VECTOR_SUPPORT if(nrealdims == 3 && dims[2] == 3) nrealdims = 2; #endif sdims = tdims = nrealdims; debug4 << mName << "Adding a " << sdims << " dimensional mesh called " << meshName.c_str() << " for HDU " << hdu << endl; avtMeshMetaData *mmd = new avtMeshMetaData( meshName, 1, 1, 1, 0, sdims, tdims, AVT_RECTILINEAR_MESH); if(xlabel != "") mmd->xLabel = xlabel; if(ylabel != "") mmd->yLabel = ylabel; if(zlabel != "") mmd->zLabel = zlabel; md->Add(mmd); } } } // // Create a name for the variable at this HDU // if(ndims > 1) { char varname[100]; SNPRINTF(varname, 100, "hdu%d", hdu); std::string vName(varname); if(objname != "") vName = objname; varToHDU[vName] = hdu; varToMesh[vName] = meshName; // Create metadata if necessary if(md != 0) { #ifdef VECTOR_SUPPORT // Limit the dimensions to 3. int ncomps = 1; int nrealdims = (ndims <= 3) ? ndims : 3; if(nrealdims == 3 && dims[2] == 3) ncomps = 3; if(ncomps == 1) { #endif debug4 << mName << "Adding a scalar called " << vName.c_str() << " for HDU " << hdu << endl; // Add the scalar metadata avtScalarMetaData *smd = new avtScalarMetaData( vName, meshName, AVT_ZONECENT); smd->hasUnits = bunit != ""; smd->units = bunit; md->Add(smd); #ifdef VECTOR_SUPPORT } else { debug4 << mName << "Adding a color vector called " << vName.c_str() << " for HDU " << hdu << endl; // Add the vector metadata avtVectorMetaData *vmd = new avtVectorMetaData( vName, meshName, AVT_ZONECENT, 4); // vmd->hasUnits = true; // vmd->units = md->Add(vmd); } #endif } } delete [] dims; } else if(hdutype == ASCII_TBL) { debug4 << mName << "HDU " << hdu << " contains an ascii table" << endl; } else if(hdutype == BINARY_TBL) { debug4 << mName << "HDU " << hdu << " contains a binary table" << endl; // Use the keywords to create a comment. SNPRINTF(tmp, 100, "Header listing for HDU #%d:\n", hdu); debug4 << tmp; for(int jj = 1; jj <= nkeys; jj++) { if(fits_read_record(fits, jj, card, &status)) PrintError(status); std::string cs(card); if(cs.size() > 0 && cs[cs.size()-1] != '\n') cs += "\n"; debug4 << "\t" << cs.c_str(); } } } if(md != 0) md->SetDatabaseComment(fileComment); } }
int main(int argc, char **argv) { int c, i, j, got, args, jsonlen, istart; int odim1, odim2, blen, pad; int idim1=0, idim2=0, bitpix=0, ncard=0; int verbose=0; size_t totbytes, dlen; char tbuf[SZ_LINE]; char *buf=NULL; char *jsonheader=NULL; char *iname=NULL, *oname=NULL; FILE *ofp=NULL; Optinfo optinfo; #if HAVE_CFITSIO int status = 0; int n; int hdutype; int maxcard, morekeys; int dims[2] = {0, 0}; int block = 1; void *dbuf; double d1, d2, d3, d4; double cens[2] = {0.0, 0.0}; char *s; char *filter=NULL; char *evtlist = DEF_EVTLIST; char card[81]; char s1[BUFLEN], s2[BUFLEN], s3[BUFLEN], s4[BUFLEN]; fitsfile *fptr=NULL, *ofptr=NULL; #elif HAVE_FUNTOOLS char *s=NULL; int dtype; Fun ifun=NULL, tfun=NULL; #endif /* we want the args in the same order in which they arrived, and gnu getopt sometimes changes things without this */ putenv("POSIXLY_CORRECT=true"); /* process switch arguments */ while ((c = getopt(argc, argv, "b:e:f:s:v")) != -1){ switch(c){ case 'b': #if HAVE_CFITSIO block = atoi(optarg); #else fprintf(stderr, "warning: -b switch only for cfitsio (ignoring)\n"); #endif break; case 'e': #if HAVE_CFITSIO evtlist = optarg; #else fprintf(stderr, "warning: -e switch only for cfitsio (ignoring)\n"); #endif break; case 'f': #if HAVE_CFITSIO filter = optarg; #else fprintf(stderr, "warning: -f switch only for cfitsio (ignoring)\n"); #endif break; case 's': #if HAVE_CFITSIO s = strdup(optarg); if( strlen(s) > BUFLEN ) s[BUFLEN-1] = '\0'; if( sscanf(s, "%[0-9.*] @ %[-0-9.*] , %[0-9.*] @ %[-0-9.*]%n", s1, s2, s3, s4, &n) == 4){ dims[0] = atof(s1); cens[0] = atof(s2); dims[1] = atof(s3); cens[1] = atof(s4); } else if(sscanf(s, "%[-0-9.*] : %[-0-9.*] , %[-0-9.*] : %[-0-9.*]%n", s1, s2, s3, s4, &n) == 4){ d1 = atof(s1); d2 = atof(s2); d3 = atof(s3); d4 = atof(s4); dims[0] = d2 - d1 + 1; cens[0] = dims[0] / 2; dims[1] = d4 - d3 + 1; cens[1] = dims[1] / 2; } else { fprintf(stderr, "warning: unknown arg for -s switch (ignoring)\n"); } if( s ) free(s); #else fprintf(stderr, "warning: -s switch only for cfitsio (ignoring)\n"); #endif break; case 'v': verbose++; break; } } /* check for required arguments */ args = argc - optind; if( args < 2 ){ fprintf(stderr, "usage: %s iname oname\n", argv[0]); exit(1); } iname = argv[optind++]; oname = argv[optind++]; /* optional info */ if( !(optinfo = (Optinfo)calloc(sizeof(OptinfoRec), 1)) ){ fprintf(stderr, "ERROR: can't allocate optional info rec\n"); exit(1); } /* open the input FITS file */ #if HAVE_CFITSIO fptr = openFITSFile(iname, evtlist, &hdutype, &status); errchk(status); #elif HAVE_FUNTOOLS if( !(ifun = FunOpen(iname, "r", NULL)) ){ fprintf(stderr, "ERROR could not open input FITS file: %s (%s)\n", iname, strerror(errno)); exit(1); } #endif /* save the input filename in the png file */ optinfo->fitsname = iname; /* open the output PGN file */ if( !strcmp(oname, "-") || !strcmp(oname, "stdout") ){ ofp = stdout; } else if( !(ofp = fopen(oname, "w")) ){ fprintf(stderr, "ERROR: could not create output PNG file: %s (%s)\n", oname, strerror(errno)); exit(1); } #if HAVE_CFITSIO switch(hdutype){ case IMAGE_HDU: // get image array dbuf = getImageToArray(fptr, NULL, NULL, &idim1, &idim2, &bitpix, &status); errchk(status); fits_get_hdrspace(fptr, &maxcard, &morekeys, &status); errchk(status); ofptr = fptr; break; default: ofptr = filterTableToImage(fptr, filter, NULL, dims, cens, block, &status); errchk(status); // get image array dbuf = getImageToArray(ofptr, NULL, NULL, &idim1, &idim2, &bitpix, &status); errchk(status); // get number of keys fits_get_hdrspace(ofptr, &maxcard, &morekeys, &status); errchk(status); break; } #elif HAVE_FUNTOOLS /* copy the input fits header into a FITS image header */ if( !(tfun = (Fun)calloc(1, sizeof(FunRec))) ){ fprintf(stderr, "ERROR: could not create tfun struct\n"); exit(1); } _FunCopy2ImageHeader(ifun, tfun); /* and save for storage in the png file */ optinfo->fitsheader = (char *)tfun->header->cards; /* get image parameters. its safe to do this before calling image get so long as we don't change bitpix before that call */ FunInfoGet(ifun, FUN_SECT_BITPIX, &bitpix, FUN_SECT_DIM1, &idim1, FUN_SECT_DIM2, &idim2, 0); #endif /* convert FITS header into a json string */ snprintf(tbuf, SZ_LINE-1, "{\"js9Protocol\": %s, ", JS9_PROTOCOL); scat(tbuf, &jsonheader); snprintf(tbuf, SZ_LINE-1, "\"js9Endian\": \"%s\", ", JS9_ENDIAN); scat(tbuf, &jsonheader); snprintf(tbuf, SZ_LINE-1, "\"cardstr\": \""); scat(tbuf, &jsonheader); // concat header cards into a single string #if HAVE_CFITSIO while( ++ncard <= maxcard ){ fits_read_record(ofptr, ncard, card, &status); errchk(status); // change " to ' for(i=0; i<80; i++){ if( card[i] == '"' ){ card[i] = '\''; } } snprintf(tbuf, SZ_LINE-1, "%-80s", card); scat(tbuf, &jsonheader); } #elif HAVE_FUNTOOLS while( (s = FunParamGets(tfun, NULL, ++ncard, NULL, &dtype)) ){ for(i=0; i<80; i++){ if( s[i] == '"' ){ s[i] = '\''; } } scat(s, &jsonheader); if( s ) free(s); } #endif // end with the number of cards snprintf(tbuf, SZ_LINE-1, "\", \"ncard\": %d}", ncard); scat(tbuf, &jsonheader); /* we want the image buffer to start on an 8-byte boundary, so make jsonheader + null byte end on one */ pad = 8 - (strlen(jsonheader) % 8) - 1; for(i=0; i<pad; i++){ strcat(jsonheader, " "); } /* get final length of json header */ jsonlen = strlen(jsonheader); /* total length of the header + null + image we are storing */ blen = ABS(bitpix/8); dlen = (size_t)idim1 * (size_t)idim2 * blen; totbytes = jsonlen + 1 + dlen; /* all of this should now fit into the png image */ /* somewhat arbitrarily, we use idim1 for odim1, and adjust odim2 to fit */ odim1 = idim1; odim2 = (int)(((totbytes + odim1 - 1) / odim1) + (COLOR_CHANNELS-1)) / COLOR_CHANNELS; /* allocate buf to hold json header + null byte + RGB image */ if( !(buf=calloc(COLOR_CHANNELS, odim1 * odim2)) ){ fprintf(stderr, "ERROR: can't allocate image buf\n"); exit(1); } /* move the json header into the output buffer */ memmove(buf, jsonheader, jsonlen); /* add a null byte to signify end of json header */ buf[jsonlen] = '\0'; /* offset into image buffer where image starts, past header and null byte */ istart = jsonlen + 1; /* debug output */ if( verbose ){ fprintf(stderr, "idim=%d,%d (bitpix=%d jsonlen=%d istart=%d endian=%s) [%ld] -> odim=%d,%d [%d]\n", idim1, idim2, bitpix, jsonlen, istart, JS9_ENDIAN, totbytes, odim1, odim2, odim1 * odim2 * COLOR_CHANNELS); } #if HAVE_CFITSIO /* move the json header into the output buffer */ memmove(&buf[istart], dbuf, dlen); #elif HAVE_FUNTOOLS /* extract and bin the data section into an image buffer */ if( !FunImageGet(ifun, &buf[istart], NULL) ){ fprintf(stderr, "ERROR: could not FunImageGet: %s\n", iname); exit(1); } #endif /* debugging output to check against javascript input */ if( verbose > 1 ){ fprintf(stderr, "jsonheader: %s\n", jsonheader); for(j=0; j<idim2; j++){ fprintf(stderr, "data #%d: ", j); for(i=0; i<idim1; i++){ switch(bitpix){ case 8: fprintf(stderr, "%d ", *(unsigned char *)(buf + istart + ((j * idim1) + i) * blen)); break; case 16: fprintf(stderr, "%d ", *(short *)(buf + istart + ((j * idim1) + i) * blen)); break; case -16: fprintf(stderr, "%d ", *(unsigned short *)(buf + istart + ((j * idim1) + i) * blen)); break; case 32: fprintf(stderr, "%d ", *(int *)(buf + istart + ((j * idim1) + i) * blen)); break; case -32: fprintf(stderr, "%.3f ", *(float *)(buf + istart + ((j * idim1) + i) * blen)); break; case -64: fprintf(stderr, "%.3f ", *(double *)(buf + istart + ((j * idim1) + i) * blen)); break; } } fprintf(stderr, "\n"); } fprintf(stderr, "\n"); } /* might have to swap to preferred endian for png creation */ if( (!strncmp(JS9_ENDIAN, "l", 1) && is_bigendian()) || (!strncmp(JS9_ENDIAN, "b", 1) && !is_bigendian()) ){ swap_data(&buf[istart], idim1 * idim2, bitpix/8); } /* write the PNG file */ got = writePNG(ofp, buf, odim1, odim2, optinfo); /* free up space */ if( buf ) free(buf); if( optinfo ) free(optinfo); if( jsonheader ) free(jsonheader); /* close files */ #if HAVE_CFITSIO status = 0; if( ofptr && (ofptr != fptr) ) closeFITSFile(ofptr, &status); if( fptr ) closeFITSFile(fptr, &status); if( dbuf ) free(dbuf); #elif HAVE_FUNTOOLS if( ifun ) FunClose(ifun); if( tfun ){ FunClose(tfun); free(tfun); } #endif if( ofp) fclose(ofp); /* return the news */ return got; }