/** * Function: intpix_corr_pet * The function applies the intra-pixel sensitivity correction to * a list of PET pixels. The values in the pixels are corrected in * place using the correction function, gemoetrical parameters and * dispersion relation in the various parameters. * * Parameters: * @param actbeam - the beam to correct * @param conf_file_path - full path to the axe configuration file * @param ipcorr - the ipc correction function * @param PET - the list of PET pixels to correct * * Returns: * - */ void intpix_corr_pet(beam actbeam, char conf_file_path[], interpolator *ipcorr, ap_pixel *PET) { interpolator *ipclambda; aperture_conf *conf; int for_grism=0; // load the configuration file conf = get_aperture_descriptor(conf_file_path); // check whether it is grism (for_grism=1) // or prism (for_grism=0) data // give an error if there is a prism solution for_grism = check_for_grism (conf_file_path, actbeam.ID); if (!for_grism) aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "intpix_corr_beam: Only grism dispersion solution can be corrected.\n"); // determine the correction factor versus wavelength ipclambda = get_ipclambda(actbeam, conf_file_path, ipcorr); print_interp(ipclambda); // apply the correction to the PET apply_corr_pet(ipclambda, PET); // free the configuration structure free_aperture_conf(conf); // free the memory in the interpolator free_interp(ipclambda); }
/** * Function: get_ipc_lambdas * The function computes the wavelengths for a list of x-offsets from the * reference point of a certain beam. The wavelength values are * returned as a gsl-vector. * * Parameters: * @param actbeam - the beam * @param conf_file_path - the full path to the aXe configuration file * @param xvalues - the list of x-offsets * * Returns: * @return lambdas - the list of wavelength values */ gsl_vector * get_ipc_lambdas(const beam actbeam, char conf_file_path[], gsl_vector *xvalues) { aperture_conf *conf; dispstruct *disp; calib_function *wl_calib; gsl_vector *lambdas; d_point pixel; int for_grism; int i; // load the configuration file conf = get_aperture_descriptor(conf_file_path); // check whether it is grism (for_grism=1) // or prism (for_grism=0) data for_grism = check_for_grism (conf_file_path, actbeam.ID); // determine the referencee point position pixel.x = actbeam.refpoint.x - conf->refx; pixel.y = actbeam.refpoint.y - conf->refy; // determine the dispersion at the reference point disp = get_dispstruct_at_pos(conf_file_path, for_grism, actbeam.ID,pixel); // make a calibration structure from the dispersion wl_calib = create_calib_from_gsl_vector(for_grism, disp->pol); // convert the x-values to tracelength-values abscissa_to_pathlength (actbeam.spec_trace, xvalues); // allocate memory for the wavelengths lambdas = gsl_vector_alloc(xvalues->size); // go over all tracelength values for (i=0; i < xvalues->size; i++) { // determine and store the wavelength for each tracelength gsl_vector_set(lambdas, i, wl_calib->func(gsl_vector_get(xvalues, i), wl_calib->order, wl_calib->coeffs)); } // free the configuration structure free_aperture_conf(conf); // free the memory in the calibration structure free_calib(wl_calib); // free the dispersion structure free_dispstruct(disp); // return the wavelengths return lambdas; }
/** * The function computes and stores at the according position * the xy offsets of a direct image. This is only important * in the fluxcube emission model, since the image coordinates * in fluxcubes are 'filter' coordinates and do not take into * account the offsets introduce by the grism. * For each object and beam those offsets are evaluated * and stored in the direct object structure. * * @param dirlist - the direct object * @param CONF_file - the new coordinate point * */ void fill_xy_offsets(dirobject **dirlist, char CONF_file[]) { aperture_conf *conf; gsl_vector *x_coeffs; gsl_vector *y_coeffs; d_point m_point; double xoffs, yoffs; int beamID=0; int i; // load the configuration file conf = get_aperture_descriptor (CONF_file); // go over each beam defined in the configuration // file for (beamID=0; beamID < conf->nbeams; beamID++) { // determine the coeeficients for the offsets // in x and in y x_coeffs = get_beam_trace_xoff (CONF_file, beamID); y_coeffs = get_beam_trace_yoff (CONF_file, beamID); // go over each direct object i=0; while (dirlist[i] !=NULL) { // get the mean direct object position m_point = get_dirobject_meanpos(dirlist[i]); // evaluate the coefficients for the 2D variable offsets // at the mean position dirlist[i]->xy_off[beamID].x = eval_trace_off_at_pos (x_coeffs, m_point, beamID); dirlist[i]->xy_off[beamID].y = eval_trace_off_at_pos (y_coeffs, m_point, beamID); // iterate the counter i++; } // free the vectors for the coefficients gsl_vector_free(x_coeffs); gsl_vector_free(y_coeffs); } // release memory free_aperture_conf(conf); }
/** * Function: fitting_ipc_corr * * Parameters: * @param actbeam - the beam to examine * @param conf_file_path - the full pathname too the configuration file * @param ipcorr - the interpolator with the correction factor * @param SPC - the full spectrum to correct * @param obs - the grism image * @param data_matrix - background subtracted grism image * @param ipc_file_path - file name for the phase data * * Returns: * @return icorr - marker whether the correction was applied or not (1/0) */ int fitting_ipc_corr(beam act_beam, char conf_file_path[], interpolator *ipcorr, full_spectr *SPC, observation *obs, gsl_matrix *data_matrix, char ipc_file_path[], beam *beam_ptr) { aperture_conf *conf; d_point fit_qual; int icorr = 0; trace_func *tracefun = act_beam.spec_trace; double *tracedata = (double *)(tracefun->data); // load the configuration file conf = get_aperture_descriptor(conf_file_path); // determine the phase data and fix the phase // by fitting a function to it fit_qual = kappa_sigma_klipp_ipc(conf, obs, data_matrix, act_beam, ipc_file_path); // report on the shift and the quality fprintf(stdout, "shift-difference: %e, quality: %e\n", fit_qual.x, fit_qual.y); // check whether the quality is good enough if (fit_qual.y < MAXQUALITY) { // apply a correction to the // reference point to achive the // right corrections act_beam.refpoint.y += fit_qual.x; beam_ptr->refpoint.y += fit_qual.x; beam_ptr->ignore = -100; // report the new y-shift fprintf(stdout, "new y-shift: %e\n", act_beam.refpoint.y - (double)(int)(act_beam.refpoint.y + tracedata[1])); // apply the sensitivity correction to the spectrum intpix_corr_beam(act_beam, conf_file_path, ipcorr, SPC); // set the correction marker icorr=1; } // free allocated memory free_aperture_conf(conf); // return the marker return icorr; }
/** * Function: intpix_corr_beam * The functio corrects a full spectrum for the intrapixel sensitivity * variations. * For every spectral element its fractional y-value is determined, * and then the correction factor for this y-value is computed * and applied to the appropriate elements of the spectral bin. * * Parameters: * @param actbeam - the beam to examine * @param conf_file_path - the full pathname too the configuration file * @param ipcorr - the interpolator with the correction factor * @param SPC - the full spectrum to correct * * Returns: * @return - */ void intpix_corr_beam(beam actbeam, char conf_file_path[], interpolator *ipcorr, full_spectr *SPC) { int index=0; int for_grism=1; double cfactor; double lambda; gsl_vector *cdisp; d_point pixel; dispstruct *beam_disp; aperture_conf *conf; // load the configuration file conf = get_aperture_descriptor(conf_file_path); // check whether it is grism (for_grism=1) // or prism (for_grism=0) data // give an error if there is a prism solution for_grism = check_for_grism (conf_file_path, actbeam.ID); if (!for_grism) aXe_message (aXe_M_FATAL, __FILE__, __LINE__, "intpix_corr_beam: Only grism dispersion solution can be corrected.\n"); // get the wavelength dispersion relation at // position "refpoint". conf->refx and conf->refy // are used at this point to allow for a non (0,0) centered // 2D field dependence. pixel.x = actbeam.refpoint.x - conf->refx; pixel.y = actbeam.refpoint.y - conf->refy; // derive the dispersion at the object position beam_disp = get_dispstruct_at_pos(conf_file_path, for_grism, actbeam.ID, pixel); // skipp high order zeroes in the dispersion solution cdisp = condense_dispersion(beam_disp->pol); for (index=0; index < SPC->nelems; index++) { lambda = SPC->fgr_spec->spec[index].lambda_mean; if (!gsl_isnan (lambda) && lambda) { cfactor = get_intpix_corr(&actbeam, cdisp, ipcorr, lambda); fprintf(stdout, "lambda: %e, factor: %e\n", lambda, cfactor); /* SPC->fgr_spec->spec[index].count = SPC->fgr_spec->spec[index].count / cfactor; SPC->fgr_spec->spec[index].error = SPC->fgr_spec->spec[index].error / cfactor; SPC->fgr_spec->spec[index].flux = SPC->fgr_spec->spec[index].flux / cfactor; SPC->fgr_spec->spec[index].ferror = SPC->fgr_spec->spec[index].ferror / cfactor; SPC->bck_spec->spec[index].count = SPC->bck_spec->spec[index].count / cfactor; SPC->bck_spec->spec[index].error = SPC->bck_spec->spec[index].error / cfactor; SPC->bck_spec->spec[index].flux = SPC->bck_spec->spec[index].flux / cfactor; SPC->bck_spec->spec[index].ferror = SPC->bck_spec->spec[index].ferror / cfactor; SPC->obj_spec->spec[index].count = SPC->obj_spec->spec[index].count / cfactor; SPC->obj_spec->spec[index].error = SPC->obj_spec->spec[index].error / cfactor; SPC->obj_spec->spec[index].flux = SPC->obj_spec->spec[index].flux / cfactor; SPC->obj_spec->spec[index].ferror = SPC->obj_spec->spec[index].ferror / cfactor; /* this is the wqrong version!! SPC->fgr_spec->spec[index].count = SPC->fgr_spec->spec[index].count * cfactor; SPC->fgr_spec->spec[index].error = SPC->fgr_spec->spec[index].error * cfactor; SPC->fgr_spec->spec[index].flux = SPC->fgr_spec->spec[index].flux * cfactor; SPC->fgr_spec->spec[index].ferror = SPC->fgr_spec->spec[index].ferror * cfactor; SPC->bck_spec->spec[index].count = SPC->bck_spec->spec[index].count * cfactor; SPC->bck_spec->spec[index].error = SPC->bck_spec->spec[index].error * cfactor; SPC->bck_spec->spec[index].flux = SPC->bck_spec->spec[index].flux * cfactor; SPC->bck_spec->spec[index].ferror = SPC->bck_spec->spec[index].ferror * cfactor; SPC->obj_spec->spec[index].count = SPC->obj_spec->spec[index].count * cfactor; SPC->obj_spec->spec[index].error = SPC->obj_spec->spec[index].error * cfactor; SPC->obj_spec->spec[index].flux = SPC->obj_spec->spec[index].flux * cfactor; SPC->obj_spec->spec[index].ferror = SPC->obj_spec->spec[index].ferror * cfactor; */ } } // free the configuration structure free_aperture_conf(conf); // free the dispersion struct free_dispstruct(beam_disp); // free the memory for the dispersion gsl_vector_free(cdisp); }
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 specmod_file[MAXCHAR]; char specmod_file_path[MAXCHAR]; char objmod_file[MAXCHAR]; char objmod_file_path[MAXCHAR]; aperture_conf *conf; int index; double lambda_psf=0.0; observation *obs; if ((argc < 3) || (opt = get_online_option ("help", argc, argv))) { fprintf (stdout, "Usage:\n" " aXe_DISPIMAGE g/prism_filename configuration_filename" "\n" "Options:\n" " -in_AF=[string] - overwrite the automatically generated name\n" " of the input aperture file\n" " -model_spectra=[string] - input model spectra" " -model_images=[string] - input model images" " -lambda_psf=[float] - lambda at which psf was measured" "\n",RELEASE); exit (1); } fprintf (stdout, "aXe_DISPIMAGE: Starting...\n"); index = 0; strcpy (grism_file, argv[++index]); build_path (AXE_IMAGE_PATH, grism_file, grism_file_path); strcpy (conf_file, argv[++index]); build_path (AXE_CONFIG_PATH, conf_file, conf_file_path); conf = get_aperture_descriptor (conf_file_path); get_extension_numbers(grism_file_path, conf,conf->optkey1,conf->optval1); /* Get or set up the name of the output Aperture File */ if ((opt = get_online_option ("in_AF", argc, argv))) { /* get it */ strcpy (aper_file, opt); strcpy (aper_file_path, opt); } else { /* Build aperture file name */ replace_file_extension (grism_file, aper_file, ".fits", ".OAF", conf->science_numext); build_path (AXE_OUTPUT_PATH, aper_file, aper_file_path); } // determine the wavelength // the object extend was determined at if ((opt = get_online_option ("lambda_psf", argc, argv))) lambda_psf = atof(opt); else lambda_psf = 800.0; // check whether a name for the spectral // models file is given if ((opt = get_online_option ("model_spectra", argc, argv))) { // get and set up the filename strcpy (specmod_file, opt); build_path (AXE_IMAGE_PATH, specmod_file, specmod_file_path); } else { strcpy (specmod_file, ""); strcpy (specmod_file_path, ""); } // check whether a name for the images // models file is given if ((opt = get_online_option ("model_images", argc, argv))) { // get and set up the filename strcpy (objmod_file, opt); build_path (AXE_IMAGE_PATH, objmod_file, objmod_file_path); } else { strcpy (objmod_file, ""); strcpy (objmod_file_path, ""); } fprintf (stdout, "aXe_DISPIMAGE: grism image file name: %s\n", grism_file_path); fprintf (stdout, "aXe_DISPIMAGE: Input Aperture file name: %s\n", aper_file_path); fprintf (stdout, "aXe_DISPIMAGE: Using spectral models in table: %s\n", specmod_file_path); fprintf (stdout, "aXe_DISPIMAGE: Using direct emission objects in image: %s\n", objmod_file_path); fprintf (stdout, "aXe_DISPIMAGE: Object parameters determined at %fnm\n", lambda_psf); fprintf (stdout, "aXe_DISPIMAGE: "); obs = load_sci_image (grism_file_path, conf->science_numext); compute_disp(grism_file_path, aper_file_path, conf_file_path, specmod_file_path, objmod_file_path, lambda_psf, obs); free_observation(obs); free_aperture_conf(conf); fprintf (stdout, "aXe_DISPIMAGE: Done...\n"); exit (0); }