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)
260 cpl_bivector *spectrum = NULL;
261 cpl_imagelist *data_in = NULL;
262 cpl_imagelist *error_in = NULL;
263 const cpl_image *tmpDataImg = NULL;
264 const cpl_image *tmpErrorImg = NULL;
265 const cpl_mask *bpm = NULL;
266 const double *pTmpData = NULL;
267 const double *pTmpError = NULL;
268 const cpl_binary *pBpm = NULL;
269 const double *pMask = NULL;
272 cpl_vector *lambda = NULL;
273 cpl_vector *spec_data = NULL;
274 cpl_vector *spec_error = NULL;
275 cpl_vector *spec_totFlux = NULL;
276 double *pLambda = NULL;;
277 double *pData = NULL;;
278 double *pError = NULL;;
279 double *pTotFlux = NULL;;
286 cpl_ensure(cube != NULL,CPL_ERROR_NULL_INPUT, NULL);
287 cpl_ensure(mask != NULL,CPL_ERROR_NULL_INPUT, NULL);
288 cpl_ensure(error != NULL,CPL_ERROR_NULL_INPUT, NULL);
289 cpl_ensure(totalFlux != NULL,CPL_ERROR_NULL_INPUT, NULL);
296 ASSURE((nx == cpl_image_get_size_x(mask)) &&
297 (ny == cpl_image_get_size_y(mask)),
298 CPL_ERROR_ILLEGAL_INPUT,
299 "Data cube and mask don't have same dimensions!");
304 for (cpl_size sz = 0; sz < nz; sz++) {
311 lambda = cpl_vector_new(nz);
312 spec_data = cpl_vector_new(nz);
313 spec_error = cpl_vector_new(nz);
314 spec_totFlux = cpl_vector_new(nz);
315 pLambda = cpl_vector_get_data(lambda);
316 pData = cpl_vector_get_data(spec_data);
317 pError = cpl_vector_get_data(spec_error);
318 pTotFlux = cpl_vector_get_data(spec_totFlux);
319 pMask = cpl_image_get_data_double_const(mask);
324 for (cpl_size sz = 0; sz < nz; sz++) {
325 tmpDataImg = cpl_imagelist_get(data_in, sz);
326 tmpErrorImg = cpl_imagelist_get(error_in, sz);
327 bpm = cpl_image_get_bpm_const(tmpDataImg);
328 pTmpData = cpl_image_get_data_double_const(tmpDataImg);
329 pTmpError = cpl_image_get_data_double_const(tmpErrorImg);
330 pBpm = cpl_mask_get_data_const(bpm);
338 for (cpl_size j = 0; j < ny; j++) {
339 for (cpl_size i = 0; i < nx; i++) {
345 sumData += pTmpData[p] * pMask[p];
346 sumVariance += pow(pTmpError[p] * pMask[p],2);
355 sumData += pTmpData[p];
356 sumVariance += pow(pTmpError[p],2);
363 if ((valid ==
true) && (fabs(weights) > DBL_ZERO_TOLERANCE)) {
364 pLambda[fill_nz] = startLambda + (double) sz * deltaLambda;
365 pData[fill_nz] = sumData / weights;
366 pError[fill_nz] = sqrt(sumVariance) / weights;
367 pTotFlux[fill_nz] = sumData;
375 BRK_IF_ERROR(cpl_vector_set_size(spec_totFlux, fill_nz));
377 spectrum = cpl_bivector_wrap_vectors(lambda, spec_data);
379 *totalFlux = spec_totFlux;
380 cpl_imagelist_delete(data_in);
381 cpl_imagelist_delete(error_in);
909cpl_bivector * eris_ifu_optimal_extraction(
const hdrl_imagelist *cube,
910 const cpl_imagelist *cube_dqi,
911 const cpl_image *img_mask,
915 cpl_vector **error_out)
917 cpl_bivector *spectrum = NULL;
918 cpl_mask *mask = NULL;
919 cpl_vector *spec = NULL,
921 eris_ifu_vector *spec2 = NULL,
931 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
932 cpl_ensure(cube_dqi != NULL, CPL_ERROR_NULL_INPUT, NULL);
933 cpl_ensure(img_mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
934 cpl_ensure(startLambda > 1.0, CPL_ERROR_NULL_INPUT, NULL);
935 cpl_ensure(deltaLambda > 0, CPL_ERROR_NULL_INPUT, NULL);
936 cpl_ensure(error_out != NULL,CPL_ERROR_NULL_INPUT, NULL);
961 if (productDepth >= PD_DEBUG) {
966 eris_ifu_opt_extr_simple_extraction(cube, mask, &spec, &spec_var));
967 if (productDepth >= PD_DEBUG) {
975 spectrum = eris_ifu_opt_extr_doit(cube, cube_dqi, mask,
977 startLambda, deltaLambda,
983 if (productDepth >= PD_DEBUG) {
990 eris_ifu_opt_extr_vector_sqrt(spec_var);
1016cpl_error_code eris_ifu_opt_extr_get_center_fwhm(
const hdrl_image *hdrl_img,
1022 cpl_error_code ret_error = CPL_ERROR_NONE;
1023 double maxval = -9999e10;
1024 const cpl_image *img_data = NULL;
1025 const double *pimg_data = NULL;
1026 const cpl_mask *img_mask = NULL;
1027 const cpl_binary *pimg_mask = NULL;
1031 cpl_ensure_code(hdrl_img != NULL, CPL_ERROR_NULL_INPUT);
1032 cpl_ensure_code(edge_trim >= 0, CPL_ERROR_NULL_INPUT);
1033 cpl_ensure_code(xcen, CPL_ERROR_NULL_INPUT);
1034 cpl_ensure_code(ycen, CPL_ERROR_NULL_INPUT);
1035 cpl_ensure_code(fwhm, CPL_ERROR_NULL_INPUT);
1040 nx = cpl_image_get_size_x(img_data);
1042 pimg_data = cpl_image_get_data_double_const(img_data));
1046 pimg_mask = cpl_mask_get_data_const(img_mask));
1051 if ((pimg_mask[x+y*nx] == GOOD_PIX) &&
1052 (pimg_data[x+y*nx] > maxval) &&
1053 (!isnan(pimg_data[x+y*nx])))
1055 maxval = pimg_data[x+y*nx];
1062 cpl_msg_debug(cpl_func,
"Mask max. value: %g)", maxval);
1068 if ((pimg_mask[x+y*nx] == GOOD_PIX) &&
1069 (pimg_data[x+y*nx] > maxval) &&
1070 (!isnan(pimg_data[x+y*nx])))
1082 ret_error = cpl_error_get_code();
1100cpl_mask* eris_ifu_opt_extr_create_mask(
int nx,
1106 cpl_mask *mask = NULL;
1107 cpl_binary *pmask =NULL;
1109 cpl_ensure(nx > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1110 cpl_ensure(ny > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1111 cpl_ensure(xcen > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1112 cpl_ensure(ycen > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1113 cpl_ensure(fwhm > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1117 mask = cpl_mask_new(nx, ny));
1119 pmask = cpl_mask_get_data(mask));
1121 for (
int x = 0; x < nx; x++) {
1122 for (
int y = 0; y < ny; y++) {
1123 if (fwhm <= sqrt(pow(x-xcen,2)+pow(y-ycen,2))) {
1125 pmask[x+y*nx] = BAD_PIX;
1128 pmask[x+y*nx] = GOOD_PIX;
1150cpl_error_code eris_ifu_opt_extr_simple_extraction(
const hdrl_imagelist *cube,
1151 const cpl_mask *mask,
1153 cpl_vector **spec_var)
1155 cpl_error_code ret_error = CPL_ERROR_NONE;
1156 const hdrl_image *tmp_img = NULL;
1157 hdrl_image *tmp_img2 = NULL;
1158 double *pspec = NULL,
1163 cpl_ensure_code(cube != NULL, CPL_ERROR_NULL_INPUT);
1164 cpl_ensure_code(mask != NULL, CPL_ERROR_NULL_INPUT);
1170 *spec = cpl_vector_new(nz));
1172 *spec_var = cpl_vector_new(nz));
1174 pspec = cpl_vector_get_data(*spec));
1176 pspec_var = cpl_vector_get_data(*spec_var));
1178 for (
int z = 0; z < nz; z++) {
1188 pspec_var[z] = hv.error*hv.error;
1193 ret_error = cpl_error_get_code();
1207cpl_bivector * eris_ifu_opt_extr_helper_usepix(
const cpl_mask *mask,
int *n_usepix)
1209 cpl_bivector *usepix = NULL;
1215 const cpl_binary *pmask = NULL;
1217 cpl_ensure(mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1220 nx = cpl_mask_get_size_x(mask);
1221 ny = cpl_mask_get_size_y(mask);
1224 *n_usepix = (nx * ny) - cpl_mask_count(mask);
1225 cpl_msg_debug(cpl_func,
"optimal extraction: n_usepix: %d", *n_usepix);
1227 if (*n_usepix > 0) {
1228 usepix = cpl_bivector_new(*n_usepix);
1229 pmask = cpl_mask_get_data_const(mask);
1231 px = cpl_vector_get_data(cpl_bivector_get_x(usepix));
1232 py = cpl_vector_get_data(cpl_bivector_get_y(usepix));
1234 for (
int y = 0; y < ny; y++) {
1235 for (
int x = 0; x < nx; x++) {
1236 if (pmask[x+y*nx] == GOOD_PIX) {
1260cpl_error_code eris_ifu_opt_extr_helper_fill_vertical(cpl_image *img,
const eris_ifu_vector *vec)
1262 cpl_ensure_code(vec, CPL_ERROR_NULL_INPUT);
1264 double *pimg = cpl_image_get_data_double(img);
1265 cpl_size nx = cpl_image_get_size_x(img),
1266 ny = cpl_image_get_size_y(img);
1267 double *pkvmask = cpl_vector_get_data(vec->data),
1268 *pkvdata = cpl_vector_get_data(vec->mask);
1272 for (
int y = 0; y < ny; y++) {
1273 for (
int x = 0; x < nx; x++) {
1274 if (pkvmask[y] > 0.5) {
1275 pimg[x+y*nx] = pkvdata[y];
1277 cpl_image_reject(img, x+1, y+1);
1282 return CPL_ERROR_NONE;
1294void eris_ifu_opt_extr_helper_fill_horizontal(cpl_image *img,
const cpl_image *slice,
const cpl_bivector *usepix,
int row,
int power) {
1295 double *pimg = cpl_image_get_data_double(img);
1296 const double *pslice_d = NULL;
1297 const int *pslice_i = NULL;
1298 cpl_size nx = cpl_image_get_size_x(slice);
1299 cpl_type type = cpl_image_get_type(slice);
1300 const double *px = cpl_vector_get_data_const(cpl_bivector_get_x_const(usepix)),
1301 *py = cpl_vector_get_data_const(cpl_bivector_get_y_const(usepix));
1302 cpl_size n_usepix = cpl_bivector_get_size(usepix);
1304 if (type == CPL_TYPE_DOUBLE) {
1305 pslice_d = cpl_image_get_data_double_const(slice);
1306 }
else if (type == CPL_TYPE_INT) {
1307 pslice_i = cpl_image_get_data_int_const(slice);
1312 if (type == CPL_TYPE_DOUBLE) {
1313 for (
int i = 0; i < n_usepix; i++) {
1314 double val = pslice_d[(int)px[i]+(
int)py[i]*nx];
1316 pimg[i+row*n_usepix] = pow(val, 2);
1318 pimg[i+row*n_usepix] = val;
1322 for (
int i = 0; i < n_usepix; i++) {
1323 int val = pslice_i[(int)px[i]+(
int)py[i]*nx];
1325 pimg[i+row*n_usepix] = pow(val, 2);
1327 pimg[i+row*n_usepix] = val;
1339void eris_ifu_opt_extr_helper_set_positive(cpl_image *img) {
1340 double *pimg = cpl_image_get_data_double(img);
1341 cpl_size nx = cpl_image_get_size_x(img),
1342 ny = cpl_image_get_size_y(img);
1345 for (
int x = 0; x < nx; x++) {
1346 for (
int y = 0; y < ny; y++) {
1347 if ((pimg[x+y*nx] < 0.) || isnan(pimg[x+y*nx])) {
1353 cpl_msg_debug(cpl_func,
"optimal extraction: Resetting %d negative values in original PSF", n_neg);
1362cpl_vector* eris_ifu_opt_extr_get_col(
const cpl_image *img,
int colnr)
1366 double *pvec = NULL;
1367 const double *pimg = NULL;
1368 cpl_vector *vec = NULL;
1370 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
1372 nx = cpl_image_get_size_x(img);
1373 ny = cpl_image_get_size_y(img);
1375 cpl_ensure(colnr <= nx, CPL_ERROR_ILLEGAL_INPUT, NULL);
1377 vec = cpl_vector_new(ny);
1378 pvec = cpl_vector_get_data(vec);
1379 pimg = cpl_image_get_data_double_const(img);
1381 for (
int y = 0; y < ny; y++) {
1382 pvec[y] = pimg[colnr+y*nx];
1394cpl_vector* eris_ifu_opt_extr_get_row(
const cpl_image *img,
int rownr)
1398 double *pvec = NULL;
1399 const double *pimg = NULL;
1400 cpl_vector *vec = NULL;
1402 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
1404 nx = cpl_image_get_size_x(img);
1405 ny = cpl_image_get_size_y(img);
1407 cpl_ensure(rownr <= ny, CPL_ERROR_ILLEGAL_INPUT, NULL);
1409 vec = cpl_vector_new(nx);
1410 pvec = cpl_vector_get_data(vec);
1411 pimg = cpl_image_get_data_double_const(img);
1413 for (
int x = 0; x < nx; x++) {
1414 pvec[x] = pimg[x+rownr*nx];
1426cpl_error_code eris_ifu_opt_extr_set_row(cpl_image *img,
1428 const cpl_vector *vec)
1432 const double *pvec = NULL;
1433 double *pimg = NULL;
1435 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1436 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1438 nx = cpl_image_get_size_x(img);
1439 ny = cpl_image_get_size_y(img);
1441 cpl_ensure_code(rownr <= ny, CPL_ERROR_ILLEGAL_INPUT);
1442 cpl_ensure_code(nx == cpl_vector_get_size(vec), CPL_ERROR_ILLEGAL_INPUT);
1444 pvec = cpl_vector_get_data_const(vec);
1445 pimg = cpl_image_get_data_double(img);
1447 for (
int x = 0; x < nx; x++) {
1448 pimg[x+rownr*nx] = pvec[x];
1451 return cpl_error_get_code();
1461cpl_error_code eris_ifu_opt_extr_set_col(cpl_image *img,
1463 const cpl_vector *vec)
1467 double *pimg = NULL;
1468 const double *pvec = NULL;
1470 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1471 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1473 nx = cpl_image_get_size_x(img);
1474 ny = cpl_image_get_size_y(img);
1476 cpl_ensure_code(colnr <= nx, CPL_ERROR_ILLEGAL_INPUT);
1477 cpl_ensure_code(ny == cpl_vector_get_size(vec), CPL_ERROR_ILLEGAL_INPUT);
1479 pvec = cpl_vector_get_data_const(vec);
1480 pimg = cpl_image_get_data_double(img);
1482 for (
int y = 0; y < ny; y++) {
1483 pimg[colnr+y*nx] = pvec[y];
1486 return cpl_error_get_code();
1489cpl_vector* eris_ifu_opt_extr_create_lambda(
int size,
double startLambda,
double deltaLambda)
1491 cpl_vector *lambda = cpl_vector_new(size);
1492 double *pLambda = cpl_vector_get_data(lambda);
1494 for (
int i = 0; i < size; i++) {
1495 pLambda[i] = startLambda + (double)i * deltaLambda;
1500cpl_error_code eris_ifu_opt_extr_vector_sqrt(cpl_vector *vec)
1502 double *pvec = cpl_vector_get_data(vec);
1503 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1505 for (
int i = 0; i < cpl_vector_get_size(vec); i++) {
1506 pvec[i] = sqrt(pvec[i]);
1508 return cpl_error_get_code();
1511cpl_bivector* eris_ifu_opt_extr_doit(
const hdrl_imagelist *cube,
1512 const cpl_imagelist *cube_dqi,
1513 const cpl_mask *mask,
1514 const eris_ifu_vector *spec,
1515 const eris_ifu_vector *spec_var,
1519 cpl_vector **error_out)
1521 cpl_bivector *spectrum = NULL,
1524 cpl_vector *vec = NULL,
1529 eris_ifu_vector *speco = NULL,
1530 *spec_var_err = NULL,
1532 cpl_image *spec1 = NULL,
1545 double clipfrac = 0.9,
1552 const double *pvec = NULL,
1555 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
1556 cpl_ensure(cube_dqi != NULL, CPL_ERROR_NULL_INPUT, NULL);
1557 cpl_ensure(mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1558 cpl_ensure(spec != NULL, CPL_ERROR_NULL_INPUT, NULL);
1559 cpl_ensure(spec_var != NULL, CPL_ERROR_NULL_INPUT, NULL);
1560 cpl_ensure(error_out != NULL, CPL_ERROR_NULL_INPUT, NULL);
1562 CPL_ERROR_ILLEGAL_INPUT, NULL);
1564 CPL_ERROR_ILLEGAL_INPUT, NULL);
1566 CPL_ERROR_ILLEGAL_INPUT, NULL);
1577 usepix = eris_ifu_opt_extr_helper_usepix(mask, &n_usepix);
1580 spec1 = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1581 psfvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1583 varvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1584 qualvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1585 pqualvals = cpl_image_get_data_double(qualvals);
1597 for (
int bigloop = 0; bigloop <= 1; bigloop++) {
1601 eris_ifu_opt_extr_helper_fill_vertical(spec1, speco));
1605 for (
int z = 0; z < nz; z++) {
1609 const cpl_image *slice_q = cpl_imagelist_get_const(cube_dqi, z);
1611 eris_ifu_opt_extr_helper_fill_horizontal(psfvals, slice_d, usepix, z, FALSE);
1612 eris_ifu_opt_extr_helper_fill_horizontal(varvals, slice_e, usepix, z, TRUE);
1613 eris_ifu_opt_extr_helper_fill_horizontal(qualvals, slice_q, usepix, z, FALSE);
1616 eris_ifu_opt_extr_helper_set_positive(psfvals);
1618 if (productDepth >= PD_DEBUG) {
1627 reject = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1628 preject = cpl_image_get_data_double(reject);
1631 new_vec = cpl_vector_new(nz);
1632 pnew_vec = cpl_vector_get_data(new_vec);
1634 for (
int iloop = 0; iloop <= 1; iloop++) {
1635 if (psfmod != NULL) {
1638 psfmod = cpl_image_divide_create(psfvals, spec1);
1639 eris_ifu_opt_extr_helper_set_positive(psfmod);
1642 if (productDepth >= PD_DEBUG) {
1647 for (
int n = 0; n < n_usepix; n++) {
1648 vec = eris_ifu_opt_extr_get_col(psfmod, n);
1649 pvec = cpl_vector_get_data_const(vec);
1655 cpl_vector_multiply(vec_err, vec));
1657 rejectvec = eris_ifu_opt_extr_get_col(reject, n);
1658 prejectvec = cpl_vector_get_data_const(rejectvec);
1662 keep0 = cpl_vector_new(nz);
1663 cpl_vector_fill(keep0, -1.0);
1664 pkeep0 = cpl_vector_get_data(keep0);
1667 for (cpl_size iz = 0; iz < nz; iz++) {
1669 if ((fabs(prejectvec[iz]) < 1e-5) &&
1678 cpl_vector_delete(rejectvec);
1681 if (keep0 != NULL) {
1682 pkeep0 = cpl_vector_get_data(keep0);
1685 if ((productDepth >= PD_DEBUG) && (n==92)) {
1690 for (
int z = 0; z < nz; z++) {
1692 int s = cpl_vector_get_size(keep0);
1693 cpl_vector* ttt = cpl_vector_new(s);
1694 double *pttt = cpl_vector_get_data(ttt);
1695 cpl_vector_fill(ttt, -1.0);
1697 for (
int iz = 0; iz < s; iz++) {
1698 int v = (int)(pkeep0[iz] +.5);
1699 if ((v > z-sm) && (v < z+sm)) {
1703 if (productDepth >= PD_DEBUG) {
1712 *ones = cpl_vector_new(cpl_vector_get_size(els));
1715 if ((productDepth >= PD_DEBUG) && (n==92) && (z == 1000)) {
1721 cpl_vector_fill(ones, 1.0);
1722 cpl_vector_divide(els, els_err);
1723 cpl_vector_divide(ones, els_err);
1724 pnew_vec[z] = cpl_vector_get_sum(els) / cpl_vector_get_sum(ones);
1740 eris_ifu_opt_extr_set_col(psfmod, n, new_vec));
1742 if ((productDepth >= PD_DEBUG) && (n==92)) {
1752 if (productDepth >= PD_DEBUG) {
1763 cpl_image *psfmod_tmp = cpl_image_multiply_create(psfmod, spec1);
1764 snr2 = cpl_image_subtract_create(psfvals, psfmod_tmp);
1765 cpl_image_power(snr2, 2);
1766 cpl_image_divide(snr2, varvals);
1769 if (productDepth >= PD_DEBUG) {
1778 for (
int iz = 0; iz < nz; iz++) {
1779 vec = eris_ifu_opt_extr_get_row(snr2, iz);
1780 int n_fin = eris_ifu_opt_extr_get_not_finite(vec);
1781 if (n_fin > n_usepix*0.25) {
1783 cpl_vector_power(vec, 2);
1784 eris_ifu_cpl_vector_sqrt(vec);
1786 cpl_vector_sort(vec, CPL_SORT_ASCENDING);
1787 double clip = cpl_vector_get(vec, n_usepix*clipfrac)*5;
1789 if ((tmp != NULL) && (cpl_vector_get_size(tmp) > 0)) {
1790 for (
int ii = 0; ii < cpl_vector_get_size(tmp); ii++) {
1791 preject[(int)(cpl_vector_get(tmp, ii)+.5)+iz*n_usepix] = 1;
1796 for (
int ii = 0; ii < n_usepix; ii++) {
1797 preject[ii+iz*n_usepix] = 1;
1803 if (productDepth >= PD_DEBUG) {
1810 for (
int ii = 0; ii < n_usepix * nz; ii++) {
1811 if (pqualvals[ii] > 0) {
1816 if (productDepth >= PD_DEBUG) {
1827 if (productDepth >= PD_DEBUG) {
1840 psfmodnew = cpl_image_duplicate(psfmod));
1845 residual = cpl_image_multiply_create(psfmod, spec1);
1846 cpl_image_subtract(residual, psfvals);
1847 cpl_image_multiply_scalar(residual, -1.);
1848 cpl_image_power(residual, 2);
1849 cpl_image_divide(residual, varvals);
1851 if (productDepth >= PD_DEBUG) {
1861 for (
int iz = 0; iz < nz; iz++) {
1862 cpl_vector *resvec0 = eris_ifu_opt_extr_get_row(residual, iz);
1863 double *presvec0 = cpl_vector_get_data(resvec0);
1865 if (productDepth >= PD_DEBUG) {
1870 keep0 = cpl_vector_new(n_usepix);
1871 cpl_vector_fill(keep0, -1.0);
1872 pkeep0 = cpl_vector_get_data(keep0);
1874 for (
int ii = 0; ii < n_usepix; ii++) {
1884 if (productDepth >= PD_DEBUG) {
1888 cpl_vector *p = eris_ifu_opt_extr_get_row(psfmod, iz);
1889 double *pp = cpl_vector_get_data(p);
1891 if ((keep0 != NULL) && (cpl_vector_get_size(keep0) > n_usepix*0.25)) {
1892 int nkeep = cpl_vector_get_size(keep0);
1894 *resvecs = cpl_vector_duplicate(resvec);
1895 cpl_vector_sort(resvecs, CPL_SORT_ASCENDING);
1897 if ((productDepth >= PD_DEBUG) && (iz == 1000)){
1901 double clip = cpl_vector_get(resvecs, (
int)(nkeep*clipfrac+.5)-1) * 5.;
1906 cpl_vector *q = eris_ifu_opt_extr_get_row(qualvals, iz);
1907 double *pq = cpl_vector_get_data(q);
1909 keep0 = cpl_vector_new(n_usepix);
1910 cpl_vector_fill(keep0, -1.0);
1911 pkeep0 = cpl_vector_get_data(keep0);
1913 for (
int ii = 0; ii < n_usepix; ii++) {
1914 if ((presvec0[ii] > clip) || (pq[ii] == 1)) {
1920 if (keep0 != NULL) {
1921 pkeep0 = cpl_vector_get_data(keep0);
1922 for (
int ii = 0; ii < cpl_vector_get_size(keep0); ii++) {
1923 pp[(int)(pkeep0[ii])] = 0.;
1927 double sum = cpl_vector_get_sum(p);
1928 for (
int ii = 0; ii < cpl_vector_get_size(p); ii++) {
1937 cpl_vector_fill(p, 0.));
1941 eris_ifu_opt_extr_set_row(psfmodnew, iz, p));
1943 cpl_vector *vals = eris_ifu_opt_extr_get_row(psfvals, iz),
1944 *var = eris_ifu_opt_extr_get_row(varvals, iz);
1946 eris_ifu_opt_extr_convert_0_to_NaN_vec(var);
1949 cpl_vector *tt = cpl_vector_duplicate(p);
1950 cpl_vector_multiply(tt, vals);
1951 cpl_vector_divide(tt, var);
1952 cpl_vector_power(p, 2.0);
1953 cpl_vector_divide(p, var);
1954 double sum_data = cpl_vector_get_sum(tt),
1955 sum_weight = cpl_vector_get_sum(p);
1986 cpl_vector *lambda = eris_ifu_opt_extr_create_lambda(nz, startLambda, deltaLambda);
1989 spectrum = cpl_bivector_wrap_vectors(lambda, speco2));
2023int eris_ifu_opt_extr_get_not_finite(cpl_vector *vec) {
2025 double *pvec = NULL;
2027 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
2029 pvec = cpl_vector_get_data(vec);
2031 for (
int i = 0; i < cpl_vector_get_size(vec); i++) {
2044void eris_ifu_opt_extr_convert_0_to_NaN_vec(cpl_vector *vec)
2047 double *pvec = NULL;
2050 pvec = cpl_vector_get_data(vec);
2052 x = cpl_vector_get_size(vec);
2054 for (
int i = 0 ; i < x; i++) {
2055 if (fabs(pvec[i]) < DBL_ZERO_TOLERANCE) {
2062cpl_image* eris_ifu_opt_extr_estimate_radius_helper(
const cpl_image *img,
2063 cpl_size center_x, cpl_size center_y,
2065 cpl_size *llx, cpl_size *lly,
2066 cpl_size *urx, cpl_size *ury)
2068 double half_maxval = 0.,
2070 const double *pimg = NULL;
2071 cpl_image *mask = NULL;
2075 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
2078 pimg = cpl_image_get_data_double_const(img);
2079 nx = cpl_image_get_size_x(img);
2080 ny = cpl_image_get_size_y(img);
2081 half_maxval = pimg[center_x+nx*center_y] / 2;
2083 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
2084 pmask = cpl_image_get_data_double(mask);
2086 *llx = center_x - radius;
2087 *lly = center_y - radius;
2088 *urx = center_x + radius;
2089 *ury = center_y + radius;
2103 for (cpl_size x = *llx; x < *urx; x++) {
2104 for (cpl_size y = *lly; y < *ury; y++) {
2105 if (pimg[x+nx*y] >= half_maxval) {
2119double eris_ifu_opt_extr_estimate_radius(
const cpl_image *img,
2120 cpl_size center_x, cpl_size center_y,
2121 double initial_radius,
2126 area_rectangle = 1.,
2128 cpl_image *mask = NULL;
2136 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, -1.);
2139 nx = cpl_image_get_size_x(img);
2140 ny = cpl_image_get_size_y(img);
2142 double max_radius = nx/2;
2143 if (ny/2 < max_radius) {
2146 radius = initial_radius - inc_radius;
2149 while ((area_mask / area_rectangle >= CPL_MATH_PI_4) && (radius < max_radius)) {
2150 radius += inc_radius;
2152 mask = eris_ifu_opt_extr_estimate_radius_helper(img,
2155 &llx, &lly, &urx, &ury);
2156 area_rectangle = (urx-llx)*(ury-lly);
2157 area_mask = cpl_image_get_flux(mask);
2158 if (productDepth >= PD_DEBUG) {
2161 cpl_msg_debug(cpl_func,
" intermediate mask center at (%d/%d), radius: %g, area mask: %g, area rect: %g)",
2162 (
int)center_x, (
int)center_y, radius, area_mask, area_rectangle);
2165 if (productDepth >= PD_DEBUG) {
2168 cpl_msg_debug(cpl_func,
"Final mask center at (%d/%d), radius: %g, area mask: %g, area rect: %g)",
2169 (
int)center_x, (
int)center_y, radius, area_mask, area_rectangle);
2228cpl_error_code eris_ifu_cpl_vector_sqrt(cpl_vector *vec)
2231 double *pvec = NULL;
2232 cpl_error_code err = CPL_ERROR_NONE;
2234 cpl_ensure_code(vec, CPL_ERROR_NULL_INPUT);
2238 n = cpl_vector_get_size(vec);
2242 pvec = cpl_vector_get_data(vec));
2245 for (
int i = 0; i < n; i++) {
2249 pvec[i] = sqrt(pvec[i]);
2255 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.