25#include "eris_ifu_extract_spec_static.h"
26#include "eris_ifu_vector.h"
27#include "eris_ifu_error.h"
28#include "eris_ifu_utils.h"
29#include "eris_utils.h"
36hdrl_image* eris_ifu_extract_spec_collapse(hdrl_imagelist *cube,
37 cpl_image **contribute)
39 hdrl_image *hImage = NULL;
41 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
42 cpl_ensure(contribute != NULL, CPL_ERROR_NULL_INPUT, NULL);
47 &hImage, contribute));
58eris_ifu_extract_free_esSofStruct(
struct esSofStruct* self){
67cpl_image * eris_ifu_extract_spec_create_fit_mask(
const hdrl_image* img)
69 cpl_image *mask = NULL;
70 const cpl_image *image = NULL;
71 cpl_array *gauss_params = NULL;
73 cpl_size xposcen, yposcen;
74 cpl_size xwinsize, ywinsize;
76 cpl_ensure(img, CPL_ERROR_NULL_INPUT, NULL);
81 nx = cpl_image_get_size_x(image);
82 ny = cpl_image_get_size_y(image);
88 BRK_IF_NULL(gauss_params = cpl_array_new(7, CPL_TYPE_DOUBLE));
89 BRK_IF_ERROR(cpl_fit_image_gaussian(image, NULL, xposcen, yposcen,
90 xwinsize, ywinsize, gauss_params,
95 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
97 for (cpl_size iy=1; iy <= ny ; iy++) {
98 for (cpl_size ix=1; ix <= nx ; ix++) {
99 cpl_image_set(mask, ix, iy,
100 cpl_gaussian_eval_2d(gauss_params, (
double) ix, (
double) iy));
107 cpl_image_subtract_scalar(mask, cpl_image_get_min(mask));
108 cpl_image_divide_scalar(mask, cpl_image_get_max(mask));
109 cpl_array_delete(gauss_params);
119cpl_image * eris_ifu_extract_spec_create_circle_mask(
126 cpl_image *mask = NULL;
127 double cen_x, cen_y, x_lo, y_lo, x_hi, y_hi, r;
130 cpl_ensure(center_x > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
131 cpl_ensure(center_y > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
132 cpl_ensure(radius > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
133 cpl_ensure(nx > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
134 cpl_ensure(ny > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
137 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
138 pmask = cpl_image_get_data_double(mask);
140 cen_x = (double) center_x - 1.0;
141 cen_y = (double) center_y - 1.0;
143 x_lo = floor(cen_x - radius);
144 if (x_lo < 0) x_lo = 0;
145 y_lo = floor(cen_y - radius);
146 if (y_lo < 0) y_lo = 0;
147 x_hi = ceil(cen_x + radius);
148 if (x_hi > nx) x_hi = (int) nx;
149 y_hi = ceil(cen_y + radius);
150 if (y_hi > ny) y_hi = (int) ny;
151 for (
int x = (
int) x_lo; x < x_hi; x++) {
152 for (
int y = (
int) y_lo; y < y_hi; y++) {
153 r = sqrt(pow(x - cen_x,2) + pow(y - cen_y,2));
154 if (r <= radius) pmask[x + y * nx] = 1.0;
178cpl_image * eris_ifu_extract_spec_create_mask(
179 struct esParamStruct params,
180 struct esSofStruct sof,
181 const hdrl_image *collapsedCube,
184 cpl_image *mask = NULL;
189 const cpl_image *img;
192 switch (params.mask_method) {
197 cpl_image_get_maxpos(
201 mask = eris_ifu_extract_spec_create_circle_mask(center_x, center_y,
207 mask = eris_ifu_extract_spec_create_circle_mask(params.center_x,
215 cpl_image_get_maxpos(img, ¢er_x, ¢er_y);
219 double radius = eris_ifu_opt_extr_estimate_radius(img,
226 mask = eris_ifu_extract_spec_create_circle_mask(center_x, center_y,
232 mask = eris_ifu_extract_spec_create_fit_mask(collapsedCube));
236 "Internal error: unknown mask method %d",
240 nx = cpl_image_get_size_x(mask);
241 ny = cpl_image_get_size_y(mask);
242 if (nx != sof.nx || ny != sof.ny) {
244 "Dimensions of mask don't match with the cube");
253cpl_bivector * eris_ifu_extract_spectrum(hdrl_imagelist *cube,
258 cpl_vector **totalFlux,
259 cpl_vector **quality)
261 cpl_bivector *spectrum = NULL;
262 cpl_imagelist *data_in = NULL;
263 cpl_imagelist *error_in = NULL;
264 const cpl_image *tmpDataImg = NULL;
265 const cpl_image *tmpErrorImg = NULL;
266 const cpl_mask *bpm = NULL;
267 const double *pTmpData = NULL;
268 const double *pTmpError = NULL;
269 const cpl_binary *pBpm = NULL;
270 const double *pMask = NULL;
273 cpl_vector *lambda = NULL;
274 cpl_vector *spec_data = NULL;
275 cpl_vector *spec_error = NULL;
276 cpl_vector *spec_totFlux = NULL;
277 cpl_vector *spec_qual = NULL;
278 double *pLambda = NULL;
279 double *pData = NULL;
280 double *pError = NULL;
281 double *pTotFlux = NULL;
282 double *pqual = NULL;
289 cpl_ensure(cube != NULL,CPL_ERROR_NULL_INPUT, NULL);
290 cpl_ensure(mask != NULL,CPL_ERROR_NULL_INPUT, NULL);
291 cpl_ensure(error != NULL,CPL_ERROR_NULL_INPUT, NULL);
292 cpl_ensure(totalFlux != NULL,CPL_ERROR_NULL_INPUT, NULL);
299 ASSURE((nx == cpl_image_get_size_x(mask)) &&
300 (ny == cpl_image_get_size_y(mask)),
301 CPL_ERROR_ILLEGAL_INPUT,
302 "Data cube and mask don't have same dimensions!");
307 for (cpl_size sz = 0; sz < nz; sz++) {
314 lambda = cpl_vector_new(nz);
315 spec_data = cpl_vector_new(nz);
316 spec_error = cpl_vector_new(nz);
317 spec_totFlux = cpl_vector_new(nz);
318 spec_qual = cpl_vector_new(nz);
319 pLambda = cpl_vector_get_data(lambda);
320 pData = cpl_vector_get_data(spec_data);
321 pError = cpl_vector_get_data(spec_error);
322 pTotFlux = cpl_vector_get_data(spec_totFlux);
323 pqual = cpl_vector_get_data(spec_qual);
324 pMask = cpl_image_get_data_double_const(mask);
329 for (cpl_size sz = 0; sz < nz; sz++) {
330 tmpDataImg = cpl_imagelist_get(data_in, sz);
331 tmpErrorImg = cpl_imagelist_get(error_in, sz);
332 bpm = cpl_image_get_bpm_const(tmpDataImg);
333 pTmpData = cpl_image_get_data_double_const(tmpDataImg);
334 pTmpError = cpl_image_get_data_double_const(tmpErrorImg);
335 pBpm = cpl_mask_get_data_const(bpm);
343 for (cpl_size j = 0; j < ny; j++) {
344 for (cpl_size i = 0; i < nx; i++) {
350 sumData += pTmpData[p] * pMask[p];
351 sumVariance += pow(pTmpError[p] * pMask[p],2);
360 sumData += pTmpData[p];
361 sumVariance += pow(pTmpError[p],2);
368 if ((valid ==
true) && (fabs(weights) > DBL_ZERO_TOLERANCE)) {
369 pLambda[fill_nz] = startLambda + (double) sz * deltaLambda;
370 pData[fill_nz] = sumData / weights;
371 pError[fill_nz] = sqrt(sumVariance) / weights;
372 pTotFlux[fill_nz] = sumData;
381 BRK_IF_ERROR(cpl_vector_set_size(spec_totFlux, fill_nz));
384 spectrum = cpl_bivector_wrap_vectors(lambda, spec_data);
386 *totalFlux = spec_totFlux;
387 *quality = spec_qual;
388 cpl_imagelist_delete(data_in);
389 cpl_imagelist_delete(error_in);
917cpl_bivector * eris_ifu_optimal_extraction(
const hdrl_imagelist *cube,
918 const cpl_imagelist *cube_dqi,
919 const cpl_image *img_mask,
923 cpl_vector **error_out)
925 cpl_bivector *spectrum = NULL;
926 cpl_mask *mask = NULL;
927 cpl_vector *spec = NULL,
929 eris_ifu_vector *spec2 = NULL,
939 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
940 cpl_ensure(cube_dqi != NULL, CPL_ERROR_NULL_INPUT, NULL);
941 cpl_ensure(img_mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
942 cpl_ensure(startLambda > 1.0, CPL_ERROR_NULL_INPUT, NULL);
943 cpl_ensure(deltaLambda > 0, CPL_ERROR_NULL_INPUT, NULL);
944 cpl_ensure(error_out != NULL,CPL_ERROR_NULL_INPUT, NULL);
969 if (productDepth >= PD_DEBUG) {
974 eris_ifu_opt_extr_simple_extraction(cube, mask, &spec, &spec_var));
975 if (productDepth >= PD_DEBUG) {
983 spectrum = eris_ifu_opt_extr_doit(cube, cube_dqi, mask,
985 startLambda, deltaLambda,
991 if (productDepth >= PD_DEBUG) {
998 eris_ifu_opt_extr_vector_sqrt(spec_var);
1024cpl_error_code eris_ifu_opt_extr_get_center_fwhm(
const hdrl_image *hdrl_img,
1030 cpl_error_code ret_error = CPL_ERROR_NONE;
1031 double maxval = -9999e10;
1032 const cpl_image *img_data = NULL;
1033 const double *pimg_data = NULL;
1034 const cpl_mask *img_mask = NULL;
1035 const cpl_binary *pimg_mask = NULL;
1039 cpl_ensure_code(hdrl_img != NULL, CPL_ERROR_NULL_INPUT);
1040 cpl_ensure_code(edge_trim >= 0, CPL_ERROR_NULL_INPUT);
1045 nx = cpl_image_get_size_x(img_data);
1047 pimg_data = cpl_image_get_data_double_const(img_data));
1051 pimg_mask = cpl_mask_get_data_const(img_mask));
1056 if ((pimg_mask[x+y*nx] == GOOD_PIX) &&
1057 (pimg_data[x+y*nx] > maxval) &&
1058 (!isnan(pimg_data[x+y*nx])))
1060 maxval = pimg_data[x+y*nx];
1067 cpl_msg_debug(cpl_func,
"Mask max. value: %g)", maxval);
1073 if ((pimg_mask[x+y*nx] == GOOD_PIX) &&
1074 (pimg_data[x+y*nx] > maxval) &&
1075 (!isnan(pimg_data[x+y*nx])))
1087 ret_error = cpl_error_get_code();
1105cpl_mask* eris_ifu_opt_extr_create_mask(
int nx,
1111 cpl_mask *mask = NULL;
1112 cpl_binary *pmask =NULL;
1114 cpl_ensure(nx > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1115 cpl_ensure(ny > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1116 cpl_ensure(xcen > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1117 cpl_ensure(ycen > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1118 cpl_ensure(fwhm > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1122 mask = cpl_mask_new(nx, ny));
1124 pmask = cpl_mask_get_data(mask));
1126 for (
int x = 0; x < nx; x++) {
1127 for (
int y = 0; y < ny; y++) {
1128 if (fwhm <= sqrt(pow(x-xcen,2)+pow(y-ycen,2))) {
1130 pmask[x+y*nx] = BAD_PIX;
1133 pmask[x+y*nx] = GOOD_PIX;
1155cpl_error_code eris_ifu_opt_extr_simple_extraction(
const hdrl_imagelist *cube,
1156 const cpl_mask *mask,
1158 cpl_vector **spec_var)
1160 cpl_error_code ret_error = CPL_ERROR_NONE;
1161 const hdrl_image *tmp_img = NULL;
1162 hdrl_image *tmp_img2 = NULL;
1163 double *pspec = NULL,
1168 cpl_ensure_code(cube != NULL, CPL_ERROR_NULL_INPUT);
1169 cpl_ensure_code(mask != NULL, CPL_ERROR_NULL_INPUT);
1175 *spec = cpl_vector_new(nz));
1177 *spec_var = cpl_vector_new(nz));
1179 pspec = cpl_vector_get_data(*spec));
1181 pspec_var = cpl_vector_get_data(*spec_var));
1183 for (
int z = 0; z < nz; z++) {
1193 pspec_var[z] = hv.error*hv.error;
1198 ret_error = cpl_error_get_code();
1212cpl_bivector * eris_ifu_opt_extr_helper_usepix(
const cpl_mask *mask,
int *n_usepix)
1214 cpl_bivector *usepix = NULL;
1220 const cpl_binary *pmask = NULL;
1222 cpl_ensure(mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1225 nx = cpl_mask_get_size_x(mask);
1226 ny = cpl_mask_get_size_y(mask);
1229 *n_usepix = (nx * ny) - cpl_mask_count(mask);
1230 cpl_msg_debug(cpl_func,
"optimal extraction: n_usepix: %d", *n_usepix);
1232 if (*n_usepix > 0) {
1233 usepix = cpl_bivector_new(*n_usepix);
1234 pmask = cpl_mask_get_data_const(mask);
1236 px = cpl_vector_get_data(cpl_bivector_get_x(usepix));
1237 py = cpl_vector_get_data(cpl_bivector_get_y(usepix));
1239 for (
int y = 0; y < ny; y++) {
1240 for (
int x = 0; x < nx; x++) {
1241 if (pmask[x+y*nx] == GOOD_PIX) {
1265cpl_error_code eris_ifu_opt_extr_helper_fill_vertical(cpl_image *img,
const eris_ifu_vector *vec)
1267 cpl_ensure_code(vec, CPL_ERROR_NULL_INPUT);
1269 double *pimg = cpl_image_get_data_double(img);
1270 cpl_size nx = cpl_image_get_size_x(img),
1271 ny = cpl_image_get_size_y(img);
1272 double *pkvmask = cpl_vector_get_data(vec->data),
1273 *pkvdata = cpl_vector_get_data(vec->mask);
1277 for (
int y = 0; y < ny; y++) {
1278 for (
int x = 0; x < nx; x++) {
1279 if (pkvmask[y] > 0.5) {
1280 pimg[x+y*nx] = pkvdata[y];
1282 cpl_image_reject(img, x+1, y+1);
1287 return CPL_ERROR_NONE;
1299void eris_ifu_opt_extr_helper_fill_horizontal(cpl_image *img,
const cpl_image *slice,
const cpl_bivector *usepix,
int row,
int power) {
1300 double *pimg = cpl_image_get_data_double(img);
1301 const double *pslice_d = NULL;
1302 const int *pslice_i = NULL;
1303 cpl_size nx = cpl_image_get_size_x(slice);
1304 cpl_type type = cpl_image_get_type(slice);
1305 const double *px = cpl_vector_get_data_const(cpl_bivector_get_x_const(usepix)),
1306 *py = cpl_vector_get_data_const(cpl_bivector_get_y_const(usepix));
1307 cpl_size n_usepix = cpl_bivector_get_size(usepix);
1309 if (type == CPL_TYPE_DOUBLE) {
1310 pslice_d = cpl_image_get_data_double_const(slice);
1311 }
else if (type == CPL_TYPE_INT) {
1312 pslice_i = cpl_image_get_data_int_const(slice);
1317 if (type == CPL_TYPE_DOUBLE) {
1318 for (
int i = 0; i < n_usepix; i++) {
1319 double val = pslice_d[(int)px[i]+(
int)py[i]*nx];
1321 pimg[i+row*n_usepix] = pow(val, 2);
1323 pimg[i+row*n_usepix] = val;
1327 for (
int i = 0; i < n_usepix; i++) {
1328 int val = pslice_i[(int)px[i]+(
int)py[i]*nx];
1330 pimg[i+row*n_usepix] = pow(val, 2);
1332 pimg[i+row*n_usepix] = val;
1344void eris_ifu_opt_extr_helper_set_positive(cpl_image *img) {
1345 double *pimg = cpl_image_get_data_double(img);
1346 cpl_size nx = cpl_image_get_size_x(img),
1347 ny = cpl_image_get_size_y(img);
1350 for (
int x = 0; x < nx; x++) {
1351 for (
int y = 0; y < ny; y++) {
1352 if ((pimg[x+y*nx] < 0.) || isnan(pimg[x+y*nx])) {
1358 cpl_msg_debug(cpl_func,
"optimal extraction: Resetting %d negative values in original PSF", n_neg);
1367cpl_vector* eris_ifu_opt_extr_get_col(
const cpl_image *img,
int colnr)
1371 double *pvec = NULL;
1372 const double *pimg = NULL;
1373 cpl_vector *vec = NULL;
1375 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
1377 nx = cpl_image_get_size_x(img);
1378 ny = cpl_image_get_size_y(img);
1380 cpl_ensure(colnr <= nx, CPL_ERROR_ILLEGAL_INPUT, NULL);
1382 vec = cpl_vector_new(ny);
1383 pvec = cpl_vector_get_data(vec);
1384 pimg = cpl_image_get_data_double_const(img);
1386 for (
int y = 0; y < ny; y++) {
1387 pvec[y] = pimg[colnr+y*nx];
1399cpl_vector* eris_ifu_opt_extr_get_row(
const cpl_image *img,
int rownr)
1403 double *pvec = NULL;
1404 const double *pimg = NULL;
1405 cpl_vector *vec = NULL;
1407 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
1409 nx = cpl_image_get_size_x(img);
1410 ny = cpl_image_get_size_y(img);
1412 cpl_ensure(rownr <= ny, CPL_ERROR_ILLEGAL_INPUT, NULL);
1414 vec = cpl_vector_new(nx);
1415 pvec = cpl_vector_get_data(vec);
1416 pimg = cpl_image_get_data_double_const(img);
1418 for (
int x = 0; x < nx; x++) {
1419 pvec[x] = pimg[x+rownr*nx];
1431cpl_error_code eris_ifu_opt_extr_set_row(cpl_image *img,
1433 const cpl_vector *vec)
1437 const double *pvec = NULL;
1438 double *pimg = NULL;
1440 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1441 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1443 nx = cpl_image_get_size_x(img);
1444 ny = cpl_image_get_size_y(img);
1446 cpl_ensure_code(rownr <= ny, CPL_ERROR_ILLEGAL_INPUT);
1447 cpl_ensure_code(nx == cpl_vector_get_size(vec), CPL_ERROR_ILLEGAL_INPUT);
1449 pvec = cpl_vector_get_data_const(vec);
1450 pimg = cpl_image_get_data_double(img);
1452 for (
int x = 0; x < nx; x++) {
1453 pimg[x+rownr*nx] = pvec[x];
1456 return cpl_error_get_code();
1466cpl_error_code eris_ifu_opt_extr_set_col(cpl_image *img,
1468 const cpl_vector *vec)
1472 double *pimg = NULL;
1473 const double *pvec = NULL;
1475 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1476 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1478 nx = cpl_image_get_size_x(img);
1479 ny = cpl_image_get_size_y(img);
1481 cpl_ensure_code(colnr <= nx, CPL_ERROR_ILLEGAL_INPUT);
1482 cpl_ensure_code(ny == cpl_vector_get_size(vec), CPL_ERROR_ILLEGAL_INPUT);
1484 pvec = cpl_vector_get_data_const(vec);
1485 pimg = cpl_image_get_data_double(img);
1487 for (
int y = 0; y < ny; y++) {
1488 pimg[colnr+y*nx] = pvec[y];
1491 return cpl_error_get_code();
1494cpl_vector* eris_ifu_opt_extr_create_lambda(
int size,
double startLambda,
double deltaLambda)
1496 cpl_vector *lambda = cpl_vector_new(size);
1497 double *pLambda = cpl_vector_get_data(lambda);
1499 for (
int i = 0; i < size; i++) {
1500 pLambda[i] = startLambda + (double)i * deltaLambda;
1505cpl_error_code eris_ifu_opt_extr_vector_sqrt(cpl_vector *vec)
1507 double *pvec = cpl_vector_get_data(vec);
1508 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1510 for (
int i = 0; i < cpl_vector_get_size(vec); i++) {
1511 pvec[i] = sqrt(pvec[i]);
1513 return cpl_error_get_code();
1516cpl_bivector* eris_ifu_opt_extr_doit(
const hdrl_imagelist *cube,
1517 const cpl_imagelist *cube_dqi,
1518 const cpl_mask *mask,
1519 const eris_ifu_vector *spec,
1520 const eris_ifu_vector *spec_var,
1524 cpl_vector **error_out)
1526 cpl_bivector *spectrum = NULL,
1529 cpl_vector *vec = NULL,
1534 eris_ifu_vector *speco = NULL,
1535 *spec_var_err = NULL,
1537 cpl_image *spec1 = NULL,
1550 double clipfrac = 0.9,
1557 const double *pvec = NULL,
1560 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
1561 cpl_ensure(cube_dqi != NULL, CPL_ERROR_NULL_INPUT, NULL);
1562 cpl_ensure(mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1563 cpl_ensure(spec != NULL, CPL_ERROR_NULL_INPUT, NULL);
1564 cpl_ensure(spec_var != NULL, CPL_ERROR_NULL_INPUT, NULL);
1565 cpl_ensure(error_out != NULL, CPL_ERROR_NULL_INPUT, NULL);
1567 CPL_ERROR_ILLEGAL_INPUT, NULL);
1569 CPL_ERROR_ILLEGAL_INPUT, NULL);
1571 CPL_ERROR_ILLEGAL_INPUT, NULL);
1582 usepix = eris_ifu_opt_extr_helper_usepix(mask, &n_usepix);
1585 spec1 = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1586 psfvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1588 varvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1589 qualvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1590 pqualvals = cpl_image_get_data_double(qualvals);
1602 for (
int bigloop = 0; bigloop <= 1; bigloop++) {
1606 eris_ifu_opt_extr_helper_fill_vertical(spec1, speco));
1610 for (
int z = 0; z < nz; z++) {
1614 const cpl_image *slice_q = cpl_imagelist_get_const(cube_dqi, z);
1616 eris_ifu_opt_extr_helper_fill_horizontal(psfvals, slice_d, usepix, z, FALSE);
1617 eris_ifu_opt_extr_helper_fill_horizontal(varvals, slice_e, usepix, z, TRUE);
1618 eris_ifu_opt_extr_helper_fill_horizontal(qualvals, slice_q, usepix, z, FALSE);
1621 eris_ifu_opt_extr_helper_set_positive(psfvals);
1623 if (productDepth >= PD_DEBUG) {
1632 reject = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1633 preject = cpl_image_get_data_double(reject);
1636 new_vec = cpl_vector_new(nz);
1637 pnew_vec = cpl_vector_get_data(new_vec);
1639 for (
int iloop = 0; iloop <= 1; iloop++) {
1640 if (psfmod != NULL) {
1643 psfmod = cpl_image_divide_create(psfvals, spec1);
1644 eris_ifu_opt_extr_helper_set_positive(psfmod);
1647 if (productDepth >= PD_DEBUG) {
1652 for (
int n = 0; n < n_usepix; n++) {
1653 vec = eris_ifu_opt_extr_get_col(psfmod, n);
1654 pvec = cpl_vector_get_data_const(vec);
1660 cpl_vector_multiply(vec_err, vec));
1662 rejectvec = eris_ifu_opt_extr_get_col(reject, n);
1663 prejectvec = cpl_vector_get_data_const(rejectvec);
1667 keep0 = cpl_vector_new(nz);
1668 cpl_vector_fill(keep0, -1.0);
1669 pkeep0 = cpl_vector_get_data(keep0);
1672 for (cpl_size iz = 0; iz < nz; iz++) {
1674 if ((fabs(prejectvec[iz]) < 1e-5) &&
1683 cpl_vector_delete(rejectvec);
1686 if (keep0 != NULL) {
1687 pkeep0 = cpl_vector_get_data(keep0);
1690 if ((productDepth >= PD_DEBUG) && (n==92)) {
1695 for (
int z = 0; z < nz; z++) {
1697 int s = cpl_vector_get_size(keep0);
1698 cpl_vector* ttt = cpl_vector_new(s);
1699 double *pttt = cpl_vector_get_data(ttt);
1700 cpl_vector_fill(ttt, -1.0);
1702 for (
int iz = 0; iz < s; iz++) {
1703 int v = (int)(pkeep0[iz] +.5);
1704 if ((v > z-sm) && (v < z+sm)) {
1708 if (productDepth >= PD_DEBUG) {
1717 *ones = cpl_vector_new(cpl_vector_get_size(els));
1720 if ((productDepth >= PD_DEBUG) && (n==92) && (z == 1000)) {
1726 cpl_vector_fill(ones, 1.0);
1727 cpl_vector_divide(els, els_err);
1728 cpl_vector_divide(ones, els_err);
1729 pnew_vec[z] = cpl_vector_get_sum(els) / cpl_vector_get_sum(ones);
1745 eris_ifu_opt_extr_set_col(psfmod, n, new_vec));
1747 if ((productDepth >= PD_DEBUG) && (n==92)) {
1757 if (productDepth >= PD_DEBUG) {
1768 cpl_image *psfmod_tmp = cpl_image_multiply_create(psfmod, spec1);
1769 snr2 = cpl_image_subtract_create(psfvals, psfmod_tmp);
1770 cpl_image_power(snr2, 2);
1771 cpl_image_divide(snr2, varvals);
1774 if (productDepth >= PD_DEBUG) {
1783 for (
int iz = 0; iz < nz; iz++) {
1784 vec = eris_ifu_opt_extr_get_row(snr2, iz);
1785 int n_fin = eris_ifu_opt_extr_get_not_finite(vec);
1786 if (n_fin > n_usepix*0.25) {
1788 cpl_vector_power(vec, 2);
1789 eris_ifu_cpl_vector_sqrt(vec);
1791 cpl_vector_sort(vec, CPL_SORT_ASCENDING);
1792 double clip = cpl_vector_get(vec, n_usepix*clipfrac)*5;
1794 if ((tmp != NULL) && (cpl_vector_get_size(tmp) > 0)) {
1795 for (
int ii = 0; ii < cpl_vector_get_size(tmp); ii++) {
1796 preject[(int)(cpl_vector_get(tmp, ii)+.5)+iz*n_usepix] = 1;
1801 for (
int ii = 0; ii < n_usepix; ii++) {
1802 preject[ii+iz*n_usepix] = 1;
1808 if (productDepth >= PD_DEBUG) {
1815 for (
int ii = 0; ii < n_usepix * nz; ii++) {
1816 if (pqualvals[ii] > 0) {
1821 if (productDepth >= PD_DEBUG) {
1832 if (productDepth >= PD_DEBUG) {
1845 psfmodnew = cpl_image_duplicate(psfmod));
1850 residual = cpl_image_multiply_create(psfmod, spec1);
1851 cpl_image_subtract(residual, psfvals);
1852 cpl_image_multiply_scalar(residual, -1.);
1853 cpl_image_power(residual, 2);
1854 cpl_image_divide(residual, varvals);
1856 if (productDepth >= PD_DEBUG) {
1866 for (
int iz = 0; iz < nz; iz++) {
1867 cpl_vector *resvec0 = eris_ifu_opt_extr_get_row(residual, iz);
1868 double *presvec0 = cpl_vector_get_data(resvec0);
1870 if (productDepth >= PD_DEBUG) {
1875 keep0 = cpl_vector_new(n_usepix);
1876 cpl_vector_fill(keep0, -1.0);
1877 pkeep0 = cpl_vector_get_data(keep0);
1879 for (
int ii = 0; ii < n_usepix; ii++) {
1889 if (productDepth >= PD_DEBUG) {
1893 cpl_vector *p = eris_ifu_opt_extr_get_row(psfmod, iz);
1894 double *pp = cpl_vector_get_data(p);
1896 if ((keep0 != NULL) && (cpl_vector_get_size(keep0) > n_usepix*0.25)) {
1897 int nkeep = cpl_vector_get_size(keep0);
1899 *resvecs = cpl_vector_duplicate(resvec);
1900 cpl_vector_sort(resvecs, CPL_SORT_ASCENDING);
1902 if ((productDepth >= PD_DEBUG) && (iz == 1000)){
1906 double clip = cpl_vector_get(resvecs, (
int)(nkeep*clipfrac+.5)-1) * 5.;
1911 cpl_vector *q = eris_ifu_opt_extr_get_row(qualvals, iz);
1912 double *pq = cpl_vector_get_data(q);
1914 keep0 = cpl_vector_new(n_usepix);
1915 cpl_vector_fill(keep0, -1.0);
1916 pkeep0 = cpl_vector_get_data(keep0);
1918 for (
int ii = 0; ii < n_usepix; ii++) {
1919 if ((presvec0[ii] > clip) || (pq[ii] == 1)) {
1925 if (keep0 != NULL) {
1926 pkeep0 = cpl_vector_get_data(keep0);
1927 for (
int ii = 0; ii < cpl_vector_get_size(keep0); ii++) {
1928 pp[(int)(pkeep0[ii])] = 0.;
1932 double sum = cpl_vector_get_sum(p);
1933 for (
int ii = 0; ii < cpl_vector_get_size(p); ii++) {
1942 cpl_vector_fill(p, 0.));
1946 eris_ifu_opt_extr_set_row(psfmodnew, iz, p));
1948 cpl_vector *vals = eris_ifu_opt_extr_get_row(psfvals, iz),
1949 *var = eris_ifu_opt_extr_get_row(varvals, iz);
1951 eris_ifu_opt_extr_convert_0_to_NaN_vec(var);
1954 cpl_vector *tt = cpl_vector_duplicate(p);
1955 cpl_vector_multiply(tt, vals);
1956 cpl_vector_divide(tt, var);
1957 cpl_vector_power(p, 2.0);
1958 cpl_vector_divide(p, var);
1959 double sum_data = cpl_vector_get_sum(tt),
1960 sum_weight = cpl_vector_get_sum(p);
1991 cpl_vector *lambda = eris_ifu_opt_extr_create_lambda(nz, startLambda, deltaLambda);
1994 spectrum = cpl_bivector_wrap_vectors(lambda, speco2));
2028int eris_ifu_opt_extr_get_not_finite(cpl_vector *vec) {
2030 double *pvec = NULL;
2032 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
2034 pvec = cpl_vector_get_data(vec);
2036 for (
int i = 0; i < cpl_vector_get_size(vec); i++) {
2049void eris_ifu_opt_extr_convert_0_to_NaN_vec(cpl_vector *vec)
2052 double *pvec = NULL;
2055 pvec = cpl_vector_get_data(vec);
2057 x = cpl_vector_get_size(vec);
2059 for (
int i = 0 ; i < x; i++) {
2060 if (fabs(pvec[i]) < DBL_ZERO_TOLERANCE) {
2067cpl_image* eris_ifu_opt_extr_estimate_radius_helper(
const cpl_image *img,
2068 cpl_size center_x, cpl_size center_y,
2070 cpl_size *llx, cpl_size *lly,
2071 cpl_size *urx, cpl_size *ury)
2073 double half_maxval = 0.,
2075 const double *pimg = NULL;
2076 cpl_image *mask = NULL;
2080 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
2083 pimg = cpl_image_get_data_double_const(img);
2084 nx = cpl_image_get_size_x(img);
2085 ny = cpl_image_get_size_y(img);
2086 half_maxval = pimg[center_x+nx*center_y] / 2;
2088 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
2089 pmask = cpl_image_get_data_double(mask);
2091 *llx = center_x - radius;
2092 *lly = center_y - radius;
2093 *urx = center_x + radius;
2094 *ury = center_y + radius;
2108 for (cpl_size x = *llx; x < *urx; x++) {
2109 for (cpl_size y = *lly; y < *ury; y++) {
2110 if (pimg[x+nx*y] >= half_maxval) {
2124double eris_ifu_opt_extr_estimate_radius(
const cpl_image *img,
2125 cpl_size center_x, cpl_size center_y,
2126 double initial_radius,
2131 area_rectangle = 1.,
2133 cpl_image *mask = NULL;
2141 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, -1.);
2144 nx = cpl_image_get_size_x(img);
2145 ny = cpl_image_get_size_y(img);
2147 double max_radius = nx/2;
2148 if (ny/2 < max_radius) {
2151 radius = initial_radius - inc_radius;
2154 while ((area_mask / area_rectangle >= CPL_MATH_PI_4) && (radius < max_radius)) {
2155 radius += inc_radius;
2157 mask = eris_ifu_opt_extr_estimate_radius_helper(img,
2160 &llx, &lly, &urx, &ury);
2161 area_rectangle = (urx-llx)*(ury-lly);
2162 area_mask = cpl_image_get_flux(mask);
2163 if (productDepth >= PD_DEBUG) {
2166 cpl_msg_debug(cpl_func,
" intermediate mask center at (%d/%d), radius: %g, area mask: %g, area rect: %g)",
2167 (
int)center_x, (
int)center_y, radius, area_mask, area_rectangle);
2170 if (productDepth >= PD_DEBUG) {
2173 cpl_msg_debug(cpl_func,
"Final mask center at (%d/%d), radius: %g, area mask: %g, area rect: %g)",
2174 (
int)center_x, (
int)center_y, radius, area_mask, area_rectangle);
2233cpl_error_code eris_ifu_cpl_vector_sqrt(cpl_vector *vec)
2236 double *pvec = NULL;
2237 cpl_error_code err = CPL_ERROR_NONE;
2239 cpl_ensure_code(vec, CPL_ERROR_NULL_INPUT);
2243 n = cpl_vector_get_size(vec);
2247 pvec = cpl_vector_get_data(vec));
2250 for (
int i = 0; i < n; i++) {
2254 pvec[i] = sqrt(pvec[i]);
2260 err = cpl_error_get_code();
#define ASSURE(condition, error,...)
error handling macro (from fors-pipeline)
#define BRK_IF_ERROR(function)
If function is or returns an error != CPL_ERROR_NONE, then the try-block is exited.
#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 CATCH_MSG()
Displays an error message.
#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.
void eris_ifu_free_propertylist(cpl_propertylist **item)
free memory and set pointer to null
cpl_vector * eris_ifu_idl_values_at_indices(const cpl_vector *data, const cpl_vector *indices)
Returns a vector of given indices.
void eris_ifu_free_vector(cpl_vector **item)
free memory and set pointer to null
cpl_error_code eris_ifu_save_vector_dbg(const cpl_vector *vec, const char *filename, int create, const cpl_propertylist *pl)
save vector
cpl_error_code eris_ifu_save_image_dbg(const cpl_image *img, const char *filename, int create, const cpl_propertylist *pl)
eris_ifu_save_image_dbg
cpl_error_code eris_ifu_cut_endings(cpl_vector **vec, int *begin, int *end, int cut)
Cut leading and trailing -1 of a vector.
void eris_ifu_free_ifu_vector(eris_ifu_vector **item)
free memory and set pointer to null
cpl_error_code eris_ifu_save_bivector_dbg(const cpl_bivector *bivec, const char *filename, int col, int create)
save bivector as a vector (col=1 or col=2) or as a table
cpl_error_code eris_ifu_save_mask_dbg(const cpl_mask *mask, const char *filename, int create, const cpl_propertylist *pl)
eris_ifu_save_mask_dbg
void eris_ifu_free_imagelist(cpl_imagelist **item)
free memory and set pointer to null
cpl_vector * eris_ifu_idl_where(const cpl_vector *data, double val, int op)
Implements the where-function knownm from IDL.
void eris_ifu_free_hdrl_imagelist(hdrl_imagelist **item)
free memory and set pointer to null
cpl_mask * eris_ifu_mask_from_image(const cpl_image *img_mask)
eris_ifu_mask_from_image
void eris_ifu_free_hdrl_image(hdrl_image **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
void eris_ifu_free_bivector(cpl_bivector **item)
free memory and set pointer to null
int eris_ifu_vector_get_size(const eris_ifu_vector *ev)
Get the size of the eris_ifu_vector.
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.
cpl_vector * eris_ifu_vector_get_data(const eris_ifu_vector *ev)
Get a copy of the data, rejected values are set to NaN.
cpl_error_code eris_ifu_vector_sqrt(eris_ifu_vector *ev)
eris_ifu_vector_sqrt
eris_ifu_vector * eris_ifu_vector_duplicate(const eris_ifu_vector *ev)
This function duplicates an existing eris_ifu_vector and allocates memory.
cpl_error_code eris_ifu_vector_set(eris_ifu_vector *ev, int pos, double val)
Set an element of the eris_ifu_vector.
cpl_error_code eris_ifu_vector_power(eris_ifu_vector *ev, double exponent)
Compute the elementwise power of the vector.
eris_ifu_vector * eris_ifu_vector_create(const cpl_vector *data)
Create a new eris_ifu_vector out of a data cpl_vector.
cpl_error_code eris_ifu_vector_divide(eris_ifu_vector *kv1, const eris_ifu_vector *kv2)
Divide two eris_ifu_vectors element-wise.
double eris_ifu_vector_get_median(const eris_ifu_vector *ev, const enum medianType type)
Compute the median of the elements of a vector.
cpl_error_code eris_check_error_code(const char *func_id)
handle CPL errors
cpl_error_code hdrl_image_reject_from_mask(hdrl_image *self, const cpl_mask *map)
set bpm of hdrl_image
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy hdrl_image
hdrl_value hdrl_image_get_sum(const hdrl_image *self)
computes the sum of all pixel values and the associated error of an image.
cpl_image * hdrl_image_get_error(hdrl_image *himg)
get error as cpl image
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
const cpl_mask * hdrl_image_get_mask_const(const hdrl_image *himg)
get cpl bad pixel mask from image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
const cpl_image * hdrl_image_get_error_const(const hdrl_image *himg)
get error as cpl image
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_size hdrl_imagelist_get_size_y(const hdrl_imagelist *himlist)
Get number of rows of images in the imagelist.
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
cpl_size hdrl_imagelist_get_size_x(const hdrl_imagelist *himlist)
Get number of colums of images in the imagelist.
hdrl_image * hdrl_imagelist_get(const hdrl_imagelist *himlist, cpl_size inum)
Get an image from a list of images.