fors_img_science_impl.c

00001 /* $Id: fors_img_science_impl.c,v 1.45 2010/09/14 07:49:30 cizzo Exp $
00002  *
00003  * This file is part of the FORS Library
00004  * Copyright (C) 2002-2010 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00019  */
00020 
00021 /*
00022  * $Author: cizzo $
00023  * $Date: 2010/09/14 07:49:30 $
00024  * $Revision: 1.45 $
00025  * $Name: fors-4_8_6 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <fors_img_science_impl.h>
00033 
00034 #include <fors_extract.h>
00035 #include <fors_tools.h>
00036 #include <fors_setting.h>
00037 #include <fors_data.h>
00038 #include <fors_image.h>
00039 #include <fors_qc.h>
00040 #include <fors_dfs.h>
00041 #include <fors_utils.h>
00042 
00043 #include <cpl.h>
00044 #include <math.h>
00045 #include <stdbool.h>
00046 
00053 const char *const fors_img_science_name = "fors_img_science";
00054 const char *const fors_img_science_description_short = "Reduce scientific exposure";
00055 const char *const fors_img_science_author = "Jonas M. Larsen";
00056 const char *const fors_img_science_email = PACKAGE_BUGREPORT;
00057 const char *const fors_img_science_description = 
00058 "Input files:\n"
00059 "  DO category:               Type:       Explanation:             Number:\n"
00060 "  SCIENCE_IMG                Raw         Science image               1\n"
00061 "  MASTER_BIAS                FITS image  Master bias                 1\n"
00062 "  MASTER_SKY_FLAT_IMG        FITS image  Master sky flat field       1\n"
00063 "\n"
00064 "Output files:\n"
00065 "  DO category:               Data type:  Explanation:\n"
00066 "  SCIENCE_REDUCED_IMG        FITS image  Reduced science image\n"
00067 "  PHOT_BACKGROUND_SCI_IMG    FITS image  Reduced science image background\n"
00068 "  SOURCES_SCI_IMG            FITS image  Unfiltered SExtractor output\n"
00069 "  OBJECT_TABLE_SCI_IMG       FITS table  Extracted sources properties\n";
00070 
00071 
00072 static double
00073 get_image_quality(const fors_star_list *sources, double *image_quality_err,
00074                   double *stellarity,
00075                   double *ellipticity,
00076                   double *ellipticity_rms);
00077 
00078 #undef cleanup
00079 #define cleanup \
00080 do { \
00081     cpl_free((void *)full_name); \
00082 } while (0)
00083 
00089 void fors_img_science_define_parameters(cpl_parameterlist *parameters)
00090 {
00091     cpl_parameter *p;
00092     const char *context = cpl_sprintf("fors.%s", fors_img_science_name);
00093     const char *full_name = NULL;
00094     const char *name;
00095 
00096     name = "cr_remove";
00097     full_name = cpl_sprintf("%s.%s", context, name);
00098     p = cpl_parameter_new_value(full_name,
00099                                 CPL_TYPE_BOOL,
00100                                 "Cosmic ray removal",
00101                                 context,
00102                                 false);
00103     cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00104     cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
00105     cpl_parameterlist_append(parameters, p);
00106     cpl_free((void *)full_name); full_name = NULL;
00107 
00108     fors_extract_define_parameters(parameters, context);
00109     
00110     cpl_free((void *)context);
00111 
00112     return;
00113 }
00114 
00115 
00116 #undef cleanup
00117 #define cleanup \
00118 do { \
00119     cpl_frameset_delete(sci_frame); \
00120     cpl_frameset_delete(master_bias_frame); \
00121     cpl_frameset_delete(master_flat_frame); \
00122     fors_image_delete(&sci); \
00123     fors_image_delete_const(&master_bias); \
00124     fors_image_delete(&master_flat); \
00125     cpl_table_delete(phot); \
00126     cpl_table_delete(sources); \
00127     cpl_image_delete(background); \
00128     fors_extract_method_delete(&em); \
00129     fors_star_list_delete(&stars, fors_star_delete); \
00130     cpl_free((void *)context); \
00131     fors_setting_delete(&setting); \
00132     cpl_propertylist_delete(qc); \
00133     cpl_propertylist_delete(product_header); \
00134     cpl_propertylist_delete(header); \
00135 } while (0)
00136 
00137 /* %%% Removed from cleanup
00138     cpl_frameset_delete(phot_table); \
00139 */
00140 
00147 void fors_img_science(cpl_frameset *frames, const cpl_parameterlist *parameters)
00148 {
00149     /* Raw */
00150     cpl_frameset *sci_frame      = NULL;
00151     fors_image *sci              = NULL;
00152 
00153     /* Calibration */
00154     cpl_frameset *master_bias_frame = NULL;
00155     const fors_image *master_bias   = NULL; 
00156 
00157     cpl_frameset *master_flat_frame = NULL;
00158     fors_image *master_flat         = NULL; 
00159 
00160 /* %%%
00161     cpl_frameset *phot_table        = NULL;
00162     double ext_coeff, dext_coeff;
00163 */
00164 
00165     /* Products */
00166     cpl_propertylist *qc = cpl_propertylist_new();
00167     cpl_propertylist *product_header = cpl_propertylist_new();
00168     cpl_propertylist *header = NULL;
00169     cpl_table *phot = NULL;
00170     fors_extract_sky_stats sky_stats;
00171     cpl_image *background = NULL;
00172     cpl_table *sources = NULL;
00173 
00174     /* Parameters */
00175     extract_method  *em = NULL;
00176 
00177     /* Other */
00178     const char *context   = cpl_sprintf("fors.%s", fors_img_science_name);
00179     fors_star_list *stars = NULL;
00180     fors_setting *setting = NULL;
00181     double avg_airmass = 0.0;
00182 
00183     /* Get parameters */
00184     em = fors_extract_method_new(parameters, context);
00185     assure( !cpl_error_get_code(), return, 
00186             "Could not get extraction parameters" );
00187     
00188     /* Find raw */
00189     sci_frame = fors_frameset_extract(frames, SCIENCE_IMG);
00190     assure( cpl_frameset_get_size(sci_frame) == 1, return, 
00191             "Exactly 1 %s required. %d found", 
00192             SCIENCE_IMG, cpl_frameset_get_size(sci_frame) );
00193 
00194     /* Find calibration */
00195     master_bias_frame = fors_frameset_extract(frames, MASTER_BIAS);
00196     assure( cpl_frameset_get_size(master_bias_frame) == 1, return, 
00197             "One %s required. %d found", 
00198             MASTER_BIAS, cpl_frameset_get_size(master_bias_frame) );
00199 
00200     master_flat_frame = fors_frameset_extract(frames, MASTER_SKY_FLAT_IMG);
00201     assure( cpl_frameset_get_size(master_flat_frame) == 1, return, 
00202             "One %s required. %d found", 
00203             MASTER_SKY_FLAT_IMG, cpl_frameset_get_size(master_flat_frame) );
00204 
00205 /* %%%
00206     phot_table = fors_frameset_extract(frames, PHOT_TABLE);
00207     assure( cpl_frameset_get_size(phot_table) == 1, return, 
00208             "One %s required. %d found",
00209             PHOT_TABLE, cpl_frameset_get_size(phot_table));
00210 */
00211 
00212     /* Done finding frames */
00213 
00214     /* Get instrument setting */
00215     setting = fors_setting_new(cpl_frameset_get_first(sci_frame));
00216     assure( !cpl_error_get_code(), return, "Could not get instrument setting" );
00217 
00218 
00219     master_bias = fors_image_load(cpl_frameset_get_first(master_bias_frame), 
00220                                   NULL, setting, NULL);
00221     assure( !cpl_error_get_code(), return, 
00222             "Could not load master bias");
00223 
00224     /* Load raw frames, subtract bias */
00225     sci = fors_image_load(cpl_frameset_get_first(sci_frame), master_bias, 
00226                           setting, NULL);
00227     assure( !cpl_error_get_code(), return, "Could not load standard image");
00228     fors_image_delete_const(&master_bias);
00229 
00230     /* Load master flat */
00231     master_flat = fors_image_load(cpl_frameset_get_first(master_flat_frame), 
00232                                   NULL, setting, NULL);
00233     assure( !cpl_error_get_code(), return, "Could not load master flat");
00234     
00235     /* Divide by normalized flat */
00236     fors_image_divide_scalar(master_flat,
00237                              fors_image_get_median(master_flat, NULL), -1.0);
00238 
00239     fors_image_divide(sci, master_flat);
00240     assure( !cpl_error_get_code(), return, "Could not divide by master flat");
00241     fors_image_delete(&master_flat);
00242 
00243     /* Extract sources */
00244     stars = fors_extract(sci, setting, em,
00245              &sky_stats, &background, &sources);
00246     assure( !cpl_error_get_code(), return, "Could not extract objects");  
00247 
00248     /* QC */
00249     fors_qc_start_group(qc, fors_qc_dic_version, setting->instrument);
00250     
00251     fors_qc_write_group_heading(cpl_frameset_get_first(sci_frame),
00252                                 PHOTOMETRY_TABLE,
00253                                 setting->instrument);
00254     assure( !cpl_error_get_code(), return, "Could not write %s QC parameters", 
00255             PHOTOMETRY_TABLE);
00256 
00257 
00258     double sky_mag;
00259     double sky_mag_rms;
00260     if (sky_stats.mean > 0) {
00261         sky_mag = -2.5*log(sky_stats.mean /
00262                            (setting->pixel_scale*setting->pixel_scale))/log(10);
00263     }
00264     else {
00265         cpl_msg_warning(cpl_func, 
00266                         "Average sky background is negative (%f ADU), "
00267                         "cannot compute magnitude, setting QC.SKYAVG to 99999.",
00268                         sky_stats.mean);
00269         sky_mag = 99999.;
00270     }
00271     fors_qc_write_qc_double(qc,
00272                             sky_mag,
00273                             "QC.SKYAVG",
00274                             "mag/arcsec^2",
00275                             "Mean of sky background",
00276                             setting->instrument);
00277     
00278     if (sky_stats.median > 0) {
00279         sky_mag = -2.5*log(sky_stats.median /
00280                            (setting->pixel_scale*setting->pixel_scale))/log(10);
00281         /* deltaM = -2.5*log10(e)*deltaF/F */
00282         sky_mag_rms = fabs(-2.5 * (1.0/log(10))*sky_stats.rms/sky_stats.median);
00283     }
00284     else {
00285         cpl_msg_warning(cpl_func, 
00286                         "Median sky background is negative (%f ADU), "
00287                         "cannot compute magnitude: setting both QC.SKYMED "
00288                         "and QC.SKYRMS to 99999.",
00289                         sky_mag);
00290         sky_mag = 99999.;
00291         sky_mag_rms = 99999.;
00292     }
00293     fors_qc_write_qc_double(qc,
00294                             sky_mag,
00295                             "QC.SKYMED",
00296                             "mag/arcsec^2",
00297                             "Median of sky background",
00298                             setting->instrument);
00299 
00300     fors_qc_write_qc_double(qc,
00301                             sky_mag_rms,
00302                             "QC.SKYRMS",
00303                             "mag/arcsec^2",
00304                             "Standard deviation of sky background",
00305                             setting->instrument);
00306 
00307     double image_quality_error;
00308     double stellarity;
00309     double ellipticity, ellipticity_rms;
00310     double image_quality = get_image_quality(stars, 
00311                                              &image_quality_error,
00312                                              &stellarity,
00313                                              &ellipticity,
00314                                              &ellipticity_rms);
00315 
00316     if (image_quality > 0.) {
00317         image_quality *= TWOSQRT2LN2 * setting->pixel_scale;
00318         image_quality_error *= TWOSQRT2LN2 * setting->pixel_scale;
00319     }
00320 
00321     fors_qc_write_qc_double(qc,
00322                             image_quality,
00323                             "QC.IMGQU",
00324                             "arcsec",
00325                             "Image quality of scientific exposure",
00326                             setting->instrument);
00327 
00328     fors_qc_write_qc_double(qc,
00329                             image_quality_error,
00330                             "QC.IMGQUERR",
00331                             "arcsec",
00332                             "Uncertainty of image quality",
00333                             setting->instrument);
00334 
00335     fors_qc_write_qc_double(qc,
00336                             stellarity,
00337                             "QC.STELLAVG",
00338                             NULL,
00339                             "Mean stellarity index",
00340                             setting->instrument);
00341 
00342     fors_qc_write_qc_double(qc,
00343                             ellipticity,
00344                             "QC.IMGQUELL",
00345                             NULL,
00346                             "Mean star ellipticity",
00347                             setting->instrument);
00348 
00349     fors_qc_write_qc_double(qc,
00350                             ellipticity_rms,
00351                             "QC.IMGQUELLERR",
00352                             NULL,
00353                             "Standard deviation of star ellipticities",
00354                             setting->instrument);
00355 
00356     fors_qc_end_group();
00357 
00358     /* Save SCIENCE_REDUCED, PHOT_BACKGROUND_SCI_IMG */
00359 
00360 /* %%% */
00361 
00362     header = cpl_propertylist_load(
00363                         cpl_frame_get_filename(
00364                            cpl_frameset_get_first(sci_frame)), 0);
00365 
00366     if (header == NULL) {
00367         cpl_msg_error(cpl_func, "Failed to load raw header");
00368         cleanup;
00369         return;
00370     }
00371 
00372     avg_airmass = fors_get_airmass(header);
00373 
00374     cpl_propertylist_update_double(qc, "AIRMASS", avg_airmass);
00375     cpl_propertylist_update_double(product_header, "AIRMASS", avg_airmass);
00376 
00377 /* %%% */
00378 
00379     fors_dfs_add_wcs(qc, cpl_frameset_get_first(sci_frame), setting);
00380     fors_dfs_add_exptime(qc, cpl_frameset_get_first(sci_frame), 0.);
00381     fors_dfs_add_wcs(product_header, cpl_frameset_get_first(sci_frame), 
00382                      setting);
00383     fors_dfs_add_exptime(product_header, cpl_frameset_get_first(sci_frame), 0.);
00384 
00385     fors_dfs_save_image(frames, sci, SCIENCE_REDUCED_IMG,
00386                         qc, parameters, fors_img_science_name, 
00387                         cpl_frameset_get_first(sci_frame));
00388     assure( !cpl_error_get_code(), return, "Saving %s failed",
00389             SCIENCE_REDUCED_IMG);
00390 
00391     fors_image_delete(&sci);
00392     
00393     dfs_save_image(frames, background, PHOT_BACKGROUND_SCI_IMG,
00394                    product_header, parameters, fors_img_science_name, 
00395                    setting->version);
00396     assure( !cpl_error_get_code(), return, "Saving %s failed",
00397             PHOT_BACKGROUND_SCI_IMG);
00398 
00399     cpl_image_delete(background); background = NULL;
00400     
00401     /* Load filter coefficients */
00402 
00403 /* %%%
00404     fors_phot_table_load(cpl_frameset_get_first(phot_table), setting,
00405                          NULL, NULL, 
00406              &ext_coeff, &dext_coeff,
00407              NULL, NULL);
00408     assure( !cpl_error_get_code(), return, "Could not load photometry table" );
00409 */
00410 
00411     /* Correct for atmospheric extinction */
00412 /* %%%
00413     fors_star_ext_corr(stars, setting, ext_coeff, dext_coeff,
00414                        cpl_frameset_get_first(sci_frame));
00415     assure( !cpl_error_get_code(), return, 
00416             "Extinction correction failed");
00417 */
00418 
00419     /* Create, save FITS product */
00420     phot = fors_create_sources_table(stars);
00421     assure( !cpl_error_get_code(), return,
00422             "Failed to create extracted sources table");
00423 
00424     /*
00425      * Eliminate unused columns from photometry table
00426      */
00427 
00428     cpl_table_erase_column(phot, "INSTR_CMAG");
00429     cpl_table_erase_column(phot, "DINSTR_CMAG");
00430     cpl_table_erase_column(phot, "OBJECT");
00431     cpl_table_erase_column(phot, "MAG");
00432     cpl_table_erase_column(phot, "DMAG");
00433     cpl_table_erase_column(phot, "CAT_MAG");
00434     cpl_table_erase_column(phot, "DCAT_MAG");
00435     cpl_table_erase_column(phot, "COLOR");
00436     /* new columns since 4.4.10 */
00437     if (cpl_table_has_column(phot, "DCOLOR"))
00438         cpl_table_erase_column(phot, "DCOLOR");
00439     if (cpl_table_has_column(phot, "COV_CATM_COL"))
00440         cpl_table_erase_column(phot, "COV_CATM_COL");
00441     cpl_table_erase_column(phot, "USE_CAT");
00442     cpl_table_erase_column(phot, "SHIFT_X");
00443     cpl_table_erase_column(phot, "SHIFT_Y");
00444     cpl_table_erase_column(phot, "ZEROPOINT");
00445     cpl_table_erase_column(phot, "DZEROPOINT");
00446     cpl_table_erase_column(phot, "WEIGHT");
00447 
00448     fors_dfs_save_table(frames, sources, SOURCES_SCI,
00449                         NULL, parameters, fors_img_science_name, 
00450                         cpl_frameset_get_first(sci_frame));
00451     assure( !cpl_error_get_code(), return, "Saving %s failed",
00452             SOURCES_SCI);
00453 
00454     fors_dfs_save_table(frames, phot, PHOTOMETRY_TABLE,
00455                         NULL, parameters, fors_img_science_name, 
00456                         cpl_frameset_get_first(sci_frame));
00457     assure( !cpl_error_get_code(), return, "Saving %s failed",
00458             PHOTOMETRY_TABLE);
00459 
00460     cleanup;
00461     return;
00462 }
00463 
00464 #undef cleanup
00465 #define cleanup
00466 
00472 static bool
00473 is_star(const fors_star *s, void *data)
00474 {
00475     data = data;
00476     assure( s != NULL, return false, NULL );
00477 
00478 /*FIXME
00479   All stars for the moment... */
00480 
00481     return s->stellarity_index >= 0.7;
00482 }
00483 
00484 #undef cleanup
00485 #define cleanup \
00486 do { \
00487     fors_star_list_delete(&stars, fors_star_delete); \
00488 } while(0)
00489 
00502 static double
00503 get_image_quality(const fors_star_list *sources, double *image_quality_err,
00504                   double *stellarity,
00505                   double *ellipticity,
00506                   double *ellipticity_rms)
00507 {
00508     fors_star_list *stars = fors_star_list_extract(sources,
00509                                                    fors_star_duplicate,
00510                                                    is_star, NULL);
00511 
00512     double fwhm;
00513     if (fors_star_list_size(stars) >= 1) {
00514         *image_quality_err = fors_star_list_mad(stars, fors_star_extension, NULL) 
00515             * STDEV_PR_MAD;
00516         
00517         fwhm = fors_star_list_median(stars, fors_star_extension , NULL);
00518         
00519         *stellarity      = fors_star_list_mean(stars, fors_star_stellarity, NULL);
00520         *ellipticity     = fors_star_list_mean(stars, fors_star_ellipticity, NULL);
00521         *ellipticity_rms = fors_star_list_mad(stars, fors_star_ellipticity, NULL)
00522             * STDEV_PR_MAD;
00523     }
00524     else {
00525         cpl_msg_warning(cpl_func, "No stars found! Cannot compute image quality, "
00526                         "setting QC parameters to -1");
00527 
00528         /* -1 is not a valid value for any of these */
00529         *image_quality_err = -1;
00530         fwhm = -1;
00531         *stellarity = -1;
00532         *ellipticity = -1;
00533         *ellipticity_rms = -1;
00534     }
00535 
00536     cleanup;
00537     return fwhm;
00538 }
00539 

Generated on Fri Mar 4 09:46:00 2011 for FORS Pipeline Reference Manual by  doxygen 1.4.7