39#include "casu_utils.h"
42#include "eris_nix_utils.h"
43#include "eris_nix_casu_utils.h"
44#include "eris_nix_dfs.h"
53static const char eris_nix_img_stack_description[] =
54"This recipe rebins a set of calibrated ERIS/NIX jitter frames to a\n"
55"common grid and stacks them.\n"
59" DO CATG Explanation Req. #Frames\n"
60" ------- ----------- --- -------\n"
61" "ERIS_NIX_CAL_PHOT_OBJECT_JITTER_PRO_CATG
62 " calibrated frames Y 1-n\n"
65" "ERIS_NIX_CAL_PHOT_STD_JITTER_PRO_CATG
66 " calibrated standard Y 1-n\n"
67" frames to be stacked.\n"
71" DO CATG Explanation \n"
72" ------- ----------- \n"
73" "ERIS_NIX_IMG_OBS_COMBINED_PRO_CATG
74 " the stacked image of the target.\n"
76" "ERIS_NIX_IMG_STD_COMBINED_PRO_CATG
77 " the stacked image of the standard.\n"
79" The output will be FITS files named 'stack.<first input filename>',\n"
80" containing extensions:\n"
81" - DATA, with the stacked target or standard data.\n"
82" - ERR, with the error plane.\n"
83" - DQ, with the stacked image quality\n"
84" - CONFIDENCE, with the target confidence plane.\n"
86" The output file can be split into smaller components, see\n"
87" param --split-output-file.\n"
89"Notes on the method.\n"
90" The stacking is done by a CASU routine, the relevant part\n"
91" of whose description is:\n"
92" 'A list of frames is given. A mean image is stacked by using the\n"
93" given WCS to work out the shift of an input pixel relative to the\n"
94" grid defined by the first image in the list. At first all are\n"
95" stacked using a nearest neighbour algorithm. Any discordant pixels\n"
96" are marked at this stage. If a different stacking algorithm is\n"
97" required, then the images are restacked, but with the discordant\n"
98" pixels found earlier removed.\n"
101#define RECIPE_NAME "eris.eris_nix_img_stack"
107cpl_recipe_define(eris_nix_img_stack, ERIS_BINARY_VERSION,
"John Lightfoot",
108 PACKAGE_BUGREPORT,
"2017",
109 "Stack calibrated ERIS/NIX jitter frames",
110 eris_nix_img_stack_description);
126static cpl_error_code eris_nix_img_stack_fill_parameterlist(
127 cpl_parameterlist * self) {
129 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
131 hdrl_parameter * catalogue_defaults = NULL;
132 cpl_parameterlist * catalogue_parlist = NULL;
133 cpl_parameter * p = NULL;
137 p = cpl_parameter_new_range(RECIPE_NAME
".stk_lthr", CPL_TYPE_DOUBLE,
138 "Low rejection threshold", RECIPE_NAME,
139 5.0, 1.0e-6, 1.0e10);
140 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stk-lthr");
141 cpl_parameterlist_append(self, p);
145 p = cpl_parameter_new_range(RECIPE_NAME
".stk_hthr", CPL_TYPE_DOUBLE,
146 "Upper rejection threshold", RECIPE_NAME,
147 5.0, 1.0e-6, 1.0e10);
148 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stk-hthr");
149 cpl_parameterlist_append(self, p);
153 p = cpl_parameter_new_enum(RECIPE_NAME
".stk_method", CPL_TYPE_STRING,
154 "The interpolation method", RECIPE_NAME,
155 "bi-linear", 2,
"nearest neighbour",
157 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stk-method");
158 cpl_parameterlist_append(self, p);
162 p = cpl_parameter_new_enum(RECIPE_NAME
".stk_fast", CPL_TYPE_STRING,
163 "Use fast stacking? The fast algorithm "
164 "uses much more memory", RECIPE_NAME,
165 "auto", 3,
"fast",
"slow",
"auto");
166 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stk-fast");
167 cpl_parameterlist_append(self, p);
171 p = cpl_parameter_new_value(RECIPE_NAME
".stk_nfst", CPL_TYPE_INT,
172 "nframes limit beyond which 'slow' "
173 "stacking is enforced", RECIPE_NAME, 30);
174 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"stk-nfst");
175 cpl_parameterlist_append(self, p);
180 cpl_parameterlist_delete(catalogue_parlist);
194static int eris_nix_img_stack(cpl_frameset * frameset,
195 const cpl_parameterlist * parlist) {
197 located_imagelist * cal_jitters = NULL;
198 located_imagelist * cal_object_jitters = NULL;
199 located_imagelist * cal_std_jitters = NULL;
200 hdrl_parameter * cat_params = NULL;
201 const char * funcid =
"eris_nix_img_stack";
202 mef_extension_list * mefs = NULL;
203 const cpl_parameter * p = NULL;
204 located_image * stack = NULL;
205 hdrl_image * stack_image = NULL;
206 cpl_frameset * used = NULL;
208 enu_check_error_code(
"%s():%d: An error is already set: %s",
209 cpl_func, __LINE__, cpl_error_get_where());
213 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
214 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
219 cpl_msg_set_level_from_env();
220 cpl_msg_severity severity = cpl_msg_get_level();
221 cpl_msg_info(funcid,
"level %d", (
int) severity);
225 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".stk_lthr");
226 const double stk_lthr = cpl_parameter_get_double(p);
227 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".stk_hthr");
228 const double stk_hthr = cpl_parameter_get_double(p);
229 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".stk_method");
230 const char * stk_method = cpl_parameter_get_string(p);
231 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".stk_fast");
232 const char * stk_fast_setting = cpl_parameter_get_string(p);
233 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".stk_nfst");
234 const int stk_nfst = cpl_parameter_get_int(p);
235 enu_check_error_code(
"Could not retrieve input parameters");
240 enu_check_error_code(
"Could not identify RAW and CALIB frames");
244 used = cpl_frameset_new();
246 ERIS_NIX_CAL_PHOT_OBJECT_JITTER_PRO_CATG, used);
247 cpl_msg_info(funcid,
"read %d %s frames", (
int) cal_object_jitters->size,
248 ERIS_NIX_CAL_PHOT_OBJECT_JITTER_PRO_CATG);
250 ERIS_NIX_CAL_PHOT_STD_JITTER_PRO_CATG, used);
251 cpl_msg_info(funcid,
"read %d %s frames", (
int) cal_std_jitters->size,
252 ERIS_NIX_CAL_PHOT_STD_JITTER_PRO_CATG);
256 enu_check(!(cal_object_jitters->size > 0 && cal_std_jitters->size > 0),
257 CPL_ERROR_ILLEGAL_INPUT,
258 "SoF cannot contain data for both target and standard");
259 enu_check(!(cal_object_jitters->size == 0 && cal_std_jitters->size == 0),
260 CPL_ERROR_DATA_NOT_FOUND,
261 "SoF contains no data");
262 if(cal_object_jitters->size > 0) {
263 cal_jitters = cal_object_jitters;
265 cal_jitters = cal_std_jitters;
271 if (!strcmp(stk_fast_setting,
"auto") && cal_jitters->size > stk_nfst) {
273 }
else if (!strcmp(stk_fast_setting,
"slow")) {
279 enu_stack(cal_jitters, stk_lthr, stk_hthr, stk_method, stk_fast,
281 enu_check_error_code(
"error set after image stacking");
285 char * proto = cpl_strdup(cpl_frame_get_filename((cal_jitters->limages[0])->
287 char * stack_fname = cpl_sprintf(
"stack.%s", basename(proto_copy));
291 cpl_frameset * provenance = cpl_frameset_new();
292 for (cpl_size j=0; j<cal_jitters->size; j++) {
293 cpl_frameset_insert(provenance, cpl_frame_duplicate(
294 cal_jitters->limages[j]->frame));
299 const char * out_tag = NULL;
300 if (cal_object_jitters->size >0) {
301 out_tag = ERIS_NIX_IMG_OBS_COMBINED_PRO_CATG;
303 out_tag = ERIS_NIX_IMG_STD_COMBINED_PRO_CATG;
305 cpl_propertylist_update_string(stack->plist, CPL_DFS_PRO_CATG, out_tag);
307 int ncombine = cal_jitters->size;
308 double total_exptime = 100.0;
309 double mjd_start = 10000.0;
310 double mjd_end = 11000.0;
311 cpl_vector * obsid = cpl_vector_new(cal_jitters->size);
312 for (cpl_size j=0; j < cal_jitters->size; j++) {
313 cpl_vector_set(obsid, j, (
double)j);
315 cpl_propertylist_update_int(stack->plist,
"NCOMBINE", ncombine);
316 cpl_propertylist_update_double(stack->plist,
"TEXPTIME", total_exptime);
317 cpl_propertylist_update_double(stack->plist,
"MJD-OBS", mjd_start);
318 cpl_propertylist_update_double(stack->plist,
"MJD-END", mjd_end);
319 for (cpl_size j = 0; j < cal_jitters->size; ++j) {
320 char * pname = cpl_sprintf(
"OBID%.0i", (
int)(j+1));
321 cpl_msg_info(cpl_func,
"%d %s", (
int)j, pname);
322 cpl_propertylist_update_int(stack->plist, pname,
323 (
int)cpl_vector_get(obsid, j));
327 enu_limage_save(stack_fname,
339 cpl_free(stack_fname);
340 cpl_frameset_delete(provenance);
347 cpl_frameset_delete(used);
349 return (
int)cpl_error_get_code();
cpl_error_code eris_nix_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
void enu_located_imagelist_delete(located_imagelist *limlist)
Delete a located_imagelist and its contents.
located_imagelist * enu_limlist_load_from_frameset(cpl_frameset *frameset, const char *tag, cpl_frameset *used)
Load tagged data from a frameset into a located_imagelist.
cpl_error_code enu_stack(located_imagelist *limages, const double stk_lthr, const double stk_hthr, const char *stk_method, const int stk_fast, located_image **result)
Stack a set of images.
void enu_mef_extension_list_delete(mef_extension_list *list)
Delete a mef_extension_list and its contents.
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_image
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter