39#include "casu_utils.h"
42#include "eris_utils.h"
43#include "eris_nix_utils.h"
44#include "eris_pfits.h"
46#include "eris_nix_dfs.h"
47#include "eris_nix_master_bpm.h"
48#include "eris_nix_master_dark.h"
49#include "eris_nix_gain_linearity.h"
50#include "eris_utils.h"
59static const char eris_nix_lss_stack_description[] =
60"This recipe uses an HDRL collapse operation to stack a set of already \n"
61"registered ERIS/NIX LSS jitter frames.\n"
65" DO CATG Explanation Req. #Frames\n"
66" ------- ----------- --- -------\n"
67" "ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG
68 " calibrated frames Y 1-n\n"
71" "ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG
72 " calibrated standard Y 1-n\n"
73" frames to be stacked.\n"
77" DO CATG Explanation \n"
78" ------- ----------- \n"
79" "ERIS_NIX_LSS_OBS_COMBINED_PRO_CATG
80 " the stacked 2d-spectrum of the target.\n"
82" "ERIS_NIX_LSS_STD_COMBINED_PRO_CATG
83 " the stacked 2d-spectrum of the standard.\n"
85" The output image will be in a FITS file named \n"
86" 'stack.<first input filename>', with extensions:\n"
87" - DATA, with the stacked target or standard data.\n"
88" - ERR, with the error plane.\n"
89" - DQ, with the stacked image quality\n"
90" - CONFIDENCE, with the target confidence plane.\n"
93"Notes on the method.\n"
94" The stacking uses hdrl_image_collapse to combine all jitter\n"
95" images such that each output pixel is the median of the inputs.\n"
99#define RECIPE_NAME "eris.eris_nix_lss_stack"
105cpl_recipe_define(eris_nix_lss_stack, ERIS_BINARY_VERSION,
107 PACKAGE_BUGREPORT,
"2017",
108 "Stack "ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG
110 eris_nix_lss_stack_description);
126static cpl_error_code eris_nix_lss_stack_fill_parameterlist(
127 cpl_parameterlist * self) {
129 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
131 cpl_parameter * p = NULL;
133 p = cpl_parameter_new_value(RECIPE_NAME
".x_probe", CPL_TYPE_INT,
134 "x coord of diagnostic pixel",
136 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"x-probe");
137 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
138 cpl_parameterlist_append(self, p);
140 p = cpl_parameter_new_value(RECIPE_NAME
".y_probe", CPL_TYPE_INT,
141 "y coord of diagnostic pixel",
143 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"y-probe");
144 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
145 cpl_parameterlist_append(self, p);
159static int eris_nix_lss_stack(cpl_frameset * frameset,
160 const cpl_parameterlist * parlist) {
162 cpl_image * contrib = NULL;
163 hdrl_imagelist * himlist = NULL;
164 located_imagelist * jitters = NULL;
165 located_imagelist * object_jitters = NULL;
166 const char * out_catg = NULL;
167 located_image * stack = NULL;
168 located_imagelist * std_jitters = NULL;
169 cpl_frameset * used = NULL;
171 enu_check_error_code(
"%s():%d: An error is already set: %s",
172 cpl_func, __LINE__, cpl_error_get_where());
176 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
177 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
181 cpl_msg_set_level_from_env();
182 cpl_msg_severity severity = cpl_msg_get_level();
183 cpl_msg_info(cpl_func,
"level %d", (
int) severity);
187 return CPL_ERROR_BAD_FILE_FORMAT;
191 const cpl_parameter * p = NULL;
192 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".x_probe");
193 cpl_size x_probe = (cpl_size) cpl_parameter_get_int(p);
194 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".y_probe");
195 cpl_size y_probe = (cpl_size) cpl_parameter_get_int(p);
197 enu_check_error_code(
"Could not retrieve input parameters");
202 enu_check_error_code(
"Could not identify RAW and CALIB frames");
203 used = cpl_frameset_new();
208 ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG, used);
210 ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG, used);
211 enu_check_error_code(
"Error loading frameset");
213 if (object_jitters->size > 0) {
214 enu_check(std_jitters->size == 0, CPL_ERROR_ILLEGAL_INPUT,
215 "SoF contains both object and std data");
216 jitters = object_jitters;
217 object_jitters = NULL;
218 out_catg = ERIS_NIX_LSS_OBS_COMBINED_PRO_CATG;
219 cpl_msg_info(cpl_func,
"Read in %d "
220 ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG
" frames",
221 (
int)(jitters->size));
222 }
else if (std_jitters->size > 0) {
223 jitters = std_jitters;
225 out_catg = ERIS_NIX_LSS_STD_COMBINED_PRO_CATG;
226 cpl_msg_info(cpl_func,
"Read in %d "
227 ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG
" frames",
228 (
int)(jitters->size));
234 double crval1 = -1.0;
235 double crval3 = -1.0;
236 for (cpl_size j=0; j < jitters->size; j++) {
241 crval1 = cpl_propertylist_get_double(jitters->limages[j]->plist,
254 if (x_probe >= 1 && x_probe <= nx &&
255 y_probe >= 1 && y_probe <= ny) {
258 x_probe, y_probe, &reject);
260 double confidence = cpl_image_get(jitters->limages[j]->confidence,
261 x_probe, y_probe, &ignore);
262 cpl_msg_info(cpl_func,
"j=%d val={%f, %f} reject=%d confidence=%f",
263 (
int)j, val.data, val.error, reject, confidence);
269 hdrl_image * stack_himage = NULL;
272 enu_check_error_code(
"error set after image stacking");
279 if (x_probe >= 1 && x_probe <= nx &&
280 y_probe >= 1 && y_probe <= ny) {
284 x_probe, y_probe, &reject);
285 cpl_msg_info(cpl_func,
"val={%f, %f} reject=%d",
286 val.data, val.error, reject);
293 for (cpl_size j=0; j < jitters->size; j++) {
298 hdrl_image * stack_bkg = NULL;
299 cpl_image_delete(contrib);
303 enu_check_error_code(
"error set after background stacking");
315 cpl_image * stack_confidence = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
317 cpl_image * stack_count = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
318 double * stack_conf_ptr = cpl_image_get_data_double(stack_confidence);
319 double * stack_count_ptr = cpl_image_get_data_double(stack_count);
320 for (cpl_size i=0; i < nx * ny; i++) {
321 stack_conf_ptr[i] = 0.0;
322 stack_count_ptr[i] = 0.0;
327 for (cpl_size j=0; j < jitters->size; j++) {
328 for (cpl_size i=1; i < nx+1; i++){
329 for (cpl_size jj=1; jj< ny+1; jj++) {
337 jitters->limages[j]->himage,
341 double jconf = cpl_image_get(
342 jitters->limages[j]->confidence,
344 double sconf = cpl_image_get(stack_confidence,
347 if (sconf != CPL_VALUE_PLUSINF) {
350 cpl_image_set(stack_confidence, i, jj,
352 double tcount = cpl_image_get(stack_count,
354 cpl_image_set(stack_count, i, jj, tcount + 1);
358 cpl_image_set(stack_confidence, i, jj,
368 for (cpl_size i=1; i < nx+1; i++){
369 for (cpl_size j=1; j< ny+1; j++) {
371 double conf = cpl_image_get(stack_confidence,
373 double count = cpl_image_get(stack_count,
375 if (conf != CPL_VALUE_PLUSINF && count > 0.0) {
376 cpl_image_set(stack_confidence,
377 i, j, conf / pow(count, 2));
379 cpl_image_set(stack_confidence,
380 i, j, CPL_VALUE_PLUSINF);
387 for (cpl_size i=0; i < nx * ny; i++) {
388 if (stack_conf_ptr[i] == CPL_VALUE_PLUSINF) {
389 stack_conf_ptr[i] = 0.0;
391 stack_conf_ptr[i] = 1.0 / stack_conf_ptr[i];
399 cpl_image_delete(stack_count);
401 enu_check_error_code(
"error set after confidence stacking");
410 cpl_propertylist_new(),
463 cpl_propertylist * olist = stack->plist;
464 cpl_propertylist_update_int(olist,
"NAXIS", 3);
465 cpl_propertylist_update_string(olist,
"CTYPE1",
"RA---TAN");
466 cpl_propertylist_update_string(olist,
"CTYPE2",
"WAVE");
467 cpl_propertylist_update_string(olist,
"CTYPE3",
"DEC--TAN");
468 cpl_propertylist_update_double(olist,
"CRPIX1", 1024.0);
469 cpl_propertylist_update_double(olist,
"CRPIX2", 0.0);
470 cpl_propertylist_update_double(olist,
"CRPIX3", 0.0);
471 cpl_propertylist_update_double(olist,
"CRVAL1", crval1);
472 cpl_propertylist_update_double(olist,
"CRVAL2", 3.045);
473 cpl_propertylist_update_double(olist,
"CRVAL3", crval3);
476 double slit_pa = 0.0;
477 double pixscale = 0.013;
478 cpl_propertylist_update_double(olist,
"CD1_1",
479 sin(slit_pa) * pixscale / (3600.0));
480 cpl_propertylist_update_double(olist,
"CD1_2", 0.0);
481 cpl_propertylist_update_double(olist,
"CD1_3", 1.0);
483 cpl_propertylist_update_double(olist,
"CD2_1", 0.0);
484 cpl_propertylist_update_double(olist,
"CD2_2",
485 (4.107 - 3.045) / 2047);
486 cpl_propertylist_update_double(olist,
"CD2_3", 0.0);
488 cpl_propertylist_update_double(olist,
"CD3_1",
489 cos(slit_pa) * pixscale / (3600.0));
490 cpl_propertylist_update_double(olist,
"CD3_2", 0.0);
491 cpl_propertylist_update_double(olist,
"CD3_3", 1.0);
493 cpl_propertylist_update_string(olist,
"CUNIT1",
"DEG");
494 cpl_propertylist_update_string(olist,
"CUNIT2",
"um");
495 cpl_propertylist_update_string(olist,
"CUNIT3",
"DEG");
503 stack->himage = NULL;
504 stack->himagelist = himlist1;
509 jitters->limages[0]->frame),
514 cpl_frameset * provenance = cpl_frameset_new();
515 for (cpl_size j=0; j<jitters->size; j++) {
516 cpl_frameset_insert(provenance, cpl_frame_duplicate(
517 jitters->limages[j]->frame));
522 cpl_propertylist * applist = cpl_propertylist_new();
523 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, out_catg);
524 cpl_propertylist_update_string(applist,
"PRODCATG",
525 "ANCILLARY.2DSPECTRUM");
527 int ncombine = jitters->size;
529 double total_exptime = 0.0;
530 double mjd_start = 1000000.0;
531 double mjd_end = 0.0;
533 cpl_vector * obsid = cpl_vector_new(jitters->size);
534 for (cpl_size j=0; j < jitters->size; j++) {
535 cpl_vector_set(obsid, j, (
double)j);
540 double dit =
enu_get_dit(jitters->limages[j]->plist);
541 double exptime = dit * cpl_propertylist_get_int(
542 jitters->limages[j]->plist,
"ESO DET NDIT");
543 total_exptime += exptime;
547 double jitter_start = cpl_propertylist_get_double(
548 jitters->limages[j]->plist,
"MJD-OBS");
549 if (jitter_start < mjd_start) {
550 mjd_start = jitter_start;
552 double jitter_end = cpl_propertylist_get_double(
553 jitters->limages[j]->plist,
"MJD-END");
554 if (jitter_end > mjd_end) {
555 mjd_end = jitter_end;
557 cpl_msg_info(cpl_func,
"..combined mjd start: %15.8f end: %15.8f",
564 cpl_propertylist_update_int(applist,
"NCOMBINE", ncombine);
565 cpl_propertylist_update_double(applist,
"EXPTIME", total_exptime);
566 cpl_propertylist_update_double(applist,
"TEXPTIME", total_exptime);
567 cpl_propertylist_update_double(applist,
"MJD-OBS", mjd_start);
568 cpl_propertylist_update_double(applist,
"MJD-END", mjd_end);
569 for (cpl_size j = 0; j < jitters->size; ++j) {
570 char * pname = cpl_sprintf(
"OBID%.0i", (
int)(j+1));
571 cpl_msg_info(cpl_func,
"%d %s", (
int)j, pname);
572 cpl_propertylist_update_int(applist, pname,
573 (
int)cpl_vector_get(obsid, j));
577 cpl_msg_info(cpl_func,
"BUNIT fudged for now");
578 cpl_propertylist_update_string(applist,
"BUNIT",
"adu/s");
590 PACKAGE
"/" PACKAGE_VERSION,
593 cpl_free(stack_fname);
594 cpl_frameset_delete(provenance);
595 cpl_propertylist_delete(applist);
598 cpl_image_delete(contrib);
602 cpl_frameset_delete(used);
604 return (
int) cpl_error_get_code();
cpl_error_code enu_dfs_save_limage(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *provenance, const cpl_boolean prov_raw, const located_image *limage, const char *recipe, const cpl_frame *inherit, cpl_propertylist *applist, const char *pipe_id, const char *filename)
Save a located image structure to a MEF.
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_image * enu_located_image_new(hdrl_image *himage, hdrl_imagelist *himagelist, cpl_image *confidence, hdrl_image *bkg, cpl_image *bkg_confidence, cpl_propertylist *plist, hdrl_catalogue_result *objects, cpl_mask *object_mask, hdrl_catalogue_result *wcs, hdrl_catalogue_result *photom, cpl_frame *frame)
Create a located_image structure and initialise the 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.
void enu_located_image_delete(located_image *limage)
Delete a located_image and its contents.
cpl_error_code enu_normalise_confidence(cpl_image *confidence)
Normalise confidence array so that mean of good pixels is 100.
char * enu_repreface(const char *filename, const char *preface)
Preface a raw filename with a string.
double enu_get_dit(const cpl_propertylist *plist)
Get the DIT of an integration.
cpl_error_code eris_files_dont_exist(cpl_frameset *frameset)
Check if all SOF files exist.
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the images.
cpl_error_code hdrl_imagelist_collapse(const hdrl_imagelist *himlist, const hdrl_parameter *param, hdrl_image **out, cpl_image **contrib)
collapsing of image list
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.