fors_bias_impl.c

00001 /* $Id: fors_bias_impl.c,v 1.27 2010/09/14 07:49:30 cizzo Exp $
00002  *
00003  * This file is part of the FORS Data Reduction Pipeline
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.27 $
00025  * $Name: fors-4_8_6 $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 #include <fors_bias_impl.h>
00033 
00034 #include <fors_stack.h>
00035 #include <fors_qc.h>
00036 #include <fors_tools.h>
00037 #include <fors_dfs.h>
00038 #include <fors_utils.h>
00039 #include <moses.h>
00040 
00041 #include <cpl.h>
00042 
00043 #include <string.h>
00044 #include <math.h>
00045 
00052 const char *const fors_bias_name = "fors_bias";
00053 const char *const fors_bias_description_short = "Compute the master bias frame";
00054 const char *const fors_bias_author = "Jonas M. Larsen, Carlo Izzo";
00055 const char *const fors_bias_email = PACKAGE_BUGREPORT;
00056 const char *const fors_bias_description =
00057 "This recipe is used to combine input raw BIAS frames into a master bias\n"
00058 "frame. The overscan regions, if present, are removed from the result.\n\n"
00059 "Input files:\n\n"
00060 "  DO category:               Type:       Explanation:         Required:\n"
00061 "  BIAS                       Raw         Bias frame              Y\n\n"
00062 "Output files:\n\n"
00063 "  DO category:               Data type:  Explanation:\n"
00064 "  MASTER_BIAS                FITS image  Master bias frame\n\n";
00065 
00066 
00067 static void
00068 write_qc(cpl_propertylist *qc,
00069          const fors_setting *setting,
00070          const cpl_frame *first_bias,
00071          const fors_image_list *bias,
00072          const fors_image *master_bias,
00073          const stack_method *sm);
00078 void fors_bias_define_parameters(cpl_parameterlist *parameters)
00079 {
00080     const char *context = cpl_sprintf("fors.%s", fors_bias_name);
00081     
00082     fors_stack_define_parameters(parameters, context, "minmax");
00083 
00084     cpl_free((void *)context);
00085 
00086     return;
00087 }
00088 
00089 #undef cleanup
00090 #define cleanup \
00091 do { \
00092     cpl_frameset_delete(bias_frames); \
00093     fors_stack_method_delete(&sm); \
00094     cpl_free((void *)context); \
00095     fors_image_list_delete_const(&bias, fors_image_delete); \
00096     fors_image_delete(&master_bias); \
00097     fors_setting_delete(&setting); \
00098     cpl_propertylist_delete(qc); \
00099 } while (0)
00100 
00109 void fors_bias(cpl_frameset *frames, const cpl_parameterlist *parameters)
00110 {
00111     /* Raw */
00112     cpl_frameset *bias_frames      = NULL;
00113     const fors_image_list *bias    = NULL;
00114 
00115     /* Product */
00116     fors_image *master_bias = NULL;
00117     cpl_propertylist *qc = cpl_propertylist_new();
00118 
00119     /* Parameters */
00120     stack_method *sm    = NULL;
00121 
00122     /* Other */
00123     fors_setting *setting = NULL;
00124     const char *context = cpl_sprintf("fors.%s", fors_bias_name);
00125 
00126     /* Get parameters */
00127     sm = fors_stack_method_new(parameters, context);
00128     assure( !cpl_error_get_code(), return, "Could not get stacking method");
00129     
00130     /* Find raw */
00131     bias_frames = fors_frameset_extract(frames, BIAS);
00132     assure( cpl_frameset_get_size(bias_frames) > 0, return, 
00133             "No %s provided", BIAS);
00134 
00135     /* Get instrument setting */
00136     setting = fors_setting_new(cpl_frameset_get_first(bias_frames));
00137     assure( !cpl_error_get_code(), return, "Could not get instrument setting" );
00138 
00139     /* Load bias */
00140     bias = fors_image_load_list_const(bias_frames, NULL, setting, NULL);
00141     assure( !cpl_error_get_code(), return, "Could not load bias images");
00142 
00143     /* Stack */
00144     master_bias = fors_stack_const(bias, sm);
00145     assure( !cpl_error_get_code(), return, "Bias stacking failed");
00146     
00147     /* QC */
00148     write_qc(qc, setting,
00149              cpl_frameset_get_first(bias_frames),
00150              bias, master_bias, sm);
00151 
00152     /* Save product */
00153     fors_dfs_save_image(frames, master_bias, MASTER_BIAS,
00154                         qc, parameters, fors_bias_name, 
00155                         cpl_frameset_get_first(bias_frames));
00156     assure( !cpl_error_get_code(), return, "Saving %s failed",
00157             MASTER_BIAS);
00158     
00159     cleanup;
00160     return;
00161 }
00162 
00163 
00164 #undef cleanup
00165 #define cleanup \
00166 do { \
00167     fors_image_delete(&image); \
00168 } while (0)
00169 
00170 
00171 static void
00172 write_qc(cpl_propertylist *qc,
00173          const fors_setting *setting,
00174          const cpl_frame *first_bias,
00175          const fors_image_list *bias,
00176          const fors_image *master_bias,
00177          const stack_method *sm)
00178 {
00179     const fors_image *first_raw  = fors_image_list_first_const(bias);
00180     const fors_image *second_raw = fors_image_list_next_const(bias);
00181     fors_image *image = NULL;
00182 
00183     fors_qc_start_group(qc, fors_qc_dic_version, setting->instrument);
00184 
00185     fors_qc_write_group_heading(first_bias,
00186                                 MASTER_BIAS,
00187                                 setting->instrument);
00188     assure( !cpl_error_get_code(), return, "Could not write %s QC parameters", 
00189             MASTER_BIAS);
00190 
00191     fors_qc_write_qc_double(qc,
00192                             fors_image_get_median(first_raw, NULL),
00193                             "QC.BIAS.LEVEL",
00194                             "ADU",
00195                             "Bias level",
00196                             setting->instrument);
00197     double ron;
00198     double fpn;
00199     if (second_raw != NULL) {
00200 
00201         image = fors_image_duplicate(first_raw);
00202         fors_image_subtract(image, second_raw);
00203 
00204         ron = fors_image_get_stdev_robust(image, 50, NULL) / sqrt(2.0);
00205 
00206         fpn = fors_fixed_pattern_noise_bias(first_raw,
00207                                             second_raw,
00208                                             ron);
00209 /*
00210         fpn = fors_fixed_pattern_noise(first_raw,
00211                                        1.0,
00212                                        ron);
00213 */
00214         assure( !cpl_error_get_code(), return, 
00215                 "Could not compute fixed pattern noise" );
00216     }
00217     else {
00218         cpl_msg_warning(cpl_func,
00219                         "Only %d bias frame(s) provided, "
00220                         "cannot compute readout noise", 
00221                         fors_image_list_size(bias));
00222         ron = -1;
00223         fpn = -1;
00224     }
00225 
00226     fors_qc_write_qc_double(qc,
00227                             ron,
00228                             "QC.RON",
00229                             "ADU",
00230                             "Readout noise",
00231                             setting->instrument);
00232 
00233     fors_qc_write_qc_double(qc,
00234                             fpn,
00235                             "QC.BIAS.FPN",
00236                             "ADU",
00237                             "Bias fixed pattern noise",
00238                             setting->instrument);
00239 
00240     double structure = fors_image_get_stdev_robust(first_raw, 50, NULL);
00241     if (structure*structure >= ron*ron + fpn*fpn) {
00242         structure = sqrt(structure*structure - ron*ron - fpn*fpn);
00243     }
00244     else {
00245         cpl_msg_warning(cpl_func,
00246                         "Overall bias standard deviation (%f ADU) is less "
00247                         "than combined readout and fixed pattern noise "
00248                         "(%f ADU), setting structure to zero",
00249                         structure , sqrt(ron*ron + fpn*fpn));
00250         structure = 0;
00251     }
00252     
00253     
00254     fors_qc_write_qc_double(qc,
00255                             structure,
00256                             "QC.BIAS.STRUCT",
00257                             "ADU",
00258                             "Bias structure",
00259                             setting->instrument);
00260 
00261     /* Master bias QC */
00262 
00263     fors_qc_write_qc_double(qc,
00264                             fors_image_get_median(master_bias, NULL),
00265                             "QC.MBIAS.LEVEL",
00266                             "ADU",
00267                             "Master bias level",
00268                             setting->instrument);
00269 
00270     double ron_expect = -1;
00271     if (ron > 0) {
00272 
00273         int N = fors_image_list_size(bias);
00274 
00275         /*
00276           When median stacking and N >= 3, we need to
00277           take into account the fact that the median is more noisy than
00278           the mean.
00279         */
00280 
00281         if (sm->method == MEDIAN) {
00282             ron_expect = fors_utils_median_corr(N) * ron / sqrt(N);
00283         }
00284         else {
00285             ron_expect = ron / sqrt(N);
00286         }
00287     }
00288     else cpl_msg_warning(cpl_func,
00289                          "Cannot compute expected master bias readout noise");
00290     
00291     fors_qc_write_qc_double(qc,
00292                             ron_expect,
00293                             "QC.MBIAS.RONEXP",
00294                             "ADU",
00295                             "Expected master bias readout noise",
00296                             setting->instrument);
00297     
00298     double mbias_noise = -1;
00299     if (ron_expect > 0) {
00300         mbias_noise =
00301             fors_image_get_stdev_robust(master_bias, 3*ron_expect, NULL);
00302     }
00303     else {
00304         mbias_noise = -1;
00305     }
00306     
00307     fors_qc_write_qc_double(qc,
00308                             mbias_noise,
00309                             "QC.MBIAS.NOISE",
00310                             "ADU",
00311                             "Master bias readout noise",
00312                             setting->instrument);
00313 
00314     fors_qc_write_qc_double(qc,
00315                             mbias_noise / ron_expect,
00316                             "QC.MBIAS.NRATIO",
00317                             NULL,
00318                             "Master bias observed/expected noise",
00319                             setting->instrument);
00320     
00321     double mbias_struct = fors_image_get_stdev(master_bias, NULL);
00322 
00323     if (mbias_struct * mbias_struct > mbias_noise * mbias_noise) {
00324 
00325         cpl_msg_debug(cpl_func, "Overall standard deviation is %f ADU",
00326                       mbias_struct);
00327 
00328         mbias_struct = sqrt(mbias_struct * mbias_struct - 
00329                             mbias_noise * mbias_noise);
00330     }
00331     else {
00332         cpl_msg_warning(cpl_func,
00333                         "Master bias overall standard deviation (%f ADU) is "
00334                         "greater than master bias noise (%f ADU), "
00335                         "cannot compute master bias structure",
00336                         mbias_struct, mbias_noise);
00337         mbias_struct = -1;
00338     }
00339 
00340     fors_qc_write_qc_double(qc,
00341                             mbias_struct,
00342                             "QC.MBIAS.STRUCT",
00343                             "ADU",
00344                             "Structure of master bias",
00345                             setting->instrument);
00346     
00347     fors_qc_end_group();
00348 
00349     cleanup;
00350     return;
00351 }

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