38#include "eris_utils.h"
39#include "eris_nix_utils.h"
40#include "eris_nix_lss_utils.h"
41#include "eris_pfits.h"
43#include "eris_nix_dfs.h"
44#include "eris_utils.h"
53static const char eris_nix_lss_startrace_description[] =
54"This recipe reduces a set of "ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG
" or\n"
55ERIS_NIX_SKYSUB_STD_LSS_JITTER_PRO_CATG
" frames to produce a "
56ERIS_NIX_MASTER_STARTRACE_PRO_CATG
" file.\n"
58"This file can be used to rectify the 2d spectra so that the slit axis\n"
59"is horizontal and the dispersion axis vertical and wavelength\n"
64" DO CATG Explanation Req. #Frames\n"
65" ------- ----------- --- -------\n"
66" "ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG
67 " sky-subtracted Y >5\n"
70" "ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG
71 " sky-subtracted Y >5\n"
76" DO CATG Explanation \n"
77" ------- ----------- \n"
78" "ERIS_NIX_MASTER_STARTRACE_PRO_CATG
79 " file containing the\n"
81" for correcting the\n"
83" "ERIS_NIX_LSS_TRACE_FIT
84 " debug files containing\n"
85" the startrace image\n"
86" and the polynomial fit\n"
87" to the trace. This can\n"
88" be plotted with the\n"
89" 'plot_trace' method\n"
90" of 'startrace_plot.py'\n"
91" "ERIS_NIX_LSS_STARTRACE_SKY
92 " debug file containing\n"
94" background spectrum\n"
95" of the observations.\n"
96" This can be plotted\n"
97" with the 'plot_lines'\n"
99" 'startrace_plot.py'\n"
101" The "ERIS_NIX_MASTER_STARTRACE_PRO_CATG
102 " result will be in a FITS file named \n"
103" 'master_wave.<first input filename>', with extensions:\n"
104" - I_POLYNOMIAL, a table with polynomial coefficients for\n"
105" mapping x,lambda => x_actual.\n"
106" - J_POLYNOMIAL, a table with polynomial coefficients for\n"
107" mapping x,lambda => y_actual.\n"
109" There will be one "ERIS_NIX_LSS_TRACE_FIT
" debug files \n"
110" for each input image, named 'startrace.<input filename>.\n"
112" The "ERIS_NIX_LSS_STARTRACE_SKY
" file will be named\n"
113" 'startrace_sky.<first input filename>.fits'.\n"
115" Notes on the method.\n"
116" It is assumed that the jitter pattern moves the object up and\n"
117" down a line along the slit direction. The reference position\n"
118" and the offset of each jitter from it are calculated as\n"
120" 1/ The reference is jitter 0. Often this lies near the \n"
121" middle of the pattern and the object is manually \n"
122" positioned near the middle of the slit.\n"
123" 2/ Derive the slit-line PA (0 = N, increasing E) from the\n"
124" extrema of the jitter centres.\n"
125" 3/ Report how far each jitter pointing lies from the\n"
127" 4/ Estimate the offset of each jitter relative to the\n"
128" reference jitter along the slit-line.\n"
130" Divide the slit response into the jitter images. The slit\n"
131" response is calculated by collapsing the background sky\n"
132" spectrum in the dispersion direction then normalising by\n"
133" its median value.\n"
135" Measure the star trace in each frame. The trace is the \n"
136" spectrum of the star dispersed over the detector. For each\n"
137" frame proceed as follows:\n"
138" 1/ Get a rough position for the trace. This is done\n"
139" by locating the maximum signal across a slice of the\n"
140" detector that has few bad pixels and is well\n"
142" 2/ Cycle up and down from the 'start' slice, fitting\n"
143" a parabola to the points straddling the rough centre\n"
144" of the trace to get a more accurate position. The\n"
145" rough trace position for the next slice is set to\n"
146" the result for the current slice, so that the process\n"
147" can follow the trace as it slowly slants across the\n"
148" detector columns.\n"
149" 3/ 'Capture' the trace by fitting a polynomial to the line\n"
150" of measured peaks for each slice.\n"
152" Calculate the median of the sky backgrounds of all frames.\n"
154" Measure several atmospheric features/lines across the 2d\n"
155" background sky spectrum. The process is similar to that\n"
156" for measuring the traces:\n"
157" 1/ Use a library of lines (currently hardwired into the\n"
158" the code) identifying the line wavelength, y coord\n"
159" at x=1024, and line width.\n"
160" 2/ For each line, cycle left and right from the 'start'\n"
161" column, fitting a parabola to the points straddling\n"
162" the rough centre of the feature to get a more accurate\n"
163" position. Unlike following a trace the rough position\n"
164" for the next column is always set to that for x=1024.\n"
165" This is because some of the spectral feaures are weak\n"
166" and the fit unreliable, and the lines do not wander as\n"
167" much as the traces.\n"
168" 3/ Fit a polynomial to the line of measured peaks along\n"
171" Do 2d calibration fit between ideal position and actual:\n"
172" x,lambda => x_actual\n"
173" x,lambda => y_actual\n"
175" The calibrated 2d spectrum will have 2048 pixels running\n"
176" from 3.045um[0] to 4.107[2047] in dispersion [y], and 2048\n"
177" pixels with 0.013arcsec pixels, centred at 1024 in slit\n"
180" With trace behaviour described by the polynomial fits\n"
181" derived earlier and dispersive behaviour by the polynomial\n"
182" fits to known atmospheric features:\n"
183" 1/ Construct the slit offset, wavelength => x_actual and\n"
184" offset,wavelength => y_actual sample arrays to be fit.\n"
185" Do this by populating the sample arrays with the\n"
186" intersection x,y of the fits to each trace and\n"
187" atmospheric line.\n"
188" 2/ Do a 2d polynomial fit to x,lambda => x_actual.\n"
189" Do a 2d polynomial fit to x,lambda => y_actual.\n"
191" Save the results to FITS.\n"
194#define RECIPE_NAME "eris.eris_nix_lss_startrace"
200cpl_recipe_define(eris_nix_lss_startrace, ERIS_BINARY_VERSION,
202 PACKAGE_BUGREPORT,
"2017",
203 "Calculate a MASTER_WAVE",
204 eris_nix_lss_startrace_description);
220static cpl_error_code eris_nix_lss_startrace_fill_parameterlist(
221 cpl_parameterlist *self) {
223 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
228 cpl_parameter * p = NULL;
229 p = cpl_parameter_new_value(RECIPE_NAME
".saturation_threshold",
230 CPL_TYPE_DOUBLE,
"frame saturation threshold", RECIPE_NAME, 5000.0);
231 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"saturation_threshold");
232 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV);
233 cpl_parameterlist_append(self, p);
249static int eris_nix_lss_startrace(cpl_frameset * frameset,
250 const cpl_parameterlist * parlist) {
252 cpl_propertylist * applist = NULL;
253 cpl_image * contrib = NULL;
254 cpl_vector * crval1_vector = NULL;
255 cpl_vector * crval2_vector = NULL;
256 located_imagelist * jitters = NULL;
257 cpl_polynomial ** line_polys = NULL;
258 mef_extension_list * mefs = NULL;
259 located_imagelist * object_jitters = NULL;
260 hdrl_imagelist * skylist = NULL;
261 hdrl_image * sky_background = NULL;
262 cpl_vector * slit_offset = NULL;
263 cpl_matrix * startrace_pos = NULL;
264 located_imagelist * std_jitters = NULL;
265 cpl_polynomial ** trace_polys = NULL;
266 cpl_frameset * used = NULL;
270 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
271 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
275 cpl_msg_set_level_from_env();
276 cpl_msg_severity severity = cpl_msg_get_level();
277 cpl_msg_info(cpl_func,
"level %d", (
int) severity);
281 return CPL_ERROR_BAD_FILE_FORMAT;
283 enu_check_error_code(
"Could not retrieve input parameters");
288 enu_check_error_code(
"Could not identify RAW and CALIB frames");
290 used = cpl_frameset_new();
295 ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG,
298 ERIS_NIX_SKYSUB_STD_LSS_JITTER_PRO_CATG,
300 enu_check_error_code(
"Error loading frameset");
302 if (object_jitters->size > 0) {
303 enu_check(std_jitters->size == 0, CPL_ERROR_ILLEGAL_INPUT,
304 "SoF contains both object and std data");
305 jitters = object_jitters;
308 }
else if (std_jitters->size > 0) {
309 jitters = std_jitters;
311 object_jitters = NULL;
313 enu_check(jitters!=NULL, CPL_ERROR_ILLEGAL_INPUT,
314 "SoF contains no valid data");
323 crval1_vector = cpl_vector_new(jitters->size);
324 crval2_vector = cpl_vector_new(jitters->size);
325 for (cpl_size i = 0; i < jitters->size; i++) {
326 double crval1 = cpl_propertylist_get_double(
327 jitters->limages[i]->plist,
329 cpl_vector_set(crval1_vector, i, crval1);
330 double crval2 = cpl_propertylist_get_double(
331 jitters->limages[i]->plist,
333 cpl_vector_set(crval2_vector, i, crval2);
334 cpl_msg_info(cpl_func,
"Jitter %d at RA=%10.7f Dec=%10.7f",
335 (
int)i, crval1, crval2);
338 double lat = cpl_vector_get_mean(crval2_vector);
339 double coslat = cos(lat / 57.2958);
340 cpl_msg_info(cpl_func,
"lat %f coslat %f", lat, coslat);
342 cpl_size crval1_maxpos = cpl_vector_get_maxpos(crval1_vector);
343 double crval1_max = cpl_vector_get(crval1_vector, crval1_maxpos);
344 cpl_size crval1_minpos = cpl_vector_get_minpos(crval1_vector);
345 double crval1_min = cpl_vector_get(crval1_vector, crval1_minpos);
347 cpl_size crval2_maxpos = cpl_vector_get_maxpos(crval2_vector);
348 double crval2_max = cpl_vector_get(crval2_vector, crval2_maxpos);
349 cpl_size crval2_minpos = cpl_vector_get_minpos(crval2_vector);
350 double crval2_min = cpl_vector_get(crval2_vector, crval2_minpos);
352 double enda[2] = {0.0, 0.0};
353 double endb[2] = {0.0, 0.0};
354 if (fabs(crval1_max - crval1_min) > fabs(crval2_max - crval2_min)) {
355 enda[0] = crval1_min;
356 enda[1] = cpl_vector_get(crval2_vector, crval1_minpos);
357 endb[0] = crval1_max;
358 endb[1] = cpl_vector_get(crval2_vector, crval2_maxpos);
360 enda[0] = cpl_vector_get(crval1_vector, crval2_minpos);
361 enda[1] = crval2_min;
362 endb[0] = cpl_vector_get(crval1_vector, crval2_maxpos);
363 endb[1] = crval2_max;
365 cpl_msg_info(cpl_func,
"Jitter line end points (RA, DEC): "
366 "(%10.7f, %10.7f) and (%10.7f, %10.7f)",
367 enda[0], enda[1], endb[0], endb[1]);
372 double centre[2] = {(enda[0] + endb[0]) / 2.0,
373 (enda[1] + endb[1]) / 2.0};
377 double slit_line[2] = {(endb[0]-enda[0]) * coslat, endb[1]-enda[1]};
378 double slit_norm = sqrt(pow(slit_line[0],2) + pow(slit_line[1],2));
379 slit_line[0] /= slit_norm;
380 slit_line[1] /= slit_norm;
381 enu_check_error_code(
"error finding line of slit");
382 cpl_msg_info(cpl_func,
"..slit direction vector (long, lat) = (%f, %f)",
383 slit_line[0], slit_line[1]);
388 double cd1_1 = cpl_propertylist_get_double(jitters->limages[0]->
390 double cd2_1 = cpl_propertylist_get_double(jitters->limages[0]->
392 double pixsize = sqrt(cd1_1 * cd1_1 + cd2_1 * cd2_1);
394 slit_offset = cpl_vector_new(jitters->size);
395 for (cpl_size i = 0; i < jitters->size; i++) {
396 double offset = -1000.0;
398 if (fabs(slit_line[0]) > 1e-6) {
399 offset = (cpl_vector_get(crval1_vector, i) - centre[0]) * coslat /
401 }
else if (fabs(slit_line[1]) > 1e-6) {
402 offset = (cpl_vector_get(crval2_vector, i) - centre[1]) /
408 double remainder[2] = {0.0,0.0};
409 remainder[0] = ((cpl_vector_get(crval1_vector, i) - centre[0]) * coslat -
410 (offset * slit_line[0])) / pixsize;
411 remainder[1] = ((cpl_vector_get(crval2_vector, i) - centre[1]) -
412 (offset * slit_line[1])) / pixsize;
413 if (fabs(remainder[0]) > 1 || fabs(remainder[1]) > 1) {
414 cpl_msg_warning(cpl_func,
"...offset remainder (%f, %f) pixels",
415 remainder[0], remainder[1]);
416 cpl_msg_warning(cpl_func,
"...slit offset does not fall on line");
419 cpl_vector_set(slit_offset, i, offset);
420 cpl_msg_info(cpl_func,
"..slit offset %d %f", (
int)i, offset);
422 enu_check_error_code(
"error calculating slit offsets");
427 cpl_vector * nominal_offset = cpl_vector_new(jitters->size);
428 for (cpl_size i = 0; i < jitters->size; i++) {
429 cpl_vector_set(nominal_offset, i, 1024.0 - cpl_vector_get(
430 slit_offset, i) / pixsize);
432 cpl_msg_info(cpl_func,
"Nominal offset:");
433 cpl_vector_dump(nominal_offset, NULL);
441 cpl_size ntrace = jitters->size;
442 trace_polys = cpl_calloc(ntrace,
sizeof(cpl_polynomial *));
450 const cpl_size start_slice = 1800;
451 startrace_pos = cpl_matrix_new(ny, ntrace);
457 for (cpl_size j = 0; j < ntrace; j++) {
462 jitters->limages[j]->bkg);
473 cpl_msg_info(cpl_func,
"jitter %d", (
int)j);
474 char * name_copy = cpl_strdup(cpl_frame_get_filename(
475 jitters->limages[j]->frame));
476 cpl_msg_info(cpl_func,
"%s", basename(name_copy));
478 cpl_msg_info(cpl_func,
"nominal offset %7.2f",
479 cpl_vector_get(nominal_offset, j));
481 cpl_vector * maximum_pos = cpl_vector_new(10);
482 cpl_vector * maximum_val = cpl_vector_new(10);
483 for (cpl_size iy = start_slice-5; iy < start_slice+5; iy++) {
484 cpl_vector * slice1d = cpl_vector_new_from_image_row(
486 jitters->limages[j]->himage),
488 cpl_vector_set(maximum_pos, iy-(start_slice-5),
489 cpl_vector_get_maxpos(slice1d));
490 cpl_vector_set(maximum_val, iy-(start_slice-5),
491 cpl_vector_get_max(slice1d));
493 cpl_vector_delete(slice1d);
497 double start_guess_pos = cpl_vector_get_median(maximum_pos);
498 double trace_val = cpl_vector_get_median(maximum_val);
500 cpl_vector_delete(maximum_pos);
501 cpl_vector_delete(maximum_val);
506 double guess_pos = start_guess_pos;
510 for (cpl_size iy = start_slice; iy < ny; iy++) {
511 cpl_vector * slice1d = cpl_vector_new_from_image_row(
513 jitters->limages[j]->himage),
517 if (!isnan(fitted_pos) &&
518 (cpl_vector_get(slice1d, (
int)fitted_pos) > 0.1 * trace_val)) {
527 cpl_matrix_set(startrace_pos, iy, j, fitted_pos);
528 guess_pos = fitted_pos;
529 cpl_msg_info(cpl_func,
"fitted pos %d %7.2f",
530 (
int)iy, fitted_pos);
532 cpl_matrix_set(startrace_pos, iy, j, fitted_pos);
534 cpl_vector_delete(slice1d);
536 enu_check_error_code(
"error following trace up");
540 guess_pos = start_guess_pos;
542 for (cpl_size iy = start_slice; iy >= 0; iy--) {
544 cpl_vector * slice1d = cpl_vector_new_from_image_row(
546 jitters->limages[j]->himage),
550 cpl_vector_delete(slice1d);
552 if (!isnan(fitted_pos) &&
553 (cpl_vector_get(slice1d, (
int)fitted_pos) > 0.1 * trace_val)) {
554 cpl_matrix_set(startrace_pos, iy, j, fitted_pos);
555 guess_pos = fitted_pos;
556 cpl_msg_info(cpl_func,
"fitted pos %d %7.2f",
557 (
int)iy, fitted_pos);
559 cpl_matrix_set(startrace_pos, iy, j, fitted_pos);
562 enu_check_error_code(
"error following trace down");
566 trace_polys[j] = cpl_polynomial_new(1);
567 cpl_vector * spectrum = cpl_vector_new(ny);
569 cpl_matrix * samppos1d = cpl_matrix_new(1, ny);
570 cpl_vector * fitvals = cpl_vector_new(ny);
571 const cpl_boolean sampsym = CPL_FALSE;
572 const cpl_size maxdeg1d = 3;
576 for (cpl_size iy = 0; iy < ny; iy++) {
577 double fitted_pos = cpl_matrix_get(startrace_pos, iy, j);
578 if (!isnan(fitted_pos)) {
579 cpl_matrix_set(samppos1d, 0, isamp, (
double)iy);
580 cpl_vector_set(fitvals, isamp, fitted_pos);
585 cpl_matrix_set_size(samppos1d, 1, isamp);
586 cpl_vector_set_size(fitvals, isamp);
593 cpl_polynomial_fit(trace_polys[j], samppos1d, &sampsym,
594 fitvals, NULL, CPL_FALSE, NULL, &maxdeg1d);
596 cpl_polynomial_dump(trace_polys[j], stdout);
598 enu_check_error_code(
"error fitting trace");
603 cpl_image * double_image = cpl_image_cast(
606 jitters->limages[j]->bkg),
608 double * data = cpl_image_get_data(double_image);
610 cpl_image * double_confidence = cpl_image_cast(
611 jitters->limages[j]->confidence,
613 double * confidence = cpl_image_get_data(double_confidence);
615 for (cpl_size iy = 0; iy < ny; iy++) {
616 double pos = cpl_polynomial_eval_1d(trace_polys[j], (
double)iy, NULL);
657 for (cpl_size dx=-20; dx <= 20; dx++) {
658 cpl_size idatum = (int)pos + dx;
660 if (idatum >= 0 && idatum < nx) {
662 val+= (wt * (data[iy * nx + idatum] *
663 confidence[iy * nx + idatum]));
664 sumwt += (wt * confidence[idatum * nx + idatum]);
676 if (fabs(sumwt) > 0) {
679 cpl_vector_set(spectrum, iy, val);
682 cpl_image_delete(double_image);
687 jitters->limages[j]->frame),
690 jitters->limages[j]->himage,
691 jitters->limages[j]->confidence,
692 1, (
const cpl_polynomial **) &(trace_polys[j]),
693 1, (
const cpl_vector **) &spectrum,
701 enu_check_error_code(
"error calculating trace spectrum / saving trace");
708 enu_check_error_code(
"error collapsing sky backgrounds");
714 double wavelength[NLINES] = {3.262,
720 double expected_iy[NLINES] = {364,
726 double half_width[NLINES] = {10.0,
733 line_polys = cpl_calloc(NLINES,
sizeof(cpl_polynomial *));
739 for (cpl_size iy = 1; iy <= ny; iy++) {
740 for (cpl_size ix = 1; ix <= nx; ix++) {
746 value.data = value.data - (10.0 + 71.0 * (iy-207.0) / 1626);
762 cpl_matrix * line_pos = cpl_matrix_new(nx, NLINES);
764 for (cpl_size line = 0; line < NLINES; line++) {
765 double guess_pos = expected_iy[line];
766 cpl_size xstart = 1024;
774 for (cpl_size ix = xstart; ix < nx; ix++) {
776 cpl_vector * slice1d = cpl_vector_new_from_image_column(
783 cpl_matrix_set(line_pos, ix, line, fitted_pos);
785 if (!isnan(fitted_pos)) {
786 cpl_msg_debug(cpl_func,
"line %d %e %e", (
int)ix,
787 guess_pos, fitted_pos);
796 cpl_vector_delete(slice1d);
801 for (cpl_size ix = xstart; ix >=0; ix--) {
803 cpl_vector * slice1d = cpl_vector_new_from_image_column(
810 cpl_matrix_set(line_pos, ix, line, fitted_pos);
811 if (!isnan(fitted_pos)) {
812 cpl_msg_debug(cpl_func,
"line %d %e %e", (
int)ix,
813 guess_pos, fitted_pos);
816 cpl_vector_delete(slice1d);
821 line_polys[line] = cpl_polynomial_new(1);
823 cpl_matrix * samppos1d = cpl_matrix_new(1, nx);
824 cpl_vector * fitvals = cpl_vector_new(nx);
825 const cpl_boolean sampsym = CPL_FALSE;
826 const cpl_size maxdeg1d = 2;
830 for (cpl_size ix = 0; ix < nx; ix++) {
831 double fitted_pos = cpl_matrix_get(line_pos, ix, line);
832 if (!isnan(fitted_pos)) {
833 cpl_matrix_set(samppos1d, 0, isamp, (
double)ix);
834 cpl_vector_set(fitvals, isamp, fitted_pos);
839 cpl_matrix_set_size(samppos1d, 1, isamp);
840 cpl_vector_set_size(fitvals, isamp);
841 cpl_polynomial_fit(line_polys[line], samppos1d, &sampsym, fitvals, NULL,
842 CPL_FALSE, NULL, &maxdeg1d);
844 cpl_msg_info(cpl_func,
"line %d poly", (
int)line);
845 cpl_polynomial_dump(line_polys[line], stdout);
848 enu_check_error_code(
"error following line features");
853 jitters->limages[0]->frame),
857 jitters->limages[0]->confidence,
860 NLINES, (
const cpl_polynomial **) line_polys,
866 enu_check_error_code(
"error saving line features");
886 cpl_size nsamples = NLINES * ntrace;
887 cpl_size isample = 0;
889 cpl_matrix * ij_nominal = cpl_matrix_new(2, nsamples);
890 cpl_vector * i_actual = cpl_vector_new(nsamples);
891 cpl_vector * j_actual = cpl_vector_new(nsamples);
893 for (cpl_size trace = 0; trace < ntrace; trace++) {
897 double i_nominal = cpl_vector_get(nominal_offset, trace);
901 for (cpl_size line = 0; line < NLINES; line++) {
903 double lambda = wavelength[line];
904 double j_nominal = ny * (lambda - 3.045) / (4.107 - 3.045);
908 cpl_size jtrace_min = -1;
909 double mindist = DBL_MAX;
910 for (cpl_size jtrace=0; jtrace < ny; jtrace++) {
911 double itrace = cpl_polynomial_eval_1d(trace_polys[trace],
912 (
double)jtrace, NULL);
913 double jline = cpl_polynomial_eval_1d(line_polys[line],
915 double dist = fabs(jline - jtrace);
916 if (dist < mindist) {
922 double i_actual_val = 0.0;
923 double j_actual_val = 0.0;
924 if (jtrace_min != -1) {
925 j_actual_val = jtrace_min;
926 i_actual_val = cpl_polynomial_eval_1d(trace_polys[trace],
937 cpl_matrix_set(ij_nominal, 0, isample, i_nominal);
938 cpl_matrix_set(ij_nominal, 1, isample, j_nominal);
939 cpl_vector_set(i_actual, isample, i_actual_val);
943 cpl_vector_set(j_actual, isample, j_actual_val);
951 cpl_polynomial * i_cal = cpl_polynomial_new(2);
952 const cpl_size maxdeg2d[] = {2, 2};
953 cpl_polynomial_fit(i_cal, ij_nominal, NULL, i_actual, NULL,
954 CPL_TRUE, NULL, maxdeg2d);
958 cpl_msg_info(cpl_func,
"The i calibration polynomial:");
959 cpl_polynomial_dump(i_cal, stdout);
964 cpl_polynomial * j_cal = cpl_polynomial_new(2);
965 cpl_polynomial_fit(j_cal, ij_nominal, NULL, j_actual, NULL,
966 CPL_TRUE, NULL, maxdeg2d);
967 cpl_msg_info(cpl_func,
"The j calibration polynomial:");
968 cpl_polynomial_dump(j_cal, stdout);
997 applist = cpl_propertylist_new();
998 cpl_propertylist_append_string(applist, CPL_DFS_PRO_CATG,
999 ERIS_NIX_MASTER_STARTRACE_PRO_CATG);
1037 jitters->limages[0]->frame),
1039 cpl_frameset * provenance = cpl_frameset_new();
1040 for (cpl_size j = 0; j<jitters->size; j++) {
1041 cpl_frameset_insert(provenance, cpl_frame_duplicate(
1042 jitters->limages[j]->frame));
1045 cpl_msg_info(cpl_func,
"..writing %s", out_fname);
1057 PACKAGE
"/" PACKAGE_VERSION,
1060 cpl_frameset_delete(provenance);
1061 cpl_free(out_fname);
1062 enu_check_error_code(
"Failed to save MASTER_WAVE");
1065 if (trace_polys != NULL) {
1066 for (cpl_size j=0; j < jitters->size; j++) {
1067 cpl_polynomial_delete(trace_polys[j]);
1069 cpl_free(trace_polys);
1071 if (line_polys != NULL) {
1072 for (cpl_size line=0; line < NLINES; line++) {
1073 cpl_polynomial_delete(line_polys[line]);
1075 cpl_free(line_polys);
1077 cpl_propertylist_delete(applist);
1078 cpl_image_delete(contrib);
1079 cpl_vector_delete(crval1_vector);
1080 cpl_vector_delete(crval2_vector);
1083 if (ij_nominal != NULL) {
1084 cpl_matrix_delete(ij_nominal);
1089 cpl_vector_delete(slit_offset);
1090 cpl_matrix_delete(startrace_pos);
1091 cpl_frameset_delete(used);
1093 return (
int)cpl_error_get_code();
cpl_error_code eris_nix_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
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(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_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.
void enu_located_imagelist_delete(located_imagelist *limlist)
Delete a located_imagelist and its contents.
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.
located_imagelist * enu_limlist_load_from_frameset(cpl_frameset *frameset, const char *tag, cpl_frameset *used)
Load tagged data from a frameset into a located_imagelist.
char * enu_repreface(const char *filename, const char *preface)
Preface a raw filename with a string.
void enu_mef_extension_list_delete(mef_extension_list *list)
Delete a mef_extension_list and its contents.
cpl_error_code eris_files_dont_exist(cpl_frameset *frameset)
Check if all SOF files exist.
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
hdrl_image * hdrl_image_duplicate(const hdrl_image *himg)
copy 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
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_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
void hdrl_imagelist_delete(hdrl_imagelist *himlist)
Free all memory used by a hdrl_imagelist object including the 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
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.