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; } }
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 != 2) { if(populate_env_variable(SPTS_BLURB_FILE, "L2_SPTS_BLURB_FILE")) { RETURN_FLAG = 1; } else { print_file(SPTS_BLURB_FILE); } write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -1, "Status flag for L2 sptrace routine", ERROR_CODES_FILE_WRITE_ACCESS); return 1; } else { // *********************************************************************** // Redefine routine input parameters int order = strtol(argv[1], NULL, 0); // *********************************************************************** // 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, "L2STATTR", -2, "Status flag for L2 sptrace 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++; } } // *********************************************************************** // Perform a few checks to ensure the input tracing parameters // are sensible if ((order < SPTRACE_VAR_POLYORDER_LO) || (order > SPTRACE_VAR_POLYORDER_HI)) { // Check [order] is within config limits write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -3, "Status flag for L2 sptrace routine", ERROR_CODES_FILE_WRITE_ACCESS); fclose(inputfile); return 1; } // *********************************************************************** // Create [SPTRACE_OUTPUTF_TRACES_FILE] output file and print a few // parameters FILE *outputfile; outputfile = fopen(SPTRACE_OUTPUTF_TRACES_FILE, FILE_WRITE_ACCESS); if (!outputfile) { write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -4, "Status flag for L2 sptrace routine", ERROR_CODES_FILE_WRITE_ACCESS); fclose(inputfile); return 1; } char timestr [80]; memset(timestr, '\0', sizeof(char)*80); find_time(timestr); fprintf(outputfile, "#### %s ####\n\n", SPTRACE_OUTPUTF_TRACES_FILE); fprintf(outputfile, "# Lists the trace coefficients and corresponding chi-squareds found using the sptrace program.\n\n"); fprintf(outputfile, "# Run datetime:\t\t%s\n", timestr); fprintf(outputfile, "# Polynomial Order:\t%d\n\n", order); // *********************************************************************** // Fit and store results to [SPTRACE_OUTPUTF_TRACES_FILE] file double coeffs[order]; double this_chi_squared; if (calc_least_sq_fit(order, row_count, x_coords, y_coords, coeffs, &this_chi_squared)) { // reversed [coord_y] and [coord_x] as want to find x = f(y) not y = f(x) write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -5, "Status flag for L2 frtrace routine", ERROR_CODES_FILE_WRITE_ACCESS); fclose(inputfile); fclose(outputfile); return 1; } int ii; for (ii=0; ii<=order; ii++) { fprintf(outputfile, SPTRACE_VAR_ACCURACY_COEFFS, coeffs[ii]); fprintf(outputfile, "\t"); } fprintf(outputfile, SPTRACE_VAR_ACCURACY_CHISQ, this_chi_squared); fprintf(outputfile, "\n"); fprintf(outputfile, "%d", EOF); printf("\nFitting results"); printf("\n--------------------\n"); printf("\nχ2:\t\t\t%.2f\n", this_chi_squared); // *********************************************************************** // Perform a few checks to ensure the chi squareds are sensible if ((this_chi_squared < SPTRACE_VAR_CHISQUARED_MIN) || (this_chi_squared > SPTRACE_VAR_CHISQUARED_MAX)) { // comparing doubles but accuracy isn't a necessity so don't need gsl_fcmp function RETURN_FLAG = 2; } // *********************************************************************** // Close [SPFIND_OUTPUTF_PEAKS_FILE] input file and // [SPTRACE_OUTPUTF_TRACES_FILE] output file if (fclose(inputfile)) { write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -6, "Status flag for L2 sptrace routine", ERROR_CODES_FILE_WRITE_ACCESS); return 1; } if (fclose(outputfile)) { write_key_to_file(ERROR_CODES_FILE, REF_ERROR_CODES_FILE, "L2STATTR", -7, "Status flag for L2 sptrace 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, "L2STATTR", RETURN_FLAG, "Status flag for L2 sptrace routine", ERROR_CODES_FILE_WRITE_ACCESS); return 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; } }
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; } }
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; } }