KMOS Pipeline Reference Manual 4.5.10
kmos_sky_tweak.c
1/*
2 * This file is part of the KMOS Pipeline
3 * Copyright (C) 2002,2003 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24/*-----------------------------------------------------------------------------
25 * Includes
26 *----------------------------------------------------------------------------*/
27
28#include <stdio.h>
29#include <string.h>
30
31#include <cpl.h>
32#include <cpl_wcs.h>
33
34#include "kmo_dfs.h"
35#include "kmo_error.h"
36#include "kmo_constants.h"
37#include "kmos_priv_sky_tweak.h"
38
39/*-----------------------------------------------------------------------------
40 * Functions prototypes
41 *----------------------------------------------------------------------------*/
42
43static int kmos_sky_tweak_create(cpl_plugin *);
44static int kmos_sky_tweak_exec(cpl_plugin *);
45static int kmos_sky_tweak_destroy(cpl_plugin *);
46static int kmos_sky_tweak(cpl_parameterlist *, cpl_frameset *);
47
48/*-----------------------------------------------------------------------------
49 * Static variables
50 *----------------------------------------------------------------------------*/
51
52static char kmos_sky_tweak_description[] =
53" This recipes is an advanced tool to remove OH sky lines.\n"
54"\n"
55"BASIC PARAMETERS:\n"
56"-----------------\n"
57"--tbsub\n"
58"If set to TRUE subtract the thermal background from the input cube.\n"
59"Default value is TRUE.\n"
60"\n"
61"---------------------------------------------------------------------------\n"
62" Input files:\n"
63" DO CATG Type Explanation Required #Frames\n"
64" -------- ----- ----------- -------- -------\n"
65" CUBE_OBJECT F3I object cubes Y >=1 \n"
66" CUBE_SKY F3I sky cube Y 1 \n"
67"\n"
68" Output files:\n"
69" DO_CATG Type Explanation\n"
70" -------- ----- -----------\n"
71" OBJECT_S F3I Corrected object cubes\n"
72"---------------------------------------------------------------------------\n"
73"\n";
74
75/*----------------------------------------------------------------------------*/
79/*----------------------------------------------------------------------------*/
80
83/*-----------------------------------------------------------------------------
84 * Functions code
85 *----------------------------------------------------------------------------*/
86
87/*----------------------------------------------------------------------------*/
96/*----------------------------------------------------------------------------*/
97int cpl_plugin_get_info(cpl_pluginlist *list)
98{
99 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
100 cpl_plugin *plugin = &recipe->interface;
101
102 cpl_plugin_init(plugin,
103 CPL_PLUGIN_API,
104 KMOS_BINARY_VERSION,
105 CPL_PLUGIN_TYPE_RECIPE,
106 "kmos_sky_tweak",
107 "Removal of OH sky lines",
108 kmos_sky_tweak_description,
109 "Erich Wiezorrek, Yves Jung",
110 "https://support.eso.org/",
111 kmos_get_license(),
112 kmos_sky_tweak_create,
113 kmos_sky_tweak_exec,
114 kmos_sky_tweak_destroy);
115 cpl_pluginlist_append(list, plugin);
116 return 0;
117}
118
119/*----------------------------------------------------------------------------*/
127/*----------------------------------------------------------------------------*/
128static int kmos_sky_tweak_create(cpl_plugin *plugin)
129{
130 cpl_recipe *recipe;
131 cpl_parameter *p;
132
133 /* Check that the plugin is part of a valid recipe */
134 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
135 recipe = (cpl_recipe *)plugin;
136 else
137 return -1;
138
139 /* Create the parameters list in the cpl_recipe object */
140 recipe->parameters = cpl_parameterlist_new();
141
142 /* Fill the parameters list */
143
144 /* --ifu */
145 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.ifu",
146 CPL_TYPE_INT, "Only reduce the specified IFU",
147 "kmos.kmos_sky_tweak", 0);
148 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "ifu");
149 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
150 cpl_parameterlist_append(recipe->parameters, p);
151
152 /* --discard_subband */
153 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.discard_subband",
154 CPL_TYPE_BOOL, "Ignore last sub-band in the sky tweaking",
155 "kmos.kmos_sky_tweak", FALSE);
156 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "discard_subband");
157 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
158 cpl_parameterlist_append(recipe->parameters, p);
159
160 /* --stretch_sky */
161 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.stretch_sky",
162 CPL_TYPE_BOOL, "Stretch sky", "kmos.kmos_sky_tweak", FALSE);
163 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "stretch");
164 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
165 cpl_parameterlist_append(recipe->parameters, p);
166
167 /* --stretch_degree */
168 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.stretch_degree",
169 CPL_TYPE_INT, "Stretch polynomial degree", "kmos.kmos_sky_tweak",
170 8);
171 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "stretch_degree");
172 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
173 cpl_parameterlist_append(recipe->parameters, p);
174
175 /* --stretch_resampling */
176 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.stretch_resampling",
177 CPL_TYPE_STRING, "Stretch resampling method (linear/spline)",
178 "kmos.kmos_sky_tweak", "spline");
179 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "stretch_resampling");
180 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
181 cpl_parameterlist_append(recipe->parameters, p);
182
183 /* --plot */
184 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.plot",
185 CPL_TYPE_INT, "Enable plotting", "kmos.kmos_sky_tweak", 0);
186 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "plot");
187 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
188 cpl_parameterlist_append(recipe->parameters, p);
189
190 /* --tbsub */
191 p = cpl_parameter_new_value("kmos.kmos_sky_tweak.tbsub", CPL_TYPE_BOOL,
192 "Subtract thermal background from input cube",
193 "kmos.kmos_sky_tweak", TRUE);
194 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "tbsub");
195 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
196 cpl_parameterlist_append(recipe->parameters, p);
197 return 0;
198}
199
200/*----------------------------------------------------------------------------*/
206/*----------------------------------------------------------------------------*/
207static int kmos_sky_tweak_exec(cpl_plugin *plugin)
208{
209 cpl_recipe *recipe;
210
211 /* Get the recipe out of the plugin */
212 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
213 recipe = (cpl_recipe *)plugin;
214 else return -1 ;
215
216 return kmos_sky_tweak(recipe->parameters, recipe->frames);
217}
218
219/*----------------------------------------------------------------------------*/
225/*----------------------------------------------------------------------------*/
226static int kmos_sky_tweak_destroy(cpl_plugin *plugin)
227{
228 cpl_recipe *recipe;
229
230 /* Get the recipe out of the plugin */
231 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
232 recipe = (cpl_recipe *)plugin;
233 else return -1 ;
234
235 cpl_parameterlist_delete(recipe->parameters);
236 return 0 ;
237}
238
239/*----------------------------------------------------------------------------*/
252/*----------------------------------------------------------------------------*/
253static int kmos_sky_tweak(
254 cpl_parameterlist * parlist,
255 cpl_frameset * frameset)
256{
257 const cpl_parameter * par ;
258 int ox, nr_object_frames, nr_obj_devices,
259 nr_sky_devices, ifu_nr, sky_index,
260 obj_index, tbsub, reduce_ifu, discard_subband,
261 stretch, stretch_degree, stretch_resampling, plot ;
262 const char * sval ;
263 const char * obj_fn ;
264 const char * sky_fn ;
265 cpl_frame ** object_frames ;
266 cpl_frame * object_frame ;
267 cpl_frame * sky_frame ;
268 cpl_imagelist * obj_data ;
269 cpl_imagelist * sky_data ;
270 cpl_imagelist * new_sky ;
271 cpl_imagelist * result ;
272 cpl_propertylist * main_header ;
273 cpl_propertylist * sub_header ;
274 main_fits_desc obj_fits_desc,
275 sky_fits_desc;
276
277 /* Check entries */
278 if (parlist == NULL || frameset == NULL) {
279 cpl_msg_error(__func__, "Null Inputs") ;
280 cpl_error_set(__func__, CPL_ERROR_NULL_INPUT) ;
281 return -1 ;
282 }
283 if (cpl_frameset_count_tags(frameset, CUBE_OBJECT) == 0 ||
284 cpl_frameset_count_tags(frameset, CUBE_SKY) == 0) {
285 cpl_msg_error(__func__, "Missing Inputs") ;
286 cpl_error_set(__func__, CPL_ERROR_FILE_NOT_FOUND) ;
287 return -1 ;
288 }
289 if (cpl_frameset_count_tags(frameset, CUBE_SKY) != 1) {
290 cpl_msg_error(__func__, "one CUBE_SKY is expected") ;
291 cpl_error_set(__func__, CPL_ERROR_FILE_NOT_FOUND) ;
292 return -1 ;
293 }
294
295 /* Initialise */
296 nr_obj_devices = nr_sky_devices = sky_index = obj_index = 0 ;
297
298 /* Identify the RAW and CALIB frames in the input frameset */
299 if (kmo_dfs_set_groups(frameset) != 1) {
300 cpl_msg_error(__func__, "Cannot identify RAW and CALIB frames") ;
301 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
302 return -1 ;
303 }
304
305 /* Get Parameters */
306 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sky_tweak.tbsub");
307 tbsub = cpl_parameter_get_bool(par);
308 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sky_tweak.ifu");
309 reduce_ifu = cpl_parameter_get_int(par);
310 par = cpl_parameterlist_find_const(parlist,
311 "kmos.kmos_sky_tweak.discard_subband");
312 discard_subband = cpl_parameter_get_bool(par);
313 par=cpl_parameterlist_find_const(parlist,"kmos.kmos_sky_tweak.stretch_sky");
314 stretch = cpl_parameter_get_bool(par);
315 par=cpl_parameterlist_find_const(parlist,
316 "kmos.kmos_sky_tweak.stretch_degree");
317 stretch_degree = cpl_parameter_get_int(par);
318 par=cpl_parameterlist_find_const(parlist,
319 "kmos.kmos_sky_tweak.stretch_resampling");
320 sval = cpl_parameter_get_string(par);
321 if (!strcmp(sval, "linear")) {
322 stretch_resampling = 1 ;
323 } else if (!strcmp(sval, "spline")) {
324 stretch_resampling = 2 ;
325 } else {
326 stretch_resampling = -1 ;
327 }
328 par = cpl_parameterlist_find_const(parlist, "kmos.kmos_sky_tweak.plot");
329 plot = cpl_parameter_get_int(par);
330
331 /* Check Parameters */
332 if (stretch_resampling < 0) {
333 cpl_msg_warning(__func__,
334 "Invalid resampling method specified - use spline") ;
335 stretch_resampling = 2 ;
336 }
337
338 nr_object_frames = cpl_frameset_count_tags(frameset, CUBE_OBJECT);
339 object_frames = cpl_malloc(nr_object_frames * sizeof(cpl_frame*));
340
341 for (ox = 0; ox < nr_object_frames; ox++) {
342 if (ox == 0) {
343 object_frames[ox] = cpl_frameset_find(frameset, CUBE_OBJECT);
344 } else {
345 object_frames[ox] = cpl_frameset_find(frameset, NULL);
346 }
347 }
348
349 sky_frame = cpl_frameset_find(frameset, CUBE_SKY);
350 sky_fits_desc = kmo_identify_fits_header(cpl_frame_get_filename(sky_frame));
351 if (sky_fits_desc.ex_noise == TRUE) nr_sky_devices = sky_fits_desc.nr_ext/2;
352 else nr_sky_devices = sky_fits_desc.nr_ext;
353
354 sky_fn = cpl_frame_get_filename(sky_frame);
355
356 /* Look on the Object files */
357 for (ox = 0; ox < nr_object_frames; ox++) {
358 object_frame = object_frames[ox];
359 obj_fits_desc =
360 kmo_identify_fits_header(cpl_frame_get_filename(object_frame));
361 if (obj_fits_desc.ex_noise == TRUE)
362 nr_obj_devices = obj_fits_desc.nr_ext / 2;
363 else
364 nr_obj_devices = obj_fits_desc.nr_ext;
365 if (nr_sky_devices != nr_obj_devices && nr_sky_devices != 1) {
366 cpl_msg_error(__func__, "SKY frame ext nr must be 1 or match OBJ");
367 return -1 ;
368 }
369
370 obj_fn = cpl_frame_get_filename(object_frame);
371 main_header = kmclipm_propertylist_load(obj_fn, 0);
372
373 kmo_dfs_save_main_header(frameset, SKY_TWEAK, "", object_frame,
374 main_header, parlist, cpl_func);
375
376 /* Loop on the IFUs */
377 for (ifu_nr = 1; ifu_nr <= nr_obj_devices; ifu_nr++) {
378 /* Compute only one ifu */
379 if (reduce_ifu != 0 && reduce_ifu != ifu_nr) continue ;
380
381 cpl_msg_info(__func__, "Processing IFU#: %d", ifu_nr);
382 cpl_msg_indent_more() ;
383
384 /* Get sky index */
385 if (nr_sky_devices == nr_obj_devices) {
386 sky_index = kmo_identify_index(sky_fn, ifu_nr, FALSE);
387 } else {
388 sky_index = kmo_identify_index(sky_fn, 1, FALSE);
389 }
390
391 /* Get Object index */
392 obj_index = kmo_identify_index(obj_fn, ifu_nr, FALSE);
393
394 /* Load Object header */
395 sub_header = kmclipm_propertylist_load(obj_fn, obj_index);
396
397 /* Only reduce valid IFUs */
398 new_sky = result = NULL ;
399 if (obj_fits_desc.sub_desc[obj_index-1].valid_data &&
400 sky_fits_desc.sub_desc[sky_index-1].valid_data) {
401 /* Load sky and object */
402 sky_data = kmclipm_imagelist_load(sky_fn, CPL_TYPE_FLOAT,
403 sky_index);
404 obj_data=kmclipm_imagelist_load(obj_fn, CPL_TYPE_FLOAT,
405 obj_index);
406
407 /* Apply the sky tweaking */
408 result = kmos_priv_sky_tweak(obj_data, sky_data,
409 sub_header, .3, tbsub, discard_subband,
410 stretch, stretch_degree, stretch_resampling, plot,
411 &new_sky);
412 cpl_imagelist_delete(new_sky);
413 cpl_imagelist_delete(obj_data);
414 cpl_imagelist_delete(sky_data);
415 } else {
416 /* Empty IFU */
417 cpl_msg_warning(__func__, "Empty IFU - skip") ;
418 }
419
420 kmo_dfs_save_cube(result, SKY_TWEAK, "", sub_header, 0./0.);
421
422 cpl_propertylist_delete(sub_header);
423 cpl_imagelist_delete(result);
424 cpl_msg_indent_less() ;
425 }
426
427 kmo_free_fits_desc(&obj_fits_desc);
428 cpl_propertylist_delete(main_header);
429 }
430 kmo_free_fits_desc(&sky_fits_desc);
431 cpl_free(object_frames);
432 return 0;
433}
434
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.