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