34 #include <cxstrutils.h>
36 #include <cpl_error.h>
37 #include <cpl_propertylist.h>
42 #include "gichebyshev.h"
43 #include "giwlresiduals.h"
54 struct GiWlResidualData {
61 typedef struct GiWlResidualData GiWlResidualData;
64 struct GiWlResiduals {
72 _giraffe_compare_int(cxcptr first, cxcptr second)
75 cxint *_first = (cxint *)first;
76 cxint *_second = (cxint *)second;
78 return *_first - *_second;
84 _giraffe_wlresidualdata_delete(GiWlResidualData *
self)
90 giraffe_chebyshev2d_delete(self->fit);
102 inline static GiWlResidualData *
103 _giraffe_wlresiduals_get(
const GiWlResiduals *
self, cxsize idx)
106 cx_map_const_iterator position;
108 GiWlResidualData *data = NULL;
111 position = cx_map_begin(self->data);
113 if (position == cx_map_end(self->data)) {
121 for (i = 1; i < idx; i++) {
122 position = cx_map_next(self->data, position);
127 data = cx_map_get_value(self->data, position);
135 _giraffe_wlresiduals_insert(GiWlResiduals *
self, cxint ssn,
136 const GiChebyshev2D *fit)
139 GiWlResidualData *data = cx_calloc(1,
sizeof *data);
143 data->fit = (GiChebyshev2D *)fit;
145 cx_map_insert(self->data, &data->ssn, data);
153 giraffe_wlresiduals_new(
void)
156 GiWlResiduals *
self = cx_calloc(1,
sizeof *
self);
160 self->data = cx_map_new(_giraffe_compare_int, NULL,
161 (cx_free_func)_giraffe_wlresidualdata_delete);
162 cx_assert(cx_map_empty(self->data));
172 giraffe_wlresiduals_clone(
const GiWlResiduals *other)
175 GiWlResiduals *
self = NULL;
180 self = giraffe_wlresiduals_new();
182 if (!cx_map_empty(other->data)) {
184 cx_map_const_iterator position = cx_map_begin(other->data);
187 while (position != cx_map_end(other->data)) {
189 GiWlResidualData *data = cx_map_get_value(other->data,
192 GiChebyshev2D *fit = giraffe_chebyshev2d_clone(data->fit);
195 _giraffe_wlresiduals_insert(
self, data->ssn, fit);
197 position = cx_map_next(other->data, position);
203 cx_assert(cx_map_size(self->data) == cx_map_size(other->data));
213 giraffe_wlresiduals_create(GiTable *wlsolution)
216 const cxchar *
const fctid =
"giraffe_wlresiduals_create";
219 cpl_propertylist *properties = NULL;
221 cpl_table *residuals = NULL;
223 GiWlResiduals *
self = giraffe_wlresiduals_new();
226 if (wlsolution == NULL) {
228 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
229 giraffe_wlresiduals_delete(
self);
237 if (properties == NULL) {
239 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
240 giraffe_wlresiduals_delete(
self);
247 if (residuals == NULL) {
249 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
250 giraffe_wlresiduals_delete(
self);
255 if (!cpl_table_has_column(residuals,
"XMIN") ||
256 !cpl_table_has_column(residuals,
"XMAX") ||
257 !cpl_table_has_column(residuals,
"YMIN") ||
258 !cpl_table_has_column(residuals,
"YMAX")) {
265 cpl_table_new_column(residuals,
"XMIN", CPL_TYPE_DOUBLE);
266 cpl_table_new_column(residuals,
"XMAX", CPL_TYPE_DOUBLE);
267 cpl_table_new_column(residuals,
"YMIN", CPL_TYPE_DOUBLE);
268 cpl_table_new_column(residuals,
"YMAX", CPL_TYPE_DOUBLE);
270 cpl_table_set_double(residuals,
"XMIN", 0, 0.);
271 cpl_table_set_double(residuals,
"XMAX", 0, 4096.);
272 cpl_table_set_double(residuals,
"YMIN", 0, 0.);
273 cpl_table_set_double(residuals,
"YMAX", 0, 2048.);
286 cx_string *label = NULL;
288 cpl_matrix *coeffs = NULL;
291 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_XRORDER)) {
293 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
294 giraffe_wlresiduals_delete(
self);
303 cpl_propertylist_get_string(properties, GIALIAS_WSOL_XRORDER);
305 cxchar **orders = cx_strsplit(s,
":", 3);
307 if (orders[1] == NULL) {
309 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
310 giraffe_wlresiduals_delete(
self);
316 xorder = strtol(orders[0], NULL, 10);
317 yorder = strtol(orders[1], NULL, 10);
326 label = cx_string_new();
327 coeffs = cpl_matrix_new(xorder + 1, yorder + 1);
330 for (i = 0; i < cpl_table_get_nrow(residuals); i++) {
334 cxint ssn = cpl_table_get_int(residuals,
"SSN", i, NULL);
336 cxdouble ax = cpl_table_get(residuals,
"XMIN", i, NULL);
337 cxdouble bx = cpl_table_get(residuals,
"XMAX", i, NULL);
338 cxdouble ay = cpl_table_get(residuals,
"YMIN", i, NULL);
339 cxdouble by = cpl_table_get(residuals,
"YMAX", i, NULL);
341 GiChebyshev2D *fit = NULL;
344 for (j = 0; j <= xorder; j++) {
348 for (k = 0; k <= yorder; k++) {
352 cx_string_sprintf(label,
"XC%-d", l);
353 coeff = cpl_table_get(residuals, cx_string_get(label),
356 cpl_matrix_set(coeffs, j, k, coeff);
363 fit = giraffe_chebyshev2d_new(xorder, yorder);
364 giraffe_chebyshev2d_set(fit, ax, bx, ay, by, coeffs);
366 _giraffe_wlresiduals_insert(
self, ssn, fit);
370 cpl_matrix_delete(coeffs);
371 cx_string_delete(label);
381 giraffe_wlresiduals_delete(GiWlResiduals *
self)
386 if (self->data != NULL) {
387 cx_map_delete(self->data);
400 giraffe_wlresiduals_get_size(
const GiWlResiduals *
self)
403 cx_assert(
self != NULL);
405 return cx_map_size(self->data);
411 giraffe_wlresiduals_get_subslit(
const GiWlResiduals *
self, cxsize idx)
414 const GiWlResidualData *data = NULL;
417 cx_assert(
self != NULL);
419 data = _giraffe_wlresiduals_get(
self, idx);
431 giraffe_wlresiduals_get_element(
const GiWlResiduals *
self, cxsize idx)
434 const GiWlResidualData *data = NULL;
437 cx_assert(
self != NULL);
439 data = _giraffe_wlresiduals_get(
self, idx);
451 giraffe_wlresiduals_set(GiWlResiduals *
self, cxint ssn,
452 const GiChebyshev2D *residuals)
455 cx_assert(
self != NULL);
457 if (residuals == NULL) {
461 cx_map_erase(self->data, &ssn);
462 _giraffe_wlresiduals_insert(
self, ssn , residuals);
469 giraffe_wlresiduals_get(
const GiWlResiduals *
self, cxint ssn)
472 const GiWlResidualData *data = NULL;
475 cx_assert(
self != NULL);
477 data = cx_map_get(self->data, &ssn);
484 giraffe_wlresiduals_table(
const GiWlResiduals *
self)
487 const cxchar *label =
"SSN";
496 cx_map_const_iterator position;
498 cpl_propertylist *sorting_order = NULL;
500 cpl_table *residuals = NULL;
502 const GiWlResidualData *data = NULL;
505 cx_assert(
self != NULL);
507 if (cx_map_empty(self->data)) {
511 position = cx_map_begin(self->data);
513 data = cx_map_get_value(self->data, position);
514 cx_assert(data != NULL);
516 giraffe_chebyshev2d_get_order(data->fit, &xorder, &yorder);
517 ncoeff = (xorder + 1) * (yorder + 1);
520 residuals = cpl_table_new(cx_map_size(self->data));
524 giraffe_error_push();
526 cpl_table_new_column(residuals, label, CPL_TYPE_INT);
528 cpl_table_new_column(residuals,
"XMIN", CPL_TYPE_DOUBLE);
529 cpl_table_new_column(residuals,
"XMAX", CPL_TYPE_DOUBLE);
530 cpl_table_new_column(residuals,
"YMIN", CPL_TYPE_DOUBLE);
531 cpl_table_new_column(residuals,
"YMAX", CPL_TYPE_DOUBLE);
534 for (i = 0; i < ncoeff; i++) {
536 cx_string_sprintf(s,
"XC%-d", i);
537 cpl_table_new_column(residuals, cx_string_get(s), CPL_TYPE_DOUBLE);
541 if (cpl_error_get_code() != CPL_ERROR_NONE) {
543 cpl_table_delete(residuals);
554 while (position != cx_map_end(self->data)) {
568 cpl_matrix *_coeffs = NULL;
570 const GiChebyshev2D *fit = NULL;
573 data = cx_map_get_value(self->data, position);
578 cx_assert(fit != NULL);
580 _coeffs = (cpl_matrix *)giraffe_chebyshev2d_coeffs(fit);
581 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
583 cpl_table_set_int(residuals, label, i , ssn);
585 cpl_table_set_double(residuals,
"XMIN", i, ax);
586 cpl_table_set_double(residuals,
"XMAX", i, bx);
587 cpl_table_set_double(residuals,
"YMIN", i, ay);
588 cpl_table_set_double(residuals,
"YMAX", i, by);
590 nx = cpl_matrix_get_nrow(_coeffs);
591 ny = cpl_matrix_get_ncol(_coeffs);
593 cx_assert(nx * ny == (cxsize)((xorder + 1) * (yorder + 1)));
595 for (j = 0; (cxsize)j < nx; j++) {
599 for (k = 0; (cxsize)k < ny; k++) {
601 cxdouble value = cpl_matrix_get(_coeffs, j, k);
603 cx_string_sprintf(s,
"XC%-" CX_PRINTF_FORMAT_SIZE_TYPE, l);
604 cpl_table_set_double(residuals, cx_string_get(s), i, value);
611 position = cx_map_next(self->data, position);
619 sorting_order = cpl_propertylist_new();
620 cpl_propertylist_append_bool(sorting_order, label, 0);
622 cpl_table_sort(residuals, sorting_order);
624 cpl_propertylist_delete(sorting_order);
625 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.