34#include "kmos_pfits.h"
37#include "kmo_constants.h"
39#include "kmos_oscan.h"
45static char * kmos_get_root_name(
const char * filename) ;
46static int kmos_level_correct_create(cpl_plugin *);
47static int kmos_level_correct_exec(cpl_plugin *);
48static int kmos_level_correct_destroy(cpl_plugin *);
49static int kmos_level_correct(cpl_parameterlist *, cpl_frameset *);
55static char kmos_level_correct_description[] =
56"This recipe applies the level correction to the input frames.\n"
58"---------------------------------------------------------------------------\n"
60" DO CATG Type Explanation Required #Frames\n"
61" ------- ----- ----------- -------- -------\n"
62" SCIENCE RAW Science frames Y 1-n \n"
63" LCAL F2D Wavelength calib. frame N 0,1 \n"
64" BADPIXEL_DARK B2D Bad pixels frame N 0,1 \n"
67" DO CATG Type Explanation\n"
68" ------- ----- -----------\n"
69" LEVEL_CORRECTED F2D Level corrected frame\n"
70"---------------------------------------------------------------------------"
97 cpl_recipe *recipe = cpl_calloc(1,
sizeof *recipe);
98 cpl_plugin *plugin = &recipe->interface;
100 cpl_plugin_init(plugin,
103 CPL_PLUGIN_TYPE_RECIPE,
104 "kmos_level_correct",
105 "Create level corrected frames",
106 kmos_level_correct_description,
108 "https://support.eso.org/",
110 kmos_level_correct_create,
111 kmos_level_correct_exec,
112 kmos_level_correct_destroy);
114 cpl_pluginlist_append(list, plugin);
128static int kmos_level_correct_create(cpl_plugin *plugin)
134 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
135 recipe = (cpl_recipe *)plugin;
140 recipe->parameters = cpl_parameterlist_new();
145 p = cpl_parameter_new_value(
"kmos.kmos_level_correct.lcmethod",
147 "Method to use for the level correction "
148 "[\"OSCAN\" (overscan), "
149 "\"SLICES_MEAN\" (intra slices with average), "
150 "\"SLICES_MEDIAN\" (intra slices with median)]",
151 "kmos.kmos_level_correct",
"OSCAN");
152 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"lcmethod");
153 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
154 cpl_parameterlist_append(recipe->parameters, p);
166static int kmos_level_correct_exec(cpl_plugin *plugin)
171 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
172 recipe = (cpl_recipe *)plugin;
175 return kmos_level_correct(recipe->parameters, recipe->frames);
185static int kmos_level_correct_destroy(cpl_plugin *plugin)
190 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
191 recipe = (cpl_recipe *)plugin;
194 cpl_parameterlist_delete(recipe->parameters);
209static int kmos_level_correct(
210 cpl_parameterlist * parlist,
211 cpl_frameset * frameset)
213 const cpl_parameter * par ;
214 const char * lcmethod ;
216 const cpl_frame * rawframe ;
217 cpl_frame * bpm_frame ;
218 cpl_frame * lcal_frame ;
222 char * level_out_fn ;
225 cpl_image * lcal_im ;
226 cpl_image * ima_corr ;
227 cpl_image * level_out ;
229 cpl_propertylist * mh_plist ;
230 cpl_propertylist * plist ;
231 double rotangle_found, rotangle ;
234 bpm_frame = lcal_frame = NULL ;
237 if (kmos_check_and_set_groups(frameset) != CPL_ERROR_NONE) {
238 return cpl_error_get_code();
242 par = cpl_parameterlist_find_const(parlist,
243 "kmos.kmos_level_correct.lcmethod");
244 lcmethod = cpl_parameter_get_string(par) ;
246 if (strcmp(lcmethod,
"OSCAN") && strcmp(lcmethod,
"SLICES_MEAN") &&
247 strcmp(lcmethod,
"SLICES_MEDIAN")) {
248 cpl_msg_error(__func__,
249 "lcmethod must be 'OSCAN', 'SLICES_MEAN' or 'SLICES_MEDIAN'") ;
250 cpl_error_set(__func__, CPL_ERROR_ILLEGAL_INPUT) ;
255 bpm_frame = kmo_dfs_get_frame(frameset, BADPIXEL_DARK) ;
256 lcal_frame = kmo_dfs_get_frame(frameset, LCAL) ;
259 rawframe = kmo_dfs_get_frame(frameset, SCIENCE);
260 while (rawframe != NULL) {
262 in_fn = cpl_frame_get_filename(rawframe) ;
263 out_fn = cpl_sprintf(
"%s_LC.fits",
264 kmos_get_root_name(kmos_get_base_name(in_fn))) ;
265 bpm_out_fn = cpl_sprintf(
"%s_BPM.fits",
266 kmos_get_root_name(kmos_get_base_name(in_fn))) ;
267 level_out_fn = cpl_sprintf(
"%s_LEVEL.fits",
268 kmos_get_root_name(kmos_get_base_name(in_fn))) ;
271 mh_plist = cpl_propertylist_load(in_fn, 0) ;
274 cpl_propertylist_update_string(mh_plist, CPL_DFS_PRO_CATG,
276 cpl_dfs_save_propertylist(frameset, NULL, parlist, frameset,
277 rawframe, cpl_func, mh_plist, NULL, VERSION, bpm_out_fn);
279 cpl_propertylist_update_string(mh_plist, CPL_DFS_PRO_CATG,
281 cpl_dfs_save_propertylist(frameset, NULL, parlist, frameset,
282 rawframe, cpl_func, mh_plist, NULL, VERSION, level_out_fn);
284 cpl_propertylist_update_string(mh_plist, CPL_DFS_PRO_CATG,
286 cpl_dfs_save_propertylist(frameset, NULL, parlist, frameset,
287 rawframe, cpl_func, mh_plist, NULL, VERSION, out_fn);
290 for (i = 1; i <= KMOS_NR_DETECTORS ; i++) {
291 cpl_msg_info(cpl_func,
"Processing det %d of file %s", i, in_fn) ;
294 img_in = cpl_image_load(in_fn, CPL_TYPE_FLOAT, 0, i) ;
297 plist = cpl_propertylist_load(in_fn, i) ;
301 if (bpm_frame != NULL) {
302 bpm_im = cpl_image_load(cpl_frame_get_filename(bpm_frame),
303 CPL_TYPE_INT, 0, i) ;
306 if (lcal_frame != NULL) {
307 rotangle = kmo_dfs_get_property_double(mh_plist, ROTANGLE);
308 lcal_im = kmo_dfs_load_cal_image_frame(lcal_frame, i, 0,
309 rotangle, FALSE, NULL, &rotangle_found, -1, 0, 0) ;
316 if (!strcmp(lcmethod,
"OSCAN")) {
317 cpl_msg_info(__func__,
"Apply Overscan correction") ;
318 ima_corr = kmos_oscan_correct(img_in) ;
319 }
else if (!strcmp(lcmethod,
"SLICES_MEAN")) {
320 cpl_msg_info(__func__,
"Apply Intra Slices correction (mean)") ;
321 ima_corr = kmos_intraslices_correct(img_in, bpm_im,
322 lcal_im, 1, &bpm_out, &level_out);
323 }
else if (!strcmp(lcmethod,
"SLICES_MEDIAN")) {
324 cpl_msg_info(__func__,
"Apply Intra Slices correction (median)");
325 ima_corr = kmos_intraslices_correct(img_in, bpm_im,
326 lcal_im, 2, &bpm_out, &level_out);
328 cpl_image_delete(img_in) ;
329 if (lcal_im != NULL) cpl_image_delete(lcal_im) ;
330 if (bpm_im != NULL) cpl_image_delete(bpm_im) ;
333 if (level_out == NULL) {
334 cpl_propertylist_save(plist, level_out_fn, CPL_IO_EXTEND);
336 cpl_image_save(level_out, level_out_fn, CPL_TYPE_DOUBLE, plist,
338 cpl_image_delete(level_out) ;
342 if (bpm_out == NULL) {
343 cpl_propertylist_save(plist, bpm_out_fn, CPL_IO_EXTEND);
345 cpl_mask_save(bpm_out, bpm_out_fn, plist, CPL_IO_EXTEND);
346 cpl_mask_delete(bpm_out) ;
350 if (ima_corr == NULL) {
351 cpl_propertylist_save(plist, out_fn, CPL_IO_EXTEND);
353 cpl_image_save(ima_corr, out_fn, CPL_TYPE_FLOAT, plist,
355 cpl_image_delete(ima_corr) ;
357 cpl_propertylist_delete(plist) ;
359 cpl_propertylist_delete(mh_plist) ;
361 cpl_free(bpm_out_fn) ;
362 cpl_free(level_out_fn) ;
365 rawframe = kmo_dfs_get_frame(frameset, NULL);
369 return CPL_ERROR_NONE;
381static char * kmos_get_root_name(
const char * filename)
383 static char path[4096+1];
385 if (filename == NULL)
return NULL;
387 if (strlen(filename)>4096)
return NULL ;
388 memset(path, 0, 4096);
389 strcpy(path, filename);
390 lastdot = strrchr(path,
'.');
391 if (lastdot == NULL)
return path ;
392 if ((!strcmp(lastdot,
".fits")) || (!strcmp(lastdot,
".FITS")) ||
393 (!strcmp(lastdot,
".dat")) || (!strcmp(lastdot,
".DAT")) ||
394 (!strcmp(lastdot,
".paf")) || (!strcmp(lastdot,
".PAF")) ||
395 (!strcmp(lastdot,
".txt")) || (!strcmp(lastdot,
".TXT")) ||
396 (!strcmp(lastdot,
".ascii")) || (!strcmp(lastdot,
".ASCII")))
398 lastdot[0] = (char)0;
int cpl_plugin_get_info(cpl_pluginlist *list)
Build the list of available plugins, for this module.