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