KMOS Pipeline Reference Manual 4.5.10
kmo_noise_map.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#include <string.h>
25
26#include <cpl.h>
27
28#include "kmo_utils.h"
29#include "kmo_dfs.h"
30#include "kmo_error.h"
31#include "kmo_priv_noise_map.h"
32#include "kmo_constants.h"
33#include "kmo_debug.h"
34
35static int kmo_noise_map_create(cpl_plugin *);
36static int kmo_noise_map_exec(cpl_plugin *);
37static int kmo_noise_map_destroy(cpl_plugin *);
38static int kmo_noise_map(cpl_parameterlist *, cpl_frameset *);
39
40static char kmo_noise_map_description[] =
41"The noise in each pixel of the input data is estimated using gain and readnoise.\n"
42"The readnoise is expected to be in the primary header (ESO DET CHIP RON), the\n"
43"gain (ESO DET CHIP GAIN) has to be in each of the subsequent headers of each \n"
44"detector frame. The output is the initial noise map of the data frame.\n"
45"\n"
46"-------------------------------------------------------------------------------\n"
47" Input files:\n"
48"\n"
49" DO KMOS \n"
50" category Type Explanation Required #Frames\n"
51" -------- ----- ----------- -------- -------\n"
52" <none or any> RAW raw data frame Y 1 \n"
53"\n"
54" Output files:\n"
55"\n"
56" DO KMOS\n"
57" category Type Explanation\n"
58" -------- ----- -----------\n"
59" NOISE_MAP F2D Initial noise map\n"
60" (6 Extensions, 3 data and 3 noise)\n"
61"-------------------------------------------------------------------------------\n"
62"\n";
63
80int cpl_plugin_get_info(cpl_pluginlist *list)
81{
82 cpl_recipe *recipe = cpl_calloc(1, sizeof *recipe);
83 cpl_plugin *plugin = &recipe->interface;
84
85 cpl_plugin_init(plugin,
86 CPL_PLUGIN_API,
87 KMOS_BINARY_VERSION,
88 CPL_PLUGIN_TYPE_RECIPE,
89 "kmo_noise_map",
90 "Generate a noise map from a raw frame",
91 kmo_noise_map_description,
92 "Alex Agudo Berbel",
93 "https://support.eso.org/",
94 kmos_get_license(),
95 kmo_noise_map_create,
96 kmo_noise_map_exec,
97 kmo_noise_map_destroy);
98
99 cpl_pluginlist_append(list, plugin);
100
101 return 0;
102}
103
111static int kmo_noise_map_create(cpl_plugin *plugin)
112{
113 cpl_recipe *recipe;
114
115 /* Check that the plugin is part of a valid recipe */
116 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
117 recipe = (cpl_recipe *)plugin;
118 else
119 return -1;
120
121 /* Create the parameters list in the cpl_recipe object */
122 recipe->parameters = cpl_parameterlist_new();
123
124 return 0;
125}
126
132static int kmo_noise_map_exec(cpl_plugin *plugin)
133{
134 cpl_recipe *recipe;
135
136 /* Get the recipe out of the plugin */
137 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
138 recipe = (cpl_recipe *)plugin;
139 else return -1 ;
140
141 return kmo_noise_map(recipe->parameters, recipe->frames);
142}
143
149static int kmo_noise_map_destroy(cpl_plugin *plugin)
150{
151 cpl_recipe *recipe;
152
153 /* Get the recipe out of the plugin */
154 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
155 recipe = (cpl_recipe *)plugin;
156 else return -1 ;
157
158 cpl_parameterlist_delete(recipe->parameters);
159 return 0 ;
160}
161
180static int kmo_noise_map(cpl_parameterlist *parlist, cpl_frameset *frameset)
181{
182 int i = 0,
183 ret_val = 0,
184 ndsamples = 0;
185 cpl_propertylist *sub_header = NULL,
186 *main_header = NULL;
187 cpl_image *img = NULL,
188 *noise_img = NULL;
189 double gain = 0.0,
190 readnoise = 0.0;
191 main_fits_desc desc;
192 cpl_frame *frame = NULL;
193 const char *readmode = NULL;
194
195 KMO_TRY
196 {
197 kmo_init_fits_desc(&desc);
198
199 /* --- check input --- */
200 KMO_TRY_ASSURE((parlist != NULL) &&
201 (frameset != NULL),
202 CPL_ERROR_NULL_INPUT,
203 "Not all input data is provided!");
204
205 KMO_TRY_ASSURE(cpl_frameset_get_size(frameset) == 1,
206 CPL_ERROR_NULL_INPUT,
207 "A fits-file must be provided!");
208
209 KMO_TRY_EXIT_IF_NULL(
210 frame = kmo_dfs_get_frame(frameset, "0"));
211
212 desc = kmo_identify_fits_header(
213 cpl_frame_get_filename(frame));
214 KMO_TRY_CHECK_ERROR_STATE_MSG("Provided fits file doesn't seem to be "
215 "in KMOS-format!");
216
217 KMO_TRY_ASSURE((desc.fits_type == raw_fits),
218 CPL_ERROR_ILLEGAL_INPUT,
219 "Input data hasn't correct data type "
220 "(KMOSTYPE must be RAW)!");
221
222 KMO_TRY_ASSURE(kmo_dfs_set_groups(frameset) == 1,
223 CPL_ERROR_ILLEGAL_INPUT,
224 "Cannot identify RAW and CALIB frames!");
225
226 cpl_msg_info("", "--- Parameter setup for kmo_noise_map ----");
227
228 cpl_msg_info("", "No parameters to set.");
229 cpl_msg_info("", "-------------------------------------------");
230
231 /* --- save primary extension --- */
232 KMO_TRY_EXIT_IF_ERROR(
233 kmo_dfs_save_main_header(frameset, NOISE_MAP, "", frame,
234 NULL, parlist, cpl_func));
235
236 /* --- load each data-frame, save it, calculate noise,
237 save it as well --- */
238 for (i = 0; i < desc.nr_ext; i++)
239 {
240 /* load data and save it away again */
241 KMO_TRY_EXIT_IF_NULL(
242 sub_header = kmo_dfs_load_sub_header(frameset, "0", i + 1,
243 FALSE));
244
245 KMO_TRY_EXIT_IF_NULL(
246 img = kmo_dfs_load_image(frameset, "0", i + 1, FALSE, TRUE, NULL));
247
248 KMO_TRY_EXIT_IF_ERROR(
249 kmo_update_sub_keywords(sub_header,
250 FALSE,
251 FALSE,
252 desc.frame_type,
253 desc.sub_desc[i].device_nr));
254
255 KMO_TRY_EXIT_IF_ERROR(
256 kmo_dfs_save_image(img, NOISE_MAP, "", sub_header, 0./0.));
257
258 /* calculate initial noise estimate */
259 KMO_TRY_EXIT_IF_NULL(
260 main_header = kmo_dfs_load_primary_header(frameset, "0"));
261
262 readmode = cpl_propertylist_get_string(main_header, READMODE);
263 KMO_TRY_CHECK_ERROR_STATE("ESO DET READ CURNAME keyword in main "
264 "header missing!");
265 gain = kmo_dfs_get_property_double(sub_header, GAIN);
266 KMO_TRY_CHECK_ERROR_STATE_MSG(
267 "GAIN-keyword in fits-header is missing!");
268
269 if (strcmp(readmode, "Nondest") == 0) {
270 // NDR: non-destructive readout mode
271 ndsamples = cpl_propertylist_get_int(main_header, NDSAMPLES);
272 KMO_TRY_CHECK_ERROR_STATE("ESO DET READ NDSAMPLES keyword in main "
273 "header missing!");
274
275 readnoise = kmo_calc_readnoise_ndr(ndsamples);
276 KMO_TRY_CHECK_ERROR_STATE();
277 } else {
278 // normal readout mode
279 readnoise = kmo_dfs_get_property_double(sub_header, RON);
280 KMO_TRY_CHECK_ERROR_STATE_MSG(
281 "READNOISE-keyword in fits-header is missing!");
282
283 }
284 KMO_TRY_EXIT_IF_NULL(
285 noise_img = kmo_calc_noise_map(img, gain, readnoise));
286
287 cpl_propertylist_delete(main_header); main_header = NULL;
288
289 /* save noise */
290 KMO_TRY_EXIT_IF_ERROR(
291 kmo_update_sub_keywords(sub_header,
292 TRUE,
293 FALSE,
294 desc.frame_type,
295 desc.sub_desc[i].device_nr));
296
297 KMO_TRY_EXIT_IF_ERROR(
298 kmo_dfs_save_image(noise_img, NOISE_MAP, "", sub_header, 0./0.));
299
300 cpl_propertylist_delete(sub_header); sub_header = NULL;
301 cpl_image_delete(img); img = NULL;
302 cpl_image_delete(noise_img); noise_img= NULL;
303 }
304 }
305 KMO_CATCH
306 {
307 KMO_CATCH_MSG();
308
309 ret_val = -1;
310 }
311
312 cpl_propertylist_delete(sub_header); sub_header = NULL;
313 cpl_image_delete(img); img = NULL;
314 cpl_image_delete(noise_img); noise_img = NULL;
315 kmo_free_fits_desc(&desc);
316 return ret_val;
317}
318
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.
Definition: kmo_noise_map.c:80