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"
80hdrl_image* eris_ifu_extract_spec_collapse(hdrl_imagelist *cube,
81 cpl_image **contribute)
83 hdrl_image *hImage = NULL;
85 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
86 cpl_ensure(contribute != NULL, CPL_ERROR_NULL_INPUT, NULL);
91 &hImage, contribute));
113eris_ifu_extract_free_esSofStruct(
struct esSofStruct* self){
144cpl_image * eris_ifu_extract_spec_create_fit_mask(
const hdrl_image* img)
146 cpl_image *mask = NULL;
147 const cpl_image *image = NULL;
148 cpl_array *gauss_params = NULL;
150 cpl_size xposcen, yposcen;
151 cpl_size xwinsize, ywinsize;
153 cpl_ensure(img, CPL_ERROR_NULL_INPUT, NULL);
158 nx = cpl_image_get_size_x(image);
159 ny = cpl_image_get_size_y(image);
165 BRK_IF_NULL(gauss_params = cpl_array_new(7, CPL_TYPE_DOUBLE));
166 BRK_IF_ERROR(cpl_fit_image_gaussian(image, NULL, xposcen, yposcen,
167 xwinsize, ywinsize, gauss_params,
172 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
174 for (cpl_size iy=1; iy <= ny ; iy++) {
175 for (cpl_size ix=1; ix <= nx ; ix++) {
176 cpl_image_set(mask, ix, iy,
177 cpl_gaussian_eval_2d(gauss_params, (
double) ix, (
double) iy));
184 cpl_image_subtract_scalar(mask, cpl_image_get_min(mask));
185 cpl_image_divide_scalar(mask, cpl_image_get_max(mask));
186 cpl_array_delete(gauss_params);
214cpl_image * eris_ifu_extract_spec_create_circle_mask(
221 cpl_image *mask = NULL;
222 double cen_x, cen_y, x_lo, y_lo, x_hi, y_hi, r;
225 cpl_ensure(center_x > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
226 cpl_ensure(center_y > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
227 cpl_ensure(radius > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
228 cpl_ensure(nx > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
229 cpl_ensure(ny > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
232 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
233 pmask = cpl_image_get_data_double(mask);
235 cen_x = (double) center_x - 1.0;
236 cen_y = (double) center_y - 1.0;
238 x_lo = floor(cen_x - radius);
239 if (x_lo < 0) x_lo = 0;
240 y_lo = floor(cen_y - radius);
241 if (y_lo < 0) y_lo = 0;
242 x_hi = ceil(cen_x + radius);
243 if (x_hi > nx) x_hi = (int) nx;
244 y_hi = ceil(cen_y + radius);
245 if (y_hi > ny) y_hi = (int) ny;
246 for (
int x = (
int) x_lo; x < x_hi; x++) {
247 for (
int y = (
int) y_lo; y < y_hi; y++) {
248 r = sqrt(pow(x - cen_x,2) + pow(y - cen_y,2));
249 if (r <= radius) pmask[x + y * nx] = 1.0;
283cpl_image * eris_ifu_extract_spec_create_mask(
284 struct esParamStruct params,
285 struct esSofStruct sof,
286 const hdrl_image *collapsedCube,
289 cpl_image *mask = NULL;
294 const cpl_image *img;
297 switch (params.mask_method) {
302 cpl_image_get_maxpos(
306 mask = eris_ifu_extract_spec_create_circle_mask(center_x, center_y,
312 mask = eris_ifu_extract_spec_create_circle_mask(params.center_x,
320 cpl_image_get_maxpos(img, ¢er_x, ¢er_y);
324 double radius = eris_ifu_opt_extr_estimate_radius(img,
331 mask = eris_ifu_extract_spec_create_circle_mask(center_x, center_y,
337 mask = eris_ifu_extract_spec_create_fit_mask(collapsedCube));
341 "Internal error: unknown mask method %d",
345 nx = cpl_image_get_size_x(mask);
346 ny = cpl_image_get_size_y(mask);
347 if (nx != sof.nx || ny != sof.ny) {
349 "Dimensions of mask don't match with the cube");
388cpl_bivector * eris_ifu_extract_spectrum(hdrl_imagelist *cube,
393 cpl_vector **totalFlux,
394 cpl_vector **quality)
396 cpl_bivector *spectrum = NULL;
397 cpl_imagelist *data_in = NULL;
398 cpl_imagelist *error_in = NULL;
399 const cpl_image *tmpDataImg = NULL;
400 const cpl_image *tmpErrorImg = NULL;
401 const cpl_mask *bpm = NULL;
402 const double *pTmpData = NULL;
403 const double *pTmpError = NULL;
404 const cpl_binary *pBpm = NULL;
405 const double *pMask = NULL;
408 cpl_vector *lambda = NULL;
409 cpl_vector *spec_data = NULL;
410 cpl_vector *spec_error = NULL;
411 cpl_vector *spec_totFlux = NULL;
412 cpl_vector *spec_qual = NULL;
413 double *pLambda = NULL;
414 double *pData = NULL;
415 double *pError = NULL;
416 double *pTotFlux = NULL;
417 double *pqual = NULL;
424 cpl_ensure(cube != NULL,CPL_ERROR_NULL_INPUT, NULL);
425 cpl_ensure(mask != NULL,CPL_ERROR_NULL_INPUT, NULL);
426 cpl_ensure(error != NULL,CPL_ERROR_NULL_INPUT, NULL);
427 cpl_ensure(totalFlux != NULL,CPL_ERROR_NULL_INPUT, NULL);
434 ASSURE((nx == cpl_image_get_size_x(mask)) &&
435 (ny == cpl_image_get_size_y(mask)),
436 CPL_ERROR_ILLEGAL_INPUT,
437 "Data cube and mask don't have same dimensions!");
442 for (cpl_size sz = 0; sz < nz; sz++) {
449 lambda = cpl_vector_new(nz);
450 spec_data = cpl_vector_new(nz);
451 spec_error = cpl_vector_new(nz);
452 spec_totFlux = cpl_vector_new(nz);
453 spec_qual = cpl_vector_new(nz);
454 pLambda = cpl_vector_get_data(lambda);
455 pData = cpl_vector_get_data(spec_data);
456 pError = cpl_vector_get_data(spec_error);
457 pTotFlux = cpl_vector_get_data(spec_totFlux);
458 pqual = cpl_vector_get_data(spec_qual);
459 pMask = cpl_image_get_data_double_const(mask);
464 for (cpl_size sz = 0; sz < nz; sz++) {
465 tmpDataImg = cpl_imagelist_get(data_in, sz);
466 tmpErrorImg = cpl_imagelist_get(error_in, sz);
467 bpm = cpl_image_get_bpm_const(tmpDataImg);
468 pTmpData = cpl_image_get_data_double_const(tmpDataImg);
469 pTmpError = cpl_image_get_data_double_const(tmpErrorImg);
470 pBpm = cpl_mask_get_data_const(bpm);
478 for (cpl_size j = 0; j < ny; j++) {
479 for (cpl_size i = 0; i < nx; i++) {
485 sumData += pTmpData[p] * pMask[p];
486 sumVariance += pow(pTmpError[p] * pMask[p],2);
495 sumData += pTmpData[p];
496 sumVariance += pow(pTmpError[p],2);
503 if ((valid ==
true) && (fabs(weights) > DBL_ZERO_TOLERANCE)) {
504 pLambda[fill_nz] = startLambda + (double) sz * deltaLambda;
505 pData[fill_nz] = sumData / weights;
506 pError[fill_nz] = sqrt(sumVariance) / weights;
507 pTotFlux[fill_nz] = sumData;
516 BRK_IF_ERROR(cpl_vector_set_size(spec_totFlux, fill_nz));
519 spectrum = cpl_bivector_wrap_vectors(lambda, spec_data);
521 *totalFlux = spec_totFlux;
522 *quality = spec_qual;
523 cpl_imagelist_delete(data_in);
524 cpl_imagelist_delete(error_in);
1075cpl_bivector * eris_ifu_optimal_extraction(
const hdrl_imagelist *cube,
1076 const cpl_imagelist *cube_dqi,
1077 const cpl_image *img_mask,
1081 cpl_vector **error_out)
1083 cpl_bivector *spectrum = NULL;
1084 cpl_mask *mask = NULL;
1085 cpl_vector *spec = NULL,
1087 eris_ifu_vector *spec2 = NULL,
1097 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
1098 cpl_ensure(cube_dqi != NULL, CPL_ERROR_NULL_INPUT, NULL);
1099 cpl_ensure(img_mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1100 cpl_ensure(startLambda > 1.0, CPL_ERROR_NULL_INPUT, NULL);
1101 cpl_ensure(deltaLambda > 0, CPL_ERROR_NULL_INPUT, NULL);
1102 cpl_ensure(error_out != NULL,CPL_ERROR_NULL_INPUT, NULL);
1127 if (productDepth >= PD_DEBUG) {
1132 eris_ifu_opt_extr_simple_extraction(cube, mask, &spec, &spec_var));
1133 if (productDepth >= PD_DEBUG) {
1141 spectrum = eris_ifu_opt_extr_doit(cube, cube_dqi, mask,
1143 startLambda, deltaLambda,
1149 if (productDepth >= PD_DEBUG) {
1156 eris_ifu_opt_extr_vector_sqrt(spec_var);
1198cpl_error_code eris_ifu_opt_extr_get_center_fwhm(
const hdrl_image *hdrl_img,
1204 cpl_error_code ret_error = CPL_ERROR_NONE;
1205 double maxval = -9999e10;
1206 const cpl_image *img_data = NULL;
1207 const double *pimg_data = NULL;
1208 const cpl_mask *img_mask = NULL;
1209 const cpl_binary *pimg_mask = NULL;
1213 cpl_ensure_code(hdrl_img != NULL, CPL_ERROR_NULL_INPUT);
1214 cpl_ensure_code(edge_trim >= 0, CPL_ERROR_NULL_INPUT);
1219 nx = cpl_image_get_size_x(img_data);
1221 pimg_data = cpl_image_get_data_double_const(img_data));
1225 pimg_mask = cpl_mask_get_data_const(img_mask));
1230 if ((pimg_mask[x+y*nx] == GOOD_PIX) &&
1231 (pimg_data[x+y*nx] > maxval) &&
1232 (!isnan(pimg_data[x+y*nx])))
1234 maxval = pimg_data[x+y*nx];
1241 cpl_msg_debug(cpl_func,
"Mask max. value: %g)", maxval);
1247 if ((pimg_mask[x+y*nx] == GOOD_PIX) &&
1248 (pimg_data[x+y*nx] > maxval) &&
1249 (!isnan(pimg_data[x+y*nx])))
1261 ret_error = cpl_error_get_code();
1289cpl_mask* eris_ifu_opt_extr_create_mask(
int nx,
1295 cpl_mask *mask = NULL;
1296 cpl_binary *pmask =NULL;
1298 cpl_ensure(nx > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1299 cpl_ensure(ny > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1300 cpl_ensure(xcen > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1301 cpl_ensure(ycen > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1302 cpl_ensure(fwhm > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
1306 mask = cpl_mask_new(nx, ny));
1308 pmask = cpl_mask_get_data(mask));
1310 for (
int x = 0; x < nx; x++) {
1311 for (
int y = 0; y < ny; y++) {
1312 if (fwhm <= sqrt(pow(x-xcen,2)+pow(y-ycen,2))) {
1314 pmask[x+y*nx] = BAD_PIX;
1317 pmask[x+y*nx] = GOOD_PIX;
1347cpl_error_code eris_ifu_opt_extr_simple_extraction(
const hdrl_imagelist *cube,
1348 const cpl_mask *mask,
1350 cpl_vector **spec_var)
1352 cpl_error_code ret_error = CPL_ERROR_NONE;
1353 const hdrl_image *tmp_img = NULL;
1354 hdrl_image *tmp_img2 = NULL;
1355 double *pspec = NULL,
1360 cpl_ensure_code(cube != NULL, CPL_ERROR_NULL_INPUT);
1361 cpl_ensure_code(mask != NULL, CPL_ERROR_NULL_INPUT);
1367 *spec = cpl_vector_new(nz));
1369 *spec_var = cpl_vector_new(nz));
1371 pspec = cpl_vector_get_data(*spec));
1373 pspec_var = cpl_vector_get_data(*spec_var));
1375 for (
int z = 0; z < nz; z++) {
1385 pspec_var[z] = hv.error*hv.error;
1390 ret_error = cpl_error_get_code();
1413cpl_bivector * eris_ifu_opt_extr_helper_usepix(
const cpl_mask *mask,
int *n_usepix)
1415 cpl_bivector *usepix = NULL;
1421 const cpl_binary *pmask = NULL;
1423 cpl_ensure(mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1426 nx = cpl_mask_get_size_x(mask);
1427 ny = cpl_mask_get_size_y(mask);
1430 *n_usepix = (nx * ny) - cpl_mask_count(mask);
1431 cpl_msg_debug(cpl_func,
"optimal extraction: n_usepix: %d", *n_usepix);
1433 if (*n_usepix > 0) {
1434 usepix = cpl_bivector_new(*n_usepix);
1435 pmask = cpl_mask_get_data_const(mask);
1437 px = cpl_vector_get_data(cpl_bivector_get_x(usepix));
1438 py = cpl_vector_get_data(cpl_bivector_get_y(usepix));
1440 for (
int y = 0; y < ny; y++) {
1441 for (
int x = 0; x < nx; x++) {
1442 if (pmask[x+y*nx] == GOOD_PIX) {
1472cpl_error_code eris_ifu_opt_extr_helper_fill_vertical(cpl_image *img,
const eris_ifu_vector *vec)
1474 cpl_ensure_code(vec, CPL_ERROR_NULL_INPUT);
1476 double *pimg = cpl_image_get_data_double(img);
1477 cpl_size nx = cpl_image_get_size_x(img),
1478 ny = cpl_image_get_size_y(img);
1479 double *pkvmask = cpl_vector_get_data(vec->data),
1480 *pkvdata = cpl_vector_get_data(vec->mask);
1484 for (
int y = 0; y < ny; y++) {
1485 for (
int x = 0; x < nx; x++) {
1486 if (pkvmask[y] > 0.5) {
1487 pimg[x+y*nx] = pkvdata[y];
1489 cpl_image_reject(img, x+1, y+1);
1494 return CPL_ERROR_NONE;
1514void eris_ifu_opt_extr_helper_fill_horizontal(cpl_image *img,
const cpl_image *slice,
const cpl_bivector *usepix,
int row,
int power) {
1515 double *pimg = cpl_image_get_data_double(img);
1516 const double *pslice_d = NULL;
1517 const int *pslice_i = NULL;
1518 cpl_size nx = cpl_image_get_size_x(slice);
1519 cpl_type type = cpl_image_get_type(slice);
1520 const double *px = cpl_vector_get_data_const(cpl_bivector_get_x_const(usepix)),
1521 *py = cpl_vector_get_data_const(cpl_bivector_get_y_const(usepix));
1522 cpl_size n_usepix = cpl_bivector_get_size(usepix);
1524 if (type == CPL_TYPE_DOUBLE) {
1525 pslice_d = cpl_image_get_data_double_const(slice);
1526 }
else if (type == CPL_TYPE_INT) {
1527 pslice_i = cpl_image_get_data_int_const(slice);
1532 if (type == CPL_TYPE_DOUBLE) {
1533 for (
int i = 0; i < n_usepix; i++) {
1534 double val = pslice_d[(int)px[i]+(
int)py[i]*nx];
1536 pimg[i+row*n_usepix] = pow(val, 2);
1538 pimg[i+row*n_usepix] = val;
1542 for (
int i = 0; i < n_usepix; i++) {
1543 int val = pslice_i[(int)px[i]+(
int)py[i]*nx];
1545 pimg[i+row*n_usepix] = pow(val, 2);
1547 pimg[i+row*n_usepix] = val;
1565void eris_ifu_opt_extr_helper_set_positive(cpl_image *img) {
1566 double *pimg = cpl_image_get_data_double(img);
1567 cpl_size nx = cpl_image_get_size_x(img),
1568 ny = cpl_image_get_size_y(img);
1571 for (
int x = 0; x < nx; x++) {
1572 for (
int y = 0; y < ny; y++) {
1573 if ((pimg[x+y*nx] < 0.) || isnan(pimg[x+y*nx])) {
1579 cpl_msg_debug(cpl_func,
"optimal extraction: Resetting %d negative values in original PSF", n_neg);
1592cpl_vector* eris_ifu_opt_extr_get_col(
const cpl_image *img,
int colnr)
1596 double *pvec = NULL;
1597 const double *pimg = NULL;
1598 cpl_vector *vec = NULL;
1600 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
1602 nx = cpl_image_get_size_x(img);
1603 ny = cpl_image_get_size_y(img);
1605 cpl_ensure(colnr <= nx, CPL_ERROR_ILLEGAL_INPUT, NULL);
1607 vec = cpl_vector_new(ny);
1608 pvec = cpl_vector_get_data(vec);
1609 pimg = cpl_image_get_data_double_const(img);
1611 for (
int y = 0; y < ny; y++) {
1612 pvec[y] = pimg[colnr+y*nx];
1628cpl_vector* eris_ifu_opt_extr_get_row(
const cpl_image *img,
int rownr)
1632 double *pvec = NULL;
1633 const double *pimg = NULL;
1634 cpl_vector *vec = NULL;
1636 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
1638 nx = cpl_image_get_size_x(img);
1639 ny = cpl_image_get_size_y(img);
1641 cpl_ensure(rownr <= ny, CPL_ERROR_ILLEGAL_INPUT, NULL);
1643 vec = cpl_vector_new(nx);
1644 pvec = cpl_vector_get_data(vec);
1645 pimg = cpl_image_get_data_double_const(img);
1647 for (
int x = 0; x < nx; x++) {
1648 pvec[x] = pimg[x+rownr*nx];
1665cpl_error_code eris_ifu_opt_extr_set_row(cpl_image *img,
1667 const cpl_vector *vec)
1671 const double *pvec = NULL;
1672 double *pimg = NULL;
1674 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1675 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1677 nx = cpl_image_get_size_x(img);
1678 ny = cpl_image_get_size_y(img);
1680 cpl_ensure_code(rownr <= ny, CPL_ERROR_ILLEGAL_INPUT);
1681 cpl_ensure_code(nx == cpl_vector_get_size(vec), CPL_ERROR_ILLEGAL_INPUT);
1683 pvec = cpl_vector_get_data_const(vec);
1684 pimg = cpl_image_get_data_double(img);
1686 for (
int x = 0; x < nx; x++) {
1687 pimg[x+rownr*nx] = pvec[x];
1690 return cpl_error_get_code();
1704cpl_error_code eris_ifu_opt_extr_set_col(cpl_image *img,
1706 const cpl_vector *vec)
1710 double *pimg = NULL;
1711 const double *pvec = NULL;
1713 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
1714 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1716 nx = cpl_image_get_size_x(img);
1717 ny = cpl_image_get_size_y(img);
1719 cpl_ensure_code(colnr <= nx, CPL_ERROR_ILLEGAL_INPUT);
1720 cpl_ensure_code(ny == cpl_vector_get_size(vec), CPL_ERROR_ILLEGAL_INPUT);
1722 pvec = cpl_vector_get_data_const(vec);
1723 pimg = cpl_image_get_data_double(img);
1725 for (
int y = 0; y < ny; y++) {
1726 pimg[colnr+y*nx] = pvec[y];
1729 return cpl_error_get_code();
1745cpl_vector* eris_ifu_opt_extr_create_lambda(
int size,
double startLambda,
double deltaLambda)
1747 cpl_vector *lambda = cpl_vector_new(size);
1748 double *pLambda = cpl_vector_get_data(lambda);
1750 for (
int i = 0; i < size; i++) {
1751 pLambda[i] = startLambda + (double)i * deltaLambda;
1766cpl_error_code eris_ifu_opt_extr_vector_sqrt(cpl_vector *vec)
1768 double *pvec = cpl_vector_get_data(vec);
1769 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
1771 for (
int i = 0; i < cpl_vector_get_size(vec); i++) {
1772 pvec[i] = sqrt(pvec[i]);
1774 return cpl_error_get_code();
1805cpl_bivector* eris_ifu_opt_extr_doit(
const hdrl_imagelist *cube,
1806 const cpl_imagelist *cube_dqi,
1807 const cpl_mask *mask,
1808 const eris_ifu_vector *spec,
1809 const eris_ifu_vector *spec_var,
1813 cpl_vector **error_out)
1815 cpl_bivector *spectrum = NULL,
1818 cpl_vector *vec = NULL,
1823 eris_ifu_vector *speco = NULL,
1824 *spec_var_err = NULL,
1826 cpl_image *spec1 = NULL,
1839 double clipfrac = 0.9,
1846 const double *pvec = NULL,
1849 cpl_ensure(cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
1850 cpl_ensure(cube_dqi != NULL, CPL_ERROR_NULL_INPUT, NULL);
1851 cpl_ensure(mask != NULL, CPL_ERROR_NULL_INPUT, NULL);
1852 cpl_ensure(spec != NULL, CPL_ERROR_NULL_INPUT, NULL);
1853 cpl_ensure(spec_var != NULL, CPL_ERROR_NULL_INPUT, NULL);
1854 cpl_ensure(error_out != NULL, CPL_ERROR_NULL_INPUT, NULL);
1856 CPL_ERROR_ILLEGAL_INPUT, NULL);
1858 CPL_ERROR_ILLEGAL_INPUT, NULL);
1860 CPL_ERROR_ILLEGAL_INPUT, NULL);
1871 usepix = eris_ifu_opt_extr_helper_usepix(mask, &n_usepix);
1874 spec1 = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1875 psfvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1877 varvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1878 qualvals = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1879 pqualvals = cpl_image_get_data_double(qualvals);
1891 for (
int bigloop = 0; bigloop <= 1; bigloop++) {
1895 eris_ifu_opt_extr_helper_fill_vertical(spec1, speco));
1899 for (
int z = 0; z < nz; z++) {
1903 const cpl_image *slice_q = cpl_imagelist_get_const(cube_dqi, z);
1905 eris_ifu_opt_extr_helper_fill_horizontal(psfvals, slice_d, usepix, z, FALSE);
1906 eris_ifu_opt_extr_helper_fill_horizontal(varvals, slice_e, usepix, z, TRUE);
1907 eris_ifu_opt_extr_helper_fill_horizontal(qualvals, slice_q, usepix, z, FALSE);
1910 eris_ifu_opt_extr_helper_set_positive(psfvals);
1912 if (productDepth >= PD_DEBUG) {
1921 reject = cpl_image_new(n_usepix, nz, CPL_TYPE_DOUBLE);
1922 preject = cpl_image_get_data_double(reject);
1925 new_vec = cpl_vector_new(nz);
1926 pnew_vec = cpl_vector_get_data(new_vec);
1928 for (
int iloop = 0; iloop <= 1; iloop++) {
1929 if (psfmod != NULL) {
1932 psfmod = cpl_image_divide_create(psfvals, spec1);
1933 eris_ifu_opt_extr_helper_set_positive(psfmod);
1936 if (productDepth >= PD_DEBUG) {
1941 for (
int n = 0; n < n_usepix; n++) {
1942 vec = eris_ifu_opt_extr_get_col(psfmod, n);
1943 pvec = cpl_vector_get_data_const(vec);
1949 cpl_vector_multiply(vec_err, vec));
1951 rejectvec = eris_ifu_opt_extr_get_col(reject, n);
1952 prejectvec = cpl_vector_get_data_const(rejectvec);
1956 keep0 = cpl_vector_new(nz);
1957 cpl_vector_fill(keep0, -1.0);
1958 pkeep0 = cpl_vector_get_data(keep0);
1961 for (cpl_size iz = 0; iz < nz; iz++) {
1963 if ((fabs(prejectvec[iz]) < 1e-5) &&
1972 cpl_vector_delete(rejectvec);
1975 if (keep0 != NULL) {
1976 pkeep0 = cpl_vector_get_data(keep0);
1979 if ((productDepth >= PD_DEBUG) && (n==92)) {
1984 for (
int z = 0; z < nz; z++) {
1986 int s = cpl_vector_get_size(keep0);
1987 cpl_vector* ttt = cpl_vector_new(s);
1988 double *pttt = cpl_vector_get_data(ttt);
1989 cpl_vector_fill(ttt, -1.0);
1991 for (
int iz = 0; iz < s; iz++) {
1992 int v = (int)(pkeep0[iz] +.5);
1993 if ((v > z-sm) && (v < z+sm)) {
1997 if (productDepth >= PD_DEBUG) {
2006 *ones = cpl_vector_new(cpl_vector_get_size(els));
2009 if ((productDepth >= PD_DEBUG) && (n==92) && (z == 1000)) {
2015 cpl_vector_fill(ones, 1.0);
2016 cpl_vector_divide(els, els_err);
2017 cpl_vector_divide(ones, els_err);
2018 pnew_vec[z] = cpl_vector_get_sum(els) / cpl_vector_get_sum(ones);
2034 eris_ifu_opt_extr_set_col(psfmod, n, new_vec));
2036 if ((productDepth >= PD_DEBUG) && (n==92)) {
2046 if (productDepth >= PD_DEBUG) {
2057 cpl_image *psfmod_tmp = cpl_image_multiply_create(psfmod, spec1);
2058 snr2 = cpl_image_subtract_create(psfvals, psfmod_tmp);
2059 cpl_image_power(snr2, 2);
2060 cpl_image_divide(snr2, varvals);
2063 if (productDepth >= PD_DEBUG) {
2072 for (
int iz = 0; iz < nz; iz++) {
2073 vec = eris_ifu_opt_extr_get_row(snr2, iz);
2074 int n_fin = eris_ifu_opt_extr_get_not_finite(vec);
2075 if (n_fin > n_usepix*0.25) {
2077 cpl_vector_power(vec, 2);
2078 eris_ifu_cpl_vector_sqrt(vec);
2080 cpl_vector_sort(vec, CPL_SORT_ASCENDING);
2081 double clip = cpl_vector_get(vec, n_usepix*clipfrac)*5;
2083 if ((tmp != NULL) && (cpl_vector_get_size(tmp) > 0)) {
2084 for (
int ii = 0; ii < cpl_vector_get_size(tmp); ii++) {
2085 preject[(int)(cpl_vector_get(tmp, ii)+.5)+iz*n_usepix] = 1;
2090 for (
int ii = 0; ii < n_usepix; ii++) {
2091 preject[ii+iz*n_usepix] = 1;
2097 if (productDepth >= PD_DEBUG) {
2104 for (
int ii = 0; ii < n_usepix * nz; ii++) {
2105 if (pqualvals[ii] > 0) {
2110 if (productDepth >= PD_DEBUG) {
2121 if (productDepth >= PD_DEBUG) {
2134 psfmodnew = cpl_image_duplicate(psfmod));
2139 residual = cpl_image_multiply_create(psfmod, spec1);
2140 cpl_image_subtract(residual, psfvals);
2141 cpl_image_multiply_scalar(residual, -1.);
2142 cpl_image_power(residual, 2);
2143 cpl_image_divide(residual, varvals);
2145 if (productDepth >= PD_DEBUG) {
2155 for (
int iz = 0; iz < nz; iz++) {
2156 cpl_vector *resvec0 = eris_ifu_opt_extr_get_row(residual, iz);
2157 double *presvec0 = cpl_vector_get_data(resvec0);
2159 if (productDepth >= PD_DEBUG) {
2164 keep0 = cpl_vector_new(n_usepix);
2165 cpl_vector_fill(keep0, -1.0);
2166 pkeep0 = cpl_vector_get_data(keep0);
2168 for (
int ii = 0; ii < n_usepix; ii++) {
2178 if (productDepth >= PD_DEBUG) {
2182 cpl_vector *p = eris_ifu_opt_extr_get_row(psfmod, iz);
2183 double *pp = cpl_vector_get_data(p);
2185 if ((keep0 != NULL) && (cpl_vector_get_size(keep0) > n_usepix*0.25)) {
2186 int nkeep = cpl_vector_get_size(keep0);
2188 *resvecs = cpl_vector_duplicate(resvec);
2189 cpl_vector_sort(resvecs, CPL_SORT_ASCENDING);
2191 if ((productDepth >= PD_DEBUG) && (iz == 1000)){
2195 double clip = cpl_vector_get(resvecs, (
int)(nkeep*clipfrac+.5)-1) * 5.;
2200 cpl_vector *q = eris_ifu_opt_extr_get_row(qualvals, iz);
2201 double *pq = cpl_vector_get_data(q);
2203 keep0 = cpl_vector_new(n_usepix);
2204 cpl_vector_fill(keep0, -1.0);
2205 pkeep0 = cpl_vector_get_data(keep0);
2207 for (
int ii = 0; ii < n_usepix; ii++) {
2208 if ((presvec0[ii] > clip) || (pq[ii] == 1)) {
2214 if (keep0 != NULL) {
2215 pkeep0 = cpl_vector_get_data(keep0);
2216 for (
int ii = 0; ii < cpl_vector_get_size(keep0); ii++) {
2217 pp[(int)(pkeep0[ii])] = 0.;
2221 double sum = cpl_vector_get_sum(p);
2222 for (
int ii = 0; ii < cpl_vector_get_size(p); ii++) {
2231 cpl_vector_fill(p, 0.));
2235 eris_ifu_opt_extr_set_row(psfmodnew, iz, p));
2237 cpl_vector *vals = eris_ifu_opt_extr_get_row(psfvals, iz),
2238 *var = eris_ifu_opt_extr_get_row(varvals, iz);
2240 eris_ifu_opt_extr_convert_0_to_NaN_vec(var);
2243 cpl_vector *tt = cpl_vector_duplicate(p);
2244 cpl_vector_multiply(tt, vals);
2245 cpl_vector_divide(tt, var);
2246 cpl_vector_power(p, 2.0);
2247 cpl_vector_divide(p, var);
2248 double sum_data = cpl_vector_get_sum(tt),
2249 sum_weight = cpl_vector_get_sum(p);
2280 cpl_vector *lambda = eris_ifu_opt_extr_create_lambda(nz, startLambda, deltaLambda);
2283 spectrum = cpl_bivector_wrap_vectors(lambda, speco2));
2319int eris_ifu_opt_extr_get_not_finite(cpl_vector *vec) {
2321 double *pvec = NULL;
2323 cpl_ensure_code(vec != NULL, CPL_ERROR_NULL_INPUT);
2325 pvec = cpl_vector_get_data(vec);
2327 for (
int i = 0; i < cpl_vector_get_size(vec); i++) {
2348void eris_ifu_opt_extr_convert_0_to_NaN_vec(cpl_vector *vec)
2351 double *pvec = NULL;
2354 pvec = cpl_vector_get_data(vec);
2356 x = cpl_vector_get_size(vec);
2358 for (
int i = 0 ; i < x; i++) {
2359 if (fabs(pvec[i]) < DBL_ZERO_TOLERANCE) {
2366cpl_image* eris_ifu_opt_extr_estimate_radius_helper(
const cpl_image *img,
2367 cpl_size center_x, cpl_size center_y,
2369 cpl_size *llx, cpl_size *lly,
2370 cpl_size *urx, cpl_size *ury)
2372 double half_maxval = 0.,
2374 const double *pimg = NULL;
2375 cpl_image *mask = NULL;
2379 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, NULL);
2382 pimg = cpl_image_get_data_double_const(img);
2383 nx = cpl_image_get_size_x(img);
2384 ny = cpl_image_get_size_y(img);
2385 half_maxval = pimg[center_x+nx*center_y] / 2;
2387 mask = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
2388 pmask = cpl_image_get_data_double(mask);
2390 *llx = center_x - radius;
2391 *lly = center_y - radius;
2392 *urx = center_x + radius;
2393 *ury = center_y + radius;
2407 for (cpl_size x = *llx; x < *urx; x++) {
2408 for (cpl_size y = *lly; y < *ury; y++) {
2409 if (pimg[x+nx*y] >= half_maxval) {
2423double eris_ifu_opt_extr_estimate_radius(
const cpl_image *img,
2424 cpl_size center_x, cpl_size center_y,
2425 double initial_radius,
2430 area_rectangle = 1.,
2432 cpl_image *mask = NULL;
2440 cpl_ensure(img != NULL, CPL_ERROR_NULL_INPUT, -1.);
2443 nx = cpl_image_get_size_x(img);
2444 ny = cpl_image_get_size_y(img);
2446 double max_radius = nx/2;
2447 if (ny/2 < max_radius) {
2450 radius = initial_radius - inc_radius;
2453 while ((area_mask / area_rectangle >= CPL_MATH_PI_4) && (radius < max_radius)) {
2454 radius += inc_radius;
2456 mask = eris_ifu_opt_extr_estimate_radius_helper(img,
2459 &llx, &lly, &urx, &ury);
2460 area_rectangle = (urx-llx)*(ury-lly);
2461 area_mask = cpl_image_get_flux(mask);
2462 if (productDepth >= PD_DEBUG) {
2465 cpl_msg_debug(cpl_func,
" intermediate mask center at (%d/%d), radius: %g, area mask: %g, area rect: %g)",
2466 (
int)center_x, (
int)center_y, radius, area_mask, area_rectangle);
2469 if (productDepth >= PD_DEBUG) {
2472 cpl_msg_debug(cpl_func,
"Final mask center at (%d/%d), radius: %g, area mask: %g, area rect: %g)",
2473 (
int)center_x, (
int)center_y, radius, area_mask, area_rectangle);
2532cpl_error_code eris_ifu_cpl_vector_sqrt(cpl_vector *vec)
2535 double *pvec = NULL;
2536 cpl_error_code err = CPL_ERROR_NONE;
2538 cpl_ensure_code(vec, CPL_ERROR_NULL_INPUT);
2542 n = cpl_vector_get_size(vec);
2546 pvec = cpl_vector_get_data(vec));
2549 for (
int i = 0; i < n; i++) {
2553 pvec[i] = sqrt(pvec[i]);
2559 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 for debugging (quick, no DFS overhead)
cpl_error_code eris_ifu_save_image_dbg(const cpl_image *img, const char *filename, int create, const cpl_propertylist *pl)
Save image for debugging (quick, no DFS overhead)
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 for debugging (as vector or table)
cpl_error_code eris_ifu_save_mask_dbg(const cpl_mask *mask, const char *filename, int create, const cpl_propertylist *pl)
Save mask for debugging (quick, no DFS overhead)
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 known 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_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_get_size(const eris_ifu_vector *ev)
Get the size of the 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.
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_sqrt(eris_ifu_vector *ev)
eris_ifu_vector_sqrt
cpl_error_code eris_ifu_vector_power(eris_ifu_vector *ev, double exponent)
Compute the elementwise power of the 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.
double eris_ifu_vector_get_median(const eris_ifu_vector *ev, const enum medianType type)
Compute the median of the elements of a 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.
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.