Пример #1
0
/* Load one periodic spectrum from datafile 
 * Space should already be allocated.
 * idx is 1-offset following cfitsio convention.
 */
int cyclic_load_ps(fitsfile *f, PS *d, int idx, int *status) {

    /* Load data */
    long fpixel[4];
    long long nelem;
    fpixel[0] = fpixel[1] = fpixel[2] = 1;
    fpixel[3] = idx;
    nelem = d->nphase * d->npol * d->nchan;
    fits_read_pix(f, TFLOAT, fpixel, nelem, NULL, d->data, NULL, status);

    /* Load header params */
    char key[9];
    sprintf(key, "IMJD%04d", idx);
    fits_read_key(f, TINT, key, &d->imjd, NULL, status);
    sprintf(key, "FMJD%04d", idx);
    fits_read_key(f, TDOUBLE, key, &d->fmjd, NULL, status);
    sprintf(key, "PHAS%04d", idx);
    fits_read_key(f, TDOUBLE, key, &d->ref_phase, NULL, status);
    sprintf(key, "FREQ%04d", idx);
    fits_read_key(f, TDOUBLE, key, &d->ref_freq, NULL, status);
    // TODO get these in the file
    d->rf = 428.0;
    d->bw = 4.0;

    return(*status);
}
Пример #2
0
image_t	*readimage(const char *filename) {
	char	errmsg[80];
	image_t	*image = NULL;
	// open the FITS file
	int	status = 0;
	fitsfile	*fits = NULL;
	if (fits_open_file(&fits, filename, READONLY, &status)) {
		fits_get_errstatus(status, errmsg);
		fprintf(stderr, "cannot read fits file %s: %s\n",
			filename, errmsg);
		return NULL;
	}

	// find dimensions of pixel array
	int	igt;
	int	naxis;
	long	naxes[3];
	if (fits_get_img_param(fits, 3, &igt, &naxis, naxes, &status)) {
		fits_get_errstatus(status, errmsg);
		fprintf(stderr, "cannot read fits file info: %s\n", errmsg);
		goto bad;
	}
	image = (image_t *)malloc(sizeof(image_t));
	image->width = naxes[0];
	image->height = naxes[1];

	// read the pixel data
	long	npixels = image->width * image->height;
	image->data = (double *)malloc(npixels * sizeof(double));
	long	firstpixel[3] = { 1, 1, 1 };
	if (fits_read_pix(fits, TDOUBLE, firstpixel, npixels, NULL, image->data,
		NULL, &status)) {
		fits_get_errstatus(status, errmsg);
		fprintf(stderr, "cannot read pixel data: %s\n", errmsg);
		goto bad;
	}

	// close the file
	if (fits_close_file(fits, &status)) {
		fits_get_errstatus(status, errmsg);
		fprintf(stderr, "cannot close fits file %s: %s\n",
			filename, errmsg);
		goto bad;
	}

	// return the image
	return image;
bad:
	if (image) {
		if (image->data) {
			free(image->data);
		}
		free(image);
	}
	if (fits) {
		fits_close_file(fits, &status);
	}
	return NULL;
}
Пример #3
0
void FitsReader::ReadFrequency(NumType* image, size_t index)
{
	int status = 0;
	int naxis = 0;
	fits_get_img_dim(_fitsPtr, &naxis, &status);
	checkStatus(status, _filename);
	std::vector<long> firstPixel(naxis);
	for(int i=0;i!=naxis;++i) firstPixel[i] = 1;
	if(naxis > 2)
		firstPixel[2] = index+1;
	
	if(sizeof(NumType)==8)
		fits_read_pix(_fitsPtr, TDOUBLE, &firstPixel[0], _imgWidth*_imgHeight, 0, image, 0, &status);
	else if(sizeof(NumType)==4)
		fits_read_pix(_fitsPtr, TFLOAT, &firstPixel[0], _imgWidth*_imgHeight, 0, image, 0, &status);
	else
		throw std::runtime_error("sizeof(NumType)!=8 || 4 not implemented");
	checkStatus(status, _filename);
}
Пример #4
0
double get_average(std::string filename) {
	fitsfile *fptr;   /* FITS file pointer, defined in fitsio.h */
	int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
	int bitpix, naxis, ii;
	long naxes[2] = {1,1}, fpixel[2] = {1,1};
	double *pixels;

	std::vector<double> values; //stores the values of all pixels in image

	if (!fits_open_file(&fptr, filename.c_str(), READONLY, &status))
	{
		if (!fits_get_img_param(fptr, 2, &bitpix, &naxis, naxes, &status) )
		{
			if (naxis > 2 || naxis == 0)
				printf("Error: only 1D or 2D images are supported\n");
			else
			{
				/* get memory for 1 row */
				pixels = (double *) malloc(naxes[0] * sizeof(double));

				if (pixels == NULL) {
					printf("Memory allocation error\n");
					return(1);
				}

				/* loop over all the rows in the image, top to bottom */
				for (fpixel[1] = naxes[1]; fpixel[1] >= 1; fpixel[1]--)
				{
					if (fits_read_pix(fptr, TDOUBLE, fpixel, naxes[0], NULL,
							pixels, NULL, &status) )  /* read row of pixels */
						break;  /* jump out of loop on error */
					for (ii = 0; ii < naxes[0]; ii++) {
						values.push_back(pixels[ii]);
					}
				}
				free(pixels);
			}
		}
		fits_close_file(fptr, &status);
	}

	if (status) fits_report_error(stderr, status); /* print any error message */

	//report average of values
	double sum = 0;
	for (int i=0; i < values.size(); i++)
		sum += values[i];
	return sum/values.size();
}
Пример #5
0
void FitsFile::ReadCurrentImageData(long startPos, num_t *buffer, long bufferSize, long double nullValue)
{
	CheckOpen();
	int status = 0, dimensions = GetCurrentImageDimensionCount();
	long *firstpixel = new long[dimensions];
	for(int i=0;i < dimensions;i++) {
		firstpixel[i] = 1 + startPos%GetCurrentImageSize(i+1);
		startPos = startPos/GetCurrentImageSize(i+1);
	}
	double *dblbuffer = new double[bufferSize];
	double dblNullValue = nullValue;
	int anynul = 0;
	fits_read_pix(_fptr, TDOUBLE, firstpixel, bufferSize, &dblNullValue, dblbuffer, &anynul, &status);
	for(int i=0;i<bufferSize;i++)
		buffer[i] = dblbuffer[i];
	delete[] dblbuffer;
	delete[] firstpixel;
	CheckStatus(status);
}
void InputFileFITS::_readImage(Image<T>& buff, int type)
{
	int status = 0;
	if(!isOpened())
		throwException("Error in InputFileFITS::readImage() ", status);

	int bitpix;
	int naxis;
	const int MAXDIM = 3;
	long naxes[MAXDIM];
	fits_get_img_param(infptr, MAXDIM,  &bitpix, &naxis, naxes, &status);
	if(!isOpened())
		throwException("Error in InputFileFITS::readImage() ", status);


	long fpixel[MAXDIM];
	long nelements = 1;
	for(int dim=0; dim<naxis; dim++)
	{
		fpixel[dim] = 1;
		nelements *= naxes[dim];
	}

	long nulval = 0;
	int anynul;

	buff.data.resize(nelements);
	fits_read_pix(infptr, type, fpixel, nelements, &nulval, &buff.data[0], &anynul, &status);
	if(!isOpened())
		throwException("Error in InputFileFITS::readImage() ", status);

	buff.dim = naxis;

	buff.sizes.resize(0);
	for(int i=0; i<naxis; i++)
		buff.sizes.push_back(naxes[i]);
}
Пример #7
0
bool usImage::Load(const wxString& fname)
{
    bool bError = false;

    try
    {
        if (!wxFileExists(fname))
        {
            pFrame->Alert(_("File does not exist - cannot load ") + fname);
            throw ERROR_INFO("File does not exist");
        }

        int status = 0;  // CFITSIO status value MUST be initialized to zero!
        fitsfile *fptr;  // FITS file pointer
        if (!PHD_fits_open_diskfile(&fptr, fname, READONLY, &status))
        {
            int hdutype;
            if (fits_get_hdu_type(fptr, &hdutype, &status) || hdutype != IMAGE_HDU)
            {
                pFrame->Alert(_("FITS file is not of an image: ") + fname);
                throw ERROR_INFO("Fits file is not an image");
            }

            // Get HDUs and size
            int naxis = 0;
            fits_get_img_dim(fptr, &naxis, &status);
            long fsize[3];
            fits_get_img_size(fptr, 2, fsize, &status);
            int nhdus = 0;
            fits_get_num_hdus(fptr, &nhdus, &status);
            if ((nhdus != 1) || (naxis != 2)) {
                pFrame->Alert(_("Unsupported type or read error loading FITS file ") + fname);
                throw ERROR_INFO("unsupported type");
            }
            if (Init((int) fsize[0], (int) fsize[1]))
            {
                pFrame->Alert(_("Memory allocation error loading FITS file ") + fname);
                throw ERROR_INFO("Memory Allocation failure");
            }
            long fpixel[3] = { 1, 1, 1 };
            if (fits_read_pix(fptr, TUSHORT, fpixel, (int)(fsize[0] * fsize[1]), NULL, ImageData, NULL, &status)) { // Read image
                pFrame->Alert(_("Error reading data from FITS file ") + fname);
                throw ERROR_INFO("Error reading");
            }

            char *key = const_cast<char *>("EXPOSURE");
            float exposure;
            status = 0;
            fits_read_key(fptr, TFLOAT, key, &exposure, NULL, &status);
            if (status == 0)
                ImgExpDur = (int) (exposure * 1000.0);

            key = const_cast<char *>("STACKCNT");
            int stackcnt;
            status = 0;
            fits_read_key(fptr, TINT, key, &stackcnt, NULL, &status);
            if (status == 0)
                ImgStackCnt = (int) stackcnt;

            PHD_fits_close_file(fptr);
        }
        else
        {
            pFrame->Alert(_("Error opening FITS file ") + fname);
            throw ERROR_INFO("error opening file");
        }
    }
    catch (wxString Msg)
    {
        POSSIBLY_UNUSED(Msg);
        bError = true;
    }

    return bError;
}
Пример #8
0
int main(int argc, char *argv []) {

	if(populate_env_variable(REF_ERROR_CODES_FILE, "L2_ERROR_CODES_FILE")) {

		printf("\nUnable to populate [REF_ERROR_CODES_FILE] variable with corresponding environment variable. Routine will proceed without error handling\n");

	}

	if (argc != 15) {

		if(populate_env_variable(SPF_BLURB_FILE, "L2_SPF_BLURB_FILE")) {

			RETURN_FLAG = 1;

		} else {

			print_file(SPF_BLURB_FILE);

		}

		write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -1, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

		return 1;

	} else {
		// ***********************************************************************
		// Redefine routine input parameters
		
		char *target_f				= strdup(argv[1]);	
		int bin_size_px				= strtol(argv[2], NULL, 0);
		double bg_percentile			= strtod(argv[3], NULL);
		double clip_sigma			= strtod(argv[4], NULL);
		int median_filter_width_px		= strtol(argv[5], NULL, 0);	
		double min_SNR				= strtod(argv[6], NULL);
		int min_spatial_width_px		= strtol(argv[7], NULL, 0);
                int finding_window_lo_px                = strtol(argv[8], NULL, 0);
                int finding_window_hi_px                = strtol(argv[9], NULL, 0);                
		int max_centering_num_px		= strtol(argv[10], NULL, 0);		
		int centroid_half_window_size_px	= strtol(argv[11], NULL, 0);
		int min_used_bins			= strtol(argv[12], NULL, 0);
		int window_x_lo				= strtol(argv[13], NULL, 0);
		int window_x_hi				= strtol(argv[14], NULL, 0);
		
		// ***********************************************************************
		// Open target file (ARG 1), get parameters and perform any data format 
		// checks

		fitsfile *target_f_ptr;

		int target_f_maxdim = 2, target_f_status = 0, target_f_bitpix, target_f_naxis;
		long target_f_naxes [2] = {1,1};

		if(!fits_open_file(&target_f_ptr, target_f, IMG_READ_ACCURACY, &target_f_status)) {

			if(!populate_img_parameters(target_f, target_f_ptr, target_f_maxdim, &target_f_bitpix, &target_f_naxis, target_f_naxes, &target_f_status, "TARGET FRAME")) {

				if (target_f_naxis != 2) {	// any data format checks here

					write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -2, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

					free(target_f);
					if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

					return 1;
	
				}

			} else { 

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -3, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, target_f_status); 

				free(target_f);
				if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

				return 1; 

			}

		} else { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -4, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error(stdout, target_f_status); 

			free(target_f);

			return 1; 

		}
		
		// ***********************************************************************
		// Set the range limits

		int cut_x [2] = {window_x_lo, window_x_hi};
		int cut_y [2] = {1, target_f_naxes[1]};

		// ***********************************************************************
		// Set parameters used when reading data from target file (ARG 1)

		long fpixel [2] = {cut_x[0], cut_y[0]};
		long nxelements = (cut_x[1] - cut_x[0]) + 1;
		long nyelements = (cut_y[1] - cut_y[0]) + 1;

		// ***********************************************************************
		// Create arrays to store pixel values from target fits file (ARG 1)

		double target_f_pixels [nxelements];
		
		// ***********************************************************************
		// Get target fits file (ARG 1) values and store in 2D array

		int ii;

		double target_frame_values [nyelements][nxelements];
		memset(target_frame_values, 0, sizeof(double)*nxelements*nyelements);
		for (fpixel[1] = cut_y[0]; fpixel[1] <= cut_y[1]; fpixel[1]++) {

			memset(target_f_pixels, 0, sizeof(double)*nxelements);

			if(!fits_read_pix(target_f_ptr, TDOUBLE, fpixel, nxelements, NULL, target_f_pixels, NULL, &target_f_status)) {

				for (ii=0; ii<nxelements; ii++) {

					target_frame_values[fpixel[1]-1][ii] = target_f_pixels[ii];

				}

			} else { 

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -5, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, target_f_status); 

				free(target_f);									
				if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

				return 1; 

			}

		}
		
		// FIND VALUES OF PEAK CENTROID ALONG DISPERSION AXIS
		// ***********************************************************************		
		// 1.	Bin array according to bin width given by [bin_size_px]
			
		int disp_nelements = nxelements, spat_nelements = nyelements;
		
		int disp_nelements_binned = (int)floor(disp_nelements/bin_size_px);			
		double this_frame_values_binned[spat_nelements][disp_nelements_binned];
		memset(this_frame_values_binned, 0, sizeof(double)*spat_nelements*disp_nelements_binned);
		
		double this_bin_value;
		int bin_number = 0;
		int jj;
		for (jj=0; jj<spat_nelements; jj++) {
			this_bin_value = 0;
			bin_number = 0;
			for (ii=0; ii<disp_nelements; ii++) {
				if (ii % bin_size_px == 0 && ii != 0) {
					this_frame_values_binned[jj][bin_number] = this_bin_value;
					bin_number++;
					this_bin_value = 0;
				}
				this_bin_value += target_frame_values[jj][ii];
			}
		}

		printf("\nFinding peaks");
		printf("\n-------------------------------------\n");	
		double peaks[disp_nelements_binned];
		int num_bins_used = 0;
		for (ii=0; ii<disp_nelements_binned; ii++) {

			// 1a.	Establish if any target flux is in this bin
			// 	First find the mean/sd of the [bg_percentile]th lowest valued pixels as an initial parameters for sigma clip			
			double this_spat_values[spat_nelements];
			double this_spat_values_sorted[spat_nelements];
			for (jj=0; jj<spat_nelements; jj++) {
				this_spat_values[jj] = this_frame_values_binned[jj][ii];
			}			
			memcpy(this_spat_values_sorted, this_spat_values, sizeof(double)*spat_nelements);	
			gsl_sort(this_spat_values_sorted, 1, spat_nelements);
			
			int bg_nelements = (int)floor(spat_nelements*bg_percentile);
			double bg_values [bg_nelements];
			int idx = 0;
			for (jj=0; jj<spat_nelements; jj++) {
				if (this_spat_values_sorted[jj] != 0) {			// avoid 0s set from median filter edges
					bg_values[idx] = this_spat_values_sorted[jj];
					idx++;
					if (idx == bg_nelements)
						break;
				}
			}

			if (idx != bg_nelements) {
				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -6, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

				free(target_f);
				if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

				return 1;
			}
			
			double start_mean = gsl_stats_mean(bg_values, 1, bg_nelements);
			double start_sd	  = gsl_stats_sd(bg_values, 1, bg_nelements);

			// 1b.	Iterative sigma clip around dataset with the initial guess
			int retain_indexes[spat_nelements];
			double final_mean, final_sd;
			int final_num_retained_indexes;
			
			printf("\nBin:\t\t\t\t%d", ii);	
			printf("\nStart mean:\t\t\t%f", start_mean);
			printf("\nStart SD:\t\t\t%f", start_sd);
			iterative_sigma_clip(this_spat_values, spat_nelements, clip_sigma, retain_indexes, start_mean, start_sd, &final_mean, &final_sd, &final_num_retained_indexes, FALSE);
			printf("\nFinal mean:\t\t\t%f", final_mean);
			printf("\nFinal SD:\t\t\t%f", final_sd);
			
			// 2.	Smooth array with median filter
			double this_spat_values_smoothed[spat_nelements];			
			memset(this_spat_values_smoothed, 0, sizeof(double)*spat_nelements);
			median_filter(this_spat_values, this_spat_values_smoothed, spat_nelements, median_filter_width_px);
			
			// 3.	Ascertain if this bin contains target flux
			int num_pixels_contain_target_flux = 0;
			for (jj=0; jj<spat_nelements-1; jj++) {
				if (this_spat_values_smoothed[jj] > final_mean + final_sd*min_SNR) {
					num_pixels_contain_target_flux++;
				}
			}
			printf("\nNum pixels (target):\t\t%d", num_pixels_contain_target_flux);
			
			printf("\nDoes bin contain target flux?\t");
			if (num_pixels_contain_target_flux >= min_spatial_width_px) {
				printf("Yes\n");
			} else {
				printf("No\n");
				peaks[ii] = -1;
				continue;
			}
			
			// 3.	Take derivatives
			double this_spat_values_der[spat_nelements-1];
			memset(this_spat_values_der, 0, sizeof(double)*spat_nelements-1);
			for (jj=1; jj<spat_nelements; jj++) {
				this_spat_values_der[jj-1] = this_frame_values_binned[jj][ii] - this_frame_values_binned[jj-1][ii];
			}
			
			// 4.	Smooth derivatives
			double this_spat_values_der_smoothed[spat_nelements-1];	
			memcpy(this_spat_values_der_smoothed, this_spat_values_der, sizeof(double)*spat_nelements-1);
			median_filter(this_spat_values_der, this_spat_values_der_smoothed, spat_nelements-1, median_filter_width_px);				
			
			// 5.	Pick most positive gradient from window, retaining proper index   
                        double this_spat_values_der_smoothed_windowed[spat_nelements-1]; 
                        memcpy(this_spat_values_der_smoothed_windowed, this_spat_values_der_smoothed, sizeof(double)*spat_nelements-1);
                        for (jj=0; jj<spat_nelements; jj++) {
                            if (jj >= finding_window_lo_px && jj <= finding_window_hi_px) {
                                this_spat_values_der_smoothed_windowed[jj] = this_spat_values_der_smoothed_windowed[jj];
                            } else {
                                this_spat_values_der_smoothed_windowed[jj] = -1;
                            }  
                        }
			size_t this_pk_idx = gsl_stats_max_index(this_spat_values_der_smoothed_windowed, 1, spat_nelements-1);
			printf("Start peak index:\t\t%d\n", this_pk_idx);	
			
			// 6.	Using this index, walk through centering window [max_centering_num_px] and find derivative turnover point
			printf("Found turnover:\t\t\t");			
			bool found_turnover = FALSE;
			for (jj=this_pk_idx; jj<this_pk_idx+max_centering_num_px; jj++) {
				if (this_spat_values_der_smoothed[jj] < 0.) {
					this_pk_idx = jj;
					found_turnover = TRUE;
					break;
				}
			}
			
			if (found_turnover) {
				printf("Yes\n");
				printf("End peak index:\t\t\t%d\n", this_pk_idx);	
			} else {
				printf("No\n");
				peaks[ii] = -1;
				continue;
			}

			// 7.	Get parabolic centroid using the full centroid window [centroid_half_window_size_px]
			double this_pk_window_idxs[1 + (2*centroid_half_window_size_px)];
			double this_pk_window_vals[1 + (2*centroid_half_window_size_px)];
			
			memset(this_pk_window_idxs, 0, sizeof(double)*(1 + (2*centroid_half_window_size_px)));
			memset(this_pk_window_vals, 0, sizeof(double)*(1 + (2*centroid_half_window_size_px)));
			idx = 0;
			for (jj=this_pk_idx-centroid_half_window_size_px; jj<=this_pk_idx+centroid_half_window_size_px; jj++) {
				this_pk_window_idxs[idx] = jj;
				this_pk_window_vals[idx] = this_frame_values_binned[jj][ii];
				idx++;
			}	
			
			int order = 2;
			double coeffs [order+1];  
			memset(coeffs, 0, sizeof(double)*order+1);
			double chi_squared;
			if (calc_least_sq_fit(2, 1 + (2*centroid_half_window_size_px), this_pk_window_idxs, this_pk_window_vals, coeffs, &chi_squared)) {

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -7, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

				free(target_f);
				if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

				return 1; 		

			}
			
			double fitted_peak_idx = -coeffs[1]/(2*coeffs[2]);
			printf("Fitted peak index:\t\t%f\n", fitted_peak_idx);

			// 8.	Ensure fitted peak location is within finding window
			printf("Is fitted peak within window?\t");
			if (fitted_peak_idx > finding_window_lo_px && fitted_peak_idx < finding_window_hi_px) {
				printf("Yes\n");
                                num_bins_used++;
			} else {
				printf("No\n");
				peaks[ii] = -1;
				continue;
			}

			peaks[ii] = fitted_peak_idx;	
			
			/*for (jj=0; jj<spat_nelements-1; jj++) {
				printf("%d\t%f\t%f\n", jj, this_spat_values_der_smoothed[jj], this_spat_values_der[jj]);
			}*/ // DEBUG	
			
		}	
		
		printf("\nNum bins used:\t%d\n", num_bins_used);		
		
		if (num_bins_used < min_used_bins) {
			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -8, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(target_f);
			if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

			return 1;
		}		
		
		// ***********************************************************************
		// Create [FRFIND_OUTPUTF_PEAKS_FILE] output file and print a few 
		// parameters

		FILE *outputfile;
		outputfile = fopen(SPFIND_OUTPUTF_PEAKS_FILE, FILE_WRITE_ACCESS);

		if (!outputfile) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -9, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(target_f);
			if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

			return 1;


		}

		char timestr [80];
		memset(timestr, '\0', sizeof(char)*80);

		find_time(timestr);

		fprintf(outputfile, "#### %s ####\n\n", SPFIND_OUTPUTF_PEAKS_FILE);
		fprintf(outputfile, "# Lists the coordinates of the peaks found using the spfind routine.\n\n");
		fprintf(outputfile, "# Run filename:\t%s\n", target_f);
		fprintf(outputfile, "# Run datetime:\t%s\n\n", timestr);
		
		for (ii=0; ii<disp_nelements_binned; ii++) {
			if (peaks[ii] == -1)
				continue;
			
			fprintf(outputfile, "%f\t%f\n", cut_x[0]+(ii*bin_size_px) + (double)bin_size_px/2., peaks[ii]);	
		}
		
		fprintf(outputfile, "%d", EOF);		
		
		// ***********************************************************************
		// Clean up heap memory

		free(target_f);

		// ***********************************************************************
		// Close [FRFIND_OUTPUTF_PEAKS_FILE] output file and target file (ARG 1)
		
		if (fclose(outputfile)) {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -10, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

			if(fits_close_file(target_f_ptr, &target_f_status)) fits_report_error (stdout, target_f_status); 

			return 1; 

		}

		if(fits_close_file(target_f_ptr, &target_f_status)) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", -11, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error (stdout, target_f_status); 

			return 1; 

	    	}		
		
		// ***********************************************************************
		// Write success to [ERROR_CODES_FILE]

		write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATFI", RETURN_FLAG, "Status flag for L2 spfind routine", ERROR_CODES_FILE_WRITE_ACCESS);

		return 0;

	}

}
Пример #9
0
struct mExamineReturn * mExamine(char *infile, int areaMode, int hdu, int plane3, int plane4, 
                                 double ra, double dec, double radius, int locinpix, int radinpix, int debug)
{
   int    i, j, offscl, nullcnt;
   int    status, clockwise, nfound;
   int    npix, nnull, first;
   int    ixpix, iypix;
   int    maxi, maxj;

   char  *header;
   char   tmpstr[32768];

   char   proj[32];
   int    csys;
   char   csys_str[64];

   char   ctype1[256];
   char   ctype2[256];

   double equinox;

   long   naxis;
   long   naxes[10];

   double naxis1;
   double naxis2;

   double crval1;
   double crval2;

   double crpix1;
   double crpix2;

   double cdelt1;
   double cdelt2;

   double crota2;

   double lon, lat;
   double lonc, latc;
   double rac, decc;
   double racp, deccp;
   double ra1, dec1, ra2, dec2, ra3, dec3, ra4, dec4;
   double xpix, ypix, rpix, rap;

   double x, y, z;
   double xp, yp, zp;

   double rot, beta, dtr;
   double r;

   double sumflux, sumflux2, sumn, mean, background, oldbackground, rms, dot;
   double sigmaref, sigmamax, sigmamin;
   double val, valx, valy, valra, valdec;
   double min, minx, miny, minra, mindec;
   double max, maxx, maxy, maxra, maxdec;
   double x0, y0, z0;

   double  fluxMin, fluxMax, fluxRef, sigma;

   struct WorldCoor *wcs;

   fitsfile *fptr;
   int       ibegin, iend, jbegin, jend;
   long      fpixel[4], nelements;

   double   *data = (double *)NULL;

   struct apPhoto *ap = (struct apPhoto *)NULL;

   int nflux, maxflux;


   struct mExamineReturn *returnStruct;

   returnStruct = (struct mExamineReturn *)malloc(sizeof(struct mExamineReturn));

   memset((void *)returnStruct, 0, sizeof(returnStruct));


   returnStruct->status = 1;

   strcpy(returnStruct->msg, "");


   nflux   = 0;
   maxflux = MAXFLUX;


   /************************************************/
   /* Make a NaN value to use setting blank pixels */
   /************************************************/

   union
   {
      double d;
     char   c[8];
   }
   value;

   double nan;

   for(i=0; i<8; ++i)
      value.c[i] = (char)255;

   nan = value.d;


   dtr = atan(1.)/45.;


   /* Process basic command-line arguments */

   if(debug)
   {
      printf("DEBUG> areaMode = %d \n", areaMode);
      printf("DEBUG> infile   = %s \n", infile);
      printf("DEBUG> ra       = %-g\n", ra);
      printf("DEBUG> dec      = %-g\n", dec);
      printf("DEBUG> radius   = %-g\n", radius);
      fflush(stdout);
   }

   rpix = 0.;

   if(areaMode == APPHOT)
      ap = (struct apPhoto *)malloc(maxflux * sizeof(struct apPhoto));


   /* Open the FITS file and initialize the WCS transform */

   status = 0;
   if(fits_open_file(&fptr, infile, READONLY, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot open FITS file %s", infile);
      return returnStruct;
   }

   if(hdu > 0)
   {
      status = 0;
      if(fits_movabs_hdu(fptr, hdu+1, NULL, &status))
      {
         if(ap) free(ap);
         sprintf(returnStruct->msg, "Can't find HDU %d", hdu);
         return returnStruct;
      }
   }

   status = 0;
   if(fits_get_image_wcs_keys(fptr, &header, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot find WCS keys in FITS file %s", infile);
      return returnStruct;
   }

   status = 0;
   if(fits_read_key_lng(fptr, "NAXIS", &naxis, (char *)NULL, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot find NAXIS keyword in FITS file %s", infile);
      return returnStruct;
   }

   status = 0;
   if(fits_read_keys_lng(fptr, "NAXIS", 1, naxis, naxes, &nfound, &status))
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "Cannot find NAXIS1,2 keywords in FITS file %s", infile);
      return returnStruct;
   }


   wcs = wcsinit(header);

   if(wcs == (struct WorldCoor *)NULL)
   {
      if(ap) free(ap);
      sprintf(returnStruct->msg, "WCS initialization failed.");
      return returnStruct;
   }



   /* A bunch of the parameters we want are in the WCS structure */

   clockwise = 0;

   strcpy(ctype1, wcs->ctype[0]);
   strcpy(ctype2, wcs->ctype[1]);

   naxis1 = wcs->nxpix;
   naxis2 = wcs->nypix;

   crval1 = wcs->xref;
   crval2 = wcs->yref;

   crpix1 = wcs->xrefpix;
   crpix2 = wcs->yrefpix;

   cdelt1 = wcs->xinc;
   cdelt2 = wcs->yinc;

   crota2 = wcs->rot;

   if((cdelt1 < 0 && cdelt2 < 0)
   || (cdelt1 > 0 && cdelt2 > 0)) clockwise = 1;

   strcpy(proj, "");

   if(strlen(ctype1) > 5)
   strcpy (proj, ctype1+5);  


   /* We get the Equinox from the WCS.  If not    */
   /* there we take the command-line value. We    */
   /* then infer Julian/Besselian as best we can. */

   equinox = wcs->equinox;

   csys = EQUJ;
   strcpy(csys_str, "EQUJ");

   if(strncmp(ctype1, "RA--", 4) == 0)
   {
      csys = EQUJ;

      strcpy(csys_str, "EQUJ");

      if(equinox < 1975.)
      {
         csys = EQUB;

         strcpy(csys_str, "EQUB");
      }
   }

   if(strncmp(ctype1, "LON-", 4) == 0)
   {
      csys = GAL;
      strcpy(csys_str, "GAL");
   }

   if(strncmp(ctype1, "GLON", 4) == 0)
   {
      csys = GAL;
      strcpy(csys_str, "GAL");
   }

   if(strncmp(ctype1, "ELON", 4) == 0)
   {
      csys = ECLJ;

      strcpy(csys_str, "ECLJ");

      if(equinox < 1975.)
      {
         csys = ECLB;

         strcpy(csys_str, "ECLB");
      }
   }

   if(debug)
   {
      printf("DEBUG> proj      = [%s]\n", proj);
      printf("DEBUG> csys      = %d\n",   csys);
      printf("DEBUG> clockwise = %d\n",   clockwise);
      printf("DEBUG> ctype1    = [%s]\n", ctype1);
      printf("DEBUG> ctype2    = [%s]\n", ctype2);
      printf("DEBUG> equinox   = %-g\n",  equinox);

      printf("\n");
      fflush(stdout);
   }


   /* To get corners and rotation in EQUJ we need the     */
   /* locations of the center pixel and the one above it. */

   pix2wcs(wcs, wcs->nxpix/2.+0.5, wcs->nypix/2.+0.5, &lonc, &latc);
   convertCoordinates (csys, equinox, lonc, latc, 
                       EQUJ, 2000., &rac, &decc, 0.);

   pix2wcs(wcs, wcs->nxpix/2.+0.5, wcs->nypix/2.+1.5, &lonc, &latc);
   convertCoordinates (csys, equinox, lonc, latc, 
                       EQUJ, 2000., &racp, &deccp, 0.);


   /* Use spherical trig to get the Equatorial rotation angle */

   x = cos(decc*dtr) * cos(rac*dtr);
   y = cos(decc*dtr) * sin(rac*dtr);
   z = sin(decc*dtr);

   xp = cos(deccp*dtr) * cos(racp*dtr);
   yp = cos(deccp*dtr) * sin(racp*dtr);
   zp = sin(deccp*dtr);

   beta = acos(x*xp + y*yp + z*zp) / dtr;

   rot = asin(cos(deccp*dtr) * sin((rac-racp)*dtr)/sin(beta*dtr)) / dtr;


   /* And for the four corners we want them uniformly clockwise */

   if(!clockwise)
   {
      pix2wcs(wcs, -0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra1, &dec1, 0.);


      pix2wcs(wcs, wcs->nxpix+0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra2, &dec2, 0.);


      pix2wcs(wcs, wcs->nxpix+0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra3, &dec3, 0.);


      pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra4, &dec4, 0.);
   }
   else
   {
      pix2wcs(wcs, -0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra2, &dec2, 0.);


      pix2wcs(wcs, wcs->nxpix+0.5, -0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra1, &dec1, 0.);


      pix2wcs(wcs, wcs->nxpix+0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra4, &dec4, 0.);


      pix2wcs(wcs, -0.5, wcs->nypix+0.5, &lon, &lat);
      convertCoordinates (csys, equinox, lon, lat, 
                          EQUJ, 2000., &ra3, &dec3, 0.);
   }


   // Treat the default region (ALL) as a circle 
   // containing the whole image

   if(areaMode == ALL)
   {
      locinpix = 1;
      radinpix = 1;

      ra  = wcs->nxpix / 2.;
      dec = wcs->nypix / 2.;

      radius = sqrt(wcs->nxpix*wcs->nxpix + wcs->nypix*wcs->nypix)/2.;
   }


   /* Get region statistics */

   ixpix = 1;
   iypix = 1;

   if(radinpix) 
   {
      rpix   = radius;
      radius = rpix * fabs(cdelt2);
   }
   else
      rpix = radius / fabs(cdelt2);

   if(locinpix)
   {
      xpix = ra;
      ypix = dec;

      pix2wcs(wcs, xpix, ypix, &lon, &lat);

      if(wcs->offscl)
      {
         if(ap) free(ap);
         sprintf(returnStruct->msg, "Location off the image.");
         return returnStruct;
      }

      convertCoordinates (csys, equinox, lon, lat,
            EQUJ, 2000., &ra, &dec, 0);
   }
   else
   {
      convertCoordinates (EQUJ, 2000., ra, dec,  
            csys, equinox, &lon, &lat, 0.);

      wcs2pix(wcs, lon, lat, &xpix, &ypix, &offscl);

      if(offscl)
      {
         if(ap) free(ap);
         sprintf(returnStruct->msg, "Location off the image.");
         return returnStruct;
      }
   }



   x0 = cos(ra*dtr) * cos(dec*dtr);
   y0 = sin(ra*dtr) * cos(dec*dtr);
   z0 = sin(dec*dtr);

   ixpix = (int)(xpix+0.5);
   iypix = (int)(ypix+0.5);

   if(debug)
   {
      printf("DEBUG> Region statististics for %-g pixels around (%-g,%-g) [%d,%d] [Equatorial (%-g, %-g)\n",
            rpix, xpix, ypix, ixpix, iypix, ra, dec);
      fflush(stdout);
   }


   // Then read the data

   jbegin = iypix - rpix - 1;
   jend   = iypix + rpix + 1;

   ibegin = ixpix - rpix - 1;
   iend   = ixpix + rpix + 1;

   if(ibegin < 1         ) ibegin = 1;
   if(iend   > wcs->nxpix) iend   = wcs->nxpix;

   nelements = iend - ibegin + 1;

   if(jbegin < 1         ) jbegin = 1;
   if(jend   > wcs->nypix) jend   = wcs->nxpix;

   fpixel[0] = ibegin;
   fpixel[1] = jbegin;
   fpixel[2] = 1;
   fpixel[3] = 1;
   fpixel[2] = plane3;
   fpixel[3] = plane4;


   data = (double *)malloc(nelements * sizeof(double));

   status = 0;

   sumflux  = 0.;
   sumflux2 = 0.;
   npix     = 0;
   nnull    = 0;

   val      = 0.;
   valx     = 0.;
   valy     = 0.;
   valra    = 0.;
   valdec   = 0.;

   max      = 0.;
   maxx     = 0.;
   maxy     = 0.;
   maxra    = 0.;
   maxdec   = 0.;

   min      = 0.;
   minx     = 0.;
   miny     = 0.;
   minra    = 0.;
   mindec   = 0.;

   first = 1;

   if(radius > 0.)
   {
      if(debug)
      {
         printf("\nDEBUG> Location: (%.6f %.6f) -> (%d,%d)\n\n", xpix, ypix, ixpix, iypix);
         printf("DEBUG> Radius: %.6f\n\n", rpix);

         printf("DEBUG> i: %d to %d\n", ibegin, iend);
         printf("DEBUG> j: %d to %d\n", jbegin, jend);
      }

      for (j=jbegin; j<=jend; ++j)
      {
         status = 0;
         if(fits_read_pix(fptr, TDOUBLE, fpixel, nelements, &nan,
                  (void *)data, &nullcnt, &status))
         {
            ++fpixel[1];

            continue;
         }

         for(i=0; i<nelements; ++i)
         {
            if(mNaN(data[i]))
            {
               if(debug)
                  printf("%10s ", "NULL");

               ++nnull;
               continue;
            }

            sumflux  += data[i];
            sumflux2 += data[i]*data[i];
            ++npix;

            x  = ibegin + i;
            y  = j;

            pix2wcs(wcs, x, y, &lon, &lat);

            convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &ra, &dec, 0.);

            xp = cos(ra*dtr) * cos(dec*dtr);
            yp = sin(ra*dtr) * cos(dec*dtr);
            zp = sin(dec*dtr);

            dot = xp*x0 + yp*y0 + zp*z0;

            if(dot > 1.)
               dot = 1.;

            r = acos(dot)/dtr / fabs(cdelt2);

            if(debug)
            {
               if(r <= rpix)
                  printf("%10.3f ", data[i]);
               else
                  printf("%10s ", ".");
            }

            if(r > rpix)
               continue;


            if(x == ixpix && y == iypix)
            {
               val = data[i];

               valx = x;
               valy = y;
            }

            if(first)
            {
               first = 0;

               min = data[i];

               minx = x;
               miny = y;

               max = data[i];

               maxx = x;
               maxy = y;

               maxi = i+ibegin;
               maxj = j;
            }

            if(data[i] > max)
            {
               max = data[i];

               maxx = x;
               maxy = y;

               maxi = i+ibegin;
               maxj = j;
            }

            if(data[i] < min)
            {
               min = data[i];

               minx = x;
               miny = y;
            }
         }

         pix2wcs(wcs, valx, valy, &lon, &lat);
         convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &valra, &valdec, 0.);

         pix2wcs(wcs, minx, miny, &lon, &lat);
         convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &minra, &mindec, 0.);

         pix2wcs(wcs, maxx, maxy, &lon, &lat);
         convertCoordinates(csys, equinox, lon, lat, EQUJ, 2000., &maxra, &maxdec, 0.);

         if(debug)
            printf("\n");

         ++fpixel[1];
      }

      mean     = 0.;
      rms      = 0.;
      sigmaref = 0.;
      sigmamin = 0.;
      sigmamax = 0.;

      if(npix > 0)
      {
         mean = sumflux / npix;
         rms  = sqrt(sumflux2/npix - mean*mean);

         sigmaref = (val - mean) / rms; 
         sigmamin = (min - mean) / rms; 
         sigmamax = (max - mean) / rms; 
      }
   }
   

   /* Finally, print out parameters */

   strcpy(montage_json,  "{");
   strcpy(montage_msgstr,  "");


   if(areaMode == ALL || areaMode == REGION)
   {
      sprintf(tmpstr, "\"proj\":\"%s\",",   proj);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"csys\":\"%s\",",   csys_str);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"equinox\":%.1f,",  equinox);               strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis\":%ld,",     naxis);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis1\":%d,",     (int)naxis1);           strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis2\":%d,",     (int)naxis2);           strcat(montage_json, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " \"naxis3\":%ld,", naxes[2]);              strcat(montage_json, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " \"naxis4\":%ld,", naxes[3]);              strcat(montage_json, tmpstr);
      }

      sprintf(tmpstr, " \"crval1\":%.7f,",   crval1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crval2\":%.7f,",   crval2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix1\":%-g,",    crpix1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix2\":%-g,",    crpix2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt1\":%.7f,",   cdelt1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt2\":%.7f,",   cdelt2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crota2\":%.4f,",   crota2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"lonc\":%.7f,",     lonc);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"latc\":%.7f,",     latc);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ximgsize\":%.6f,", fabs(naxis1*cdelt1));   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"yimgsize\":%.6f,", fabs(naxis1*cdelt2));   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rotequ\":%.4f,",   rot);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rac\":%.7f,",      rac);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decc\":%.7f,",     decc);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra1\":%.7f,",      ra1);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec1\":%.7f,",     dec1);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra2\":%.7f,",      ra2);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec2\":%.7f,",     dec2);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra3\":%.7f,",      ra3);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec3\":%.7f,",     dec3);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra4\":%.7f,",      ra4);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec4\":%.7f,",     dec4);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"radius\":%.7f,",   radius);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"radpix\":%.2f,",   rpix);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"npixel\":%d,",     npix);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"nnull\":%d,",      nnull);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"aveflux\":%-g,",   mean);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rmsflux\":%-g,",   rms);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"fluxref\":%-g,",   val);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"sigmaref\":%-g,",  sigmaref);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"xref\":%.0f,",     valx);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"yref\":%.0f,",     valy);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"raref\":%.7f,",    valra);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decref\":%.7f,",   valdec);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"fluxmin\":%-g,",   min);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"sigmamin\":%-g,",  sigmamin);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"xmin\":%.0f,",     minx);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ymin\":%.0f,",     miny);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ramin\":%.7f,",    minra);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decmin\":%.7f,",   mindec);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"fluxmax\":%-g,",   max);                   strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"sigmamax\":%-g,",  sigmamax);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"xmax\":%.0f,",     maxx);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ymax\":%.0f,",     maxy);                  strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ramax\":%.7f,",    maxra);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decmax\":%.7f",    maxdec);                strcat(montage_json, tmpstr);
   

      sprintf(tmpstr, "proj=\"%s\",",   proj);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " csys=\"%s\",",   csys_str);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " equinox=%.1f,",  equinox);               strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis=%ld,",     naxis);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis1=%d,",     (int)naxis1);           strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis2=%d,",     (int)naxis2);           strcat(montage_msgstr, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " naxis3=%ld,", naxes[2]);              strcat(montage_msgstr, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " naxis4=%ld,", naxes[3]);              strcat(montage_msgstr, tmpstr);
      }

      sprintf(tmpstr, " crval1=%.7f,",   crval1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crval2=%.7f,",   crval2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix1=%-g,",    crpix1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix2=%-g,",    crpix2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt1=%.7f,",   cdelt1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt2=%.7f,",   cdelt2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crota2=%.4f,",   crota2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " lonc=%.7f,",     lonc);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " latc=%.7f,",     latc);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ximgsize=%.6f,", fabs(naxis1*cdelt1));   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " yimgsize=%.6f,", fabs(naxis1*cdelt2));   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rotequ=%.4f,",   rot);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rac=%.7f,",      rac);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decc=%.7f,",     decc);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra1=%.7f,",      ra1);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec1=%.7f,",     dec1);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra2=%.7f,",      ra2);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec2=%.7f,",     dec2);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra3=%.7f,",      ra3);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec3=%.7f,",     dec3);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra4=%.7f,",      ra4);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec4=%.7f,",     dec4);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " radius=%.7f,",   radius);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " radpix=%.2f,",   rpix);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " npixel=%d,",     npix);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " nnull=%d,",      nnull);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " aveflux=%-g,",   mean);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rmsflux=%-g,",   rms);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " fluxref=%-g,",   val);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " sigmaref=%-g,",  sigmaref);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " xref=%.0f,",     valx);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " yref=%.0f,",     valy);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " raref=%.7f,",    valra);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decref=%.7f,",   valdec);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " fluxmin=%-g,",   min);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " sigmamin=%-g,",  sigmamin);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " xmin=%.0f,",     minx);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ymin=%.0f,",     miny);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ramin=%.7f,",    minra);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decmin=%.7f,",   mindec);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " fluxmax=%-g,",   max);                   strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " sigmamax=%-g,",  sigmamax);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " xmax=%.0f,",     maxx);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ymax=%.0f,",     maxy);                  strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ramax=%.7f,",    maxra);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decmax=%.7f",    maxdec);                strcat(montage_msgstr, tmpstr);
   }
   
   else if(areaMode == APPHOT)
   {
      // For aperture photometry mode we process the flux vs. radius data
      // to get the integrated source flux. 

      rap = radius;

      jbegin = maxj - rap - 1;
      jend   = maxj + rap + 1;

      ibegin = maxi - rap - 1;
      iend   = maxi + rap + 1;

      nelements = iend - ibegin + 1;

      fpixel[0] = ibegin;
      fpixel[1] = jbegin;
      fpixel[2] = 1;
      fpixel[3] = 1;

      for (j=jbegin; j<=jend; ++j)
      {
         status = 0;
         if(fits_read_pix(fptr, TDOUBLE, fpixel, nelements, &nan,
                          (void *)data, &nullcnt, &status))
         {
            if(ap) free(ap);
            free(data);
            sprintf(returnStruct->msg, "Error reading FITS data.");
            return returnStruct;
         }

         for(i=0; i<nelements; ++i)
         {
            if(mNaN(data[i]))
               continue;

            r = sqrt(((double)i+ibegin-maxi)*((double)i+ibegin-maxi) + ((double)j-maxj)*((double)j-maxj));

            if(r > rap)
               continue;

            ap[nflux].rad  = r;
            ap[nflux].flux = data[i];
            ap[nflux].fit  = 0.;

            ++nflux;
            if(nflux >= maxflux)
            {
               maxflux += MAXFLUX;

               ap = (struct apPhoto *)realloc(ap, maxflux * sizeof(struct apPhoto));
            }
         }

         ++fpixel[1];
      }


      // Sort the data by radius

      qsort(ap, (size_t)nflux, sizeof(struct apPhoto), mExamine_radCompare);


      // Find the peak flux and the minimum flux.

      // The max is constrained to be in the first quarter of the
      // data, just to be careful.

      fluxMax = -1.e99;
      fluxMin =  1.e99;

      for(i=0; i<nflux; ++i)
      {
         if(i < nflux/4 && ap[i].flux > fluxMax)
            fluxMax = ap[i].flux;

         if(ap[i].flux < fluxMin)
            fluxMin = ap[i].flux;
      }


      // Fit the minimum a little more carefully, iterating
      // and excluding points more than 3 sigma above the 
      // minimum.

      background = fluxMin;
      sigma      = fluxMax - fluxMin;

      for(j=0; j<1000; ++j)
      {
         oldbackground = background;

         sumn     = 0.;
         sumflux  = 0.;
         sumflux2 = 0.;

         for(i=0; i<nflux; ++i)
         {
            if(fabs(ap[i].flux - background) > 3.*sigma)
               continue;

            sumn     += 1.;
            sumflux  += ap[i].flux;
            sumflux2 += ap[i].flux * ap[i].flux;
         }

         background = sumflux / sumn;
         sigma      = sqrt(sumflux2/sumn - background*background);

         if(fabs((background - oldbackground) / oldbackground) < 1.e-3)
            break;
      }


      fluxRef = (fluxMax-fluxMin) / exp(1.);

      for(i=0; i<nflux; ++i)
      {
         if(ap[i].flux < fluxRef)
         {
            sigma = ap[i].rad;
            break;
         }
      }

      for(i=0; i<nflux; ++i)
      {
         ap[i].fit = (fluxMax-background) * exp(-(ap[i].rad * ap[i].rad) / (sigma * sigma)) + background;

         if(i == 0)
            ap[i].sum = ap[i].flux - background;
         else
            ap[i].sum = ap[i-1].sum + (ap[i].flux - background);
      }


      if(debug)
      {
         printf("|    rad    |    flux    |     fit     |     sum     |\n");
         fflush(stdout);

         for(i=0; i<nflux; ++i)
         {
            printf("%12.6f %12.6f %12.6f %12.6f  \n", ap[i].rad, ap[i].flux, ap[i].fit, ap[i].sum);
            fflush(stdout);
         }
      }

      sprintf(tmpstr, "\"proj\":\"%s\",",    proj);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"csys\":\"%s\",",    csys_str);            strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"equinox\":%.1f,",   equinox);             strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis\":%ld,",      naxis);               strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis1\":%d,",      (int)naxis1);         strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"naxis2\":%d,",      (int)naxis2);         strcat(montage_json, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " \"naxis3\":%ld,",   naxes[2]);           strcat(montage_json, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " \"naxis4\":%ld,",   naxes[3]);           strcat(montage_json, tmpstr);
      }

      sprintf(tmpstr, " \"crval1\":%.7f,",    crval1);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crval2\":%.7f,",    crval2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix1\":%-g,",     crpix1);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crpix2\":%-g,",     crpix2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt1\":%.7f,",    cdelt1);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"cdelt2\":%.7f,",    cdelt2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"crota2\":%.4f,",    crota2);              strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"lonc\":%.7f,",      lonc);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"latc\":%.7f,",      latc);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ximgsize\":%.6f,",  fabs(naxis1*cdelt1)); strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"yimgsize\":%.6f,",  fabs(naxis1*cdelt2)); strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rotequ\":%.4f,",    rot);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"rac\":%.7f,",       rac);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"decc\":%.7f,",      decc);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra1\":%.7f,",       ra1);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec1\":%.7f,",      dec1);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra2\":%.7f,",       ra2);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec2\":%.7f,",      dec2);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra3\":%.7f,",       ra3);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec3\":%.7f,",      dec3);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"ra4\":%.7f,",       ra4);                 strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"dec4\":%.7f,",      dec4);                strcat(montage_json, tmpstr);
      sprintf(tmpstr, " \"totalflux\":%.7e",  ap[nflux/2].sum);     strcat(montage_json, tmpstr);

      sprintf(tmpstr, "proj=\"%s\",",    proj);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " csys=\"%s\",",    csys_str);            strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " equinox=%.1f,",   equinox);             strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis=%ld,",      naxis);               strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis1=%d,",      (int)naxis1);         strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " naxis2=%d,",      (int)naxis2);         strcat(montage_msgstr, tmpstr);

      if(naxis > 2)
      {
         sprintf(tmpstr, " naxis3=%ld,",   naxes[2]);           strcat(montage_msgstr, tmpstr);
      }

      if(naxis > 3)
      {
         sprintf(tmpstr, " naxis4=%ld,",   naxes[3]);           strcat(montage_msgstr, tmpstr);
      }

      sprintf(tmpstr, " crval1=%.7f,",    crval1);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crval2=%.7f,",    crval2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix1=%-g,",     crpix1);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crpix2=%-g,",     crpix2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt1=%.7f,",    cdelt1);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " cdelt2=%.7f,",    cdelt2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " crota2=%.4f,",    crota2);              strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " lonc=%.7f,",      lonc);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " latc=%.7f,",      latc);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ximgsize=%.6f,",  fabs(naxis1*cdelt1)); strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " yimgsize=%.6f,",  fabs(naxis1*cdelt2)); strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rotequ=%.4f,",    rot);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " rac=%.7f,",       rac);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " decc=%.7f,",      decc);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra1=%.7f,",       ra1);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec1=%.7f,",      dec1);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra2=%.7f,",       ra2);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec2=%.7f,",      dec2);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra3=%.7f,",       ra3);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec3=%.7f,",      dec3);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " ra4=%.7f,",       ra4);                 strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " dec4=%.7f,",      dec4);                strcat(montage_msgstr, tmpstr);
      sprintf(tmpstr, " totalflux=%.7e",  ap[nflux/2].sum);     strcat(montage_msgstr, tmpstr);
   }

   strcat(montage_json, "}");

   if(ap) free(ap);
   free(data);

   returnStruct->status = 0;

   strcpy(returnStruct->msg,  montage_msgstr);
   strcpy(returnStruct->json, montage_json);
   strcpy(returnStruct->proj, proj);
   strcpy(returnStruct->csys, csys_str);

   returnStruct->equinox   = equinox;
   returnStruct->naxis     = naxis;
   returnStruct->naxis1    = naxis1;
   returnStruct->naxis2    = naxis2;
   returnStruct->naxis3    = naxes[2];
   returnStruct->naxis4    = naxes[3];
   returnStruct->crval1    = crval1;
   returnStruct->crval2    = crval2;
   returnStruct->crpix1    = crpix1;
   returnStruct->crpix2    = crpix2;
   returnStruct->cdelt1    = cdelt1;
   returnStruct->cdelt2    = cdelt2;
   returnStruct->crota2    = crota2;
   returnStruct->lonc      = lonc;
   returnStruct->latc      = latc;
   returnStruct->ximgsize  = fabs(naxis1*cdelt1);
   returnStruct->yimgsize  = fabs(naxis2*cdelt2);
   returnStruct->rotequ    = rot;
   returnStruct->rac       = rac;
   returnStruct->decc      = decc;
   returnStruct->ra1       = ra1;
   returnStruct->dec1      = dec1;
   returnStruct->ra2       = ra2;
   returnStruct->dec2      = dec2;
   returnStruct->ra3       = ra3;
   returnStruct->dec3      = dec3;
   returnStruct->ra4       = ra4;
   returnStruct->dec4      = dec4;
   returnStruct->radius    = radius;
   returnStruct->radpix    = rpix;
   returnStruct->npixel    = npix;
   returnStruct->nnull     = nnull;
   returnStruct->aveflux   = mean;
   returnStruct->rmsflux   = rms;
   returnStruct->fluxref   = val;
   returnStruct->sigmaref  = sigmaref;
   returnStruct->xref      = valx;
   returnStruct->yref      = valy;
   returnStruct->raref     = valra;
   returnStruct->decref    = valdec;
   returnStruct->fluxmin   = min;
   returnStruct->sigmamin  = sigmamin;
   returnStruct->xmin      = minx;
   returnStruct->ymin      = miny;
   returnStruct->ramin     = minra;
   returnStruct->decmin    = mindec;
   returnStruct->fluxmax   = max;
   returnStruct->sigmamax  = sigmamax;
   returnStruct->xmax      = maxx;
   returnStruct->ymax      = maxy;
   returnStruct->ramax     = maxra;
   returnStruct->decmax    = maxdec;

   if(areaMode == APPHOT)
      returnStruct->totalflux = ap[nflux/2].sum;
   else
      returnStruct->totalflux = 0.;

   return returnStruct;
}
Пример #10
0
int main(int argc, char *argv[])
{
  fitsfile *fptr = 0;   /* FITS file pointer, defined in fitsio.h */
  int status = 0;   /* CFITSIO status value MUST be initialized to zero! */
  int bitpix = 0, naxis = 0, ii = 0, d = 0;
  long naxes[9] = {1,1,1,1,1,1,1,1,1}, fpixel[9] = {1,1,1,1,1,1,1,1,1};
  double *pixels = 0;
  char format[20], hdformat[20];

  int printhelp = (argc == 2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0));

  if (printhelp || argc != 2) {
    fprintf(stderr, "Usage:  %s filename[ext][section filter] \n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "List the the pixel values in a FITS array \n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Example: \n");
    fprintf(stderr, "  %s array.fits                    - list the whole array\n", argv[0]);
    fprintf(stderr, "  %s array.fits[100:110,400:410]   - list a section\n", argv[0]);
    fprintf(stderr, "  %s table.fits[2][bin (x,y) = 32] - list the pixels in\n", argv[0]);
    fprintf(stderr, "         an array constructed from a 2D histogram of X and Y\n");
    fprintf(stderr, "         columns in a table with a binning factor = 32\n");
    return (0);
  }

  FILE *fout = popen(PAGER, "w");
  if (fout == NULL) {
    fprintf(stderr, "Could not execute '%s'\n", PAGER);
    return (1);
  }

  if (!fits_open_file(&fptr, argv[1], READONLY, &status)) {
    if (!fits_get_img_param(fptr, 9, &bitpix, &naxis, naxes, &status)) {
      if (naxis > 9 || naxis == 0) {
        fprintf(stderr, "Error: only 1- to 9-dimensional arrays are supported\n");
      } else {
        /* get memory for 1 row */
        pixels = (double *) malloc(naxes[0] * sizeof(double));

        if (pixels == NULL) {
          fprintf(stderr, "Memory allocation error\n");
          return (1);
        }

        if (bitpix > 0) {  /* set the default output format string */
          strcpy(hdformat, "   %7d");
          strcpy(format,   "   %7.0g");
        } else {
          strcpy(hdformat, "   %15d");
          strcpy(format,   "   %15.5g");
        }

        if (naxis > 2) {  /* label higher dimensions */
          fprintf(fout, "#");
          for (d = naxis - 1; d > 0; d--) {
            fprintf(fout, "%1iD ", d+1);
          }
          fprintf(fout, "\n");
        }

        /* loop over all the rows in the array */
        for (fpixel[8] = 1; fpixel[8] <= naxes[8]; fpixel[8]++) {
          for (fpixel[7] = 1; fpixel[7] <= naxes[7]; fpixel[7]++) {
            for (fpixel[6] = 1; fpixel[6] <= naxes[6]; fpixel[6]++) {
              for (fpixel[5] = 1; fpixel[5] <= naxes[5]; fpixel[5]++) {
                for (fpixel[4] = 1; fpixel[4] <= naxes[4]; fpixel[4]++) {
                  for (fpixel[3] = 1; fpixel[3] <= naxes[3]; fpixel[3]++) {
                    for (fpixel[2] = 1; fpixel[2] <= naxes[2]; fpixel[2]++) {
                      for (fpixel[1] = 1; fpixel[1] <= naxes[1]; fpixel[1]++) {
                        if (fits_read_pix(fptr, TDOUBLE, fpixel, naxes[0], NULL,
                                          pixels, NULL, &status)) { /* read row of pixels */
                          break;  /* jump out of loop on error */
                        }

                        if (naxis > 2) {  /* print higher dimensions */
                          fprintf(fout, " ");
                          for (d = naxis - 1; d > 0; d--) {
                            fprintf(fout, "% 2li ", fpixel[d]);
                          }
                        }
                        for (ii = 0; ii < naxes[0]; ii++) {
                          fprintf(fout, format, pixels[ii]);  /* print each value  */
                        }
                        fprintf(fout, "\n");                    /* terminate line */
                      }
                    }
                  }
                }
              }
            }
          }
        }
        free(pixels);
      }
    }
    fits_close_file(fptr, &status);
  }

  pclose(fout);

  if (status) {
    fits_report_error(stderr, status);  /* print any error message */
  }
  return (status);
}
Пример #11
0
int main(int argc, char *argv[])
{
  fitsfile *fptr = 0;  /* FITS file pointer */
  int status = 0;  /* CFITSIO status value MUST be initialized to zero! */
  int hdutype = 0, naxis = 0, ii = 0;
  long naxes[2], totpix = 0, fpixel[2];
  double *pix, sum = 0., meanval = 0., minval = 1.E33, maxval = -1.E33;

  if (argc != 2) {
    fprintf(stderr, "Usage: %s array \n", argv[0]);
    fprintf(stderr, "\n");
    fprintf(stderr, "Compute statistics of pixels in the input array\n");
    fprintf(stderr, "\n");
    fprintf(stderr, "Examples: \n");
    fprintf(stderr, "  imarith array.fits                    - the whole array\n");
    fprintf(stderr, "  imarith 'array.fits[200:210,300:310]' - array section\n");
    fprintf(stderr, "  imarith 'table.fits+1[bin (X,Y) = 4]' - array constructed\n");
    fprintf(stderr, "     from X and Y columns of a table, with 4-pixel bin size\n");
    return (0);
  }

  if (!fits_open_image(&fptr, argv[1], READONLY, &status)) {
    if (fits_get_hdu_type(fptr, &hdutype, &status) || hdutype != IMAGE_HDU) {
      fprintf(stderr, "Error: this program only works on arrays, not tables\n");
      return (1);
    }

    fits_get_img_dim(fptr, &naxis, &status);
    fits_get_img_size(fptr, 2, naxes, &status);

    if (status || naxis != 2) {
      fprintf(stderr, "Error: NAXIS = %d.  Only 2-D arrays are supported.\n", naxis);
      return (1);
    }

    pix = (double *) malloc(naxes[0] * sizeof(double)); /* memory for 1 row */

    if (pix == NULL) {
      fprintf(stderr, "Memory allocation error\n");
      return (1);
    }

    totpix = naxes[0] * naxes[1];
    fpixel[0] = 1;  /* read starting with first pixel in each row */

    /* process array one row at a time; increment row # in each loop */
    for (fpixel[1] = 1; fpixel[1] <= naxes[1]; fpixel[1]++) {
      /* give starting pixel coordinate and number of pixels to read */
      if (fits_read_pix(fptr, TDOUBLE, fpixel, naxes[0],0, pix,0, &status)) {
        break;  /* jump out of loop on error */
      }

      for (ii = 0; ii < naxes[0]; ii++) {
        sum += pix[ii];                      /* accumlate sum */
        if (pix[ii] < minval) {
          minval = pix[ii];  /* find min and  */
        }
        if (pix[ii] > maxval) {
          maxval = pix[ii];  /* max values    */
        }
      }
    }

    free(pix);
    fits_close_file(fptr, &status);
  }

  if (status)  {
    fits_report_error(stderr, status); /* print any error message */
  } else {
    if (totpix > 0) {
      meanval = sum / totpix;
    }

    printf("Statistics of %ld x %ld  array\n",
           naxes[0], naxes[1]);
    printf("  sum of pixels = %g\n", sum);
    printf("  mean value    = %g\n", meanval);
    printf("  minimum value = %g\n", minval);
    printf("  maximum value = %g\n", maxval);
  }

  return (status);
}
Пример #12
0
void montage_copyData(fitsfile *infptr, fitsfile *outfptr, struct imageParams *params)
{
   long    fpixel[4], fpixelo[4];
   int     i, j, nullcnt;
   int     status = 0;
   double *buffer, refval;


   /*************************************************/
   /* Make a NaN value to use checking blank pixels */
   /*************************************************/

   union
   {
      double d;
      char   c[8];
   }
   value;

   double nan;

   for(i=0; i<8; ++i)
      value.c[i] = 255;

   nan = value.d;


   fpixel[0] = params->ibegin;
   fpixel[1] = params->jbegin;
   fpixel[2] = 1;
   fpixel[3] = 1;

   if(params->plane)
      fpixel[2] = params->plane;

   buffer  = (double *)malloc(params->nelements * sizeof(double));

   fpixelo[0] = 1;
   fpixelo[1] = 1;
   fpixelo[2] = 1;
   fpixelo[3] = 1;

   isflat = 1;

   refval = nan;

   for (j=params->jbegin; j<=params->jend; ++j)
   {
      if(debug >= 2)
      {
         printf("Processing input image row %5d\n", j);
         fflush(stdout);
      }

      if(fits_read_pix(infptr, TDOUBLE, fpixel, params->nelements, &nan,
                       buffer, &nullcnt, &status))
         montage_printFitsError(status);

      for(i=0; i<params->nelements; ++i)
      {
         if(!mNaN(buffer[i]))
         {
            if(mNaN(refval))
               refval = buffer[i];

            if(buffer[i] != refval)
               isflat = 0;
         }
      }

      if (fits_write_pix(outfptr, TDOUBLE, fpixelo, params->nelements,
                         (void *)buffer, &status))
         montage_printFitsError(status);

      ++fpixelo[1];
      ++fpixel [1];
   }


   free(buffer);

   if(isflat)
   {
      if(mNaN(refval))
         strcpy(content, "blank");
      else
         strcpy(content, "flat");
   }
   else
      strcpy(content, "normal");
}
int main(int argc, char *argv []) {

	if(populate_env_variable(REF_ERROR_CODES_FILE, "L2_ERROR_CODES_FILE")) {

		printf("\nUnable to populate [REF_ERROR_CODES_FILE] variable with corresponding environment variable. Routine will proceed without error handling\n");

	}

	if (argc != 5) {

		if(populate_env_variable(SPCS_BLURB_FILE, "L2_SPCS_BLURB_FILE")) {

			RETURN_FLAG = 1;

		} else {

			print_file(SPCS_BLURB_FILE);

		}

		write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -1, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);

		return 1;

	} else {
		// ***********************************************************************
		// Redefine routine input parameters
		
		char *input_f			= strdup(argv[1]);
		char *interpolation_type	= strdup(argv[2]);
		int conserve_flux		= strtol(argv[3], NULL, 0);		
		char *output_f			= strdup(argv[4]);		
		
		// ***********************************************************************
		// Open input file (ARG 1), get parameters and perform any data format 
		// checks

		fitsfile *input_f_ptr;

		int input_f_maxdim = 2, input_f_status = 0, input_f_bitpix, input_f_naxis;
		long input_f_naxes [2] = {1,1};

		if(!fits_open_file(&input_f_ptr, input_f, IMG_READ_ACCURACY, &input_f_status)) {

			if(!populate_img_parameters(input_f, input_f_ptr, input_f_maxdim, &input_f_bitpix, &input_f_naxis, input_f_naxes, &input_f_status, "INPUT FRAME")) {

				if (input_f_naxis != 2) {	// any data format checks here

					write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -2, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);

					free(input_f);
					free(output_f);					
					free(interpolation_type);
					if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

					return 1;
	
				}

			} else { 

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -3, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, input_f_status); 

				free(input_f);
					free(output_f);					
				free(interpolation_type);
				if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

				return 1; 

			}

		} else { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -4, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error(stdout, input_f_status); 

			free(input_f);
			free(output_f);				
			free(interpolation_type);			

			return 1; 

		}
		
		// ***********************************************************************
		// Set the range limits

		int cut_x [2] = {1, input_f_naxes[0]};
		int cut_y [2] = {1, input_f_naxes[1]};

		// ***********************************************************************
		// Set parameters used when reading data from input file (ARG 1)

		long fpixel [2] = {cut_x[0], cut_y[0]};
		long nxelements = (cut_x[1] - cut_x[0]) + 1;
		long nyelements = (cut_y[1] - cut_y[0]) + 1;

		// ***********************************************************************
		// Create arrays to store pixel values from input fits file (ARG 1)

		double input_f_pixels [nxelements];
		
		// ***********************************************************************
		// Get input fits file (ARG 1) values and store in 2D array

		int ii;

		double input_frame_values [nyelements][nxelements];
		memset(input_frame_values, 0, sizeof(double)*nxelements*nyelements);
		for (fpixel[1] = cut_y[0]; fpixel[1] <= cut_y[1]; fpixel[1]++) {

			memset(input_f_pixels, 0, sizeof(double)*nxelements);

			if(!fits_read_pix(input_f_ptr, TDOUBLE, fpixel, nxelements, NULL, input_f_pixels, NULL, &input_f_status)) {

				for (ii=0; ii<nxelements; ii++) {

					input_frame_values[fpixel[1]-1][ii] = input_f_pixels[ii];

				}

			} else { 

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -5, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, input_f_status); 

				free(input_f);
				free(output_f);					
				free(interpolation_type);				
				if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

				return 1; 

			}

		}	
		
		// ***********************************************************************
		// Open [SPTRACE_OUTPUTF_TRACES_FILE] input file
	
		FILE *inputfile;
	
		if (!check_file_exists(SPTRACE_OUTPUTF_TRACES_FILE)) { 

			inputfile = fopen(SPTRACE_OUTPUTF_TRACES_FILE , "r");

		} else {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -6, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);

			return 1;

		}	
		
		// ***********************************************************************
		// Find some [SPTRACE_OUTPUTF_TRACES_FILE] file details

		char input_string [500];

		bool find_polynomialorder_comment = FALSE;

		int polynomial_order;	

		char search_string_1 [20] = "# Polynomial Order:\0";	// this is the comment to be found from the [SPTRACE_OUTPUTF_TRACES_FILE] file

		while(!feof(inputfile)) {

			memset(input_string, '\0', sizeof(char)*500);
	
			fgets(input_string, 500, inputfile);	

			if (strncmp(input_string, search_string_1, strlen(search_string_1)) == 0) { 

				sscanf(input_string, "%*[^\t]%d", &polynomial_order);		// read all data up to tab as string ([^\t]), but do not store (*)
				find_polynomialorder_comment = TRUE;
				break;

			} 

		}

		if (find_polynomialorder_comment == FALSE) {	// error check - didn't find the comment in the [SPTRACE_OUTPUTF_TRACES_FILE] file

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -7, "Status flag for L2 frcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(input_f);
			free(output_f);				
			free(interpolation_type);				
			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1;

		}
		
		// ***********************************************************************
		// Rewind and extract coefficients from [SPTRACE_OUTPUTF_TRACES_FILE] file 

		rewind(inputfile);

		int token_index;	// this variable will hold which token we're dealing with
		int coeff_index;	// this variable will hold which coefficient we're dealing with
		double this_coeff;
		double this_chisquared;
	
		char *token;

		double coeffs [polynomial_order+1];
		memset(coeffs, 0, sizeof(double)*(polynomial_order+1));

		while(!feof(inputfile)) {

			memset(input_string, '\0', sizeof(char)*500);
	
			fgets(input_string, 500, inputfile);

			token_index = 0;
			coeff_index = 0;

			if (strtol(&input_string[0], NULL, 0) > 0) { 		// check the line begins with a positive number
				
				// ***********************************************************************
				// String tokenisation loop: 
				//
				// 1. init calls strtok() loading the function with input_string
				// 2. terminate when token is null
				// 3. we keep assigning tokens of input_string to token until termination by calling strtok with a NULL first argument
				// 
				// n.b. searching for tab or newline separators ('\t' and '\n')
				for (token=strtok(input_string, "\t\n"); token !=NULL; token = strtok(NULL, "\t\n")) {	
					if ((token_index >= 0) && (token_index <= polynomial_order)) { 			// coeff token
						this_coeff = strtod(token, NULL);
						//printf("%d\t%e\n", coeff_index, this_coeff);				// DEBUG
						coeffs[coeff_index] = this_coeff;
						coeff_index++;
					} else if (token_index == polynomial_order+1) {					// chisquared token
						this_chisquared = strtod(token, NULL);
					}
					token_index++;
				}
			}
		}	
		
		// ***********************************************************************
		// Determine the min and max offsets from c0 (this is needed to avoid 
		// trying to interpolate past the limits) otherwise throws GSL 
		// INTERPOLATION ERROR.
		
		double c0 = coeffs[0];
		float min_offset = 0;	// this is how much the curvature extends in -ve y
		float max_offset = 0;	// this is how much the curvature extends in +ve y
		for (ii=0; ii<nxelements; ii++) {
			float this_offset = gsl_poly_eval(coeffs, polynomial_order+1, ii) - c0;
			if (this_offset > max_offset) {
				max_offset = this_offset;
			}
			if (this_offset < min_offset) {
				min_offset = this_offset;
			}
		}	

                int min_offset_int = (int)ceil(fabs(min_offset));
		int max_offset_int = (int)ceil(fabs(max_offset));
		int nyelements_reb = nyelements - max_offset_int - min_offset_int;

		// ***********************************************************************
		// Do the rebinning (conserving flux where applicable)

		double reb_values[nyelements_reb][nxelements];
		memset(reb_values, 0, sizeof(double)*nyelements_reb*nxelements);		
		
		double this_pre_rebin_flux, this_post_rebin_flux;
		double this_column_values[nyelements];
		double this_column_values_reb[nyelements_reb];		
		double x_offsetted[nyelements];
		
		int jj;
		for (ii=0; ii<nxelements; ii++) {
			this_pre_rebin_flux = 0.;
			double this_offset = gsl_poly_eval(coeffs, polynomial_order+1, ii) - c0;
			memset(this_column_values, 0, sizeof(double)*nyelements);
			memset(this_column_values_reb, 0, sizeof(double)*nyelements_reb);			
			for (jj=0; jj<nyelements; jj++) {
				this_column_values[jj] = input_frame_values[jj][ii];
				x_offsetted[jj] = jj - this_offset;
				this_pre_rebin_flux += input_frame_values[jj][ii];
			}

			interpolate(interpolation_type, x_offsetted, this_column_values, nyelements, min_offset_int, nyelements_reb-max_offset_int, 1, this_column_values_reb);

			// get post rebin flux
			this_post_rebin_flux = 0.;
			for (jj=0; jj<nyelements_reb; jj++) {
				this_post_rebin_flux += this_column_values_reb[jj];
			}
			
			// apply conservation factor
			double conservation_factor = this_pre_rebin_flux/this_post_rebin_flux;
			//printf("%f\t%f\t%f\n", this_pre_rebin_flux, this_post_rebin_flux, conservation_factor);	// DEBUG
			if (conserve_flux == TRUE) {
				for (jj=0; jj<nyelements_reb; jj++) {
					reb_values[jj][ii] = this_column_values_reb[jj] * conservation_factor;
				} 
			} else {
				for (jj=0; jj<nyelements_reb; jj++) {				
					reb_values[jj][ii] = this_column_values_reb[jj];					
				}
			}	
		}
		
		// ***********************************************************************
		// Set output frame parameters	

		fitsfile *output_f_ptr;
	
		int output_f_status = 0;
		long output_f_naxes [2] = {nxelements,nyelements_reb};
	
		long output_f_fpixel = 1;

		// ***********************************************************************
		// Create [output_frame_values] array to hold the output data in the 
		// correct format
                
		int kk;
		double output_frame_values [nxelements*nyelements_reb];
		memset(output_frame_values, 0, sizeof(double)*nxelements*nyelements_reb);
		for (ii=0; ii<nyelements_reb; ii++) {	
			jj = ii * nxelements;			
			for (kk=0; kk<nxelements; kk++) {
				output_frame_values[jj] = reb_values[ii][kk];
				jj++;
			}
		}	
		
		// ***********************************************************************
		// Create and write [output_frame_values] to output file (ARG 4)
	
		if (!fits_create_file(&output_f_ptr, output_f, &output_f_status)) {
	
			if (!fits_create_img(output_f_ptr, INTERMEDIATE_IMG_ACCURACY[0], 2, output_f_naxes, &output_f_status)) {

				if (!fits_write_img(output_f_ptr, INTERMEDIATE_IMG_ACCURACY[1], output_f_fpixel, nxelements*nyelements_reb, output_frame_values, &output_f_status)) {

				} else { 

					write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -8, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
					fits_report_error(stdout, output_f_status); 

					free(input_f);
					free(output_f);				
					free(interpolation_type);
					if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
					if(fits_close_file(output_f_ptr, &output_f_status)) fits_report_error (stdout, output_f_status);

					return 1; 

				}

			} else {

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -9, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, output_f_status); 

				free(input_f);
				free(output_f);				
				free(interpolation_type);
				if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
				if(fits_close_file(output_f_ptr, &output_f_status)) fits_report_error (stdout, output_f_status);

				return 1; 

			}

		} else {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -10, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error(stdout, output_f_status); 

			free(input_f);
			free(output_f);				
			free(interpolation_type);
			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1; 

		}

		// ***********************************************************************
		// Free arrays on heap

		free(input_f);
		free(interpolation_type);
		free(output_f);
		
		// ***********************************************************************
		// Close [SPTRACE_OUTPUTF_TRACES_FILE] output file, input file (ARG 1) and
		// output file (ARG 4)
		
		if (fclose(inputfile)) {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -11, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1; 

		}		

		if(fits_close_file(input_f_ptr, &input_f_status)) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -12, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error (stdout, input_f_status); 

			return 1; 

	    	}
	    	
		if(fits_close_file(output_f_ptr, &output_f_status)) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", -13, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error (stdout, output_f_status); 

			return 1; 

	    	}	    	
		
		// ***********************************************************************
		// Write success to [ERROR_CODES_FILE]

		write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATCO", RETURN_FLAG, "Status flag for L2 spcorrect routine", ERROR_CODES_FILE_WRITE_ACCESS);

		return 0;

	}

}
Пример #14
0
void *readFits(const Config *para, int *bitpix, int *status, long naxes[2], double (**convert)(void *,long )){
  /* Reads fits file and return info. "convert" is a pointer to a pointer of a function. */
  
  if(para->coordType != CART){
    fprintf(stderr,"%s: fits file detected. coord should be set to cart for image coordinates. Exiting...\n",MYNAME);
    exit(EXIT_FAILURE);
  }
  fitsfile *fptr; 
  
  fits_open_file(&fptr, para->fileRegInName, READONLY, status);
  if(*status == FILE_NOT_OPENED){
    fprintf(stderr,"%s: %s not found. Exiting...\n",MYNAME,para->fileRegInName);
    exit(EXIT_FAILURE);
  }
  fits_get_img_type(fptr, bitpix, status);
  fits_get_img_size(fptr, 2, naxes, status);
  
  long fpixel[2];
  fpixel[0] = fpixel[1] = 1;
  
  void   *result;
  char   *table_CHAR;
  short  *table_SHORT;
  long   *table_LONG;
  float  *table_FLOAT;  
  double *table_DOUBLE;  
  
  fprintf(stderr,"Reading fits file (format detected: ");
  switch (*bitpix){
  case BYTE_IMG:
    fprintf(stderr,"BYTE)...\n");
    table_CHAR = (char *)malloc(naxes[0]*naxes[1]*sizeof(char)); 
    fits_read_pix(fptr,TBYTE,fpixel,naxes[0]*naxes[1],NULL,table_CHAR,NULL,status);
    result = (void *)table_CHAR;
    *convert = convertCHAR;
    break;
  case SHORT_IMG:
    fprintf(stderr,"SHORT)...\n");
    table_SHORT = (short *)malloc(naxes[0]*naxes[1]*sizeof(short)); 
    fits_read_pix(fptr,TSHORT,fpixel,naxes[0]*naxes[1],NULL,table_SHORT,NULL,status);
    result = (void *)table_SHORT;
    *convert = convertSHORT;
    break;
  case LONG_IMG:
    fprintf(stderr,"LONG)...\n");
    table_LONG = (long *)malloc(naxes[0]*naxes[1]*sizeof(long)); 
    fits_read_pix(fptr,TLONG,fpixel,naxes[0]*naxes[1],NULL,table_LONG,NULL,status);
    result = (void *)table_LONG;
    *convert = convertLONG;
    break;
  case FLOAT_IMG:
    fprintf(stderr,"FLOAT)...\n");
    table_FLOAT = (float *)malloc(naxes[0]*naxes[1]*sizeof(float)); 
    fits_read_pix(fptr,TFLOAT,fpixel,naxes[0]*naxes[1],NULL,table_FLOAT,NULL,status);
    result = (void *)table_FLOAT;
    *convert = convertFLOAT;
    break;
  case DOUBLE_IMG:
    fprintf(stderr,"DOUBLE)...\n");
    table_DOUBLE = (double *)malloc(naxes[0]*naxes[1]*sizeof(double)); 
    fits_read_pix(fptr,TDOUBLE,fpixel,naxes[0]*naxes[1],NULL,table_DOUBLE,NULL,status);
    result = (void *)table_DOUBLE;
    *convert = convertDOUBLE;
    break;
  default:
    fprintf(stderr,"NULL) \n%s: fits format not recognized. Exiting...\n",MYNAME);
    exit(EXIT_FAILURE);
  }  
  
  fits_close_file(fptr, status);
  
  if (*status)         
    fits_report_error(stderr, *status);
  
  return result;
}
Пример #15
0
int extractAvePlane (char *cubepath, char *impath, int iplane, int nplaneave,
    int *splaneave, int *eplaneave, char *errmsg)
{
    struct stat     buf;
    struct FitsHdr  hdr;

    char   str[1024];
    char   cmd[1024];
    
    int    bitpix;
    int    istatus;
    
    int    nhdu, hdutype, hdunum;

    int    nelements;
   
    int    naxis3;
    int    l;
    int    j;
    int    i;
    int    jj;
    int    nullcnt;

    int    splane;
    int    eplane;

    long   fpixel[4];
    long   fpixelo[4];

    double *fitsbuf;
    double *imbuff;
    
    fitsfile  *infptr;
    fitsfile  *outfptr;

    
    int    debugfile = 1;
    int    debugfile1 = 0;


/*
     Make a NaN value to use setting blank pixels
 */

    union
    {
        double d;
        char   c[8];
    }
    value;

    double nan;

    for(i=0; i<8; ++i)
        value.c[i] = 255;

    nan = value.d;


    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, "\nEnter extractAvePlane: cubepath= [%s]\n", 
	    cubepath);
	fprintf (fp_debug, "iplane= [%d]\n", iplane);
	fprintf (fp_debug, "nplaneave= [%d]\n", nplaneave);
	fprintf (fp_debug, "impath= [%s]\n", impath);
        fflush (fp_debug);
    }

    splane = iplane - nplaneave/2;
    eplane = splane + nplaneave - 1;

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, "splane= [%d] eplane= [%d]\n", splane, eplane);
        fflush (fp_debug);
    }

    istatus = 0;
    if (fits_open_file (&infptr, cubepath, READONLY, &istatus)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	    fprintf (fp_debug, "istatus= [%d]\n", istatus);
            fflush (fp_debug);
	}

	sprintf (errmsg, "Failed to open FITS file [%s]\n", cubepath);
	return (-1);
    } 
   
    hdunum = 1; 
    nhdu = 0;
    istatus = 0;
    istatus = fits_get_num_hdus (infptr, &nhdu, &istatus);
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, 
	    "returned fits_get_hdu_num: istatus= [%d] nhdu= [%d]\n",
	    istatus, nhdu);
        fflush (fp_debug);
    }

    if (hdunum > nhdu) {

        sprintf (errmsg, "fname [%s] doesn't contain any HDU", cubepath);
	return (-1);
    }


/*
    Read fits keywords from the first HDU
*/
    hdutype = 0;
    istatus = 0;
    istatus = fits_movabs_hdu (infptr, hdunum, &hdutype, &istatus);

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, 
	    "returned fits_movabs_hdu: istatus= [%d] hdutype= [%d]\n",
	    istatus, hdutype);
        fflush (fp_debug);
    }

/*
    Read fits keywords
*/
    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "simple", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword SIMPLE not found in fits header");
        return (-1);
    }
   
    if ((strcmp (str, "T") != 0) && (strcmp (str, "F") != 0)) {
        sprintf (errmsg, "keyword SIMPLE must be T or F");
        return (-1);
    }

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "bitpix", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword BITPIX not found in fits header");
        return (-1);
    }
  
    istatus = str2Integer (str, &bitpix, errmsg);
    if (istatus != 0) {
        sprintf (errmsg, "keyword BITPIX must be an integer");
        return (-1);
    }

    if ((bitpix != 8) &&
        (bitpix != 16) &&
        (bitpix != 32) &&
        (bitpix != 64) &&
        (bitpix != -32) &&
        (bitpix != -64)) {
        
	sprintf (errmsg, 
	    "keyword BITPIX value must be 8, 16, 32, 64, -32, -64");
        return (-1);
    }

    hdr.bitpix = bitpix;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis", str, (char *)NULL, 
        &istatus);
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }
    istatus = str2Integer (str, &hdr.naxis, errmsg);
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis to integer");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "naxis= [%d]\n", hdr.naxis);
        fflush (fp_debug);
    }


    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis1", str, (char *)NULL, 
        &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis1 not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.ns, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis1 string to integer");
        return (-1);
    }
    hdr.naxes[0] = hdr.ns;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis2", str, 
        (char *)NULL, &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis2 not found in fits header");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.nl, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis2 string to integer");
        return (-1);
    }
    hdr.naxes[1] = hdr.nl;

    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "ns= [%d] nl= [%d]\n", hdr.ns, hdr.nl);
        fflush (fp_debug);
    }

    hdr.nplane = 1;

    if (hdr.naxis > 2) {
    
        istatus = 0;
        istatus = fits_read_key (infptr, TSTRING, "naxis3", str, 
            (char *)NULL, &istatus);
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

            fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", 
	        istatus);
            fflush (fp_debug);
        }
        
        if (istatus == KEY_NO_EXIST) {
            sprintf (errmsg, "keyword naxis3 not found in fits header");
            return (-1);
        }
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

            fprintf (fp_debug, "str= [%s]\n", str);
            fflush (fp_debug);
        }

        istatus = str2Integer (str, &hdr.naxes[2], errmsg);
    
        if (istatus < 0) {
            sprintf (errmsg, "Failed to convert naxis3 string to integer");
            return (-1);
        }
        hdr.nplane = hdr.naxes[2];
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

            fprintf (fp_debug, "naxes[2]= [%d]\n", hdr.naxes[2]);
            fflush (fp_debug);
        }
    }
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

        fprintf (fp_debug, "nplane= [%d]\n", hdr.nplane);
        fflush (fp_debug);
    }


    istatus = stat (impath, &buf);
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "impath exists? : istatus= [%d]\n", istatus);
        fflush (fp_debug); 
    }

    if (istatus >= 0) {
        sprintf (cmd, "unlink %s", impath);
	istatus = system (cmd);
    }	

/*
    Create output fits file
*/
    istatus = 0;
    if (fits_create_file (&outfptr, impath, &istatus)) {
	    
        sprintf (errmsg, "Failed to create output fitsfile [%s]\n", impath);
        
	if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
	    fflush (fp_debug);
        }
	return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
	fprintf (fp_debug, "outptr created\n");
        fflush (fp_debug);
    }


/* 
    Copy input fits header to output fitsfile
*/
    istatus = 0;
    if (fits_copy_header (infptr, outfptr, &istatus)) {

        strcpy (errmsg, "Failed to copy fitshdr\n");
        
	if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
	    fflush (fp_debug);
        }
	return (-1);
    }

/*
    Update header keyword NAXIS3
*/
    naxis3 = 1;
    istatus = 0;
    if (fits_update_key_lng(outfptr, "NAXIS3", naxis3, (char *)NULL, 
        &istatus)) {
	
        strcpy (errmsg, "Failed to update keyword NAXIS3\n");
	return (-1);
    }

    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
	        
	fprintf (fp_debug, "cubepath= [%s]\n", cubepath);
        fflush (fp_debug);
    }

    istatus = 0;
    if (fits_open_file (&infptr, cubepath, READONLY, &istatus)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	    fprintf (fp_debug, "istatus= [%d]\n", istatus);
            fflush (fp_debug);
	}

	sprintf (errmsg, "Failed to open FITS file [%s]\n", cubepath);
	return (-1);
    } 
  
/*
    Create imbuff for average image
*/
    imbuff = (double *)malloc (hdr.ns*hdr.nl*sizeof(double));
    for (i=0; i<hdr.nl*hdr.ns; i++) {
        imbuff[i] = 0.;
    }


/*
    Read data from nth plane and write to output fitsfile
*/
    nelements = hdr.ns;
       
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {

	fprintf (fp_debug, "iplane= [%d]\n", iplane);
        fflush (fp_debug);
    }

    fitsbuf  = (double *)malloc(hdr.ns*sizeof(double));

    if (splane < 1)
        splane = 1;
    
    if (eplane > hdr.nplane)
        eplane = hdr.nplane;

    for (l=splane; l<=eplane; l++) { 
    
        fpixel[0] = 1;
        fpixel[1] = 1;
        fpixel[2] = l;
        fpixel[3] = 1;

        for (j=0; j<hdr.nl; j++) {

	    if (j == 0) {
	        if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        
	            fprintf (fp_debug, "l= [%d] fpixel[2]= [%ld]\n", 
		        l, fpixel[2]);
                    fflush (fp_debug);
	        }
            }

	    if (fits_read_pix (infptr, TDOUBLE, fpixel, nelements, &nan,
                fitsbuf, &nullcnt, &istatus)) {
	        break;
	    }
            
	    if (j == 10) {
	        if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
                    for (i=0; i<hdr.ns; i++) {
	                fprintf (fp_debug, "j= [%d] i= [%d] fitsbuf= [%lf]\n",
	                    j, i, fitsbuf[i]);
	                fprintf (fp_debug, "fitsbuf/nplaneave= [%lf]\n",
	                    fitsbuf[i]/nplaneave);
		    }
                    fflush (fp_debug);
	        }
            }         

/*
    Copy data to imbuff for plane averaging
*/
            jj = hdr.ns*j;
	    if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        fprintf (fp_debug, "jj= [%d]\n", jj);
                fflush (fp_debug);
	    }
	        
            for (i=0; i<hdr.ns; i++) {
		imbuff[jj+i] += fitsbuf[i]/nplaneave; 
            }         
 
            if (j == 10) {
	        if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        
                    for (i=0; i<hdr.ns; i++) {
	                fprintf (fp_debug, "j= [%d] i= [%d] imbuff= [%lf]\n",
	                    j, i, imbuff[jj+i]);
		    }
                    fflush (fp_debug);
	        }
            }         
            fpixel[1]++;
        }
    }

/*
    Write averaged image to output FITS file
*/
    fpixelo[0] = 1;
    fpixelo[1] = 1;
    fpixelo[2] = 1;
    fpixelo[3] = 1;
    
    for (j=0; j<hdr.nl; j++) {

        jj = hdr.ns*j;
        for (i=0; i<hdr.ns; i++) {
	    fitsbuf[i] = imbuff[jj+i]; 
        }
            
	if (j == 10) {
	    if ((debugfile1) && (fp_debug != (FILE *)NULL)) {
	        
                for (i=0; i<hdr.ns; i++) {
	            fprintf (fp_debug, "j= [%d] i= [%d] fitsbuf= [%lf]\n", 
		        j, i, fitsbuf[i]);
		}
                fflush (fp_debug);
	    }
        }         

        
	if (fits_write_pix (outfptr, TDOUBLE, fpixelo, nelements,
			 (void *)fitsbuf, &istatus)) {

            sprintf (errmsg, "fits write error: l= [%d]\n", l);
            return (-1);
        }

        fpixelo[1]++;
    }   


    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }
    
    istatus = 0;
    if (fits_close_file (outfptr, &istatus)) {
        sprintf (errmsg, "Failed to close impath [%s]\n", impath);
        return (-1); 
    }

    *splaneave = splane;
    *eplaneave = eplane;

    return (0);
}
Пример #16
0
int extractWaveSpectra (struct Mviewer *param)
{
    FILE   *fp;

    struct FitsHdr  hdr;

    char   str[1024];

    char   colname[40];
    char   datatype[40];
    char   null[40];
    char   unit[40];

    char   rootname[1024];
    char   suffix[40];

    int    istatus;
    int    status;
    int    fileExist; 

    long    nelements;
  
    int    iscube;    

    int    ixpix;
    int    iypix;

    int    ixs;
    int    iys;
    int    ixe;
    int    iye;

    double xs;
    double ys;
    double xe;
    double ye;

    int    npixel;

    int    l;
    int    j;
    int    i;
    int    nullcnt;

    long   fpixel[4];
    
    double *data;
    double *xarr;
    double *yarr;
    
    fitsfile  *infptr;


/*
     Make a NaN value to use setting blank pixels 
*/

    union
    {
       double d;
       char   c[8];
    }
    value;

    double nan;

    for(i=0; i<8; ++i)
       value.c[i] = 255;

    nan = value.d;

    
    int    debugfile = 1;


    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "\nEnter extractWaveSpectra: cubepath= [%s]\n", 
            param->imcubepath);
        
        fprintf (fp_debug, "\nEnter extractWaveSpectra: imageFile= [%s]\n", 
            param->imageFile);

        fprintf (fp_debug, "\nshrunkimfile= [%s]\n", param->shrunkimfile);
        fprintf (fp_debug, "\nwaveplottype= [%s]\n", param->waveplottype);

        if (strcasecmp (param->waveplottype, "pix") == 0) {
            fprintf (fp_debug, "xs= [%lf] ys= [%lf]\n", 
                param->xs, param->ys);
        }
        else {
            fprintf (fp_debug, "xs= [%lf] ys= [%lf] xe= [%lf] ye= [%lf]\n", 
                param->xs, param->ys, param->xe, param->ye);
        }
        
        fprintf (fp_debug, "zoomfactor= [%lf]\n", param->zoomfactor);
        fprintf (fp_debug, "ss= [%lf] sl= [%lf\n", param->ss, param->sl);
        fprintf (fp_debug, "xflip= [%d] yflip= [%d]\n", 
            param->xflip, param->yflip);
        fflush (fp_debug);
    }


    iscube = 1;
    istatus = getFitshdr (param->imcubepath, &hdr, iscube); 
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "returned getFitshdr: istatus= %d\n", istatus);
        fflush (fp_debug);
    }

    if (istatus == -1) {
        sprintf (param->errmsg, "Failed to getFitshdr: FITS file %s\n", 
            param->imcubepath);
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "ns= [%d] nl= [%d] nplane= [%d]\n", 
            hdr.ns, hdr.nl, hdr.nplane);
        fprintf (fp_debug, "crval3= [%lf] cdelt3= [%lf]\n", 
            hdr.crval[2], hdr.cdelt[2]);
        fflush (fp_debug);
    }


/*
    Adjust xpix, ypix based on xflip, yflip
*/
    if (strcasecmp (param->waveplottype, "pix") == 0) {
    
        param->xpix = param->xs/param->zoomfactor + param->ss;
        param->ypix = param->ys/param->zoomfactor + param->sl;
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "xpix= [%lf] ypix= [%lf]\n", 
                param->xpix, param->ypix);
            fflush (fp_debug);
        }
        
        ixpix = (int)(param->xpix+0.5);
        iypix = (int)(param->ypix+0.5);

        if (param->xflip)
            ixpix = hdr.ns - ixpix;
        else
            ixpix = ixpix + 1;
    
        if (param->yflip)
            iypix = hdr.nl - iypix;
        else
            iypix = iypix + 1;
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "ixpix= [%d] iypix= [%d]\n", ixpix, iypix);
            fflush (fp_debug);
        }
        
    }
    else if (strcasecmp (param->waveplottype, "ave") == 0) {

        xs = param->xs/param->zoomfactor + param->ss;
        ys = param->ys/param->zoomfactor + param->sl;
        xe = param->xe/param->zoomfactor + param->ss;
        ye = param->ye/param->zoomfactor + param->sl;
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "xs= [%lf] ys= [%lf]\n", xs, ys);
            fprintf (fp_debug, "xe= [%lf] ye= [%lf]\n", xe, ye);
            fflush (fp_debug);
        }
        
        ixs = (int)(xs+0.5);
        iys = (int)(ys+0.5);
        ixe = (int)(xe+0.5);
        iye = (int)(ye+0.5);

        
        if (param->xflip) {
            ixs = hdr.ns - ixs;
            ixe = hdr.ns - ixe;
        }
        else {
            ixs = ixs + 1;
            ixe = ixe + 1;
        }
    
        if (param->yflip) {
            iys = hdr.nl - iys;
            iye = hdr.nl - iye;
        }
        else {
            iys = iys + 1;
            iye = iye + 1;
        }

        if (iys > iye) {
            i = iys;
            iys = iye;
            iye = i;
        }
        if (ixs > ixe) {
            i = ixs;
            ixs = ixe;
            ixe = i;
        }
    
        npixel = (ixe-ixs+1) * (iye-iys+1);
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "ixs= [%d] iys= [%d] ixe= [%d] iye= [%d]\n", 
                ixs, iys, ixe, iye);
            fprintf (fp_debug, "npixel= [%d]\n", npixel);
            fflush (fp_debug);
        }
    
    }


/*
    malloc plot arrays: xarr and yarr
*/
    xarr = (double *)malloc (hdr.nplane*sizeof(double));
    yarr = (double *)malloc (hdr.nplane*sizeof(double));
    for (i=0; i<hdr.nplane; i++) {
        xarr[i] = 0.;
        yarr[i] = 0.;
    }


/*
    Create plot xarr based on wavelen axis (i.e. crval3 and cdelt3)
*/
    for (i=0; i<hdr.nplane; i++) {
        xarr[i] = hdr.crval[2] + i*hdr.cdelt[2];
    }

/*
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        for (i=0; i<hdr.nplane; i++) {
            fprintf (fp_debug, "i= [%d] xarr= [%lf]\n", i, xarr[i]);
        }
        fflush (fp_debug);
    }
*/


/*
    Open cubefile for read
*/
    istatus = 0;
    if (fits_open_file (&infptr, param->imcubepath, READONLY, &status)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "istatus= [%d] status= [%d]\n", istatus, status);
            fflush (fp_debug);
        }

        sprintf (param->errmsg, "Failed to open FITS cubefile %s\n", 
            param->imcubepath);
        
        sprintf (param->retstr, "[struct stat=error, msg=%s]\n", 
            param->errmsg); 
        return (-1);
    } 
   

/*
    Read data from nth plane and write to output fitsfile
*/
    nelements = 1;
    data  = (double *)malloc(nelements*sizeof(double));

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "waveplottype= [%s]\n", param->waveplottype);
        fflush (fp_debug);
    }         
        
    
    for (l=0; l<hdr.nplane; l++) { 

        fpixel[2] = l;
        fpixel[3] = 1;
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "l= [%d] fpixel[2]= [%ld]\n", l, fpixel[2]);
            fflush (fp_debug);
        }         
        
        if (strcasecmp (param->waveplottype, "pix") == 0) {

            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                fprintf (fp_debug, "here1\n");
                fflush (fp_debug);
            }             
            
            fpixel[0] = ixpix;
            fpixel[1] = iypix;

            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                fprintf (fp_debug, "ixpix= [%d] iypix= [%d]\n", ixpix, iypix);
                fprintf (fp_debug, "fpixel[0]= [%ld] fpixel[1]= [%ld]\n", 
                    fpixel[0], fpixel[1]);
                fprintf (fp_debug, "call fits_read_pix\n");
                fflush (fp_debug);
            }             

            istatus = 0;
            istatus = fits_read_pix (infptr, TDOUBLE, fpixel, nelements, &nan,
                (void *)data, &nullcnt, &istatus);
           
            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                fprintf (fp_debug, "returned fits_read_pix: istatus= [%d]\n",
                    istatus);
                fflush (fp_debug);
            }    

            
            if (istatus == -1) {
                sprintf (param->errmsg, "Failed to read FITS file %s\n",
                    param->imcubepath);
                sprintf (param->retstr, "[struct stat=error, msg=%s]\n", 
                    param->errmsg); 
                return (-1);
            }

            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                fprintf (fp_debug, "l= [%d] data= [%lf]\n", l, data[0]);
                fflush (fp_debug);
            }         

            yarr[l] = (double)data[0];
        }
        else if (strcasecmp (param->waveplottype, "ave") == 0) {

            for (j=iys; j<=iye; j++) {
                
                fpixel[1] = j;

/*
                if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    fprintf (fp_debug, "j= [%d] fpixel[1]= [%ld]\n", 
                        j, fpixel[1]);
                    fflush (fp_debug);
                }        
*/

                for (i=ixs; i<=ixe; i++) {

                    fpixel[0] = i;

/*
                    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                        fprintf (fp_debug, "i= [%d] fpixel[0]= [%ld]\n", 
                            i, fpixel[0]);
                        fflush (fp_debug);
                    }
*/

                    istatus = 0;
                    istatus = fits_read_pix (infptr, TDOUBLE, fpixel, nelements, &nan, 
                                        (void *)data, &nullcnt, &istatus);


/*
                    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                        fprintf (fp_debug, 
                            "returned fits_read_pix: istatus= [%d]\n", istatus);
                        fflush (fp_debug);
                    }    
 */

                    if (istatus == -1) {
                        sprintf (param->errmsg, "Failed to read FITS file %s\n",
                            param->imcubepath);
                        sprintf (param->retstr, "[struct stat=error, msg=%s]\n",
                            param->errmsg); 
                        return (-1);
                    }
/*
                    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                        fprintf (fp_debug, "l= [%d] data= [%lf]\n", l, data[0]);
                        fflush (fp_debug);
                    }         
 */           
                    yarr[l] += (double)data[0]/npixel;
  /*                  
                    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                        fprintf (fp_debug, "yarr= [%lf]\n", yarr[l]);
                        fflush (fp_debug);
                    }         
   */         
                }
            }
        }

    }

/*
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        for (l=0; l<hdr.nplane; l++) {
            fprintf (fp_debug, "l= [%d] xarr= [%lf] yarr= [%lf]\n", 
                l, xarr[l], yarr[l]);
        }
        fflush (fp_debug);
    }         
*/

    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (param->errmsg, "Failed to close imcubepath %s\n", 
            param->imcubepath);
        
        sprintf (param->retstr, "[struct stat=error, msg=%s]\n", 
            param->errmsg); 
        return (-1); 
    }
    

/*
    Write tblarr to output IPAC table
*/
    sprintf (param->plotfile, "%s_plot.tbl", param->imageFile);
    sprintf (param->plotpath, "%s/%s", param->directory, param->plotfile);

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "plotpath= [%s]\n", param->plotpath);
        fflush (fp_debug);
    }         

    fp = (FILE *)NULL;
    if ((fp = fopen (param->plotpath, "w+")) == (FILE *)NULL) {
   
        param->errmsg[0] = '\0';
        sprintf (param->errmsg, "Failed to open tblpath %s\n", 
            param->plotpath);
        
        sprintf (param->retstr, "[struct stat=error, msg=%s]\n", 
            param->errmsg); 
        return (-1);
    }
    
/*
    Write header
*/
    strcpy (colname, "planenum");
    fprintf (fp, "|%-16s|", colname); 

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "plotxaxis= [%s] plotyaxis= [%s]\n", 
            param->plotxaxis, param->plotyaxis);
        fflush (fp_debug);
    }         


    if ((int)strlen(param->plotxaxis) > 0) {
        sprintf (colname, "%s", param->plotxaxis);
    }
    else {
        strcpy (colname, "wave");
    } 
    fprintf (fp, "%-16s|", colname);
    
    if ((int)strlen(param->plotyaxis) > 0) {
        sprintf (colname, "%s", param->plotyaxis);
    }
    else {
        strcpy (colname, "flux");
    } 
    fprintf (fp, "%-16s|", colname);
    fprintf (fp, "\n"); 
    fflush (fp);

    strcpy (datatype, "int");
    fprintf (fp, "|%-16s|", datatype); 
    strcpy (datatype, "double");
    fprintf (fp, "%-16s|", datatype);
    strcpy (datatype, "double");
    fprintf (fp, "%-16s|", datatype);
    fprintf (fp, "\n"); 
    fflush (fp);

    strcpy (unit, "");
    fprintf (fp, "|%-16s|", unit); 
    strcpy (unit, hdr.cunit[2]);
    fprintf (fp, "%-16s|", unit);
    strcpy (unit, "dn");
    fprintf (fp, "%-16s|", unit);
    fprintf (fp, "\n"); 
    fflush (fp);

    strcpy (null, "null");
    fprintf (fp, "|%-16s|", null); 
    fprintf (fp, "%-16s|", null);
    fprintf (fp, "%-16s|", null);
    fprintf (fp, "\n"); 
    fflush (fp);

/*
    Write data 
*/
    for (i=0; i<hdr.nplane; i++) {

        sprintf (str, "%d", i);
        fprintf (fp, " %-16s ", str); 
    
        sprintf (str, "%16.2f", xarr[i]);
        fprintf (fp, "%-16s ", str); 
    
        sprintf (str, "%16.4f", yarr[i]);
        fprintf (fp, "%-16s ", str); 
    
        fprintf (fp, "\n"); 
        fflush (fp);
    }
        
    fclose (fp);        


/*
    Plot jsonfile
*/
    sprintf (param->plotjsonfile, "%s_plot.json", param->imageFile);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "call checkFileExist (plotjsonfile)\n");
        fflush (fp_debug);  
    }

    strcpy (param->plothistvalue, "uniform step"); 
    strcpy (param->plotcolor, "#008800"); 
    strcpy (param->plotlinecolor, "#008800"); 
    strcpy (param->plotbgcolor, "white"); 
    strcpy (param->plotsymbol, "ball"); 
    strcpy (param->plotlinestyle, "solid"); 
    strcpy (param->plotxaxis, "wave"); 
    strcpy (param->plotxlabel, "Wavelength (nm)"); 
    strcpy (param->plotyaxis, "flux"); 
    strcpy (param->plotylabel, "Flux (dn)"); 
    strcpy (param->plottitle, "");
    strcpy (param->plotxlabeloffset, "false");
    strcpy (param->plotylabeloffset, "false");
    
    param->plothiststyle = 1;


    fileExist = checkFileExist (param->plotjsonfile, rootname, suffix,
        param->directory, param->plotjsonpath);

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "returned checkFileExist: fileExist= [%d]\n", 
            fileExist);
        fprintf (fp_debug, "plotjsonfile= [%s]\n", param->plotjsonfile);
        fprintf (fp_debug, "plotjsonpath= [%s]\n", param->plotjsonpath);
        fflush (fp_debug);  
        
        fprintf (fp_debug, "plotwidth= [%d]\n", param->plotwidth);
        fprintf (fp_debug, "plotheight= [%d]\n", param->plotheight);
        fprintf (fp_debug, "plotbgcolor= [%s]\n", param->plotbgcolor);
        
        fprintf (fp_debug, "plothiststyle= [%d]\n", param->plothiststyle);
        fprintf (fp_debug, "plothistvalue= [%s]\n", param->plothistvalue);

        fprintf (fp_debug, "plotcolor= [%s]\n", param->plotcolor);
        fprintf (fp_debug, "plotlinecolor= [%s]\n", param->plotlinecolor);
        fprintf (fp_debug, "plotlinestyle= [%s]\n", param->plotlinestyle);
        

        fflush (fp_debug);  
    }
        

/*
    if (!fileExist) {
*/

/*
    Write plot jsonfile: re-write every time because the parameters 
    (width and height might have changed)
*/
        sprintf (param->plotjsonpath, "%s/%s", 
            param->directory, param->plotjsonfile);
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "plotjsonpaht= [%s]\n", param->plotjsonpath); 
        fflush (fp_debug);  
    }

        fp = (FILE *)NULL;
        if ((fp = fopen (param->plotjsonpath, "w+")) == (FILE *)NULL) {
   
            param->errmsg[0] = '\0';
            sprintf (param->errmsg, "Failed to open tblpath %s\n", 
                param->plotjsonpath);
        
            sprintf (param->retstr, "[struct stat=error, msg=%s]\n", 
                param->errmsg); 
            return (-1);
        }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "start writint plotjsonfile: [%s]\n",
            param->plotjsonpath);
        fflush (fp_debug);  
    }

/* 
    Create a default jsonfile; in this case, the following input parameters
    have to exist.
*/

         fprintf(fp, "{\n");
         
         fprintf(fp, "   \"jpeg\" :\n");
         fprintf(fp, "   {\n");
/*
         fprintf(fp, "      \"width\"  : \"%dpx\",\n", param->plotwidth);
         fprintf(fp, "      \"height\" : \"%dpx\",\n", param->plotheight);
*/
         fprintf(fp, "      \"width\"  : %d,\n", param->plotwidth);
         fprintf(fp, "      \"height\" : %d,\n", param->plotheight);


         fprintf(fp, "      \"background\" : \"%s\"\n", 
             param->plotbgcolor);
         fprintf(fp, "   },\n");
         fprintf(fp, "\n");

         if (param->plothiststyle) {
             fprintf(fp, "   \"histogram\" : \"%s\",\n", param->plothistvalue);
             fprintf(fp, "\n");
         }

         fprintf(fp, "   \"axes\" :\n");
         fprintf(fp, "   {\n");
         fprintf(fp, "      \"colors\" :\n");
         fprintf(fp, "      {\n");
         fprintf(fp, "         \"axes\"   : \"black\",\n");
         fprintf(fp, "         \"labels\" : \"black\"\n");
         fprintf(fp, "      },\n");

         if(strlen(param->plottitle) > 0)
         {
            fprintf(fp, "\n");
            fprintf(fp, "      \"title\" : \"%s\",\n", param->plottitle);
         }

         fprintf(fp, "\n");
         fprintf(fp, "      \"xaxis\" :\n");
         fprintf(fp, "      {\n");
         
         if ((int)strlen(param->plotxlabel) > 0) {
             fprintf(fp, "         \"label\"       : \"%s\",\n", 
                 param->plotxlabel);
         }
         else {
             fprintf(fp, "         \"label\"       : \"%s\",\n", 
                 param->plotxaxis);
         }

         if ((int)strlen(param->plotxlabeloffset) > 0) {
             fprintf(fp, "         \"offsetlabel\"       : \"%s\",\n", 
                 param->plotxlabeloffset);
         }
         else {
             fprintf(fp, "         \"offsetlabel\" : \"false\",\n");
         } 
         
         fprintf(fp, "         \"autoscale\"   : true,\n");
         fprintf(fp, "         \"scaling\"     : \"linear\"\n");
         fprintf(fp, "      },\n");
         fprintf(fp, "\n");
         fprintf(fp, "      \"yaxis\" :\n");
         fprintf(fp, "      {\n");
         
         if ((int)strlen(param->plotylabel) > 0) {
             fprintf(fp, "         \"label\"       : \"%s\",\n", 
                 param->plotylabel);
         }
         else {
             fprintf(fp, "         \"label\"       : \"%s\",\n", 
                 param->plotyaxis);
         }
         
         if ((int)strlen(param->plotylabeloffset) > 0) {
             fprintf(fp, "         \"offsetlabel\"       : \"%s\",\n", 
                 param->plotxlabeloffset);
         }
         else {
             fprintf(fp, "         \"offsetlabel\" : \"false\",\n");
         } 
         
         fprintf(fp, "         \"autoscale\"   : true,\n");
         fprintf(fp, "         \"scaling\"     : \"linear\"\n");
         fprintf(fp, "      }\n");
         fprintf(fp, "   },\n");
         fprintf(fp, "\n");
         fprintf(fp, "   \"pointset\" : \n");
         fprintf(fp, "   [\n");
         fprintf(fp, "      {\n");
         fprintf(fp, "         \"source\" :\n");
         fprintf(fp, "         {\n");
         fprintf(fp, "            \"table\" : \"%s\",\n", param->plotpath);
         fprintf(fp, "\n");


         fprintf(fp, "            \"xcolumn\" : \"%s\",\n", param->plotxaxis);
         fprintf(fp, "            \"ycolumn\" : \"%s\"\n", param->plotyaxis);
         fprintf(fp, "         },\n");
         fprintf(fp, "\n");
         fprintf(fp, "         \"points\" :\n");
         fprintf(fp, "         {\n");
         fprintf(fp, "            \"symbol\" : \"%s\",\n", param->plotsymbol);
         fprintf(fp, "            \"size\"   : 0.5,\n");
         fprintf(fp, "            \"color\"  : \"%s\"\n", param->plotcolor);
         fprintf(fp, "         },\n");
         fprintf(fp, "\n");
         fprintf(fp, "         \"lines\" :\n");
         fprintf(fp, "         {\n");
         fprintf(fp, "            \"style\" : \"%s\",\n", param->plotlinestyle);
         fprintf(fp, "            \"width\"   : 1.0,\n");
         fprintf(fp, "            \"color\"  : \"%s\"\n", param->plotlinecolor);
         fprintf(fp, "         }\n");
         fprintf(fp, "      }\n");
         fprintf(fp, "   ]\n");
         fprintf(fp, "}\n");

         fflush(fp);
         fclose(fp);
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "done writing plotjsonpath= [%s]\n", 
            param->plotjsonpath); 
        fflush (fp_debug);  
    }

/*
    }
*/
    return (0);
}
Пример #17
0
int main(int argc, char *argv[]) {
	fitsfile *afptr; /* FITS file pointers */
	int status = 0; /* CFITSIO status value MUST be initialized to zero! */
	int anaxis, check = 1, ii;
	int plane = -1; // parameter
	long npixels = 1, firstpix[3] = { 1, 1, 1 };
	long anaxes[3] = { 1, 1, 1 };
	double *apix;

	if (argc != 3) {
		printf("Usage: fits_subset fitsfile[startX:startY,endX:endY] plane\n");
		printf("\n");
		printf("Example: Print pixels in the rectangle bound by "
				"X87, Y181 and X166, Y260 in plane 5:\n");
		printf("  ./fits_subset fits/0000801.fits[87:166,181:260] 5 \n");
		return (0);
	}
	
//	for(int i=0;i<argc;i++)
//			printf("Argument %d: '%s'\n", (i+1), argv[i]);

	plane = atoi(argv[2]);

	fits_open_file(&afptr, argv[1], READONLY, &status); /* open input images */
	if (status) {
		fits_report_error(stderr, status); /* print error message */
		return (status);
	}

	fits_get_img_dim(afptr, &anaxis, &status); /* read dimensions */
	fits_get_img_size(afptr, 3, anaxes, &status);

	if (status) {
		fits_report_error(stderr, status); /* print error message */
		return (status);
	}

	if (anaxis > 3) {
		printf("Error: images with > 3 dimensions are not supported\n");
		check = 0;
	}

	npixels = anaxes[0]; /* no. of pixels to read in each row */
	apix = (double *) malloc(npixels * sizeof(double)); /* mem for 1 row */

	if (apix == NULL) {
		printf("Memory allocation error\n");
		return (1);
	}

	/* loop over the requested plane of the cube */
	for (firstpix[1] = 1; firstpix[1] <= anaxes[1]; firstpix[1]++) {
		/* Read both images as doubles, regardless of actual datatype.  */
		/* Give starting pixel coordinate and no. of pixels to read.    */
		/* This version does not support undefined pixels in the image. */

		if (fits_read_pix(afptr, TDOUBLE, firstpix, npixels, NULL, apix, NULL, &status))
			break; /* jump out of loop on error */
		for (ii = 0; ii < npixels; ii++)
			printf("%*.*f\n", 11, 10, apix[ii]);
	}

	free(apix);

	fits_close_file(afptr, &status);

	if (status)
		fits_report_error(stderr, status); /* print any error message */
	return (status);
}
Пример #18
0
int main(int argc, char *argv[])
{
	fitsfile *afptr, *outfptr;  /* FITS file pointers */
	int status = 0;  /* CFITSIO status value MUST be initialized to zero! */
	int anaxis, check = 1, ii, op, keytype;
	long npixels = 1, firstpix[3] = {1,1,1}, ntodo;
	long anaxes[3] = {1,1,1};
	double *apix;
	double maxval, minval;
	char card[FLEN_CARD];

	if (argc != 5) { 
		printf("Usage: pruneimage image max min outimage \n");
		printf("\n");
		printf("Compiled from cfitsio v2.460\n");
		printf("\n");
		printf("Trim off the peaks and valley values of the image.\n");
		printf("\n");
		printf("outimage is of format BITPIX = -32\n");
		printf("\n");
		printf("Example: \n");
		printf("  pruneimage in.fit 1000 850 out.fits - sets all values above 1000 to 1000\n");
		printf("                                            and all values below 850 to 850.\n");
		return(0);
	}

	fits_open_file(&afptr, argv[1], READONLY, &status); /* open input images */
	fits_get_img_dim(afptr, &anaxis, &status);  /* read dimensions */
	fits_get_img_size(afptr, 3, anaxes, &status);

	if (status) {
		fits_report_error(stderr, status); /* print error message */
		return(status);
	}

	if (anaxis > 3) {
		printf("Error: images with > 3 dimensions are not supported\n");
		check = 0;
	}

	maxval = atof ( argv[2] );
	minval = atof ( argv[3] );

	/* create the new empty output file if the above checks are OK */
	if (check && !fits_create_file(&outfptr, argv[4], &status) )
	{
		/* copy all the header keywords from first image to new output file */
		fits_copy_header(afptr, outfptr, &status);

		/* change to floating point variable */
		fits_modify_key_lng (outfptr, "BITPIX", -32, "&", &status );

		fits_modify_key_flt (outfptr, "DATAMIN", minval, -10, "&", &status );
		fits_modify_key_flt (outfptr, "DATAMAX", maxval, -10, "&", &status );

		npixels = anaxes[0];  /* no. of pixels to read in each row */
		apix = (double *) malloc(npixels * sizeof(double)); /* mem for 1 row */

		if (apix == NULL) {
			printf("Memory allocation error\n");
			return(1);
		}

		/* loop over all planes of the cube (2D images have 1 plane) */
		for (firstpix[2] = 1; firstpix[2] <= anaxes[2]; firstpix[2]++)
		{
			/* loop over all rows of the plane */
			for (firstpix[1] = 1; firstpix[1] <= anaxes[1]; firstpix[1]++)
			{
				/* Read both images as doubles, regardless of actual datatype.  */
				/* Give starting pixel coordinate and no. of pixels to read.    */
				/* This version does not support undefined pixels in the image. */
				if (fits_read_pix(afptr, TDOUBLE, firstpix, npixels, NULL, apix,
					NULL, &status)  )
					break;   /* jump out of loop on error */



				for(ii=0; ii< npixels; ii++) {
					if ( apix[ii] > maxval )
						apix[ii] = maxval;
					else if ( apix[ii] < minval )
						apix[ii] = minval;
				}

				fits_write_pix(outfptr, TDOUBLE, firstpix, npixels,
					apix, &status); /* write new values to output image */
			}
		}    /* end of loop over planes */

		fits_close_file(outfptr, &status);
		free(apix);
	}

	fits_close_file(afptr, &status);
	 
	if (status) fits_report_error(stderr, status); /* print any error message */
		return(status);
}
Пример #19
0
int main(int argc, char *argv[])
{
	fitsfile *fptr;  /* FITS file pointer */
	int status = 0;  /* CFITSIO status value MUST be initialized to zero! */
	int hdutype, naxis, ii;
	long naxes[2], totpix, fpixel[2], rowlen;
	double *pix, sum = 0., medianval = 0.;	//, minval = 1.E33, maxval = -1.E33;
	double *medarray;

	if (argc != 2) { 
		printf("Usage: imagemedian image \n");
		printf("\n");
		printf("Compute median of pixels in the input image\n");
		printf("(Actually the median of the median of each row.)\n");
		printf("\n");
		printf("Examples: \n");
		printf("  imagemedian image.fits                    - the whole image\n");
//		printf("  imagemedian 'image.fits[200:210,300:310]' - image section\n");
//		printf("  imagemedian 'table.fits+1[bin (X,Y) = 4]' - image constructed\n");
//		printf("     from X and Y columns of a table, with 4-pixel bin size\n");
		printf("\n");
		return(0);
	}

	if ( !fits_open_file(&fptr, argv[1], READONLY, &status) )
	{
		if (fits_get_hdu_type(fptr, &hdutype, &status) || hdutype != IMAGE_HDU) { 
			printf("Error: this program only works on images, not tables\n");
			return(1);
		}

		fits_get_img_dim(fptr, &naxis, &status);
		fits_get_img_size(fptr, 2, naxes, &status);

		if (status || naxis != 2) { 
			printf("Error: NAXIS = %d.  Only 2-D images are supported.\n", naxis);
			return(1);
		}

		pix = (double *) malloc(naxes[0] * sizeof(double)); /* memory for 1 row */
		medarray = (double *) malloc(naxes[1] * sizeof(double)); /* memory for 1 column */

		if (pix == NULL) {
			printf("Memory allocation error\n");
			return(1);
		}

		totpix = naxes[0] * naxes[1];
		fpixel[0] = 1;  /* read starting with first pixel in each row */






//		printf("totpix: %lu\n", totpix);
//		printf("fpixel: %lu\n", fpixel[0]);
//		printf("fpixel: %lu\n", fpixel[1]);
//		printf("Whole : %lu\n", naxes[0]);
//		printf("Mod   : %lu\n", naxes[0]%2);
//		printf("Div   : %lu\n", naxes[0]/2);
//		printf("Whole : %lu\n", naxes[1]-1);
//		printf("Mod   : %lu\n", (naxes[1]-1)%2);
//		printf("Div   : %lu\n", (naxes[1]-1)/2);


		/* process image one row at a time; increment row # in each loop */
		for (fpixel[1] = 1; fpixel[1] <= naxes[1]; fpixel[1]++)
		{  
			/* give starting pixel coordinate and number of pixels to read */
			if (fits_read_pix(fptr, TDOUBLE, fpixel, naxes[0],0, pix,0, &status))
				break;   /* jump out of loop on error */

//	compute row median and store then compute median of medians 
//	not perfect, but pretty close

//		store in medianarray

			medarray[fpixel[1]] = median ( pix, naxes[0] );
//			printf("%g\n", medarray[fpixel[1]]);




//			for (ii = 0; ii < naxes[0]; ii++) {
//				sum += pix[ii];                      /* accumlate sum */
//				if (pix[ii] < minval) minval = pix[ii];  /* find min and  */
//				if (pix[ii] > maxval) maxval = pix[ii];  /* max values    */
//			}
		}
      
		free(pix);
		fits_close_file(fptr, &status);
	}

	if (status)  {
		fits_report_error(stderr, status); /* print any error message */
	} 

 	else {
		printf("%g\n", median ( medarray, naxes[1] ) );


// 		if (totpix > 0) meanval = sum / totpix;
//
//		printf("Statistics of %ld x %ld  image  = %g\n",
//			naxes[0], naxes[1]);
//		printf("  sum of pixels = %g\n", sum);
//		printf("  mean value    = %g\n", meanval);
//		printf("  minimum value = %g\n", minval);
//		printf("  maximum value = %g\n", maxval);
	}

	return(status);
}
Пример #20
0
void read_fits(const char* filename, int datatype, size_t* width, size_t* height, void** image)
{
    int status = 0;
    
    // the FITS file
    fitsfile* fptr;
    
    // metadata
    int bitpix;
    int naxis;
    long naxes[2];
    
    // total number of pixels
    long npix;
    
    // reading offset
    long fpixel[2] = { 1, 1 };
    
    // size of output image pixels
    size_t spix = 0;
    
    // open FITS file
    fits_open_image(&fptr, filename, READONLY, &status);
    if(status)
        fits_error(filename, status);
    
    // get metadata
    fits_get_img_param(fptr, 2, &bitpix, &naxis, naxes, &status);
    if(status)
        fits_error(filename, status);
    
    // check dimension of image
    if(naxis != 2)
        errorf(filename, 0, "file has %d axes (should be 2)", naxis);
    
    // set dimensions
    *width = naxes[0];
    *height = naxes[1];
    
    // size of output pixels
    switch(datatype)
    {
        case TINT:
            spix = sizeof(int);
            break;
            
        case TFLOAT:
            spix = sizeof(float);
            break;
            
        case TDOUBLE:
            spix = sizeof(double);
            break;
            
        default:
            error("read_fits(): datatype %d not implemented", datatype);
    }
    
    // create array for pixels
    npix = naxes[0]*naxes[1];
    *image = malloc(npix*spix);
    if(!*image)
        errori(NULL);
    
    // read pixels into array
    fits_read_pix(fptr, datatype, fpixel, npix, NULL, *image, NULL, &status);
    if(status)
        fits_error(filename, status);
    
    // close file again
    fits_close_file(fptr, &status);
    if(status)
        fits_error(filename, status);
}
Пример #21
0
int generateMedianPlane (char *cubepath, char *impath, int iplane,
    int nplane_in, int *startplane, int *endplane, char *errmsg)
{
    struct stat     buf;
    struct FitsHdr  hdr;

    char   str[1024];
    char   cmd[1024];
    
    int    bitpix;
    int    istatus;
    
    int    nhdu, hdutype, hdunum;

    
    long    nelements;
    
    int    naxis3;
    int    l;
    int    i;
    int    j;
    int    jj;

    int    nullcnt;
    
    int    splane;
    int    eplane;
    int    nplane;
    
    
    int    indx;
    int    indx1;
    int    indx2;

    int    npixel;
    int    midpoint; 

    long   fpixel[4];
    long   fpixelo[4];

    double *fitscubebuf;
    double *outbuf;
    double *fitsbuf1d;
    double *wavebuf;


    fitsfile  *infptr;
    fitsfile  *outfptr;

    
    int    debugfile = 1;


/*
     Make a NaN value to use setting blank pixels
*/

    union
    {
        double d;
        char   c[8];
    }
    value;

    double nan;

    for(i=0; i<8; ++i)
        value.c[i] = 255;

    nan = value.d;


    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "\nEnter generateMedianPlane: cubepath= [%s]\n", 
            cubepath);
        fprintf (fp_debug, "impath= [%s]\n", impath);
        fprintf (fp_debug, "iplane= [%d]\n", iplane);
        fprintf (fp_debug, "nplane_in= [%d]\n", nplane_in);
        fflush (fp_debug);
    }

    nplane = nplane_in;

    splane = iplane - nplane/2;
    eplane = splane + nplane - 1;

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "splane= [%d] eplane= [%d]\n", splane, eplane);
        fflush (fp_debug);
    }


/*
    Open input fits cube 
*/
    istatus = 0;
    if (fits_open_file (&infptr, cubepath, READONLY, &istatus)) {

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "istatus= [%d]\n", istatus);
            fflush (fp_debug);
        }

        sprintf (errmsg, "Failed to open FITS file [%s]\n", cubepath);
        return (-1);
    } 


    hdunum = 1; 
    nhdu = 0;
    istatus = 0;
    istatus = fits_get_num_hdus (infptr, &nhdu, &istatus);
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, 
            "returned fits_get_hdu_num: istatus= [%d] nhdu= [%d]\n",
            istatus, nhdu);
        fflush (fp_debug);
    }

    if (hdunum > nhdu) {

        sprintf (errmsg, "fname [%s] doesn't contain any HDU", cubepath);
        return (-1);
    }


/*
    Read fits keywords from the first HDU
*/
    hdutype = 0;
    istatus = 0;
    istatus = fits_movabs_hdu (infptr, hdunum, &hdutype, &istatus);

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, 
            "returned fits_movabs_hdu: istatus= [%d] hdutype= [%d]\n",
            istatus, hdutype);
        fflush (fp_debug);
    }

/*
    Read fits keywords
*/
    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "simple", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword SIMPLE not found in fits header");
        return (-1);
    }
   
    if ((strcmp (str, "T") != 0) && (strcmp (str, "F") != 0)) {
        sprintf (errmsg, "keyword SIMPLE must be T or F");
        return (-1);
    }

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "bitpix", str, (char *)NULL, 
        &istatus);
    
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword BITPIX not found in fits header");
        return (-1);
    }
  
    istatus = str2Integer (str, &bitpix, errmsg);
    if (istatus != 0) {
        sprintf (errmsg, "keyword BITPIX must be an integer");
        return (-1);
    }

    if ((bitpix != 8) &&
        (bitpix != 16) &&
        (bitpix != 32) &&
        (bitpix != 64) &&
        (bitpix != -32) &&
        (bitpix != -64)) {
        
        sprintf (errmsg, 
            "keyword BITPIX value must be 8, 16, 32, 64, -32, -64");
        return (-1);
    }

    hdr.bitpix = bitpix;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis", str, (char *)NULL, 
        &istatus);
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }
    istatus = str2Integer (str, &hdr.naxis, errmsg);
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis to integer");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "naxis= [%d]\n", hdr.naxis);
        fflush (fp_debug);
    }


    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis1", str, (char *)NULL, 
        &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis1 not found in fits header");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.ns, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis1 string to integer");
        return (-1);
    }
    hdr.naxes[0] = hdr.ns;

    istatus = 0;
    istatus = fits_read_key (infptr, TSTRING, "naxis2", str, 
        (char *)NULL, &istatus);
        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", istatus);
        fflush (fp_debug);
    }
        
    if (istatus == KEY_NO_EXIST) {
        sprintf (errmsg, "keyword naxis2 not found in fits header");
        return (-1);
    }
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "str= [%s]\n", str);
        fflush (fp_debug);
    }

    istatus = str2Integer (str, &hdr.nl, errmsg);
    
    if (istatus < 0) {
        sprintf (errmsg, "Failed to convert naxis2 string to integer");
        return (-1);
    }
    hdr.naxes[1] = hdr.nl;

    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "ns= [%d] nl= [%d]\n", hdr.ns, hdr.nl);
        fflush (fp_debug);
    }

    hdr.nplane = 1;

    if (hdr.naxis > 2) {
    
        istatus = 0;
        istatus = fits_read_key (infptr, TSTRING, "naxis3", str, 
            (char *)NULL, &istatus);
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "returned fits_read_key: istatus= [%d]\n", 
                istatus);
            fflush (fp_debug);
        }
        
        if (istatus == KEY_NO_EXIST) {
            sprintf (errmsg, "keyword naxis3 not found in fits header");
            return (-1);
        }
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "str= [%s]\n", str);
            fflush (fp_debug);
        }

        istatus = str2Integer (str, &hdr.naxes[2], errmsg);
    
        if (istatus < 0) {
            sprintf (errmsg, "Failed to convert naxis3 string to integer");
            return (-1);
        }
        hdr.nplane = hdr.naxes[2];
    
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
            fprintf (fp_debug, "naxes[2]= [%d]\n", hdr.naxes[2]);
            fflush (fp_debug);
        }
    }
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "hdr.nplane= [%d]\n", hdr.nplane);
        fflush (fp_debug);
    }


    if (splane < 1)
        splane = 1;
    
    if (eplane > hdr.nplane)
        eplane = hdr.nplane;

    nplane = eplane - splane + 1;

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        
        fprintf (fp_debug, "hdr.nplane= [%d]\n", hdr.nplane);
        fprintf (fp_debug, "splane= [%d] eplane= [%d]\n", splane, eplane);
        fprintf (fp_debug, "nplane= [%d]\n", nplane);
        fflush (fp_debug);
    }


/*
    malloc arrays for reading data
*/
    fitscubebuf  
    = (double *)malloc(hdr.ns*hdr.nl*nplane*sizeof(double));
    
    outbuf  = (double *)malloc(hdr.ns*hdr.nl*sizeof(double));
    
    wavebuf  = (double *)malloc(nplane*sizeof(double));
    
    fitsbuf1d  = (double *)malloc(hdr.ns*sizeof(double));

    nelements = hdr.ns;

    npixel = hdr.ns*hdr.nl;
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "npixel= [%d]\n", npixel);
        fflush (fp_debug);
    }


/*
    Read cube data to fitscubebuf
*/
    fpixel[0] = 1;
    fpixel[3] = 1;
    
    indx = 0;
    for (l=splane; l<=eplane; l++)
    {
       
        indx2 = hdr.nl*hdr.ns*(l-splane); 

        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "l= [%d]\n", l);
            fflush (fp_debug);
        }


        fpixel[1] = 1;
        fpixel[2] = l;
        
        for (j=0; j<hdr.nl; j++)
        {
            indx1 = hdr.ns*j; 

            if (fits_read_pix (infptr, TDOUBLE, fpixel, nelements, &nan,
                fitsbuf1d, &nullcnt, &istatus)) {
                break;
            }

            for (i=0; i<nelements; i++) {
                
                fitscubebuf[indx2+indx1+i] = fitsbuf1d[i];
                
                if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    
                    if ((i == 30) && (j == 25)) {
                        fprintf (fp_debug, "i=[%d] j=[%d] l=[%d] pixel=[%lf]\n",
                            i, j, l, fitscubebuf[indx2+indx1+i]);
                        fflush (fp_debug);
                    }
                }


            }

            fpixel[1]++;
        }
   }

/*
    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }
*/


/*
    Extract wave axis and compute median values
*/
    midpoint = nplane / 2;
    
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "midpint= [%d]\n", midpoint);
        fflush (fp_debug);
    }

    for (j=0; j<hdr.nl; j++) {
        
        indx1 = hdr.ns*j;

        for (i=0; i<hdr.ns; i++) {
        
            for (l=0; l<nplane; l++) {
                
                indx = npixel*l + indx1 + i;

                wavebuf[l] = fitscubebuf[indx];
                    
                if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    
                    if ((i == 30) && (j == 25)) {
                        fprintf (fp_debug, "i=[%d] j=[%d] l=[%d] pixel=[%lf]\n",
                            i, j, l, wavebuf[l]);
                        fflush (fp_debug);
                    }
                }
            }

            sort (wavebuf, nplane);
                
            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                    
                
                if ((i == 30) && (j == 25)) {
                    
                    fprintf (fp_debug, "after qsort\n");
                    for (l=0; l<nplane; l++) {
                        fprintf (fp_debug, "l=[%d] pixel=[%lf]\n", 
                            l, wavebuf[l]);
                    }
                    fflush (fp_debug);
                }
            }

            outbuf[indx1+i] = wavebuf[midpoint];
            
            if ((debugfile) && (fp_debug != (FILE *)NULL)) {
                if ((i == 30) && (j == 25)) {
                    fprintf (fp_debug, "outbuf= [%lf]\n", outbuf[indx1+i]);
                    fflush (fp_debug);
                }
            }

        }
    }



/*
    Create output fits file
*/
    istatus = stat (impath, &buf);
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "impath exists? : istatus= [%d]\n", istatus);
        fflush (fp_debug); 
    }

    if (istatus >= 0) {
        sprintf (cmd, "unlink %s", impath);
        istatus = system (cmd);
    }        


    istatus = 0;
    if (fits_create_file (&outfptr, impath, &istatus)) {
            
        sprintf (errmsg, "Failed to create output fitsfile [%s]\n", 
            impath);
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
            fflush (fp_debug);
        }
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "outptr created\n");
        fflush (fp_debug);
    }


/* 
    Copy input fits header to output fitsfile
*/
    istatus = 0;
    if (fits_copy_header (infptr, outfptr, &istatus)) {

        strcpy (errmsg, "Failed to copy fitshdr\n");
        
        if ((debugfile) && (fp_debug != (FILE *)NULL)) {
            fprintf (fp_debug, "err: [%s]\n", errmsg);
            fflush (fp_debug);
        }
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "header copied\n");
        fflush (fp_debug);
    }



/*
    Update header keyword NAXIS3
*/
    naxis3 = 1;
    istatus = 0;
    if (fits_update_key_lng(outfptr, "NAXIS3", naxis3, (char *)NULL, 
        &istatus)) {
        
        strcpy (errmsg, "Failed to update keyword NAXIS3\n");
        return (-1);
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "naxis3 updated\n");
        fflush (fp_debug);
    }


/*
    Write to output fitsfile
*/
    nelements = hdr.ns;
    fpixelo[0] = 1;
    fpixelo[1] = 1;
    fpixelo[2] = 1;
    fpixelo[3] = 1;
       
    for (j=0; j<hdr.nl; j++) {
    
        jj = hdr.ns*j;
        for (i=0; i<hdr.ns; i++) {
                
            fitsbuf1d[i] = outbuf[jj+i];
        }

        if (fits_write_pix (outfptr, TDOUBLE, fpixelo, nelements,
             (void *)fitsbuf1d, &istatus)) {

            sprintf (errmsg, "fits write error: l= [%d] j= [%d]\n", l, j);
            return (-1);
        }

        fpixelo[1]++;
    }

        
    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "here2\n");
        fflush (fp_debug);
    }


    istatus = 0;
    if (fits_close_file (infptr, &istatus)) {
        sprintf (errmsg, "Failed to close cubepath [%s]\n", cubepath);
        return (-1); 
    }

    if ((debugfile) && (fp_debug != (FILE *)NULL)) {
        fprintf (fp_debug, "here3\n");
        fflush (fp_debug);
    }


    istatus = 0;
    if (fits_close_file (outfptr, &istatus)) {
        sprintf (errmsg, "Failed to close impath [%s]\n", impath);
        return (-1); 
    }

    *startplane = splane;
    *endplane = eplane;


    return (0);
}
Пример #22
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;
}
Пример #23
0
int main(int argc, char *argv[])
{
	fitsfile *afptr, *outfptr;  /* FITS file pointers */
	int status = 0;  /* CFITSIO status value MUST be initialized to zero! */
	int anaxis, check = 1, keytype;
	long npixels = 1, firstpix[3] = {1,1,1};
	long anaxes[3] = {1,1,1};
	double *apix;
	char card[FLEN_CARD];

	if (argc != 3) { 
		printf("Usage: tofitsbp16 inimage outimage \n");
		printf("\n");
		printf("Compiled from cfitsio v2.460\n");
		printf("\n");
		printf("Converts a FITS from BITPIX = -32 to BITPIX = 16\n");
		printf("\n");
		printf("Example: \n");
		printf("  tofitsbp16 in.fit out.fits.\n");
		return(0);
	}

	fits_open_file(&afptr, argv[1], READONLY, &status); /* open input images */

	fits_get_img_dim(afptr, &anaxis, &status);  /* read dimensions */
	fits_get_img_size(afptr, 3, anaxes, &status);

	if (status) {
		fits_report_error(stderr, status); /* print error message */
		return(status);
	}

	/* create the new empty output file if the above checks are OK */
	if (check && !fits_create_file(&outfptr, argv[2], &status) )
	{
		/* copy all the header keywords from first image to new output file */
		fits_copy_header(afptr, outfptr, &status);

		/* change to 16 bit integer variable */
		fits_modify_key_lng (outfptr, "BITPIX", 16, "&", &status );

		npixels = anaxes[0];  /* no. of pixels to read in each row */
		apix = (double *) malloc(npixels * sizeof(double)); /* mem for 1 row */

		if (apix == NULL) {
			printf("Memory allocation error\n");
			return(1);
		}

		/* loop over all planes of the cube (2D images have 1 plane) */
		for (firstpix[2] = 1; firstpix[2] <= anaxes[2]; firstpix[2]++)
		{
			/* loop over all rows of the plane */
			for (firstpix[1] = 1; firstpix[1] <= anaxes[1]; firstpix[1]++)
			{
				/* Read both images as doubles, regardless of actual datatype.  */
				/* Give starting pixel coordinate and no. of pixels to read.    */
				/* This version does not support undefined pixels in the image. */
				if (fits_read_pix(afptr, TDOUBLE, firstpix, npixels, NULL, apix,
					NULL, &status)  )
					break;   /* jump out of loop on error */

				fits_write_pix(outfptr, TDOUBLE, firstpix, npixels,
					apix, &status); /* write new values to output image */
			}
		}    /* end of loop over planes */

		fits_close_file(outfptr, &status);
		free(apix);
	}

	fits_close_file(afptr, &status);
	 
	if (status) fits_report_error(stderr, status); /* print any error message */
		return(status);
}
Пример #24
0
struct mShrinkReturn *mShrink(char *input_file, int hduin, char *output_file, double shrinkFactor, int fixedSize, int debug)
{
   int       i, j, ii, jj, status, bufrow,  split;
   int       ibuffer, jbuffer, ifactor, nbuf, nullcnt, k, l, imin, imax, jmin, jmax;
   long      fpixel[4], fpixelo[4], nelements, nelementso;
   double    obegin, oend;
   double   *colfact, *rowfact;
   double   *buffer;
   double    xfactor, flux, area;

   double   *outdata;
   double  **indata;

   struct mShrinkReturn *returnStruct;


   /************************************************/
   /* Make a NaN value to use setting blank pixels */
   /************************************************/

   union
   {
      double d;
      char   c[8];
   }
   value;

   double nan;

   for(i=0; i<8; ++i)
      value.c[i] = 255;

   nan = value.d;



   /*******************************/
   /* Initialize return structure */
   /**n****************************/

   returnStruct = (struct mShrinkReturn *)malloc(sizeof(struct mShrinkReturn));

   bzero((void *)returnStruct, sizeof(returnStruct));


   returnStruct->status = 1;

   strcpy(returnStruct->msg, "");


   /***************************************/
   /* Process the command-line parameters */
   /***************************************/

   time(&currtime);
   start = currtime;

   hdu = hduin;

   xfactor = shrinkFactor;
   
   if(!fixedSize)
   {
      ifactor = ceil(xfactor);

      if((double)ifactor < xfactor)
         xfactor += 2;
   }

   if(xfactor <= 0)
   {
      if(fixedSize)
         mShrink_printError("Requested image size must be positive");
      else
         mShrink_printError("Shrink factor must be positive");

      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(debug >= 1)
   {
      printf("input_file       = [%s]\n", input_file);
      printf("output_file      = [%s]\n", output_file);
      printf("xfactor          = %-g\n",  xfactor);
      printf("ifactor          = %d\n",   ifactor);
      fflush(stdout);
   }


   /************************/
   /* Read the input image */
   /************************/

   if(mShrink_readFits(input_file))
   {
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   // Error if we are trying to shrink to less than one pixel

   if(!fixedSize
   && (   shrinkFactor > input.naxes[0]
       || shrinkFactor > input.naxes[1]))
   {
      mShrink_printError("Trying to shrink image to smaller than one pixel");
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   if(debug >= 1)
   {
      printf("\nflux file            =  %s\n",  input_file);
      printf("input.bitpix         =  %ld\n",   input.bitpix);
      printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
      printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);

      if(haveCtype)   printf("input.ctype1         =  %s\n",    input.ctype1);
      if(haveCtype)   printf("input.typel2         =  %s\n",    input.ctype2);
      if(haveCrval)   printf("input.crval1         =  %-g\n",   input.crval1);
      if(haveCrval)   printf("input.crval2         =  %-g\n",   input.crval2);
      if(haveCrpix)   printf("input.crpix1         =  %-g\n",   input.crpix1);
      if(haveCrpix)   printf("input.crpix2         =  %-g\n",   input.crpix2);
      if(haveCnpix)   printf("input.cnpix1         =  %-g\n",   input.cnpix1);
      if(haveCnpix)   printf("input.cnpix2         =  %-g\n",   input.cnpix2);
      if(havePixelsz) printf("input.xpixelsz       =  %-g\n",   input.xpixelsz);
      if(havePixelsz) printf("input.ypixelsz       =  %-g\n",   input.ypixelsz);
      if(havePP)      printf("input.ppo3           =  %-g\n",   input.ppo3);
      if(havePP)      printf("input.ppo6           =  %-g\n",   input.ppo6);
      if(haveCdelt)   printf("input.cdelt1         =  %-g\n",   input.cdelt1);
      if(haveCdelt)   printf("input.cdelt2         =  %-g\n",   input.cdelt2);
      if(haveCrota2)  printf("input.crota2         =  %-g\n",   input.crota2);
      if(haveCD11)    printf("input.cd11           =  %-g\n",   input.cd11);
      if(haveCD12)    printf("input.cd12           =  %-g\n",   input.cd12);
      if(haveCD21)    printf("input.cd21           =  %-g\n",   input.cd21);
      if(haveCD22)    printf("input.cd22           =  %-g\n",   input.cd22);
      if(havePC11)    printf("input.pc11           =  %-g\n",   input.pc11);
      if(havePC12)    printf("input.pc12           =  %-g\n",   input.pc12);
      if(havePC21)    printf("input.pc21           =  %-g\n",   input.pc21);
      if(havePC22)    printf("input.pc22           =  %-g\n",   input.pc22);
      if(haveEpoch)   printf("input.epoch          =  %-g\n",   input.epoch);
      if(haveEquinox) printf("input.equinox        =  %-g\n",   input.equinox);
      if(haveBunit)   printf("input.bunit          =  %s\n",    input.bunit);
      if(haveBlank)   printf("input.blank          =  %ld\n",   input.blank);
      printf("\n");

      fflush(stdout);
   }


   /***********************************************/
   /* If we are going for a fixed size, the scale */
   /* factor needs to be computed.                */
   /***********************************************/

   if(fixedSize)
   {
      if(input.naxes[0] > input.naxes[1])
         xfactor = (double)input.naxes[0]/(int)xfactor;
      else
         xfactor = (double)input.naxes[1]/(int)xfactor;

      ifactor = ceil(xfactor);

      if((double)ifactor < xfactor)
         xfactor += 2;

      if(debug >= 1)
      {
         printf("xfactor         -> %-g\n",  xfactor);
         printf("ifactor         -> %d\n",   ifactor);
         fflush(stdout);
      }
   }

   /***********************************************/
   /* Compute all the parameters for the shrunken */
   /* output file.                                */
   /***********************************************/

   output.naxes[0] = floor((double)input.naxes[0]/xfactor);
   output.naxes[1] = floor((double)input.naxes[1]/xfactor);
   
   if(debug >= 1)
   {
      printf("output.naxes[0] = %ld\n",  output.naxes[0]);
      printf("output.naxes[1] = %ld\n",  output.naxes[1]);
      fflush(stdout);
   }

   strcpy(output.ctype1, input.ctype1);
   strcpy(output.ctype2, input.ctype2);

   output.crval1   = input.crval1;
   output.crval2   = input.crval2;
   output.crpix1   = (input.crpix1-0.5)/xfactor + 0.5;
   output.crpix2   = (input.crpix2-0.5)/xfactor + 0.5;
   output.cdelt1   = input.cdelt1*xfactor;
   output.cdelt2   = input.cdelt2*xfactor;
   output.crota2   = input.crota2;
   output.cd11     = input.cd11*xfactor;
   output.cd12     = input.cd12*xfactor;
   output.cd21     = input.cd21*xfactor;
   output.cd22     = input.cd22*xfactor;
   output.pc11     = input.pc11;
   output.pc12     = input.pc12;
   output.pc21     = input.pc21;
   output.pc22     = input.pc22;
   output.epoch    = input.epoch;
   output.equinox  = input.equinox;

   strcpy(output.bunit, input.bunit);

   if(haveCnpix)
   {
      input.crpix1    = input.ppo3 / input.xpixelsz - input.cnpix1 + 0.5; 
      input.crpix2    = input.ppo6 / input.ypixelsz - input.cnpix2 + 0.5; 

      output.crpix1   = (input.crpix1-0.5)/xfactor + 0.5;
      output.crpix2   = (input.crpix2-0.5)/xfactor + 0.5;

      output.xpixelsz = input.xpixelsz * xfactor;
      output.ypixelsz = input.ypixelsz * xfactor;

      output.cnpix1   = input.ppo3 / output.xpixelsz - output.crpix1 + 0.5;
      output.cnpix2   = input.ppo6 / output.ypixelsz - output.crpix2 + 0.5;
   }


   /********************************/
   /* Create the output FITS files */
   /********************************/

   status = 0;

   remove(output_file);               

   if(fits_create_file(&output.fptr, output_file, &status)) 
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   /******************************************************/
   /* Create the FITS image.  Copy over the whole header */
   /******************************************************/

   if(fits_copy_header(input.fptr, output.fptr, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(debug >= 1)
   {
      printf("\nFITS header copied to output\n"); 
      fflush(stdout);
   }


   /************************************/
   /* Reset all the WCS header kewords */
   /************************************/

   if(fits_update_key_lng(output.fptr, "NAXIS", 2,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(fits_update_key_lng(output.fptr, "NAXIS1", output.naxes[0],
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(fits_update_key_lng(output.fptr, "NAXIS2", output.naxes[1],
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveBunit && fits_update_key_str(output.fptr, "BUNIT", output.bunit,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveBlank && fits_update_key_lng(output.fptr, "BLANK", output.blank,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCtype && fits_update_key_str(output.fptr, "CTYPE1", output.ctype1,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCtype && fits_update_key_str(output.fptr, "CTYPE2", output.ctype2,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrval && fits_update_key_dbl(output.fptr, "CRVAL1", output.crval1, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrval && fits_update_key_dbl(output.fptr, "CRVAL2", output.crval2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrpix && fits_update_key_dbl(output.fptr, "CRPIX1", output.crpix1, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrpix && fits_update_key_dbl(output.fptr, "CRPIX2", output.crpix2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCnpix && fits_update_key_dbl(output.fptr, "CNPIX1", output.cnpix1, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCnpix && fits_update_key_dbl(output.fptr, "CNPIX2", output.cnpix2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePixelsz && fits_update_key_dbl(output.fptr, "XPIXELSZ", output.xpixelsz, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePixelsz && fits_update_key_dbl(output.fptr, "YPIXELSZ", output.ypixelsz, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCdelt && fits_update_key_dbl(output.fptr, "CDELT1", output.cdelt1, -14,
                                     (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCdelt && fits_update_key_dbl(output.fptr, "CDELT2", output.cdelt2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCrota2 && fits_update_key_dbl(output.fptr, "CROTA2", output.crota2, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD11 && fits_update_key_dbl(output.fptr, "CD1_1", output.cd11, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD12 && fits_update_key_dbl(output.fptr, "CD1_2", output.cd12, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD21 && fits_update_key_dbl(output.fptr, "CD2_1", output.cd21, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveCD22 && fits_update_key_dbl(output.fptr, "CD2_2", output.cd22, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC11 && fits_update_key_dbl(output.fptr, "PC1_1", output.pc11, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC12 && fits_update_key_dbl(output.fptr, "PC1_2", output.pc12, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC21 && fits_update_key_dbl(output.fptr, "PC2_1", output.pc21, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(havePC22 && fits_update_key_dbl(output.fptr, "PC2_2", output.pc22, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveEpoch && fits_update_key_dbl(output.fptr, "EPOCH", output.epoch, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(haveEquinox && fits_update_key_dbl(output.fptr, "EQUINOX", output.equinox, -14,
                                  (char *)NULL, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }


   if(debug >= 1)
   {
      printf("Output header keywords set\n\n");
      fflush(stdout);
   }



   /***********************************************/ 
   /* Allocate memory for a line of output pixels */ 
   /***********************************************/ 

   outdata = (double *)malloc(output.naxes[0] * sizeof(double));


   /*************************************************************************/ 
   /* We could probably come up with logic that would work for both scale   */
   /* factors of less than one and greater than one but the it would be too */
   /* hard to follow.  Instead, we put in a big switch here to deal with    */
   /* the two cases separately.                                             */
   /*************************************************************************/ 

   if(xfactor < 1.)
   {
      /************************************************/ 
      /* Allocate memory for "ifactor" lines of input */ 
      /************************************************/ 

      nbuf = 2;

      indata = (double **)malloc(nbuf * sizeof(double *));

      for(j=0; j<nbuf; ++j)
         indata[j] = (double *)malloc((input.naxes[0]+1) * sizeof(double));


      /**********************************************************/
      /* Create the output array by processing the input pixels */
      /**********************************************************/

      ibuffer = 0;

      buffer  = (double *)malloc(input.naxes[0] * sizeof(double));
      colfact = (double *)malloc(nbuf * sizeof(double));
      rowfact = (double *)malloc(nbuf * sizeof(double));

      fpixel[0] = 1;
      fpixel[1] = 1;
      fpixel[2] = 1;
      fpixel[3] = 1;

      fpixelo[0] = 1;
      fpixelo[1] = 1;

      nelements = input.naxes[0];

      status = 0;


      /******************************/
      /* Loop over the output lines */
      /******************************/

      split = 0;

      for(l=0; l<output.naxes[1]; ++l)
      {
         obegin = (fpixelo[1] - 1.) * xfactor;
         oend   =  fpixelo[1] * xfactor;

         if(floor(oend) == oend)
            oend = obegin;

         if(debug >= 2)
         {
            printf("OUTPUT row %d: obegin = %.2f -> oend = %.3f\n\n", l, obegin, oend);
            fflush(stdout);
         }

         rowfact[0] = 1.;
         rowfact[1] = 0.;


         /******************************************/
         /* If we have gone over into the next row */
         /******************************************/

         if(l == 0 || (int)oend > (int)obegin)
         {
            rowfact[0] = 1.;
            rowfact[1] = 0.;

            if(l > 0)
            {
               split = 1;

               jbuffer = (ibuffer + 1) % nbuf;

               rowfact[1] = (oend - (int)(fpixelo[1] * xfactor))/xfactor;
               rowfact[0] = 1. - rowfact[1];
            }
            else
            {
               jbuffer = 0;
            }

            if(debug >= 2)
            {
               printf("Reading input image row %5ld  (ibuffer %d)\n", fpixel[1], jbuffer);
               fflush(stdout);
            }

            if(debug >= 2)
            {
               printf("Rowfact:  %-g %-g\n", rowfact[0], rowfact[1]);
               fflush(stdout);
            }


            /***********************************/
            /* Read a line from the input file */
            /***********************************/

            if(fpixel[1] <= input.naxes[1])
            {
               if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, &nan,
                                buffer, &nullcnt, &status))
               {
                  mShrink_printFitsError(status);
                  strcpy(returnStruct->msg, montage_msgstr);
                  return returnStruct;
               }
            }
            
            ++fpixel[1];


            /************************/
            /* For each input pixel */
            /************************/

            indata[jbuffer][input.naxes[0]] = nan;

            for (i=0; i<input.naxes[0]; ++i)
            {
               indata[jbuffer][i] = buffer[i];

               if(debug >= 4)
               {
                  printf("input: line %5ld / pixel %5d: indata[%d][%d] = %10.3e\n",
                     fpixel[1]-2, i, jbuffer, i, indata[jbuffer][i]);
                  fflush(stdout);
               }
            }

            if(debug >= 4)
            {
               printf("---\n");
               fflush(stdout);
            }
         }


         /*************************************/
         /* Write out the next line of output */
         /*************************************/

         nelementso = output.naxes[0];

         for(k=0; k<nelementso; ++k)
         {
            /* When "expanding" we never need to use more than two   */
            /* pixels in more than two rows.  The row factors were   */
            /* computed above and the column factors will be compute */
            /* here as we go.                                        */

            outdata[k] = nan;

            colfact[0] = 1.;
            colfact[1] = 0.;

            obegin =  (double)k     * xfactor;
            oend   = ((double)k+1.) * xfactor;

            if(floor(oend) == oend)
               oend = obegin;

            imin = (int)obegin;

            if((int)oend > (int)obegin)
            {
               colfact[1] = (oend - (int)(((double)k+1.) * xfactor))/xfactor;
               colfact[0] = 1. - colfact[1];
            }

            flux = 0;
            area = 0;

            for(jj=0; jj<2; ++jj)
            {
               if(rowfact[jj] == 0.)
                  continue;

               for(ii=0; ii<2; ++ii)
               {
                  bufrow = (ibuffer + jj) % nbuf;

                  if(!mNaN(indata[bufrow][imin+ii]) && colfact[ii] > 0.)
                  {
                     flux += indata[bufrow][imin+ii] * colfact[ii] * rowfact[jj];
                     area += colfact[ii] * rowfact[jj];

                     if(debug >= 3)
                     {
                        printf("output[%d][%d] -> %10.2e (area: %10.2e) (using indata[%d][%d] = %10.2e, colfact[%d] = %5.3f, rowfact[%d] = %5.3f)\n", 
                           l, k, flux, area,
                           bufrow, imin+ii, indata[bufrow][imin+ii], 
                           imin+ii, colfact[ii],
                           jj, rowfact[jj]);

                        fflush(stdout);
                     }
                  }
               }
            }

            if(area > 0.)
               outdata[k] = flux/area;
            else
               outdata[k] = nan;

            if(debug >= 3)
            {
               printf("\nflux[%d] = %-g / area = %-g --> outdata[%d] = %-g\n",
                  k, flux, area, k, outdata[k]);
               
               printf("---\n");
               fflush(stdout);
            }
         }

         if(fpixelo[1] <= output.naxes[1])
         {
            if(debug >= 2)
            {
               printf("\nWRITE output image row %5ld\n===========================================\n", fpixelo[1]);
               fflush(stdout);
            }

            if (fits_write_pix(output.fptr, TDOUBLE, fpixelo, nelementso, 
                               (void *)(outdata), &status))
            {
               mShrink_printFitsError(status);
               strcpy(returnStruct->msg, montage_msgstr);
               return returnStruct;
            }
         }

         ++fpixelo[1];

         if(split)
         {
            ibuffer = jbuffer;
            split = 0;
         }


         /***************************************************************/
         /* Special case:  The expansion factor is integral and we have */
         /* gotten to the point where we need the next line.            */
         /***************************************************************/

         oend   =  fpixelo[1] * xfactor;

         if(fpixel[1] <= input.naxes[1] && floor(oend) == oend)
         {
            if(debug >= 2)
            {
               printf("Reading input image row %5ld  (ibuffer %d)\n", fpixel[1], jbuffer);
               fflush(stdout);
            }

            if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, &nan,
                             buffer, &nullcnt, &status))
            {
               mShrink_printFitsError(status);
               strcpy(returnStruct->msg, montage_msgstr);
               return returnStruct;
            }
            
            ++fpixel[1];

            indata[jbuffer][input.naxes[0]] = nan;

            for (i=0; i<input.naxes[0]; ++i)
            {
               indata[jbuffer][i] = buffer[i];

               if(debug >= 4)
               {
                  printf("input: line %5ld / pixel %5d: indata[%d][%d] = %10.3e\n",
                     fpixel[1]-2, i, jbuffer, i, indata[jbuffer][i]);
                  fflush(stdout);
               }
            }

            if(debug >= 4)
            {
               printf("---\n");
               fflush(stdout);
            }
         }
      }
   }
   else
   {
      /************************************************/ 
      /* Allocate memory for "ifactor" lines of input */ 
      /************************************************/ 

      nbuf = ifactor + 1;

      indata = (double **)malloc(nbuf * sizeof(double *));

      for(j=0; j<nbuf; ++j)
         indata[j] = (double *)malloc(input.naxes[0] * sizeof(double));



      /**********************************************************/
      /* Create the output array by processing the input pixels */
      /**********************************************************/

      ibuffer = 0;

      buffer  = (double *)malloc(input.naxes[0] * sizeof(double));
      colfact = (double *)malloc(input.naxes[0] * sizeof(double));
      rowfact = (double *)malloc(input.naxes[1] * sizeof(double));

      fpixel[0] = 1;
      fpixel[1] = 1;
      fpixel[2] = 1;
      fpixel[3] = 1;

      fpixelo[0] = 1;
      fpixelo[1] = 1;

      nelements = input.naxes[0];

      status = 0;


      /*****************************/
      /* Loop over the input lines */
      /*****************************/

      l = 0;

      obegin =  (double)l     * xfactor;
      oend   = ((double)l+1.) * xfactor;

      jmin = floor(obegin);
      jmax = ceil (oend);

      for(jj=jmin; jj<=jmax; ++jj)
      {
         rowfact[jj-jmin] = 1.;

              if(jj <= obegin && jj+1 <= oend) rowfact[jj-jmin] = jj+1. - obegin;
         else if(jj <= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - obegin;
         else if(jj >= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - jj;

         if(rowfact[jj-jmin] < 0.)
            rowfact[jj-jmin] = 0.;

         if(debug >= 4)
         {
            printf("rowfact[%d]  %-g\n", jj, rowfact[jj]);
            fflush(stdout);
         }
      }

      for (j=0; j<input.naxes[1]; ++j)
      {
         if(debug >= 2)
         {
            printf("Reading input image row %5ld  (ibuffer %d)\n", fpixel[1], ibuffer);
            fflush(stdout);
         }


         /***********************************/
         /* Read a line from the input file */
         /***********************************/

         if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, &nan,
                          buffer, &nullcnt, &status))
         {
            mShrink_printFitsError(status);
            strcpy(returnStruct->msg, montage_msgstr);
            return returnStruct;
         }
         
         ++fpixel[1];

         /************************/
         /* For each input pixel */
         /************************/

         for (i=0; i<input.naxes[0]; ++i)
         {
            indata[ibuffer][i] = buffer[i];

            if(debug >= 4)
            {
               printf("input: line %5d / pixel %5d: indata[%d][%d] = %10.2e\n",
                  j, i, ibuffer, i, indata[ibuffer][i]);
               fflush(stdout);
            }
         }

         if(debug >= 4)
         {
            printf("---\n");
            fflush(stdout);
         }


         /**************************************************/
         /* If we have enough for the next line of output, */
         /* compute and write it                           */
         /**************************************************/

         if(j == jmax || fpixel[1] == input.naxes[1])
         {
            nelementso = output.naxes[0];

            for(k=0; k<nelementso; ++k)
            {
               /* OK, we are trying to determine the correct flux   */
               /* for output pixel k in output line l.  We have all */
               /* the input lines we need (modulo looping back from */
               /* indata[ibuffer])                                  */

               outdata[k] = nan;

               obegin =  (double)k     * xfactor;
               oend   = ((double)k+1.) * xfactor;

               imin = floor(obegin);
               imax = ceil (oend);

               if(debug >= 3)
               {
                  printf("\nimin = %4d, imax = %4d, jmin = %4d, jmax = %4d\n", imin, imax, jmin, jmax);
                  fflush(stdout);
               }

               flux = 0;
               area = 0;

               for(ii=imin; ii<=imax; ++ii)
               {
                  colfact[ii-imin] = 1.;

                       if(ii <= obegin && ii+1 <= oend) colfact[ii-imin] = ii+1. - obegin;
                  else if(ii <= obegin && ii+1 >= oend) colfact[ii-imin] = oend - obegin;
                  else if(ii >= obegin && ii+1 >= oend) colfact[ii-imin] = oend - ii;

                  if(colfact[ii-imin] < 0.)
                     colfact[ii-imin] = 0.;
               }

               for(jj=jmin; jj<=jmax; ++jj)
               {
                  if(rowfact[jj-jmin] == 0.)
                     continue;

                  for(ii=imin; ii<=imax; ++ii)
                  {
                     bufrow = (ibuffer - jmax + jj + nbuf) % nbuf;

                     if(!mNaN(indata[bufrow][ii]) && colfact[ii-imin] > 0.)
                     {
                        flux += indata[bufrow][ii] * colfact[ii-imin] * rowfact[jj-jmin];
                        area += colfact[ii-imin] * rowfact[jj-jmin];

                        if(debug >= 3)
                        {
                           printf("output[%d][%d] -> %10.2e (area: %10.2e) (using indata[%d][%d] = %10.2e, colfact[%d-%d] = %5.3f, rowfact[%d-%d] = %5.3f)\n", 
                              l, k, flux, area,
                              bufrow, ii, indata[bufrow][ii], 
                              ii, imin, colfact[ii-imin],
                              jj, jmin, rowfact[jj-jmin]);

                           fflush(stdout);
                        }
                     }
                  }

                  if(debug >= 3)
                  {
                     printf("---\n");
                     fflush(stdout);
                  }
               }

               if(area > 0.)
                  outdata[k] = flux/area;
               else
                  outdata[k] = nan;

               if(debug >= 3)
               {
                  printf("\nflux = %-g / area = %-g --> outdata[%d] = %-g\n",
                     flux, area, k, outdata[k]);
                  
                  fflush(stdout);
               }
            }

            if(fpixelo[1] <= output.naxes[1])
            {
               if(debug >= 2)
               {
                  printf("\nWRITE output image row %5ld\n===========================================\n", fpixelo[1]);
                  fflush(stdout);
               }

               if (fits_write_pix(output.fptr, TDOUBLE, fpixelo, nelementso, 
                                  (void *)(outdata), &status))
               {
                  mShrink_printFitsError(status);
                  strcpy(returnStruct->msg, montage_msgstr);
                  return returnStruct;
               }
            }

            ++fpixelo[1];

            ++l;

            obegin =  (double)l     * xfactor;
            oend   = ((double)l+1.) * xfactor;

            jmin = floor(obegin);
            jmax = ceil (oend);

            for(jj=jmin; jj<=jmax; ++jj)
            {
               rowfact[jj-jmin] = 1.;

                    if(jj <= obegin && jj+1 <= oend) rowfact[jj-jmin] = jj+1. - obegin;
               else if(jj <= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - obegin;
               else if(jj >= obegin && jj+1 >= oend) rowfact[jj-jmin] = oend - jj;

               if(rowfact[jj-jmin] < 0.)
                  rowfact[jj-jmin] = 0.;

               if(debug >= 4)
               {
                  printf("rowfact[%d-%d] -> %-g\n", jj, jmin, rowfact[jj-jmin]);
                  fflush(stdout);
               }
            }
         }

         ibuffer = (ibuffer + 1) % nbuf;
      }
   }


   /*******************/
   /* Close the files */
   /*******************/

   if(fits_close_file(input.fptr, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(fits_close_file(output.fptr, &status))
   {
      mShrink_printFitsError(status);
      strcpy(returnStruct->msg, montage_msgstr);
      return returnStruct;
   }

   if(debug >= 1)
   {
      printf("FITS data image finalized\n"); 
      fflush(stdout);
   }

   time(&currtime);

   returnStruct->status = 0;

   sprintf(returnStruct->msg,  "time=%.0f",       (double)(currtime - start));
   sprintf(returnStruct->json, "{\"time\"=%.0f}", (double)(currtime - start));

   returnStruct->time = (double)(currtime - start);

   return returnStruct;
}
Пример #25
0
int main(int argc, char **argv)
{
    if (argc < 3) {
        fprintf(stderr,"test-read filename ext\n");
        exit(EXIT_FAILURE);
    }
    fitsfile* fits=NULL;
    struct image *image=NULL;

    const char *fname=argv[1];
    int ext = atoi(argv[2]);

    fprintf(stderr,"reading ext %d from %s\n",ext,fname);

    int status=0;
    if (fits_open_file(&fits, fname, READONLY, &status)) {
        fits_report_error(stderr, status);
        exit(EXIT_FAILURE);
    }

    int hdutype=0;
    if (fits_movabs_hdu(fits, ext+1, &hdutype, &status)) {
        fits_report_error(stderr, status);
        exit(EXIT_FAILURE);
    }


    int maxdim=CFITSIO_MAX_ARRAY_DIMS;
    LONGLONG dims[CFITSIO_MAX_ARRAY_DIMS];
    int bitpix=0, ndims=0;
    if (fits_get_img_paramll(fits, maxdim, &bitpix, &ndims, dims, &status)) {
        fits_report_error(stderr, status);
        exit(EXIT_FAILURE);
    }
    if (ndims != 2) {
        fprintf(stderr,"expected ndims=2, got %d\n", ndims);
        goto _test_read_bail;
    }
    // dims reversed
    fprintf(stderr,"dims: [%lld,%lld]\n", dims[1], dims[2]);

    // note dims are reversed
    image=image_new(dims[1], dims[0]);
    long npix=dims[1]*dims[0];
    long fpixel[2]={1,1};
    if (fits_read_pix(fits, TDOUBLE, fpixel, npix,
                      NULL,image->rows[0], NULL, &status)) {
        fits_report_error(stderr, status);
        exit(EXIT_FAILURE);
    }

    size_t row=0,col=0;

    row=10; col=13;
    fprintf(stderr,"im[%ld,%ld]: %.16g\n",row,col,IM_GET(image,row,col));
    row=10; col=10;
    fprintf(stderr,"im[%ld,%ld]: %.16g\n",row,col,IM_GET(image,row,col));
    row=18; col=24;
    fprintf(stderr,"im[%ld,%ld]: %.16g\n",row,col,IM_GET(image,row,col));


_test_read_bail:
    image=image_free(image);
    if (fits_close_file(fits, &status)) {
        fits_report_error(stderr, status);
        exit(EXIT_FAILURE);
    }
}
Пример #26
0
int main(int argc, char **argv)
{
    int       i, j, c, ifile, status;
    long      fpixel[4], nelements;
    int       nullcnt;
    int       imin, jmin, haveMinMax;
    int       imax, jmax;
    int       istart, iend, ilength;
    int       jstart, jend, jlength;
    double   *buffer, *abuffer;
    double    datamin, datamax;
    double    areamin, areamax;

    int       narea1, narea2;
    double    avearea1, avearea2;
    double    maxarea1, maxarea2;

    double    pixel_value;

    double  **data;
    double  **area;

    char      template_file[MAXSTR];
    char      line         [MAXSTR];

    char      infile[2][MAXSTR];
    char      inarea[2][MAXSTR];


    /*************************************************/
    /* Initialize output FITS basic image parameters */
    /*************************************************/

    int  bitpix = DOUBLE_IMG;
    long naxis  = 2;


    /************************************************/
    /* Make a NaN value to use setting blank pixels */
    /************************************************/

    union
    {
        double d;
        char   c[8];
    }
    value;

    double nan;

    for(i=0; i<8; ++i)
        value.c[i] = 255;

    nan = value.d;



    /***************************************/
    /* Process the command-line parameters */
    /***************************************/

    debug   = 0;
    noAreas = 0;

    coverageLimit = 0.0001;

    opterr = 0;

    fstatus = stdout;

    while ((c = getopt(argc, argv, "nc:d:s:")) != EOF)
    {
        switch (c)
        {
        case 'n':
            noAreas = 1;
            break;

        case 'c':
            coverageLimit = atof(optarg);
            break;

        case 'd':
            debug = debugCheck(optarg);
            break;

        case 's':
            if((fstatus = fopen(optarg, "w+")) == (FILE *)NULL)
            {
                printf("[struct stat=\"ERROR\", msg=\"Cannot open status file: %s\"]\n",
                       optarg);
                exit(1);
            }
            break;

        default:
            printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level] [-n(o-areas)] [-s statusfile] in1.fits in2.fits out.fits hdr.template\"]\n", argv[0]);
            exit(1);
            break;
        }
    }

    if (argc - optind < 4)
    {
        printf("[struct stat=\"ERROR\", msg=\"Usage: %s [-d level] [-n(o-areas)] [-s statusfile] in1.fits in2.fits out.fits hdr.template\"]\n", argv[0]);
        exit(1);
    }

    strcpy(input_file1,   argv[optind]);
    strcpy(input_file2,   argv[optind + 1]);
    strcpy(output_file,   argv[optind + 2]);
    strcpy(template_file, argv[optind + 3]);

    checkHdr(template_file, 1, 0);

    if(strlen(output_file) > 5 &&
            strncmp(output_file+strlen(output_file)-5, ".fits", 5) == 0)
        output_file[strlen(output_file)-5] = '\0';

    strcpy(output_area_file, output_file);
    strcat(output_file,  ".fits");
    strcat(output_area_file, "_area.fits");

    if(debug >= 1)
    {
        printf("input_file1      = [%s]\n", input_file1);
        printf("input_file2      = [%s]\n", input_file2);
        printf("output_file      = [%s]\n", output_file);
        printf("output_area_file = [%s]\n", output_area_file);
        printf("template_file    = [%s]\n", template_file);
        fflush(stdout);
    }


    /****************************/
    /* Get the input file names */
    /****************************/

    if(strlen(input_file1) > 5
            && strcmp(input_file1+strlen(input_file1)-5, ".fits") == 0)
    {
        strcpy(line, input_file1);

        line[strlen(line)-5] = '\0';

        strcpy(infile[0], line);
        strcat(infile[0],  ".fits");
        strcpy(inarea[0], line);
        strcat(inarea[0], "_area.fits");
    }
    else
    {
        strcpy(infile[0], input_file1);
        strcat(infile[0],  ".fits");
        strcpy(inarea[0], input_file1);
        strcat(inarea[0], "_area.fits");
    }


    if(strlen(input_file2) > 5
            && strcmp(input_file2+strlen(input_file2)-5, ".fits") == 0)
    {
        strcpy(line, input_file2);

        line[strlen(line)-5] = '\0';

        strcpy(infile[1], line);
        strcat(infile[1],  ".fits");
        strcpy(inarea[1], line);
        strcat(inarea[1], "_area.fits");
    }
    else
    {
        strcpy(infile[1], input_file2);
        strcat(infile[1],  ".fits");
        strcpy(inarea[1], input_file2);
        strcat(inarea[1], "_area.fits");
    }

    if(debug >= 1)
    {
        printf("\ninput files:\n\n");

        printf("   [%s][%s]\n", infile[0], inarea[0]);
        printf("   [%s][%s]\n", infile[1], inarea[1]);

        printf("\n");
    }


    /*************************************************/
    /* Process the output header template to get the */
    /* image size, coordinate system and projection  */
    /*************************************************/

    readTemplate(template_file);

    if(debug >= 1)
    {
        printf("output.naxes[0] =  %ld\n", output.naxes[0]);
        printf("output.naxes[1] =  %ld\n", output.naxes[1]);
        printf("output.crpix1   =  %-g\n", output.crpix1);
        printf("output.crpix2   =  %-g\n", output.crpix2);
        fflush(stdout);
    }


    /*****************************************************/
    /* We open the two input files briefly to get enough */
    /* information to determine the region of overlap    */
    /* (for memory allocation purposes)                  */
    /*****************************************************/

    readFits(infile[0], inarea[0]);

    imin = output.crpix1 - input.crpix1;
    jmin = output.crpix2 - input.crpix2;

    imax = imin + input.naxes[0];
    jmax = jmin + input.naxes[1];

    istart = imin;
    iend   = imax;

    jstart = jmin;
    jend   = jmax;

    if(debug >= 1)
    {
        printf("\nFile 1:\n");
        printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
        printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
        printf("input.crpix1         =  %-g\n",   input.crpix1);
        printf("input.crpix2         =  %-g\n",   input.crpix2);
        printf("imin                 =  %d\n",    imin);
        printf("imax                 =  %d\n",    imax);
        printf("jmin                 =  %d\n",    jmin);
        printf("jmax                 =  %d\n\n",  jmax);
        printf("istart               =  %d\n",    istart);
        printf("iend                 =  %d\n",    iend);
        printf("jstart               =  %d\n",    jstart);
        printf("jend                 =  %d\n",    jend);

        fflush(stdout);
    }

    status = 0;

    if(fits_close_file(input.fptr, &status))
        printFitsError(status);

    if(!noAreas)
    {
        if(fits_close_file(input_area.fptr, &status))
            printFitsError(status);
    }

    readFits(infile[1], inarea[1]);

    imin = output.crpix1 - input.crpix1;
    jmin = output.crpix2 - input.crpix2;

    imax = imin + input.naxes[0];
    jmax = jmin + input.naxes[1];

    if(debug >= 1)
    {
        printf("\nFile 2:\n");
        printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
        printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
        printf("input.crpix1         =  %-g\n",   input.crpix1);
        printf("input.crpix2         =  %-g\n",   input.crpix2);
        printf("imin                 =  %d\n",    imin);
        printf("imax                 =  %d\n",    imax);
        printf("jmin                 =  %d\n",    jmin);
        printf("jmax                 =  %d\n",    jmax);
        printf("istart               =  %d\n\n",  istart);
        printf("iend                 =  %d\n",    iend);
        printf("jstart               =  %d\n",    jstart);
        printf("jend                 =  %d\n",    jend);
        printf("\n");

        fflush(stdout);
    }

    if(imin > istart) istart = imin;
    if(imax < iend  ) iend   = imax;

    if(jmin > jstart) jstart = jmin;
    if(jmax < jend  ) jend   = jmax;

    if(istart < 0) istart = 0;
    if(jstart < 0) jstart = 0;

    if(iend > output.naxes[0]-1) iend = output.naxes[0]-1;
    if(jend > output.naxes[1]-1) jend = output.naxes[1]-1;

    ilength = iend - istart + 1;
    jlength = jend - jstart + 1;

    if(debug >= 1)
    {
        printf("\nComposite:\n");
        printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
        printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
        printf("input.crpix1         =  %-g\n",   input.crpix1);
        printf("input.crpix2         =  %-g\n",   input.crpix2);
        printf("istart               =  %d\n",    istart);
        printf("iend                 =  %d\n",    iend);
        printf("jstart               =  %d\n",    jstart);
        printf("jend                 =  %d\n",    jend);
        printf("ilength              =  %d\n",    ilength);
        printf("jlength              =  %d\n",    jlength);
        printf("\n");

        fflush(stdout);
    }

    if(fits_close_file(input.fptr, &status))
        printFitsError(status);

    if(!noAreas)
    {
        if(fits_close_file(input_area.fptr, &status))
            printFitsError(status);
    }

    /*********************/
    /* Check for overlap */
    /*********************/

    if(ilength <= 0 || jlength <= 0)
        printError("Images don't overlap");


    /***********************************************/
    /* Allocate memory for the output image pixels */
    /***********************************************/

    data = (double **)malloc(jlength * sizeof(double *));

    for(j=0; j<jlength; ++j)
        data[j] = (double *)malloc(ilength * sizeof(double));

    if(debug >= 1)
    {
        printf("%d bytes allocated for image pixels\n",
               ilength * jlength * sizeof(double));
        fflush(stdout);
    }


    /****************************/
    /* Initialize data to zeros */
    /****************************/

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            data[j][i] = 0.;
        }
    }


    /**********************************************/
    /* Allocate memory for the output pixel areas */
    /**********************************************/

    area = (double **)malloc(jlength * sizeof(double *));

    for(j=0; j<jlength; ++j)
        area[j] = (double *)malloc(ilength * sizeof(double));

    if(debug >= 1)
    {
        printf("%d bytes allocated for pixel areas\n",
               ilength * jlength * sizeof(double));
        fflush(stdout);
    }


    /****************************/
    /* Initialize area to zeros */
    /****************************/

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            area[j][i] = 0.;
        }
    }


    /***************************/
    /* For the two input files */
    /***************************/

    time(&currtime);
    start = currtime;

    avearea1 = 0.;
    avearea2 = 0.;
    maxarea1 = 0.;
    maxarea2 = 0.;
    narea1   = 0.;
    narea2   = 0.;

    for(ifile=0; ifile<2; ++ifile)
    {
        /************************/
        /* Read the input image */
        /************************/

        readFits(infile[ifile], inarea[ifile]);

        imin = output.crpix1 - input.crpix1;
        jmin = output.crpix2 - input.crpix2;

        if(debug >= 1)
        {
            printf("\nflux file            =  %s\n",  infile[ifile]);
            printf("input.naxes[0]       =  %ld\n",   input.naxes[0]);
            printf("input.naxes[1]       =  %ld\n",   input.naxes[1]);
            printf("input.crpix1         =  %-g\n",   input.crpix1);
            printf("input.crpix2         =  %-g\n",   input.crpix2);
            printf("\narea file            =  %s\n",  inarea[ifile]);
            printf("input_area.naxes[0]  =  %ld\n",   input.naxes[0]);
            printf("input_area.naxes[1]  =  %ld\n",   input.naxes[1]);
            printf("input_area.crpix1    =  %-g\n",   input.crpix1);
            printf("input_area.crpix2    =  %-g\n",   input.crpix2);
            printf("\nimin                 =  %d\n",  imin);
            printf("jmin                 =  %d\n\n",  jmin);

            fflush(stdout);
        }


        /**********************************************************/
        /* Create the output array by processing the input pixels */
        /**********************************************************/

        buffer  = (double *)malloc(input.naxes[0] * sizeof(double));
        abuffer = (double *)malloc(input.naxes[0] * sizeof(double));

        fpixel[0] = 1;
        fpixel[1] = 1;
        fpixel[2] = 1;
        fpixel[3] = 1;

        nelements = input.naxes[0];

        status = 0;


        /*****************************/
        /* Loop over the input lines */
        /*****************************/

        for (j=0; j<input.naxes[1]; ++j)
        {
            if(debug >= 2)
            {
                printf("\rProcessing input row %5d  ", j);
                fflush(stdout);
            }


            /***********************************/
            /* Read a line from the input file */
            /***********************************/

            if(fits_read_pix(input.fptr, TDOUBLE, fpixel, nelements, NULL,
                             buffer, &nullcnt, &status))
                printFitsError(status);


            if(noAreas)
            {
                for(i=0; i<input.naxes[0]; ++i)
                    abuffer[i] = 1.;
            }
            else
            {
                if(fits_read_pix(input_area.fptr, TDOUBLE, fpixel, nelements, NULL,
                                 abuffer, &nullcnt, &status))
                    printFitsError(status);
            }

            ++fpixel[1];


            /************************/
            /* For each input pixel */
            /************************/

            for (i=0; i<input.naxes[0]; ++i)
            {
                pixel_value = buffer[i] * abuffer[i];

                if(debug >= 4)
                {
                    printf("input: line %5d / pixel %5d, value = %10.2e (%10.2e) [array: %5d %5d]\n",
                           j, i, buffer[i], abuffer[i], j+jmin-jstart, i+imin-istart);
                    fflush(stdout);
                }

                if(i+imin < istart) continue;
                if(j+jmin < jstart) continue;

                if(i+imin >= iend) continue;
                if(j+jmin >= jend) continue;

                if(debug >= 3)
                {
                    printf("keep: line %5d / pixel %5d, value = %10.2e (%10.2e) [array: %5d %5d]\n",
                           j, i, buffer[i], abuffer[i], j+jmin-jstart, i+imin-istart);
                    fflush(stdout);
                }

                if(ifile == 0)
                {
                    if(mNaN(buffer[i])
                            || abuffer[i] <= 0.)
                    {
                        if(debug >= 5)
                        {
                            printf("First file. Setting data to NaN and area to zero.\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] = nan;
                        area[j+jmin-jstart][i+imin-istart] = 0.;

                        if(debug >= 5)
                        {
                            printf("done.\n");
                            fflush(stdout);
                        }

                        continue;
                    }
                    else
                    {
                        if(debug >= 5)
                        {
                            printf("First file. Setting data to pixel value.\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] = pixel_value;
                        area[j+jmin-jstart][i+imin-istart] = abuffer[i];

                        ++narea1;
                        avearea1 += abuffer[i];

                        if(abuffer[i] > maxarea1)
                            maxarea1 = abuffer[i];

                        if(debug >= 5)
                        {
                            printf("done.\n");
                            fflush(stdout);
                        }

                    }
                }
                else
                {
                    if(mNaN(buffer[i])
                            || abuffer[i] <= 0.
                            || data[j+jmin-jstart][i+imin-istart] == nan
                            || area[j+jmin-jstart][i+imin-istart] == 0.)
                    {
                        if(debug >= 5)
                        {
                            printf("Second file. One or the other value is NaN (or zero area).\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] = nan;
                        area[j+jmin-jstart][i+imin-istart] = 0.;

                        continue;
                    }
                    else
                    {
                        if(debug >= 5)
                        {
                            printf("Second file. Subtracting pixel value.\n");
                            fflush(stdout);
                        }

                        data[j+jmin-jstart][i+imin-istart] -= pixel_value;
                        area[j+jmin-jstart][i+imin-istart] += abuffer[i];

                        ++narea2;
                        avearea2 += abuffer[i];

                        if(abuffer[i] > maxarea2)
                            maxarea2 = abuffer[i];

                        if(debug >= 5)
                        {
                            printf("done.\n");
                            fflush(stdout);
                        }
                    }
                }
            }
        }

        free(buffer);
        free(abuffer);

        if(fits_close_file(input.fptr, &status))
            printFitsError(status);

        if(!noAreas)
        {
            if(fits_close_file(input_area.fptr, &status))
                printFitsError(status);
        }
    }

    if(debug >= 1)
    {
        time(&currtime);
        printf("\nDone reading data (%.0f seconds)\n",
               (double)(currtime - start));
        fflush(stdout);
    }


    /************************************/
    /* Anly keep those pixels that were */
    /* covered twice reasonably fully   */
    /************************************/

    avearea1 = avearea1/narea1;
    avearea2 = avearea2/narea2;

    areamax = maxarea1 + maxarea2;

    if(debug >= 2)
    {
        printf("\npixel areas: %-g + %-g = %-g\n\n", avearea1, avearea2, areamax);
        fflush(stdout);
    }

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            if(mNaN(area[j][i]) || area[j][i] == 0.)
            {
                data[j][i] = 0.;
                area[j][i] = 0.;
            }
            else
            {
                if(fabs(area[j][i] - areamax)/areamax > coverageLimit)
                {
                    data[j][i] = 0.;
                    area[j][i] = 0.;
                }
            }
        }
    }


    /*********************************/
    /* Normalize image data based on */
    /* total area added to pixel     */
    /*********************************/

    haveMinMax = 0;

    datamax = 0.,
    datamin = 0.;
    areamin = 0.;
    areamax = 0.;

    imin = 99999;
    imax = 0;

    jmin = 99999;
    jmax = 0;

    for (j=0; j<jlength; ++j)
    {
        for (i=0; i<ilength; ++i)
        {
            if(area[j][i] > 0.)
            {
                data[j][i] = 2. * data[j][i] / area[j][i];

                if(!haveMinMax)
                {
                    datamin = data[j][i];
                    datamax = data[j][i];
                    areamin = area[j][i];
                    areamax = area[j][i];

                    haveMinMax = 1;
                }

                if(data[j][i] < datamin) datamin = data[j][i];
                if(data[j][i] > datamax) datamax = data[j][i];
                if(area[j][i] < areamin) areamin = area[j][i];
                if(area[j][i] > areamax) areamax = area[j][i];

                if(j < jmin) jmin = j;
                if(j > jmax) jmax = j;
                if(i < imin) imin = i;
                if(i > imax) imax = i;
            }
            else
            {
                data[j][i] = nan;
                area[j][i] = 0.;
            }
        }
    }

    imin += istart;
    jmin += jstart;

    imax += istart;
    jmax += jstart;

    if(debug >= 1)
    {
        printf("Data min = %-g\n", datamin);
        printf("Data max = %-g\n", datamax);
        printf("Area min = %-g\n", areamin);
        printf("Area max = %-g\n\n", areamax);
        printf("j min    = %d\n", jmin);
        printf("j max    = %d\n", jmax);
        printf("i min    = %d\n", imin);
        printf("i max    = %d\n", imax);
    }

    if(jmin > jmax || imin > imax)
        printError("All pixels are blank.");


    /********************************/
    /* Create the output FITS files */
    /********************************/

    remove(output_file);
    remove(output_area_file);

    if(fits_create_file(&output.fptr, output_file, &status))
        printFitsError(status);

    if(fits_create_file(&output_area.fptr, output_area_file, &status))
        printFitsError(status);


    /*********************************************************/
    /* Create the FITS image.  All the required keywords are */
    /* handled automatically.                                */
    /*********************************************************/

    if (fits_create_img(output.fptr, bitpix, naxis, output.naxes, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("\nFITS data image created (not yet populated)\n");
        fflush(stdout);
    }

    if (fits_create_img(output_area.fptr, bitpix, naxis, output_area.naxes, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("FITS area image created (not yet populated)\n");
        fflush(stdout);
    }


    /****************************************/
    /* Set FITS header from a template file */
    /****************************************/

    if(fits_write_key_template(output.fptr, template_file, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("Template keywords written to FITS data image\n");
        fflush(stdout);
    }

    if(fits_write_key_template(output_area.fptr, template_file, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("Template keywords written to FITS area image\n\n");
        fflush(stdout);
    }


    /***************************/
    /* Modify BITPIX to be -64 */
    /***************************/

    if(fits_update_key_lng(output.fptr, "BITPIX", -64,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "BITPIX", -64,
                           (char *)NULL, &status))
        printFitsError(status);


    /***************************************************/
    /* Update NAXIS, NAXIS1, NAXIS2, CRPIX1 and CRPIX2 */
    /***************************************************/

    if(fits_update_key_lng(output.fptr, "NAXIS", 2,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output.fptr, "NAXIS1", imax-imin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output.fptr, "NAXIS2", jmax-jmin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output.fptr, "CRPIX1", output.crpix1-imin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output.fptr, "CRPIX2", output.crpix2-jmin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "NAXIS", 2,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "NAXIS1", imax-imin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_lng(output_area.fptr, "NAXIS2", jmax-jmin+1,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output_area.fptr, "CRPIX1", output.crpix1-imin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(fits_update_key_dbl(output_area.fptr, "CRPIX2", output.crpix2-jmin, -14,
                           (char *)NULL, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("Template keywords BITPIX, CRPIX, and NAXIS updated\n");
        fflush(stdout);
    }


    /************************/
    /* Write the image data */
    /************************/

    fpixel[0] = 1;
    fpixel[1] = 1;
    nelements = imax - imin + 1;

    for(j=jmin; j<=jmax; ++j)
    {
        if (fits_write_pix(output.fptr, TDOUBLE, fpixel, nelements,
                           (void *)(&data[j-jstart][imin-istart]), &status))
            printFitsError(status);

        ++fpixel[1];
    }

    free(data[0]);

    if(debug >= 1)
    {
        printf("Data written to FITS data image\n");
        fflush(stdout);
    }


    /***********************/
    /* Write the area data */
    /***********************/

    fpixel[0] = 1;
    fpixel[1] = 1;
    nelements = imax - imin + 1;

    for(j=jmin; j<=jmax; ++j)
    {
        if (fits_write_pix(output_area.fptr, TDOUBLE, fpixel, nelements,
                           (void *)(&area[j-jstart][imin-istart]), &status))
            printFitsError(status);

        ++fpixel[1];
    }

    free(area[0]);

    if(debug >= 1)
    {
        printf("Data written to FITS area image\n\n");
        fflush(stdout);
    }


    /***********************/
    /* Close the FITS file */
    /***********************/

    if(fits_close_file(output.fptr, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("FITS data image finalized\n");
        fflush(stdout);
    }

    if(fits_close_file(output_area.fptr, &status))
        printFitsError(status);

    if(debug >= 1)
    {
        printf("FITS area image finalized\n\n");
        fflush(stdout);
    }

    if(debug >= 1)
    {
        time(&currtime);
        printf("Done (%.0f seconds total)\n", (double)(currtime - start));
        fflush(stdout);
    }

    fprintf(fstatus, "[struct stat=\"OK\"]\n");
    fflush(stdout);

    exit(0);
}
Пример #27
0
void montage_dataRange(fitsfile *infptr, int *imin, int *imax, int *jmin, int *jmax)
{
   long    fpixel[4];
   long    naxis, naxes[10];
   int     i, j, nullcnt, nfound;
   double *buffer;

   int     status = 0;

   /*************************************************/
   /* Make a NaN value to use checking blank pixels */
   /*************************************************/

   union
   {
      double d;
      char   c[8];
   }
   value;

   double nan;

   for(i=0; i<8; ++i)
      value.c[i] = 255;

   nan = value.d;

   if(fits_read_key_lng(infptr, "NAXIS", &naxis, (char *)NULL, &status))
      montage_printFitsError(status);
   
   if(fits_read_keys_lng(infptr, "NAXIS", 1, naxis, naxes, &nfound, &status))
      montage_printFitsError(status);

   fpixel[0] = 1;
   fpixel[1] = 1;
   fpixel[2] = 1;
   fpixel[3] = 1;

   *imin =  1000000000;
   *imax = -1;
   *jmin =  1000000000;
   *jmax = -1;

   buffer  = (double *)malloc(naxes[0] * sizeof(double));

   for (j=1; j<=naxes[1]; ++j)
   {
      if(debug >= 2)
      {
         printf("Processing image row %5d\n", j);
         fflush(stdout);
      }

      if(fits_read_pix(infptr, TDOUBLE, fpixel, naxes[0], &nan,
                       buffer, &nullcnt, &status))
         montage_printFitsError(status);

      for(i=1; i<=naxes[0]; ++i)
      {
         if(!mNaN(buffer[i-1]))
         {
            if(buffer[i-1] != nan)
            {
               if(i < *imin) *imin = i;
               if(i > *imax) *imax = i;
               if(j < *jmin) *jmin = j;
               if(j > *jmax) *jmax = j;
            }
         }
      }

      ++fpixel [1];
   }

   free(buffer);
}
Пример #28
0
int DoIt(){
 
    /* Variable declarations */

    /* Generic use variables */

    int i,j,k;					/* Generic loop counters */

    /* DRMS/JSOC variables */

	char *harpnum,*time_range;					/* SHARPs ID and time range from module_args[] */
	char *drms_query;							/* The DRMS query we are going to send */
	double umb_sig, pen_sig;					/* Cutoffs for sunspots */
	int num_query_chars;						/* Number of characters in total query for malloc definition */
	CmdParams_t *params=&cmdparams;				/* For the module_args stuff */
	DRMS_RecordSet_t *drms_ids;					/* Holds the id structure of the records */
	DRMS_Record_t *drms_record;					/* Holds specific record information */
	DRMS_Segment_t *drms_segment;				/* Segment information */
	int drms_status;							/* Status variable */
	int num_records;							/* Number of records and variables to get the segment locations we need */
	
	/* cfitsio-related variables */

    fitsfile *c_ptr,*i_ptr;				/* Pointers for FITS files */
    int c_status, i_status;				/* Status checker for opening files */
    int hdu_pos,num_hdus;				/* HDU number and location */
    int needed_hdu;						/* The HDU we want to be on */
    int any_nulls;						/* Nonzero if there are null values in data */
    char i_filename[DRMS_MAXPATHLEN+1],c_filename[DRMS_MAXPATHLEN+1];	/* Containers for the filenames */
    double nulval;							/* Container for what null values in data should be set to */
	

    /* Needed FITS keywords */

    int naxis1,naxis2,naxis;			/* Length of axes */
    double crpix1,crpix2;				/* SHARPs CRPIX is the center of the sun relative to the lower left (fortran: 1,1) of patch */
    double cdelt1		;				/* HMI pixel sizes in as */
    double rsun_obs;					/* Radius of the sun, observed at t_obs */
    double blank;						/* Values of bad data */
    TIME t_obs;							/* Observation time, ZULU */
    char **t_obs_s;						/* String version of observation time */
    long *quality;						/* QUALITY keyword */
    
    /* Data-related variables */
    
    double **con_dat, **inc_dat;			/* Data arrays, size defined once naxis1/2 are known */
    int **p_mask, **n_mask;					/* Mask for each polarity of umbrae within continuum data */ 
    double *c_pixel_strip;					/* Strip of pixels read from the continuum data */
    double *i_pixel_strip;					/* Strip of pixels read from the inclination data */
    long fpixel[2];							/* Holds the location of pixel to be read */
    LONGLONG nelements;						/* Number of elements in a strip to be read (naxis2) */
    FILE *outptr,*bad_outptr;				/* Pointer to the outfile */
    char outfile_name[29];					/* Name of the outfile */
    char bad_outfile_name[24];				/* Name of the outfile for bad quality*/    
    
    /* Variables related to the actual task */
    
    double rllx,rlly;				/* Disk center, patch coordinates */
    double **radius;				/* Array to hold where the Sun's boundaries are, column major order */
    double rsun_pix,xx,yy,r;		/* Variables associated with radial boundaries */
    double umb,pen;					/* Intensity cutoffs for the umbra and penumbra */
    double num_good;				/* The number of nonzero continuum values in a sunspot region */
    double *p_spots,*n_spots;		/* Number of sunspots of each polarity within an active region */
    double mu;						/* Angle from solar center */
    long *t_secs;					/* T_OBS time converted to seconds since UNIX epoch */
    int noaa_ar;					/* Active region number */
    
    /* Initialise variables that need it */

    i=j=k=0;
    drms_status=0;

	/* Grab values from module_args[] */

	harpnum=strdup(params_get_str(params,"harpnum"));
	time_range=strdup(params_get_str(params,"time_range"));
	umb_sig=params_get_double(params,"umb_sig");
	pen_sig=params_get_double(params,"pen_sig");

	/* Now we start the main program. The rough layout is as follows: 
	   
	   1. Query drms. Based on what we learn, either exit or grab what we need from it.
	   2. Loop through the files, determining the number of sunspots in each polarity.
	   3. Print out a table of values at the end.				   */
	
	/* Forge the DRMS query. */
	
	num_query_chars=16+strlen(harpnum);		/* hmi.sharp_720s[] is 16 characters */
	
	if (time_range!="[]"){
		
		num_query_chars+=strlen(time_range);
		
	}
	
	drms_query=calloc(num_query_chars,sizeof(char));
	strcat(drms_query,"hmi.sharp_720s[");
	strcat(drms_query,harpnum);
	strcat(drms_query,"]");
	
	if (time_range!="[]"){
	
		strcat(drms_query,time_range);
		
	}
	
	/* Query DRMS for the records. */
	
	printf("Querying DRMS. This may take some time.\n");
	
	if (!(drms_ids=drms_open_records(drms_env,drms_query,&drms_status))){
		
		printf("No record sets match your criteria. Check your SHARPs ID and your time range.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		free(drms_query);
		return 0;
		
	}

	free(drms_query);

	num_records=drms_ids->n;
	printf("%d records match. Checking to make sure we have the needed data segments.\n",num_records);

	drms_record=drms_ids->records[0];

	if (!(drms_segment_lookup(drms_record,"continuum"))){
		
		printf("Continuum segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}

	if (!(drms_segment_lookup(drms_record,"inclination"))){
		
		printf("Inclination segment not present! Exiting.\n");
		drms_close_records(drms_ids,DRMS_FREE_RECORD);
		return 0;
	
	}
	
	/* Now we can start. We loop over all records, get the keyword information we need, get the data, and then calculate. */
	
	/* First set the size of some of the pointers that are intended to be arrays. */
	
	/* Data-related arrays */
	p_spots=malloc(num_records*sizeof(double));
	n_spots=malloc(num_records*sizeof(double));
	
	/* Time-related arrays */
	
	t_secs=malloc(num_records*sizeof(long));
	t_obs_s=malloc(num_records*sizeof(char *));
	
	for (i=0;i<num_records;i++){
		
		t_obs_s[i]=malloc(T_OBS_LENGTH*sizeof(char));
		
	}
	
	/* Quality */
	
	quality=malloc(num_records*sizeof(long));
		
	for (k=0;k<num_records;k++){ 

		drms_record=drms_ids->records[k];
		
		/* Check to see if we have data for a particular observation time */
		
		if (!(t_obs=drms_getkey_time(drms_record,"T_OBS",&drms_status))){
					
			printf("Keyword %s not present! Exiting.\n","T_OBS");
			drms_close_records(drms_ids,DRMS_FREE_RECORD);
			return 0;
		
		}
		
		if (time_is_invalid(t_obs)){
			
			printf("Bad record, skipping.\n");
			
		} else {

			if (k == 0){
				
				/* Get active region number for pregame info */
			
				if (!(noaa_ar=drms_getkey_int(drms_record,"NOAA_AR",&drms_status))){
					
					printf("Keyword %s not present! Exiting.\n","NOAA_AR");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
		
				}
				
				/* Create data output filename */
			
				sprintf(outfile_name,"AR%d.spotcount-output.dat",noaa_ar);
				sprintf(bad_outfile_name,"AR%d.bad-quality.dat",noaa_ar);
				
				/* Print out some stats before we run */
			
				printf("Pre-analysis details:\n");
				printf("Analyzing: HARP Number: %s\t NOAA AR: %d\n",harpnum,noaa_ar);
				printf("Output file: %s\n",outfile_name);
			
				if (time_range == "[]"){
				
					printf("We are covering the entire data set.\n");
			
				} else {
				
					printf("Time range: %s\n",time_range);
			
				}

					printf("\n\n");
			
			}
			
			printf("Processing record %d of %d.\n",k+1,num_records);
		
			/* Fill keywords */
			
			if (!(quality[k]=drms_getkey_longlong(drms_record,"QUALITY",&drms_status))){
			
				quality[k]=0;
		
			}
	
			if (!(crpix1=drms_getkey_double(drms_record,"CRPIX1",&drms_status))){
			
				printf("Keyword %s not present! Exiting.\n","CRPIX1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
			
			if (!(crpix2=drms_getkey_double(drms_record,"CRPIX2",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CRPIX2");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(cdelt1=drms_getkey_double(drms_record,"CDELT1",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","CDELT1");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(rsun_obs=drms_getkey_double(drms_record,"RSUN_OBS",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","RSUN_OBS");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			if (!(blank=drms_getkey_double(drms_record,"BLANK",&drms_status))){
					
				printf("Keyword %s not present! Exiting.\n","BLANK");
				drms_close_records(drms_ids,DRMS_FREE_RECORD);
				return 0;
		
			}
		
			sprint_ut(t_obs_s[k],t_obs);		/* Convert to string */
			
			if (quality[k] == 0){
		
				/* Ok, now we get the file locations for the data from DRMS. Originally I attempted
				* to pull the data directly from DRMS but there were vague free() and malloc() issues
				* possibly due to icc and multithreading. */
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"continuum"))){
			
					printf("Problem opening the continuum segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,c_filename);
			
				/* naxis1 and naxis2 we get from segment information */
		
				naxis1=(int)drms_segment->axis[0];
				naxis2=(int)drms_segment->axis[1];
		
				if (!(drms_segment=drms_segment_lookup(drms_record,"inclination"))){
			
					printf("Problem opening the inclination segment! Exiting.\n");
					drms_close_records(drms_ids,DRMS_FREE_RECORD);
					return 0;
			
				}
		
				drms_segment_filename(drms_segment,i_filename);
		
				/* Now open the FITS files and get to work. */
	
				c_status=i_status=0;

				if (fits_open_file(&c_ptr,c_filename,READONLY,&c_status)){
				
					printf("Cannot open %s! Exiting.\n",c_filename);
					exit(0);

				}

				if (fits_open_file(&i_ptr,i_filename,READONLY,&i_status)){
				
					printf("Cannot open %s! Exiting.\n",i_filename);
					fits_close_file(c_ptr,&c_status);
					exit(0);

				}

				printf(" Opening FITs files.\n");

				/* Walk through the HDUs until we get to one with NAXIS=2 */

				/* Number of headers and which one we are on */

				fits_get_num_hdus(c_ptr,&num_hdus,&c_status);
				fits_get_hdu_num(c_ptr,&hdu_pos);

				/* Find the one with two naxes */

				naxis=0;
			
				for (i=1;i<=num_hdus;i++){
				
					fits_movabs_hdu(c_ptr,i,NULL,&c_status);
					fits_read_key(c_ptr,TINT,"NAXIS",&naxis,NULL,&c_status);
				
					if (naxis == 2){
	
						needed_hdu=i;
	
					}
				}

				/* Set all to the needed HDU */

				if (naxis == 0){
		
					printf("HDU problems: can't find one with the required number of axes.\n");
					fits_close_file(c_ptr,&c_status);
					fits_close_file(i_ptr,&i_status);
					exit(0);

				} else {

					fits_movabs_hdu(c_ptr,needed_hdu,NULL,&c_status);
					fits_movabs_hdu(i_ptr,needed_hdu,NULL,&i_status);

				}

				/* Now set some definite boundaries on arrays to help with memory usage. Arrays are called as con_dat[y][x]. */
	
				p_mask=malloc(naxis2*sizeof(int *));
				n_mask=malloc(naxis2*sizeof(int *));
				con_dat=malloc(naxis2*sizeof(double *));
				inc_dat=malloc(naxis2*sizeof(double *));
				radius=malloc(naxis2*sizeof(double *));
				
				c_pixel_strip=calloc(naxis1,sizeof(double));
				i_pixel_strip=calloc(naxis1,sizeof(double));
	
				for (j=0;j<naxis2;j++){
		
					p_mask[j]=calloc(naxis1,sizeof(int));
					n_mask[j]=calloc(naxis1,sizeof(int));
					con_dat[j]=calloc(naxis1,sizeof(double));
					inc_dat[j]=calloc(naxis1,sizeof(double));
					radius[j]=calloc(naxis1,sizeof(double));
		
				}
    
				/* Next, put data in the arrays, clear out blank values and NaNs from the data */
	
				fpixel[0]=1;		/* cfitsio uses fortran reference instead of c when accessing data */
				nelements=naxis1;
				nulval=0;
				any_nulls=0;
    
				for (j=0;j<naxis2;j++){
		
					fpixel[1]=j+1;	/* Add 1 to account for fortran FITS indexing */
					fits_read_pix(c_ptr,TDOUBLE,fpixel,nelements,&nulval,c_pixel_strip,&any_nulls,&c_status);
					fits_read_pix(i_ptr,TDOUBLE,fpixel,nelements,&nulval,i_pixel_strip,&any_nulls,&i_status);
		
					for (i=0;i<naxis1;i++){
			
						/* Kill blank values if present, if not assign to the correct place in array */
			
						if (c_pixel_strip[i] == blank){
				
							con_dat[j][i]=0.0;
					
						} else {
					
							con_dat[j][i]=c_pixel_strip[i];
			
						}
			
						if (i_pixel_strip[i] == blank){
				
							inc_dat[j][i]=0.0;
				
						} else {
					
							inc_dat[j][i]=i_pixel_strip[i];
			
						}
					
					}
				}
		
				printf(" Analyzing data.\n");
	
				/* We now have filled arrays of data about the SHARPs patch and all of the needed keywords. */
	
				/* Coordinate variable definitions for future use. See the declaration section */
				/* at the front of the code to understand what these refer to. */
	
				rllx=(crpix1-1);
				rlly=(crpix2-1);
	
				/* Fill the radius array, handle limb darkening, find max value in patch. */
	
				rsun_pix=rsun_obs/cdelt1;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
			
						xx=(double)i-rllx;
						yy=(double)j-rlly;
						r=sqrt(xx*xx+yy*yy);
				
						if (r <= rsun_pix){
				
							radius[j][i]=r;
							mu=sqrt(1-pow(r/rsun_pix,2.0));
							con_dat[j][i]=con_dat[j][i]/limb_darken(mu);
					
						}
					}
				}
	
				/* Create the actual masks for sunspot counting */
			
				spotbounds(con_dat,naxis1,naxis2,&umb,&pen,umb_sig,pen_sig);

				num_good=0;
	
				for (i=0;i<naxis1;i++){
		
					for (j=0;j<naxis2;j++){
		
						if ((radius[j][i] > 0)&&(con_dat[j][i] <= pen)&&(con_dat[j][i] > 0)){
				
							num_good++;
			
						}
					}
				}

				p_spots[k]=n_spots[k]=0.0;
	
				if (num_good > 0){
		
					/* We have a region. */
		
					for (i=0;i<naxis1;i++){
					
						for (j=0;j<naxis2;j++){
				
							/* On the solar disk, with continuum values at or below the cutoff for
							* the penumbra */
				
							if ((radius[j][i] > 0)&&(con_dat[j][i] <= umb)&&(con_dat[j][i] > 0)){
						
								/* "Positive" sunspot polarities. */
							
								if (inc_dat[j][i] < 90){
							
									p_mask[j][i]=1;
					
								}
					
								/* "Negative" sunspot polarities. */
					
								if (inc_dat[j][i] > 90){
							
									n_mask[j][i]=1;
					
								}
							}
						}
					}
				
					/* Now find the number of unique spots */
				
					p_spots[k]=connected_component_detect(p_mask,naxis1,naxis2);
					n_spots[k]=connected_component_detect(n_mask,naxis1,naxis2);
			
				}

			
				/* Free up dynamic arrays and close the files for the next iteration. */

				for (i=0;i<naxis2;i++){

					free(p_mask[i]);
					free(n_mask[i]);
					free(con_dat[i]);
					free(inc_dat[i]);
					free(radius[i]);
				
				}

				free(p_mask);
				free(n_mask);
				free(con_dat);
				free(inc_dat);
				free(radius);

				free(c_pixel_strip);
				free(i_pixel_strip);
				
				fits_close_file(c_ptr,&c_status);
				fits_close_file(i_ptr,&i_status);

			}
	
		}
		printf(" Completed run %d of %d.\n",k+1,num_records);
	}
	
	/* Output the results to a text file. */
	
	/* First, convert t_obs to a more reasonable product. */
	
	for (i=0;i<num_records;i++){			
	
		t_secs[i]=isotime(t_obs_s[i]);

	}

	printf("Writing to file %s.\n",outfile_name);
	
	outptr=fopen(outfile_name,"w");
	bad_outptr=fopen(bad_outfile_name,"w");
	
	fprintf(outptr,"Active Region: %d\n",noaa_ar);
	fprintf(outptr,"Full UT Time            time(s)  num pos  num neg\n");
	fprintf(outptr,"----------------------  -------  -------  -------\n");
	
	fprintf(bad_outptr,"Active Region: AR%d\n",noaa_ar);
	fprintf(bad_outptr,"Full UT Time            quality  time(s)  number\n");
	fprintf(bad_outptr,"----------------------  -------  -------  ------\n");
	
	for (i=0;i<num_records;i++){
		
		/* Make times relative to the first recorded one. */
		
		if (quality[i] == 0){
		
			fprintf(outptr,"%s  %7ld  %6.2lf  %6.2lf\n",t_obs_s[i],t_secs[i]-t_secs[0],p_spots[i],n_spots[i]);
	
		} else {
			
			fprintf(bad_outptr,"%s  0x%08lX  %7ld  %d\n",t_obs_s[i],quality[i],t_secs[i],i+1);
			
		}
	}
	
	fclose(outptr);
	fclose(bad_outptr);
	
	printf("Done!\n");
	
	/* Free memory associated with dynamic arrays. */
    
	free(p_spots);
	free(n_spots);

	free(t_secs);
	free(t_obs_s);
	
	free(quality);
	
	/* Close the drms records connection */
	
	drms_close_records(drms_ids,DRMS_FREE_RECORD);
    
	/* Done! */
    
	return 0;
}
Пример #29
0
int main(int argc, char *argv []) {

        if(populate_env_variable(REF_ERROR_CODES_FILE, "L2_ERROR_CODES_FILE")) {

                printf("\nUnable to populate [REF_ERROR_CODES_FILE] variable with corresponding environment variable. Routine will proceed without error handling\n");

        }

        if (argc != 7) {

                if(populate_env_variable(SPE_BLURB_FILE, "L2_SPE_BLURB_FILE")) {

                        RETURN_FLAG = 1;

                } else {

                        print_file(SPE_BLURB_FILE);

                }

                write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -1, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);

                return 1;

        } else {
                // ***********************************************************************
                // Redefine routine input parameters
                
                char *input_f                           = strdup(argv[1]);              
                char *method                            = strdup(argv[2]); 
                char *ss_method                         = strdup(argv[3]); 
                double target_half_aperture_px          = strtod(argv[4], NULL); 
                int sky_window_half_aperture_px         = strtol(argv[5], NULL, 0);   
                char *output_f                          = strdup(argv[6]);                    
                
                // ***********************************************************************
                // Open input file (ARG 1), get parameters and perform any data format 
                // checks

                fitsfile *input_f_ptr;

                int input_f_maxdim = 2, input_f_status = 0, input_f_bitpix, input_f_naxis;
                long input_f_naxes [2] = {1,1};

                if(!fits_open_file(&input_f_ptr, input_f, IMG_READ_ACCURACY, &input_f_status)) {

                        if(!populate_img_parameters(input_f, input_f_ptr, input_f_maxdim, &input_f_bitpix, &input_f_naxis, input_f_naxes, &input_f_status, "INPUT FRAME")) {

                                if (input_f_naxis != 2) {       // any data format checks here

                                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -2, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);

                                        free(input_f);
                                        free(output_f);
                                        free(method);
                                        free(ss_method);
                                        if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

                                        return 1;
        
                                }

                        } else { 

                                write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -3, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                                fits_report_error(stdout, input_f_status); 

                                free(input_f);
                                free(output_f);                                
                                free(method);
                                free(ss_method);
                                if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

                                return 1; 

                        }

                } else { 

                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -4, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                        fits_report_error(stdout, input_f_status); 

                        free(input_f);
                        free(output_f);                        
                        free(method);
                        free(ss_method);
                        
                        return 1; 

                }
                
                // ***********************************************************************
                // Set the range limits

                int cut_x [2] = {1, input_f_naxes[0]};
                int cut_y [2] = {1, input_f_naxes[1]};

                // ***********************************************************************
                // Set parameters used when reading data from input file (ARG 1)

                long fpixel [2] = {cut_x[0], cut_y[0]};
                long nxelements = (cut_x[1] - cut_x[0]) + 1;
                long nyelements = (cut_y[1] - cut_y[0]) + 1;

                // ***********************************************************************
                // Create arrays to store pixel values from input fits file (ARG 1)

                double input_f_pixels [nxelements];
                
                // ***********************************************************************
                // Get input fits file (ARG 1) values and store in 2D array

                int ii;

                double input_frame_values [nyelements][nxelements];
                memset(input_frame_values, 0, sizeof(double)*nxelements*nyelements);
                for (fpixel[1] = cut_y[0]; fpixel[1] <= cut_y[1]; fpixel[1]++) {

                        memset(input_f_pixels, 0, sizeof(double)*nxelements);

                        if(!fits_read_pix(input_f_ptr, TDOUBLE, fpixel, nxelements, NULL, input_f_pixels, NULL, &input_f_status)) {

                                for (ii=0; ii<nxelements; ii++) {
                                        input_frame_values[fpixel[1]-1][ii] = input_f_pixels[ii];
                                }

                        } else { 

                                write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -5, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                                fits_report_error(stdout, input_f_status); 

                                free(input_f);  
                                free(output_f);  
                                free(method);
                                free(ss_method);                                
                                if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

                                return 1; 

                        }

                }
                
                // ***********************************************************************
                // Open [SPFIND_OUTPUTF_PEAKS_FILE] input file
        
                FILE *inputfile;
        
                if (!check_file_exists(SPFIND_OUTPUTF_PEAKS_FILE)) { 

                        inputfile = fopen(SPFIND_OUTPUTF_PEAKS_FILE , "r");

                } else {

                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -6, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);

                        return 1;

                }

                // ***********************************************************************
                // Find some [SPFIND_OUTPUTF_PEAKS_FILE] input file details

                char input_string [150];
                
                int row_count = 0;
                while(!feof(inputfile)) {
                        memset(input_string, '\0', sizeof(char)*150);
                        fgets(input_string, 150, inputfile);
                        if (strtol(&input_string[0], NULL, 0) > 0) {            // check the line begins with a positive number (usable)
                                row_count++;
                        }
                }
                
                rewind(inputfile);
                
                // ***********************************************************************
                // Store [SPFIND_OUTPUTF_PEAKS_FILE] data               
                
                double x_coords[row_count];
                memset(x_coords, 0, sizeof(double)*(row_count));

                double y_coords[row_count];
                memset(y_coords, 0, sizeof(double)*(row_count));

                double coord_x, coord_y;
                int idx = 0;
                while(!feof(inputfile)) {
                        memset(input_string, '\0', sizeof(char)*150);
                        fgets(input_string, 150, inputfile);    
                        if (strtol(&input_string[0], NULL, 0) > 0) {            // check the line begins with a positive number (usable)
                                sscanf(input_string, "%lf\t%lf\n", &coord_x, &coord_y);
                                x_coords[idx] = coord_x;
                                y_coords[idx] = coord_y;
                                idx++;
                        }
                }            
        
                double output_frame_values[nxelements];
                memset(output_frame_values, 0, sizeof(double)*nxelements);     
                
                // ***********************************************************************
                // EXTRACTION
                               
                if (strcmp(method, "simple") == 0) {
                    // ***********************************************************************
                    // PARTIAL PIXEL APERTURE

                    int ii, jj;

                    double y;    
                    
                    y = y_coords[0];                            // should only be one bin in [SPFIND_OUTPUTF_PEAKS_FILE] data file
     
                    double this_col_value;
                    for (ii=0; ii<nxelements; ii++) {   
                      
                        this_col_value = 0.;
                        
                        // ***********************************************************************
                        // Does [y] violate the img boundaries?

                        if ((y + target_half_aperture_px > nyelements) || (y - target_half_aperture_px <= 0)) {

                            write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -7, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                            fits_report_error(stdout, input_f_status); 

                            free(input_f);
                            free(output_f);  
                            free(method);
                            free(ss_method);
                            
                            if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                            fclose(inputfile);

                            return 1;

                        }

                        // ***********************************************************************
                        // Extract flux within aperture

                        double y_low, y_high;

                        y_low = y-target_half_aperture_px-0.5;
                        y_high = y+target_half_aperture_px+0.5;                   

                        int y_low_floor, y_high_floor;
        
                        y_low_floor = floor(y-target_half_aperture_px-0.5);            // 0.5 as taking (half_ap*2) + 1 as total aperture
                        y_high_floor = floor(y+target_half_aperture_px+0.5);
                                            
                        for (jj=y_low_floor; jj<=y_high_floor; jj++) {
                         
                            if (jj == y_low_floor) {                        // outside pixel where partial flux needs to be taken into account
                                  

                                double partial_fraction_of_bin = (y_low_floor + 1) - y_low;
                                this_col_value += partial_fraction_of_bin * input_frame_values[jj][ii];
                                
                            } else if (jj == y_high_floor) {                // outside pixel where partial flux needs to be taken into account
                                  
                                double partial_fraction_of_bin = y_high - y_high_floor;
                                this_col_value += partial_fraction_of_bin * input_frame_values[jj][ii];
                                
                            } else {
                              
                                this_col_value += input_frame_values[jj][ii]; 
                                    
                            }
                        }   
                        
                        output_frame_values[ii] = this_col_value;
                        
                    }    
                } else {
                  
                    write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -8, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                    fits_report_error(stdout, input_f_status); 

                    free(input_f);
                    free(output_f);
                    free(method);
                    free(ss_method);
                    
                    if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status);  
                    fclose(inputfile);
                    
                    return 1;
                    
                }
                
                // ***********************************************************************
                // SKY SUBTRACTION
                
                if (strcmp(ss_method, "none") == 0) {
                } else if (strcmp(ss_method, "median") == 0) {

                    // ***********************************************************************
                    // MEDIAN SUBTRACTION             
                    int ii, jj;

                    double y;    
                    
                    y = y_coords[0];                            // should only be one bin in [SPFIND_OUTPUTF_PEAKS_FILE] data file
     
                    double this_col_value;
                    
                    for (ii=0; ii<nxelements; ii++) {          
                        this_col_value = 0.;
                        
                        // ***********************************************************************
                        // Does [y] violate the img boundaries?

                        if ((y + target_half_aperture_px + sky_window_half_aperture_px > nyelements) || (y - target_half_aperture_px - sky_window_half_aperture_px <= 0)) {

                            write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -9, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                            fits_report_error(stdout, input_f_status); 

                            free(input_f);
                            free(output_f);  
                            free(method);
                            free(ss_method);
                            
                            if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                            fclose(inputfile);

                            return 1;

                        }
                        
                        // ***********************************************************************
                        // Find pixels for sky aperture

                        int ap_lower_lo, ap_lower_hi, ap_upper_lo, ap_upper_hi; 
                        
                        ap_lower_lo = floor(y-target_half_aperture_px-0.5) - sky_window_half_aperture_px - 1;
                        ap_lower_hi = floor(y-target_half_aperture_px-0.5) - 1;
                        ap_upper_lo = floor(y+target_half_aperture_px+0.5) + 1;
                        ap_upper_hi = floor(y+target_half_aperture_px+0.5) + sky_window_half_aperture_px + 1;
                        
                        int n_ap_values = (ap_lower_hi-ap_lower_lo) + (ap_upper_hi-ap_upper_lo) + 2;
                        
                        double ap_values[n_ap_values];
                             
                        int idx = 0;
 
                        
                        for (jj=ap_lower_lo; jj<=ap_lower_hi; jj++) {
                          
                            ap_values[idx] = input_frame_values[jj][ii]; 
                            idx++;
                                    
                        }  
                        
                        for (jj=ap_upper_lo; jj<=ap_upper_hi; jj++) {
                          
                            ap_values[idx] = input_frame_values[jj][ii]; 
                            idx++;
                                    
                        }  
                        
                        // DEBUG
                        /*for (jj=0; jj<idx; jj++) 
                          printf("%f,", ap_values[jj]);
                        
                        printf("\n");
                        
                        for (jj=0; jj<idx; jj++) 
                          printf("%d,", jj);
                        
                        printf("\n");*/ 
                        
                        // Take median
                        double ap_values_sorted [n_ap_values];
                        memcpy(ap_values_sorted, ap_values, sizeof(double)*n_ap_values);

                        gsl_sort(ap_values_sorted, 1, (ap_lower_hi-ap_lower_lo) + (ap_upper_hi-ap_upper_lo) + 2);
                        double ap_values_median = gsl_stats_median_from_sorted_data(ap_values_sorted, 1, n_ap_values);     
                        
                        this_col_value = ap_values_median * ((target_half_aperture_px*2) + 1);    // need to scale up to target extraction aperture size
                        
                        output_frame_values[ii] -= this_col_value;              

                    }
                  
                } else {
                  
                    write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -10, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                    fits_report_error(stdout, input_f_status); 

                    free(input_f);
                    free(output_f);
                    free(method);
                    free(ss_method);
                    
                    if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status);  
                    fclose(inputfile);
                    
                    return 1;
                    
                }
                
                // ***********************************************************************
                // Set output frame parameters

                fitsfile *output_f_ptr;
        
                int output_f_status = 0;
                long output_f_naxes [2] = {nxelements, 1};
        
                long output_f_fpixel = 1;

                // ***********************************************************************
                // Create and write [output_frame_values] to output file (ARG 6)
        
                if (!fits_create_file(&output_f_ptr, output_f, &output_f_status)) {
        
                        if (!fits_create_img(output_f_ptr, INTERMEDIATE_IMG_ACCURACY[0], 2, output_f_naxes, &output_f_status)) {

                                if (!fits_write_img(output_f_ptr, INTERMEDIATE_IMG_ACCURACY[1], output_f_fpixel, nxelements, output_frame_values, &output_f_status)) {

                                } else { 

                                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -11, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                                        fits_report_error(stdout, output_f_status); 

                                        free(input_f);
                                        free(output_f);
                                        free(method);
                                        free(ss_method);
                                        
                                        if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                                        if(fits_close_file(output_f_ptr, &output_f_status)) fits_report_error (stdout, output_f_status);
                                        fclose(inputfile);

                                        return 1; 

                                }

                        } else {

                                write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -12, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                                fits_report_error(stdout, output_f_status); 

                                free(input_f);
                                free(output_f);
                                free(method);
                                free(ss_method);
                                
                                if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                                if(fits_close_file(output_f_ptr, &output_f_status)) fits_report_error (stdout, output_f_status);
                                fclose(inputfile);

                                return 1; 

                        }

                } else {

                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -13, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                        fits_report_error(stdout, output_f_status); 

                        free(input_f);
                        free(output_f);
                        free(method);
                        if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                        fclose(inputfile);

                        return 1; 

                }                
                
                // ***********************************************************************
                // Free arrays on heap

                free(input_f);
                free(output_f);
                free(method);  
                free(ss_method);
                
                // ***********************************************************************
                // Close input file (ARG 1) and output file (ARG 6)          
                
                if(fits_close_file(input_f_ptr, &input_f_status)) { 

                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -14, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                        fits_report_error (stdout, input_f_status); 

                        return 1; 

                }     
               
                if(fits_close_file(output_f_ptr, &output_f_status)) { 

                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", -15, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                        fits_report_error (stdout, output_f_status); 

                        return 1; 

                }  
                
                if (fclose(inputfile)) {
                        write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -16, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);
                        return 1; 
                } 
                
                // Write success to [ERROR_CODES_FILE]

                write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATEX", RETURN_FLAG, "Status flag for L2 spextract routine", ERROR_CODES_FILE_WRITE_ACCESS);

                return 0;

        }

}
Пример #30
0
int main (int argc, char *argv []) {

	if(populate_env_variable(REF_ERROR_CODES_FILE, "L2_ERROR_CODES_FILE")) {

		printf("\nUnable to populate [REF_ERROR_CODES_FILE] variable with corresponding environment variable. Routine will proceed without error handling\n");

	}

	if (argc != 8) {

		if(populate_env_variable(LOR_BLURB_FILE, "L2_LOR_BLURB_FILE")) {

			RETURN_FLAG = 1;

		} else {

			print_file(LOR_BLURB_FILE);

		}

		write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -1, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

		return 1;

	} else {

		// ***********************************************************************
		// Redefine routine input parameters
	
		char *input_f	                = strdup(argv[1]);
		double start_wav		= strtod(argv[2], NULL);
		double end_wav			= strtod(argv[3], NULL);
		char *interpolation_type	= strdup(argv[4]);
		double dispersion		= strtod(argv[5], NULL);
		int conserve_flux		= strtol(argv[6], NULL, 0);
		char *output_f	                = strdup(argv[7]);

		// ***********************************************************************
		// Open input file (ARG 1), get parameters and perform any data format 
                // checks 

		fitsfile *input_f_ptr;

		int input_f_maxdim = 2;
		int input_f_status = 0, input_f_bitpix, input_f_naxis;
		long input_f_naxes [2] = {1,1};

		if(!fits_open_file(&input_f_ptr, input_f, READONLY, &input_f_status)) {

			if(!populate_img_parameters(input_f, input_f_ptr, input_f_maxdim, &input_f_bitpix, &input_f_naxis, input_f_naxes, &input_f_status, "INPUT FRAME")) {

				if (input_f_naxis != 2) {	// any data format checks here

					write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -2, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

					free(input_f);
					free(interpolation_type);
					free(output_f);

					if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

					return 1;
	
				}

			} else { 

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -3, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, input_f_status); 

				free(input_f);
				free(interpolation_type);
				free(output_f);

				if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

				return 1; 

			}

		} else { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -4, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error(stdout, input_f_status); 

			free(input_f);
			free(interpolation_type);
			free(output_f);

			return 1; 

		}

		// ***********************************************************************
		// Set the range limits using input fits file (ARG 1)

		int cut_x [2] = {1, input_f_naxes[0]};
		int cut_y [2] = {1, input_f_naxes[1]};

		// ***********************************************************************
		// Set parameters used when reading data from input fits file (ARG 1)

		long fpixel [2] = {cut_x[0], cut_y[0]};
		long nxelements = (cut_x[1] - cut_x[0]) + 1;
		long nyelements = (cut_y[1] - cut_y[0]) + 1;

		// ***********************************************************************
		// Create arrays to store pixel values from input fits file (ARG 1)

		double input_f_pixels [nxelements];

		// ***********************************************************************
		// Open [LOARCFIT_OUTPUTF_WAVFITS_FILE] dispersion solutions file

		FILE *dispersion_solutions_f;
	
		if (!check_file_exists(LOARCFIT_OUTPUTF_WAVFITS_FILE)) { 

			dispersion_solutions_f = fopen(LOARCFIT_OUTPUTF_WAVFITS_FILE , "r");

		} else {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -5, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(input_f);
			free(interpolation_type);
			free(output_f);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1;

		}	

		// ***********************************************************************
		// Find some [LOARCFIT_OUTPUTF_WAVFITS_FILE] file details

		char input_string [500];

		bool find_polynomialorder_comment = FALSE;

		int polynomial_order;	

		char search_string_1 [20] = "# Polynomial Order:\0";	// this is the comment to be found from the [LOARCFIT_OUTPUTF_WAVFITS_FILE] file

		while(!feof(dispersion_solutions_f)) {

			memset(input_string, '\0', sizeof(char)*500);
	
			fgets(input_string, 500, dispersion_solutions_f);	

			if (strncmp(input_string, search_string_1, strlen(search_string_1)) == 0) { 

				sscanf(input_string, "%*[^\t]%d", &polynomial_order);		// read all data up to tab as string ([^\t]), but do not store (*)
				find_polynomialorder_comment = TRUE;
				break;


			} 

		}

		if (find_polynomialorder_comment == FALSE) {	// error check - didn't find the comment in the [LOARCFIT_OUTPUTF_WAVFITS_FILE] file

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -6, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(input_f);
			free(interpolation_type);
			free(output_f);

			fclose(dispersion_solutions_f);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1;

		}

		// ***********************************************************************
		// Rewind and extract coefficients from [LOARCFIT_OUTPUTF_WAVFITS_FILE]
		// file 

		rewind(dispersion_solutions_f);

		int token_index;	// this variable will hold which token we're dealing with
		int coeff_index;	// this variable will hold which coefficient we're dealing with
		double this_coeff;
		double this_chisquared;
	
		char *token;

		double coeffs [polynomial_order+1];
		memset(coeffs, 0, sizeof(double)*(polynomial_order+1));

		while(!feof(dispersion_solutions_f)) {

			memset(input_string, '\0', sizeof(char)*500);
	
			fgets(input_string, 500, dispersion_solutions_f);

			token_index = 0;
			coeff_index = 0;

			if (strtol(&input_string[0], NULL, 0) > 0) { 		// check the line begins with a positive number

				// ***********************************************************************
				// String tokenisation loop: 
				//
				// 1. init calls strtok() loading the function with input_string
				// 2. terminate when token is null
				// 3. we keep assigning tokens of input_string to token until termination by calling strtok with a NULL first argument
				// 
				// n.b. searching for tab or newline separators ('\t' and '\n')

				for (token=strtok(input_string, "\t\n"); token !=NULL; token = strtok(NULL, "\t\n")) {
                                  
                                        if (token_index == 0) {    
                                        } else if ((token_index >= 1) && (token_index <= polynomial_order+1)) { 	// coeff token

						this_coeff = strtod(token, NULL);
						// printf("%d\t%e\n", coeff_index, this_coeff);		// DEBUG
						coeffs[coeff_index] = this_coeff;
						coeff_index++;

					} else if (token_index == polynomial_order+2) {					// chisquared token

						this_chisquared = strtod(token, NULL);
                                                //printf("%f\n", this_chisquared);                      // DEBUG

					}

					token_index++;

				}

			}

		}

		// ***********************************************************************
		// Find wavelength extremities from [LOARCFIT_OUTPUTF_WAVFITS_FILE] file
		// and ensure the input constraints [start_wav] (ARG 2) and [end_wav]
		// (ARG 3) don't lie outside these boundaries

		double smallest_wav, largest_wav;

		int ii;

		for (ii=0; ii<=polynomial_order; ii++) {
		    
			smallest_wav += coeffs[ii]*pow(0+INDEXING_CORRECTION, ii);
			largest_wav += coeffs[ii]*pow((cut_x[1]-1)+INDEXING_CORRECTION, ii);

		}

		// ***********************************************************************
	        // Need to find pixel indexes for starting/ending wavelength positions

	        double this_element_wav;
	        int first_element_index, last_element_index;
                int jj;
		for (ii=0; ii<nxelements; ii++) {
                        this_element_wav = 0.0;
                        for (jj=0; jj<=polynomial_order; jj++) {
                                this_element_wav += coeffs[jj]*pow(ii,jj);
                        }
		      	if (this_element_wav >= start_wav) {	// the current index, ii, represents the first pixel with a wavelength >= start_wav. Comparing doubles but accuracy isn't a necessity so don't need gsl_fcmp function
		       		break;
		     	}
		     	
                        first_element_index = ii;		     	
                }

		// printf("%d\t%f\n", ii, this_element_wav);	// DEBUG

		for (ii=nxelements; ii>=0; ii--) {
                        this_element_wav = 0.0;
                        for (jj=0; jj<=polynomial_order; jj++) {
                                this_element_wav += coeffs[jj]*pow(ii,jj);
                        }
                        if (this_element_wav <= end_wav) {    // the current index, ii, represents the first pixel with a wavelength <= end_wav. Comparing doubles but accuracy isn't a necessity so don't need gsl_fcmp function
                                break;
                        }

			last_element_index = ii;

	        }
	        
	        // printf("%d\t%f\n", ii, this_element_wav);     // DEBUG
	
		printf("\nWavelength boundaries");
		printf("\n---------------------\n");

		printf("\nInherent minimum wavelength:\t%.2f Å", smallest_wav);
		printf("\nInherent maximum wavelength:\t%.2f Å\n", largest_wav);

		if (start_wav < smallest_wav) {         // Comparing doubles but accuracy isn't a necessity so don't need gsl_fcmp function
		  
			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -7, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(input_f);
			free(interpolation_type);
			free(output_f);

			fclose(dispersion_solutions_f);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1; 

		} else if (end_wav > largest_wav) {     // Comparing doubles but accuracy isn't a necessity so don't need gsl_fcmp function

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -8, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(input_f);
			free(interpolation_type);
			free(output_f);

			fclose(dispersion_solutions_f);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1; 

		}

		// ***********************************************************************
	        // Set the bin wavelengths 

		int num_bins = 0;

		if (!gsl_fcmp((end_wav-start_wav)/dispersion, rint((end_wav-start_wav)/dispersion), 1e-5)) {	// check to see if nearest integer is within tolerance value	

			num_bins = rint((end_wav-start_wav)/dispersion) + 1;					// if TRUE, round

		} else {

			num_bins = floor((end_wav-start_wav)/dispersion) + 1;					// if FALSE, floor

		}

		// printf("%d\n", num_bins);						// DEBUG

		double bin_wavelengths [num_bins];
		memset(bin_wavelengths, 0, sizeof(double)*num_bins);

		for (ii=0; ii<num_bins; ii++) {

			bin_wavelengths[ii] = start_wav + dispersion*ii;		
			// printf("%f\n", bin_wavelengths[ii]);				// DEBUG
		
		}	

		// printf("%f\t%f\n", bin_wavelengths[0], bin_wavelengths[num_bins-1]);	// DEBUG


		// REBIN INPUT FRAME (ARG 1) AND CONSERVE FLUX IF APPLICABLE
		// ***********************************************************************
		// 1.	Open input frame

		int this_row_index;

		double x_wav [nxelements];

		double output_frame_values [nyelements][num_bins];
		memset(output_frame_values, 0, sizeof(double)*nyelements*num_bins);

		double output_f_pixels [num_bins];
		memset(output_f_pixels, 0, sizeof(double)*(num_bins));

		double this_pre_rebin_row_flux, this_post_rebin_row_flux;

		double conservation_factor;	

		for (fpixel[1] = cut_y[0]; fpixel[1] <= cut_y[1]; fpixel[1]++) {

			this_row_index = fpixel[1] - 1;

			memset(input_f_pixels, 0, sizeof(double)*nxelements);

			if(!fits_read_pix(input_f_ptr, IMG_READ_ACCURACY, fpixel, nxelements, NULL, input_f_pixels, NULL, &input_f_status)) {

				// 2.	Calculate pre-rebin total fluxes

				this_pre_rebin_row_flux = 0.0;

				for (ii=first_element_index; ii<=last_element_index; ii++) {

					this_pre_rebin_row_flux += input_f_pixels[ii];

				}

				// 3.	Create pixel-wavelength translation array and perform interpolation

				memset(x_wav, 0, sizeof(double)*nxelements);

				for (ii=0; ii<nxelements; ii++) {

					for (jj=0; jj<=polynomial_order; jj++) {
					    
						x_wav[ii] += coeffs[jj]*pow(ii+INDEXING_CORRECTION,jj);

					}

					// printf("%d\t%f\n", ii, x_wav[ii]); // DEBUG

				}

				// for (ii=0; ii< nxelements; ii++) printf("\n%f\t%f", x_wav[ii], input_f_pixels[ii]);	// DEBUG

				if (interpolate(interpolation_type, x_wav, input_f_pixels, nxelements, bin_wavelengths[0], bin_wavelengths[num_bins-1], dispersion, output_f_pixels)) {
		
					write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -9, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

					free(input_f);
					free(interpolation_type);
					free(output_f);

					fclose(dispersion_solutions_f);

					if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

					return 1; 

				}

				// 4.	Calculate post-rebin total fluxes

				this_post_rebin_row_flux = 0.0;

				for (ii=0; ii<num_bins; ii++) {

					this_post_rebin_row_flux += output_f_pixels[ii];

				}

				// 5.	Conserve flux if applicable

				conservation_factor = this_pre_rebin_row_flux/this_post_rebin_row_flux;

				// printf("%f\t%f\t%f\n", this_pre_rebin_row_flux, this_post_rebin_row_flux, conservation_factor);	// DEBUG

				for (ii=0; ii<num_bins; ii++) {

					if (conserve_flux == TRUE) {

						output_frame_values[this_row_index][ii] = output_f_pixels[ii]*conservation_factor;

					} else {

						output_frame_values[this_row_index][ii] = output_f_pixels[ii];

					}

				}

			} else { 

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -10, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, input_f_status);

				free(input_f);
				free(interpolation_type);
				free(output_f);

				fclose(dispersion_solutions_f);

				if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

				return 1; 

			}

		}

		// 6.	Create [LOREBIN_OUTPUTF_REBIN_WAVFITS_FILE] output file and print
		// 	a few parameters

		FILE *outputfile;
		outputfile = fopen(LOREBIN_OUTPUTF_REBIN_WAVFITS_FILE, FILE_WRITE_ACCESS);

		if (!outputfile) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -11, "Status flag for L2 frrebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

			free(input_f);
			free(interpolation_type);
			free(output_f);

			fclose(dispersion_solutions_f);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 

			return 1;

		}

		char timestr [80];
		memset(timestr, '\0', sizeof(char)*80);

		find_time(timestr);

		fprintf(outputfile, "#### %s ####\n\n", LOREBIN_OUTPUTF_REBIN_WAVFITS_FILE);
	        fprintf(outputfile, "# Rebinning wavelength fit parameters.\n\n");
                fprintf(outputfile, "# Run Datetime:\t\t%s\n\n", timestr);
	        fprintf(outputfile, "# Target Filename:\t%s\n\n", input_f);
	        fprintf(outputfile, "# Starting Wavelength:\t%.2f\n", bin_wavelengths[0]);
	        fprintf(outputfile, "# Dispersion:\t\t%.2f\n", dispersion);
		fprintf(outputfile, "%d", EOF);

		// 7.	Write these values to the [ADDITIONAL_KEYS_FILE] file

		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CTYPE1", "Wavelength", "Type of co-ordinate on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CUNIT1", "Angstroms", "Units for axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CRVAL1", bin_wavelengths[0], "[pixel] Value at ref. pixel on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CDELT1", dispersion, "[pixel] Pixel scale on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CRPIX1", 1.0, "[pixel] Reference pixel on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CTYPE2", "a2", "Type of co-ordinate on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CUNIT2", "Pixels", "Units for axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CRVAL2", 1, "[pixel] Value at ref. pixel on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CDELT2", 1, "[pixel] Pixel scale on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "LSS_CALIBRATION", "CRPIX2", 1, "[pixel] Reference pixel on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);

		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CTYPE1", "Wavelength", "Type of co-ordinate on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CUNIT1", "Angstroms", "Units for axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CRVAL1", bin_wavelengths[0], "[pixel] Value at ref. pixel on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CDELT1", dispersion, "[pixel] Pixel scale on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CRPIX1", 1.0, "[pixel] Reference pixel on axis 1", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CTYPE2", "a2", "Type of co-ordinate on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_str(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CUNIT2", "Pixels", "Units for axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CRVAL2", 1, "[pixel] Value at ref. pixel on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CDELT2", 1, "[pixel] Pixel scale on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);
		write_additional_key_to_file_dbl(ADDITIONAL_KEYS_FILE, "SPEC_CALIBRATION", "CRPIX2", 1, "[pixel] Reference pixel on axis 2", ADDITIONAL_KEYS_FILE_WRITE_ACCESS);

		// ***********************************************************************
		// Set output frame parameters

		fitsfile *output_f_ptr;
	
		int output_f_status = 0;
		long output_f_naxes [2] = {num_bins,nyelements};
	
		long output_f_fpixel = 1;

		// ***********************************************************************
		// Create [output_frame_values_1D] array to hold the output data in the 
                // correct format

		double output_frame_values_1D [num_bins*nyelements];
		memset(output_frame_values_1D, 0, sizeof(double)*num_bins*nyelements);
                int kk;
		for (ii=0; ii<nyelements; ii++) {
	
			jj = ii * num_bins;
	
			for (kk=0; kk<num_bins; kk++) {
	
				output_frame_values_1D[jj] = output_frame_values[ii][kk];
				jj++;

			}
		
		}

		// ***********************************************************************
		// Create and write [output_frame_values_1D] to output file (ARG 5)	
	
		if (!fits_create_file(&output_f_ptr, output_f, &output_f_status)) {
	
			if (!fits_create_img(output_f_ptr, INTERMEDIATE_IMG_ACCURACY[0], 2, output_f_naxes, &output_f_status)) {

				if (!fits_write_img(output_f_ptr, INTERMEDIATE_IMG_ACCURACY[1], output_f_fpixel, num_bins * nyelements, output_frame_values_1D, &output_f_status)) {

				} else { 

					write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -12, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
					fits_report_error(stdout, output_f_status); 

					free(input_f);
					free(interpolation_type);
					free(output_f);

					fclose(dispersion_solutions_f);
					fclose(outputfile);

					if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
					if(fits_close_file(output_f_ptr, &output_f_status)); 

					return 1; 

				}

			} else {

				write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -13, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
				fits_report_error(stdout, output_f_status); 

				free(input_f);
				free(interpolation_type);
				free(output_f);

				fclose(dispersion_solutions_f);
				fclose(outputfile);

                                if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                                if(fits_close_file(output_f_ptr, &output_f_status)); 

				return 1; 

			}

		} else {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -14, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error(stdout, output_f_status); 

			free(input_f);
			free(interpolation_type);
			free(output_f);

			fclose(dispersion_solutions_f);
			fclose(outputfile);

			if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status);  

			return 1; 

		}

		// ***********************************************************************
		// Clean up heap memory

		free(input_f);
		free(interpolation_type);
		free(output_f);

		// ***********************************************************************
		// Close input file (ARG 1), output file (ARG 7) and 
		// [FRARCFIT_OUTPUTF_WAVFITS_FILE] file

		if (fclose(dispersion_solutions_f)) {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -15, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

			fclose(outputfile);

                        if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                        if(fits_close_file(output_f_ptr, &output_f_status)); 

			return 1; 

		}

		if (fclose(outputfile)) {

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -16, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

                        if(fits_close_file(input_f_ptr, &input_f_status)) fits_report_error (stdout, input_f_status); 
                        if(fits_close_file(output_f_ptr, &output_f_status)); 

			return 1; 

		}

		if(fits_close_file(input_f_ptr, &input_f_status)) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -17, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error (stdout, input_f_status); 

                        if(fits_close_file(output_f_ptr, &output_f_status)); 

			return 1; 

	    	}

		if(fits_close_file(output_f_ptr, &output_f_status)) { 

			write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", -18, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);
			fits_report_error (stdout, output_f_status); 

			return 1; 

	    	}

		// ***********************************************************************
		// Write success to [ERROR_CODES_FILE]

		write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATRE", RETURN_FLAG, "Status flag for L2 lorebin routine", ERROR_CODES_FILE_WRITE_ACCESS);

		return 0;

	}

}