37 #include <cxstrutils.h>
39 #include <cpl_error.h>
40 #include <cpl_propertylist.h>
46 #include "gichebyshev.h"
47 #include "giwlsolution.h"
63 GiWlResiduals *residuals;
68 inline static GiWlSolution *
69 _giraffe_wlsolution_new(
const cxchar *name)
72 GiWlSolution *
self = cx_calloc(1,
sizeof *
self);
77 self->model = giraffe_model_new(name);
79 if (self->model == NULL) {
80 giraffe_wlsolution_delete(
self);
84 if (giraffe_model_get_type(self->model) != GI_MODEL_XOPT) {
85 giraffe_wlsolution_delete(
self);
89 self->subslits = FALSE;
90 self->residuals = NULL;
100 giraffe_wlsolution_new(
const cxchar *name, cxint orientation, cxint npixels,
104 GiWlSolution *
self = NULL;
111 if (grating == NULL) {
116 self = _giraffe_wlsolution_new(name);
120 orientation = orientation < 0 ? -npixels : npixels;
123 giraffe_error_push();
125 giraffe_model_set_parameter(self->model,
"Orientation",
127 giraffe_model_set_parameter(self->model,
"Order",
129 giraffe_model_set_parameter(self->model,
"PixelSize",
131 giraffe_model_set_parameter(self->model,
"FocalLength",
133 giraffe_model_set_parameter(self->model,
"Magnification",
135 giraffe_model_set_parameter(self->model,
"Angle",
137 giraffe_model_set_parameter(self->model,
"Spacing",
140 if (strcmp(name,
"xoptmod2") == 0) {
142 giraffe_model_set_parameter(self->model,
"Sdx", grating->
sdx);
143 giraffe_model_set_parameter(self->model,
"Sdy", grating->
sdy);
144 giraffe_model_set_parameter(self->model,
"Sphi", grating->
sphi);
148 if (cpl_error_get_code() != CPL_ERROR_NONE) {
149 giraffe_wlsolution_delete(
self);
179 GiWlSolution *
self = NULL;
184 self = cx_calloc(1,
sizeof(GiWlSolution));
186 self->model = giraffe_model_clone(other->model);
188 self->subslits = other->subslits;
189 self->residuals = giraffe_wlresiduals_clone(other->residuals);
218 const cxchar *name = NULL;
221 cxint orientation = 0;
223 cxdouble pixelsize = 0.;
232 cpl_propertylist *properties = NULL;
234 GiWlSolution *
self = NULL;
238 if (solution == NULL) {
251 if (spectra == NULL) {
264 if (grating == NULL) {
280 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
289 pixelsize = cpl_propertylist_get_double(properties, GIALIAS_PIXSIZX);
305 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMNAME)) {
309 name = cpl_propertylist_get_string(properties, GIALIAS_WSOL_OMNAME);
313 self = _giraffe_wlsolution_new(name);
317 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_SUBSLITS)) {
318 giraffe_wlsolution_delete(
self);
323 self->subslits = cpl_propertylist_get_bool(properties,
324 GIALIAS_WSOL_SUBSLITS);
328 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMDIR)) {
329 giraffe_wlsolution_delete(
self);
333 orientation = cpl_propertylist_get_int(properties,
335 orientation = orientation < 0 ? -fabs(npixels) : fabs(npixels);
339 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMFCOLL)) {
340 giraffe_wlsolution_delete(
self);
344 fcoll = cpl_propertylist_get_double(properties,
345 GIALIAS_WSOL_OMFCOLL);
349 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMGCAM)) {
350 giraffe_wlsolution_delete(
self);
354 gcam = cpl_propertylist_get_double(properties,
355 GIALIAS_WSOL_OMGCAM);
359 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMGTHETA)) {
360 giraffe_wlsolution_delete(
self);
364 theta = cpl_propertylist_get_double(properties,
365 GIALIAS_WSOL_OMGTHETA);
369 if (strcmp(name,
"xoptmod2") == 0) {
371 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDX)) {
372 giraffe_wlsolution_delete(
self);
376 sdx = cpl_propertylist_get_double(properties,
381 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSDY)) {
382 giraffe_wlsolution_delete(
self);
386 sdy = cpl_propertylist_get_double(properties,
391 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_OMSPHI)) {
392 giraffe_wlsolution_delete(
self);
396 sphi = cpl_propertylist_get_double(properties,
397 GIALIAS_WSOL_OMSPHI);
407 giraffe_error_push();
409 giraffe_model_set_parameter(self->model,
"Orientation", orientation);
410 giraffe_model_set_parameter(self->model,
"Order", grating->
order);
411 giraffe_model_set_parameter(self->model,
"PixelSize", pixelsize);
412 giraffe_model_set_parameter(self->model,
"FocalLength", fcoll);
413 giraffe_model_set_parameter(self->model,
"Magnification", gcam);
414 giraffe_model_set_parameter(self->model,
"Angle", theta);
415 giraffe_model_set_parameter(self->model,
"Spacing", grating->
space);
417 if (strcmp(name,
"xoptmod2") == 0) {
418 giraffe_model_set_parameter(self->model,
"Sdx", sdx);
419 giraffe_model_set_parameter(self->model,
"Sdy", sdy);
420 giraffe_model_set_parameter(self->model,
"Sphi", sphi);
423 if (cpl_error_get_code() != CPL_ERROR_NONE) {
424 giraffe_wlsolution_delete(
self);
436 self->residuals = giraffe_wlresiduals_create(solution);
438 if (self->residuals == NULL) {
439 self->subslits = FALSE;
450 giraffe_wlsolution_delete(GiWlSolution *
self)
455 if (self->model != NULL) {
456 giraffe_model_delete(self->model);
459 if (self->residuals != NULL) {
460 giraffe_wlresiduals_delete(self->residuals);
473 giraffe_wlsolution_name(
const GiWlSolution *
self)
476 GiModel *model = NULL;
479 cx_assert(
self != NULL);
482 cx_assert(model != NULL);
484 return giraffe_model_get_name(model);
490 giraffe_wlsolution_model(
const GiWlSolution *
self)
493 cx_assert(
self != NULL);
501 giraffe_wlsolution_set_subslits(GiWlSolution *
self, cxbool flag)
504 cx_assert(
self != NULL);
506 if (self->residuals != NULL) {
510 self->subslits = flag;
518 giraffe_wlsolution_get_subslits(
const GiWlSolution *
self)
521 cx_assert(
self != NULL);
523 return self->subslits;
529 giraffe_wlsolution_set_residuals(GiWlSolution *
self,
530 const GiWlResiduals *residuals)
533 cxbool subslits = FALSE;
536 cx_assert(
self != NULL);
538 if (residuals == NULL) {
549 subslits = giraffe_wlresiduals_get(residuals, 0) == NULL;
551 if (self->subslits != subslits) {
555 giraffe_wlsolution_reset_residuals(
self);
557 self->residuals = (GiWlResiduals *)residuals;
565 giraffe_wlsolution_get_residuals(
const GiWlSolution *
self)
568 cx_assert(
self != NULL);
570 return self->residuals;
576 giraffe_wlsolution_reset_residuals(GiWlSolution *
self)
579 cx_assert(
self != NULL);
581 if (self->residuals != NULL) {
582 giraffe_wlresiduals_delete(self->residuals);
583 self->residuals = NULL;
592 giraffe_wlsolution_compute_pixel(
const GiWlSolution *
self, cxdouble lambda,
593 cxdouble x, cxdouble y, cxint *status)
599 cxdouble result = 0.;
602 cx_assert(
self != NULL);
604 giraffe_error_push();
606 giraffe_model_set_argument(self->model,
"xf", x);
607 giraffe_model_set_argument(self->model,
"yf", y);
608 giraffe_model_set_argument(self->model,
"lambda", lambda);
610 if (cpl_error_get_code() != CPL_ERROR_NONE) {
612 if (status != NULL) {
621 code = giraffe_model_evaluate(self->model, &result, &_status);
625 if (status != NULL) {
633 if (status != NULL) {
643 giraffe_wlsolution_compute_residual(
const GiWlSolution *
self, cxdouble x,
651 const GiWlResiduals *residuals = NULL;
654 cx_assert(
self != NULL);
656 residuals = giraffe_wlsolution_get_residuals(
self);
658 if (residuals == NULL) {
669 for (i = 0; (cxsize)i < giraffe_wlresiduals_get_size(residuals); i++) {
671 const GiChebyshev2D *fit = giraffe_wlresiduals_get(residuals, i);
680 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
682 if (ax <= x && x <= bx && ay <= y && y <= by) {
683 r = giraffe_chebyshev2d_eval(fit, x, y);
697 giraffe_wlsolution_create_table(
const GiWlSolution *solution)
705 cpl_propertylist *properties = NULL;
707 GiTable *result = NULL;
709 const GiModel *model = NULL;
711 const GiWlResiduals *residuals = NULL;
714 if (solution == NULL) {
720 cx_assert(result != NULL);
722 properties = cpl_propertylist_new();
723 cx_assert(properties != NULL);
730 cpl_propertylist_update_string(properties, GIALIAS_GIRFTYPE,
732 cpl_propertylist_set_comment(properties, GIALIAS_GIRFTYPE,
733 "Giraffe frame type.");
735 cpl_propertylist_update_string(properties, GIALIAS_WSOL_OMNAME,
736 giraffe_wlsolution_name(solution));
737 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMNAME,
738 "Optical model name");
740 model = giraffe_wlsolution_model(solution);
742 sign = giraffe_model_get_parameter(model,
"Orientation") < 0 ? -1 : 1;
743 cpl_propertylist_update_int(properties, GIALIAS_WSOL_OMDIR, sign);
744 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMDIR,
745 "Optical model orientation");
747 value = giraffe_model_get_parameter(model,
"FocalLength");
748 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMFCOLL, value);
749 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMFCOLL,
750 "Optical model focal length");
752 value = giraffe_model_get_parameter(model,
"Magnification");
753 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMGCAM, value);
754 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMGCAM,
755 "Optical model camera factor");
757 value = giraffe_model_get_parameter(model,
"Angle");
758 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMGTHETA,
760 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMGTHETA,
761 "Optical model grating angle");
763 if (strcmp(giraffe_wlsolution_name(solution),
"xoptmod2") == 0) {
765 value = giraffe_model_get_parameter(model,
"Sdx");
766 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSDX,
768 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSDX,
769 "Optical model slit x-offset");
771 value = giraffe_model_get_parameter(model,
"Sdy");
772 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSDY,
774 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSDY,
775 "Optical model slit y-offset");
777 value = giraffe_model_get_parameter(model,
"Sphi");
778 cpl_propertylist_update_double(properties, GIALIAS_WSOL_OMSPHI,
780 cpl_propertylist_set_comment(properties, GIALIAS_WSOL_OMSPHI,
781 "Optical model slit rotation");
791 residuals = giraffe_wlsolution_get_residuals(solution);
793 if (residuals != NULL) {
795 cpl_table *coeffs = giraffe_wlresiduals_table(residuals);
797 if (coeffs != NULL) {
805 cpl_propertylist_delete(properties);
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe 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.
cxint giraffe_table_set_properties(GiTable *self, cpl_propertylist *properties)
Attaches a property list to an table.
Structure to handle Grating Information.
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.