26 #include <cxstrutils.h>
28 #include <cpl_error.h>
29 #include <cpl_propertylist.h>
34 #include "gichebyshev.h"
35 #include "giwlresiduals.h"
46 struct GiWlResidualData {
53 typedef struct GiWlResidualData GiWlResidualData;
56 struct GiWlResiduals {
64 _giraffe_compare_int(cxcptr first, cxcptr second)
67 cxint *_first = (cxint *)first;
68 cxint *_second = (cxint *)second;
70 return *_first - *_second;
76 _giraffe_wlresidualdata_delete(GiWlResidualData *
self)
82 giraffe_chebyshev2d_delete(self->fit);
94 inline static GiWlResidualData *
95 _giraffe_wlresiduals_get(
const GiWlResiduals *
self, cxsize idx)
98 cx_map_const_iterator position;
100 GiWlResidualData *data = NULL;
103 position = cx_map_begin(self->data);
105 if (position == cx_map_end(self->data)) {
113 for (i = 1; i < idx; i++) {
114 position = cx_map_next(self->data, position);
119 data = cx_map_get_value(self->data, position);
127 _giraffe_wlresiduals_insert(GiWlResiduals *
self, cxint ssn,
128 const GiChebyshev2D *fit)
131 GiWlResidualData *data = cx_calloc(1,
sizeof *data);
135 data->fit = (GiChebyshev2D *)fit;
137 cx_map_insert(self->data, &data->ssn, data);
145 giraffe_wlresiduals_new(
void)
148 GiWlResiduals *
self = cx_calloc(1,
sizeof *
self);
152 self->data = cx_map_new(_giraffe_compare_int, NULL,
153 (cx_free_func)_giraffe_wlresidualdata_delete);
154 cx_assert(cx_map_empty(self->data));
164 giraffe_wlresiduals_clone(
const GiWlResiduals *other)
167 GiWlResiduals *
self = NULL;
172 self = giraffe_wlresiduals_new();
174 if (!cx_map_empty(other->data)) {
176 cx_map_const_iterator position = cx_map_begin(other->data);
179 while (position != cx_map_end(other->data)) {
181 GiWlResidualData *data = cx_map_get_value(other->data,
184 GiChebyshev2D *fit = giraffe_chebyshev2d_clone(data->fit);
187 _giraffe_wlresiduals_insert(
self, data->ssn, fit);
189 position = cx_map_next(other->data, position);
195 cx_assert(cx_map_size(self->data) == cx_map_size(other->data));
205 giraffe_wlresiduals_create(GiTable *wlsolution)
208 const cxchar *
const fctid =
"giraffe_wlresiduals_create";
211 cpl_propertylist *properties = NULL;
213 cpl_table *residuals = NULL;
215 GiWlResiduals *
self = giraffe_wlresiduals_new();
218 if (wlsolution == NULL) {
220 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
221 giraffe_wlresiduals_delete(
self);
229 if (properties == NULL) {
231 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
232 giraffe_wlresiduals_delete(
self);
239 if (residuals == NULL) {
241 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
242 giraffe_wlresiduals_delete(
self);
247 if (!cpl_table_has_column(residuals,
"XMIN") ||
248 !cpl_table_has_column(residuals,
"XMAX") ||
249 !cpl_table_has_column(residuals,
"YMIN") ||
250 !cpl_table_has_column(residuals,
"YMAX")) {
257 cpl_table_new_column(residuals,
"XMIN", CPL_TYPE_DOUBLE);
258 cpl_table_new_column(residuals,
"XMAX", CPL_TYPE_DOUBLE);
259 cpl_table_new_column(residuals,
"YMIN", CPL_TYPE_DOUBLE);
260 cpl_table_new_column(residuals,
"YMAX", CPL_TYPE_DOUBLE);
262 cpl_table_set_double(residuals,
"XMIN", 0, 0.);
263 cpl_table_set_double(residuals,
"XMAX", 0, 4096.);
264 cpl_table_set_double(residuals,
"YMIN", 0, 0.);
265 cpl_table_set_double(residuals,
"YMAX", 0, 2048.);
278 cx_string *label = NULL;
280 cpl_matrix *coeffs = NULL;
283 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_XRORDER)) {
285 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
286 giraffe_wlresiduals_delete(
self);
295 cpl_propertylist_get_string(properties, GIALIAS_WSOL_XRORDER);
297 cxchar **orders = cx_strsplit(s,
":", 3);
299 if (orders[1] == NULL) {
301 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
302 giraffe_wlresiduals_delete(
self);
308 xorder = strtol(orders[0], NULL, 10);
309 yorder = strtol(orders[1], NULL, 10);
318 label = cx_string_new();
319 coeffs = cpl_matrix_new(xorder + 1, yorder + 1);
322 for (i = 0; i < cpl_table_get_nrow(residuals); i++) {
326 cxint ssn = cpl_table_get_int(residuals,
"SSN", i, NULL);
328 cxdouble ax = cpl_table_get(residuals,
"XMIN", i, NULL);
329 cxdouble bx = cpl_table_get(residuals,
"XMAX", i, NULL);
330 cxdouble ay = cpl_table_get(residuals,
"YMIN", i, NULL);
331 cxdouble by = cpl_table_get(residuals,
"YMAX", i, NULL);
333 GiChebyshev2D *fit = NULL;
336 for (j = 0; j <= xorder; j++) {
340 for (k = 0; k <= yorder; k++) {
344 cx_string_sprintf(label,
"XC%-d", l);
345 coeff = cpl_table_get(residuals, cx_string_get(label),
348 cpl_matrix_set(coeffs, j, k, coeff);
355 fit = giraffe_chebyshev2d_new(xorder, yorder);
356 giraffe_chebyshev2d_set(fit, ax, bx, ay, by, coeffs);
358 _giraffe_wlresiduals_insert(
self, ssn, fit);
362 cpl_matrix_delete(coeffs);
363 cx_string_delete(label);
373 giraffe_wlresiduals_delete(GiWlResiduals *
self)
378 if (self->data != NULL) {
379 cx_map_delete(self->data);
392 giraffe_wlresiduals_get_size(
const GiWlResiduals *
self)
395 cx_assert(
self != NULL);
397 return cx_map_size(self->data);
403 giraffe_wlresiduals_get_subslit(
const GiWlResiduals *
self, cxsize idx)
406 const GiWlResidualData *data = NULL;
409 cx_assert(
self != NULL);
411 data = _giraffe_wlresiduals_get(
self, idx);
423 giraffe_wlresiduals_get_element(
const GiWlResiduals *
self, cxsize idx)
426 const GiWlResidualData *data = NULL;
429 cx_assert(
self != NULL);
431 data = _giraffe_wlresiduals_get(
self, idx);
443 giraffe_wlresiduals_set(GiWlResiduals *
self, cxint ssn,
444 const GiChebyshev2D *residuals)
447 cx_assert(
self != NULL);
449 if (residuals == NULL) {
453 cx_map_erase(self->data, &ssn);
454 _giraffe_wlresiduals_insert(
self, ssn , residuals);
461 giraffe_wlresiduals_get(
const GiWlResiduals *
self, cxint ssn)
464 const GiWlResidualData *data = NULL;
467 cx_assert(
self != NULL);
469 data = cx_map_get(self->data, &ssn);
476 giraffe_wlresiduals_table(
const GiWlResiduals *
self)
479 const cxchar *label =
"SSN";
488 cx_map_const_iterator position;
490 cpl_propertylist *sorting_order = NULL;
492 cpl_table *residuals = NULL;
494 const GiWlResidualData *data = NULL;
497 cx_assert(
self != NULL);
499 if (cx_map_empty(self->data)) {
503 position = cx_map_begin(self->data);
505 data = cx_map_get_value(self->data, position);
506 cx_assert(data != NULL);
508 giraffe_chebyshev2d_get_order(data->fit, &xorder, &yorder);
509 ncoeff = (xorder + 1) * (yorder + 1);
512 residuals = cpl_table_new(cx_map_size(self->data));
516 giraffe_error_push();
518 cpl_table_new_column(residuals, label, CPL_TYPE_INT);
520 cpl_table_new_column(residuals,
"XMIN", CPL_TYPE_DOUBLE);
521 cpl_table_new_column(residuals,
"XMAX", CPL_TYPE_DOUBLE);
522 cpl_table_new_column(residuals,
"YMIN", CPL_TYPE_DOUBLE);
523 cpl_table_new_column(residuals,
"YMAX", CPL_TYPE_DOUBLE);
526 for (i = 0; i < ncoeff; i++) {
528 cx_string_sprintf(s,
"XC%-d", i);
529 cpl_table_new_column(residuals, cx_string_get(s), CPL_TYPE_DOUBLE);
533 if (cpl_error_get_code() != CPL_ERROR_NONE) {
535 cpl_table_delete(residuals);
546 while (position != cx_map_end(self->data)) {
560 cpl_matrix *_coeffs = NULL;
562 const GiChebyshev2D *fit = NULL;
565 data = cx_map_get_value(self->data, position);
570 cx_assert(fit != NULL);
572 _coeffs = (cpl_matrix *)giraffe_chebyshev2d_coeffs(fit);
573 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
575 cpl_table_set_int(residuals, label, i , ssn);
577 cpl_table_set_double(residuals,
"XMIN", i, ax);
578 cpl_table_set_double(residuals,
"XMAX", i, bx);
579 cpl_table_set_double(residuals,
"YMIN", i, ay);
580 cpl_table_set_double(residuals,
"YMAX", i, by);
582 nx = cpl_matrix_get_nrow(_coeffs);
583 ny = cpl_matrix_get_ncol(_coeffs);
585 cx_assert(nx * ny == (cxsize)((xorder + 1) * (yorder + 1)));
587 for (j = 0; (cxsize)j < nx; j++) {
591 for (k = 0; (cxsize)k < ny; k++) {
593 cxdouble value = cpl_matrix_get(_coeffs, j, k);
595 cx_string_sprintf(s,
"XC%-" CX_PRINTF_FORMAT_SIZE_TYPE, l);
596 cpl_table_set_double(residuals, cx_string_get(s), i, value);
603 position = cx_map_next(self->data, position);
611 sorting_order = cpl_propertylist_new();
612 cpl_propertylist_append_bool(sorting_order, label, 0);
614 cpl_table_sort(residuals, sorting_order);
616 cpl_propertylist_delete(sorting_order);
617 sorting_order = NULL;
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.