29 #include <cxstrutils.h>
31 #include <cpl_error.h>
32 #include <cpl_propertylist.h>
38 #include "gichebyshev.h"
39 #include "giwlsolution.h"
55 GiWlResiduals *residuals;
60 inline static GiWlSolution *
61 _giraffe_wlsolution_new(
const cxchar *name)
64 GiWlSolution *
self = cx_calloc(1,
sizeof *
self);
69 self->model = giraffe_model_new(name);
71 if (self->model == NULL) {
72 giraffe_wlsolution_delete(
self);
76 if (giraffe_model_get_type(self->model) != GI_MODEL_XOPT) {
77 giraffe_wlsolution_delete(
self);
81 self->subslits = FALSE;
82 self->residuals = NULL;
92 giraffe_wlsolution_new(
const cxchar *name, cxint orientation, cxint npixels,
96 GiWlSolution *
self = NULL;
103 if (grating == NULL) {
108 self = _giraffe_wlsolution_new(name);
112 orientation = orientation < 0 ? -npixels : npixels;
115 giraffe_error_push();
117 giraffe_model_set_parameter(self->model,
"Orientation",
119 giraffe_model_set_parameter(self->model,
"Order",
121 giraffe_model_set_parameter(self->model,
"PixelSize",
123 giraffe_model_set_parameter(self->model,
"FocalLength",
125 giraffe_model_set_parameter(self->model,
"Magnification",
127 giraffe_model_set_parameter(self->model,
"Angle",
129 giraffe_model_set_parameter(self->model,
"Spacing",
132 if (strcmp(name,
"xoptmod2") == 0) {
134 giraffe_model_set_parameter(self->model,
"Sdx", grating->
sdx);
135 giraffe_model_set_parameter(self->model,
"Sdy", grating->
sdy);
136 giraffe_model_set_parameter(self->model,
"Sphi", grating->
sphi);
140 if (cpl_error_get_code() != CPL_ERROR_NONE) {
141 giraffe_wlsolution_delete(
self);
171 GiWlSolution *
self = NULL;
176 self = cx_calloc(1,
sizeof(GiWlSolution));
178 self->model = giraffe_model_clone(other->model);
180 self->subslits = other->subslits;
181 self->residuals = giraffe_wlresiduals_clone(other->residuals);
210 const cxchar *name = NULL;
213 cxint orientation = 0;
215 cxdouble pixelsize = 0.;
224 cpl_propertylist *properties = NULL;
226 GiWlSolution *
self = NULL;
230 if (solution == NULL) {
243 if (spectra == NULL) {
256 if (grating == NULL) {
272 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
281 pixelsize = cpl_propertylist_get_double(properties, GIALIAS_PIXSIZX);
297 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMNAME)) {
301 name = cpl_propertylist_get_string(properties, GIALIAS_WSOL_OMNAME);
305 self = _giraffe_wlsolution_new(name);
309 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_SUBSLITS)) {
310 giraffe_wlsolution_delete(
self);
315 self->subslits = cpl_propertylist_get_bool(properties,
316 GIALIAS_WSOL_SUBSLITS);
320 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMDIR)) {
321 giraffe_wlsolution_delete(
self);
325 orientation = cpl_propertylist_get_int(properties,
327 orientation = orientation < 0 ? -fabs(npixels) : fabs(npixels);
331 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMFCOLL)) {
332 giraffe_wlsolution_delete(
self);
336 fcoll = cpl_propertylist_get_double(properties,
337 GIALIAS_WSOL_OMFCOLL);
341 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMGCAM)) {
342 giraffe_wlsolution_delete(
self);
346 gcam = cpl_propertylist_get_double(properties,
347 GIALIAS_WSOL_OMGCAM);
351 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMGTHETA)) {
352 giraffe_wlsolution_delete(
self);
356 theta = cpl_propertylist_get_double(properties,
357 GIALIAS_WSOL_OMGTHETA);
361 if (strcmp(name,
"xoptmod2") == 0) {
363 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDX)) {
364 giraffe_wlsolution_delete(
self);
368 sdx = cpl_propertylist_get_double(properties,
373 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDY)) {
374 giraffe_wlsolution_delete(
self);
378 sdy = cpl_propertylist_get_double(properties,
383 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSPHI)) {
384 giraffe_wlsolution_delete(
self);
388 sphi = cpl_propertylist_get_double(properties,
389 GIALIAS_WSOL_OMSPHI);
399 giraffe_error_push();
401 giraffe_model_set_parameter(self->model,
"Orientation", orientation);
402 giraffe_model_set_parameter(self->model,
"Order", grating->
order);
403 giraffe_model_set_parameter(self->model,
"PixelSize", pixelsize);
404 giraffe_model_set_parameter(self->model,
"FocalLength", fcoll);
405 giraffe_model_set_parameter(self->model,
"Magnification", gcam);
406 giraffe_model_set_parameter(self->model,
"Angle", theta);
407 giraffe_model_set_parameter(self->model,
"Spacing", grating->
space);
409 if (strcmp(name,
"xoptmod2") == 0) {
410 giraffe_model_set_parameter(self->model,
"Sdx", sdx);
411 giraffe_model_set_parameter(self->model,
"Sdy", sdy);
412 giraffe_model_set_parameter(self->model,
"Sphi", sphi);
415 if (cpl_error_get_code() != CPL_ERROR_NONE) {
416 giraffe_wlsolution_delete(
self);
428 self->residuals = giraffe_wlresiduals_create(solution);
430 if (self->residuals == NULL) {
431 self->subslits = FALSE;
442 giraffe_wlsolution_delete(GiWlSolution *
self)
447 if (self->model != NULL) {
448 giraffe_model_delete(self->model);
451 if (self->residuals != NULL) {
452 giraffe_wlresiduals_delete(self->residuals);
465 giraffe_wlsolution_name(
const GiWlSolution *
self)
468 GiModel *model = NULL;
471 cx_assert(
self != NULL);
474 cx_assert(model != NULL);
476 return giraffe_model_get_name(model);
482 giraffe_wlsolution_model(
const GiWlSolution *
self)
485 cx_assert(
self != NULL);
493 giraffe_wlsolution_set_subslits(GiWlSolution *
self, cxbool flag)
496 cx_assert(
self != NULL);
498 if (self->residuals != NULL) {
502 self->subslits = flag;
510 giraffe_wlsolution_get_subslits(
const GiWlSolution *
self)
513 cx_assert(
self != NULL);
515 return self->subslits;
521 giraffe_wlsolution_set_residuals(GiWlSolution *
self,
522 const GiWlResiduals *residuals)
525 cxbool subslits = FALSE;
528 cx_assert(
self != NULL);
530 if (residuals == NULL) {
541 subslits = giraffe_wlresiduals_get(residuals, 0) == NULL;
543 if (self->subslits != subslits) {
547 giraffe_wlsolution_reset_residuals(
self);
549 self->residuals = (GiWlResiduals *)residuals;
557 giraffe_wlsolution_get_residuals(
const GiWlSolution *
self)
560 cx_assert(
self != NULL);
562 return self->residuals;
568 giraffe_wlsolution_reset_residuals(GiWlSolution *
self)
571 cx_assert(
self != NULL);
573 if (self->residuals != NULL) {
574 giraffe_wlresiduals_delete(self->residuals);
575 self->residuals = NULL;
584 giraffe_wlsolution_compute_pixel(
const GiWlSolution *
self, cxdouble lambda,
585 cxdouble x, cxdouble y, cxint *status)
591 cxdouble result = 0.;
594 cx_assert(
self != NULL);
596 giraffe_error_push();
598 giraffe_model_set_argument(self->model,
"xf", x);
599 giraffe_model_set_argument(self->model,
"yf", y);
600 giraffe_model_set_argument(self->model,
"lambda", lambda);
602 if (cpl_error_get_code() != CPL_ERROR_NONE) {
604 if (status != NULL) {
613 code = giraffe_model_evaluate(self->model, &result, &_status);
617 if (status != NULL) {
625 if (status != NULL) {
635 giraffe_wlsolution_compute_residual(
const GiWlSolution *
self, cxdouble x,
643 const GiWlResiduals *residuals = NULL;
646 cx_assert(
self != NULL);
648 residuals = giraffe_wlsolution_get_residuals(
self);
650 if (residuals == NULL) {
661 for (i = 0; (cxsize)i < giraffe_wlresiduals_get_size(residuals); i++) {
663 const GiChebyshev2D *fit = giraffe_wlresiduals_get(residuals, i);
672 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
674 if (ax <= x && x <= bx && ay <= y && y <= by) {
675 r = giraffe_chebyshev2d_eval(fit, x, y);
689 giraffe_wlsolution_create_table(
const GiWlSolution *solution)
697 cpl_propertylist *properties = NULL;
699 GiTable *result = NULL;
701 const GiModel *model = NULL;
703 const GiWlResiduals *residuals = NULL;
706 if (solution == NULL) {
712 cx_assert(result != NULL);
714 properties = cpl_propertylist_new();
715 cx_assert(properties != NULL);
722 cpl_propertylist_update_string(properties, GIALIAS_GIRFTYPE,
724 cpl_propertylist_set_comment(properties, GIALIAS_GIRFTYPE,
725 "Giraffe frame type.");
727 cpl_propertylist_update_string(properties, GIALIAS_WSOL_OMNAME,
728 giraffe_wlsolution_name(solution));
729 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMNAME,
730 "Optical model name");
732 model = giraffe_wlsolution_model(solution);
734 sign = giraffe_model_get_parameter(model,
"Orientation") < 0 ? -1 : 1;
735 cpl_propertylist_update_int(properties, GIALIAS_WSOL_OMDIR, sign);
736 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMDIR,
737 "Optical model orientation");
739 value = giraffe_model_get_parameter(model,
"FocalLength");
740 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMFCOLL, value);
741 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMFCOLL,
742 "Optical model focal length");
744 value = giraffe_model_get_parameter(model,
"Magnification");
745 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMGCAM, value);
746 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMGCAM,
747 "Optical model camera factor");
749 value = giraffe_model_get_parameter(model,
"Angle");
750 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMGTHETA,
752 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMGTHETA,
753 "Optical model grating angle");
755 if (strcmp(giraffe_wlsolution_name(solution),
"xoptmod2") == 0) {
757 value = giraffe_model_get_parameter(model,
"Sdx");
758 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSDX,
760 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSDX,
761 "Optical model slit x-offset");
763 value = giraffe_model_get_parameter(model,
"Sdy");
764 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSDY,
766 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSDY,
767 "Optical model slit y-offset");
769 value = giraffe_model_get_parameter(model,
"Sphi");
770 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSPHI,
772 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSPHI,
773 "Optical model slit rotation");
783 residuals = giraffe_wlsolution_get_residuals(solution);
785 if (residuals != NULL) {
787 cpl_table *coeffs = giraffe_wlresiduals_table(residuals);
789 if (coeffs != NULL) {
797 cpl_propertylist_delete(properties);
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe table.
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
cxint giraffe_table_set_properties(GiTable *self, cpl_propertylist *properties)
Attaches a property list to an table.
GiWlSolution * giraffe_wlsolution_create(GiTable *solution, GiImage *spectra, GiGrating *grating)
Create a new wavelength solution from a wavelength solution table.
GiWlSolution * giraffe_wlsolution_clone(const GiWlSolution *other)
Create a new wavelength solution from another wavelength solution.
Structure to handle Grating Information.