FORS Pipeline Reference Manual 4.9.20
|
00001 /* $Id: fors_normalise_flat.c,v 1.6 2013/02/28 15:14:38 cgarcia 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: cgarcia $ 00023 * $Date: 2013/02/28 15:14:38 $ 00024 * $Revision: 1.6 $ 00025 * $Name: fors-4_9_20 $ 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_normalise_flat_create(cpl_plugin *); 00038 static int fors_normalise_flat_exec(cpl_plugin *); 00039 static int fors_normalise_flat_destroy(cpl_plugin *); 00040 static int fors_normalise_flat(cpl_parameterlist *, cpl_frameset *); 00041 00042 static char fors_normalise_flat_description[] = 00043 "This recipe is used to normalise a master flat field frame dividing it\n" 00044 "by its large scale illumination trend. This recipe can be applied both\n" 00045 "to generic multi-slit (MOS/MXU) and to long slit exposures (either LSS, or\n" 00046 "LSS-like MOS/MXU), even if different normalisation methods are applied in\n" 00047 "such different cases. The input master flat field image is the product\n" 00048 "of the recipe fors_flat. The input spectral curvature table, product of\n" 00049 "the recipe fors_detect_spectra, is only required in the case of multi-slit\n" 00050 "data.\n" 00051 "\n" 00052 "In the case of multi-slit data, the flat field spectra are spatially\n" 00053 "rectified, heavily smoothed, and then mapped back on the CCD. Then the\n" 00054 "master flat image is divided by its smoothed counterpart. The smoothing\n" 00055 "may be obtained either by applying a running median filter of specified\n" 00056 "sizes, or by polynomial fitting along the dispersion direction performed\n" 00057 "independently for each row of the spatially remapped spectra.\n" 00058 "\n" 00059 "In the case of long-slit data, the smoothing can still be obtained either\n" 00060 "by applying a running median filter or by polynomial fitting, but the\n" 00061 "polynomial fitting will be performed along the spatial direction, for\n" 00062 "each column of the spectrum.\n" 00063 "\n" 00064 "In the table below the MXU acronym can be alternatively read as MOS or\n" 00065 "LSS.\n\n" 00066 "Input files:\n\n" 00067 " DO category: Type: Explanation: Required:\n" 00068 " MASTER_SCREEN_FLAT_MXU Calib Master flat frame Y\n" 00069 " CURV_COEFF_MXU Calib Spectral curvature .\n" 00070 " GRISM_TABLE Calib Grism table .\n\n" 00071 "Output files:\n\n" 00072 " DO category: Data type: Explanation:\n" 00073 " MASTER_NORM_FLAT_MXU FITS image Normalised flat field\n\n"; 00074 00075 #define fors_normalise_flat_exit(message) \ 00076 { \ 00077 if (message) cpl_msg_error(recipe, message); \ 00078 cpl_image_delete(master_flat); \ 00079 cpl_image_delete(spatial); \ 00080 cpl_image_delete(coordinate); \ 00081 cpl_image_delete(smo_flat); \ 00082 cpl_table_delete(grism_table); \ 00083 cpl_table_delete(maskslits); \ 00084 cpl_table_delete(slits); \ 00085 cpl_table_delete(polytraces); \ 00086 cpl_propertylist_delete(header); \ 00087 cpl_msg_indent_less(); \ 00088 return -1; \ 00089 } 00090 00091 #define fors_normalise_flat_exit_memcheck(message) \ 00092 { \ 00093 if (message) cpl_msg_info(recipe, message); \ 00094 printf("free master_flat (%p)\n", master_flat); \ 00095 cpl_image_delete(master_flat); \ 00096 printf("free spatial (%p)\n", spatial); \ 00097 cpl_image_delete(spatial); \ 00098 printf("free coordinate (%p)\n", coordinate); \ 00099 cpl_image_delete(coordinate); \ 00100 printf("free smo_flat (%p)\n", smo_flat); \ 00101 cpl_image_delete(smo_flat); \ 00102 printf("free grism_table (%p)\n", grism_table); \ 00103 cpl_table_delete(grism_table); \ 00104 printf("free maskslits (%p)\n", maskslits); \ 00105 cpl_table_delete(maskslits); \ 00106 printf("free slits (%p)\n", slits); \ 00107 cpl_table_delete(slits); \ 00108 printf("free polytraces (%p)\n", polytraces); \ 00109 cpl_table_delete(polytraces); \ 00110 printf("free header (%p)\n", header); \ 00111 cpl_propertylist_delete(header); \ 00112 cpl_msg_indent_less(); \ 00113 return 0; \ 00114 } 00115 00116 00128 int cpl_plugin_get_info(cpl_pluginlist *list) 00129 { 00130 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe ); 00131 cpl_plugin *plugin = &recipe->interface; 00132 00133 cpl_plugin_init(plugin, 00134 CPL_PLUGIN_API, 00135 FORS_BINARY_VERSION, 00136 CPL_PLUGIN_TYPE_RECIPE, 00137 "fors_normalise_flat", 00138 "Normalise master flat spectrum", 00139 fors_normalise_flat_description, 00140 "Carlo Izzo", 00141 PACKAGE_BUGREPORT, 00142 "This file is currently part of the FORS Instrument Pipeline\n" 00143 "Copyright (C) 2002-2010 European Southern Observatory\n\n" 00144 "This program is free software; you can redistribute it and/or modify\n" 00145 "it under the terms of the GNU General Public License as published by\n" 00146 "the Free Software Foundation; either version 2 of the License, or\n" 00147 "(at your option) any later version.\n\n" 00148 "This program is distributed in the hope that it will be useful,\n" 00149 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 00150 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 00151 "GNU General Public License for more details.\n\n" 00152 "You should have received a copy of the GNU General Public License\n" 00153 "along with this program; if not, write to the Free Software Foundation,\n" 00154 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n", 00155 fors_normalise_flat_create, 00156 fors_normalise_flat_exec, 00157 fors_normalise_flat_destroy); 00158 00159 cpl_pluginlist_append(list, plugin); 00160 00161 return 0; 00162 } 00163 00164 00175 static int fors_normalise_flat_create(cpl_plugin *plugin) 00176 { 00177 cpl_recipe *recipe; 00178 cpl_parameter *p; 00179 00180 /* 00181 * Check that the plugin is part of a valid recipe 00182 */ 00183 00184 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00185 recipe = (cpl_recipe *)plugin; 00186 else 00187 return -1; 00188 00189 /* 00190 * Create the (empty) parameters list in the cpl_recipe object 00191 */ 00192 00193 recipe->parameters = cpl_parameterlist_new(); 00194 00195 /* 00196 * Dispersion 00197 */ 00198 00199 p = cpl_parameter_new_value("fors.fors_normalise_flat.dispersion", 00200 CPL_TYPE_DOUBLE, 00201 "Expected spectral dispersion (Angstrom/pixel)", 00202 "fors.fors_normalise_flat", 00203 0.0); 00204 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dispersion"); 00205 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00206 cpl_parameterlist_append(recipe->parameters, p); 00207 00208 /* 00209 * Start wavelength for spectral extraction 00210 */ 00211 00212 p = cpl_parameter_new_value("fors.fors_normalise_flat.startwavelength", 00213 CPL_TYPE_DOUBLE, 00214 "Start wavelength in spectral extraction", 00215 "fors.fors_normalise_flat", 00216 0.0); 00217 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "startwavelength"); 00218 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00219 cpl_parameterlist_append(recipe->parameters, p); 00220 00221 /* 00222 * End wavelength for spectral extraction 00223 */ 00224 00225 p = cpl_parameter_new_value("fors.fors_normalise_flat.endwavelength", 00226 CPL_TYPE_DOUBLE, 00227 "End wavelength in spectral extraction", 00228 "fors.fors_normalise_flat", 00229 0.0); 00230 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "endwavelength"); 00231 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00232 cpl_parameterlist_append(recipe->parameters, p); 00233 00234 /* 00235 * Degree of flat field fitting polynomial along spatial direction 00236 * (used for LSS data) 00237 */ 00238 00239 p = cpl_parameter_new_value("fors.fors_normalise_flat.sdegree", 00240 CPL_TYPE_INT, 00241 "Degree of flat field fitting polynomial " 00242 "along spatial direction (used for LSS " 00243 "data only)", 00244 "fors.fors_normalise_flat", 00245 4); 00246 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sdegree"); 00247 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00248 cpl_parameterlist_append(recipe->parameters, p); 00249 00250 /* 00251 * Degree of flat field fitting polynomial along dispersion direction 00252 * (used for MOS and MXU data) 00253 */ 00254 00255 p = cpl_parameter_new_value("fors.fors_normalise_flat.ddegree", 00256 CPL_TYPE_INT, 00257 "Degree of flat field fitting polynomial " 00258 "along dispersion direction (used for MOS " 00259 "and MXU data only)", 00260 "fors.fors_normalise_flat", 00261 -1); 00262 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ddegree"); 00263 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00264 cpl_parameterlist_append(recipe->parameters, p); 00265 00266 /* 00267 * Smooth box radius for flat field along dispersion direction 00268 */ 00269 00270 p = cpl_parameter_new_value("fors.fors_normalise_flat.dradius", 00271 CPL_TYPE_INT, 00272 "Smooth box radius for flat field along " 00273 "dispersion direction", 00274 "fors.fors_normalise_flat", 00275 10); 00276 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "dradius"); 00277 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00278 cpl_parameterlist_append(recipe->parameters, p); 00279 00280 /* 00281 * Smooth box radius for flat field along spatial direction 00282 * (used for LSS data only) 00283 */ 00284 00285 p = cpl_parameter_new_value("fors.fors_normalise_flat.sradius", 00286 CPL_TYPE_INT, 00287 "Smooth box radius for flat field along " 00288 "spatial direction", 00289 "fors.fors_normalise_flat", 00290 10); 00291 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "sradius"); 00292 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); 00293 cpl_parameterlist_append(recipe->parameters, p); 00294 00295 return 0; 00296 } 00297 00298 00307 static int fors_normalise_flat_exec(cpl_plugin *plugin) 00308 { 00309 cpl_recipe *recipe; 00310 00311 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00312 recipe = (cpl_recipe *)plugin; 00313 else 00314 return -1; 00315 00316 return fors_normalise_flat(recipe->parameters, recipe->frames); 00317 } 00318 00319 00328 static int fors_normalise_flat_destroy(cpl_plugin *plugin) 00329 { 00330 cpl_recipe *recipe; 00331 00332 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE) 00333 recipe = (cpl_recipe *)plugin; 00334 else 00335 return -1; 00336 00337 cpl_parameterlist_delete(recipe->parameters); 00338 00339 return 0; 00340 } 00341 00342 00352 static int fors_normalise_flat(cpl_parameterlist *parlist, 00353 cpl_frameset *frameset) 00354 { 00355 00356 const char *recipe = "fors_normalise_flat"; 00357 00358 00359 /* 00360 * Input parameters 00361 */ 00362 00363 double dispersion; 00364 double startwavelength; 00365 double endwavelength; 00366 int sdegree; 00367 int ddegree; 00368 int sradius; 00369 int dradius; 00370 00371 /* 00372 * CPL objects 00373 */ 00374 00375 cpl_image *master_flat = NULL; 00376 cpl_image *smo_flat = NULL; 00377 cpl_image *coordinate = NULL; 00378 cpl_image *spatial = NULL; 00379 cpl_table *grism_table = NULL; 00380 cpl_table *slits = NULL; 00381 cpl_table *polytraces = NULL; 00382 cpl_table *maskslits = NULL; 00383 cpl_propertylist *header = NULL; 00384 00385 /* 00386 * Auxiliary variables 00387 */ 00388 00389 char version[80]; 00390 const char *master_flat_tag; 00391 const char *master_norm_flat_tag; 00392 const char *slit_location_tag; 00393 const char *curv_coeff_tag; 00394 int mxu, mos, lss; 00395 int nflat; 00396 int rebin; 00397 int nx, ny; 00398 int nslits; 00399 int treat_as_lss; 00400 int i; 00401 double reference; 00402 double *xpos; 00403 double mxpos; 00404 00405 char *instrume = NULL; 00406 00407 00408 cpl_msg_set_indentation(2); 00409 00410 if (dfs_files_dont_exist(frameset)) 00411 fors_normalise_flat_exit(NULL); 00412 00413 00414 /* 00415 * Get configuration parameters 00416 */ 00417 00418 cpl_msg_info(recipe, "Recipe %s configuration parameters:", recipe); 00419 cpl_msg_indent_more(); 00420 00421 if (cpl_frameset_count_tags(frameset, "GRISM_TABLE") > 1) 00422 fors_normalise_flat_exit("Too many in input: GRISM_TABLE"); 00423 00424 grism_table = dfs_load_table(frameset, "GRISM_TABLE", 1); 00425 00426 dispersion = dfs_get_parameter_double(parlist, 00427 "fors.fors_normalise_flat.dispersion", grism_table); 00428 00429 if (dispersion <= 0.0) 00430 fors_normalise_flat_exit("Invalid spectral dispersion value"); 00431 00432 startwavelength = dfs_get_parameter_double(parlist, 00433 "fors.fors_normalise_flat.startwavelength", grism_table); 00434 if (startwavelength > 1.0) 00435 if (startwavelength < 3000.0 || startwavelength > 13000.0) 00436 fors_normalise_flat_exit("Invalid wavelength"); 00437 00438 endwavelength = dfs_get_parameter_double(parlist, 00439 "fors.fors_normalise_flat.endwavelength", grism_table); 00440 if (endwavelength > 1.0) { 00441 if (endwavelength < 3000.0 || endwavelength > 13000.0) 00442 fors_normalise_flat_exit("Invalid wavelength"); 00443 if (startwavelength < 1.0) 00444 fors_normalise_flat_exit("Invalid wavelength interval"); 00445 } 00446 00447 if (startwavelength > 1.0) 00448 if (endwavelength - startwavelength <= 0.0) 00449 fors_normalise_flat_exit("Invalid wavelength interval"); 00450 00451 sdegree = dfs_get_parameter_int(parlist, 00452 "fors.fors_normalise_flat.sdegree", NULL); 00453 ddegree = dfs_get_parameter_int(parlist, 00454 "fors.fors_normalise_flat.ddegree", NULL); 00455 sradius = dfs_get_parameter_int(parlist, 00456 "fors.fors_normalise_flat.sradius", NULL); 00457 dradius = dfs_get_parameter_int(parlist, 00458 "fors.fors_normalise_flat.dradius", NULL); 00459 00460 if (sradius < 1 || dradius < 1) 00461 fors_normalise_flat_exit("Invalid smoothing box radius"); 00462 00463 cpl_table_delete(grism_table); grism_table = NULL; 00464 00465 if (cpl_error_get_code()) 00466 fors_normalise_flat_exit("Failure reading the configuration " 00467 "parameters"); 00468 00469 00470 cpl_msg_indent_less(); 00471 cpl_msg_info(recipe, "Check input set-of-frames:"); 00472 cpl_msg_indent_more(); 00473 00474 nflat = mxu = cpl_frameset_count_tags(frameset, "MASTER_SCREEN_FLAT_MXU"); 00475 nflat += mos = cpl_frameset_count_tags(frameset, "MASTER_SCREEN_FLAT_MOS"); 00476 nflat += lss = cpl_frameset_count_tags(frameset, "MASTER_SCREEN_FLAT_LSS"); 00477 00478 if (nflat == 0) { 00479 fors_normalise_flat_exit("Missing input master flat field frame"); 00480 } 00481 if (nflat > 1) { 00482 cpl_msg_error(recipe, "Too many input flat frames (%d > 1)", nflat); 00483 fors_normalise_flat_exit(NULL); 00484 } 00485 00486 if (mxu) { 00487 master_flat_tag = "MASTER_SCREEN_FLAT_MXU"; 00488 master_norm_flat_tag = "MASTER_NORM_FLAT_MXU"; 00489 slit_location_tag = "SLIT_LOCATION_MXU"; 00490 curv_coeff_tag = "CURV_COEFF_MXU"; 00491 } 00492 else if (mos) { 00493 master_flat_tag = "MASTER_SCREEN_FLAT_MOS"; 00494 master_norm_flat_tag = "MASTER_NORM_FLAT_MOS"; 00495 slit_location_tag = "SLIT_LOCATION_MOS"; 00496 curv_coeff_tag = "CURV_COEFF_MOS"; 00497 } 00498 else if (lss) { 00499 master_flat_tag = "MASTER_SCREEN_FLAT_LSS"; 00500 master_norm_flat_tag = "MASTER_NORM_FLAT_LSS"; 00501 } 00502 00503 header = dfs_load_header(frameset, master_flat_tag, 0); 00504 00505 if (mos || mxu) { 00506 int nslits_out_det = 0; 00507 if (mos) 00508 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det); 00509 else 00510 maskslits = mos_load_slits_fors_mxu(header); 00511 00512 /* 00513 * Check if all slits have the same X offset: in such case, 00514 * treat the observation as a long-slit one! 00515 */ 00516 00517 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det); 00518 00519 cpl_table_delete(maskslits); maskslits = NULL; 00520 00521 if (treat_as_lss) 00522 cpl_msg_warning(recipe, "All MOS slits have the same offset: %.2f\n" 00523 "The LSS data reduction strategy is applied!", 00524 mxpos); 00525 } 00526 00527 if (!(lss || treat_as_lss)) { 00528 if (cpl_frameset_count_tags(frameset, curv_coeff_tag) == 0) { 00529 cpl_msg_error(recipe, "Missing input: %s", curv_coeff_tag); 00530 fors_normalise_flat_exit(NULL); 00531 } 00532 00533 if (cpl_frameset_count_tags(frameset, curv_coeff_tag) > 1) { 00534 cpl_msg_error(recipe, "Too many in input: %s", curv_coeff_tag); 00535 fors_normalise_flat_exit(NULL); 00536 } 00537 00538 if (cpl_frameset_count_tags(frameset, slit_location_tag) == 0) { 00539 cpl_msg_error(recipe, "Missing input: %s", slit_location_tag); 00540 fors_normalise_flat_exit(NULL); 00541 } 00542 00543 if (cpl_frameset_count_tags(frameset, slit_location_tag) > 1) { 00544 cpl_msg_error(recipe, "Too many in input: %s", slit_location_tag); 00545 fors_normalise_flat_exit(NULL); 00546 } 00547 } 00548 00549 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00550 fors_normalise_flat_exit("Input frames are not from the same grism"); 00551 00552 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00553 fors_normalise_flat_exit("Input frames are not from the same filter"); 00554 00555 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00556 fors_normalise_flat_exit("Input frames are not from the same chip"); 00557 00558 00559 /* 00560 * Get the reference wavelength and the rebin factor along the 00561 * dispersion direction from the master flat frame 00562 */ 00563 00564 if (header == NULL) 00565 fors_normalise_flat_exit("Cannot load master flat frame header"); 00566 00567 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00568 if (instrume == NULL) 00569 fors_normalise_flat_exit("Missing keyword INSTRUME in master " 00570 "flat header"); 00571 00572 if (instrume[4] == '1') 00573 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00574 if (instrume[4] == '2') 00575 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00576 00577 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN"); 00578 00579 if (cpl_error_get_code() != CPL_ERROR_NONE) 00580 fors_normalise_flat_exit("Missing keyword ESO INS GRIS1 WLEN " 00581 "in master flat frame header"); 00582 00583 if (reference < 3000.0) /* Perhaps in nanometers... */ 00584 reference *= 10; 00585 00586 if (reference < 3000.0 || reference > 13000.0) { 00587 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from " 00588 "keyword ESO INS GRIS1 WLEN in master flat header", 00589 reference); 00590 fors_normalise_flat_exit(NULL); 00591 } 00592 00593 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference); 00594 00595 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX"); 00596 00597 if (cpl_error_get_code() != CPL_ERROR_NONE) 00598 fors_normalise_flat_exit("Missing keyword ESO DET WIN1 BINX " 00599 "in master flat header"); 00600 00601 if (rebin != 1) { 00602 dispersion *= rebin; 00603 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the " 00604 "working dispersion used is %f A/pixel", rebin, 00605 dispersion); 00606 } 00607 00608 00609 cpl_msg_indent_less(); 00610 cpl_msg_info(recipe, "Load input frames..."); 00611 cpl_msg_indent_more(); 00612 00613 master_flat = dfs_load_image(frameset, master_flat_tag, 00614 CPL_TYPE_FLOAT, 0, 0); 00615 if (master_flat == NULL) 00616 fors_normalise_flat_exit("Cannot load master flat field frame"); 00617 00618 00619 cpl_msg_indent_less(); 00620 cpl_msg_info(recipe, "Perform flat field normalisation..."); 00621 cpl_msg_indent_more(); 00622 00623 if (lss || treat_as_lss) { 00624 00625 /* FIXME: 00626 * The LSS data calibration is still dirty: it doesn't apply 00627 * any spatial rectification, and only in future an external 00628 * spectral curvature model would be provided in input. Here 00629 * and there temporary solutions are adpted, such as accepting 00630 * the preliminary wavelength calibration. 00631 */ 00632 00633 /* 00634 * Flat field normalisation is done directly on the master flat 00635 * field (without spatial rectification first). The spectral 00636 * curvature model may be provided in input, in future releases. 00637 */ 00638 00639 smo_flat = mos_normalise_longflat(master_flat, 00640 sradius, dradius, sdegree); 00641 00642 cpl_image_delete(smo_flat); smo_flat = NULL; /* It may be a product */ 00643 00644 if (dfs_save_image(frameset, master_flat, master_norm_flat_tag, 00645 header, parlist, recipe, version)) 00646 fors_normalise_flat_exit(NULL); 00647 00648 cpl_propertylist_delete(header); header = NULL; 00649 cpl_image_delete(master_flat); master_flat = NULL; 00650 00651 return 0; 00652 } 00653 00654 00655 /* 00656 * This is the generic MOS/MXU handling 00657 */ 00658 00659 slits = dfs_load_table(frameset, slit_location_tag, 1); 00660 if (slits == NULL) 00661 fors_normalise_flat_exit("Cannot load slits location table"); 00662 00663 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1); 00664 if (slits == NULL) 00665 fors_normalise_flat_exit("Cannot load spectral curvature table"); 00666 00667 nx = cpl_image_get_size_x(master_flat); 00668 ny = cpl_image_get_size_y(master_flat); 00669 00670 coordinate = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 00671 spatial = mos_spatial_calibration(master_flat, slits, polytraces, 00672 reference, 00673 startwavelength, endwavelength, 00674 dispersion, 0, coordinate); 00675 00676 cpl_image_delete(spatial); spatial = NULL; 00677 00678 smo_flat = mos_normalise_flat(master_flat, coordinate, slits, polytraces, 00679 reference, startwavelength, endwavelength, 00680 dispersion, dradius, ddegree); 00681 00682 cpl_image_delete(smo_flat); smo_flat = NULL; /* It may be a product */ 00683 cpl_image_delete(coordinate); coordinate = NULL; 00684 cpl_table_delete(polytraces); polytraces = NULL; 00685 cpl_table_delete(slits); slits = NULL; 00686 00687 if (dfs_save_image(frameset, master_flat, master_norm_flat_tag, 00688 header, parlist, recipe, version)) 00689 fors_normalise_flat_exit(NULL); 00690 00691 cpl_propertylist_delete(header); header = NULL; 00692 cpl_image_delete(master_flat); master_flat = NULL; 00693 00694 return 0; 00695 }