00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032 #include <math.h>
00033 #include <cpl.h>
00034 #include <moses.h>
00035 #include <fors_dfs.h>
00036
00037 static int fors_flatfield_create(cpl_plugin *);
00038 static int fors_flatfield_exec(cpl_plugin *);
00039 static int fors_flatfield_destroy(cpl_plugin *);
00040 static int fors_flatfield(cpl_parameterlist *, cpl_frameset *);
00041
00042 static char fors_flatfield_description[] =
00043 "This recipe is used to divide the input frame by the normalised flat\n"
00044 "field frame produced by recipe fors_normalise_flat. The input frame must\n"
00045 "be already bias subtracted (e.g., by recipe fors_remove_bias).\n"
00046 "In the table below the MXU acronym can be alternatively read as MOS and\n"
00047 "LSS.\n\n"
00048 "Input files:\n\n"
00049 " DO category: Type: Explanation: Required:\n"
00050 " SCIENCE_UNBIAS_MXU\n"
00051 " or STANDARD_UNBIAS_MXU Raw Bias subtracted frame Y\n"
00052 " MASTER_NORM_FLAT_MXU Calib Normalised flat frame Y\n\n"
00053 "Output files:\n\n"
00054 " DO category: Data type: Explanation:\n"
00055 " SCIENCE_UNFLAT_MXU\n"
00056 " or STANDARD_UNFLAT_MXU FITS image Flat field corrected frame\n\n";
00057
00058 #define fors_flatfield_exit(message) \
00059 { \
00060 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
00061 cpl_image_delete(raw_image); \
00062 cpl_image_delete(norm_flat); \
00063 cpl_propertylist_delete(header); \
00064 cpl_msg_indent_less(); \
00065 return -1; \
00066 }
00067
00068 #define fors_flatfield_exit_memcheck(message) \
00069 { \
00070 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
00071 printf("free raw_image (%p)\n", raw_image); \
00072 cpl_image_delete(raw_image); \
00073 printf("free norm_flat (%p)\n", norm_flat); \
00074 cpl_image_delete(norm_flat); \
00075 printf("free header (%p)\n", header); \
00076 cpl_propertylist_delete(header); \
00077 cpl_msg_indent_less(); \
00078 return 0; \
00079 }
00080
00081
00093 int cpl_plugin_get_info(cpl_pluginlist *list)
00094 {
00095 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00096 cpl_plugin *plugin = &recipe->interface;
00097
00098 cpl_plugin_init(plugin,
00099 CPL_PLUGIN_API,
00100 FORS_BINARY_VERSION,
00101 CPL_PLUGIN_TYPE_RECIPE,
00102 "fors_flatfield",
00103 "Flat field correction of input frame",
00104 fors_flatfield_description,
00105 "Carlo Izzo",
00106 PACKAGE_BUGREPORT,
00107 "This file is currently part of the FORS Instrument Pipeline\n"
00108 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00109 "This program is free software; you can redistribute it and/or modify\n"
00110 "it under the terms of the GNU General Public License as published by\n"
00111 "the Free Software Foundation; either version 2 of the License, or\n"
00112 "(at your option) any later version.\n\n"
00113 "This program is distributed in the hope that it will be useful,\n"
00114 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00115 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00116 "GNU General Public License for more details.\n\n"
00117 "You should have received a copy of the GNU General Public License\n"
00118 "along with this program; if not, write to the Free Software Foundation,\n"
00119 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
00120 fors_flatfield_create,
00121 fors_flatfield_exec,
00122 fors_flatfield_destroy);
00123
00124 cpl_pluginlist_append(list, plugin);
00125
00126 return 0;
00127 }
00128
00129
00140 static int fors_flatfield_create(cpl_plugin *plugin)
00141 {
00142 cpl_recipe *recipe;
00143
00144
00145
00146
00147
00148
00149
00150
00151 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00152 recipe = (cpl_recipe *)plugin;
00153 else
00154 return -1;
00155
00156
00157
00158
00159
00160 recipe->parameters = cpl_parameterlist_new();
00161
00162 return 0;
00163 }
00164
00165
00174 static int fors_flatfield_exec(cpl_plugin *plugin)
00175 {
00176 cpl_recipe *recipe;
00177
00178 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00179 recipe = (cpl_recipe *)plugin;
00180 else
00181 return -1;
00182
00183 return fors_flatfield(recipe->parameters, recipe->frames);
00184 }
00185
00186
00195 static int fors_flatfield_destroy(cpl_plugin *plugin)
00196 {
00197 cpl_recipe *recipe;
00198
00199 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00200 recipe = (cpl_recipe *)plugin;
00201 else
00202 return -1;
00203
00204 cpl_parameterlist_delete(recipe->parameters);
00205
00206 return 0;
00207 }
00208
00209
00219 static int fors_flatfield(cpl_parameterlist *parlist, cpl_frameset *frameset)
00220 {
00221
00222 const char *recipe = "fors_flatfield";
00223
00224
00225
00226
00227
00228
00229 cpl_image *raw_image = NULL;
00230 cpl_image *norm_flat = NULL;
00231 cpl_propertylist *header = NULL;
00232
00233
00234
00235
00236
00237 char version[80];
00238 const char *norm_flat_tag;
00239 const char *raw_image_tag;
00240 const char *pro_image_tag;
00241 char *instrume = NULL;
00242 int science_mxu;
00243 int science_mos;
00244 int science_lss;
00245 int standard_mxu;
00246 int standard_mos;
00247 int standard_lss;
00248 int nflat, nframe;
00249
00250
00251 cpl_msg_set_indentation(2);
00252
00253
00254 cpl_msg_info(recipe, "Check input set-of-frames:");
00255 cpl_msg_indent_more();
00256
00257 nframe = science_mxu = cpl_frameset_count_tags(frameset,
00258 "SCIENCE_UNBIAS_MXU");
00259 nframe += science_mos = cpl_frameset_count_tags(frameset,
00260 "SCIENCE_UNBIAS_MOS");
00261 nframe += science_lss = cpl_frameset_count_tags(frameset,
00262 "SCIENCE_UNBIAS_LSS");
00263 nframe += standard_mxu = cpl_frameset_count_tags(frameset,
00264 "STANDARD_UNBIAS_MXU");
00265 nframe += standard_mos = cpl_frameset_count_tags(frameset,
00266 "STANDARD_UNBIAS_MOS");
00267 nframe += standard_lss = cpl_frameset_count_tags(frameset,
00268 "STANDARD_UNBIAS_LSS");
00269
00270 if (nframe == 0) {
00271 fors_flatfield_exit("Missing required input scientific frame");
00272 }
00273 if (nframe > 1) {
00274 cpl_msg_error(recipe, "Too many input scientific frames (%d > 1)",
00275 nframe);
00276 fors_flatfield_exit(NULL);
00277 }
00278
00279 if (science_mxu) {
00280 norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00281 pro_image_tag = "SCIENCE_UNFLAT_MXU";
00282 raw_image_tag = "SCIENCE_UNBIAS_MXU";
00283 }
00284 else if (science_mos) {
00285 norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00286 pro_image_tag = "SCIENCE_UNFLAT_MOS";
00287 raw_image_tag = "SCIENCE_UNBIAS_MOS";
00288 }
00289 else if (science_lss) {
00290 norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00291 pro_image_tag = "SCIENCE_UNFLAT_LSS";
00292 raw_image_tag = "SCIENCE_UNBIAS_LSS";
00293 }
00294 else if (standard_mxu) {
00295 norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00296 pro_image_tag = "STANDARD_UNFLAT_MXU";
00297 raw_image_tag = "STANDARD_UNBIAS_MXU";
00298 }
00299 else if (standard_mos) {
00300 norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00301 pro_image_tag = "STANDARD_UNFLAT_MOS";
00302 raw_image_tag = "STANDARD_UNBIAS_MOS";
00303 }
00304 else if (standard_lss) {
00305 norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00306 pro_image_tag = "STANDARD_UNFLAT_LSS";
00307 raw_image_tag = "STANDARD_UNBIAS_LSS";
00308 }
00309
00310 nflat = cpl_frameset_count_tags(frameset, norm_flat_tag);
00311 if (nflat == 0) {
00312 cpl_msg_error(recipe, "Missing required input: %s", norm_flat_tag);
00313 fors_flatfield_exit(NULL);
00314 }
00315 if (nflat > 1) {
00316 cpl_msg_error(recipe, "Too many in input (%d > 1): %s",
00317 nflat, norm_flat_tag);
00318 fors_flatfield_exit(NULL);
00319 }
00320
00321 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00322 cpl_msg_warning(cpl_func,"Input frames are not from the same grism");
00323
00324 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00325 cpl_msg_warning(cpl_func,"Input frames are not from the same filter");
00326
00327 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00328 cpl_msg_warning(cpl_func,"Input frames are not from the same chip");
00329
00330 header = dfs_load_header(frameset, raw_image_tag, 0);
00331
00332 if (header == NULL) {
00333 cpl_msg_error(recipe, "Cannot load header of %s frame", raw_image_tag);
00334 fors_flatfield_exit(NULL);
00335 }
00336
00337 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00338 if (instrume == NULL) {
00339 cpl_msg_error(recipe, "Missing keyword INSTRUME in %s header",
00340 raw_image_tag);
00341 fors_flatfield_exit(NULL);
00342 }
00343
00344 if (instrume[4] == '1')
00345 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00346 if (instrume[4] == '2')
00347 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00348
00349 cpl_msg_indent_less();
00350 cpl_msg_info(recipe, "Load input frames:");
00351 cpl_msg_indent_more();
00352
00353 norm_flat = dfs_load_image(frameset, norm_flat_tag, CPL_TYPE_FLOAT, 0, 1);
00354 if (norm_flat == NULL)
00355 fors_flatfield_exit("Cannot load normalised flat field");
00356
00357 raw_image = dfs_load_image(frameset, raw_image_tag, CPL_TYPE_FLOAT, 0, 0);
00358 if (raw_image == NULL) {
00359 cpl_msg_error(recipe, "Cannot load %s frame", raw_image_tag);
00360 fors_flatfield_exit(NULL);
00361 }
00362
00363 cpl_msg_indent_less();
00364 cpl_msg_info(recipe, "Divide input %s by flat field...", raw_image_tag);
00365 cpl_msg_indent_more();
00366
00367 if (cpl_image_divide(raw_image, norm_flat) != CPL_ERROR_NONE) {
00368 cpl_msg_error(recipe, "Failure of flat field correction: %s",
00369 cpl_error_get_message());
00370 fors_flatfield_exit(NULL);
00371 }
00372 cpl_image_delete(norm_flat); norm_flat = NULL;
00373
00374 cpl_msg_indent_less();
00375
00376 if (dfs_save_image(frameset, raw_image, pro_image_tag,
00377 header, parlist, recipe, version))
00378 fors_flatfield_exit(NULL);
00379
00380 cpl_propertylist_delete(header); header = NULL;
00381 cpl_image_delete(raw_image); raw_image = NULL;
00382
00383 return 0;
00384 }