FORS Pipeline Reference Manual 4.9.9
|
00001 /* $Id: fors_normalise_flat.c,v 1.5 2010/09/14 07:38:16 cizzo 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: cizzo $ 00023 * $Date: 2010/09/14 07:38:16 $ 00024 * $Revision: 1.5 $ 00025 * $Name: fors-4_9_9 $ 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 if (mos) 00507 maskslits = mos_load_slits_fors_mos(header); 00508 else 00509 maskslits = mos_load_slits_fors_mxu(header); 00510 00511 /* 00512 * Check if all slits have the same X offset: in such case, 00513 * treat the observation as a long-slit one! 00514 */ 00515 00516 mxpos = cpl_table_get_column_median(maskslits, "xtop"); 00517 xpos = cpl_table_get_data_double(maskslits, "xtop"); 00518 nslits = cpl_table_get_nrow(maskslits); 00519 00520 treat_as_lss = 1; 00521 for (i = 0; i < nslits; i++) { 00522 if (fabs(mxpos-xpos[i]) > 0.01) { 00523 treat_as_lss = 0; 00524 break; 00525 } 00526 } 00527 00528 cpl_table_delete(maskslits); maskslits = NULL; 00529 00530 if (treat_as_lss) 00531 cpl_msg_warning(recipe, "All MOS slits have the same offset: %.2f\n" 00532 "The LSS data reduction strategy is applied!", 00533 mxpos); 00534 } 00535 00536 if (!(lss || treat_as_lss)) { 00537 if (cpl_frameset_count_tags(frameset, curv_coeff_tag) == 0) { 00538 cpl_msg_error(recipe, "Missing input: %s", curv_coeff_tag); 00539 fors_normalise_flat_exit(NULL); 00540 } 00541 00542 if (cpl_frameset_count_tags(frameset, curv_coeff_tag) > 1) { 00543 cpl_msg_error(recipe, "Too many in input: %s", curv_coeff_tag); 00544 fors_normalise_flat_exit(NULL); 00545 } 00546 00547 if (cpl_frameset_count_tags(frameset, slit_location_tag) == 0) { 00548 cpl_msg_error(recipe, "Missing input: %s", slit_location_tag); 00549 fors_normalise_flat_exit(NULL); 00550 } 00551 00552 if (cpl_frameset_count_tags(frameset, slit_location_tag) > 1) { 00553 cpl_msg_error(recipe, "Too many in input: %s", slit_location_tag); 00554 fors_normalise_flat_exit(NULL); 00555 } 00556 } 00557 00558 if (!dfs_equal_keyword(frameset, "ESO INS GRIS1 ID")) 00559 fors_normalise_flat_exit("Input frames are not from the same grism"); 00560 00561 if (!dfs_equal_keyword(frameset, "ESO INS FILT1 ID")) 00562 fors_normalise_flat_exit("Input frames are not from the same filter"); 00563 00564 if (!dfs_equal_keyword(frameset, "ESO DET CHIP1 ID")) 00565 fors_normalise_flat_exit("Input frames are not from the same chip"); 00566 00567 00568 /* 00569 * Get the reference wavelength and the rebin factor along the 00570 * dispersion direction from the master flat frame 00571 */ 00572 00573 if (header == NULL) 00574 fors_normalise_flat_exit("Cannot load master flat frame header"); 00575 00576 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME"); 00577 if (instrume == NULL) 00578 fors_normalise_flat_exit("Missing keyword INSTRUME in master " 00579 "flat header"); 00580 00581 if (instrume[4] == '1') 00582 snprintf(version, 80, "%s/%s", "fors1", VERSION); 00583 if (instrume[4] == '2') 00584 snprintf(version, 80, "%s/%s", "fors2", VERSION); 00585 00586 reference = cpl_propertylist_get_double(header, "ESO INS GRIS1 WLEN"); 00587 00588 if (cpl_error_get_code() != CPL_ERROR_NONE) 00589 fors_normalise_flat_exit("Missing keyword ESO INS GRIS1 WLEN " 00590 "in master flat frame header"); 00591 00592 if (reference < 3000.0) /* Perhaps in nanometers... */ 00593 reference *= 10; 00594 00595 if (reference < 3000.0 || reference > 13000.0) { 00596 cpl_msg_error(recipe, "Invalid central wavelength %.2f read from " 00597 "keyword ESO INS GRIS1 WLEN in master flat header", 00598 reference); 00599 fors_normalise_flat_exit(NULL); 00600 } 00601 00602 cpl_msg_info(recipe, "The central wavelength is: %.2f", reference); 00603 00604 rebin = cpl_propertylist_get_int(header, "ESO DET WIN1 BINX"); 00605 00606 if (cpl_error_get_code() != CPL_ERROR_NONE) 00607 fors_normalise_flat_exit("Missing keyword ESO DET WIN1 BINX " 00608 "in master flat header"); 00609 00610 if (rebin != 1) { 00611 dispersion *= rebin; 00612 cpl_msg_warning(recipe, "The rebin factor is %d, and therefore the " 00613 "working dispersion used is %f A/pixel", rebin, 00614 dispersion); 00615 } 00616 00617 00618 cpl_msg_indent_less(); 00619 cpl_msg_info(recipe, "Load input frames..."); 00620 cpl_msg_indent_more(); 00621 00622 master_flat = dfs_load_image(frameset, master_flat_tag, 00623 CPL_TYPE_FLOAT, 0, 0); 00624 if (master_flat == NULL) 00625 fors_normalise_flat_exit("Cannot load master flat field frame"); 00626 00627 00628 cpl_msg_indent_less(); 00629 cpl_msg_info(recipe, "Perform flat field normalisation..."); 00630 cpl_msg_indent_more(); 00631 00632 if (lss || treat_as_lss) { 00633 00634 /* FIXME: 00635 * The LSS data calibration is still dirty: it doesn't apply 00636 * any spatial rectification, and only in future an external 00637 * spectral curvature model would be provided in input. Here 00638 * and there temporary solutions are adpted, such as accepting 00639 * the preliminary wavelength calibration. 00640 */ 00641 00642 /* 00643 * Flat field normalisation is done directly on the master flat 00644 * field (without spatial rectification first). The spectral 00645 * curvature model may be provided in input, in future releases. 00646 */ 00647 00648 smo_flat = mos_normalise_longflat(master_flat, 00649 sradius, dradius, sdegree); 00650 00651 cpl_image_delete(smo_flat); smo_flat = NULL; /* It may be a product */ 00652 00653 if (dfs_save_image(frameset, master_flat, master_norm_flat_tag, 00654 header, parlist, recipe, version)) 00655 fors_normalise_flat_exit(NULL); 00656 00657 cpl_propertylist_delete(header); header = NULL; 00658 cpl_image_delete(master_flat); master_flat = NULL; 00659 00660 return 0; 00661 } 00662 00663 00664 /* 00665 * This is the generic MOS/MXU handling 00666 */ 00667 00668 slits = dfs_load_table(frameset, slit_location_tag, 1); 00669 if (slits == NULL) 00670 fors_normalise_flat_exit("Cannot load slits location table"); 00671 00672 polytraces = dfs_load_table(frameset, curv_coeff_tag, 1); 00673 if (slits == NULL) 00674 fors_normalise_flat_exit("Cannot load spectral curvature table"); 00675 00676 nx = cpl_image_get_size_x(master_flat); 00677 ny = cpl_image_get_size_y(master_flat); 00678 00679 coordinate = cpl_image_new(nx, ny, CPL_TYPE_FLOAT); 00680 spatial = mos_spatial_calibration(master_flat, slits, polytraces, 00681 reference, 00682 startwavelength, endwavelength, 00683 dispersion, 0, coordinate); 00684 00685 cpl_image_delete(spatial); spatial = NULL; 00686 00687 smo_flat = mos_normalise_flat(master_flat, coordinate, slits, polytraces, 00688 reference, startwavelength, endwavelength, 00689 dispersion, dradius, ddegree); 00690 00691 cpl_image_delete(smo_flat); smo_flat = NULL; /* It may be a product */ 00692 cpl_image_delete(coordinate); coordinate = NULL; 00693 cpl_table_delete(polytraces); polytraces = NULL; 00694 cpl_table_delete(slits); slits = NULL; 00695 00696 if (dfs_save_image(frameset, master_flat, master_norm_flat_tag, 00697 header, parlist, recipe, version)) 00698 fors_normalise_flat_exit(NULL); 00699 00700 cpl_propertylist_delete(header); header = NULL; 00701 cpl_image_delete(master_flat); master_flat = NULL; 00702 00703 return 0; 00704 }