39#include "casu_utils.h"
41#include "casu_stats.h"
43#include "eris_utils.h"
44#include "eris_nix_utils.h"
45#include "eris_pfits.h"
47#include "eris_nix_dfs.h"
48#include "eris_utils.h"
49#include "eris_nix_lss_utils.h"
58static const char eris_nix_lss_straighten_description[] =
59"This recipe uses a CPL warping routine to correct the wavelength and\n"
60"slit offset coordinates of the input ERIS/NIX long-slit spectra. The\n"
61"aim for the output spectra is to have slit offset along the horizontal\n"
62"axis and dispersion along the vertical.\n"
64"Areas of the detector not illuminated by the slit have their data and\n"
65"confidence values set to 0.\n"
69" DO CATG Explanation Req. #Frames\n"
70" ------- ----------- --- -------\n"
71" "ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG
72 " sky-subtracted frames Y 1-n\n"
73" to be straightened.\n"
75" "ERIS_NIX_SKYSUB_STD_LSS_JITTER_PRO_CATG
76 " sky-subtracted Y 1-n\n"
79" "ERIS_NIX_MASTER_STARTRACE_PRO_CATG
80 " file containing the Y 1\n"
82" for correcting the\n"
87" DO CATG Explanation \n"
88" ------- ----------- \n"
89" "ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG
90 " the straightened 2d-spectrum of the\n"
93" "ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG
94 " the straightened 2d-spectrum of the\n"
97" The output image will be in a FITS file named \n"
98" 'corrected.<first input filename>', with extensions:\n"
99" - DATA, with the corrected data.\n"
100" - ERR, with the corrected error plane.\n"
101" - DQ, with the corrected image quality\n"
102" - CONFIDENCE, with the corrected confidence plane.\n"
103" - BKG_DATA, with corrected background spectrum.\n"
104" - BKG_ERR, with the corrected background error plane.\n"
105" - BKG_CONF, with the corrected background confidence.\n"
107" Notes on the method.\n"
108" It is assumed that the jitter pattern moves the object up and\n"
109" down the slit-line. The reference position and the offset of\n"
110" each jitter from it are calculated as follows:\n"
111" 1/ The reference is jitter 0. Often this lies near the \n"
112" middle of the pattern and the object is manually \n"
113" positioned near the middle of the slit.\n"
114" 2/ Derive the slit-line PA (0 = N, increasing E) from the\n"
115" extrema of the jitter centres.\n"
116" 3/ Report how far each jitter pointing lies from the\n"
118" 4/ Estimate the offset of each jitter relative to the\n"
119" reference jitter along the slit-line.\n"
121" Correct the spectra to:\n"
122" Calibrate the wavelengths and straighten the spectrum by\n"
123" removing slit/dispersion curvature from the image.\n"
124" Shift spectra so that an object appears in the same column\n"
125" as it would in the reference jitter.\n"
127" This is done for each jitter by:\n"
128" 1/ Estimating the shift required to place the object in\n"
129" the same column as in the reference jitter.\n"
130" a/ Take a copy of the spectrum.\n"
131" b/ Apply the warp polynomials to straighten the copy.\n"
132" c/ Collapse the copy along the dispersion axis.\n"
133" d/ Find the position of the star.\n"
134" e/ Calculate the offset required to move the star to\n"
135" its position in the reference jitter.\n"
136" 2/ Modify the warp polynomials to apply the required shift\n"
137" with the straightening and wavelength calibration.\n"
138" 3/ Apply the shifted warp polynomials to:\n"
140" ..the error plane\n"
141" ..the background spectrum\n"
142" ..the confidence array\n"
144" Set the confidence to 0 outside the illuminated range\n"
145" of the shifted spectrum - to reduce edge effects when\n"
146" stacking them later.\n"
148" Save the straightened spectra. For each spectrum:\n"
149" 1/ Add FITS keywords to describe the WCS of the 2d\n"
151" 2/ Save the spectrum to FITS\n"
154 static cpl_polynomial * eris_nix_lss_shift_polynomial(
155 const cpl_polynomial * polynomial,
156 const double xshift);
159#define RECIPE_NAME "eris.eris_nix_lss_straighten"
165cpl_recipe_define(eris_nix_lss_straighten, ERIS_BINARY_VERSION,
167 PACKAGE_BUGREPORT,
"2017",
168 "Straighten and calibrate "
169 ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG
171 eris_nix_lss_straighten_description);
187static cpl_error_code eris_nix_lss_straighten_fill_parameterlist(
188 cpl_parameterlist * self) {
190 if (cpl_error_get_code() != CPL_ERROR_NONE)
return cpl_error_get_code();
192 cpl_parameter * p = NULL;
194 p = cpl_parameter_new_value(RECIPE_NAME
".debug_data",
196 "write debugging data",
197 RECIPE_NAME, CPL_FALSE);
198 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI,
"debug_data");
199 cpl_parameterlist_append(self, p);
222cpl_polynomial * eris_nix_lss_shift_polynomial(
223 const cpl_polynomial * polynomial,
224 const double xshift) {
226 if (cpl_error_get_code() != CPL_ERROR_NONE)
return NULL;
227 cpl_ensure(polynomial, CPL_ERROR_NULL_INPUT, NULL);
229 cpl_polynomial * result = cpl_polynomial_duplicate(polynomial);
231 cpl_size pows00[2] = {0, 0};
232 double coeff00 = cpl_polynomial_get_coeff(result, pows00);
233 cpl_size pows10[2] = {1, 0};
234 double coeff10 = cpl_polynomial_get_coeff(result, pows10);
235 cpl_size pows20[2] = {2, 0};
236 double coeff20 = cpl_polynomial_get_coeff(result, pows20);
238 cpl_size pows01[2] = {0, 1};
239 double coeff01 = cpl_polynomial_get_coeff(result, pows01);
240 cpl_size pows11[2] = {1, 1};
241 double coeff11 = cpl_polynomial_get_coeff(result, pows11);
242 cpl_size pows21[2] = {2, 1};
243 double coeff21 = cpl_polynomial_get_coeff(result, pows21);
245 cpl_size pows02[2] = {0, 2};
246 double coeff02 = cpl_polynomial_get_coeff(result, pows02);
247 cpl_size pows12[2] = {1, 2};
248 double coeff12 = cpl_polynomial_get_coeff(result, pows12);
249 cpl_size pows22[2] = {2, 2};
250 double coeff22 = cpl_polynomial_get_coeff(result, pows22);
252 double shift_coeff00 = coeff00 - coeff10 * xshift + coeff20 * pow(xshift,2);
253 cpl_polynomial_set_coeff(result, pows00, shift_coeff00);
254 double shift_coeff10 = coeff10 - coeff20 * 2.0 * xshift;
255 cpl_polynomial_set_coeff(result, pows10, shift_coeff10);
258 double shift_coeff01 = coeff01 - coeff11 * xshift + coeff21 * pow(xshift,2);
259 cpl_polynomial_set_coeff(result, pows01, shift_coeff01);
260 double shift_coeff11 = coeff11 - coeff21 * 2.0 * xshift;
261 cpl_polynomial_set_coeff(result, pows11, shift_coeff11);
264 double shift_coeff02 = coeff02 - coeff12 * xshift + coeff22 * pow(xshift,2);
265 cpl_polynomial_set_coeff(result, pows02, shift_coeff02);
266 double shift_coeff12 = coeff12 - coeff22 * 2.0 * xshift;
267 cpl_polynomial_set_coeff(result, pows12, shift_coeff12);
274 if (cpl_error_get_code() != CPL_ERROR_NONE) {
275 cpl_polynomial_delete(result);
291static int eris_nix_lss_straighten(cpl_frameset * frameset,
292 const cpl_parameterlist * parlist) {
294 cpl_vector * crval1_vector = NULL;
295 cpl_vector * crval2_vector = NULL;
296 located_imagelist * jitters = NULL;
297 cpl_table * jitter_table = NULL;
298 located_imagelist * object_jitters = NULL;
299 const char * out_catg = NULL;
300 const cpl_parameter * p = NULL;
301 cpl_vector * profile = NULL;
302 cpl_vector * slit_offset = NULL;
303 mef_extension_list * startrace_mefs = NULL;
304 cpl_propertylist * startrace_plist = NULL;
305 cpl_polynomial * startrace_poly_i = NULL;
306 cpl_polynomial * startrace_poly_j = NULL;
307 located_imagelist * std_jitters = NULL;
308 cpl_frameset * used = NULL;
310 enu_check_error_code(
"%s():%d: An error is already set: %s",
311 cpl_func, __LINE__, cpl_error_get_where());
315 cpl_ensure_code(frameset, CPL_ERROR_NULL_INPUT);
316 cpl_ensure_code(parlist, CPL_ERROR_NULL_INPUT);
320 cpl_msg_set_level_from_env();
321 cpl_msg_severity severity = cpl_msg_get_level();
322 cpl_msg_info(cpl_func,
"level %d", (
int) severity);
326 return CPL_ERROR_BAD_FILE_FORMAT;
331 p = cpl_parameterlist_find_const(parlist, RECIPE_NAME
".debug_data");
332 int debug_data = cpl_parameter_get_bool(p);
333 enu_check_error_code(
"Could not retrieve input parameters");
338 enu_check_error_code(
"Could not identify RAW and CALIB frames");
342 used = cpl_frameset_new();
344 ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG, used);
346 ERIS_NIX_SKYSUB_STD_LSS_JITTER_PRO_CATG, used);
347 enu_check_error_code(
"Error loading frameset");
349 if (object_jitters->size > 0) {
350 enu_check(std_jitters->size == 0, CPL_ERROR_ILLEGAL_INPUT,
351 "SoF contains both object and std data");
352 jitters = object_jitters;
353 object_jitters = NULL;
354 out_catg = ERIS_NIX_CORRECTED_OBJECT_LSS_JITTER_PRO_CATG;
355 cpl_msg_info(cpl_func,
"Read in %d "
356 ERIS_NIX_SKYSUB_OBJECT_LSS_JITTER_PRO_CATG
"frames",
357 (
int)(jitters->size));
358 }
else if (std_jitters->size > 0) {
359 jitters = std_jitters;
361 out_catg = ERIS_NIX_CORRECTED_STD_LSS_JITTER_PRO_CATG;
362 cpl_msg_info(cpl_func,
"Read in %d "
363 ERIS_NIX_SKYSUB_STD_LSS_JITTER_PRO_CATG
"frames",
364 (
int)(jitters->size));
369 cpl_frameset_iterator * frameset_iter = cpl_frameset_iterator_new(frameset);
370 for (cpl_frame * frame = NULL;
371 (frame = cpl_frameset_iterator_get(frameset_iter)) &&
372 (cpl_error_get_code() == CPL_ERROR_NONE);
373 cpl_frameset_iterator_advance(frameset_iter, 1)) {
375 const char * tag = cpl_frame_get_tag(frame);
377 if (!strcmp(tag, ERIS_NIX_MASTER_STARTRACE_PRO_CATG)) {
378 const char * filename = cpl_frame_get_filename(frame);
381 cpl_msg_info(cpl_func,
"Read MASTER_STARTRACE %s", filename);
385 enu_check(startrace_mefs != NULL, CPL_ERROR_DATA_NOT_FOUND,
386 "SoF contains no "ERIS_NIX_MASTER_STARTRACE_PRO_CATG
394 cpl_msg_info(cpl_func,
"Finding centre of jitter pattern");
395 crval1_vector = cpl_vector_new(jitters->size);
396 crval2_vector = cpl_vector_new(jitters->size);
397 for (cpl_size i = 0; i < jitters->size; i++) {
398 double crval1 = cpl_propertylist_get_double(
399 jitters->limages[i]->plist,
401 cpl_vector_set(crval1_vector, i, crval1);
402 double crval2 = cpl_propertylist_get_double(
403 jitters->limages[i]->plist,
405 cpl_vector_set(crval2_vector, i, crval2);
406 cpl_msg_info(cpl_func,
"..jitter %d at RA=%10.7f Dec=%10.7f",
407 (
int)i, crval1, crval2);
410 cpl_size crval1_maxpos = cpl_vector_get_maxpos(crval1_vector);
411 double crval1_max = cpl_vector_get(crval1_vector, crval1_maxpos);
412 cpl_size crval1_minpos = cpl_vector_get_minpos(crval1_vector);
413 double crval1_min = cpl_vector_get(crval1_vector, crval1_minpos);
415 cpl_size crval2_maxpos = cpl_vector_get_maxpos(crval2_vector);
416 double crval2_max = cpl_vector_get(crval2_vector, crval2_maxpos);
417 cpl_size crval2_minpos = cpl_vector_get_minpos(crval2_vector);
418 double crval2_min = cpl_vector_get(crval2_vector, crval2_minpos);
422 double enda[2] = {0.0, 0.0};
423 double endb[2] = {0.0, 0.0};
424 if (fabs(crval1_max - crval1_min) > fabs(crval2_max - crval2_min)) {
425 enda[0] = crval1_min;
426 enda[1] = cpl_vector_get(crval2_vector, crval1_minpos);
427 endb[0] = crval1_max;
428 endb[1] = cpl_vector_get(crval2_vector, crval1_maxpos);
430 enda[0] = cpl_vector_get(crval1_vector, crval2_minpos);
431 enda[1] = crval2_min;
432 endb[0] = cpl_vector_get(crval1_vector, crval2_maxpos);
433 endb[1] = crval2_max;
435 cpl_msg_info(cpl_func,
"Jitter line end points (RA, DEC): "
436 "(%10.7f, %10.7f) and (%10.7f, %10.7f)",
437 enda[0], enda[1], endb[0], endb[1]);
439 double centre[2] = {0.0, 0.0};
445 centre[0] = cpl_vector_get(crval1_vector, 0);
446 centre[1] = cpl_vector_get(crval2_vector, 0);
455 cpl_msg_info(cpl_func,
"Jitter centre %f %f", centre[0], centre[1]);
456 double coslat = cos(centre[1] * CPL_MATH_PI / 180.0);
460 double slit_line[2] = {(endb[0]-enda[0]) * coslat, endb[1]-enda[1]};
461 double slit_norm = sqrt(pow(slit_line[0],2) + pow(slit_line[1],2));
462 slit_line[0] /= slit_norm;
463 slit_line[1] /= slit_norm;
464 double slit_pa = atan2(slit_line[0], slit_line[1]);
465 cpl_msg_info(cpl_func,
"..slit direction vector (long, lat) = (%f, %f)",
466 slit_line[0], slit_line[1]);
467 cpl_msg_info(cpl_func,
"..slit PA = %f deg", slit_pa * 180.0 / CPL_MATH_PI);
469 double cd1_1 = cpl_propertylist_get_double(jitters->limages[0]->
471 double cd2_1 = cpl_propertylist_get_double(jitters->limages[0]->
474 double pixsize = sqrt(cd1_1 * cd1_1 + cd2_1 * cd2_1);
475 cpl_msg_info(cpl_func,
"pixel size %f deg", pixsize);
479 slit_offset = cpl_vector_new(jitters->size);
480 for (cpl_size i = 0; i < jitters->size; i++) {
481 double offset = -1000.0;
483 if (fabs(slit_line[0]) > slit_line[1]) {
484 offset = (cpl_vector_get(crval1_vector, i) - centre[0]) *
485 coslat / slit_line[0];
487 offset = (cpl_vector_get(crval2_vector, i) - centre[1]) /
493 double distance[2] = {0.0,0.0};
494 distance[0] = ((cpl_vector_get(crval1_vector, i) - centre[0]) *
496 (offset * slit_line[0])) / pixsize;
497 distance[1] = ((cpl_vector_get(crval2_vector, i) - centre[1]) -
498 (offset * slit_line[1])) / pixsize;
502 cpl_msg_warning(cpl_func,
503 "...distance from jitter line (%f, %f) pixels",
504 distance[0], distance[1]);
506 cpl_vector_set(slit_offset, i, offset);
507 cpl_msg_info(cpl_func,
"..slit offset jitter %d %f deg",
514 cpl_vector * nominal_offset = cpl_vector_new(jitters->size);
515 for (cpl_size i = 0; i < jitters->size; i++) {
516 cpl_vector_set(nominal_offset, i,
517 cpl_vector_get(slit_offset, i) / pixsize);
519 cpl_msg_info(cpl_func,
"Nominal offset of each jitter from "
520 "reference (pixels):");
521 cpl_vector_dump(nominal_offset, NULL);
522 enu_check_error_code(
"Error calculating nominal slit offsets");
526 cpl_table * poly_table = cpl_table_duplicate(
527 (cpl_table *) startrace_mefs->mef[0]->data);
529 cpl_table_delete(poly_table);
531 poly_table = cpl_table_duplicate(
532 (cpl_table *) startrace_mefs->mef[1]->data);
534 cpl_table_delete(poly_table);
535 enu_check_error_code(
"Error reading warp polynomials");
545 profile = cpl_vector_new(CPL_KERNEL_DEF_SAMPLES);
546 cpl_vector_fill_kernel_profile(profile, CPL_KERNEL_LANCZOS,
547 CPL_KERNEL_DEF_WIDTH);
558 jitters->limages[0]->bkg));
559 cpl_image_warp_polynomial(bkg_copy,
561 jitters->limages[0]->bkg),
562 startrace_poly_i, startrace_poly_j,
563 profile, CPL_KERNEL_DEF_WIDTH,
564 profile, CPL_KERNEL_DEF_WIDTH);
565 cpl_image_reject_value(bkg_copy, CPL_VALUE_NOTFINITE);
567 cpl_image_save(bkg_copy,
"bkg_warped.fits", CPL_TYPE_UNSPECIFIED,
568 NULL, CPL_IO_CREATE);
572 cpl_image * bkg_collapse = cpl_image_collapse_median_create(
573 bkg_copy, 1, 600, 550);
574 cpl_vector * bkg_vector = cpl_vector_new_from_image_column(
576 cpl_vector_save(bkg_vector,
582 cpl_vector_delete(bkg_vector);
583 cpl_image_delete(bkg_collapse);
584 cpl_image_delete(bkg_copy);
589 double actual_offset_0 = 0.0;
591 for (cpl_size j = 0; j < jitters->size; j++) {
598 jitters->limages[j]->himage));
603 jitters->limages[j]->himage), copy_image,
604 startrace_poly_i, startrace_poly_j,
605 profile, CPL_KERNEL_DEF_WIDTH,
606 profile, CPL_KERNEL_DEF_WIDTH);
609 char* filename = cpl_sprintf(
"warp_%d.fits", (
int)j);
611 filename, CPL_TYPE_UNSPECIFIED, NULL,
619 cpl_image * collapse_image = cpl_image_collapse_create(
621 limages[j]->himage), 0);
622 cpl_vector * collapse = cpl_vector_new_from_image_row(
635 double guess = (double) cpl_vector_get_maxpos(collapse);
636 cpl_msg_debug(cpl_func,
"..maxpos %d", (
int)guess);
638 double nominal = cpl_vector_get(nominal_offset, j);
640 actual_offset_0 = actual_offset;
641 cpl_msg_info(cpl_func,
"..object in jitter 0 is at %f pixels",
644 cpl_msg_info(cpl_func,
"multiplying nominal offset by -1 as "
645 "increasing RA decreases detector column");
646 cpl_msg_info(cpl_func,
"..object slit offsets (nominal, "
648 -1.0 * nominal, actual_offset);
658 double xshift = (actual_offset_0 - actual_offset);
659 cpl_msg_info(cpl_func,
"..shift to place object at jitter 0 "
660 "position is %5.2f pixels",
663 cpl_polynomial * shifted_poly_i = eris_nix_lss_shift_polynomial(
664 startrace_poly_i, xshift);
665 cpl_polynomial * shifted_poly_j = eris_nix_lss_shift_polynomial(
666 startrace_poly_j, xshift);
671 jitters->limages[j]->himage), copy_image,
672 shifted_poly_i, shifted_poly_j,
673 profile, CPL_KERNEL_DEF_WIDTH,
674 profile, CPL_KERNEL_DEF_WIDTH);
675 cpl_image_delete(copy_image);
678 char* filename = cpl_sprintf(
"warp2_%d.fits", (
int)j);
680 filename, CPL_TYPE_UNSPECIFIED, NULL,
689 jitters->limages[j]->himage));
691 jitters->limages[j]->himage), copy_error,
692 shifted_poly_i, shifted_poly_j,
693 profile, CPL_KERNEL_DEF_WIDTH,
694 profile, CPL_KERNEL_DEF_WIDTH);
695 cpl_image_delete(copy_error);
700 jitters->limages[j]->bkg));
702 jitters->limages[j]->bkg), copy_bkg,
703 shifted_poly_i, shifted_poly_j,
704 profile, CPL_KERNEL_DEF_WIDTH,
705 profile, CPL_KERNEL_DEF_WIDTH);
706 cpl_image_delete(copy_bkg);
711 jitters->limages[j]->bkg));
713 jitters->limages[j]->bkg), copy_bkg_err,
714 shifted_poly_i, shifted_poly_j,
715 profile, CPL_KERNEL_DEF_WIDTH,
716 profile, CPL_KERNEL_DEF_WIDTH);
717 cpl_image_delete(copy_bkg_err);
721 cpl_image* copy_conf = cpl_image_duplicate(jitters->limages[j]->confidence);
722 cpl_image_warp_polynomial(jitters->limages[j]->confidence, copy_conf,
723 shifted_poly_i, shifted_poly_j,
724 profile, CPL_KERNEL_DEF_WIDTH,
725 profile, CPL_KERNEL_DEF_WIDTH);
726 cpl_image_delete(copy_conf);
730 cpl_polynomial_delete(shifted_poly_i);
731 cpl_polynomial_delete(shifted_poly_j);
732 enu_check_error_code(
"Error resampling data");
737 cpl_size left_edge = 593 + (cpl_size)xshift;
738 cpl_size right_edge = 1507 + (cpl_size)xshift;
742 if (ii > left_edge && ii < right_edge)
continue;
746 cpl_image_set(jitters->limages[j]->confidence, ii+1, jj+1,
749 (hdrl_value){0.0, 0.0});
754 enu_check_error_code(
"Error zeroing confidence outside "
760 for (cpl_size i = 0; i < jitters->size; i++) {
806 cpl_propertylist_update_int(jitters->limages[i]->plist,
"NAXIS", 3);
807 cpl_propertylist_update_string(jitters->limages[i]->plist,
"CTYPE1",
809 cpl_propertylist_update_string(jitters->limages[i]->plist,
"CTYPE2",
811 cpl_propertylist_update_string(jitters->limages[i]->plist,
"CTYPE3",
813 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CRPIX1",
815 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CRPIX2",
817 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CRPIX3",
819 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CRVAL1",
821 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CRVAL2",
823 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CRVAL3",
826 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD1_1",
827 sin(slit_pa) * pixsize);
828 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD1_2",
830 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD1_3",
833 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD2_1",
835 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD2_2",
836 (4.107 - 3.045) / 2047);
837 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD2_3",
840 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD3_1",
841 cos(slit_pa) * pixsize);
842 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD3_2",
844 cpl_propertylist_update_double(jitters->limages[i]->plist,
"CD3_3",
847 cpl_propertylist_update_string(jitters->limages[i]->plist,
"CUNIT1",
849 cpl_propertylist_update_string(jitters->limages[i]->plist,
"CUNIT2",
851 cpl_propertylist_update_string(jitters->limages[i]->plist,
"CUNIT3",
854 cpl_propertylist * applist = cpl_propertylist_new();
855 cpl_propertylist_update_string(applist, CPL_DFS_PRO_CATG, out_catg);
856 cpl_propertylist_update_string(applist,
"PRODCATG",
857 "ANCILLARY.2DSPECTRUM");
864 char* filename = cpl_sprintf(
"warp3_%d.fits", (
int)i);
866 filename, CPL_TYPE_UNSPECIFIED, NULL,
877 jitters->limages[i]->himagelist = NULL;
882 jitters->limages[i]->frame),
885 cpl_frameset * provenance = cpl_frameset_new();
886 cpl_frameset_insert(provenance, cpl_frame_duplicate(
887 jitters->limages[i]->frame));
889 cpl_msg_info(cpl_func,
"..writing %s", out_fname);
896 jitters->limages[i]->frame,
898 PACKAGE
"/" PACKAGE_VERSION,
902 cpl_frameset_delete(provenance);
903 cpl_propertylist_delete(applist);
907 cpl_vector_delete(crval1_vector);
908 cpl_vector_delete(crval2_vector);
910 cpl_table_delete(jitter_table);
912 cpl_vector_delete(profile);
913 cpl_vector_delete(slit_offset);
915 cpl_propertylist_delete(startrace_plist);
916 cpl_polynomial_delete(startrace_poly_i);
917 cpl_polynomial_delete(startrace_poly_j);
919 cpl_frameset_delete(used);
921 return (
int) cpl_error_get_code();
cpl_error_code enu_dfs_save_limage(cpl_frameset *allframes, const cpl_parameterlist *parlist, const cpl_frameset *provenance, const cpl_boolean prov_raw, const located_image *limage, const char *recipe, const cpl_frame *inherit, cpl_propertylist *applist, const char *pipe_id, const char *filename)
Save a located image structure to a MEF.
cpl_error_code eris_nix_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
double enlu_linepos_1d(const cpl_vector *spectrum1d, const double guess_pos, const cpl_size half_width)
Fit line peak.
cpl_polynomial * enlu_warp_poly_load_from_table(const cpl_table *table)
Load a LSS warp polynomial from a cpl_table.
void enu_located_imagelist_delete(located_imagelist *limlist)
Delete a located_imagelist and its contents.
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.
cpl_error_code enu_normalise_confidence(cpl_image *confidence)
Normalise confidence array so that mean of good pixels is 100.
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.
mef_extension_list * enu_load_mef_components(const char *filename, cpl_propertylist **plist)
Load components of a multi-extension FITS file.
cpl_error_code eris_files_dont_exist(cpl_frameset *frameset)
Check if all SOF files exist.
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_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
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
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
cpl_error_code hdrl_imagelist_set(hdrl_imagelist *himlist, hdrl_image *himg, cpl_size pos)
Insert an image into an imagelist.
hdrl_imagelist * hdrl_imagelist_new(void)
Create an empty imagelist.