29#include <cxmessages.h>
31#include <cxstrutils.h>
34#include <cpl_propertylist.h>
40#include "gichebyshev.h"
41#include "giwlsolution.h"
57 GiWlResiduals *residuals;
62inline static GiWlSolution *
63_giraffe_wlsolution_new(
const cxchar *name)
66 GiWlSolution *self = cx_calloc(1,
sizeof *self);
71 self->model = giraffe_model_new(name);
73 if (self->model == NULL) {
74 giraffe_wlsolution_delete(self);
78 if (giraffe_model_get_type(self->model) != GI_MODEL_XOPT) {
79 giraffe_wlsolution_delete(self);
83 self->subslits = FALSE;
84 self->residuals = NULL;
94giraffe_wlsolution_new(
const cxchar *name, cxint orientation, cxint npixels,
98 GiWlSolution *self = NULL;
105 if (grating == NULL) {
110 self = _giraffe_wlsolution_new(name);
114 orientation = orientation < 0 ? -npixels : npixels;
117 giraffe_error_push();
119 giraffe_model_set_parameter(self->model,
"Orientation",
121 giraffe_model_set_parameter(self->model,
"Order",
123 giraffe_model_set_parameter(self->model,
"PixelSize",
125 giraffe_model_set_parameter(self->model,
"FocalLength",
127 giraffe_model_set_parameter(self->model,
"Magnification",
129 giraffe_model_set_parameter(self->model,
"Angle",
131 giraffe_model_set_parameter(self->model,
"Spacing",
134 if (strcmp(name,
"xoptmod2") == 0) {
136 giraffe_model_set_parameter(self->model,
"Sdx", grating->
sdx);
137 giraffe_model_set_parameter(self->model,
"Sdy", grating->
sdy);
138 giraffe_model_set_parameter(self->model,
"Sphi", grating->
sphi);
142 if (cpl_error_get_code() != CPL_ERROR_NONE) {
143 giraffe_wlsolution_delete(self);
173 GiWlSolution *self = NULL;
178 self = cx_calloc(1,
sizeof(GiWlSolution));
180 self->model = giraffe_model_clone(other->model);
182 self->subslits = other->subslits;
183 self->residuals = giraffe_wlresiduals_clone(other->residuals);
212 const cxchar *name = NULL;
215 cxint orientation = 0;
217 cxdouble pixelsize = 0.;
226 cpl_propertylist *properties = NULL;
228 GiWlSolution *self = NULL;
232 if (solution == NULL) {
245 if (spectra == NULL) {
258 if (grating == NULL) {
274 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
283 pixelsize = cpl_propertylist_get_double(properties, GIALIAS_PIXSIZX);
299 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMNAME)) {
303 name = cpl_propertylist_get_string(properties, GIALIAS_WSOL_OMNAME);
307 self = _giraffe_wlsolution_new(name);
311 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_SUBSLITS)) {
312 giraffe_wlsolution_delete(self);
317 self->subslits = cpl_propertylist_get_bool(properties,
318 GIALIAS_WSOL_SUBSLITS);
322 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMDIR)) {
323 giraffe_wlsolution_delete(self);
327 orientation = cpl_propertylist_get_int(properties,
329 orientation = orientation < 0 ? -fabs(npixels) : fabs(npixels);
333 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMFCOLL)) {
334 giraffe_wlsolution_delete(self);
338 fcoll = cpl_propertylist_get_double(properties,
339 GIALIAS_WSOL_OMFCOLL);
343 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMGCAM)) {
344 giraffe_wlsolution_delete(self);
348 gcam = cpl_propertylist_get_double(properties,
349 GIALIAS_WSOL_OMGCAM);
353 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMGTHETA)) {
354 giraffe_wlsolution_delete(self);
358 theta = cpl_propertylist_get_double(properties,
359 GIALIAS_WSOL_OMGTHETA);
363 if (strcmp(name,
"xoptmod2") == 0) {
365 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDX)) {
366 giraffe_wlsolution_delete(self);
370 sdx = cpl_propertylist_get_double(properties,
375 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDY)) {
376 giraffe_wlsolution_delete(self);
380 sdy = cpl_propertylist_get_double(properties,
385 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSPHI)) {
386 giraffe_wlsolution_delete(self);
390 sphi = cpl_propertylist_get_double(properties,
391 GIALIAS_WSOL_OMSPHI);
401 giraffe_error_push();
403 giraffe_model_set_parameter(self->model,
"Orientation", orientation);
404 giraffe_model_set_parameter(self->model,
"Order", grating->
order);
405 giraffe_model_set_parameter(self->model,
"PixelSize", pixelsize);
406 giraffe_model_set_parameter(self->model,
"FocalLength", fcoll);
407 giraffe_model_set_parameter(self->model,
"Magnification", gcam);
408 giraffe_model_set_parameter(self->model,
"Angle", theta);
409 giraffe_model_set_parameter(self->model,
"Spacing", grating->
space);
411 if (strcmp(name,
"xoptmod2") == 0) {
412 giraffe_model_set_parameter(self->model,
"Sdx", sdx);
413 giraffe_model_set_parameter(self->model,
"Sdy", sdy);
414 giraffe_model_set_parameter(self->model,
"Sphi", sphi);
417 if (cpl_error_get_code() != CPL_ERROR_NONE) {
418 giraffe_wlsolution_delete(self);
430 self->residuals = giraffe_wlresiduals_create(solution);
432 if (self->residuals == NULL) {
433 self->subslits = FALSE;
444giraffe_wlsolution_delete(GiWlSolution *self)
449 if (self->model != NULL) {
450 giraffe_model_delete(self->model);
453 if (self->residuals != NULL) {
454 giraffe_wlresiduals_delete(self->residuals);
467giraffe_wlsolution_name(
const GiWlSolution *self)
470 GiModel *model = NULL;
473 cx_assert(self != NULL);
476 cx_assert(model != NULL);
478 return giraffe_model_get_name(model);
484giraffe_wlsolution_model(
const GiWlSolution *self)
487 cx_assert(self != NULL);
495giraffe_wlsolution_set_subslits(GiWlSolution *self, cxbool flag)
498 cx_assert(self != NULL);
500 if (self->residuals != NULL) {
504 self->subslits = flag;
512giraffe_wlsolution_get_subslits(
const GiWlSolution *self)
515 cx_assert(self != NULL);
517 return self->subslits;
523giraffe_wlsolution_set_residuals(GiWlSolution *self,
524 const GiWlResiduals *residuals)
527 cxbool subslits = FALSE;
530 cx_assert(self != NULL);
532 if (residuals == NULL) {
543 subslits = giraffe_wlresiduals_get(residuals, 0) == NULL;
545 if (self->subslits != subslits) {
549 giraffe_wlsolution_reset_residuals(self);
551 self->residuals = (GiWlResiduals *)residuals;
559giraffe_wlsolution_get_residuals(
const GiWlSolution *self)
562 cx_assert(self != NULL);
564 return self->residuals;
570giraffe_wlsolution_reset_residuals(GiWlSolution *self)
573 cx_assert(self != NULL);
575 if (self->residuals != NULL) {
576 giraffe_wlresiduals_delete(self->residuals);
577 self->residuals = NULL;
586giraffe_wlsolution_compute_pixel(
const GiWlSolution *self, cxdouble lambda,
587 cxdouble x, cxdouble y, cxint *status)
593 cxdouble result = 0.;
596 cx_assert(self != NULL);
598 giraffe_error_push();
600 giraffe_model_set_argument(self->model,
"xf", x);
601 giraffe_model_set_argument(self->model,
"yf", y);
602 giraffe_model_set_argument(self->model,
"lambda", lambda);
604 if (cpl_error_get_code() != CPL_ERROR_NONE) {
606 if (status != NULL) {
615 code = giraffe_model_evaluate(self->model, &result, &_status);
619 if (status != NULL) {
627 if (status != NULL) {
637giraffe_wlsolution_compute_residual(
const GiWlSolution *self, cxdouble x,
645 const GiWlResiduals *residuals = NULL;
648 cx_assert(self != NULL);
650 residuals = giraffe_wlsolution_get_residuals(self);
652 if (residuals == NULL) {
663 for (i = 0; (cxsize)i < giraffe_wlresiduals_get_size(residuals); i++) {
665 const GiChebyshev2D *fit = giraffe_wlresiduals_get(residuals, i);
674 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
676 if (ax <= x && x <= bx && ay <= y && y <= by) {
677 r = giraffe_chebyshev2d_eval(fit, x, y);
691giraffe_wlsolution_create_table(
const GiWlSolution *solution)
699 cpl_propertylist *properties = NULL;
701 GiTable *result = NULL;
703 const GiModel *model = NULL;
705 const GiWlResiduals *residuals = NULL;
708 if (solution == NULL) {
714 cx_assert(result != NULL);
716 properties = cpl_propertylist_new();
717 cx_assert(properties != NULL);
724 cpl_propertylist_update_string(properties, GIALIAS_GIRFTYPE,
726 cpl_propertylist_set_comment(properties, GIALIAS_GIRFTYPE,
727 "Giraffe frame type.");
729 cpl_propertylist_update_string(properties, GIALIAS_WSOL_OMNAME,
730 giraffe_wlsolution_name(solution));
731 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMNAME,
732 "Optical model name");
734 model = giraffe_wlsolution_model(solution);
736 sign = giraffe_model_get_parameter(model,
"Orientation") < 0 ? -1 : 1;
737 cpl_propertylist_update_int(properties, GIALIAS_WSOL_OMDIR, sign);
738 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMDIR,
739 "Optical model orientation");
741 value = giraffe_model_get_parameter(model,
"FocalLength");
742 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMFCOLL, value);
743 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMFCOLL,
744 "Optical model focal length");
746 value = giraffe_model_get_parameter(model,
"Magnification");
747 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMGCAM, value);
748 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMGCAM,
749 "Optical model camera factor");
751 value = giraffe_model_get_parameter(model,
"Angle");
752 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMGTHETA,
754 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMGTHETA,
755 "Optical model grating angle");
757 if (strcmp(giraffe_wlsolution_name(solution),
"xoptmod2") == 0) {
759 value = giraffe_model_get_parameter(model,
"Sdx");
760 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSDX,
762 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSDX,
763 "Optical model slit x-offset");
765 value = giraffe_model_get_parameter(model,
"Sdy");
766 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSDY,
768 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSDY,
769 "Optical model slit y-offset");
771 value = giraffe_model_get_parameter(model,
"Sphi");
772 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSPHI,
774 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSPHI,
775 "Optical model slit rotation");
785 residuals = giraffe_wlsolution_get_residuals(solution);
787 if (residuals != NULL) {
789 cpl_table *coeffs = giraffe_wlresiduals_table(residuals);
791 if (coeffs != NULL) {
799 cpl_propertylist_delete(properties);
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
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.
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
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.