24#include "eris_nix_img_supersky.h"
25#include "eris_nix_utils.h"
26#include "eris_nix_dfs.h"
27#include "eris_pfits.h"
28#include "eris_utils.h"
32static hdrl_image * create_sky_flat_first(
33 hdrl_imagelist * image_list,
38 const cpl_size plane_id);
40static hdrl_image * create_sky_flat_final(
41 hdrl_imagelist * image_list,
46 const cpl_size plane_id);
48static cpl_mask * detect_sources_hdrl_catalogue(
49 const cpl_image * image,
52static cpl_mask * dilate_mask(
53 const cpl_mask * input_mask,
57eris_image_stats(
const hdrl_image *in_image,
72eris_first_sky_sub(
const hdrl_imagelist* science_images,
const hdrl_image* sky_flat_0,
73 hdrl_imagelist** skysub_images);
76eris_locate_and_mask_sources(hdrl_imagelist* skysub_images,
const cpl_image* bpm_image,
77 const cpl_parameterlist* parlist,
const char* RECIPE_NAME, cpl_mask** source_masks);
80eris_load_data_and_crea_error(
const char* fname,
const cpl_size kk,
const cpl_mask* bad_pixel_map,
81 hdrl_imagelist** science_images);
84eris_load_data_and_error_simple(
const char* fname,
const cpl_size kk,
const cpl_mask* bad_pixel_map,
85 hdrl_imagelist** science_images);
88eris_load_and_error_cube(
const char* fname,
const cpl_mask* bad_pixel_map, cpl_size* kkk,
89 hdrl_imagelist** science_images);
93eris_create_final_skysub_products(
const hdrl_imagelist* science_iml,
const hdrl_image* sky_flat, cpl_frameset** products);
96eris_crea_imagelist_all(cpl_frameset* raw_frames, cpl_mask* bad_pixel_map);
99eris_check_format_is_cube_of_same_size(
const cpl_frameset * raw_frames);
102eris_load_and_error_cube_slice(
const char* fname,
const cpl_mask* bad_pixel_map,
const cpl_size k,
103 const cpl_size kkk, hdrl_imagelist** science_images);
105eris_save_sky_flat_final(
const cpl_frameset* raw_frames,
const hdrl_image* sky_flat_final, cpl_frameset** product_frames);
107const static int debug = 1;
129cpl_error_code eris_nix_img_supersky_run(
130 cpl_frameset * frameset,
131 const cpl_parameterlist * parlist,
132 const char* RECIPE_NAME,
133 cpl_frameset ** product_frames)
135 cpl_frameset * raw_frames = NULL;
136 const cpl_frame * bpm_frame = NULL;
137 cpl_mask * bad_pixel_map = NULL;
138 hdrl_imagelist * science_images = NULL;
139 hdrl_imagelist * skysub_images_0 = NULL;
140 cpl_mask ** source_masks = NULL;
141 hdrl_image * sky_flat_0 = NULL;
142 hdrl_image * sky_flat_final = NULL;
147 const char * combine_method;
150 cpl_boolean save_skysub;
151 cpl_error_code error = CPL_ERROR_NONE;
153 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
154 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
155 cpl_ensure_code(product_frames, CPL_ERROR_NULL_INPUT);
158 combine_method = cpl_parameter_get_string(
159 cpl_parameterlist_find_const(parlist,
"eris.eris_nix_img_supersky.combine_method"));
160 sigma_clip = cpl_parameter_get_double(
161 cpl_parameterlist_find_const(parlist,
"eris.eris_nix_img_supersky.sigma_clip"));
162 max_iter = cpl_parameter_get_int(
163 cpl_parameterlist_find_const(parlist,
"eris.eris_nix_img_supersky.max_iter"));
164 save_skysub = cpl_parameter_get_bool(
165 cpl_parameterlist_find_const(parlist,
"eris.eris_nix_img_supersky.save_skysub"));
170 if (!raw_frames || cpl_frameset_get_size(raw_frames) == 0) {
171 cpl_msg_error(cpl_func,
"No science frames found with tag %s", ERIS_NIX_IMG_SUPERSKY_RAW);
172 error = CPL_ERROR_DATA_NOT_FOUND;
175 num_frames = cpl_frameset_get_size(raw_frames);
176 cpl_msg_info(cpl_func,
"Processing %d science frames", num_frames);
179 bpm_frame = cpl_frameset_find_const(frameset, ERIS_NIX_IMG_SUPERSKY_BPM);
181 cpl_msg_error(cpl_func,
"No bad pixel map found with tag %s", ERIS_NIX_IMG_SUPERSKY_BPM);
182 error = CPL_ERROR_DATA_NOT_FOUND;
186 cpl_image * bpm_image = cpl_image_load(cpl_frame_get_filename(bpm_frame), CPL_TYPE_INT, 0, 0);
188 error = CPL_ERROR_FILE_NOT_FOUND;
193 bad_pixel_map = cpl_mask_threshold_image_create(bpm_image, 0.5, DBL_MAX);
195 cpl_mask_save(bad_pixel_map,
"bad_pixel_map.fits", NULL, CPL_IO_DEFAULT);
197 cpl_mask *inp_mask = cpl_mask_threshold_image_create(bpm_image, -0.5, 0.5);
199 if (!bad_pixel_map) {
200 error = CPL_ERROR_ILLEGAL_INPUT;
203 cpl_boolean same_cubes = CPL_TRUE;
204 cpl_boolean test_cubes = CPL_TRUE;
205 same_cubes = eris_check_format_is_cube_of_same_size(raw_frames);
206 cpl_size num_tot_images = 0;
208 *product_frames = cpl_frameset_new();
209 if(!test_cubes && !same_cubes) {
212 science_images = eris_crea_imagelist_all(raw_frames, bad_pixel_map);
215 cpl_msg_info(cpl_func,
"Creating first-pass super-sky flat...");
216 sky_flat_0 = create_sky_flat_first(science_images, bad_pixel_map, combine_method, sigma_clip,
220 eris_first_sky_sub(science_images, sky_flat_0, &skysub_images_0);
223 eris_print_rec_status(300);
226 cpl_msg_info(cpl_func,
"num_tot_images: %lld",num_tot_images);
227 source_masks = cpl_calloc(num_tot_images,
sizeof(cpl_mask *));
229 eris_locate_and_mask_sources(skysub_images_0, bpm_image, parlist, RECIPE_NAME, source_masks);
231 eris_print_rec_status(400);
233 cpl_msg_info(cpl_func,
"Creating final super-sky flat with source masking...");
234 sky_flat_final = create_sky_flat_final(science_images, source_masks,
235 combine_method, sigma_clip, max_iter, -1);
236 eris_print_rec_status(450);
238 eris_print_rec_status(460);
240 if (!sky_flat_final) {
241 cpl_msg_error(cpl_func,
"Failed to create final sky flat");
242 error = CPL_ERROR_ILLEGAL_OUTPUT;
248 eris_print_rec_status(500);
250 eris_save_sky_flat_final(raw_frames, sky_flat_final, product_frames);
256 eris_create_final_skysub_products(science_images, sky_flat_final, product_frames);
260 if (source_masks != NULL) {
261 for (
int i = 0; i < num_tot_images; i++) {
262 if (source_masks[i]) cpl_mask_delete(source_masks[i]);
264 cpl_free(source_masks);
267 cpl_msg_warning(cpl_func,
"code to be implemented");
269 const cpl_frame * frame = cpl_frameset_get_position_const(raw_frames, 0);
270 const char * filename = cpl_frame_get_filename(frame);
271 cpl_imagelist * data_iml = cpl_imagelist_load(filename, CPL_TYPE_DOUBLE, 1);
272 cpl_size nplanes = cpl_imagelist_get_size(data_iml);
274 for(cpl_size k = 0; k < nplanes; k++) {
276 for(cpl_size kkk = 0; kkk < num_frames; kkk++) {
277 frame = cpl_frameset_get_position_const(raw_frames, kkk);
278 filename = cpl_frame_get_filename(frame);
279 eris_load_and_error_cube_slice(filename, bad_pixel_map, k, kkk, &science_images);
283 cpl_msg_info(cpl_func,
"Creating first-pass super-sky flat...");
284 sky_flat_0 = create_sky_flat_first(science_images, bad_pixel_map, combine_method, sigma_clip, max_iter, k);
287 eris_first_sky_sub(science_images, sky_flat_0, &skysub_images_0);
289 eris_print_rec_status(300);
292 cpl_msg_info(cpl_func,
"num_tot_images: %lld",num_tot_images);
293 source_masks = cpl_calloc(num_tot_images,
sizeof(cpl_mask *));
295 eris_locate_and_mask_sources(skysub_images_0, bpm_image, parlist, RECIPE_NAME, source_masks);
297 eris_print_rec_status(400);
299 cpl_msg_info(cpl_func,
"Creating final super-sky flat with source masking...");
301 sky_flat_final = create_sky_flat_final(science_images, source_masks,
302 combine_method, sigma_clip, max_iter, k);
305 eris_create_final_skysub_products(science_images, sky_flat_final, product_frames);
312 if (source_masks != NULL) {
313 for (
int i = 0; i < num_tot_images; i++) {
314 if (source_masks[i]) cpl_mask_delete(source_masks[i]);
316 cpl_free(source_masks);
319 cpl_imagelist_delete(data_iml);
322 eris_print_rec_status(700);
324 eris_print_rec_status(800);
325 cpl_msg_info(cpl_func,
"Super-sky recipe completed successfully");
328 eris_print_rec_status(600);
329 if (raw_frames) cpl_frameset_delete(raw_frames);
330 if (bad_pixel_map) cpl_mask_delete(bad_pixel_map);
334 if(inp_mask) cpl_mask_delete(inp_mask);
335 if(bpm_image) cpl_image_delete(bpm_image);
342eris_save_sky_flat_final(
const cpl_frameset* raw_frames,
const hdrl_image* sky_flat_final, cpl_frameset** product_frames)
346 cpl_size num_frames = cpl_frameset_get_size(raw_frames);
347 eris_print_rec_status(500);
352 cpl_propertylist* plist = cpl_propertylist_load(cpl_frame_get_filename(
353 cpl_frameset_get_position_const(raw_frames, 0)), 0);
354 cpl_propertylist_update_string(plist, CPL_DFS_PRO_CATG, ERIS_NIX_IMG_SUPERSKY_SKYFLAT);
355 cpl_propertylist_update_double(plist,
"ESO QC SKY MEDIAN", med_sky_final.data);
356 cpl_propertylist_update_int(plist,
"ESO QC NFRAMES", num_frames);
357 eris_print_rec_status(600);
358 char* fname = cpl_sprintf(
"sky_flat_2nd.fits");
362 cpl_frame * product = cpl_frame_new();
363 cpl_frame_set_filename(product, fname);
364 cpl_frame_set_tag(product, ERIS_NIX_IMG_SUPERSKY_SKYFLAT);
365 cpl_frame_set_type(product, CPL_FRAME_TYPE_IMAGE);
366 cpl_frame_set_group(product, CPL_FRAME_GROUP_PRODUCT);
367 cpl_frameset_insert(*product_frames, product);
370 cpl_propertylist_delete(plist);
373 return cpl_error_get_code();
376static hdrl_imagelist*
377eris_crea_imagelist_all(cpl_frameset* raw_frames, cpl_mask* bad_pixel_map)
382 cpl_size num_frames = cpl_frameset_get_size(raw_frames);
384 const char* format = NULL;
385 cpl_propertylist* pheader = NULL;
386 eris_print_rec_status(100);
388 for (cpl_size kk = 0; kk < num_frames; kk++) {
389 const cpl_frame * frame = cpl_frameset_get_position_const(raw_frames, kk);
390 const char * filename = cpl_frame_get_filename(frame);
391 next = cpl_frame_get_nextensions(frame);
392 pheader = cpl_propertylist_load(filename,0);
396 eris_load_data_and_crea_error(filename, kk, bad_pixel_map, &science_images);
398 cpl_msg_info(cpl_func,
"sci data with extentions %s", filename);
399 if(!strcmp(format,
"single")) {
400 eris_load_data_and_error_simple(filename, kk, bad_pixel_map, &science_images);
402 eris_load_and_error_cube(filename, bad_pixel_map, &kkk, &science_images);
405 cpl_propertylist_delete(pheader);
410 cpl_msg_info(cpl_func,
"Image dimensions: %lld x %lld", nx, ny);
414 return science_images;
418eris_check_format_is_cube_of_same_size(
const cpl_frameset * raw_frames)
421 cpl_boolean result = CPL_TRUE;
422 cpl_size nplanes = 0;
423 cpl_size nplanes_tmp = 0;
425 cpl_size num_frames = cpl_frameset_get_size(raw_frames);
427 for (
int kk = 0; kk < num_frames; kk++) {
428 const cpl_frame * frame = cpl_frameset_get_position_const(raw_frames, kk);
429 next = cpl_frame_get_nextensions(frame);
431 const char * fname = cpl_frame_get_filename(frame);
433 cpl_propertylist* phead = cpl_propertylist_load(fname,0);
434 if(cpl_propertylist_has(phead,
"CD3_3")) {
435 cpl_imagelist * data_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 1);
437 nplanes_tmp = cpl_imagelist_get_size(data_iml);
439 nplanes = nplanes_tmp;
440 }
else if (nplanes_tmp != nplanes) {
441 cpl_msg_info(cpl_func,
"cubes not of same size");
444 cpl_imagelist_delete(data_iml);
446 cpl_msg_info(cpl_func,
"Input Data are simple format (images)");
447 cpl_propertylist_delete(phead);
450 cpl_propertylist_delete(phead);
452 cpl_msg_info(cpl_func,
"Data with less than 4 extensions");
472eris_create_final_skysub_products(
const hdrl_imagelist* science_iml,
const hdrl_image* sky_flat, cpl_frameset** products)
475 cpl_msg_info(cpl_func,
"Saving sky-subtracted frames...");
479 for (
int i = 0; i < num_tot_images; i++) {
484 scale.data = med_img.data / med_sky.data;
493 snprintf(outfile, 256,
"sci_skysub_2nd_%03d.fits", i);
496 cpl_msg_info(cpl_func,
"ESO QC SKY_MED: %g",med_img.data);
497 cpl_msg_info(cpl_func,
"ESO QC SKYSUB_MED: %g", med_skyub.data);
511 cpl_frame * product = cpl_frame_new();
512 cpl_frame_set_filename(product, outfile);
513 cpl_frame_set_tag(product, ERIS_NIX_IMG_SUPERSKY_SKYSUB);
514 cpl_frame_set_type(product, CPL_FRAME_TYPE_IMAGE);
515 cpl_frame_set_group(product, CPL_FRAME_GROUP_PRODUCT);
516 cpl_frameset_insert(*products, product);
523 return cpl_error_get_code();
537eris_load_and_error_cube(
const char* fname,
const cpl_mask* bad_pixel_map, cpl_size* kkk,
538 hdrl_imagelist** science_images){
540 eris_print_rec_status(0);
541 cpl_imagelist * data_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 1);
542 cpl_imagelist * error_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 2);
543 cpl_mask * dqual_msk = cpl_mask_load(fname, 0, 3);
544 cpl_imagelist * confm_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 4);
546 double* pconf_img = cpl_image_get_data_double(cpl_imagelist_get(confm_iml,0));
548 cpl_binary* pbpm = cpl_mask_get_data(dqual_msk);
549 cpl_size sx = cpl_mask_get_size_x(dqual_msk);
550 cpl_size sy = cpl_mask_get_size_y(dqual_msk);
551 cpl_size sz = cpl_imagelist_get_size(data_iml);
553 cpl_mask* mask_tot = cpl_mask_duplicate(bad_pixel_map);
554 cpl_mask_or(mask_tot, dqual_msk);
555 double* pdata = NULL;
556 cpl_image * data_img = NULL;
557 cpl_image * error_img = NULL;
560 for (cpl_size k = 0; k < sz; k++) {
561 data_img = cpl_imagelist_get(data_iml,k);
562 error_img = cpl_imagelist_get(error_iml,k);
563 pdata = cpl_image_get_data(cpl_imagelist_get(data_iml,k));
564 for (cpl_size j = 0; j < sy; j++) {
567 for (cpl_size i = 0; i < sx; i++) {
570 if((pconf_img[pixel] == 0) || !isfinite(pdata[pixel])) {
571 pbpm[pixel] = CPL_BINARY_1;
577 cpl_image_reject_from_mask(data_img, mask_tot);
578 cpl_image_reject_from_mask(error_img, mask_tot);
585 cpl_mask_delete(mask_tot);
586 cpl_mask_delete(dqual_msk);
587 cpl_imagelist_delete(data_iml);
588 cpl_imagelist_delete(error_iml);
589 cpl_imagelist_delete(confm_iml);
592 return cpl_error_get_code();
610eris_load_and_error_cube_slice(
const char* fname,
const cpl_mask* bad_pixel_map,
const cpl_size k,
611 const cpl_size kkk, hdrl_imagelist** science_images){
614 cpl_imagelist * data_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 1);
615 cpl_imagelist * error_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 2);
616 cpl_mask * dqual_msk = cpl_mask_load(fname, 0, 3);
617 cpl_imagelist * confm_iml = cpl_imagelist_load(fname, CPL_TYPE_DOUBLE, 4);
619 double* pconf_img = cpl_image_get_data_double(cpl_imagelist_get(confm_iml,0));
621 cpl_binary* pbpm = cpl_mask_get_data(dqual_msk);
622 cpl_size sx = cpl_mask_get_size_x(dqual_msk);
623 cpl_size sy = cpl_mask_get_size_y(dqual_msk);
625 cpl_mask* mask_tot = cpl_mask_duplicate(bad_pixel_map);
627 cpl_mask_or(mask_tot, dqual_msk);
628 double* pdata = NULL;
629 cpl_image * data_img = NULL;
630 cpl_image * error_img = NULL;
634 data_img = cpl_imagelist_get(data_iml,k);
635 error_img = cpl_imagelist_get(error_iml,k);
636 pdata = cpl_image_get_data(cpl_imagelist_get(data_iml,k));
638 for (cpl_size j = 0; j < sy; j++) {
641 for (cpl_size i = 0; i < sx; i++) {
644 if((pconf_img[pixel] == 0) || !isfinite(pdata[pixel])) {
645 pbpm[pixel] = CPL_BINARY_1;
651 cpl_image_reject_from_mask(data_img, mask_tot);
652 cpl_image_reject_from_mask(error_img, mask_tot);
656 cpl_mask_delete(mask_tot);
657 cpl_mask_delete(dqual_msk);
658 cpl_imagelist_delete(data_iml);
659 cpl_imagelist_delete(error_iml);
660 cpl_imagelist_delete(confm_iml);
663 return cpl_error_get_code();
680eris_load_data_and_error_simple(
const char* fname,
const cpl_size kk,
const cpl_mask* bad_pixel_map,
681 hdrl_imagelist** science_images)
684 cpl_ensure_code(fname, CPL_ERROR_NULL_INPUT);
685 cpl_image * data_img = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 1);
686 cpl_image * error_img = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 2);
687 cpl_mask* dqual_msk = cpl_mask_load(fname, 0, 3);
688 cpl_image* confm_img = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 4);
689 double* pdata = cpl_image_get_data(data_img);
690 double* pconf_img = cpl_image_get_data_double(confm_img);
691 cpl_binary* pbpm = cpl_mask_get_data(dqual_msk);
692 cpl_size sx = cpl_image_get_size_x(confm_img);
693 cpl_size sy = cpl_image_get_size_y(confm_img);
696 for (cpl_size j = 0; j < sy; j++) {
699 for (cpl_size i = 0; i < sx; i++) {
702 if((pconf_img[pixel] == 0) || !isfinite(pdata[pixel])) {
703 pbpm[pixel] = CPL_BINARY_1;
709 cpl_mask* mask_tot = cpl_mask_duplicate(bad_pixel_map);
710 cpl_mask_or(mask_tot, dqual_msk);
712 cpl_image_reject_from_mask(data_img, mask_tot);
713 cpl_image_reject_from_mask(error_img, mask_tot);
721 cpl_image_delete(data_img);
722 cpl_image_delete(error_img);
723 cpl_mask_delete(mask_tot);
724 cpl_mask_delete(dqual_msk);
725 cpl_image_delete(confm_img);
729 double median=0, mean=0, stdev=0,tmean=0, tstd=0, mad=0, min_val=0, max_val=0;
736 &median, &mean, &stdev, &tmean, &tstd, &mad, &min_val, &max_val
739 cpl_msg_info(cpl_func,
"process file: %s", fname);
740 cpl_msg_info(cpl_func,
"Median=%.3f, Mean=%.3f, StdDev=%.3f "
741 "Trimmed: Mean=%.3f, StdDev=%.3f, MAD=%.3f "
742 "Range: [%.3f, %.3f]", median, mean, stdev, tmean, tstd, mad, min_val, max_val);
745 return cpl_error_get_code();
760eris_load_data_and_crea_error(
const char* fname,
const cpl_size kk,
const cpl_mask* bad_pixel_map,
761 hdrl_imagelist** science_images)
763 cpl_ensure_code(fname, CPL_ERROR_NULL_INPUT);
764 cpl_image * data_img = NULL;
765 cpl_image * error_img = NULL;
766 cpl_msg_info(cpl_func,
"sci data with less than 4 extensions");
767 data_img = cpl_image_load(fname, CPL_TYPE_DOUBLE, 0, 0);
769 cpl_msg_error(cpl_func,
"Failed to load frame %s", fname);
771 return cpl_error_get_code();
773 double* pdata = NULL;
774 cpl_mask * dqual_msk = NULL;
775 pdata = cpl_image_get_data(data_img);
776 dqual_msk = cpl_image_get_bpm(data_img);
777 cpl_size sx = cpl_image_get_size_x(data_img);
778 cpl_size sy = cpl_image_get_size_y(data_img);
779 cpl_binary* pbpm = cpl_mask_get_data(dqual_msk);
782 for (cpl_size j = 0; j < sy; j++) {
784 for (cpl_size i = 0; i < sx; i++) {
786 if(!isfinite(pdata[pixel])) {
787 pbpm[pixel] = CPL_BINARY_1;
792 cpl_mask* mask_tot = cpl_mask_duplicate(bad_pixel_map);
793 cpl_mask_or(mask_tot, dqual_msk);
795 cpl_image_reject_from_mask(data_img, mask_tot);
798 error_img = cpl_image_duplicate(data_img);
799 cpl_image_abs(error_img);
800 cpl_image_add_scalar(error_img, 1.0);
801 cpl_image_power(error_img, 0.5);
807 cpl_image_delete(data_img);
808 cpl_image_delete(error_img);
809 cpl_mask_delete(mask_tot);
812 return cpl_error_get_code();
828eris_locate_and_mask_sources(hdrl_imagelist* skysub_images,
const cpl_image* bpm_image,
829 const cpl_parameterlist* parlist,
const char* RECIPE_NAME, cpl_mask** source_masks)
831 cpl_msg_info(cpl_func,
"Detecting sources...");
837 const hdrl_catalogue_options opt = HDRL_CATALOGUE_SEGMAP;
840 for (
int i = 0; i < num_tot_images; i++) {
845 cpl_mask *bpm = cpl_mask_threshold_image_create(bpm_image, 0, INT_MAX);
846 cpl_image_reject_from_mask(data, bpm);
848 source_masks[i] = detect_sources_hdrl_catalogue(data, par_cat);
850 char* fname = cpl_sprintf(
"msk_%d.fits",i);
851 cpl_mask_save(source_masks[i], fname, NULL, CPL_IO_DEFAULT);
854 cpl_mask_delete(bpm);
857 cpl_mask* bad_pixel_map = cpl_mask_threshold_image_create(bpm_image, 0.5, DBL_MAX);
858 if(source_masks[i] != NULL && bad_pixel_map != NULL) {
859 int nsources = cpl_mask_count(source_masks[i]) -
860 cpl_mask_count(bad_pixel_map);
863 cpl_msg_info(cpl_func,
" Frame %d: detected %d source pixels", i+1, nsources);
865 cpl_msg_warning(cpl_func,
" Frame %d: no sources detected", i+1);
868 cpl_mask_delete(bad_pixel_map);
872 return cpl_error_get_code();
884eris_first_sky_sub(
const hdrl_imagelist* science_images,
const hdrl_image* sky_flat_0,
885 hdrl_imagelist** skysub_images)
888 cpl_msg_info(cpl_func,
"Subtracting first-pass sky flat...");
892 hdrl_value scale = {0, 0};
894 for (
int i = 0; i < num_tot_images; i++) {
898 scale.data = med_img.data / med_sky_0.data;
904 fname = cpl_sprintf(
"sci_%d.fits",i);
907 fname = cpl_sprintf(
"scaled_sky_0_%d.fits",i);
915 fname = cpl_sprintf(
"sci_skysub_1st_%03d.fits",i);
924 return cpl_error_get_code();
927#define HDRL_USE_PRIVATE YES
939static hdrl_image * create_sky_flat_first(
940 hdrl_imagelist * image_list,
945 const cpl_size plane_id)
947 hdrl_image * result = NULL;
949 hdrl_imagelist * masked_list = NULL;
950 hdrl_parameter * collapse_par = NULL;
953 cpl_ensure(image_list, CPL_ERROR_NULL_INPUT, NULL);
954 cpl_ensure(method, CPL_ERROR_NULL_INPUT, NULL);
957 cpl_ensure(num_images > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
958 cpl_msg_warning(cpl_func,
"kappa: %g niter: %d", kappa, niter);
963 for (
int i = 0; i < num_images; i++) {
969 cpl_image_reject_from_mask(data, mask);
974 masked_list = image_list;
978 if (strcmp(method,
"median") == 0) {
981 cpl_msg_info(cpl_func,
"kappa: %g niter: %d",kappa, niter);
990 fname = cpl_sprintf(
"sky_flat_1st.fits");
992 fname = cpl_sprintf(
"sky_flat_1st_plane_%3.3lld.fits",plane_id);
999 cpl_image_delete(contrib);
1016static hdrl_image * create_sky_flat_final(
1017 hdrl_imagelist * image_list,
1019 const char * method,
1022 const cpl_size plane_id)
1024 hdrl_image * result = NULL;
1025 hdrl_imagelist * masked_list = NULL;
1026 hdrl_parameter * collapse_par = NULL;
1027 cpl_image* contrib = NULL;
1029 cpl_ensure(image_list, CPL_ERROR_NULL_INPUT, NULL);
1030 cpl_ensure(method, CPL_ERROR_NULL_INPUT, NULL);
1033 cpl_ensure(num_images > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1039 for (
int i = 0; i < num_images; i++) {
1047 cpl_image_reject_from_mask(data, masks[i]);
1051 fname = cpl_sprintf(
"mask_%d.fits",i);
1053 fname = cpl_sprintf(
"mask_%d_%3.3lld.fits",i,plane_id);
1056 cpl_mask_save(masks[i], fname, NULL, CPL_IO_DEFAULT);
1064 masked_list = image_list;
1068 if (strcmp(method,
"median") == 0) {
1080 fname = cpl_sprintf(
"sky_flat_2nd.fits");
1082 fname = cpl_sprintf(
"sky_flat_2nd_plane_%3.3lld.fits",plane_id);
1089 if (contrib != NULL) {
1090 cpl_image_delete(contrib);
1095 if (masks && masked_list) {
1103static cpl_mask * detect_sources_hdrl_catalogue(
1104 const cpl_image * image,
1108 cpl_mask * mask_res = NULL;
1112 char* fname = cpl_sprintf(
"smap_%d.fits",0);
1113 cpl_image_save(res->segmentation_map, fname, CPL_TYPE_DOUBLE, NULL, CPL_IO_DEFAULT);
1116 double max = cpl_image_get_max(res->segmentation_map);
1117 mask_res = cpl_mask_threshold_image_create(res->segmentation_map, 0.9, max + 0.1);
1131static cpl_mask * dilate_mask(
1132 const cpl_mask * input_mask,
1135 cpl_mask * result = NULL;
1136 cpl_mask * temp = NULL;
1139 cpl_ensure(input_mask, CPL_ERROR_NULL_INPUT, NULL);
1140 cpl_ensure(radius > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1142 nx = cpl_mask_get_size_x(input_mask);
1143 ny = cpl_mask_get_size_y(input_mask);
1145 result = cpl_mask_duplicate(input_mask);
1148 for (
int iter = 0; iter < radius; iter++) {
1149 temp = cpl_mask_duplicate(result);
1151 for (cpl_size j = 2; j < ny - 1; j++) {
1152 for (cpl_size i = 2; i < nx - 1; i++) {
1153 if (cpl_mask_get(temp, i, j) ||
1154 cpl_mask_get(temp, i-1, j) ||
1155 cpl_mask_get(temp, i+1, j) ||
1156 cpl_mask_get(temp, i, j-1) ||
1157 cpl_mask_get(temp, i, j+1)) {
1158 cpl_mask_set(result, i, j, CPL_BINARY_1);
1162 cpl_mask_delete(temp);
1200eris_image_stats(
const hdrl_image *in_image,
1203 const cpl_mask *mask,
1204 double trim_fraction,
1214 cpl_ensure_code(in_image, CPL_ERROR_NULL_INPUT);
1215 cpl_ensure_code(median, CPL_ERROR_NULL_INPUT);
1216 cpl_ensure_code(mean, CPL_ERROR_NULL_INPUT);
1217 cpl_ensure_code(stdev, CPL_ERROR_NULL_INPUT);
1218 cpl_ensure_code(tmean, CPL_ERROR_NULL_INPUT);
1219 cpl_ensure_code(tstd, CPL_ERROR_NULL_INPUT);
1220 cpl_ensure_code(mad, CPL_ERROR_NULL_INPUT);
1221 cpl_ensure_code(min_val, CPL_ERROR_NULL_INPUT);
1222 cpl_ensure_code(max_val, CPL_ERROR_NULL_INPUT);
1225 cpl_image *work_img = NULL;
1226 cpl_vector *data_vec = NULL;
1229 work_img = cpl_image_duplicate(img);
1231 return cpl_error_set_message(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT,
1232 "Failed to duplicate image");
1237 cpl_image_reject_from_mask(work_img, mask);
1245 *median = median0.data;
1250 cpl_size nx = cpl_image_get_size_x(work_img);
1251 cpl_size ny = cpl_image_get_size_y(work_img);
1252 cpl_size npix = nx * ny;
1255 const cpl_mask *rej_mask = cpl_image_get_bpm_const(work_img);
1256 cpl_size nvalid = npix;
1258 nvalid = npix - cpl_mask_count(rej_mask);
1262 cpl_image_delete(work_img);
1263 return cpl_error_set_message(cpl_func, CPL_ERROR_DATA_NOT_FOUND,
1264 "No valid pixels in image");
1268 data_vec = cpl_vector_new(nvalid);
1270 for (cpl_size j = 1; j <= ny; j++) {
1271 for (cpl_size i = 1; i <= nx; i++) {
1272 int is_rejected = 0;
1273 double val = cpl_image_get(work_img, i, j, &is_rejected);
1274 if (!is_rejected && isfinite(val)) {
1275 cpl_vector_set(data_vec, idx, val);
1283 cpl_vector *tmp = cpl_vector_extract(data_vec, 0, idx - 1, 1);
1284 cpl_vector_delete(data_vec);
1290 cpl_vector_sort(data_vec, CPL_SORT_ASCENDING);
1291 cpl_size trim_count = (cpl_size)(trim_fraction * nvalid);
1292 if (trim_count * 2 >= nvalid) {
1296 double tmean0_10 = 0.0;
1297 if (trim_count > 0) {
1299 cpl_vector *trimmed = cpl_vector_extract(data_vec, trim_count,
1300 nvalid - trim_count - 1, 1);
1301 tmean0_10 = cpl_vector_get_mean(trimmed);
1302 cpl_vector_delete(trimmed);
1304 tmean0_10 = cpl_vector_get_mean(data_vec);
1308 double rmin = tmean0_10 - l_sig * (*stdev);
1309 double rmax = tmean0_10 + u_sig * (*stdev);
1312 cpl_size nclipped = 0;
1313 double sum_clipped = 0.0;
1314 double sum_sq_clipped = 0.0;
1316 for (cpl_size i = 0; i < nvalid; i++) {
1317 double val = cpl_vector_get(data_vec, i);
1318 if (val >= rmin && val <= rmax) {
1320 sum_sq_clipped += val * val;
1326 *tmean = sum_clipped / nclipped;
1329 double variance = (sum_sq_clipped - sum_clipped * sum_clipped / nclipped)
1331 *tstd = (variance > 0.0) ? sqrt(variance) : 0.0;
1343 cpl_vector *abs_dev = cpl_vector_duplicate(data_vec);
1344 cpl_vector_subtract_scalar(abs_dev, *median);
1345 for (cpl_size i = 0; i < nvalid; i++) {
1346 double val = cpl_vector_get(abs_dev, i);
1347 cpl_vector_set(abs_dev, i, fabs(val));
1349 cpl_vector_sort(abs_dev, CPL_SORT_ASCENDING);
1360 *mad = cpl_vector_get_median(abs_dev);
1362 cpl_vector_delete(abs_dev);
1365 *min_val = cpl_vector_get_min(data_vec);
1366 *max_val = cpl_vector_get_max(data_vec);
1369 cpl_vector_delete(data_vec);
1370 cpl_image_delete(work_img);
1372 return CPL_ERROR_NONE;
const char * eris_pfits_get_frame_format(const cpl_propertylist *plist)
find out the frame format (DET FRAM FORMAT) value
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
cpl_frameset * eris_dfs_extract_frames_with_tag(cpl_frameset *input, const char *rtag)
Extract frames of user given tag.
hdrl_catalogue_result * hdrl_catalogue_compute(const cpl_image *image_, const cpl_image *confidence_map, const cpl_wcs *wcs, hdrl_parameter *param_)
build object catalog
void hdrl_catalogue_result_delete(hdrl_catalogue_result *result)
delete hdrl parameter result object
hdrl_parameter * hdrl_catalogue_parameter_parse_parlist(const cpl_parameterlist *parlist, const char *prefix)
Parse parameter list to create input parameters for the catalogue.
cpl_error_code hdrl_catalogue_parameter_set_option(hdrl_parameter *par, hdrl_catalogue_options opt)
set result option of catalogue parameter
hdrl_parameter * hdrl_collapse_sigclip_parameter_create(double kappa_low, double kappa_high, int niter)
create a parameter object for sigclipped mean
hdrl_parameter * hdrl_collapse_median_parameter_create(void)
create a parameter object for median
cpl_error_code hdrl_image_sub_image(hdrl_image *self, const hdrl_image *other)
Subtract two images, store the result in the first image.
hdrl_value hdrl_image_get_median(const hdrl_image *self)
computes the median and associated error of an image.
cpl_error_code hdrl_image_mul_scalar(hdrl_image *self, hdrl_value value)
Elementwise multiplication of an image with a scalar.
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
double hdrl_image_get_stdev(const hdrl_image *self)
computes the standard deviation of the data of an image
hdrl_value hdrl_image_get_mean(const hdrl_image *self)
computes mean pixel value and associated error of an 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
hdrl_image * hdrl_image_create(const cpl_image *image, const cpl_image *error)
create a new hdrl_image from to existing images by copying them
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image
void hdrl_image_delete(hdrl_image *himg)
delete hdrl_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.
const hdrl_image * hdrl_imagelist_get_const(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
cpl_size hdrl_imagelist_get_size(const hdrl_imagelist *himlist)
Get the number of images in the imagelist.
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.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.
void hdrl_parameter_delete(hdrl_parameter *obj)
shallow delete of a parameter