35#include "eris_nix_lss_utils.h"
36#include "eris_nix_dfs.h"
37#include "eris_nix_utils.h"
67 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
68 cpl_ensure_code(jitters, CPL_ERROR_NULL_INPUT);
70 cpl_msg_info(cpl_func,
"..dividing by slit response");
72 for (cpl_size j = 0; j < jitters->size; j++) {
76 cpl_image * bkg_copy = cpl_image_duplicate(
78 jitters->limages[j]->bkg));
79 cpl_image_reject_value(bkg_copy, CPL_VALUE_NOTFINITE);
85 cpl_size drop_ll = 300;
86 cpl_size drop_ur = 300;
87 cpl_image * bkg_collapse = cpl_image_collapse_median_create(bkg_copy, 0, drop_ll, drop_ur);
93 cpl_size sx = cpl_image_get_size_x(bkg_collapse);
100 for(cpl_size kk = 0; kk < niter; kk++) {
101 maxval = cpl_image_get_max_window(bkg_collapse,drop_ll,1,sx - drop_ur,1);
102 medval = cpl_image_get_median_window(bkg_collapse,drop_ll,1,sx - drop_ur,1);
103 stdval = cpl_image_get_stdev_window(bkg_collapse,drop_ll,1,sx - drop_ur,1);
104 cpl_msg_warning(cpl_func,
"maxval: %g", maxval);
105 cpl_msg_warning(cpl_func,
"medval: %g", medval);
106 cpl_msg_warning(cpl_func,
"stdval: %g", stdval);
107 cpl_mask_threshold_image(cpl_image_get_bpm(bkg_collapse),
109 medval - kappa * stdval,
112 cpl_image_fill_rejected(bkg_collapse, 0.0);
119 medval = cpl_image_get_median(bkg_collapse);
120 cpl_msg_warning(cpl_func,
"medval: %g", medval);
122 cpl_image_divide_scalar(bkg_collapse, medval);
158 cpl_image_delete(bkg_collapse);
159 cpl_image_delete(bkg_copy);
162 return cpl_error_get_code();
176 cpl_image * response_1d) {
180 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
181 cpl_ensure_code(himage_2d, CPL_ERROR_NULL_INPUT);
182 cpl_ensure_code(response_1d, CPL_ERROR_NULL_INPUT);
192 for (cpl_size i = 1; i <= nx; i++) {
194 double slit = cpl_image_get(response_1d, i, 1, &slit_ok);
195 for (cpl_size j = 1; j <= ny; j++) {
199 if (data_ok==0 && slit_ok==0) {
200 data.data = data.data / slit;
201 data.error = data.error / slit;
203 data = (hdrl_value) {0.0, 0.0};
213 return cpl_error_get_code();
260 const cpl_size slice_index,
261 const cpl_vector * guess_pos) {
263 cpl_matrix * line_pos = NULL;
264 cpl_vector * next_guess_pos = NULL;
265 cpl_vector * spectrum1d = NULL;
267 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
269 cpl_ensure(spectrum2d, CPL_ERROR_NULL_INPUT, NULL);
270 cpl_ensure(guess_pos, CPL_ERROR_NULL_INPUT, NULL);
271 cpl_ensure(cpl_vector_get_size(guess_pos) > 0,
272 CPL_ERROR_ILLEGAL_INPUT, NULL);
274 cpl_size nlines = cpl_vector_get_size(guess_pos);
277 line_pos = cpl_matrix_new(nx, nlines);
278 cpl_matrix_fill(line_pos, NAN);
283 next_guess_pos = cpl_vector_duplicate(guess_pos);
285 for (cpl_size ix = slice_index; ix < nx; ix++) {
289 spectrum1d = cpl_vector_new_from_image_column(
292 for (cpl_size line_id=0; line_id < nlines; line_id++) {
293 double line_guess_pos = cpl_vector_get(next_guess_pos, line_id);
295 if (!isnan(fitted_pos)) {
301 cpl_matrix_set(line_pos, ix, line_id, fitted_pos);
302 cpl_vector_set(next_guess_pos, line_id, fitted_pos);
305 cpl_vector_delete(spectrum1d);
307 cpl_vector_delete(next_guess_pos);
311 next_guess_pos = cpl_vector_duplicate(guess_pos);
313 for (cpl_size ix = slice_index-1; ix >= 0; ix--) {
314 spectrum1d = cpl_vector_new_from_image_column(
317 for (cpl_size line_id=0; line_id < nlines; line_id++) {
318 double line_guess_pos = cpl_vector_get(next_guess_pos, line_id);
320 if (!isnan(fitted_pos)) {
321 cpl_matrix_set(line_pos, ix, line_id, fitted_pos);
322 cpl_vector_set(next_guess_pos, line_id, fitted_pos);
325 cpl_vector_delete(spectrum1d);
327 cpl_vector_delete(next_guess_pos);
331 if (cpl_error_get_code() != CPL_ERROR_NONE) {
332 cpl_matrix_delete(line_pos);
362 const double guess_pos,
363 const cpl_size half_width) {
365 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NAN;
366 cpl_ensure(spectrum1d, CPL_ERROR_NULL_INPUT, NAN);
368 cpl_polynomial * line_fit = NULL;
371 cpl_size istart = (cpl_size) guess_pos - half_width;
372 cpl_size istop = (cpl_size) guess_pos + half_width;
373 cpl_size npos = istop - istart + 1;
377 cpl_matrix * pos_chunk = cpl_matrix_new(1, npos);
378 for (cpl_size i = 0; i < npos; i++) {
379 cpl_matrix_set(pos_chunk, 0, i, (
double) (i + istart));
385 cpl_vector * spectrum_chunk = cpl_vector_extract(spectrum1d,
387 const double * spectrum_chunk_data = cpl_vector_get_data_const(
390 for (cpl_size i = 0; i < npos; i++) {
392 spectrum_chunk_data[i] != 0.0 &&
393 !isnan(spectrum_chunk_data[i]);
399 line_fit = cpl_polynomial_new(1);
400 const cpl_size maxdeg1d = 2;
401 cpl_polynomial_fit(line_fit, pos_chunk, NULL, spectrum_chunk, NULL,
402 CPL_FALSE, NULL, &maxdeg1d);
409 double poly_b = cpl_polynomial_get_coeff(line_fit, &pow);
411 double poly_c = cpl_polynomial_get_coeff(line_fit, &pow);
412 result = -poly_b / (2.0 * poly_c);
418 if (fabs(result - guess_pos) > half_width) {
423 cpl_matrix_delete(pos_chunk);
424 cpl_vector_delete(spectrum_chunk);
425 cpl_polynomial_delete(line_fit);
427 if (cpl_error_get_code() != CPL_ERROR_NONE) {
451 const hdrl_image * image,
452 const cpl_image * confidence,
453 const cpl_size ntraces,
454 const cpl_polynomial * traces[ntraces],
455 const cpl_size nspectra,
456 const cpl_vector * spectra[nspectra],
457 const cpl_size nlines,
458 const cpl_polynomial * lines[nlines],
459 cpl_frameset * frameset,
460 const cpl_parameterlist * parlist,
461 const char * filename,
462 const char * recipe_name) {
466 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
467 cpl_ensure_code(pro_catg, CPL_ERROR_NULL_INPUT);
468 cpl_ensure_code(image, CPL_ERROR_NULL_INPUT);
469 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
470 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
471 cpl_ensure_code(filename, CPL_ERROR_NULL_INPUT);
473 mef_extension_list * mefs = NULL;
474 cpl_propertylist * plist = NULL;
478 plist = cpl_propertylist_new();
479 cpl_propertylist_append_string(plist, CPL_DFS_PRO_CATG, pro_catg);
484 enu_check_error_code(
"error constructing output propertylist");
490 cpl_size nmefs = ntraces + nspectra + nlines + 1;
495 for (cpl_size i = 0; i < ntraces; i++) {
496 cpl_propertylist * mef_plist = cpl_propertylist_new();
497 cpl_propertylist_update_string(mef_plist,
"DIR",
"Y");
504 for (cpl_size i = 0; i < nspectra; i++) {
508 for (cpl_size i = 0; i < nlines; i++) {
509 cpl_propertylist * mef_plist = cpl_propertylist_new();
510 cpl_propertylist_update_string(mef_plist,
"DIR",
"X");
529 PACKAGE
"/" PACKAGE_VERSION,
534 cpl_propertylist_delete(plist);
536 return cpl_error_get_code();
557 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
558 cpl_ensure(table, CPL_ERROR_NULL_INPUT, NULL);
562 cpl_polynomial * result = cpl_polynomial_new(2);
566 enu_check(cpl_table_has_column(table,
"1.dim.power"),
567 CPL_ERROR_ILLEGAL_INPUT,
568 "table does not have column '1.dim.power'");
569 enu_check(cpl_table_has_column(table,
"2.dim.power"),
570 CPL_ERROR_ILLEGAL_INPUT,
571 "table does not have column '2.dim.power'");
572 enu_check(cpl_table_has_column(table,
"coefficient"),
573 CPL_ERROR_ILLEGAL_INPUT,
574 "table does not have column 'coefficient'");
578 cpl_size nrow = cpl_table_get_nrow(table);
579 for (cpl_size row=0; row<nrow; row++) {
581 int pow1 = cpl_table_get_int(table,
"1.dim.power", row, &null1);
583 int pow2 = cpl_table_get_int(table,
"2.dim.power", row, &null2);
585 double coeff = cpl_table_get_double(table,
"coefficient", row,
587 enu_check(!(null1 || null2 || nullcoeff), CPL_ERROR_ILLEGAL_INPUT,
588 "table contains NULL values");
590 cpl_size pows[2] = {pow1, pow2};
591 cpl_polynomial_set_coeff(result, pows, coeff);
595 if (cpl_error_get_code() != CPL_ERROR_NONE) {
596 cpl_polynomial_delete(result);
619 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
620 cpl_ensure(poly, CPL_ERROR_NULL_INPUT, NULL);
622 cpl_table * result = NULL;
626 const cpl_size dimension = cpl_polynomial_get_dimension(poly);
627 enu_check(dimension==1 || dimension==2, CPL_ERROR_ILLEGAL_INPUT,
628 "can only handle polynomial with dimension 1 or 2");
630 if (dimension == 1) {
632 const cpl_size degree = cpl_polynomial_get_degree(poly);
633 result = cpl_table_new(degree + 1);
637 cpl_table_new_column(result,
"1.dim.power", CPL_TYPE_INT);
638 cpl_table_new_column(result,
"coefficient", CPL_TYPE_DOUBLE);
641 for (cpl_size dim1_power=0; dim1_power<=degree; dim1_power++) {
642 double coeff = cpl_polynomial_get_coeff(poly, &dim1_power);
644 cpl_table_set_int(result,
"1.dim.power", nrows, dim1_power);
645 cpl_table_set_double(result,
"coefficient", nrows, coeff);
649 cpl_table_set_size(result, nrows);
651 }
else if (dimension == 2) {
653 const cpl_size degree = cpl_polynomial_get_degree(poly);
654 result = cpl_table_new((degree + 1) * (degree + 1));
658 cpl_table_new_column(result,
"1.dim.power", CPL_TYPE_INT);
659 cpl_table_new_column(result,
"2.dim.power", CPL_TYPE_INT);
660 cpl_table_new_column(result,
"coefficient", CPL_TYPE_DOUBLE);
663 for (
int dim2_power=0; dim2_power<=degree; dim2_power++) {
664 for (
int dim1_power=0; dim1_power<=degree; dim1_power++) {
665 cpl_size pows[2] = {dim1_power, dim2_power};
666 double coeff = cpl_polynomial_get_coeff(poly, pows);
668 cpl_table_set_int(result,
"1.dim.power", nrows, dim1_power);
669 cpl_table_set_int(result,
"2.dim.power", nrows, dim2_power);
670 cpl_table_set_double(result,
"coefficient", nrows, coeff);
675 cpl_table_set_size(result, nrows);
680 if (cpl_error_get_code() != CPL_ERROR_NONE) {
681 cpl_table_delete(result);
cpl_error_code enu_dfs_save_himage(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *provenance, const cpl_boolean prov_raw, const hdrl_image *image, const hdrl_imagelist *imagelist, const mef_extension_list *mefs, const char *recipe, const cpl_frame *inherit_frame, const cpl_propertylist *applist, const cpl_propertylist *wcs_plist, const char *pipe_id, const char *filename)
Save an hdrl_image/imagelist as a DFS-compliant MEF pipeline product.
cpl_error_code enlu_divide_slit_response_worker(hdrl_image *himage_2d, cpl_image *response_1d)
Worker function to divide a 2d image by a 1d response.
cpl_error_code enlu_divide_slit_response(located_imagelist *jitters)
Divide LSS 2d-spectra by the slit response.
double enlu_linepos_1d(const cpl_vector *spectrum1d, const double guess_pos, const cpl_size half_width)
Fit line peak.
cpl_table * enlu_warp_poly_save_to_table(const cpl_polynomial *poly)
Save an LSS polynomial to a cpl_table.
cpl_matrix * enlu_linepos_2d(const hdrl_image *spectrum2d, const cpl_size slice_index, const cpl_vector *guess_pos)
Fit the line peaks of a wave calibration spectrum.
cpl_polynomial * enlu_warp_poly_load_from_table(const cpl_table *table)
Load a LSS warp polynomial from a cpl_table.
cpl_error_code enlu_trace_save(const char *pro_catg, const hdrl_image *image, const cpl_image *confidence, const cpl_size ntraces, const cpl_polynomial *traces[ntraces], const cpl_size nspectra, const cpl_vector *spectra[nspectra], const cpl_size nlines, const cpl_polynomial *lines[nlines], cpl_frameset *frameset, const cpl_parameterlist *parlist, const char *filename, const char *recipe_name)
Save a trace result.
mef_extension * enu_mef_new_image(const char *name, const cpl_image *data, const cpl_propertylist *plist)
Create a mef_extension to hold a cpl_image.
mef_extension * enu_mef_new_table(const char *name, const cpl_table *table, const cpl_propertylist *plist)
Create a mef_extension struct holding a cpl_table.
mef_extension_list * enu_mef_extension_list_new(cpl_size size)
Construct a new mef_extension_list.
mef_extension * enu_mef_new_vector(const char *name, const cpl_vector *vector, const cpl_propertylist *plist)
Create a mef_extension struct holding a cpl_vector.
void enu_mef_extension_list_delete(mef_extension_list *list)
Delete a mef_extension_list and its contents.
hdrl_value hdrl_image_get_pixel(const hdrl_image *self, cpl_size xpos, cpl_size ypos, int *pis_rejected)
get pixel values of hdrl_image
cpl_error_code hdrl_image_set_pixel(hdrl_image *self, cpl_size xpos, cpl_size ypos, hdrl_value value)
set pixel values of hdrl_image
cpl_size hdrl_image_get_size_y(const hdrl_image *self)
return size of Y dimension of image
cpl_size hdrl_image_get_size_x(const hdrl_image *self)
return size of X dimension of image
cpl_image * hdrl_image_get_image(hdrl_image *himg)
get data as cpl image
cpl_error_code hdrl_image_reject(hdrl_image *self, cpl_size xpos, cpl_size ypos)
mark pixel as bad
const cpl_image * hdrl_image_get_image_const(const hdrl_image *himg)
get data as cpl image