/** * Function: get_fits_header * Returns the header of extension hdunum from a fits file filename * * Parameters: * @param filename The name of the FITS file * @param hdunum the number of the HDU to access * * Returns: * @return a pointer to a newly allocated string containing the entire header */ char * get_fits_header (char filename[], int hdunum) { fitsfile *input; int f_status = 0, hdutype; int nkeys, i; char card[FLEN_CARD]; char *header, *p; // Open the file for creating/appending fits_open_file (&input, filename, READONLY, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_fits_header: Could not open" " file:", filename); } fits_movabs_hdu (input, hdunum, &hdutype, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_fits_header: " "Could not read extention %d from file: %s", hdunum, filename); } fits_get_hdrspace (input, &nkeys, NULL, &f_status); /* get # of keywords */ header = (char *) malloc ((nkeys + 1) * FLEN_CARD * sizeof (char)); p = header; for (i = 0; i < nkeys; i++) { /* Read and print each keywords */ if (fits_read_record (input, i + 1, card, &f_status)) break; sprintf(p,"%-80s", card); p = p + 80; } /* Add END keyword */ sprintf (card, "END"); sprintf(p,"%-80s", card); return header; }
/** * Function: get_lcolumn_from_SPC_opened * The function reads the values from a column with long specified * by its name into a array of type long. The array is returned. * * Parameters: * @param SPC_ptr - pointer to the SPC extension * @param count_col - name of the column to load * @param nelems - number of elements in the column * * Returns: * @return values - pointer to a filled array */ long * get_lcolumn_from_SPC_opened(fitsfile *SPC_ptr, char colname[], int nelems) { int colnum=0; int anynul; int f_status=0; long *values; // allocate the return array; // give an error if allocation fails values = (long *) malloc(nelems * sizeof(long)); if (!values) { aXe_message (aXe_M_ERROR, __FILE__, __LINE__, "Memory allocation failed"); } // get the desired column number; // give an error if the column name // can not be read fits_get_colnum (SPC_ptr, CASEINSEN, colname, &colnum, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_dcolumn_from_SPC_opened: " "Could not determine column %s in " " table!\n", colname); } // read all data in the column fits_read_col (SPC_ptr, TLONG, colnum, 1, 1, nelems, NULL, values, &anynul, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_dcolumn_from_SPC_opened: " "Could not read column %s" " from BINARY table!",colname); } // return the filled array return values; }
/** * Function: get_SPC_opened * The function opens an existing SPC file and returns the pointer * to it. * As of now, the mode of opening it is automatically READWRITE. * Later on a differentiation using the free parameter "mode" * might be added to generalize the function. * * Parameters: * @param SPCname - name of the SPC file * @param mode - mode to open it (not yet used) * * Returns: * @return SPC_ptr - pointer to the opened fits file * */ fitsfile * get_SPC_opened(char SPCname[], int mode) { fitsfile *SPC_ptr; int f_status=0; // Open the OPET file for reading/writing fits_open_file (&SPC_ptr, SPCname, READWRITE, &f_status); if (f_status) { ffrprt (stdout, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_INTPIXCORR: Could not open file: %s\n", SPCname); } // return the pointer to the fits file return SPC_ptr; }
/** * Function: get_num_extensions * The function determines the number of extensions in * the fits file. Here the primary extension does not count. * * Parameters: * @param spectral_models_file - pathname to the spectral models file * * Returns: * @return n_models - the number of spectral models */ int get_num_extensions(const char spectral_models_file[]) { int n_ext=0; int n_models=0; int i; int f_status=0; fitsfile *s_models; // open the fits file // report any error fits_open_file (&s_models, spectral_models_file, READONLY, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PETCONT: " "Could not open file: %s", spectral_models_file); } // do until a fits error occurs while (!f_status) { // move one extension forward fits_movrel_hdu (s_models, 1, NULL, &f_status); // count up n_ext++; } // close the fits file fits_close_file (s_models, &f_status); // the zeroth extension // does nnot count!! n_models = n_ext - 1; // return the return n_models; }
int main (int argc, char *argv[]) { char *opt; char grism_file[MAXCHAR]; char grism_file_path[MAXCHAR]; char aper_file[MAXCHAR]; char aper_file_path[MAXCHAR]; char obj_PET_file[MAXCHAR]; char obj_PET_file_path[MAXCHAR]; char bck_PET_file[MAXCHAR]; char bck_PET_file_path[MAXCHAR]; char conf_file[MAXCHAR]; char conf_file_path[MAXCHAR]; char SPC_file[MAXCHAR]; char SPC_file_path[MAXCHAR]; char SPC_opt_file[MAXCHAR]; char SPC_opt_file_path[MAXCHAR]; char WHT_file[MAXCHAR]; char WHT_file_path[MAXCHAR]; char label[MAXCHAR]; int i, index, dobck = 0, noflux = 1; object **oblist; FITScards *cards; ap_pixel *obj_PET = NULL, *bck_PET = NULL; observation *obs; //tracestruct *trace; aperture_conf *conf; spectrum *obj_spec = NULL, *bck_spec = NULL, *sobj_spec = NULL; spectrum *resp; response_function *resp_func; calib_function *wl_calibration; fitsfile *OPET_ptr, *BPET_ptr; int f_status = 0; fitsfile *SPC_ptr, *SPC_opt_ptr, *WHT_ptr; gsl_matrix *weights; drzstamp *modvar; int obj_aperID, obj_beamID, objindex; int bck_aperID, bck_beamID; char table[MAXCHAR], table_path[MAXCHAR]; //char comment[FLEN_COMMENT]; int empty; int drizzle; int quant_cont=0; int opt_weights=0; int for_grism=0; int smooth_conv=0; d_point smooth_params; double exptime; double sky_cps; drzstamp_dim dimension; gsl_matrix *coverage; if (((argc < 3)) || (opt = get_online_option ("help", argc, argv))) { fprintf (stdout, "ST-ECF European Coordinating Facility\n" "Copyright (C) 2002 Martin Kuemmel\n" "aXe_PET2SPC Version %s:\n" " aXe task that produces 1-D, binned spectra using information\n" " contained in a OPET and a BPET. A 1-D spectrum is generated\n" " for each beam in each of both the OPET and the BPET files\n" " The binned background spectra of each beam (order) is then\n" " subtraced from the corresponding spectra form the OPET. Th\ne" " background subtraction (and reading a BPET altogether can be\n" " avoided by using the -noBPET option\n" " An SPC file, a multi-extension FITS file containing binned\n" " spectra is produced. Each extension (named after the beam ID,\n" " e.g. 11B for aperture (object) 11,beam (order) B) contains the\n" " following columns:\n" "\n" " LAMBDA ; the wavelength (in A)\n" " TCOUNT ; the total number of counts (in DN)\n" " TERROR ; the error in TERRORS (in DN)\n" " BCOUNT ; the estimated number of counts from the\n" " background (in DN)\n" " BERROR ; the error in BCOUNTS (in DN)\n" " COUNT ; the estimated number of counts from the\n" " object (in DN)\n" " ERROR ; the error in COUNTS (in DN)\n" " FLUX ; the estimated flux (in erg/s/cm^2/A)\n" " FERROR ; the error in FLUX (in erg/s/cm^s/A)\n" " WEIGHT ; weight (in pixels)\n" "\n" " Input FITS mages are looked for in $AXE_IMAGE_PATH\n" " aXe config file is looked for in $AXE_CONFIG_PATH\n" " All outputs are writen to $AXE_OUTPUT_PATH\n" "\n" "Usage:\n" " aXe_PET2SPC [g/prism image filename] [aXe config file name] [options]\n" "\n" "Options:\n" " -noBPET - to disable the use of a BPET file\n" " -noflux - to disable the flux calibration\n" " -drz - use $AXE_DRIZZLE_PATH to locate the grism-, OAF-\n" " - and PET-files instead of $AXE_IMAGE/OUTPUT_PATH\n" " -in_AF=[string] - overwrite the default input Aperture File name\n" " -OPET=[string] - overwrite the default input Object PET file name\n" " -BPET=[string] - overwrite the default input Background PET\n" " file name\n" " -out_SPC=[string] - overwrite the default output SPC file name\n" "\n" "Example:\n" " ./aXe_PET2SPC slim_grism.fits SLIM.conf.A.0\n" "\n",RELEASE); exit (1); } // make a general opening statement fprintf (stdout, "aXe_PET2SPC: Starting...\n"); // get the name of the flt-file index = 0; strcpy (grism_file, argv[++index]); if ((opt = get_online_option ("drz", argc, argv))) { build_path (AXE_DRIZZLE_PATH, grism_file, grism_file_path); drizzle=1; } else { build_path (AXE_IMAGE_PATH, grism_file, grism_file_path); drizzle=0; } // get the name of the configuration file strcpy (conf_file, argv[++index]); build_path (AXE_CONFIG_PATH, conf_file, conf_file_path); // load the configuration file conf = get_aperture_descriptor (conf_file_path); // Determine where the various extensions are in the FITS file get_extension_numbers(grism_file_path, conf,conf->optkey1,conf->optval1); // Build aperture file name replace_file_extension (grism_file, aper_file, ".fits", ".OAF", conf->science_numext); if (drizzle) build_path (AXE_DRIZZLE_PATH, aper_file, aper_file_path); else build_path (AXE_OUTPUT_PATH, aper_file, aper_file_path); // Build object PET file name replace_file_extension (grism_file, obj_PET_file, ".fits", ".PET.fits", conf->science_numext); // make the total filename if (drizzle) build_path (AXE_DRIZZLE_PATH, obj_PET_file, obj_PET_file_path); else build_path (AXE_OUTPUT_PATH, obj_PET_file, obj_PET_file_path); // Build background PET file name replace_file_extension (grism_file, bck_PET_file, ".fits", ".BCK.PET.fits", conf->science_numext); // make the total filename if (drizzle) build_path (AXE_DRIZZLE_PATH, bck_PET_file, bck_PET_file_path); else build_path (AXE_OUTPUT_PATH, bck_PET_file, bck_PET_file_path); // make a non-standard AF name if necessary if ((opt = get_online_option ("in_AF", argc, argv))) { strcpy(aper_file,opt); strcpy(aper_file_path,opt); } // make a non-standard PET name if necessary if ((opt = get_online_option ("OPET", argc, argv))) { strcpy(obj_PET_file,opt); strcpy(obj_PET_file_path,opt); } // make a non-standard BPET name if necessary if ((opt = get_online_option ("BPET", argc, argv))) { strcpy(bck_PET_file,opt); strcpy(bck_PET_file_path,opt); } // set the flagg for no background subtraction if ((opt = get_online_option ("noBPET",argc,argv))) { dobck = 0; strcpy(bck_PET_file,"None"); strcpy(bck_PET_file_path, "None"); } else { dobck = 1; } // set the flagg for flux if ((opt = get_online_option ("noflux",argc,argv))) noflux = 1; else noflux = 0; // check for the weights flagg, // set the file name if the flagg is set if ((opt = get_online_option ("opt_weights",argc,argv))) opt_weights = 1; else opt_weights = 0; // read the trigger for smoothing the sensitivity if ((opt = get_online_option ("smooth_conv",argc,argv))) smooth_conv = 1; else smooth_conv = 0; if ((opt = get_online_option ("out_SPC", argc, argv))) { strcpy (SPC_file, opt); strcpy (SPC_file_path, opt); if (opt_weights) { replace_file_extension (SPC_file, SPC_opt_file, ".fits", "_opt.SPC.fits", -1); replace_file_extension (SPC_file_path, SPC_opt_file_path, ".fits", "_opt.SPC.fits", -1); replace_file_extension (SPC_opt_file, WHT_file, ".SPC.fits", ".WHT.fits", -1); replace_file_extension (SPC_opt_file_path, WHT_file_path, ".SPC.fits", ".WHT.fits", -1); } } else { replace_file_extension (obj_PET_file, SPC_file, ".PET.fits", ".SPC.fits", -1); if (drizzle) build_path (AXE_DRIZZLE_PATH, SPC_file, SPC_file_path); else build_path (AXE_OUTPUT_PATH, SPC_file, SPC_file_path); if (opt_weights) { replace_file_extension (obj_PET_file, SPC_opt_file, ".PET.fits", "_opt.SPC.fits", -1); replace_file_extension (SPC_opt_file, WHT_file, ".SPC.fits", ".WHT.fits", -1); if (drizzle) { build_path (AXE_DRIZZLE_PATH, SPC_opt_file, SPC_opt_file_path); build_path (AXE_DRIZZLE_PATH, WHT_file, WHT_file_path); } else { build_path (AXE_OUTPUT_PATH, SPC_opt_file, SPC_opt_file_path); build_path (AXE_OUTPUT_PATH, WHT_file, WHT_file_path); } } } // check the configuration file for the smoothin keywords if (!check_conf_for_smoothing(conf, smooth_conv)) aXe_message(aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SP: Either the configuration file %s does not contain\n" "the necessary keywords for the smoothing (POBJSIZE, SMFACTOR),\n" "or one of these keywords has an unreasonable value < 0.0!\n", conf_file_path); // give feedback onto the screen: // report on input and output // and also on specific parameter fprintf (stdout, "aXe_PET2SPC: Input configuration file name: %s\n", conf_file_path); fprintf (stdout, "aXe_PET2SPC: Input Object Aperture file name: %s\n", aper_file_path); fprintf (stdout, "aXe_PET2SPC: Input Object PET file name: %s\n", obj_PET_file_path); if (dobck) fprintf (stdout, "aXe_PET2SPC: Input Background PET file name: %s\n", bck_PET_file_path); fprintf (stdout, "aXe_PET2SPC: Output SPC file name: %s\n", SPC_file_path); if (opt_weights) { fprintf (stdout, "aXe_PET2SPC: Computing optimal weights.\n"); fprintf (stdout, "aXe_PET2SPC: Optimized SPC file name: %s\n", SPC_opt_file_path); fprintf (stdout, "aXe_PET2SPC: Output WHT file name: %s\n", WHT_file_path); } if (!noflux) { fprintf (stdout, "aXe_PET2SPC: Performing flux calibration.\n"); if (smooth_conv) fprintf (stdout, "aXe_PET2SPC: Using smoothed sensitivity curves.\n"); } fprintf (stdout, "\n\n"); // // try to get the descriptor 'exptime' from the 'sci'-extension // exptime = (double)get_float_from_keyword(grism_file_path, conf->science_numext, conf->exptimekey); if (isnan(exptime)) exptime = (double)get_float_from_keyword(grism_file_path, 1, conf->exptimekey); if (isnan(exptime)) exptime = 1.0; // // try to get the descriptor 'SKY_CPS' from the 'sci'-extension // sky_cps = (double)get_float_from_keyword(grism_file_path, conf->science_numext, "SKY_CPS"); if (isnan(sky_cps)) sky_cps = 0.0; // Open the OPET file for reading fits_open_file (&OPET_ptr, obj_PET_file_path, READONLY, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SPC: Could not open file: %s\n", obj_PET_file_path); } // check whether the contamination is quantitative quant_cont = check_quantitative_contamination(OPET_ptr); if (opt_weights && !quant_cont) aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SPC: The optimal extractions needs quantitative contamination! " " Please re-run aXe with Gauss or Fluxcube contamination!"); obs = load_dummy_observation (); /* Loading the object list */ fprintf (stdout, "aXe_PET2SPC: Loading object aperture list..."); oblist = file_to_object_list_seq (aper_file_path, obs); fprintf (stdout,"%d objects loaded.\n",object_list_size(oblist)); if (dobck) { // Open the file for reading fits_open_file (&BPET_ptr, bck_PET_file_path, READONLY, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SP: Could not open file: %s\n", bck_PET_file_path); } } /* Copy the header info from the grism image */ SPC_ptr = create_SPC_opened (SPC_file_path,1); cards = get_FITS_cards_opened(OPET_ptr); put_FITS_cards_opened(SPC_ptr, cards); free_FITScards(cards); if (opt_weights) { cards = get_FITS_cards_opened(OPET_ptr); // open the WHT file and add the header keywords WHT_ptr = create_FITSimage_opened (WHT_file_path, 1); put_FITS_cards_opened(WHT_ptr, cards); // open the opt_SPC and add the header keywords SPC_opt_ptr = create_SPC_opened (SPC_opt_file_path,1); put_FITS_cards_opened(SPC_opt_ptr, cards); // delete the header keywords free_FITScards(cards); } // do something only if there // exist valid objects i = 0; if (oblist!=NULL) { // turn until the end of the PET is reached while (1) { empty=0; // Get the PET for this object obj_PET = get_ALL_from_next_in_PET(OPET_ptr, &obj_aperID, &obj_beamID); // load the background PET if requested if (dobck) { bck_PET = get_ALL_from_next_in_PET(BPET_ptr, &bck_aperID, &bck_beamID); if ((bck_aperID!=obj_aperID)||(bck_beamID!=obj_beamID)) aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "Background PET and Object PET extensions are not" " in the same order and cannot be combined.\n"); } // end of PET reached: the break condition if ((obj_aperID==-1) && (obj_beamID==-1)) break; // signal an empty PET if (obj_PET==NULL) empty=1; // give feedback to the screen fprintf (stdout, "aXe_PET2SPC: BEAM %d; %d%c\n", i, obj_aperID, BEAM(obj_beamID));fflush(stdout); // identify the object which matches the PET objindex = find_object_in_object_list(oblist,obj_aperID); // look whether we are for grisms or prisms for_grism = check_for_grism (conf_file_path, obj_beamID); wl_calibration = get_calfunc_for_beam(oblist[objindex]->beams[obj_beamID], for_grism, conf_file_path, conf); // compute the object spectrum obj_spec = bin_naive (obj_PET, oblist[objindex]->beams[obj_beamID].width, oblist[objindex]->beams[obj_beamID].orient, quant_cont); // check for the existence of a background PET if (dobck) { // compute the background spectrum bck_spec = bin_naive (bck_PET, oblist[objindex]->beams[bck_beamID].width, oblist[objindex]->beams[bck_beamID].orient, quant_cont); } else { // create a dummy background spectrum bck_spec = empty_counts_spectrum_copy(obj_spec); } // subtract the background spectrum from the // object (or forground) spectrum sobj_spec = subtract_spectra (obj_spec, bck_spec); if(!noflux) { get_troughput_table_name(conf_file_path, oblist[objindex]->beams[obj_beamID].ID, table); if (strcmp(table,"None")) { build_path (AXE_CONFIG_PATH, table, table_path); resp=get_response_function_from_FITS(table_path,2); resp_func = create_response_function(table_path); if (resp->spec_len <2) { aXe_message (aXe_M_WARN1, __FILE__, __LINE__, "Throughput table %s contains only %d" " values. No sensitivity curve was applied.\n", table_path,resp->spec_len); } else { fprintf(stdout,"aXe_PET2SPC: Applying sensitivity contained in %s\n",table_path); smooth_params = get_smooth_pars_for_beam(conf, smooth_conv, oblist[objindex]->beams[obj_beamID]); if (smooth_params.x > 0.0) { // apply a smoothed flux conversion apply_smoothed_response(wl_calibration, for_grism, quant_cont, resp_func, smooth_params, sobj_spec); } else { // apply a normal flux conversion apply_response_function(sobj_spec,resp, quant_cont); } } // free the memory of the // response functions free_spectrum(resp); free_response_function(resp_func); } } if (empty!=1) { add_spectra_to_SPC_opened (SPC_ptr, obj_spec, bck_spec, sobj_spec, oblist[objindex]->ID, oblist[objindex]->beams[obj_beamID].ID); /* Copy header from OPET extension into this SPC extension */ cards = get_FITS_cards_opened(OPET_ptr); put_FITS_cards_opened(SPC_ptr,cards); free_FITScards(cards); } free_spectrum (bck_spec); free_spectrum (sobj_spec); free_spectrum (obj_spec); if (opt_weights) { // get the dimension in trace length // and crossdispersion dimension = get_all_dims(obj_PET, bck_PET, oblist[objindex]->beams[obj_beamID], dobck); // check for empty PET if (!dimension.resolution) { // create dummies in case of empty PET's weights = get_default_weight(); modvar = get_default_modvar(); } else { // prepare the PET's by computing the inverse variance. // Also the trace distances are shifted by 0.5 // to get a sampling comparable to the unweighted // extraction prepare_inv_variance(obj_PET, bck_PET, dobck, conf, exptime, sky_cps, 0.0); // compute the inverse variance and the profile // image in the trace distance - crossdispersion plane modvar = compute_modvar(obj_PET, oblist[objindex]->beams[obj_beamID], dimension); // compute the optimal weights weights = comp_allweight(modvar); } if (dimension.resolution && empty != 1) { sprintf (label, "WHT_%d%c", obj_aperID, BEAM (obj_beamID)); gsl_to_FITSimage_opened (weights, WHT_ptr ,0,label); // make and store the default header cards = beam_to_FITScards(oblist[objindex],obj_beamID); put_FITS_cards_opened(WHT_ptr,cards); free_FITScards(cards); } // create the optimal weighted // foreground spectrum obj_spec = bin_optimal (obj_PET,oblist[objindex]->beams[obj_beamID], quant_cont, weights, dimension, coverage); // check for the presence of a background PET if (dobck) { // create the optimal weighted // background spectrum bck_spec = bin_optimal (bck_PET,oblist[objindex]->beams[obj_beamID], quant_cont, weights, dimension, coverage); } else { // make a dummy background spectrum bck_spec = empty_counts_spectrum_copy(obj_spec); } // release memory gsl_matrix_free(weights); free_drzstamp(modvar); // subtract the background spectrum from the // object (or forground) spectrum sobj_spec = subtract_spectra (obj_spec, bck_spec); if(!noflux) { get_troughput_table_name(conf_file_path, oblist[objindex]->beams[obj_beamID].ID, table); if (strcmp(table,"None")) { build_path (AXE_CONFIG_PATH, table, table_path); resp=get_response_function_from_FITS(table_path,2); resp_func = create_response_function(table_path); if (resp->spec_len <2) { aXe_message (aXe_M_WARN1, __FILE__, __LINE__, "Throughput table %s contains only %d" " values. No sensitivity curve was applied.\n", table_path,resp->spec_len); } else { fprintf(stdout,"aXe_PET2SPC: Applying sensitivity contained in %s\n",table_path); smooth_params = get_smooth_pars_for_beam(conf, smooth_conv, oblist[objindex]->beams[obj_beamID]); if (smooth_params.x > 0.0) { apply_smoothed_response(wl_calibration, for_grism, quant_cont, resp_func, smooth_params, sobj_spec); } else { apply_response_function(sobj_spec,resp, quant_cont); } } // free the memory free_spectrum(resp); free_response_function(resp_func); } } if (empty!=1) { add_spectra_to_SPC_opened (SPC_opt_ptr, obj_spec, bck_spec, sobj_spec, oblist[objindex]->ID, oblist[objindex]->beams[obj_beamID].ID); /* Copy header from OPET extension into this SPC extension */ cards = get_FITS_cards_opened(OPET_ptr); put_FITS_cards_opened(SPC_opt_ptr,cards); free_FITScards(cards); } free_spectrum (bck_spec); free_spectrum (sobj_spec); free_spectrum (obj_spec); } // free memory free_calib (wl_calibration); if (bck_PET!=NULL) free (bck_PET); if (obj_PET!=NULL) free (obj_PET); i++; } } fits_close_file (SPC_ptr, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SPC: " "Error closing SPC: %s\n", SPC_file_path); } if (opt_weights) { fits_close_file (WHT_ptr, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SPC: " "Error closing WHT: %s\n", WHT_file_path); } fits_close_file (SPC_opt_ptr, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_PET2SPC: " "Error closing PSC: %s\n", SPC_opt_file_path); } } if (oblist!=NULL) free_oblist (oblist); fprintf (stdout, "aXe_PET2SPC: Done...\n"); exit (0); }
/** * Function: get_ALL_from_next_in_SPC * The function creates and fills a full spectrum structure with * the content of a SPC table extension. This is only done when, * according to the beam ID, this beam should be corrected. * For extensions with higher order beams which are not corrected * an emply structure is returned. * * Parameters: * @param SPCn_ptr - pointer to the opened SPC file * @param aperID - pointer to aperture identification number * @param beamID - pointer to beam identification number * * Returns: * @return SPC - the full spectrum structure */ full_spectr * get_ALL_from_next_in_SPC(fitsfile *SPC_ptr, int *aperID, int *beamID) { int f_status=0, hdutype; long tmp; //long nrows=0; char comment[FLEN_COMMENT]; full_spectr *SPC; fits_movrel_hdu (SPC_ptr, 1, &hdutype, &f_status); if (f_status) { *aperID = -1; *beamID = -1; SPC = NULL; return SPC; } // read the beam ID number fits_read_key_lng (SPC_ptr, "BEAMID", &tmp, comment, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_ALL_from_next_in_SPC: Error getting index keyword OBJECTID"); } *beamID = (int)tmp; // check whether this beam should be correct if (*beamID > CORRMAX) { // set it to NULL and return SPC = NULL; // fprintf (stdout, "aXe_PETFF: Skipping beam: %c.\n", BEAM(*beamID)); return SPC; } // the beam shall be corrected and // first must be read in SPC = (full_spectr *) malloc (sizeof (full_spectr )); // transfer the beam ID SPC->beamID = (int)tmp; // read the aperture number fits_read_key_lng (SPC_ptr, "OBJECTID", &tmp, comment, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_ALL_from_next_in_SPC: Error getting index keyword OBJECTID"); } // transfer the aperture ID *aperID = (int)tmp; SPC->aperID = (int)tmp; // Get the number of rows fits_get_num_rows (SPC_ptr, &tmp, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "get_ALL_from_next_in_SPC: " "Could not determine the number of rows in" " correction function table!"); } SPC->nelems = (int)tmp; // load the background subtracted object spectrum SPC->obj_spec = get_spectrum_from_SPC(SPC_ptr, "COUNT", "ERROR", SPC->nelems); // load the total object spectrum SPC->fgr_spec = get_spectrum_from_SPC(SPC_ptr, "TCOUNT", "TERROR", SPC->nelems); // load the background spectrum SPC->bck_spec = get_spectrum_from_SPC(SPC_ptr, "BCOUNT", "BERROR", SPC->nelems); // return the filled structure return SPC; }
/** * Function: load_SED_from_fitsext * The function creates a energy distribution from the data stored * in a fits file extension. The data must be stored in the columns * "wavelength" and "flux". * * Parameters: * @param spectral_models_file - pathname to the spectral models file * @param s_models - pointer to the fits file extension * * Returns: * @return sed - the energy distribution created */ energy_distrib * load_SED_from_fitsext(const char spectral_models_file[], fitsfile *s_models) { int f_status=0; int anynul; long nrows=0; int colnum1; int colnum2; energy_distrib *sed; double *sed_wavs; double *sed_flux; // allocate memory for the energy distribution sed = (energy_distrib *) malloc(sizeof(energy_distrib)); // get number of rows fits_get_num_rows (s_models, &nrows, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "load_SED_from_fitsext: " "Could not determine the number of rows in" " table %s",spectral_models_file); } // allocate memory for the data sed_wavs = (double *) malloc(nrows*sizeof(double)); if (!sed_wavs) { aXe_message (aXe_M_ERROR, __FILE__, __LINE__, "Memory allocation failed"); } sed_flux = (double *) malloc(nrows*sizeof(double)); if (!sed_flux) { aXe_message (aXe_M_ERROR, __FILE__, __LINE__, "Memory allocation failed"); } // get the column number for the wavelength fits_get_colnum (s_models, CASEINSEN, "WAV_NM", &colnum1, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "create_interp_ftable: " "Could not determine column %s in " " table %s", "WAV_NM", spectral_models_file); } // read the wavelength fits_read_col (s_models, TDOUBLE, colnum1, 1, 1, nrows, NULL, sed_wavs, &anynul, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "load_SED_from_fitsext: " "Could not read content of WAVELENGTH column " " from BINARY table %s", spectral_models_file); } // get the column number for the flux fits_get_colnum (s_models, CASEINSEN, "FLUX", &colnum2, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "create_interp_ftable: " "Could not determine column %s in " " table %s", "FLUX", spectral_models_file); } // read the flux column fits_read_col (s_models, TDOUBLE, colnum2, 1, 1, nrows, NULL, sed_flux, &anynul, &f_status); if (f_status) { ffrprt (stderr, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "load_SED_from_fitsext: " "Could not read content of FLUX column " " from BINARY table %s", spectral_models_file); } // transfer the vector and length information // to the SED object sed->npoints = nrows; sed->wavelength = sed_wavs ; sed->flux = sed_flux; // allocate some structures for the interpolator sed->interp = gsl_interp_alloc (SMODEL_INTERP_TYPE, (size_t)sed->npoints ); sed->accel = gsl_interp_accel_alloc (); // initialize the iterpolator gsl_interp_init (sed->interp, sed->wavelength, sed->flux, (size_t)sed->npoints); // return the energy distribution return sed; }
int main (int argc, char *argv[]) { char *opt; char aper_file[MAXCHAR]; char aper_file_path[MAXCHAR]; char conf_file[MAXCHAR]; char conf_file_path[MAXCHAR]; char grism_file[MAXCHAR]; char grism_file_path[MAXCHAR]; char PET_file[MAXCHAR]; char PET_file_path[MAXCHAR]; // char outputroot[MAXCHAR]; // char outputroot_path[MAXCHAR]; char STP_file[MAXCHAR]; char STP_file_path[MAXCHAR]; // char output_path[MAXCHAR]; aperture_conf *conf; object **oblist; observation *obs; ap_pixel *PET; int index, i; char label[MAXCHAR]; fitsfile *PET_ptr, *STP_ptr; int f_status = 0; int aperID, beamID, objindex; FITScards *cards; FITScards *xymin_cards; gsl_matrix *rstamp; drzstamp *drzstmp; drzstamp_dim dim; int rectified = 0; //int drizzled = 0; int drizzle=0; int drzstamp=0; int for_grism=0; d_point stp_min; if ((argc < 3) || (opt = get_online_option ("help", argc, argv))) { fprintf (stdout, "ST-ECF European Coordinating Facility\n" "aXe_STAMPS Version %s:\n" " Task that generates some Postscript stamp images from the\n" " content of a Pixel Extraction Table (PET)\n" " The trace is overplotted and is generated from the group\n" " of pixels in the PET which have the smallest projected distance\n" " to the trace in the PET. No analytical a-priori trace function \n" " is used.\n" "\n" "Usage:\n" " aXe_STAMPS g/prism_filename configuration_filename [options]\n" "\n" "Options:\n" " -rectified - produces rectified stamp image following the\n" " direction of the extraction process\n" " -drz - use $AXE_DRIZZLE_PATH to locate the grism-, OAF-\n" " and PET-files instead of $AXE_IMAGE/OUTPUT_PATH\n" " -in_AF=[string] - overwrite the automatically generated name\n" " of the input aperture file\n" " -in_PET=[string] - overwrite the automatically generated name\n" " of the input PET file\n" " -out_STP=[string] - overwrite the automatically generated name\n" " of the output stamp FITS image\n" "\n",RELEASE); exit (1); } fprintf (stdout, "aXe_STAMPS: Starting...\n"); index = 0; strcpy (grism_file, argv[++index]); if ((opt = get_online_option ("drz", argc, argv))){ build_path (AXE_DRIZZLE_PATH, grism_file, grism_file_path); drizzle=1; } else{ build_path (AXE_IMAGE_PATH, grism_file, grism_file_path); drizzle=0; } strcpy (conf_file, argv[++index]); build_path (AXE_CONFIG_PATH, conf_file, conf_file_path); conf = get_aperture_descriptor (conf_file_path); /* Determine where the various extensions are in the FITS file */ get_extension_numbers(grism_file_path, conf,conf->optkey1,conf->optval1); /* Build aperture file name */ if ((opt = get_online_option("in_AF", argc, argv))){ /* get it */ strcpy (aper_file, opt); strcpy (aper_file_path, opt); } else { replace_file_extension (grism_file, aper_file, ".fits", ".OAF", conf->science_numext); if (drizzle) build_path (AXE_DRIZZLE_PATH, aper_file, aper_file_path); else build_path (AXE_OUTPUT_PATH, aper_file, aper_file_path); } if ((opt = get_online_option("in_PET", argc, argv))){ /* get it */ strcpy (PET_file, opt); strcpy (PET_file_path, opt); } else{ /* Build object PET file name */ replace_file_extension (grism_file, PET_file, ".fits", ".PET.fits", conf->science_numext); if (drizzle) build_path (AXE_DRIZZLE_PATH, PET_file, PET_file_path); else build_path (AXE_OUTPUT_PATH, PET_file, PET_file_path); } if ( (opt = get_online_option ("out_STP", argc, argv)) ) { strcpy (STP_file, opt); // strcpy (STP_file_PATH, opt); } else { // replace_file_extension (PET_file, STP_file, ".PET.fits", ".STP.fits",-1); replace_file_extension (grism_file, STP_file, ".fits", ".STP.fits",conf->science_numext); } if (drizzle) build_path (AXE_DRIZZLE_PATH, STP_file, STP_file_path); else build_path (AXE_OUTPUT_PATH, STP_file, STP_file_path); if ((opt=get_online_option("rectified",argc,argv))) rectified = 1; else if ((opt = get_online_option ("drzstamp", argc, argv))) drzstamp=1; // give feedback onto the screen: // report on input and output // and also on specific parameters fprintf (stdout, "aXe_STAMPS: Input Image file name: %s\n", grism_file_path); fprintf (stdout, "aXe_STAMPS: Input Aperture file name: %s\n", aper_file_path); fprintf (stdout, "aXe_STAMPS: Input PET file name: %s\n", PET_file_path); fprintf (stdout, "aXe_STAMPS: Name of STP file : %s\n", STP_file_path); if (rectified) fprintf (stdout, "aXe_STAMPS: Producing rectified stamp images.\n"); else if (drzstamp) fprintf (stdout, "aXe_STAMPS: Producing drizzled stamp images.\n"); else fprintf (stdout, "aXe_STAMPS: Producing trace stamp images.\n"); // Loading the object list obs = load_dummy_observation (); fprintf (stdout, "\naXe_STAMPS: Loading object aperture list..."); oblist = file_to_object_list_seq (aper_file_path, obs); fprintf (stdout,"%d objects loaded.\n\n",object_list_size(oblist)); // Open the OPET file for reading fits_open_file (&PET_ptr, PET_file_path, READONLY, &f_status); if (f_status) { ffrprt (stdout, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_STAMPS: Could not open file: %s\n", PET_file_path); } STP_ptr = create_FITSimage_opened (STP_file_path, 1); i = 0; if (oblist!=NULL) { while (1) { /* Get the PET for this object */ PET = get_ALL_from_next_in_PET(PET_ptr, &aperID, &beamID); if ((aperID==-1) && (beamID==-1)) break; fprintf (stdout, "aXe_STAMPS: BEAM %d%c.", aperID, BEAM(beamID)); objindex = find_object_in_object_list(oblist,aperID); sprintf (label, "%s.%d%c.ps/CPS", STP_file_path, oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID)); // determine the minimum in x and y stp_min.x = -1.0; stp_min.y = -1.0; // special treatment for FORS2: dirzzled stamp images if (drzstamp) { for_grism = check_for_grism (conf_file_path, beamID); if (!for_grism) aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_STAMPS: Drizzled stamp images are not\n" "supported for prism images. Please choose a different option!\n"); // get the dimensions of the drizzled stamp dim = get_stamp_dim(PET, oblist[objindex]->beams[beamID].width, conf, beamID, &stp_min); // fill the drzstamp structure (counts plus weight matrix) drzstmp = drizzled_stamp_img (PET,oblist[objindex]->beams[beamID].width, oblist[objindex]->beams[beamID].orient, dim); // does this make sense interpolate_over_NaN (drzstmp->counts); // give the extension name and store the counts sprintf (label, "BEAM_%d%c",oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID)); gsl_to_FITSimage_opened (drzstmp->counts, STP_ptr ,0,label); // in case that the stamp is no dummy, make and store the WCS header if (dim.resolution) { cards = get_WCS_FITScards(dim.xstart*dim.resolution, dim.resolution, dim.ystart); put_FITS_cards_opened(STP_ptr,cards); free_FITScards(cards); } // make and store the default header cards = beam_to_FITScards(oblist[objindex],beamID); xymin_cards = stpmin_to_FITScards(stp_min); put_FITS_cards_opened(STP_ptr,cards); put_FITS_cards_opened(STP_ptr,xymin_cards); free_FITScards(cards); free_FITScards(xymin_cards); // give the extension name and store the weight image sprintf (label, "WEIG_%d%c",oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID)); gsl_to_FITSimage_opened (drzstmp->weight, STP_ptr ,0,label); // in case that the stamp is no dummy, make and store the WCS header if (dim.resolution) { cards = get_WCS_FITScards(dim.xstart*dim.resolution, dim.resolution, dim.ystart); put_FITS_cards_opened(STP_ptr,cards); free_FITScards(cards); } // make and store the default header cards = beam_to_FITScards(oblist[objindex],beamID); xymin_cards = stpmin_to_FITScards(stp_min); put_FITS_cards_opened(STP_ptr,cards); put_FITS_cards_opened(STP_ptr,xymin_cards); free_FITScards(cards); free_FITScards(xymin_cards); // free the structure with the count and weight matrix free_drzstamp(drzstmp); } else { if (rectified) { rstamp = rectified_stamp_img (PET,oblist[objindex]->beams[beamID].width, &stp_min); } else { rstamp = stamp_img (PET,oblist[objindex]->beams[beamID].width, &stp_min); } sprintf (label, "BEAM_%d%c",oblist[objindex]->ID, BEAM (oblist[objindex]->beams[beamID].ID)); interpolate_over_NaN (rstamp); gsl_to_FITSimage_opened (rstamp, STP_ptr ,0,label); cards = beam_to_FITScards(oblist[objindex],beamID); xymin_cards = stpmin_to_FITScards(stp_min); put_FITS_cards_opened(STP_ptr,cards); put_FITS_cards_opened(STP_ptr,xymin_cards); free_FITScards(cards); free_FITScards(xymin_cards); free_stamp_img(rstamp); } if (PET!=NULL) free(PET); fprintf (stdout, " Done.\n"); i++; } } if (oblist!=NULL) free_oblist (oblist); fits_close_file (STP_ptr, &f_status); if (f_status) { ffrprt (stdout, f_status); aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "aXe_STAMPS: Could not" " close STP file: %s\n", STP_file_path); } fprintf (stdout, "aXe_STAMPS: Done...\n"); /* Copy the header info from the grism image */ { FITScards *cards; cards = get_FITS_cards (PET_file_path, 1); put_FITS_cards(STP_file_path,1,cards); free_FITScards(cards); } exit (0); }