40 #include "irplib_plugin.h"
41 #include "irplib_utils.h"
42 #include "irplib_spectrum.h"
44 #include "isaac_utils.h"
45 #include "isaac_pfits.h"
46 #include "isaac_dfs.h"
52 #define RECIPE_STRING "isaac_spc_startrace"
54 #define Z_LR_LEFT_REJ 300
55 #define Z_LR_RIGHT_REJ 325
56 #define SZ_LR_LEFT_REJ 300
57 #define SZ_LR_RIGHT_REJ 325
58 #define J_LR_LEFT_REJ 200
59 #define J_LR_RIGHT_REJ 200
60 #define SH_LR_LEFT_REJ 150
61 #define SH_LR_RIGHT_REJ 175
62 #define SK_LR_LEFT_REJ 150
63 #define SK_LR_RIGHT_REJ 175
64 #define MR_LEFT_REJ 30
65 #define MR_RIGHT_REJ 30
71 static cpl_error_code isaac_spc_startrace_reduce(cpl_frameset *,
73 const cpl_matrix *,
char,
74 const cpl_parameterlist *);
76 static cpl_size * isaac_spc_startrace_resol(cpl_frameset *);
77 static cpl_imagelist * isaac_spc_startrace_load(
const cpl_frameset *);
78 static cpl_matrix * isaac_spc_startrace_starpos(
const cpl_frameset *);
79 static cpl_polynomial * isaac_spc_startrace_shape(cpl_image *,
double,
char,
81 static cpl_polynomial * isaac_spc_startrace_distor(cpl_polynomial **,
82 cpl_vector *,
int,
int);
83 static cpl_error_code isaac_spc_startrace_save(cpl_frameset *,
90 const cpl_parameterlist *);
93 cpl_recipe_define(isaac_spc_startrace, ISAAC_BINARY_VERSION,
94 "Lars Lundin", PACKAGE_BUGREPORT,
"2002, 2003, 2008",
95 "ISAAC Spectro startrace recipe",
96 RECIPE_STRING
" -- ISAAC Spectro startrace recipe\n"
97 "The files listed in the Set Of Frames (sof-file) "
99 "raw-file.fits "ISAAC_SPC_STARTRACE_IM_RAW
" or\n"
100 "raw-file.fits "ISAAC_SPC_STARTRACE_SP_RAW
"\n"
101 "Given N imaging frames, the spectro frames must consist of "
102 "N (or zero) low resolution frames and "
103 "N (or zero) medium resolution frames.");
129 } isaac_spc_startrace_config;
145 cpl_error_code isaac_spc_startrace_fill_parameterlist(cpl_parameterlist *
self)
147 const char * context = PACKAGE
"." RECIPE_STRING;
150 cpl_ensure_code(
self, CPL_ERROR_NULL_INPUT);
155 err = irplib_parameterlist_set_int(
self, PACKAGE, RECIPE_STRING,
157 context,
"polynomial degree");
158 cpl_ensure_code(!err, err);
161 err = irplib_parameterlist_set_int(
self, PACKAGE, RECIPE_STRING,
162 "spectrum_width", 40,
"spec_width",
163 context,
"spectrum width");
164 cpl_ensure_code(!err, err);
167 err = irplib_parameterlist_set_int(
self, PACKAGE, RECIPE_STRING,
168 "reject_left", -1, NULL,
169 context,
"left part rejection");
170 cpl_ensure_code(!err, err);
173 err = irplib_parameterlist_set_int(
self, PACKAGE, RECIPE_STRING,
174 "reject_right", -1, NULL,
175 context,
"right part rejection");
176 cpl_ensure_code(!err, err);
179 err = irplib_parameterlist_set_bool(
self, PACKAGE, RECIPE_STRING,
180 "display", CPL_FALSE, NULL, context,
181 "Flag to make plots");
182 cpl_ensure_code(!err, err);
184 return CPL_ERROR_NONE;
197 static int isaac_spc_startrace(cpl_frameset * framelist,
198 const cpl_parameterlist * parlist)
201 cpl_size * labels = NULL;
202 const cpl_frame * cur_frame;
203 cpl_propertylist * plist = NULL;
204 cpl_frameset * imframes = NULL;
205 cpl_frameset * spframes = NULL;
206 cpl_frameset * spframes_lr = NULL;
207 cpl_frameset * spframes_mr = NULL;
208 cpl_matrix * star_pos = NULL;
217 isaac_spc_startrace_config.degree
218 = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
221 isaac_spc_startrace_config.spec_width
222 = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
225 isaac_spc_startrace_config.reject_left
226 = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
228 isaac_spc_startrace_config.reject_right
229 = irplib_parameterlist_get_int(parlist, PACKAGE, RECIPE_STRING,
232 isaac_spc_startrace_config.display
233 = irplib_parameterlist_get_bool(parlist, PACKAGE, RECIPE_STRING,
240 cur_frame = cpl_frameset_get_position_const(framelist,0);
241 error_if(cur_frame == NULL, CPL_ERROR_DATA_NOT_FOUND,
242 "Could not get 1st frame from frameset");
243 plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
244 any_if(
"Could not load propertylist from 1st frame");
247 any_if(
"Could not get the arm");
249 if (sval[0] ==
'S') {
250 isaac_spc_startrace_config.arm = 1;
251 }
else if (sval[0] ==
'L') {
252 isaac_spc_startrace_config.arm = 2;
254 error_if(1, CPL_ERROR_UNSUPPORTED_MODE,
"Unsupported arm: %s", sval);
259 any_if(
"Could not get the filter");
262 any_if(
"Could not get the band");
264 cpl_propertylist_empty(plist);
268 error_if(imframes == NULL, CPL_ERROR_DATA_NOT_FOUND,
"Could not find the "
269 "imframes in the input list");
272 error_if(spframes == NULL, CPL_ERROR_DATA_NOT_FOUND,
"Could not find the "
273 "spframes in the input list");
276 labels = isaac_spc_startrace_resol(spframes);
277 error_if(labels == NULL, cpl_error_get_code(),
"Could not differentiate "
280 spframes_lr = cpl_frameset_extract(spframes, labels, 1);
281 spframes_mr = cpl_frameset_extract(spframes, labels, 2);
286 cpl_msg_info(cpl_func,
"Get the star positions");
287 star_pos = isaac_spc_startrace_starpos(imframes);
288 error_if(star_pos == NULL, cpl_error_get_code(),
"Could not find star the "
291 cpl_frameset_delete(imframes);
294 error_if (spframes_lr == NULL && spframes_mr == NULL,
295 CPL_ERROR_UNSUPPORTED_MODE,
"The %d spectro frames are not LR "
296 "nor MR", (
int)cpl_frameset_get_size(spframes));
297 cpl_frameset_delete(spframes);
300 if (spframes_lr != NULL) {
301 cpl_errorstate prestate = cpl_errorstate_get();
303 cpl_msg_info(cpl_func,
"Reducing the LR spectra");
304 if (isaac_spc_startrace_reduce(framelist, spframes_lr, star_pos,
306 irplib_error_recover(prestate,
"Could not reduce the LR spectra");
310 cpl_frameset_delete(spframes_lr);
313 if (spframes_mr != NULL) {
314 cpl_errorstate prestate = cpl_errorstate_get();
316 cpl_msg_info(cpl_func,
"Reducing the MR spectra");
317 if (isaac_spc_startrace_reduce(framelist, spframes_mr, star_pos,
319 irplib_error_recover(prestate,
"Could not reduce the MR spectra");
323 cpl_frameset_delete(spframes_mr);
327 error_if(!ndone, CPL_ERROR_ILLEGAL_INPUT,
"Could not reduce the spectra");
332 cpl_propertylist_delete(plist);
333 cpl_frameset_delete(imframes);
334 cpl_frameset_delete(spframes);
335 cpl_frameset_delete(spframes_lr);
336 cpl_frameset_delete(spframes_mr);
337 cpl_matrix_delete(star_pos);
339 return cpl_error_get_code();
355 cpl_error_code isaac_spc_startrace_reduce(cpl_frameset * framelist,
356 const cpl_frameset * spframes,
357 const cpl_matrix * star_pos,
359 const cpl_parameterlist * parlist)
362 cpl_imagelist * ilist = isaac_spc_startrace_load(spframes);
363 const int nframes = cpl_frameset_get_size(spframes);
364 cpl_vector * spec_pos = cpl_vector_new(nframes);
365 double * pspec_pos = cpl_vector_get_data(spec_pos);
366 cpl_polynomial * corresp = cpl_polynomial_new(1);
367 cpl_polynomial ** shapes = cpl_calloc(nframes,
sizeof(cpl_polynomial*));
368 cpl_vector * fit_q = cpl_vector_new(nframes);
369 double * pfit_q = cpl_vector_get_data(fit_q);
370 const int nx = cpl_image_get_size_x(cpl_imagelist_get(ilist, 0));
371 cpl_polynomial * distor = NULL;
372 cpl_table * out_tab = NULL;
374 const cpl_size maxdeg = 2;
378 bug_if(framelist == NULL);
379 bug_if(star_pos == NULL);
380 bug_if(parlist == NULL);
382 error_if(cpl_matrix_get_ncol(star_pos) != nframes,
383 CPL_ERROR_INCOMPATIBLE_INPUT,
"Number of spectro frames (%d) "
384 "differ from number of star positions (%d)", nframes,
385 (
int)cpl_matrix_get_ncol(star_pos));
388 for (i=0; i<nframes; i++) {
389 const cpl_image * image = cpl_imagelist_get_const(ilist, i);
390 const double mean = cpl_image_get_mean(image);
391 const double min_bright = 20.0 * mean;
393 error_if (irplib_spectrum_find_brightest(image, 0, NO_SHADOW,
394 min_bright, 0, &(pspec_pos[i])),
395 cpl_error_get_code(),
"Could not detect spectrum in frame %d "
396 "of %d with mean flux=%g", (
int)i+1, nframes, mean);
400 error_if (cpl_polynomial_fit(corresp, star_pos, NULL, spec_pos, NULL,
401 CPL_FALSE, NULL, &maxdeg), cpl_error_get_code(),
402 "Could not fit a %d degree polynomial to the %d positions",
403 (
int)maxdeg, nframes);
407 isaac_spc_startrace_config.corr_is1 = cpl_polynomial_get_coeff(corresp, &i);
409 isaac_spc_startrace_config.corr_is2 = cpl_polynomial_get_coeff(corresp, &i);
411 isaac_spc_startrace_config.corr_is3 = cpl_polynomial_get_coeff(corresp, &i);
412 cpl_polynomial_delete(corresp);
416 for (i=0; i<nframes; i++) {
417 shapes[i] = isaac_spc_startrace_shape(cpl_imagelist_get(ilist, i),
418 cpl_vector_get(spec_pos, i),
422 error_if (shapes[i] == NULL, cpl_error_get_code(),
"Could not get the "
423 "shape of frame %d of %d", (
int)i+1, nframes);
425 cpl_msg_info(cpl_func,
"Spectrum %d : Y = %g; Fit mse = %g", (
int)i+1,
426 cpl_vector_get(spec_pos, i), pfit_q[i]);
428 isaac_spc_startrace_config.shapes_fit_q = cpl_vector_get_median_const(fit_q);
429 cpl_vector_delete(fit_q);
431 cpl_imagelist_delete(ilist);
435 distor = isaac_spc_startrace_distor(shapes, spec_pos, nframes, nx);
436 error_if (distor == NULL, cpl_error_get_code(),
"Could not compute the "
440 out_tab = cpl_table_new(6);
441 cpl_table_new_column(out_tab,
"Degree_of_x", CPL_TYPE_INT);
442 cpl_table_new_column(out_tab,
"Degree_of_y", CPL_TYPE_INT);
443 cpl_table_new_column(out_tab,
"poly2d_coef", CPL_TYPE_DOUBLE);
444 power[0] = 0; power[1] = 0;
445 cpl_table_set_int(out_tab,
"Degree_of_x", 0, power[0]);
446 cpl_table_set_int(out_tab,
"Degree_of_y", 0, power[1]);
447 isaac_spc_startrace_config.dist1 = cpl_polynomial_get_coeff(distor, power);
448 cpl_table_set_double(out_tab,
"poly2d_coef", 0,
449 isaac_spc_startrace_config.dist1);
450 power[0] = 1; power[1] = 0;
451 cpl_table_set_int(out_tab,
"Degree_of_x", 1, power[0]);
452 cpl_table_set_int(out_tab,
"Degree_of_y", 1, power[1]);
453 isaac_spc_startrace_config.distx = cpl_polynomial_get_coeff(distor, power);
454 cpl_table_set_double(out_tab,
"poly2d_coef", 1,
455 isaac_spc_startrace_config.distx);
456 power[0] = 0; power[1] = 1;
457 cpl_table_set_int(out_tab,
"Degree_of_x", 2, power[0]);
458 cpl_table_set_int(out_tab,
"Degree_of_y", 2, power[1]);
459 isaac_spc_startrace_config.disty = cpl_polynomial_get_coeff(distor, power);
460 cpl_table_set_double(out_tab,
"poly2d_coef", 2,
461 isaac_spc_startrace_config.disty);
462 power[0] = 1; power[1] = 1;
463 cpl_table_set_int(out_tab,
"Degree_of_x", 3, power[0]);
464 cpl_table_set_int(out_tab,
"Degree_of_y", 3, power[1]);
465 isaac_spc_startrace_config.distxy = cpl_polynomial_get_coeff(distor, power);
466 cpl_table_set_double(out_tab,
"poly2d_coef", 3,
467 isaac_spc_startrace_config.distxy);
468 power[0] = 2; power[1] = 0;
469 cpl_table_set_int(out_tab,
"Degree_of_x", 4, power[0]);
470 cpl_table_set_int(out_tab,
"Degree_of_y", 4, power[1]);
471 isaac_spc_startrace_config.distxx = cpl_polynomial_get_coeff(distor, power);
472 cpl_table_set_double(out_tab,
"poly2d_coef", 4,
473 isaac_spc_startrace_config.distxx);
474 power[0] = 0; power[1] = 2;
475 cpl_table_set_int(out_tab,
"Degree_of_x", 5, power[0]);
476 cpl_table_set_int(out_tab,
"Degree_of_y", 5, power[1]);
477 isaac_spc_startrace_config.distyy = cpl_polynomial_get_coeff(distor, power);
478 cpl_table_set_double(out_tab,
"poly2d_coef", 5,
479 isaac_spc_startrace_config.distyy);
481 cpl_polynomial_delete(distor);
485 cpl_msg_info(cpl_func,
486 "Distortion : Y(x,y) = a + bx + cy + dxy + exx + fyy");
487 cpl_msg_info(cpl_func,
"a = %g", isaac_spc_startrace_config.dist1);
488 cpl_msg_info(cpl_func,
"b = %g", isaac_spc_startrace_config.distx);
489 cpl_msg_info(cpl_func,
"c = %g", isaac_spc_startrace_config.disty);
490 cpl_msg_info(cpl_func,
"d = %g", isaac_spc_startrace_config.distxy);
491 cpl_msg_info(cpl_func,
"e = %g", isaac_spc_startrace_config.distxx);
492 cpl_msg_info(cpl_func,
"f = %g", isaac_spc_startrace_config.distyy);
495 skip_if (isaac_spc_startrace_save(framelist, out_tab, star_pos, spec_pos,
496 shapes, spframes, resol, parlist));
500 cpl_polynomial_delete(distor);
501 cpl_vector_delete(fit_q);
502 cpl_polynomial_delete(corresp);
503 if (shapes != NULL) {
504 for (i = 0; i < nframes; i++) cpl_polynomial_delete(shapes[i]);
507 cpl_vector_delete(spec_pos);
508 cpl_imagelist_delete(ilist);
509 cpl_table_delete(out_tab);
511 return cpl_error_get_code();
523 static cpl_size * isaac_spc_startrace_resol(cpl_frameset * spframes)
527 cpl_frame * cur_frame;
528 cpl_propertylist * plist;
533 if (spframes == NULL)
return NULL;
536 nframes = cpl_frameset_get_size(spframes);
539 labels = (cpl_size*)cpl_malloc(nframes *
sizeof(*labels));
542 for (i=0; i<nframes; i++) {
543 cur_frame = cpl_frameset_get_position(spframes, i);
544 plist=cpl_propertylist_load(cpl_frame_get_filename(cur_frame), 0);
548 cpl_msg_error(cpl_func,
"cannot get the resolution");
551 if (sval[0]==
'L') labels[i] = 1;
552 else if (sval[0]==
'M') labels[i] = 2;
554 cpl_propertylist_delete(plist);
567 static cpl_matrix * isaac_spc_startrace_starpos(
const cpl_frameset * imframes)
570 cpl_matrix * ypositions;
571 cpl_apertures * objects;
573 cpl_imagelist * ilist;
577 if (imframes == NULL)
return NULL;
580 if ((ilist = isaac_spc_startrace_load(imframes)) == NULL)
return NULL;
583 nframes = cpl_frameset_get_size(imframes);
586 ypositions = cpl_matrix_new(1, nframes);
587 ypos = cpl_matrix_get_data(ypositions);
590 for (i=0; i<nframes; i++) {
592 if ((objects = cpl_apertures_extract_sigma(cpl_imagelist_get(ilist, i),
594 cpl_msg_error(cpl_func,
"cannot detect any object");
595 cpl_matrix_delete(ypositions);
596 cpl_imagelist_delete(ilist);
599 cpl_apertures_sort_by_flux(objects);
600 xpos = cpl_apertures_get_centroid_x(objects, 1);
601 ypos[i] = cpl_apertures_get_centroid_y(objects, 1);
602 cpl_apertures_delete(objects);
603 cpl_msg_info(cpl_func,
"Image %d: Position (%g, %g)", i+1,xpos, ypos[i]);
605 cpl_imagelist_delete(ilist);
617 static cpl_imagelist * isaac_spc_startrace_load(
const cpl_frameset * inframes)
619 cpl_imagelist * ilist;
625 if (inframes == NULL)
return NULL;
628 nframes = cpl_frameset_get_size(inframes);
631 if ((ilist = cpl_imagelist_load_frameset(inframes, CPL_TYPE_FLOAT, 1,
632 0)) == NULL)
return NULL;
635 if (isaac_spc_startrace_config.arm == 2)
return ilist;
638 tmp_im = cpl_image_duplicate(cpl_imagelist_get(ilist, 0));
639 for (i=0; i<nframes-1; i++) {
640 if (cpl_image_subtract(cpl_imagelist_get(ilist, i),
641 cpl_imagelist_get(ilist, i+1)) != CPL_ERROR_NONE) {
642 cpl_msg_error(cpl_func,
"cannot subtract images");
643 cpl_imagelist_delete(ilist);
644 cpl_image_delete(tmp_im);
649 if (cpl_image_subtract(cpl_imagelist_get(ilist, nframes-1),
650 tmp_im) != CPL_ERROR_NONE) {
651 cpl_msg_error(cpl_func,
"cannot subtract images");
652 cpl_imagelist_delete(ilist);
653 cpl_image_delete(tmp_im);
656 cpl_image_delete(tmp_im);
659 cpl_imagelist_threshold(ilist, 0.0, DBL_MAX, 0.0, 0.0);
675 static cpl_polynomial * isaac_spc_startrace_shape(
679 double * fit_quality)
681 int reject_left, reject_right;
682 cpl_image * filtered;
683 int low_side, up_side;
689 cpl_polynomial * fitted;
690 cpl_bivector * toplot;
693 const cpl_boolean sampsym = CPL_TRUE;
696 if ((in == NULL) || (ypos < 0) || (fit_quality == NULL))
return NULL;
699 reject_left = isaac_spc_startrace_config.reject_left;
700 reject_right = isaac_spc_startrace_config.reject_right;
701 low_side = (int)(ypos - (isaac_spc_startrace_config.spec_width)/2);
702 up_side = low_side + isaac_spc_startrace_config.spec_width;
705 if ((low_side < 1) || (up_side > cpl_image_get_size_y(in))) {
706 cpl_msg_error(cpl_func,
"spectrum too close to the image border");
711 if (isaac_spc_startrace_config.arm == 1) {
713 if (reject_left < 0) {
714 if (resol ==
'M') reject_left = MR_LEFT_REJ;
715 else if (resol ==
'L') {
716 switch (isaac_spc_startrace_config.band) {
717 case ISAAC_BAND_Z: reject_left = Z_LR_LEFT_REJ;
break;
718 case ISAAC_BAND_SZ: reject_left = SZ_LR_LEFT_REJ;
break;
719 case ISAAC_BAND_JBLOCK:
720 case ISAAC_BAND_J: reject_left = J_LR_LEFT_REJ;
break;
721 case ISAAC_BAND_SH: reject_left = SH_LR_LEFT_REJ;
break;
722 case ISAAC_BAND_SK: reject_left = SK_LR_LEFT_REJ;
break;
724 cpl_msg_warning(cpl_func,
"unsupported filter");
730 if (reject_right < 0) {
731 if (resol ==
'M') reject_right = MR_RIGHT_REJ;
732 else if (resol ==
'L') {
733 switch (isaac_spc_startrace_config.band) {
734 case ISAAC_BAND_Z: reject_right = Z_LR_RIGHT_REJ;
break;
735 case ISAAC_BAND_SZ: reject_right = SZ_LR_RIGHT_REJ;
break;
736 case ISAAC_BAND_JBLOCK:
737 case ISAAC_BAND_J: reject_right = J_LR_RIGHT_REJ;
break;
738 case ISAAC_BAND_SH: reject_right = SH_LR_RIGHT_REJ;
break;
739 case ISAAC_BAND_SK: reject_right = SK_LR_RIGHT_REJ;
break;
741 cpl_msg_warning(cpl_func,
"unsupported filter");
747 }
else if (isaac_spc_startrace_config.arm == 2) {
749 if (reject_left < 0) reject_left = 150;
750 if (reject_right < 0) reject_right = 150;
753 cpl_msg_error(cpl_func,
"Unrecognized mode - abort");
758 kernel = cpl_mask_new(3, 3);
759 cpl_mask_not(kernel);
760 filtered = cpl_image_new(cpl_image_get_size_x(in), cpl_image_get_size_y(in),
761 cpl_image_get_type(in));
762 if (cpl_image_filter_mask(filtered, in, kernel, CPL_FILTER_MEDIAN,
763 CPL_BORDER_FILTER)) {
764 cpl_msg_error(cpl_func,
"cannot filter the image");
765 cpl_mask_delete(kernel);
768 cpl_mask_delete(kernel);
771 nsamples = cpl_image_get_size_x(in) - reject_right - reject_left;
772 fit_x = cpl_matrix_new(1, nsamples);
773 pfit_x = cpl_matrix_get_data(fit_x);
774 fit_y = cpl_vector_new(nsamples);
775 pfit_y = cpl_vector_get_data(fit_y);
776 for (i=0; i < nsamples; i++) {
777 pfit_x[i] = (double)(i+1+reject_left);
778 pfit_y[i] = cpl_image_get_centroid_y_window(filtered, i+1+reject_left,
779 low_side, i+1+reject_left, up_side);
781 cpl_image_delete(filtered);
784 fitted = cpl_polynomial_new(1);
785 if (cpl_polynomial_fit(fitted, fit_x, &sampsym, fit_y, NULL, CPL_FALSE,
786 NULL, &(isaac_spc_startrace_config.degree))) {
787 cpl_msg_error(cpl_func,
"cannot fit the shape");
788 cpl_polynomial_delete(fitted);
789 cpl_matrix_delete(fit_x);
790 cpl_vector_delete(fit_y);
795 if (isaac_spc_startrace_config.display) {
797 = cpl_vector_wrap(nsamples, pfit_x);
798 toplot = cpl_bivector_wrap_vectors(vfit_x, fit_y);
799 cpl_plot_bivector(NULL, NULL, NULL, toplot);
800 cpl_bivector_unwrap_vectors(toplot);
801 (void)cpl_vector_unwrap(vfit_x);
804 cpl_vector_fill_polynomial_fit_residual(fit_y, fit_y, NULL, fitted,
806 *fit_quality = cpl_vector_product(fit_y, fit_y) / nsamples;
809 if (isaac_spc_startrace_config.display) {
811 = cpl_vector_wrap(nsamples, pfit_x);
812 toplot = cpl_bivector_wrap_vectors(vfit_x, fit_y);
813 for (i=0; i<nsamples; i++) {
814 pfit_y[i] = cpl_polynomial_eval_1d(fitted, pfit_x[i], NULL);
816 cpl_plot_bivector(NULL, NULL, NULL, toplot);
817 cpl_bivector_unwrap_vectors(toplot);
818 (void)cpl_vector_unwrap(vfit_x);
822 cpl_matrix_delete(fit_x);
823 cpl_vector_delete(fit_y);
838 static cpl_polynomial * isaac_spc_startrace_distor(
839 cpl_polynomial ** shapes,
840 cpl_vector * spec_pos,
844 cpl_polynomial * distor;
850 int nb_xpoints, npoints;
853 const cpl_size maxdeg = 2;
857 npoints = nb_xpoints * nshapes;
860 xy_vec = cpl_matrix_new(2, npoints);
861 x_data = cpl_matrix_get_data(xy_vec);
862 y_data = x_data + npoints;
863 z_vec = cpl_vector_new(npoints);
864 z_data = cpl_vector_get_data(z_vec);
865 for (j=0; j<nshapes; j++) {
866 for (i=0; i<nb_xpoints; i++) {
867 pos = i + j*nb_xpoints;
868 x_data[pos] = nx * (i+1) / nb_xpoints;
869 y_data[pos] = cpl_vector_get(spec_pos, j);
870 z_data[pos] = cpl_polynomial_eval_1d(shapes[j], x_data[pos], NULL);
875 distor = cpl_polynomial_new(2);
876 if (cpl_polynomial_fit(distor, xy_vec, NULL, z_vec, NULL, CPL_FALSE, NULL,
878 cpl_msg_error(cpl_func,
"cannot fit the distortion");
879 cpl_matrix_delete(xy_vec);
880 cpl_vector_delete(z_vec);
881 cpl_polynomial_delete(distor);
884 cpl_matrix_delete(xy_vec);
885 cpl_vector_delete(z_vec);
906 cpl_error_code isaac_spc_startrace_save(cpl_frameset * set_tot,
907 const cpl_table * tab,
908 const cpl_matrix * star_pos,
909 const cpl_vector * spec_pos,
910 cpl_polynomial ** shapes,
911 const cpl_frameset * set,
913 const cpl_parameterlist * parlist)
915 cpl_propertylist * plist;
916 cpl_propertylist * qclist;
917 cpl_propertylist * paflist;
918 const cpl_frame * ref_frame;
920 cpl_table * shapes_table;
921 cpl_table * pos_table;
922 const char * procatt;
928 qclist = cpl_propertylist_new();
931 cpl_propertylist_append_double(qclist,
"ESO QC CORR_IS1",
932 isaac_spc_startrace_config.corr_is1);
933 cpl_propertylist_append_double(qclist,
"ESO QC CORR_IS2",
934 isaac_spc_startrace_config.corr_is2);
935 cpl_propertylist_append_double(qclist,
"ESO QC CORR_IS3",
936 isaac_spc_startrace_config.corr_is3);
937 cpl_propertylist_append_double(qclist,
"ESO QC FITMSE",
938 isaac_spc_startrace_config.shapes_fit_q);
939 cpl_propertylist_append_double(qclist,
"ESO QC DIST1",
940 isaac_spc_startrace_config.dist1);
941 cpl_propertylist_append_double(qclist,
"ESO QC DISTX",
942 isaac_spc_startrace_config.distx);
943 cpl_propertylist_append_double(qclist,
"ESO QC DISTY",
944 isaac_spc_startrace_config.disty);
945 cpl_propertylist_append_double(qclist,
"ESO QC DISTXY",
946 isaac_spc_startrace_config.distxy);
947 cpl_propertylist_append_double(qclist,
"ESO QC DISTXX",
948 isaac_spc_startrace_config.distxx);
949 cpl_propertylist_append_double(qclist,
"ESO QC DISTYY",
950 isaac_spc_startrace_config.distyy);
953 procatt = isaac_spc_startrace_config.arm == 1
954 ? ISAAC_SPC_STARTRACE_SW_RES : ISAAC_SPC_STARTRACE_LW_RES;
955 filename = cpl_sprintf(
"isaac_spc_startrace_2dpoly_%cR.fits", resol);
956 irplib_dfs_save_table(set_tot,
961 "isaac_spc_startrace",
965 PACKAGE
"/" PACKAGE_VERSION,
970 pos_table = cpl_table_new(cpl_matrix_get_ncol(star_pos));
973 cpl_table_wrap_double(pos_table, cpl_matrix_get_data((cpl_matrix*)star_pos),
976 cpl_table_wrap_double(pos_table, cpl_vector_get_data((cpl_vector*)spec_pos),
979 procat = isaac_spc_startrace_config.arm == 1
980 ? ISAAC_SPC_STARTRACE_SW_POS : ISAAC_SPC_STARTRACE_LW_POS;
981 filename = cpl_sprintf(
"isaac_spc_startrace_positions_%cR.fits", resol);
982 irplib_dfs_save_table(set_tot,
987 "isaac_spc_startrace",
991 PACKAGE
"/" PACKAGE_VERSION,
995 (void)cpl_table_unwrap(pos_table,
"Star_positions");
996 (void)cpl_table_unwrap(pos_table,
"Spec_positions");
997 cpl_table_delete(pos_table);
1000 shapes_table = cpl_table_new(isaac_spc_startrace_config.degree + 1);
1001 for (i=0; i<cpl_vector_get_size(spec_pos); i++) {
1002 sprintf(colname,
"Spec_%d", i+1);
1003 cpl_table_new_column(shapes_table, colname, CPL_TYPE_DOUBLE);
1005 for (i=0; i<cpl_vector_get_size(spec_pos); i++) {
1007 sprintf(colname,
"Spec_%d", i+1);
1008 for (j=0; j<isaac_spc_startrace_config.degree + 1; j++) {
1009 cpl_table_set_double(shapes_table, colname, j,
1010 cpl_polynomial_get_coeff(shapes[i], &j));
1013 procat = isaac_spc_startrace_config.arm == 1 ?
1014 ISAAC_SPC_STARTRACE_SW_SHAPE : ISAAC_SPC_STARTRACE_LW_SHAPE;
1015 filename = cpl_sprintf(
"isaac_spc_startrace_shapes_%cR.fits", resol);
1016 irplib_dfs_save_table(set_tot,
1021 "isaac_spc_startrace",
1025 PACKAGE
"/" PACKAGE_VERSION,
1028 cpl_table_delete(shapes_table);
1031 ref_frame = irplib_frameset_get_first_from_group(set, CPL_FRAME_GROUP_RAW);
1034 if ((plist=cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
1036 cpl_msg_error(cpl_func,
"getting header from reference frame");
1037 cpl_propertylist_delete(qclist);
1038 return CPL_ERROR_UNSPECIFIED;
1042 paflist = cpl_propertylist_new();
1043 cpl_propertylist_copy_property_regexp(paflist, plist,
1044 "^(ARCFILE|MJD-OBS|INSTRUME|ESO TPL ID|ESO TPL NEXP|ESO DPR CATG|"
1045 "ESO DPR TECH|ESO DPR TYPE|DATE-OBS|ESO INS GRAT NAME|"
1046 "ESO OCS SELECT-ARM)$", 0);
1047 cpl_propertylist_delete(plist);
1050 cpl_propertylist_copy_property_regexp(paflist, qclist,
".", 0);
1051 cpl_propertylist_delete(qclist);
1054 cpl_propertylist_update_string(paflist, CPL_DFS_PRO_CATG, procatt);
1057 filename = cpl_sprintf(
"isaac_spc_startrace_%cR.paf", resol);
1058 cpl_dfs_save_paf(
"ISAAC",
1059 "isaac_spc_startrace",
1063 cpl_propertylist_delete(paflist);
int isaac_dfs_set_groups(cpl_frameset *set)
Set the group as RAW or CALIB in a frameset.
const char * isaac_pfits_get_arm(const cpl_propertylist *plist)
find out the arm which is active
const char * isaac_pfits_get_resolution(const cpl_propertylist *plist)
find out the resolution
const char * isaac_pfits_get_filter(const cpl_propertylist *plist)
find out the filter
isaac_band isaac_get_bbfilter(const char *f)
Get the broad band filter.
cpl_frameset * isaac_extract_frameset(const cpl_frameset *self, const char *tag)
Extract the frames with the given tag from a frameset.