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"
84 cpl_image **imagesData,
85 cpl_image **imagesError,
88 cpl_image **mergedImageData,
89 cpl_image **mergedImageError,
90 cpl_image **mergedImageDIT,
94 const double *exptimes,
96 const char *compute_mode,
107 float *sub_offsetx = NULL,
109 cpl_image **imagesDataShifted = NULL,
110 **imagesErrorShifted = NULL;
111 cpl_error_code ret_err = CPL_ERROR_NONE;
113 cpl_ensure_code(imagesData != NULL, CPL_ERROR_NULL_INPUT);
114 cpl_ensure_code(imagesError != NULL, CPL_ERROR_NULL_INPUT);
115 cpl_ensure_code(mergedImageData != NULL, CPL_ERROR_NULL_INPUT);
116 cpl_ensure_code(mergedImageError != NULL, CPL_ERROR_NULL_INPUT);
117 cpl_ensure_code(mergedImageDIT != NULL, CPL_ERROR_NULL_INPUT);
118 cpl_ensure_code(offsetx != NULL, CPL_ERROR_NULL_INPUT);
119 cpl_ensure_code(offsety != NULL, CPL_ERROR_NULL_INPUT);
120 cpl_ensure_code(exptimes != NULL, CPL_ERROR_NULL_INPUT);
121 cpl_ensure_code(compute_mode != NULL, CPL_ERROR_NULL_INPUT);
124 nx_in = cpl_image_get_size_x(imagesData[0]);
125 ny_in = cpl_image_get_size_y(imagesData[0]);
132 llx0 = (int)((
double)(nx_out - nx_in) / 2.0 + 0.5);
133 lly0 = (int)((
double)(ny_out - ny_in) / 2.0 + 0.5);
138 llx = cpl_calloc(n_cubes,
sizeof(
int));
139 lly = cpl_calloc(n_cubes,
sizeof(
int));
140 sub_offsetx = cpl_calloc(n_cubes,
sizeof(
float));
141 sub_offsety = cpl_calloc(n_cubes,
sizeof(
float));
144 for (
int i = 0; i < n_cubes; i++) {
151 if (llx[i] < min_lx) {
154 if (lly[i] < min_ly) {
162 for (
int i = 0 ; i < n_cubes ; i++ ) {
163 llx[i] = llx[i] - min_lx;
167 for (
int i = 0 ; i < n_cubes ; i++ ) {
168 lly[i] = lly[i] - min_ly;
177 imagesDataShifted = (cpl_image**)cpl_calloc(n_cubes,
sizeof(cpl_imagelist*)));
179 imagesErrorShifted = (cpl_image**)cpl_calloc(n_cubes,
sizeof(cpl_imagelist*)));
181 for (
int i = 0; i < n_cubes; i++) {
185 sub_offsetx[i], sub_offsety[i],
190 sub_offsetx[i], sub_offsety[i],
202 if ((kappa != -1) && (pclip != -1)) {
207 kappa, llx, lly, exptimes,
208 mergedImageData, mergedImageError, *mergedImageDIT,
209 imagesDataShifted, imagesErrorShifted,
210 compute_mode, pclip, nx_out, ny_out));
216 mergedImageData, mergedImageError, *mergedImageDIT,
217 imagesDataShifted, imagesErrorShifted,
219 llx, lly, compute_mode, nx_out, ny_out));
223 ret_err = cpl_error_get_code();
230 for (
int i = 0; i < n_cubes; i++) {
235 cpl_free(imagesDataShifted); imagesDataShifted = NULL;
236 cpl_free(imagesErrorShifted); imagesErrorShifted = NULL;
237 cpl_free(llx); llx = NULL;
238 cpl_free(lly); lly = NULL;
239 cpl_free(sub_offsetx); sub_offsetx = NULL;
240 cpl_free(sub_offsety); sub_offsety = NULL;
258 const double *exptimes)
260 cpl_ensure_code(cubesData,CPL_ERROR_NULL_INPUT);
262 for (
int i = 0; i < n_cubes; i++) {
264 cpl_imagelist_divide_scalar(cubesData[i], exptimes[i]));
270 return cpl_error_get_code();
292 const float *offsety,
304 cpl_ensure_code(offsetx != NULL, CPL_ERROR_ILLEGAL_INPUT);
305 cpl_ensure_code(offsety != NULL, CPL_ERROR_ILLEGAL_INPUT);
306 cpl_ensure_code(nframes > 0, CPL_ERROR_ILLEGAL_INPUT);
307 cpl_ensure_code(*size_x >= 64, CPL_ERROR_ILLEGAL_INPUT);
308 cpl_ensure_code(*size_y >= 64, CPL_ERROR_ILLEGAL_INPUT);
310 cpl_msg_info (cpl_func,
"Computation of output cube size") ;
313 &min_offx, &max_offx,
314 &min_offy, &max_offy);
316 cpl_msg_info(cpl_func,
" max_offx = %f, max_offy = %f", max_offx, max_offy);
317 cpl_msg_info(cpl_func,
" min_offx = %f, min_offy = %f", min_offx, min_offy);
319 *ref_offx = (min_offx+max_offx)/2;
320 *ref_offy = (min_offy+max_offy)/2;
325 *size_x += 2*floor(max_offx-min_offx+0.5);
326 *size_y += 2*floor(max_offy-min_offy+0.5);
328 cpl_msg_info(cpl_func,
" Output cube size: %d x %d",*size_x,*size_y);
329 cpl_msg_info(cpl_func,
" Ref. offset x: %f, y: %f",*ref_offx,*ref_offy);
330 cpl_msg_info(cpl_func,
" Max. offset x: %f, y: %f",max_offx,max_offy);
331 cpl_msg_info(cpl_func,
" Min. offset x: %f, y: %f",min_offx,min_offy);
333 return cpl_error_get_code();
364 cpl_image *mergedImgDIT,
368 const double *exptimes)
374 cpl_image *imgCubesDataShifted = NULL;
375 double *pimgMergedCubeDIT = NULL;
377 cpl_ensure_code(llx != NULL, CPL_ERROR_NULL_INPUT);
378 cpl_ensure_code(lly != NULL, CPL_ERROR_NULL_INPUT);
379 cpl_ensure_code(exptimes != NULL, CPL_ERROR_NULL_INPUT);
380 cpl_ensure_code(cubesDataShifted != NULL, CPL_ERROR_NULL_INPUT);
381 cpl_ensure_code(mergedImgDIT != NULL, CPL_ERROR_NULL_INPUT);
383 nx_out = cpl_image_get_size_x(mergedImgDIT);
384 ny_out = cpl_image_get_size_y(mergedImgDIT);
386 pimgMergedCubeDIT = cpl_image_get_data_double(mergedImgDIT);
388 for (
int i = 0; i < n_cubes; i++) {
389 imgCubesDataShifted = cpl_imagelist_get(cubesDataShifted[i], 0);
390 nx_in = cpl_image_get_size_x(imgCubesDataShifted);
391 ny_in = cpl_image_get_size_y(imgCubesDataShifted);
394 for (
int y = 0; y < ny_out; y++) {
395 for (
int x = 0; x < nx_out; x++) {
398 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
399 (x >= llx[i]) && (x < llx[i]+nx_in))
401 pimgMergedCubeDIT[x+y*nx_out] += exptimes[i];
406 return cpl_error_get_code();
430 cpl_image **mergedImgDIT,
433 const double *exptimes,
442 double *pimgMergedCubeDIT = NULL,
443 *pimgCubesDataShifted = NULL;
444 cpl_image *imgCubesDataShifted = NULL;
445 cpl_error_code ret_err = CPL_ERROR_NONE;
447 cpl_ensure_code(llx != NULL, CPL_ERROR_NULL_INPUT);
448 cpl_ensure_code(lly != NULL, CPL_ERROR_NULL_INPUT);
449 cpl_ensure_code(exptimes != NULL, CPL_ERROR_NULL_INPUT);
450 cpl_ensure_code(imagesDataShifted != NULL, CPL_ERROR_NULL_INPUT);
451 cpl_ensure_code(mergedImgDIT != NULL, CPL_ERROR_NULL_INPUT);
455 *mergedImgDIT = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE));
457 pimgMergedCubeDIT = cpl_image_get_data_double(*mergedImgDIT));
459 for (
int i = 0; i < n_cubes; i++) {
460 imgCubesDataShifted = imagesDataShifted[i];
462 pimgCubesDataShifted = cpl_image_get_data_double(imgCubesDataShifted));
463 nx_in = cpl_image_get_size_x(imgCubesDataShifted);
464 ny_in = cpl_image_get_size_y(imgCubesDataShifted);
467 for (
int y = 0; y < ny_out; y++) {
468 for (
int x = 0; x < nx_out; x++) {
471 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
472 (x >= llx[i]) && (x < llx[i]+nx_in))
475 !cpl_image_is_rejected(imgCubesDataShifted, x_in+1, y_in+1))
477 pimgMergedCubeDIT[x+y*nx_out] += exptimes[i];
493 ret_err = cpl_error_get_code();
531 const double *exptimes,
532 cpl_image **imgMergedCubeData,
533 cpl_image **imgMergedCubeError,
534 cpl_image *mergedImgDIT,
535 cpl_image **imagesDataShifted,
536 cpl_image **imagesErrorShifted,
537 const char *compute_mode,
542 int n_contributes = 0,
548 double *pimgCubesDataShifted = NULL,
549 *pimgCubesErrorShifted = NULL,
550 *pimgMergedCubeData = NULL,
551 *pimgMergedCubeError = NULL,
552 *pmergedImgDIT = NULL;
553 cpl_vector *msk = NULL,
555 eris_ifu_vector *data_vec = NULL,
559 nx_in = cpl_image_get_size_x(imagesDataShifted[0]);
560 ny_in = cpl_image_get_size_y(imagesDataShifted[0]);
563 (nx_out != cpl_image_get_size_x(mergedImgDIT)) ||
564 (ny_out != cpl_image_get_size_y(mergedImgDIT))
567 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
568 return cpl_error_get_code();
572 *imgMergedCubeData = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE));
574 pimgMergedCubeData = cpl_image_get_data_double(*imgMergedCubeData));
577 *imgMergedCubeError = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE));
579 pimgMergedCubeError = cpl_image_get_data_double(*imgMergedCubeError));
582 pmergedImgDIT = cpl_image_get_data_double(mergedImgDIT));
584 for (
int y = 0; y < ny_out; y++) {
585 for (
int x = 0; x < nx_out; x++) {
589 if (n_contributes > 0) {
590 msk = cpl_vector_new(n_frames);
591 for (
int i = 0; i < n_frames; i++) {
592 cpl_vector_set(msk, i, 1);
598 llx, lly, kappa, &msk,
599 compute_mode, pclip));
601 if (!strcmp(compute_mode,
"MEDIAN")){
603 val = cpl_vector_new(n_frames);
610 for (
int i = 0; i < n_frames; i++) {
611 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
612 (x >= llx[i]) && (x < llx[i]+nx_in))
614 pimgCubesDataShifted = cpl_image_get_data_double(imagesDataShifted[i]);
615 pimgCubesErrorShifted = cpl_image_get_data_double(imagesErrorShifted[i]);
620 if (!isnan(pimgCubesDataShifted[posx+posy*nx_in]) &&
621 (fabs(pimgCubesDataShifted[posx+posy*nx_in]) > DBL_ZERO_TOLERANCE) &&
622 (fabs(pmergedImgDIT[x+y*nx_out]) > DBL_ZERO_TOLERANCE) &&
623 (cpl_vector_get(msk, i) != 0))
625 if (!strcmp(compute_mode,
"MEDIAN")) {
627 cpl_vector_set(val, ovr, pimgCubesDataShifted[posx+posy*nx_in]);
631 pimgMergedCubeData[x+y*nx_out] += pimgCubesDataShifted[posx+posy*nx_in] * exptimes[i];
652 if (!strcmp(compute_mode,
"MEDIAN")) {
655 cpl_vector *tval = cpl_vector_extract(val, 0, ovr-1, 1);
656 pimgMergedCubeData[x+y*nx_out] = cpl_vector_get_median_const(tval);
662 pimgMergedCubeData[x+y*nx_out] /= pmergedImgDIT[x+y*nx_out];
677 return cpl_error_get_code();
701 const int n_contributions,
708 const char *compute_mode,
726 cpl_vector *val = NULL;
727 cpl_error_code ret_err = CPL_ERROR_NONE;
730 nx = cpl_image_get_size_x(imagesDataShifted[0]);
731 ny = cpl_image_get_size_y(imagesDataShifted[0]);
733 for (
int ks = 0; ks < n_contributions; ks++) {
738 if (n_contributions-nclip > 0) {
739 val = cpl_vector_new(n_contributions-nclip);
745 for (
int i = 0; i < n_frames; i++) {
746 pimg_in = cpl_image_get_data_double(imagesDataShifted[i]);
753 if ((y >= loy) && (y < upy) && (x >= lox) && (x < upx)) {
758 if (!isnan(pimg_in[pos]) &&
759 (fabs(pimg_in[pos]) > DBL_ZERO_TOLERANCE) &&
760 (cpl_vector_get(*msk, i) != 0))
763 cpl_vector_set(val, ovr, pimg_in[pos]));
771 if (!strcmp(compute_mode,
"MEDIAN")) {
772 med=cpl_vector_get_median(val);
774 med = cpl_vector_get_mean(val);
778 if ((ks == 0) && (pclip < 100) && (pclip > 0)) {
779 med = cpl_vector_get_median(val);
780 cpl_vector_subtract_scalar(val, med);
781 cpl_vector_power(val, 2);
782 cpl_vector_sqrt(val);
783 cpl_vector_sort(val, CPL_SORT_ASCENDING);
784 pk = round(pclip/100.0*(cpl_vector_get_size(val)-1));
785 sig = cpl_vector_get(val, pk) / kappa;
787 if (!strcmp(compute_mode,
"MEDIAN")){
788 cpl_vector_subtract_scalar(val, med);
789 cpl_vector_power(val, 2);
790 cpl_vector_sqrt(val);
791 sig = 1.4826 * cpl_vector_get_median(val);
793 sig=cpl_vector_get_stdev(val);
797 for (
int i = 0 ; i < n_frames; i++) {
798 pimg_in = cpl_image_get_data_double(imagesDataShifted[i]);
806 if ((y >= loy) && (y < upy) && (x >= lox) && (x < upx)) {
811 if (!isnan(pimg_in[pos]) &&
812 (fabs(pimg_in[pos]) > DBL_ZERO_TOLERANCE) &&
813 (cpl_vector_get(*msk,i) != 0))
815 if(fabs((pimg_in[pos]-med)) > kappa*sig)
820 cpl_image_reject(imagesDataShifted[i], posx+1, posy+1);
821 cpl_vector_set(*msk, i, 0);
832 ret_err = cpl_error_get_code();
862 cpl_image **imgMergedCubeData,
863 cpl_image **imgMergedCubeError,
864 cpl_image *mergedImgDIT,
865 cpl_image **imagesDataShifted,
866 cpl_image **imagesErrorShifted,
867 const double *exptimes,
870 const char *compute_mode,
879 double *pimgCubesDataShifted = NULL,
880 *pimgCubesErrorShifted = NULL,
881 *pimgMergedCubeData = NULL,
882 *pimgMergedCubeError = NULL,
883 *pmergedImgDIT = NULL;
884 cpl_vector *val = NULL;
885 eris_ifu_vector *data_vec = NULL,
888 nx_in = cpl_image_get_size_x(imagesDataShifted[0]);
889 ny_in = cpl_image_get_size_y(imagesDataShifted[0]);
892 (nx_out != cpl_image_get_size_x(mergedImgDIT)) ||
893 (ny_out != cpl_image_get_size_y(mergedImgDIT))
896 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
897 return cpl_error_get_code();
900 *imgMergedCubeData = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE);
901 pimgMergedCubeData = cpl_image_get_data_double(*imgMergedCubeData);
903 *imgMergedCubeError = cpl_image_new(nx_out, ny_out, CPL_TYPE_DOUBLE);
904 pimgMergedCubeError = cpl_image_get_data_double(*imgMergedCubeError);
906 pmergedImgDIT = cpl_image_get_data_double(mergedImgDIT);
908 for (
int y = 0; y < ny_out; y++) {
909 for (
int x = 0; x < nx_out; x++) {
910 if (!strcmp(compute_mode,
"MEDIAN")) {
912 val = cpl_vector_new(n_cubes);
919 for (
int i = 0; i < n_cubes; i++) {
920 if ((y >= lly[i]) && (y < lly[i]+ny_in) &&
921 (x >= llx[i]) && (x < llx[i]+nx_in))
923 pimgCubesDataShifted = cpl_image_get_data_double(imagesDataShifted[i]);
924 pimgCubesErrorShifted = cpl_image_get_data_double(imagesErrorShifted[i]);
929 if (!isnan(pimgCubesDataShifted[posx+posy*nx_in]) &&
930 (fabs(pimgCubesDataShifted[posx+posy*nx_in]) > DBL_ZERO_TOLERANCE) &&
931 (fabs(pmergedImgDIT[x+y*nx_out]) > DBL_ZERO_TOLERANCE))
934 if (!strcmp(compute_mode,
"MEDIAN")) {
936 cpl_vector_set(val, ovr, pimgCubesDataShifted[posx+posy*nx_in]);
940 pimgMergedCubeData[x+y*nx_out] += pimgCubesDataShifted[posx+posy*nx_in] * exptimes[i];
962 if (!strcmp(compute_mode,
"MEDIAN")){
965 cpl_vector *tval = cpl_vector_extract(val, 0, ovr-1, 1);
966 pimgMergedCubeData[x+y*nx_out] = cpl_vector_get_median_const(tval);
972 pimgMergedCubeData[x+y*nx_out] /= pmergedImgDIT[x+y*nx_out];
977 return cpl_error_get_code();
994 const int* llx,
const int* lly,
995 const int x,
const int y)
997 int n_contributes = 0,
1005 double *pimg = NULL;
1009 nx = cpl_image_get_size_x(imagesDataShifted[0]);
1010 ny = cpl_image_get_size_y(imagesDataShifted[0]);
1014 for (
int i = 0; i < n_frames; i++) {
1015 pimg = cpl_image_get_data_double(imagesDataShifted[i]);
1022 if ((y >= loy) && (y < upy) && (x >= lox) && (x < upx)) {
1027 if (!isnan(pimg[pos]) && (fabs(pimg[pos]) > DBL_ZERO_TOLERANCE)) {
1033 return n_contributes;
1049 double local_median = 0.;
1050 cpl_error_code err = CPL_ERROR_NONE;
1052 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1056 cpl_image_reject_value(img, CPL_VALUE_NOTFINITE));
1058 local_median = cpl_image_get_median(img);
1059 if (cpl_error_get_code() == CPL_ERROR_DATA_NOT_FOUND) {
1065 if (!isnan(local_median)) {
1067 cpl_image_subtract_scalar(img, local_median));
1074 err = cpl_error_get_code();
1094 const float *offsetx,
const float *offsety,
1095 float *min_offx,
float *max_offx,
1096 float *min_offy,
float *max_offy)
1101 for (
int n = 0; n < nframes; n++) {
1110 if(offx > *max_offx)
1112 if(offy > *max_offy)
1114 if(offx < *min_offx)
1116 if(offy < *min_offy)
1136 if ((x - (
double)k) <= 0.5) {
1142 if ((x - (
double)k) <= -0.5) {
1182 const double shift_x,
1183 const double shift_y,
1184 const double *kernel)
1186 cpl_image *img_shifted = NULL;
1189 int samples = KERNEL_SAMPLES,
1203 *pimg_shifted = NULL;
1204 const double *pimg_in = NULL;
1206 cpl_ensure(img_in != NULL, CPL_ERROR_NULL_INPUT, NULL);
1207 cpl_ensure(kernel != NULL, CPL_ERROR_NULL_INPUT, NULL);
1210 if ((fabs(shift_x) < 1e-2) && (fabs(shift_y) < 1e-2))
1211 return cpl_image_duplicate(img_in);
1213 nx = cpl_image_get_size_x(img_in);
1214 ny = cpl_image_get_size_y(img_in);
1216 pimg_in = cpl_image_get_data_double_const(img_in);
1217 if (pimg_in != NULL) {
1218 first_pass = cpl_calloc(nx, ny*
sizeof(
double));
1219 img_shifted = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
1220 pimg_shifted = cpl_image_get_data_double(img_shifted);
1221 for (
int y = 0; y < (int)ny; y++) {
1222 for (
int x = 1; x < (int)nx-2; x++) {
1223 fx = (double)x - shift_x;
1225 rx = fx - (double)px;
1226 pos = px + y * (int)nx;
1228 if ((px>1) && (px<(nx-3))) {
1229 tabx = (int)(fabs(mid * rx));
1233 value = pimg_in[pos-1] * kernel[mid+tabx] +
1234 pimg_in[pos] * kernel[tabx] +
1235 pimg_in[pos+1] * kernel[mid-tabx] +
1236 pimg_in[pos+2] * kernel[samples-tabx-1];
1240 norm = kernel[mid+tabx] +
1243 kernel[samples-tabx-1];
1245 if (fabs(norm) > 1e-4) {
1253 first_pass[x+y*nx] = value;
1257 for (
int x = 0; x < (int)nx; x++) {
1258 for (
int y = 1; y < (int)ny-3; y++) {
1259 fy = (double)y - shift_y;
1261 ry = fy - (double)py ;
1264 if ((py > 1) && (py < ((int)ny-2))) {
1265 taby = (int)(fabs((
double)mid * ry));
1269 value = first_pass[pos-nx] * kernel[mid+taby] +
1270 first_pass[pos] * kernel[taby] +
1271 first_pass[pos+nx] * kernel[mid-taby] +
1272 first_pass[pos+2*nx]*kernel[samples-taby-1];
1276 norm = kernel[mid+taby] +
1279 kernel[samples-taby-1];
1281 if (fabs(norm) > 1e-4) {
1287 pimg_shifted[x+y*nx] = value;
1291 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT);
1292 cpl_msg_error(cpl_func,
"Cannot get a data from an image");
1297 cpl_free(first_pass); first_pass = NULL;
1312 double *pimg = NULL;
1315 pimg = cpl_image_get_data_double(img);
1317 nx = cpl_image_get_size_x(img);
1318 ny = cpl_image_get_size_y(img);
1320 for (
int i = 0 ; i < nx*ny; i++) {
1321 if (fabs(pimg[i]) < DBL_ZERO_TOLERANCE) {
1338 eris_ifu_vector *err_vec,
1339 const char *compute_mode)
1341 double std_err = 0.,
1344 cpl_ensure_code(data_vec != NULL, CPL_ERROR_NULL_INPUT);
1345 cpl_ensure_code(err_vec != NULL, CPL_ERROR_NULL_INPUT);
1353 if (!strcmp(compute_mode,
"MEDIAN")) {
1358 std_err = std_dev / sqrt(vec_size);
1362 if (vec_size == 1) {
1368 }
else if (vec_size == 2) {
1369 double tmp_dbl = 0.;
1383 std_dev = tmp_dbl / 2;
1384 std_err = std_dev / sqrt(2);
1399double** matrix(
int nrow,
int ncol) {
1400 double **matrix = (
double**)cpl_malloc((
size_t)((nrow)*
sizeof(
double*)));
1402 for(
int i = 0; i < nrow; i++) {
1403 matrix[i] = (
double *) cpl_malloc((
size_t)((ncol)*
sizeof(
double)));
1409void free_matrix(
double **matrix,
int nrow) {
1410 for(
int i = 0; i < nrow; i++) {
1411 cpl_free(matrix[i]); matrix[i] = NULL;
1413 cpl_free(matrix); matrix = NULL;
1432 cpl_error_code err = CPL_ERROR_NONE;
1438 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1442 nx = cpl_image_get_size_x(img);
1443 ny = cpl_image_get_size_y(img);
1446 for (
int ix = 1; ix <= nx; ix++) {
1447 for (
int iy = 1; iy <= ny; iy++) {
1448 tmp = cpl_image_get(img, ix, iy, &is_rej);
1451 if (!is_rej && isnan(tmp)) {
1453 cpl_image_reject(img, ix, iy));
1458 err = cpl_error_get_code();
1518 const enum extrapolationType extrapolation)
1520 const double *pimg_in = NULL;
1521 double **array_in = NULL,
1524 cpl_image *img_out = NULL;
1530 cpl_ensure(img_in != NULL, CPL_ERROR_NULL_INPUT, NULL);
1531 cpl_ensure((extrapolation == NONE_NANS) ||
1532 (extrapolation == NONE_CLIPPING)
1534, CPL_ERROR_ILLEGAL_INPUT, NULL);
1537 if ((xshift == 0.0) && (yshift == 0.0)) {
1540 img_out = cpl_image_duplicate(img_in));
1542 xdim = cpl_image_get_size_x(img_in);
1543 ydim = cpl_image_get_size_y(img_in);
1545 pimg_in = cpl_image_get_data_double_const(img_in);
1547 array_in = matrix(xdim, ydim);
1548 for (
int j = 0; j < ydim ; j++) {
1549 for (
int i = 0; i < xdim ; i++) {
1550 if (isnan(pimg_in[i + j*xdim]))
1554 array_in[i][j] = pimg_in[i + j*xdim];
1576if (strcmp(method,
"NN") == 0) {
1577 if (fabs(xshift) > 1.0 || fabs(yshift) > 1.0) {
1579 "Neither xshift nor yshift are allowed to "
1580 "be greater than 1 pixel for NN");
1586 }
else if (xshift < -0.5) {
1593 }
else if (yshift < -0.5) {
1598 array_out = matrix(xdim,ydim);
1599 for (
int j = 0; j < ydim; j++) {
1600 for (
int i = 0; i < xdim; i++) {
1601 int xix = i+xoffset,
1603 if (xix < 0 || xix >= xdim || yix < 0 || yix >= ydim) {
1604 array_out[i][j] = NAN;
1606 array_out[i][j] = array_in[i+xoffset][j+yoffset];
1612 "Unknown value for interpolation method");
1614 free_matrix(array_in, xdim);
1616 switch (extrapolation) {
1628 xdim_new = xdim - lrintf(ceill(fabsl(xshift)));
1629 ydim_new = xdim - lrintf(ceill(fabsl(yshift)));
1631 pimg_out = cpl_malloc(xdim_new * ydim_new *
sizeof(
double)));
1632 int xmin = - floorl(xshift);
1635 int xmax = xdim - ceill(xshift);
1638 int ymin = - floorl(yshift);
1641 int ymax = ydim - ceill(yshift);
1644 for (
int j = ymin; j < ymax; j++) {
1645 for (
int i = xmin; i < xmax; i++) {
1646 pimg_out[(i - xmin) + (j - ymin) * xdim_new] = array_out[i][j];
1654 pimg_out = cpl_malloc(xdim * ydim *
sizeof(
double)));
1655 float xxmin = 0 - xshift;
1656 float xxmax = xdim - 1 - xshift;
1657 float yymin = 0 - yshift;
1658 float yymax = ydim - 1 - yshift;
1659 for (
int j = 0; j < ydim; j++) {
1660 for (
int i = 0; i < xdim; i++) {
1661 if ((i < xxmin ) || (i > xxmax) ||
1662 (j < yymin ) || (j > yymax))
1664 pimg_out[i+j*xdim] = NAN;
1666 pimg_out[i+j*xdim] = array_out[i][j];
1673 "Unknown value for extrapolation type");
1676 free_matrix(array_out, xdim);
1677 img_out = cpl_image_wrap_double(xdim_new, ydim_new, pimg_out);
1706 cpl_image **imagesData,
1707 cpl_image **imagesError,
1710 bool subtract_background)
1712 cpl_size nframes = 0,
1717 cpl_error_code err = CPL_ERROR_NONE;
1718 const cpl_frame *frame = NULL;
1719 cpl_mask *tmp_mask = NULL;
1720 cpl_image *cube_qual_tmp = NULL;
1721 cpl_propertylist *plist = NULL;
1722 const char *name = NULL;
1728 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
1731 nframes = cpl_frameset_get_size(frameset);
1734 for (cpl_size n = 0; n < nframes; n++) {
1736 frame = cpl_frameset_get_position_const(frameset, n));
1738 name = cpl_frame_get_filename(frame));
1739 if (edge_trim > 0) {
1741 plist = cpl_propertylist_load(name, 1));
1747 llx = 1 + edge_trim;
1748 lly = 1 + edge_trim;
1749 urx = tmp_size_x - edge_trim;
1750 ury = tmp_size_y - edge_trim;
1753 imagesData[n] = cpl_image_load_window(name, CPL_TYPE_DOUBLE, z, 1, llx, lly, urx, ury));
1755 imagesError[n] = cpl_image_load_window(name, CPL_TYPE_DOUBLE, z, 2, llx, lly, urx, ury));
1757 cube_qual_tmp = cpl_image_load_window(name, CPL_TYPE_DOUBLE, z, 3, llx, lly, urx, ury));
1761 imagesData[n] = cpl_image_load(name, CPL_TYPE_DOUBLE, z, 1));
1763 imagesError[n] = cpl_image_load(name, CPL_TYPE_DOUBLE, z, 2));
1765 cube_qual_tmp = cpl_image_load(name, CPL_TYPE_DOUBLE, z, 3));
1770 tmp_mask = cpl_mask_threshold_image_create(cube_qual_tmp, 0, INT_MAX));
1772 cpl_image_reject_from_mask(imagesData[n], tmp_mask));
1774 cpl_image_reject_from_mask(imagesError[n], tmp_mask));
1778 if (subtract_background) {
1781 if (warn && !warned) {
1783 cpl_msg_warning(cpl_func,
" local_median is NAN in %dth plane", z);
1790 err = cpl_error_get_code();
1815 const char *name = NULL;
1816 const cpl_frame *fr = NULL;
1817 cpl_propertylist *pl = NULL;
1819 cpl_ensure(fs != NULL, CPL_ERROR_NULL_INPUT, -1);
1823 cpl_frameset_iterator *iter = NULL;
1825 iter = cpl_frameset_iterator_new(fs));
1826 fr = cpl_frameset_iterator_get(iter);
1829 name = cpl_frame_get_filename(fr));
1833 pl = cpl_propertylist_load(name, 1));
1834 naxis3 = cpl_propertylist_get_int( pl, NAXIS3);
1835 crpix3 = cpl_propertylist_get_double(pl, CRPIX3);
1836 crval3 = cpl_propertylist_get_double(pl, CRVAL3);
1837 cd3_3 = cpl_propertylist_get_double(pl, CD3_3);
1842 cpl_frameset_iterator_advance(iter, 1));
1843 fr = cpl_frameset_iterator_get(iter);
1846 while (fr != NULL) {
1848 name = cpl_frame_get_filename(fr));
1851 pl = cpl_propertylist_load(name, 1));
1853 naxis3_tmp = cpl_propertylist_get_int( pl, NAXIS3);
1854 crpix3_tmp = cpl_propertylist_get_double(pl, CRPIX3);
1855 crval3_tmp = cpl_propertylist_get_double(pl, CRVAL3);
1856 cd3_3_tmp = cpl_propertylist_get_double(pl, CD3_3);
1860 if ((fabs(crpix3 - crpix3_tmp) > DBL_ZERO_TOLERANCE) ||
1861 (fabs(crval3 - crval3_tmp) > DBL_ZERO_TOLERANCE) ||
1862 (fabs(cd3_3 - cd3_3_tmp) > DBL_ZERO_TOLERANCE))
1865 "WCS not matching for all frames!");
1868 if (naxis3_tmp < naxis3) {
1869 naxis3 = naxis3_tmp;
1873 cpl_frameset_iterator_advance(iter, 1));
1874 fr = cpl_frameset_iterator_get(iter);
void eris_ifu_combine_get_xy_min_max(const int nframes, const float *offsetx, const float *offsety, float *min_offx, float *max_offx, float *min_offy, float *max_offy)
eris_ifu_combine_get_xy_min_max
void eris_ifu_combine_convert_0_to_NaN_img(cpl_image *img)
eris_ifu_combine_convert_0_to_NaN_img
int eris_ifu_combine_nearest_int(const double x)
Determine the nearest integer to a specified real value.
cpl_error_code eris_ifu_combine_build_mask_cube(cpl_image **imagesDataShifted, cpl_image **mergedImgDIT, const int *llx, const int *lly, const double *exptimes, int n_cubes, cpl_size nx_out, cpl_size ny_out)
Build the mask data cube.
int eris_ifu_combine_min_cube_size(const cpl_frameset *fs)
eris_ifu_combine_min_cube_size
double eris_ifu_combine_calc_error(eris_ifu_vector *data_vec, eris_ifu_vector *err_vec, const char *compute_mode)
Calculate error for coadded pixel.
cpl_error_code eris_ifu_reject_nan(cpl_image *img)
Rejects NaN values in the internal badpixelmask.
cpl_error_code eris_ifu_combine_read_image_planes(const cpl_frameset *frameset, cpl_image **imagesData, cpl_image **imagesError, int z, int edge_trim, bool subtract_background)
Read image planes from a frameset.
cpl_error_code eris_ifu_combine_coadd_ks_clip_internal(cpl_image **imagesDataShifted, const int n_frames, const int n_contributions, const int x, const int y, int *llx, int *lly, const double kappa, cpl_vector **msk, const char *compute_mode, const int pclip)
Internal routine for kappa-sigma clipping at a single pixel.
cpl_image * eris_ifu_combine_shift_image_kmos(const cpl_image *img_in, double xshift, double yshift, const char *method, const enum extrapolationType extrapolation)
Shifts each image of an image cube.
cpl_image * eris_ifu_combine_shift_image(const cpl_image *img_in, const double shift_x, const double shift_y, const double *kernel)
Shift an image by a given (non-integer) 2d offset.
cpl_error_code eris_ifu_combine_divide_DIT(cpl_imagelist **cubesData, const int n_cubes, const double *exptimes)
Divide each cube in a list by its exposure time.
int eris_ifu_combine_calc_contributions(cpl_image **imagesDataShifted, const int n_frames, const int *llx, const int *lly, const int x, const int y)
Calculate the number of frames contributing to a pixel.
cpl_error_code eris_ifu_combine_coadd(const int n_cubes, cpl_image **imgMergedCubeData, cpl_image **imgMergedCubeError, cpl_image *mergedImgDIT, cpl_image **imagesDataShifted, cpl_image **imagesErrorShifted, const double *exptimes, int *llx, int *lly, const char *compute_mode, const int nx_out, const int ny_out)
Compute weighted mean or median of shifted images.
cpl_error_code eris_ifu_combine_coadd_ks_clip(const int n_frames, const double kappa, int *llx, int *lly, const double *exptimes, cpl_image **imgMergedCubeData, cpl_image **imgMergedCubeError, cpl_image *mergedImgDIT, cpl_image **imagesDataShifted, cpl_image **imagesErrorShifted, const char *compute_mode, const int pclip, const int nx_out, const int ny_out)
Coadd images with kappa-sigma clipping.
cpl_error_code eris_ifu_combine_subtract_background(cpl_image *img, bool *warn)
Subtract spatial median from an image.
cpl_error_code eris_ifu_combine_jittered_images(cpl_image **imagesData, cpl_image **imagesError, int nx_out, int ny_out, cpl_image **mergedImageData, cpl_image **mergedImageError, cpl_image **mergedImageDIT, int n_cubes, const float *offsetx, const float *offsety, const double *exptimes, const double kappa, const char *compute_mode, const int pclip)
Combine jittered images into a merged image with optional kappa-sigma clipping.
cpl_error_code eris_ifu_combine_auto_size_cube(const float *offsetx, const float *offsety, const int nframes, float *ref_offx, float *ref_offy, int *size_x, int *size_y)
Computes size of coadded cube.
cpl_error_code eris_ifu_combine_build_mask(cpl_imagelist **cubesDataShifted, cpl_image *mergedImgDIT, const int n_cubes, const int *llx, const int *lly, const double *exptimes)
Build the mask data image.
#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 using median instead of mean.
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.
int eris_ifu_vector_count_non_rejected(const eris_ifu_vector *ev)
Count the number of non-rejected elements in a eris_ifu_vector.
int eris_ifu_vector_is_rejected(const eris_ifu_vector *ev, int n)
Test if a value is good or bad.
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_stdev(const eris_ifu_vector *ev)
Compute the bias-corrected standard deviation of a vector's elements.
double eris_ifu_vector_get(const eris_ifu_vector *ev, int pos)
Get an element of the 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.
void eris_ifu_vector_delete(eris_ifu_vector *ev)
Delete 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