28#include "eris_pfits.h"
29#include "eris_ifu_error.h"
30#include "eris_ifu_functions.h"
31#include "eris_ifu_utils.h"
32#include "eris_ifu_combine_static.h"
75cpl_error_code eris_ifu_combine_jittered_images(
76 cpl_image **imagesData,
77 cpl_image **imagesError,
80 cpl_image **mergedImageData,
81 cpl_image **mergedImageError,
82 cpl_image **mergedImageDIT,
86 const double *exptimes,
88 const char *compute_mode,
99 float *sub_offsetx = NULL,
101 cpl_image **imagesDataShifted = NULL,
102 **imagesErrorShifted = NULL;
103 cpl_error_code ret_err = CPL_ERROR_NONE;
105 cpl_ensure_code(imagesData != NULL, CPL_ERROR_NULL_INPUT);
106 cpl_ensure_code(imagesError != NULL, CPL_ERROR_NULL_INPUT);
107 cpl_ensure_code(mergedImageData != NULL, CPL_ERROR_NULL_INPUT);
108 cpl_ensure_code(mergedImageError != NULL, CPL_ERROR_NULL_INPUT);
109 cpl_ensure_code(mergedImageDIT != NULL, CPL_ERROR_NULL_INPUT);
110 cpl_ensure_code(offsetx != NULL, CPL_ERROR_NULL_INPUT);
111 cpl_ensure_code(offsety != NULL, CPL_ERROR_NULL_INPUT);
112 cpl_ensure_code(exptimes != NULL, CPL_ERROR_NULL_INPUT);
113 cpl_ensure_code(compute_mode != NULL, CPL_ERROR_NULL_INPUT);
116 nx_in = cpl_image_get_size_x(imagesData[0]);
117 ny_in = cpl_image_get_size_y(imagesData[0]);
124 llx0 = (int)((
double)(nx_out - nx_in) / 2.0 + 0.5);
125 lly0 = (int)((
double)(ny_out - ny_in) / 2.0 + 0.5);
130 llx = cpl_calloc(n_cubes,
sizeof(
int));
131 lly = cpl_calloc(n_cubes,
sizeof(
int));
132 sub_offsetx = cpl_calloc(n_cubes,
sizeof(
float));
133 sub_offsety = cpl_calloc(n_cubes,
sizeof(
float));
136 for (
int i = 0; i < n_cubes; i++) {
137 llx[i] = llx0 - eris_ifu_combine_nearest_int(offsetx[i]);
139 sub_offsetx[i] = (float)eris_ifu_combine_nearest_int(offsetx[i]) - offsetx[i];
140 lly[i] = lly0 - eris_ifu_combine_nearest_int(offsety[i]);
141 sub_offsety[i] = (float)eris_ifu_combine_nearest_int(offsety[i]) - offsety[i];
143 if (llx[i] < min_lx) {
146 if (lly[i] < min_ly) {
154 for (
int i = 0 ; i < n_cubes ; i++ ) {
155 llx[i] = llx[i] - min_lx;
159 for (
int i = 0 ; i < n_cubes ; i++ ) {
160 lly[i] = lly[i] - min_ly;
169 imagesDataShifted = (cpl_image**)cpl_calloc(n_cubes,
sizeof(cpl_imagelist*)));
171 imagesErrorShifted = (cpl_image**)cpl_calloc(n_cubes,
sizeof(cpl_imagelist*)));
173 for (
int i = 0; i < n_cubes; i++) {
175 imagesDataShifted[i] = eris_ifu_combine_shift_image_kmos(
177 sub_offsetx[i], sub_offsety[i],
180 imagesErrorShifted[i] = eris_ifu_combine_shift_image_kmos(
182 sub_offsetx[i], sub_offsety[i],
188 eris_ifu_combine_build_mask_cube(imagesDataShifted,
194 if ((kappa != -1) && (pclip != -1)) {
197 eris_ifu_combine_coadd_ks_clip(
199 kappa, llx, lly, exptimes,
200 mergedImageData, mergedImageError, *mergedImageDIT,
201 imagesDataShifted, imagesErrorShifted,
202 compute_mode, pclip, nx_out, ny_out));
207 eris_ifu_combine_coadd(n_cubes,
208 mergedImageData, mergedImageError, *mergedImageDIT,
209 imagesDataShifted, imagesErrorShifted,
211 llx, lly, compute_mode, nx_out, ny_out));
215 ret_err = cpl_error_get_code();
222 for (
int i = 0; i < n_cubes; i++) {
227 cpl_free(imagesDataShifted); imagesDataShifted = NULL;
228 cpl_free(imagesErrorShifted); imagesErrorShifted = NULL;
229 cpl_free(llx); llx = NULL;
230 cpl_free(lly); lly = NULL;
231 cpl_free(sub_offsetx); sub_offsetx = NULL;
232 cpl_free(sub_offsety); sub_offsety = NULL;
246cpl_error_code eris_ifu_combine_divide_DIT( cpl_imagelist **cubesData,
248 const double *exptimes)
250 cpl_ensure_code(cubesData,CPL_ERROR_NULL_INPUT);
252 for (
int i = 0; i < n_cubes; i++) {
254 cpl_imagelist_divide_scalar(cubesData[i], exptimes[i]));
260 return cpl_error_get_code();
279cpl_error_code eris_ifu_combine_auto_size_cube(
const float *offsetx,
280 const float *offsety,
292 cpl_ensure_code(offsetx != NULL, CPL_ERROR_ILLEGAL_INPUT);
293 cpl_ensure_code(offsety != NULL, CPL_ERROR_ILLEGAL_INPUT);
294 cpl_ensure_code(nframes > 0, CPL_ERROR_ILLEGAL_INPUT);
295 cpl_ensure_code(*size_x >= 64, CPL_ERROR_ILLEGAL_INPUT);
296 cpl_ensure_code(*size_y >= 64, CPL_ERROR_ILLEGAL_INPUT);
298 cpl_msg_info (cpl_func,
"Computation of output cube size") ;
299 eris_ifu_combine_get_xy_min_max(nframes,
301 &min_offx, &max_offx,
302 &min_offy, &max_offy);
304 cpl_msg_info(cpl_func,
" max_offx = %f, max_offy = %f", max_offx, max_offy);
305 cpl_msg_info(cpl_func,
" min_offx = %f, min_offy = %f", min_offx, min_offy);
307 *ref_offx = (min_offx+max_offx)/2;
308 *ref_offy = (min_offy+max_offy)/2;
313 *size_x += 2*floor(max_offx-min_offx+0.5);
314 *size_y += 2*floor(max_offy-min_offy+0.5);
316 cpl_msg_info(cpl_func,
" Output cube size: %d x %d",*size_x,*size_y);
317 cpl_msg_info(cpl_func,
" Ref. offset x: %f, y: %f",*ref_offx,*ref_offy);
318 cpl_msg_info(cpl_func,
" Max. offset x: %f, y: %f",max_offx,max_offy);
319 cpl_msg_info(cpl_func,
" Min. offset x: %f, y: %f",min_offx,min_offy);
321 return cpl_error_get_code();
356cpl_error_code eris_ifu_combine_build_mask(cpl_imagelist **cubesDataShifted,
357 cpl_image *mergedImgDIT,
361 const double *exptimes)
367 cpl_image *imgCubesDataShifted = NULL;
368 double *pimgMergedCubeDIT = NULL;
370 cpl_ensure_code(llx != NULL, CPL_ERROR_NULL_INPUT);
371 cpl_ensure_code(lly != NULL, CPL_ERROR_NULL_INPUT);
372 cpl_ensure_code(exptimes != NULL, CPL_ERROR_NULL_INPUT);
373 cpl_ensure_code(cubesDataShifted != NULL, CPL_ERROR_NULL_INPUT);
374 cpl_ensure_code(mergedImgDIT != NULL, CPL_ERROR_NULL_INPUT);
376 nx_out = cpl_image_get_size_x(mergedImgDIT);
377 ny_out = cpl_image_get_size_y(mergedImgDIT);
379 pimgMergedCubeDIT = cpl_image_get_data_double(mergedImgDIT);
381 for (
int i = 0; i < n_cubes; i++) {
382 imgCubesDataShifted = cpl_imagelist_get(cubesDataShifted[i], 0);
383 nx_in = cpl_image_get_size_x(imgCubesDataShifted);
384 ny_in = cpl_image_get_size_y(imgCubesDataShifted);
387 for (
int y = 0; y < ny_out; y++) {
388 for (
int x = 0; x < nx_out; x++) {
391 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
392 (x >= llx[i]) && (x < llx[i]+nx_in))
394 pimgMergedCubeDIT[x+y*nx_out] += exptimes[i];
399 return cpl_error_get_code();
425cpl_error_code eris_ifu_combine_build_mask_cube(cpl_image **imagesDataShifted,
426 cpl_image **mergedImgDIT,
429 const double *exptimes,
438 double *pimgMergedCubeDIT = NULL,
439 *pimgCubesDataShifted = NULL;
440 cpl_image *imgCubesDataShifted = NULL;
441 cpl_error_code ret_err = CPL_ERROR_NONE;
443 cpl_ensure_code(llx != NULL, CPL_ERROR_NULL_INPUT);
444 cpl_ensure_code(lly != NULL, CPL_ERROR_NULL_INPUT);
445 cpl_ensure_code(exptimes != NULL, CPL_ERROR_NULL_INPUT);
446 cpl_ensure_code(imagesDataShifted != NULL, CPL_ERROR_NULL_INPUT);
447 cpl_ensure_code(mergedImgDIT != NULL, CPL_ERROR_NULL_INPUT);
451 *mergedImgDIT = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE));
453 pimgMergedCubeDIT = cpl_image_get_data_double(*mergedImgDIT));
455 for (
int i = 0; i < n_cubes; i++) {
456 imgCubesDataShifted = imagesDataShifted[i];
458 pimgCubesDataShifted = cpl_image_get_data_double(imgCubesDataShifted));
459 nx_in = cpl_image_get_size_x(imgCubesDataShifted);
460 ny_in = cpl_image_get_size_y(imgCubesDataShifted);
463 for (
int y = 0; y < ny_out; y++) {
464 for (
int x = 0; x < nx_out; x++) {
467 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
468 (x >= llx[i]) && (x < llx[i]+nx_in))
471 !cpl_image_is_rejected(imgCubesDataShifted, x_in+1, y_in+1))
473 pimgMergedCubeDIT[x+y*nx_out] += exptimes[i];
489 ret_err = cpl_error_get_code();
520cpl_error_code eris_ifu_combine_coadd_ks_clip(
const int n_frames,
524 const double *exptimes,
525 cpl_image **imgMergedCubeData,
526 cpl_image **imgMergedCubeError,
527 cpl_image *mergedImgDIT,
528 cpl_image **imagesDataShifted,
529 cpl_image **imagesErrorShifted,
530 const char *compute_mode,
535 int n_contributes = 0,
541 double *pimgCubesDataShifted = NULL,
542 *pimgCubesErrorShifted = NULL,
543 *pimgMergedCubeData = NULL,
544 *pimgMergedCubeError = NULL,
545 *pmergedImgDIT = NULL;
546 cpl_vector *msk = NULL,
548 eris_ifu_vector *data_vec = NULL,
552 nx_in = cpl_image_get_size_x(imagesDataShifted[0]);
553 ny_in = cpl_image_get_size_y(imagesDataShifted[0]);
556 (nx_out != cpl_image_get_size_x(mergedImgDIT)) ||
557 (ny_out != cpl_image_get_size_y(mergedImgDIT))
560 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
561 return cpl_error_get_code();
565 *imgMergedCubeData = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE));
567 pimgMergedCubeData = cpl_image_get_data_double(*imgMergedCubeData));
570 *imgMergedCubeError = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE));
572 pimgMergedCubeError = cpl_image_get_data_double(*imgMergedCubeError));
575 pmergedImgDIT = cpl_image_get_data_double(mergedImgDIT));
577 for (
int y = 0; y < ny_out; y++) {
578 for (
int x = 0; x < nx_out; x++) {
579 n_contributes = eris_ifu_combine_calc_contributions(imagesDataShifted,
582 if (n_contributes > 0) {
583 msk = cpl_vector_new(n_frames);
584 for (
int i = 0; i < n_frames; i++) {
585 cpl_vector_set(msk, i, 1);
589 eris_ifu_combine_coadd_ks_clip_internal(imagesDataShifted, n_frames,
591 llx, lly, kappa, &msk,
592 compute_mode, pclip));
594 if (!strcmp(compute_mode,
"MEDIAN")){
596 val = cpl_vector_new(n_frames);
603 for (
int i = 0; i < n_frames; i++) {
604 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
605 (x >= llx[i]) && (x < llx[i]+nx_in))
607 pimgCubesDataShifted = cpl_image_get_data_double(imagesDataShifted[i]);
608 pimgCubesErrorShifted = cpl_image_get_data_double(imagesErrorShifted[i]);
613 if (!isnan(pimgCubesDataShifted[posx+posy*nx_in]) &&
614 (fabs(pimgCubesDataShifted[posx+posy*nx_in]) > DBL_ZERO_TOLERANCE) &&
615 (fabs(pmergedImgDIT[x+y*nx_out]) > DBL_ZERO_TOLERANCE) &&
616 (cpl_vector_get(msk, i) != 0))
618 if (!strcmp(compute_mode,
"MEDIAN")) {
620 cpl_vector_set(val, ovr, pimgCubesDataShifted[posx+posy*nx_in]);
624 pimgMergedCubeData[x+y*nx_out] += pimgCubesDataShifted[posx+posy*nx_in] * exptimes[i];
641 pimgMergedCubeError[x+y*nx_out] = eris_ifu_combine_calc_error(data_vec, err_vec, compute_mode);
645 if (!strcmp(compute_mode,
"MEDIAN")) {
648 cpl_vector *tval = cpl_vector_extract(val, 0, ovr-1, 1);
649 pimgMergedCubeData[x+y*nx_out] = cpl_vector_get_median_const(tval);
655 pimgMergedCubeData[x+y*nx_out] /= pmergedImgDIT[x+y*nx_out];
670 return cpl_error_get_code();
691cpl_error_code eris_ifu_combine_coadd_ks_clip_internal(cpl_image** imagesDataShifted,
693 const int n_contributions,
700 const char *compute_mode,
718 cpl_vector *val = NULL;
719 cpl_error_code ret_err = CPL_ERROR_NONE;
722 nx = cpl_image_get_size_x(imagesDataShifted[0]);
723 ny = cpl_image_get_size_y(imagesDataShifted[0]);
725 for (
int ks = 0; ks < n_contributions; ks++) {
730 if (n_contributions-nclip > 0) {
731 val = cpl_vector_new(n_contributions-nclip);
737 for (
int i = 0; i < n_frames; i++) {
738 pimg_in = cpl_image_get_data_double(imagesDataShifted[i]);
745 if ((y >= loy) && (y < upy) && (x >= lox) && (x < upx)) {
750 if (!isnan(pimg_in[pos]) &&
751 (fabs(pimg_in[pos]) > DBL_ZERO_TOLERANCE) &&
752 (cpl_vector_get(*msk, i) != 0))
755 cpl_vector_set(val, ovr, pimg_in[pos]));
763 if (!strcmp(compute_mode,
"MEDIAN")) {
764 med=cpl_vector_get_median(val);
766 med = cpl_vector_get_mean(val);
770 if ((ks == 0) && (pclip < 100) && (pclip > 0)) {
771 med = cpl_vector_get_median(val);
772 cpl_vector_subtract_scalar(val, med);
773 cpl_vector_power(val, 2);
774 cpl_vector_sqrt(val);
775 cpl_vector_sort(val, CPL_SORT_ASCENDING);
776 pk = round(pclip/100.0*(cpl_vector_get_size(val)-1));
777 sig = cpl_vector_get(val, pk) / kappa;
779 if (!strcmp(compute_mode,
"MEDIAN")){
780 cpl_vector_subtract_scalar(val, med);
781 cpl_vector_power(val, 2);
782 cpl_vector_sqrt(val);
783 sig = 1.4826 * cpl_vector_get_median(val);
785 sig=cpl_vector_get_stdev(val);
789 for (
int i = 0 ; i < n_frames; i++) {
790 pimg_in = cpl_image_get_data_double(imagesDataShifted[i]);
798 if ((y >= loy) && (y < upy) && (x >= lox) && (x < upx)) {
803 if (!isnan(pimg_in[pos]) &&
804 (fabs(pimg_in[pos]) > DBL_ZERO_TOLERANCE) &&
805 (cpl_vector_get(*msk,i) != 0))
807 if(fabs((pimg_in[pos]-med)) > kappa*sig)
812 cpl_image_reject(imagesDataShifted[i], posx+1, posy+1);
813 cpl_vector_set(*msk, i, 0);
824 ret_err = cpl_error_get_code();
855cpl_error_code eris_ifu_combine_coadd(
const int n_cubes,
856 cpl_image **imgMergedCubeData,
857 cpl_image **imgMergedCubeError,
858 cpl_image *mergedImgDIT,
859 cpl_image **imagesDataShifted,
860 cpl_image **imagesErrorShifted,
861 const double *exptimes,
864 const char *compute_mode,
873 double *pimgCubesDataShifted = NULL,
874 *pimgCubesErrorShifted = NULL,
875 *pimgMergedCubeData = NULL,
876 *pimgMergedCubeError = NULL,
877 *pmergedImgDIT = NULL;
878 cpl_vector *val = NULL;
879 eris_ifu_vector *data_vec = NULL,
882 nx_in = cpl_image_get_size_x(imagesDataShifted[0]);
883 ny_in = cpl_image_get_size_y(imagesDataShifted[0]);
886 (nx_out != cpl_image_get_size_x(mergedImgDIT)) ||
887 (ny_out != cpl_image_get_size_y(mergedImgDIT))
890 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
891 return cpl_error_get_code();
894 *imgMergedCubeData = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE);
895 pimgMergedCubeData = cpl_image_get_data_double(*imgMergedCubeData);
897 *imgMergedCubeError = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE);
898 pimgMergedCubeError = cpl_image_get_data_double(*imgMergedCubeError);
900 pmergedImgDIT = cpl_image_get_data_double(mergedImgDIT);
902 for (
int y = 0; y < ny_out; y++) {
903 for (
int x = 0; x < nx_out; x++) {
904 if (!strcmp(compute_mode,
"MEDIAN")) {
906 val = cpl_vector_new(n_cubes);
913 for (
int i = 0; i < n_cubes; i++) {
914 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
915 (x >= llx[i]) && (x < llx[i]+nx_in))
917 pimgCubesDataShifted = cpl_image_get_data_double(imagesDataShifted[i]);
918 pimgCubesErrorShifted = cpl_image_get_data_double(imagesErrorShifted[i]);
923 if (!isnan(pimgCubesDataShifted[posx+posy*nx_in]) &&
924 (fabs(pimgCubesDataShifted[posx+posy*nx_in]) > DBL_ZERO_TOLERANCE) &&
925 (fabs(pmergedImgDIT[x+y*nx_out]) > DBL_ZERO_TOLERANCE))
928 if (!strcmp(compute_mode,
"MEDIAN")) {
930 cpl_vector_set(val, ovr, pimgCubesDataShifted[posx+posy*nx_in]);
934 pimgMergedCubeData[x+y*nx_out] += pimgCubesDataShifted[posx+posy*nx_in] * exptimes[i];
951 pimgMergedCubeError[x+y*nx_out] = eris_ifu_combine_calc_error(data_vec, err_vec, compute_mode);
956 if (!strcmp(compute_mode,
"MEDIAN")){
959 cpl_vector *tval = cpl_vector_extract(val, 0, ovr-1, 1);
960 pimgMergedCubeData[x+y*nx_out] = cpl_vector_get_median_const(tval);
966 pimgMergedCubeData[x+y*nx_out] /= pmergedImgDIT[x+y*nx_out];
971 return cpl_error_get_code();
974int eris_ifu_combine_calc_contributions(cpl_image **imagesDataShifted,
976 const int* llx,
const int* lly,
977 const int x,
const int y)
979 int n_contributes = 0,
991 nx = cpl_image_get_size_x(imagesDataShifted[0]);
992 ny = cpl_image_get_size_y(imagesDataShifted[0]);
996 for (
int i = 0; i < n_frames; i++) {
997 pimg = cpl_image_get_data_double(imagesDataShifted[i]);
1004 if ((y >= loy) && (y < upy) && (x >= lox) && (x < upx)) {
1009 if (!isnan(pimg[pos]) && (fabs(pimg[pos]) > DBL_ZERO_TOLERANCE)) {
1015 return n_contributes;
1024cpl_error_code eris_ifu_combine_subtract_background(cpl_image *img,
1027 double local_median = 0.;
1028 cpl_error_code err = CPL_ERROR_NONE;
1030 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1034 cpl_image_reject_value(img, CPL_VALUE_NOTFINITE));
1036 local_median = cpl_image_get_median(img);
1037 if (cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) {
1043 if (!isnan(local_median)) {
1045 cpl_image_subtract_scalar(img, local_median));
1052 err = cpl_error_get_code();
1069void eris_ifu_combine_get_xy_min_max(
const int nframes,
1070 const float *offsetx,
const float *offsety,
1071 float *min_offx,
float *max_offx,
1072 float *min_offy,
float *max_offy)
1077 for (
int n = 0; n < nframes; n++) {
1086 if(offx > *max_offx)
1088 if(offy > *max_offy)
1090 if(offx < *min_offx)
1092 if(offy < *min_offy)
1106int eris_ifu_combine_nearest_int(
const double x)
1111 if ((x - (
double)k) <= 0.5) {
1117 if ((x - (
double)k) <= -0.5) {
1154cpl_image* eris_ifu_combine_shift_image(
const cpl_image *img_in,
1155 const double shift_x,
1156 const double shift_y,
1157 const double *kernel)
1159 cpl_image *img_shifted = NULL;
1162 int samples = KERNEL_SAMPLES,
1176 *pimg_shifted = NULL;
1177 const double *pimg_in = NULL;
1179 cpl_ensure(img_in != NULL, CPL_ERROR_NULL_INPUT, NULL);
1180 cpl_ensure(kernel != NULL, CPL_ERROR_NULL_INPUT, NULL);
1183 if ((fabs(shift_x) < 1e-2) && (fabs(shift_y) < 1e-2))
1184 return cpl_image_duplicate(img_in);
1186 nx = cpl_image_get_size_x(img_in);
1187 ny = cpl_image_get_size_y(img_in);
1189 pimg_in = cpl_image_get_data_double_const(img_in);
1190 if (pimg_in != NULL) {
1191 first_pass = cpl_calloc(nx, ny*
sizeof(
double));
1192 img_shifted = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
1193 pimg_shifted = cpl_image_get_data_double(img_shifted);
1194 for (
int y = 0; y < (int)ny; y++) {
1195 for (
int x = 1; x < (int)nx-2; x++) {
1196 fx = (double)x - shift_x;
1198 rx = fx - (double)px;
1199 pos = px + y * (int)nx;
1201 if ((px>1) && (px<(nx-3))) {
1202 tabx = (int)(fabs(mid * rx));
1206 value = pimg_in[pos-1] * kernel[mid+tabx] +
1207 pimg_in[pos] * kernel[tabx] +
1208 pimg_in[pos+1] * kernel[mid-tabx] +
1209 pimg_in[pos+2] * kernel[samples-tabx-1];
1213 norm = kernel[mid+tabx] +
1216 kernel[samples-tabx-1];
1218 if (fabs(norm) > 1e-4) {
1226 first_pass[x+y*nx] = value;
1230 for (
int x = 0; x < (int)nx; x++) {
1231 for (
int y = 1; y < (int)ny-3; y++) {
1232 fy = (double)y - shift_y;
1234 ry = fy - (double)py ;
1237 if ((py > 1) && (py < ((int)ny-2))) {
1238 taby = (int)(fabs((
double)mid * ry));
1242 value = first_pass[pos-nx] * kernel[mid+taby] +
1243 first_pass[pos] * kernel[taby] +
1244 first_pass[pos+nx] * kernel[mid-taby] +
1245 first_pass[pos+2*nx]*kernel[samples-taby-1];
1249 norm = kernel[mid+taby] +
1252 kernel[samples-taby-1];
1254 if (fabs(norm) > 1e-4) {
1260 pimg_shifted[x+y*nx] = value;
1264 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT);
1265 cpl_msg_error(cpl_func,
"Cannot get a data from an image");
1270 cpl_free(first_pass); first_pass = NULL;
1279void eris_ifu_combine_convert_0_to_NaN_img(cpl_image *img)
1283 double *pimg = NULL;
1286 pimg = cpl_image_get_data_double(img);
1288 nx = cpl_image_get_size_x(img);
1289 ny = cpl_image_get_size_y(img);
1291 for (
int i = 0 ; i < nx*ny; i++) {
1292 if (fabs(pimg[i]) < DBL_ZERO_TOLERANCE) {
1299double eris_ifu_combine_calc_error(eris_ifu_vector *data_vec,
1300 eris_ifu_vector *err_vec,
1301 const char *compute_mode)
1303 double std_err = 0.,
1306 cpl_ensure_code(data_vec != NULL, CPL_ERROR_NULL_INPUT);
1307 cpl_ensure_code(err_vec != NULL, CPL_ERROR_NULL_INPUT);
1315 if (!strcmp(compute_mode,
"MEDIAN")) {
1320 std_err = std_dev / sqrt(vec_size);
1324 if (vec_size == 1) {
1330 }
else if (vec_size == 2) {
1331 double tmp_dbl = 0.;
1345 std_dev = tmp_dbl / 2;
1346 std_err = std_dev / sqrt(2);
1361double** matrix(
int nrow,
int ncol) {
1362 double **matrix = (
double**)cpl_malloc((
size_t)((nrow)*
sizeof(
double*)));
1364 for(
int i = 0; i < nrow; i++) {
1365 matrix[i] = (
double *) cpl_malloc((
size_t)((ncol)*
sizeof(
double)));
1371void free_matrix(
double **matrix,
int nrow) {
1372 for(
int i = 0; i < nrow; i++) {
1373 cpl_free(matrix[i]); matrix[i] = NULL;
1375 cpl_free(matrix); matrix = NULL;
1390cpl_error_code eris_ifu_reject_nan(cpl_image *img)
1392 cpl_error_code err = CPL_ERROR_NONE;
1398 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1402 nx = cpl_image_get_size_x(img);
1403 ny = cpl_image_get_size_y(img);
1406 for (
int ix = 1; ix <= nx; ix++) {
1407 for (
int iy = 1; iy <= ny; iy++) {
1408 tmp = cpl_image_get(img, ix, iy, &is_rej);
1411 if (!is_rej && isnan(tmp)) {
1413 cpl_image_reject(img, ix, iy));
1418 err = cpl_error_get_code();
1472cpl_image* eris_ifu_combine_shift_image_kmos(
const cpl_image *img_in,
1476 const enum extrapolationType extrapolation)
1478 const double *pimg_in = NULL;
1479 double **array_in = NULL,
1482 cpl_image *img_out = NULL;
1488 cpl_ensure(img_in != NULL, CPL_ERROR_NULL_INPUT, NULL);
1489 cpl_ensure((extrapolation == NONE_NANS) ||
1490 (extrapolation == NONE_CLIPPING)
1492, CPL_ERROR_ILLEGAL_INPUT, NULL);
1495 if ((xshift == 0.0) && (yshift == 0.0)) {
1498 img_out = cpl_image_duplicate(img_in));
1500 xdim = cpl_image_get_size_x(img_in);
1501 ydim = cpl_image_get_size_y(img_in);
1503 pimg_in = cpl_image_get_data_double_const(img_in);
1505 array_in = matrix(xdim, ydim);
1506 for (
int j = 0; j < ydim ; j++) {
1507 for (
int i = 0; i < xdim ; i++) {
1508 if (isnan(pimg_in[i + j*xdim]))
1512 array_in[i][j] = pimg_in[i + j*xdim];
1534if (strcmp(method,
"NN") == 0) {
1535 if (fabs(xshift) > 1.0 || fabs(yshift) > 1.0) {
1537 "Neither xshift nor yshift are allowed to "
1538 "be greater than 1 pixel for NN");
1544 }
else if (xshift < -0.5) {
1551 }
else if (yshift < -0.5) {
1556 array_out = matrix(xdim,ydim);
1557 for (
int j = 0; j < ydim; j++) {
1558 for (
int i = 0; i < xdim; i++) {
1559 int xix = i+xoffset,
1561 if (xix < 0 || xix >= xdim || yix < 0 || yix >= ydim) {
1562 array_out[i][j] = NAN;
1564 array_out[i][j] = array_in[i+xoffset][j+yoffset];
1570 "Unknown value for interpolation method");
1572 free_matrix(array_in, xdim);
1574 switch (extrapolation) {
1586 xdim_new = xdim - lrintf(ceill(fabsl(xshift)));
1587 ydim_new = xdim - lrintf(ceill(fabsl(yshift)));
1589 pimg_out = cpl_malloc(xdim_new * ydim_new *
sizeof(
double)));
1590 int xmin = - floorl(xshift);
1593 int xmax = xdim - ceill(xshift);
1596 int ymin = - floorl(yshift);
1599 int ymax = ydim - ceill(yshift);
1602 for (
int j = ymin; j < ymax; j++) {
1603 for (
int i = xmin; i < xmax; i++) {
1604 pimg_out[(i - xmin) + (j - ymin) * xdim_new] = array_out[i][j];
1612 pimg_out = cpl_malloc(xdim * ydim *
sizeof(
double)));
1613 float xxmin = 0 - xshift;
1614 float xxmax = xdim - 1 - xshift;
1615 float yymin = 0 - yshift;
1616 float yymax = ydim - 1 - yshift;
1617 for (
int j = 0; j < ydim; j++) {
1618 for (
int i = 0; i < xdim; i++) {
1619 if ((i < xxmin ) || (i > xxmax) ||
1620 (j < yymin ) || (j > yymax))
1622 pimg_out[i+j*xdim] = NAN;
1624 pimg_out[i+j*xdim] = array_out[i][j];
1631 "Unknown value for extrapolation type");
1634 free_matrix(array_out, xdim);
1635 img_out = cpl_image_wrap_double(xdim_new, ydim_new, pimg_out);
1639 eris_ifu_reject_nan(img_out));
1651cpl_error_code eris_ifu_combine_read_image_planes(
const cpl_frameset *frameset,
1652 cpl_image **imagesData,
1653 cpl_image **imagesError,
1656 bool subtract_background)
1658 cpl_size nframes = 0,
1663 cpl_error_code err = CPL_ERROR_NONE;
1664 const cpl_frame *frame = NULL;
1665 cpl_mask *tmp_mask = NULL;
1666 cpl_image *cube_qual_tmp = NULL;
1667 cpl_propertylist *plist = NULL;
1668 const char *name = NULL;
1674 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
1677 nframes = cpl_frameset_get_size(frameset);
1680 for (cpl_size n = 0; n < nframes; n++) {
1682 frame = cpl_frameset_get_position_const(frameset, n));
1684 name = cpl_frame_get_filename(frame));
1685 if (edge_trim > 0) {
1687 plist = cpl_propertylist_load(name, 1));
1693 llx = 1 + edge_trim;
1694 lly = 1 + edge_trim;
1695 urx = tmp_size_x - edge_trim;
1696 ury = tmp_size_y - edge_trim;
1699 imagesData[n] = cpl_image_load_window(name, CPL_TYPE_DOUBLE, z, 1, llx, lly, urx, ury));
1701 imagesError[n] = cpl_image_load_window(name, CPL_TYPE_DOUBLE, z, 2, llx, lly, urx, ury));
1703 cube_qual_tmp = cpl_image_load_window(name, CPL_TYPE_DOUBLE, z, 3, llx, lly, urx, ury));
1707 imagesData[n] = cpl_image_load(name, CPL_TYPE_DOUBLE, z, 1));
1709 imagesError[n] = cpl_image_load(name, CPL_TYPE_DOUBLE, z, 2));
1711 cube_qual_tmp = cpl_image_load(name, CPL_TYPE_DOUBLE, z, 3));
1716 tmp_mask = cpl_mask_threshold_image_create(cube_qual_tmp, 0, INT_MAX));
1718 cpl_image_reject_from_mask(imagesData[n], tmp_mask));
1720 cpl_image_reject_from_mask(imagesError[n], tmp_mask));
1724 if (subtract_background) {
1726 eris_ifu_combine_subtract_background(imagesData[n], &warn));
1727 if (warn && !warned) {
1729 cpl_msg_warning(cpl_func,
" local_median is NAN in %dth plane", z);
1736 err = cpl_error_get_code();
1750int eris_ifu_combine_min_cube_size(
const cpl_frameset *fs) {
1759 const char *name = NULL;
1760 const cpl_frame *fr = NULL;
1761 cpl_propertylist *pl = NULL;
1763 cpl_ensure(fs != NULL, CPL_ERROR_NULL_INPUT, -1);
1767 cpl_frameset_iterator *iter = NULL;
1769 iter = cpl_frameset_iterator_new(fs));
1770 fr = cpl_frameset_iterator_get(iter);
1773 name = cpl_frame_get_filename(fr));
1777 pl = cpl_propertylist_load(name, 1));
1778 naxis3 = cpl_propertylist_get_int( pl, NAXIS3);
1779 crpix3 = cpl_propertylist_get_double(pl, CRPIX3);
1780 crval3 = cpl_propertylist_get_double(pl, CRVAL3);
1781 cd3_3 = cpl_propertylist_get_double(pl, CD3_3);
1786 cpl_frameset_iterator_advance(iter, 1));
1787 fr = cpl_frameset_iterator_get(iter);
1790 while (fr != NULL) {
1792 name = cpl_frame_get_filename(fr));
1795 pl = cpl_propertylist_load(name, 1));
1797 naxis3_tmp = cpl_propertylist_get_int( pl, NAXIS3);
1798 crpix3_tmp = cpl_propertylist_get_double(pl, CRPIX3);
1799 crval3_tmp = cpl_propertylist_get_double(pl, CRVAL3);
1800 cd3_3_tmp = cpl_propertylist_get_double(pl, CD3_3);
1804 if ((fabs(crpix3 - crpix3_tmp) > DBL_ZERO_TOLERANCE) ||
1805 (fabs(crval3 - crval3_tmp) > DBL_ZERO_TOLERANCE) ||
1806 (fabs(cd3_3 - cd3_3_tmp) > DBL_ZERO_TOLERANCE))
1809 "WCS not matching for all frames!");
1812 if (naxis3_tmp < naxis3) {
1813 naxis3 = naxis3_tmp;
1817 cpl_frameset_iterator_advance(iter, 1));
1818 fr = cpl_frameset_iterator_get(iter);
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#define RECOVER(void)
Recover the error state which was present during TRY (at the beginning of the try-block).
#define CHECK_ERROR_STATE(void)
Check the CPL error state, and exit the try-block if not CPL_ERROR_NONE.
#define BRK_WITH_ERROR_MSG(code,...)
Set a new CPL error, and exit the try-block.
#define TRY
Beginning of a TRY-block.
#define CATCH
End of a TRY-block, beginning of a CATCH-block.
#define BRK_IF_NULL(function)
If function is or returns a NULL pointer, then the try-block is exited.
#define CATCH_MSGS()
Displays an error message stack.
void eris_ifu_free_propertylist(cpl_propertylist **item)
free memory and set pointer to null
void eris_ifu_free_vector(cpl_vector **item)
free memory and set pointer to null
void eris_ifu_free_image(cpl_image **item)
free memory and set pointer to null
void eris_ifu_free_mask(cpl_mask **item)
free memory and set pointer to null
double eris_ifu_vector_get_stdev_median(const eris_ifu_vector *ev)
Compute the bias-corrected standard deviation of a vectors elements using median.
int eris_ifu_is_nan_or_inf(double A)
Checks if a value is nan, inf or -inf.
eris_ifu_vector * eris_ifu_vector_new(int n)
Create a new eris_ifu_vector.
double eris_ifu_vector_get_stdev(const eris_ifu_vector *ev)
Compute the bias-corrected standard deviation of a vectors elements.
int eris_ifu_vector_is_rejected(const eris_ifu_vector *ev, int n)
Test if a value is good or bad.
int eris_ifu_vector_count_non_rejected(const eris_ifu_vector *ev)
Count the number of non-rejected elements in a eris_ifu_vector.
cpl_error_code eris_ifu_vector_set(eris_ifu_vector *ev, int pos, double val)
Set an element of the eris_ifu_vector.
double eris_ifu_vector_get(const eris_ifu_vector *ev, int pos)
Get an element of the eris_ifu_vector.
void eris_ifu_vector_delete(eris_ifu_vector *ev)
Delete a eris_ifu_vector.
cpl_error_code eris_ifu_vector_reject(eris_ifu_vector *ev, int n)
Set a value as rejected in a eris_ifu_vector.
int eris_pfits_get_naxis2(const cpl_propertylist *plist)
find out the character string associated to the NAXIS2 keyword
int eris_pfits_get_naxis1(const cpl_propertylist *plist)
find out the character string associated to the NAXIS1 keyword