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_flat_create(cpl_plugin *);
00038 static int fors_flat_exec(cpl_plugin *);
00039 static int fors_flat_destroy(cpl_plugin *);
00040 static int fors_flat(cpl_parameterlist *, cpl_frameset *);
00041
00042 static char fors_flat_description[] =
00043 "This recipe is used to subtract the master bias, produced by the recipe\n"
00044 "fors_bias, from a set of raw flat field frames. The input raw frames are\n"
00045 "summed, the master bias frame is rescaled accordingly, and subtracted\n"
00046 "from the result. The overscan regions, if present, are used to compensate\n"
00047 "for variations of the bias level between master bias and input raw frames.\n"
00048 "The overscan regions are then trimmed from the result.\n"
00049 "In the table below the MXU acronym can be alternatively read as MOS and\n"
00050 "LSS.\n\n"
00051 "Input files:\n\n"
00052 " DO category: Type: Explanation: Required:\n"
00053 " SCREEN_FLAT_MXU Raw Raw data frame Y\n"
00054 " MASTER_BIAS Calib Master bias frame Y\n\n"
00055 "Output files:\n\n"
00056 " DO category: Data type: Explanation:\n"
00057 " MASTER_SCREEN_FLAT_MXU FITS image Bias subtracted sum frame\n\n";
00058
00059 #define fors_flat_exit(message) \
00060 { \
00061 if (message) cpl_msg_error(recipe, message); \
00062 cpl_image_delete(flat); \
00063 cpl_image_delete(master_flat); \
00064 cpl_image_delete(master_bias); \
00065 cpl_propertylist_delete(header); \
00066 cpl_table_delete(overscans); \
00067 cpl_msg_indent_less(); \
00068 return -1; \
00069 }
00070
00071 #define fors_flat_exit_memcheck(message) \
00072 { \
00073 if (message) cpl_msg_info(recipe, message); \
00074 printf("free flat (%p)\n", flat); \
00075 cpl_image_delete(flat); \
00076 printf("free master_flat (%p)\n", master_flat); \
00077 cpl_image_delete(master_flat); \
00078 printf("free master_bias (%p)\n", master_bias); \
00079 cpl_image_delete(master_bias); \
00080 printf("free header (%p)\n", header); \
00081 cpl_propertylist_delete(header); \
00082 printf("free overscans (%p)\n", overscans); \
00083 cpl_table_delete(overscans); \
00084 cpl_msg_indent_less(); \
00085 return 0; \
00086 }
00087
00088
00100 int cpl_plugin_get_info(cpl_pluginlist *list)
00101 {
00102 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00103 cpl_plugin *plugin = &recipe->interface;
00104
00105 cpl_plugin_init(plugin,
00106 CPL_PLUGIN_API,
00107 FORS_BINARY_VERSION,
00108 CPL_PLUGIN_TYPE_RECIPE,
00109 "fors_flat",
00110 "Sum input flat field frames and remove bias",
00111 fors_flat_description,
00112 "Carlo Izzo",
00113 PACKAGE_BUGREPORT,
00114 "This file is currently part of the FORS Instrument Pipeline\n"
00115 "Copyright (C) 2002-2006 European Southern Observatory\n\n"
00116 "This program is free software; you can redistribute it and/or modify\n"
00117 "it under the terms of the GNU General Public License as published by\n"
00118 "the Free Software Foundation; either version 2 of the License, or\n"
00119 "(at your option) any later version.\n\n"
00120 "This program is distributed in the hope that it will be useful,\n"
00121 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00122 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00123 "GNU General Public License for more details.\n\n"
00124 "You should have received a copy of the GNU General Public License\n"
00125 "along with this program; if not, write to the Free Software Foundation,\n"
00126 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
00127 fors_flat_create,
00128 fors_flat_exec,
00129 fors_flat_destroy);
00130
00131 cpl_pluginlist_append(list, plugin);
00132
00133 return 0;
00134 }
00135
00136
00147 static int fors_flat_create(cpl_plugin *plugin)
00148 {
00149 cpl_recipe *recipe;
00150
00151
00152
00153
00154
00155
00156
00157
00158 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00159 recipe = (cpl_recipe *)plugin;
00160 else
00161 return -1;
00162
00163
00164
00165
00166
00167 recipe->parameters = cpl_parameterlist_new();
00168
00169 return 0;
00170 }
00171
00172
00181 static int fors_flat_exec(cpl_plugin *plugin)
00182 {
00183 cpl_recipe *recipe;
00184
00185 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00186 recipe = (cpl_recipe *)plugin;
00187 else
00188 return -1;
00189
00190 return fors_flat(recipe->parameters, recipe->frames);
00191 }
00192
00193
00202 static int fors_flat_destroy(cpl_plugin *plugin)
00203 {
00204 cpl_recipe *recipe;
00205
00206 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00207 recipe = (cpl_recipe *)plugin;
00208 else
00209 return -1;
00210
00211 cpl_parameterlist_delete(recipe->parameters);
00212
00213 return 0;
00214 }
00215
00216
00226 static int fors_flat(cpl_parameterlist *parlist, cpl_frameset *frameset)
00227 {
00228
00229 const char *recipe = "fors_flat";
00230
00231
00232
00233
00234
00235
00236 cpl_image *flat = NULL;
00237 cpl_image *master_flat = NULL;
00238 cpl_image *master_bias = NULL;
00239 cpl_image *multi_bias = NULL;
00240 cpl_image *dummy = NULL;
00241 cpl_table *overscans = NULL;
00242 cpl_propertylist *header = NULL;
00243
00244
00245
00246
00247
00248 char version[80];
00249 const char *master_bias_tag = "MASTER_BIAS";
00250 const char *flat_tag;
00251 const char *pro_tag;
00252 char *instrume = NULL;
00253 int flat_mxu;
00254 int flat_mos;
00255 int flat_lss;
00256 int nbias, nflat;
00257 int i;
00258
00259
00260 cpl_msg_set_indentation(2);
00261
00262 if (dfs_files_dont_exist(frameset))
00263 fors_flat_exit(NULL);
00264
00265
00266 cpl_msg_info(recipe, "Check input set-of-frames:");
00267 cpl_msg_indent_more();
00268
00269 nbias = cpl_frameset_count_tags(frameset, master_bias_tag);
00270 if (nbias == 0) {
00271 cpl_msg_error(recipe, "Missing required input: %s", master_bias_tag);
00272 fors_flat_exit(NULL);
00273 }
00274 if (nbias > 1) {
00275 cpl_msg_error(recipe, "Too many in input (%d > 1): %s",
00276 nbias, master_bias_tag);
00277 fors_flat_exit(NULL);
00278 }
00279
00280 nflat = flat_mxu = cpl_frameset_count_tags(frameset, "SCREEN_FLAT_MXU");
00281 nflat += flat_mos = cpl_frameset_count_tags(frameset, "SCREEN_FLAT_MOS");
00282 nflat += flat_lss = cpl_frameset_count_tags(frameset, "SCREEN_FLAT_LSS");
00283
00284 if (nflat == 0) {
00285 fors_flat_exit("Missing required input raw frames");
00286 }
00287
00288 if (flat_mxu) {
00289 flat_tag = "SCREEN_FLAT_MXU";
00290 pro_tag = "MASTER_SCREEN_FLAT_MXU";
00291 }
00292 else if (flat_mos) {
00293 flat_tag = "SCREEN_FLAT_MOS";
00294 pro_tag = "MASTER_SCREEN_FLAT_MOS";
00295 }
00296 else if (flat_lss) {
00297 flat_tag = "SCREEN_FLAT_LSS";
00298 pro_tag = "MASTER_SCREEN_FLAT_LSS";
00299 }
00300
00301 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID"))
00302 fors_flat_exit("Input frames are not from the same grism");
00303
00304 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID"))
00305 fors_flat_exit("Input frames are not from the same filter");
00306
00307 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID"))
00308 fors_flat_exit("Input frames are not from the same chip");
00309
00310 header = dfs_load_header(frameset, flat_tag, 0);
00311
00312 if (header == NULL) {
00313 cpl_msg_error(recipe, "Cannot load header of %s frame", flat_tag);
00314 fors_flat_exit(NULL);
00315 }
00316
00317 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00318 if (instrume == NULL) {
00319 cpl_msg_error(recipe, "Missing keyword INSTRUME in %s header",
00320 flat_tag);
00321 fors_flat_exit(NULL);
00322 }
00323
00324 if (instrume[4] == '1')
00325 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00326 if (instrume[4] == '2')
00327 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00328
00329
00330 cpl_msg_indent_less();
00331 cpl_msg_info(recipe, "Load input frames:");
00332 cpl_msg_indent_more();
00333
00334 master_flat = dfs_load_image(frameset, flat_tag, CPL_TYPE_FLOAT, 0, 0);
00335
00336 if (master_flat == NULL)
00337 fors_flat_exit("Cannot load flat field");
00338
00339 for (i = 1; i < nflat; i++) {
00340 flat = dfs_load_image(frameset, NULL, CPL_TYPE_FLOAT, 0, 0);
00341 if (flat) {
00342 cpl_image_add(master_flat, flat);
00343 cpl_image_delete(flat); flat = NULL;
00344 }
00345 else
00346 fors_flat_exit("Cannot load flat field");
00347 }
00348
00349 master_bias = dfs_load_image(frameset,
00350 master_bias_tag, CPL_TYPE_FLOAT, 0, 1);
00351 if (master_bias == NULL)
00352 fors_flat_exit("Cannot load master bias");
00353
00354 cpl_msg_indent_less();
00355 cpl_msg_info(recipe, "Subtract the master bias from sum flat frame...");
00356 cpl_msg_indent_more();
00357
00358 overscans = mos_load_overscans_vimos(header, 1);
00359
00360 if (nflat > 1) {
00361 multi_bias = cpl_image_multiply_scalar_create(master_bias, nflat);
00362 dummy = mos_remove_bias(master_flat, multi_bias, overscans);
00363 cpl_image_delete(multi_bias);
00364 }
00365 else {
00366 dummy = mos_remove_bias(master_flat, master_bias, overscans);
00367 }
00368
00369 cpl_table_delete(overscans); overscans = NULL;
00370 cpl_image_delete(master_bias); master_bias = NULL;
00371 cpl_image_delete(master_flat); master_flat = dummy;
00372
00373 if (master_flat == NULL) {
00374 cpl_msg_error(recipe, "Cannot remove bias from sum flat frame");
00375 fors_flat_exit(NULL);
00376 }
00377
00378 cpl_msg_indent_less();
00379
00380 cpl_propertylist_update_int(header, "ESO PRO DATANCOM", nflat);
00381
00382 if (dfs_save_image(frameset, master_flat, pro_tag,
00383 header, parlist, recipe, version))
00384 fors_flat_exit(NULL);
00385
00386 cpl_image_delete(master_flat); master_flat = NULL;
00387 cpl_propertylist_delete(header); header = NULL;
00388
00389 return 0;
00390 }