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 (message) 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 (message) 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 if (dfs_files_dont_exist(frameset))
00254 fors_flatfield_exit(NULL);
00255
00256
00257 cpl_msg_info(recipe, "Check input set-of-frames:");
00258 cpl_msg_indent_more();
00259
00260 nframe = science_mxu = cpl_frameset_count_tags(frameset,
00261 "SCIENCE_UNBIAS_MXU");
00262 nframe += science_mos = cpl_frameset_count_tags(frameset,
00263 "SCIENCE_UNBIAS_MOS");
00264 nframe += science_lss = cpl_frameset_count_tags(frameset,
00265 "SCIENCE_UNBIAS_LSS");
00266 nframe += standard_mxu = cpl_frameset_count_tags(frameset,
00267 "STANDARD_UNBIAS_MXU");
00268 nframe += standard_mos = cpl_frameset_count_tags(frameset,
00269 "STANDARD_UNBIAS_MOS");
00270 nframe += standard_lss = cpl_frameset_count_tags(frameset,
00271 "STANDARD_UNBIAS_LSS");
00272
00273 if (nframe == 0) {
00274 fors_flatfield_exit("Missing required input scientific frame");
00275 }
00276 if (nframe > 1) {
00277 cpl_msg_error(recipe, "Too many input scientific frames (%d > 1)",
00278 nframe);
00279 fors_flatfield_exit(NULL);
00280 }
00281
00282 if (science_mxu) {
00283 norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00284 pro_image_tag = "SCIENCE_UNFLAT_MXU";
00285 raw_image_tag = "SCIENCE_UNBIAS_MXU";
00286 }
00287 else if (science_mos) {
00288 norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00289 pro_image_tag = "SCIENCE_UNFLAT_MOS";
00290 raw_image_tag = "SCIENCE_UNBIAS_MOS";
00291 }
00292 else if (science_lss) {
00293 norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00294 pro_image_tag = "SCIENCE_UNFLAT_LSS";
00295 raw_image_tag = "SCIENCE_UNBIAS_LSS";
00296 }
00297 else if (standard_mxu) {
00298 norm_flat_tag = "MASTER_NORM_FLAT_MXU";
00299 pro_image_tag = "STANDARD_UNFLAT_MXU";
00300 raw_image_tag = "STANDARD_UNBIAS_MXU";
00301 }
00302 else if (standard_mos) {
00303 norm_flat_tag = "MASTER_NORM_FLAT_MOS";
00304 pro_image_tag = "STANDARD_UNFLAT_MOS";
00305 raw_image_tag = "STANDARD_UNBIAS_MOS";
00306 }
00307 else if (standard_lss) {
00308 norm_flat_tag = "MASTER_NORM_FLAT_LSS";
00309 pro_image_tag = "STANDARD_UNFLAT_LSS";
00310 raw_image_tag = "STANDARD_UNBIAS_LSS";
00311 }
00312
00313 nflat = cpl_frameset_count_tags(frameset, norm_flat_tag);
00314 if (nflat == 0) {
00315 cpl_msg_error(recipe, "Missing required input: %s", norm_flat_tag);
00316 fors_flatfield_exit(NULL);
00317 }
00318 if (nflat > 1) {
00319 cpl_msg_error(recipe, "Too many in input (%d > 1): %s",
00320 nflat, norm_flat_tag);
00321 fors_flatfield_exit(NULL);
00322 }
00323
00324 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00325 fors_flatfield_exit("Input frames are not from the same grism");
00326
00327 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00328 fors_flatfield_exit("Input frames are not from the same filter");
00329
00330 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00331 fors_flatfield_exit("Input frames are not from the same chip");
00332
00333 header = dfs_load_header(frameset, raw_image_tag, 0);
00334
00335 if (header == NULL) {
00336 cpl_msg_error(recipe, "Cannot load header of %s frame", raw_image_tag);
00337 fors_flatfield_exit(NULL);
00338 }
00339
00340 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00341 if (instrume == NULL) {
00342 cpl_msg_error(recipe, "Missing keyword INSTRUME in %s header",
00343 raw_image_tag);
00344 fors_flatfield_exit(NULL);
00345 }
00346
00347 if (instrume[4] == '1')
00348 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00349 if (instrume[4] == '2')
00350 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00351
00352 cpl_msg_indent_less();
00353 cpl_msg_info(recipe, "Load input frames:");
00354 cpl_msg_indent_more();
00355
00356 norm_flat = dfs_load_image(frameset, norm_flat_tag, CPL_TYPE_FLOAT, 0, 1);
00357 if (norm_flat == NULL)
00358 fors_flatfield_exit("Cannot load normalised flat field");
00359
00360 raw_image = dfs_load_image(frameset, raw_image_tag, CPL_TYPE_FLOAT, 0, 0);
00361 if (raw_image == NULL) {
00362 cpl_msg_error(recipe, "Cannot load %s frame", raw_image_tag);
00363 fors_flatfield_exit(NULL);
00364 }
00365
00366 cpl_msg_indent_less();
00367 cpl_msg_info(recipe, "Divide input %s by flat field...", raw_image_tag);
00368 cpl_msg_indent_more();
00369
00370 if (cpl_image_divide(raw_image, norm_flat) != CPL_ERROR_NONE) {
00371 cpl_msg_error(recipe, "Failure of flat field correction: %s",
00372 cpl_error_get_message());
00373 fors_flatfield_exit(NULL);
00374 }
00375 cpl_image_delete(norm_flat); norm_flat = NULL;
00376
00377 cpl_msg_indent_less();
00378
00379 if (dfs_save_image(frameset, raw_image, pro_image_tag,
00380 header, parlist, recipe, version))
00381 fors_flatfield_exit(NULL);
00382
00383 cpl_propertylist_delete(header); header = NULL;
00384 cpl_image_delete(raw_image); raw_image = NULL;
00385
00386 return 0;
00387 }