26#include <cxmessages.h>
28#include <cxstrutils.h>
31#include <cpl_propertylist.h>
36#include "gichebyshev.h"
37#include "giwlresiduals.h"
48struct GiWlResidualData {
55typedef struct GiWlResidualData GiWlResidualData;
66_giraffe_compare_int(cxcptr first, cxcptr second)
69 cxint *_first = (cxint *)first;
70 cxint *_second = (cxint *)second;
72 return *_first - *_second;
78_giraffe_wlresidualdata_delete(GiWlResidualData *self)
84 giraffe_chebyshev2d_delete(self->fit);
96inline static GiWlResidualData *
97_giraffe_wlresiduals_get(
const GiWlResiduals *self, cxsize idx)
100 cx_map_const_iterator position;
102 GiWlResidualData *data = NULL;
105 position = cx_map_begin(self->data);
107 if (position == cx_map_end(self->data)) {
115 for (i = 1; i < idx; i++) {
116 position = cx_map_next(self->data, position);
121 data = cx_map_get_value(self->data, position);
129_giraffe_wlresiduals_insert(GiWlResiduals *self, cxint ssn,
130 const GiChebyshev2D *fit)
133 GiWlResidualData *data = cx_calloc(1,
sizeof *data);
137 data->fit = (GiChebyshev2D *)fit;
139 cx_map_insert(self->data, &data->ssn, data);
147giraffe_wlresiduals_new(
void)
150 GiWlResiduals *self = cx_calloc(1,
sizeof *self);
154 self->data = cx_map_new(_giraffe_compare_int, NULL,
155 (cx_free_func)_giraffe_wlresidualdata_delete);
156 cx_assert(cx_map_empty(self->data));
166giraffe_wlresiduals_clone(
const GiWlResiduals *other)
169 GiWlResiduals *self = NULL;
174 self = giraffe_wlresiduals_new();
176 if (!cx_map_empty(other->data)) {
178 cx_map_const_iterator position = cx_map_begin(other->data);
181 while (position != cx_map_end(other->data)) {
183 GiWlResidualData *data = cx_map_get_value(other->data,
186 GiChebyshev2D *fit = giraffe_chebyshev2d_clone(data->fit);
189 _giraffe_wlresiduals_insert(self, data->ssn, fit);
191 position = cx_map_next(other->data, position);
197 cx_assert(cx_map_size(self->data) == cx_map_size(other->data));
207giraffe_wlresiduals_create(GiTable *wlsolution)
210 const cxchar *
const fctid =
"giraffe_wlresiduals_create";
213 cpl_propertylist *properties = NULL;
215 cpl_table *residuals = NULL;
217 GiWlResiduals *self = giraffe_wlresiduals_new();
220 if (wlsolution == NULL) {
222 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
223 giraffe_wlresiduals_delete(self);
231 if (properties == NULL) {
233 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
234 giraffe_wlresiduals_delete(self);
241 if (residuals == NULL) {
243 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
244 giraffe_wlresiduals_delete(self);
249 if (!cpl_table_has_column(residuals,
"XMIN") ||
250 !cpl_table_has_column(residuals,
"XMAX") ||
251 !cpl_table_has_column(residuals,
"YMIN") ||
252 !cpl_table_has_column(residuals,
"YMAX")) {
259 cpl_table_new_column(residuals,
"XMIN", CPL_TYPE_DOUBLE);
260 cpl_table_new_column(residuals,
"XMAX", CPL_TYPE_DOUBLE);
261 cpl_table_new_column(residuals,
"YMIN", CPL_TYPE_DOUBLE);
262 cpl_table_new_column(residuals,
"YMAX", CPL_TYPE_DOUBLE);
264 cpl_table_set_double(residuals,
"XMIN", 0, 0.);
265 cpl_table_set_double(residuals,
"XMAX", 0, 4096.);
266 cpl_table_set_double(residuals,
"YMIN", 0, 0.);
267 cpl_table_set_double(residuals,
"YMAX", 0, 2048.);
280 cx_string *label = NULL;
282 cpl_matrix *coeffs = NULL;
285 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_XRORDER)) {
287 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
288 giraffe_wlresiduals_delete(self);
297 cpl_propertylist_get_string(properties, GIALIAS_WSOL_XRORDER);
299 cxchar **orders = cx_strsplit(s,
":", 3);
301 if (orders[1] == NULL) {
303 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
304 giraffe_wlresiduals_delete(self);
310 xorder = strtol(orders[0], NULL, 10);
311 yorder = strtol(orders[1], NULL, 10);
320 label = cx_string_new();
321 coeffs = cpl_matrix_new(xorder + 1, yorder + 1);
324 for (i = 0; i < cpl_table_get_nrow(residuals); i++) {
328 cxint ssn = cpl_table_get_int(residuals,
"SSN", i, NULL);
330 cxdouble ax = cpl_table_get(residuals,
"XMIN", i, NULL);
331 cxdouble bx = cpl_table_get(residuals,
"XMAX", i, NULL);
332 cxdouble ay = cpl_table_get(residuals,
"YMIN", i, NULL);
333 cxdouble by = cpl_table_get(residuals,
"YMAX", i, NULL);
335 GiChebyshev2D *fit = NULL;
338 for (j = 0; j <= xorder; j++) {
342 for (k = 0; k <= yorder; k++) {
346 cx_string_sprintf(label,
"XC%-d", l);
347 coeff = cpl_table_get(residuals, cx_string_get(label),
350 cpl_matrix_set(coeffs, j, k, coeff);
357 fit = giraffe_chebyshev2d_new(xorder, yorder);
358 giraffe_chebyshev2d_set(fit, ax, bx, ay, by, coeffs);
360 _giraffe_wlresiduals_insert(self, ssn, fit);
364 cpl_matrix_delete(coeffs);
365 cx_string_delete(label);
375giraffe_wlresiduals_delete(GiWlResiduals *self)
380 if (self->data != NULL) {
381 cx_map_delete(self->data);
394giraffe_wlresiduals_get_size(
const GiWlResiduals *self)
397 cx_assert(self != NULL);
399 return cx_map_size(self->data);
405giraffe_wlresiduals_get_subslit(
const GiWlResiduals *self, cxsize idx)
408 const GiWlResidualData *data = NULL;
411 cx_assert(self != NULL);
413 data = _giraffe_wlresiduals_get(self, idx);
425giraffe_wlresiduals_get_element(
const GiWlResiduals *self, cxsize idx)
428 const GiWlResidualData *data = NULL;
431 cx_assert(self != NULL);
433 data = _giraffe_wlresiduals_get(self, idx);
445giraffe_wlresiduals_set(GiWlResiduals *self, cxint ssn,
446 const GiChebyshev2D *residuals)
449 cx_assert(self != NULL);
451 if (residuals == NULL) {
455 cx_map_erase(self->data, &ssn);
456 _giraffe_wlresiduals_insert(self, ssn , residuals);
463giraffe_wlresiduals_get(
const GiWlResiduals *self, cxint ssn)
466 const GiWlResidualData *data = NULL;
469 cx_assert(self != NULL);
471 data = cx_map_get(self->data, &ssn);
478giraffe_wlresiduals_table(
const GiWlResiduals *self)
481 const cxchar *label =
"SSN";
490 cx_map_const_iterator position;
492 cpl_propertylist *sorting_order = NULL;
494 cpl_table *residuals = NULL;
496 const GiWlResidualData *data = NULL;
499 cx_assert(self != NULL);
501 if (cx_map_empty(self->data)) {
505 position = cx_map_begin(self->data);
507 data = cx_map_get_value(self->data, position);
508 cx_assert(data != NULL);
510 giraffe_chebyshev2d_get_order(data->fit, &xorder, &yorder);
511 ncoeff = (xorder + 1) * (yorder + 1);
514 residuals = cpl_table_new(cx_map_size(self->data));
518 giraffe_error_push();
520 cpl_table_new_column(residuals, label, CPL_TYPE_INT);
522 cpl_table_new_column(residuals,
"XMIN", CPL_TYPE_DOUBLE);
523 cpl_table_new_column(residuals,
"XMAX", CPL_TYPE_DOUBLE);
524 cpl_table_new_column(residuals,
"YMIN", CPL_TYPE_DOUBLE);
525 cpl_table_new_column(residuals,
"YMAX", CPL_TYPE_DOUBLE);
528 for (i = 0; i < ncoeff; i++) {
530 cx_string_sprintf(s,
"XC%-d", i);
531 cpl_table_new_column(residuals, cx_string_get(s), CPL_TYPE_DOUBLE);
535 if (cpl_error_get_code() != CPL_ERROR_NONE) {
537 cpl_table_delete(residuals);
548 while (position != cx_map_end(self->data)) {
562 cpl_matrix *_coeffs = NULL;
564 const GiChebyshev2D *fit = NULL;
567 data = cx_map_get_value(self->data, position);
572 cx_assert(fit != NULL);
574 _coeffs = (cpl_matrix *)giraffe_chebyshev2d_coeffs(fit);
575 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
577 cpl_table_set_int(residuals, label, i , ssn);
579 cpl_table_set_double(residuals,
"XMIN", i, ax);
580 cpl_table_set_double(residuals,
"XMAX", i, bx);
581 cpl_table_set_double(residuals,
"YMIN", i, ay);
582 cpl_table_set_double(residuals,
"YMAX", i, by);
584 nx = cpl_matrix_get_nrow(_coeffs);
585 ny = cpl_matrix_get_ncol(_coeffs);
587 cx_assert(nx * ny == (cxsize)((xorder + 1) * (yorder + 1)));
589 for (j = 0; (cxsize)j < nx; j++) {
593 for (k = 0; (cxsize)k < ny; k++) {
595 cxdouble value = cpl_matrix_get(_coeffs, j, k);
597 cx_string_sprintf(s,
"XC%-" CX_PRINTF_FORMAT_SIZE_TYPE, l);
598 cpl_table_set_double(residuals, cx_string_get(s), i, value);
605 position = cx_map_next(self->data, position);
613 sorting_order = cpl_propertylist_new();
614 cpl_propertylist_append_bool(sorting_order, label, 0);
616 cpl_table_sort(residuals, sorting_order);
618 cpl_propertylist_delete(sorting_order);
619 sorting_order = NULL;
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.