GIRAFFE Pipeline Reference Manual

giwlresiduals.c
1/*
2 * This file is part of the GIRAFFE Pipeline
3 * Copyright (C) 2002-2019 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <cxmap.h>
25#include <cxmemory.h>
26#include <cxmessages.h>
27#include <cxstring.h>
28#include <cxstrutils.h>
29
30#include <cpl_error.h>
31#include <cpl_propertylist.h>
32
33#include "gialias.h"
34#include "gitable.h"
35#include "gierror.h"
36#include "gichebyshev.h"
37#include "giwlresiduals.h"
38
39
48struct GiWlResidualData {
49
50 cxint ssn;
51 GiChebyshev2D *fit;
52
53};
54
55typedef struct GiWlResidualData GiWlResidualData;
56
57
58struct GiWlResiduals {
59
60 cx_map *data;
61
62};
63
64
65inline static cxint
66_giraffe_compare_int(cxcptr first, cxcptr second)
67{
68
69 cxint *_first = (cxint *)first;
70 cxint *_second = (cxint *)second;
71
72 return *_first - *_second;
73
74}
75
76
77inline static void
78_giraffe_wlresidualdata_delete(GiWlResidualData *self)
79{
80
81 if (self) {
82
83 if (self->fit) {
84 giraffe_chebyshev2d_delete(self->fit);
85 }
86
87 cx_free(self);
88
89 }
90
91 return;
92
93}
94
95
96inline static GiWlResidualData *
97_giraffe_wlresiduals_get(const GiWlResiduals *self, cxsize idx)
98{
99
100 cx_map_const_iterator position;
101
102 GiWlResidualData *data = NULL;
103
104
105 position = cx_map_begin(self->data);
106
107 if (position == cx_map_end(self->data)) {
108 return NULL;
109 }
110
111 if (idx > 0) {
112
113 cxsize i;
114
115 for (i = 1; i < idx; i++) {
116 position = cx_map_next(self->data, position);
117 }
118
119 }
120
121 data = cx_map_get_value(self->data, position);
122
123 return data;
124
125}
126
127
128inline static void
129_giraffe_wlresiduals_insert(GiWlResiduals *self, cxint ssn,
130 const GiChebyshev2D *fit)
131{
132
133 GiWlResidualData *data = cx_calloc(1, sizeof *data);
134
135
136 data->ssn = ssn;
137 data->fit = (GiChebyshev2D *)fit;
138
139 cx_map_insert(self->data, &data->ssn, data);
140
141 return;
142
143}
144
145
146GiWlResiduals *
147giraffe_wlresiduals_new(void)
148{
149
150 GiWlResiduals *self = cx_calloc(1, sizeof *self);
151
152 if (self) {
153
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));
157
158 }
159
160 return self;
161
162}
163
164
165GiWlResiduals *
166giraffe_wlresiduals_clone(const GiWlResiduals *other)
167{
168
169 GiWlResiduals *self = NULL;
170
171
172 if (other != NULL) {
173
174 self = giraffe_wlresiduals_new();
175
176 if (!cx_map_empty(other->data)) {
177
178 cx_map_const_iterator position = cx_map_begin(other->data);
179
180
181 while (position != cx_map_end(other->data)) {
182
183 GiWlResidualData *data = cx_map_get_value(other->data,
184 position);
185
186 GiChebyshev2D *fit = giraffe_chebyshev2d_clone(data->fit);
187
188
189 _giraffe_wlresiduals_insert(self, data->ssn, fit);
190
191 position = cx_map_next(other->data, position);
192
193 }
194
195 }
196
197 cx_assert(cx_map_size(self->data) == cx_map_size(other->data));
198
199 }
200
201 return self;
202
203}
204
205
206GiWlResiduals *
207giraffe_wlresiduals_create(GiTable *wlsolution)
208{
209
210 const cxchar *const fctid = "giraffe_wlresiduals_create";
211
212
213 cpl_propertylist *properties = NULL;
214
215 cpl_table *residuals = NULL;
216
217 GiWlResiduals *self = giraffe_wlresiduals_new();
218
219
220 if (wlsolution == NULL) {
221
222 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
223 giraffe_wlresiduals_delete(self);
224
225 return NULL;
226
227 }
228
229 properties = giraffe_table_get_properties(wlsolution);
230
231 if (properties == NULL) {
232
233 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
234 giraffe_wlresiduals_delete(self);
235
236 return NULL;
237 }
238
239 residuals = giraffe_table_get(wlsolution);
240
241 if (residuals == NULL) {
242
243 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
244 giraffe_wlresiduals_delete(self);
245
246 return NULL;
247 }
248
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")) {
253
254// cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
255// giraffe_wlresiduals_delete(self);
256
257// return NULL;
258
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);
263
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.);
268
269 }
270
271// else {
272
273 if (1) {
274
275 cxint i;
276 cxint xorder = 0;
277 cxint yorder = 0;
278 /*cxint nc = 0;*/
279
280 cx_string *label = NULL;
281
282 cpl_matrix *coeffs = NULL;
283
284
285 if (!cpl_propertylist_has(properties, GIALIAS_WSOL_XRORDER)) {
286
287 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
288 giraffe_wlresiduals_delete(self);
289
290 return NULL;
291
292 }
293 else {
294
295
296 const cxchar *s =
297 cpl_propertylist_get_string(properties, GIALIAS_WSOL_XRORDER);
298
299 cxchar **orders = cx_strsplit(s, ":", 3);
300
301 if (orders[1] == NULL) {
302
303 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
304 giraffe_wlresiduals_delete(self);
305 cx_strfreev(orders);
306
307 return NULL;
308 }
309
310 xorder = strtol(orders[0], NULL, 10);
311 yorder = strtol(orders[1], NULL, 10);
312
313 cx_strfreev(orders);
314
315 }
316
317
318 /*nc = (xorder + 1) * (yorder + 1);*/
319
320 label = cx_string_new();
321 coeffs = cpl_matrix_new(xorder + 1, yorder + 1);
322
323
324 for (i = 0; i < cpl_table_get_nrow(residuals); i++) {
325
326 cxint j;
327 cxint l = 0;
328 cxint ssn = cpl_table_get_int(residuals, "SSN", i, NULL);
329
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);
334
335 GiChebyshev2D *fit = NULL;
336
337
338 for (j = 0; j <= xorder; j++) {
339
340 cxint k;
341
342 for (k = 0; k <= yorder; k++) {
343
344 cxdouble coeff = 0.;
345
346 cx_string_sprintf(label, "XC%-d", l);
347 coeff = cpl_table_get(residuals, cx_string_get(label),
348 i, NULL);
349
350 cpl_matrix_set(coeffs, j, k, coeff);
351 ++l;
352
353 }
354
355 }
356
357 fit = giraffe_chebyshev2d_new(xorder, yorder);
358 giraffe_chebyshev2d_set(fit, ax, bx, ay, by, coeffs);
359
360 _giraffe_wlresiduals_insert(self, ssn, fit);
361
362 }
363
364 cpl_matrix_delete(coeffs);
365 cx_string_delete(label);
366
367 }
368
369 return self;
370
371}
372
373
374void
375giraffe_wlresiduals_delete(GiWlResiduals *self)
376{
377
378 if (self) {
379
380 if (self->data != NULL) {
381 cx_map_delete(self->data);
382 }
383
384 cx_free(self);
385
386 }
387
388 return;
389
390}
391
392
393cxsize
394giraffe_wlresiduals_get_size(const GiWlResiduals *self)
395{
396
397 cx_assert(self != NULL);
398
399 return cx_map_size(self->data);
400
401}
402
403
404cxint
405giraffe_wlresiduals_get_subslit(const GiWlResiduals *self, cxsize idx)
406{
407
408 const GiWlResidualData *data = NULL;
409
410
411 cx_assert(self != NULL);
412
413 data = _giraffe_wlresiduals_get(self, idx);
414
415 if (data == NULL) {
416 return -1;
417 }
418
419 return data->ssn;
420
421}
422
423
424GiChebyshev2D *
425giraffe_wlresiduals_get_element(const GiWlResiduals *self, cxsize idx)
426{
427
428 const GiWlResidualData *data = NULL;
429
430
431 cx_assert(self != NULL);
432
433 data = _giraffe_wlresiduals_get(self, idx);
434
435 if (data == NULL) {
436 return NULL;
437 }
438
439 return data->fit;
440
441}
442
443
444cxint
445giraffe_wlresiduals_set(GiWlResiduals *self, cxint ssn,
446 const GiChebyshev2D *residuals)
447{
448
449 cx_assert(self != NULL);
450
451 if (residuals == NULL) {
452 return 1;
453 }
454
455 cx_map_erase(self->data, &ssn);
456 _giraffe_wlresiduals_insert(self, ssn , residuals);
457
458 return 0;
459
460}
461
462GiChebyshev2D *
463giraffe_wlresiduals_get(const GiWlResiduals *self, cxint ssn)
464{
465
466 const GiWlResidualData *data = NULL;
467
468
469 cx_assert(self != NULL);
470
471 data = cx_map_get(self->data, &ssn);
472 return data->fit;
473
474}
475
476
477cpl_table *
478giraffe_wlresiduals_table(const GiWlResiduals *self)
479{
480
481 const cxchar *label = "SSN";
482
483 cxint i = 0;
484 cxint xorder = 0;
485 cxint yorder = 0;
486 cxint ncoeff = 0;
487
488 cx_string *s = NULL;
489
490 cx_map_const_iterator position;
491
492 cpl_propertylist *sorting_order = NULL;
493
494 cpl_table *residuals = NULL;
495
496 const GiWlResidualData *data = NULL;
497
498
499 cx_assert(self != NULL);
500
501 if (cx_map_empty(self->data)) {
502 return NULL;
503 }
504
505 position = cx_map_begin(self->data);
506
507 data = cx_map_get_value(self->data, position);
508 cx_assert(data != NULL);
509
510 giraffe_chebyshev2d_get_order(data->fit, &xorder, &yorder);
511 ncoeff = (xorder + 1) * (yorder + 1);
512
513
514 residuals = cpl_table_new(cx_map_size(self->data));
515
516 s = cx_string_new();
517
518 giraffe_error_push();
519
520 cpl_table_new_column(residuals, label, CPL_TYPE_INT);
521
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);
526
527
528 for (i = 0; i < ncoeff; i++) {
529
530 cx_string_sprintf(s, "XC%-d", i);
531 cpl_table_new_column(residuals, cx_string_get(s), CPL_TYPE_DOUBLE);
532
533 }
534
535 if (cpl_error_get_code() != CPL_ERROR_NONE) {
536
537 cpl_table_delete(residuals);
538 cx_string_delete(s);
539
540 return NULL;
541 }
542
543 giraffe_error_pop();
544
545
546 i = 0;
547
548 while (position != cx_map_end(self->data)) {
549
550 cxint ssn = 0;
551
552 cxsize j;
553 cxsize l = 0;
554 cxsize nx = 0;
555 cxsize ny = 0;
556
557 cxdouble ax = 0.;
558 cxdouble bx = 0.;
559 cxdouble ay = 0.;
560 cxdouble by = 0.;
561
562 cpl_matrix *_coeffs = NULL;
563
564 const GiChebyshev2D *fit = NULL;
565
566
567 data = cx_map_get_value(self->data, position);
568
569 ssn = data->ssn;
570
571 fit = data->fit;
572 cx_assert(fit != NULL);
573
574 _coeffs = (cpl_matrix *)giraffe_chebyshev2d_coeffs(fit);
575 giraffe_chebyshev2d_get_range(fit, &ax, &bx, &ay, &by);
576
577 cpl_table_set_int(residuals, label, i , ssn);
578
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);
583
584 nx = cpl_matrix_get_nrow(_coeffs);
585 ny = cpl_matrix_get_ncol(_coeffs);
586
587 cx_assert(nx * ny == (cxsize)((xorder + 1) * (yorder + 1)));
588
589 for (j = 0; (cxsize)j < nx; j++) {
590
591 cxint k;
592
593 for (k = 0; (cxsize)k < ny; k++) {
594
595 cxdouble value = cpl_matrix_get(_coeffs, j, k);
596
597 cx_string_sprintf(s, "XC%-" CX_PRINTF_FORMAT_SIZE_TYPE, l);
598 cpl_table_set_double(residuals, cx_string_get(s), i, value);
599 ++l;
600
601 }
602
603 }
604
605 position = cx_map_next(self->data, position);
606 ++i;
607
608 }
609
610 cx_string_delete(s);
611 s = NULL;
612
613 sorting_order = cpl_propertylist_new();
614 cpl_propertylist_append_bool(sorting_order, label, 0);
615
616 cpl_table_sort(residuals, sorting_order);
617
618 cpl_propertylist_delete(sorting_order);
619 sorting_order = NULL;
620
621 return residuals;
622
623}
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
Definition: gitable.c:433
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
Definition: gitable.c:489

This file is part of the GIRAFFE Pipeline Reference Manual 2.19.4.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Fri Feb 6 2026 11:30:08 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004