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_subtract_sky_lss_create(cpl_plugin *);
00038 static int fors_subtract_sky_lss_exec(cpl_plugin *);
00039 static int fors_subtract_sky_lss_destroy(cpl_plugin *);
00040 static int fors_subtract_sky_lss(cpl_parameterlist *, cpl_frameset *);
00041
00042 static char fors_subtract_sky_lss_description[] =
00043 "This recipe is used to subtract the sky from wavelength calibrated\n"
00044 "scientific spectra produced by the recipe fors_resample. A simple median\n"
00045 "signal level is subtracted from each image column.\n"
00046 "In the table below the MXU acronym can be read alternatively as MOS\n"
00047 "and LSS, depending on the instrument mode of the input data. The acronym\n"
00048 "SCI may be read STD in case of standard stars observations.\n"
00049 "Note that only LSS or LSS-like MOS/MXU data are to be processed by this\n"
00050 "recipe.\n\n"
00051 "Input files:\n\n"
00052 " DO category: Type: Explanation: Required:\n"
00053 " MAPPED_ALL_SCI_MXU Raw Scientific exposure Y\n\n"
00054 "Output files:\n\n"
00055 " DO category: Data type: Explanation:\n"
00056 " MAPPED_SCI_MXU FITS image Rectified scientific spectra\n"
00057 " MAPPED_SKY_SCI_MXU FITS image Rectified sky spectra\n\n";
00058
00059 #define fors_subtract_sky_lss_exit(message) \
00060 { \
00061 if ((const char *)message != NULL) cpl_msg_error(recipe, message); \
00062 cpl_image_delete(skymap); \
00063 cpl_image_delete(sky); \
00064 cpl_image_delete(spectra); \
00065 cpl_propertylist_delete(header); \
00066 cpl_msg_indent_less(); \
00067 return -1; \
00068 }
00069
00070
00071 #define fors_subtract_sky_lss_exit_memcheck(message) \
00072 { \
00073 if ((const char *)message != NULL) cpl_msg_info(recipe, message); \
00074 cpl_image_delete(skymap); \
00075 cpl_image_delete(sky); \
00076 cpl_image_delete(spectra); \
00077 cpl_propertylist_delete(header); \
00078 cpl_msg_indent_less(); \
00079 return 0; \
00080 }
00081
00082
00094 int cpl_plugin_get_info(cpl_pluginlist *list)
00095 {
00096 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe );
00097 cpl_plugin *plugin = &recipe->interface;
00098
00099 cpl_plugin_init(plugin,
00100 CPL_PLUGIN_API,
00101 FORS_BINARY_VERSION,
00102 CPL_PLUGIN_TYPE_RECIPE,
00103 "fors_subtract_sky_lss",
00104 "Subtract sky from calibrated long slit exposure",
00105 fors_subtract_sky_lss_description,
00106 "Carlo Izzo",
00107 PACKAGE_BUGREPORT,
00108 "This file is currently part of the FORS Instrument Pipeline\n"
00109 "Copyright (C) 2002-2010 European Southern Observatory\n\n"
00110 "This program is free software; you can redistribute it and/or modify\n"
00111 "it under the terms of the GNU General Public License as published by\n"
00112 "the Free Software Foundation; either version 2 of the License, or\n"
00113 "(at your option) any later version.\n\n"
00114 "This program is distributed in the hope that it will be useful,\n"
00115 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00116 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00117 "GNU General Public License for more details.\n\n"
00118 "You should have received a copy of the GNU General Public License\n"
00119 "along with this program; if not, write to the Free Software Foundation,\n"
00120 "Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n",
00121 fors_subtract_sky_lss_create,
00122 fors_subtract_sky_lss_exec,
00123 fors_subtract_sky_lss_destroy);
00124
00125 cpl_pluginlist_append(list, plugin);
00126
00127 return 0;
00128 }
00129
00130
00141 static int fors_subtract_sky_lss_create(cpl_plugin *plugin)
00142 {
00143 cpl_recipe *recipe;
00144
00145
00146
00147
00148
00149
00150
00151
00152 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00153 recipe = (cpl_recipe *)plugin;
00154 else
00155 return -1;
00156
00157
00158
00159
00160
00161 recipe->parameters = cpl_parameterlist_new();
00162
00163 return 0;
00164 }
00165
00166
00175 static int fors_subtract_sky_lss_exec(cpl_plugin *plugin)
00176 {
00177 cpl_recipe *recipe;
00178
00179 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00180 recipe = (cpl_recipe *)plugin;
00181 else
00182 return -1;
00183
00184 return fors_subtract_sky_lss(recipe->parameters, recipe->frames);
00185 }
00186
00187
00196 static int fors_subtract_sky_lss_destroy(cpl_plugin *plugin)
00197 {
00198 cpl_recipe *recipe;
00199
00200 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00201 recipe = (cpl_recipe *)plugin;
00202 else
00203 return -1;
00204
00205 cpl_parameterlist_delete(recipe->parameters);
00206
00207 return 0;
00208 }
00209
00210
00220 static int fors_subtract_sky_lss(cpl_parameterlist *parlist,
00221 cpl_frameset *frameset)
00222 {
00223
00224 const char *recipe = "fors_subtract_sky_lss";
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 cpl_image *spectra = NULL;
00236 cpl_image *skymap = NULL;
00237 cpl_image *sky = NULL;
00238 cpl_table *maskslits = NULL;
00239
00240 cpl_propertylist *header = NULL;
00241
00242
00243
00244
00245
00246 char version[80];
00247 char *instrume = NULL;
00248 const char *mapped_science_tag;
00249 const char *mapped_science_sky_tag;
00250 const char *mapped_sky_tag;
00251 int mxu, mos, lss;
00252 int treat_as_lss = 0;
00253 int nscience;
00254 double mxpos;
00255 int nx, ny;
00256 int standard;
00257 float *data;
00258 float *sdata;
00259 int i, j;
00260
00261
00262 snprintf(version, 80, "%s-%s", PACKAGE, PACKAGE_VERSION);
00263
00264 cpl_msg_set_indentation(2);
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 cpl_msg_indent_less();
00276 cpl_msg_info(recipe, "Check input set-of-frames:");
00277 cpl_msg_indent_more();
00278
00279 mxu = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_MXU");
00280 mos = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_MOS");
00281 lss = cpl_frameset_count_tags(frameset, "MAPPED_ALL_SCI_LSS");
00282 standard = 0;
00283
00284 if (mxu + mos + lss == 0) {
00285 mxu = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_MXU");
00286 mos = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_MOS");
00287 lss = cpl_frameset_count_tags(frameset, "MAPPED_ALL_STD_LSS");
00288 standard = 1;
00289 }
00290
00291 if (mxu + mos + lss == 0)
00292 fors_subtract_sky_lss_exit("Missing input scientific frame");
00293
00294 nscience = mxu + mos + lss;
00295
00296 if (nscience > 1)
00297 fors_subtract_sky_lss_exit("More than one scientific frame in input");
00298
00299 if (mxu) {
00300 if (standard) {
00301 cpl_msg_info(recipe, "MXU data found");
00302 mapped_science_tag = "MAPPED_STD_MXU";
00303 mapped_science_sky_tag = "MAPPED_ALL_STD_MXU";
00304 mapped_sky_tag = "MAPPED_SKY_STD_MXU";
00305 }
00306 else {
00307 cpl_msg_info(recipe, "MXU data found");
00308 mapped_science_tag = "MAPPED_SCI_MXU";
00309 mapped_science_sky_tag = "MAPPED_ALL_SCI_MXU";
00310 mapped_sky_tag = "MAPPED_SKY_SCI_MXU";
00311 }
00312 }
00313
00314 if (lss) {
00315 if (standard) {
00316 cpl_msg_info(recipe, "LSS data found");
00317 mapped_science_tag = "MAPPED_STD_LSS";
00318 mapped_science_sky_tag = "MAPPED_ALL_STD_LSS";
00319 mapped_sky_tag = "MAPPED_SKY_STD_LSS";
00320 }
00321 else {
00322 cpl_msg_info(recipe, "LSS data found");
00323 mapped_science_tag = "MAPPED_SCI_LSS";
00324 mapped_science_sky_tag = "MAPPED_ALL_SCI_LSS";
00325 mapped_sky_tag = "MAPPED_SKY_SCI_LSS";
00326 }
00327 }
00328
00329 if (mos) {
00330 if (standard) {
00331 cpl_msg_info(recipe, "MOS data found");
00332 mapped_science_tag = "MAPPED_STD_MOS";
00333 mapped_science_sky_tag = "MAPPED_ALL_STD_MOS";
00334 mapped_sky_tag = "MAPPED_SKY_STD_MOS";
00335 }
00336 else {
00337 cpl_msg_info(recipe, "MOS data found");
00338 mapped_science_tag = "MAPPED_SCI_MOS";
00339 mapped_science_sky_tag = "MAPPED_ALL_SCI_MOS";
00340 mapped_sky_tag = "MAPPED_SKY_SCI_MOS";
00341 }
00342 }
00343
00344
00345
00346
00347
00348 cpl_msg_info(recipe, "Load mapped scientific exposure...");
00349 cpl_msg_indent_more();
00350
00351 spectra = dfs_load_image(frameset, mapped_science_sky_tag,
00352 CPL_TYPE_FLOAT, 0, 0);
00353
00354 if (spectra == NULL)
00355 fors_subtract_sky_lss_exit("Cannot load input frame");
00356
00357 header = dfs_load_header(frameset, mapped_science_sky_tag, 0);
00358
00359 if (header == NULL)
00360 fors_subtract_sky_lss_exit("Cannot load input frame header");
00361
00362 instrume = (char *)cpl_propertylist_get_string(header, "INSTRUME");
00363 if (instrume == NULL)
00364 fors_subtract_sky_lss_exit("Missing keyword INSTRUME in scientific header");
00365 instrume = cpl_strdup(instrume);
00366
00367 if (instrume[4] == '1')
00368 snprintf(version, 80, "%s/%s", "fors1", VERSION);
00369 if (instrume[4] == '2')
00370 snprintf(version, 80, "%s/%s", "fors2", VERSION);
00371
00372 cpl_free(instrume); instrume = NULL;
00373
00374 cpl_msg_indent_less();
00375
00376 if (mos || mxu) {
00377 int nslits_out_det = 0;
00378
00379 if (mos)
00380 maskslits = mos_load_slits_fors_mos(header, &nslits_out_det);
00381 else
00382 maskslits = mos_load_slits_fors_mxu(header);
00383
00384
00385
00386
00387
00388
00389 treat_as_lss = fors_mos_is_lss_like(maskslits, nslits_out_det);
00390
00391 cpl_table_delete(maskslits); maskslits = NULL;
00392
00393 if (treat_as_lss)
00394 cpl_msg_info(recipe, "All MOS slits have the same offset: %.2f\n"
00395 "The LSS data reduction strategy is applied.",
00396 mxpos);
00397 else
00398 fors_subtract_sky_lss_exit("This recipe can only be used "
00399 "with LSS-like data");
00400 }
00401
00402 nx = cpl_image_get_size_x(spectra);
00403 ny = cpl_image_get_size_y(spectra);
00404
00405 skymap = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00406 sky = cpl_image_collapse_median_create(spectra, 0, 0, 1);
00407
00408 data = cpl_image_get_data(skymap);
00409
00410 for (i = 0; i < ny; i++) {
00411 sdata = cpl_image_get_data(sky);
00412 for (j = 0; j < nx; j++) {
00413 *data++ = *sdata++;
00414 }
00415 }
00416
00417 cpl_image_delete(sky); sky = NULL;
00418 cpl_image_subtract(spectra, skymap);
00419
00420 if (dfs_save_image(frameset, skymap, mapped_sky_tag, header,
00421 parlist, recipe, version))
00422 fors_subtract_sky_lss_exit(NULL);
00423
00424 cpl_image_delete(skymap); skymap = NULL;
00425
00426 if (dfs_save_image(frameset, spectra, mapped_science_tag, header,
00427 parlist, recipe, version))
00428 fors_subtract_sky_lss_exit(NULL);
00429
00430 cpl_image_delete(spectra); spectra = NULL;
00431
00432 cpl_propertylist_delete(header); header = NULL;
00433
00434 if (cpl_error_get_code()) {
00435 cpl_msg_error(cpl_error_get_where(), "%s", cpl_error_get_message());
00436 fors_subtract_sky_lss_exit(NULL);
00437 }
00438 else
00439 return 0;
00440 }