GIRAFFE Pipeline Reference Manual

gitable.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 <string.h>
25
26#include <cxmemory.h>
27#include <cxmessages.h>
28#include <cxstring.h>
29
30#include <cpl_error.h>
31#include <cpl_array.h>
32
33#include "gialias.h"
34#include "gitable.h"
35
36
45struct GiTable {
46 cpl_table *data;
47 cpl_propertylist *properties;
48};
49
50/*
51 * Clear the table contents. After calling this function the Giraffe
52 * table is empty.
53 */
54
55inline static void
56_giraffe_table_clear(GiTable *self)
57{
58
59 if (self->data) {
60 cpl_table_delete(self->data);
61 self->data = NULL;
62 }
63
64 if (self->properties) {
65 cpl_propertylist_delete(self->properties);
66 self->properties = NULL;
67 }
68
69 return;
70
71}
72
73
84GiTable *
86{
87
88 GiTable *self = cx_calloc(1, sizeof(GiTable));
89
90 self->data = NULL;
91 self->properties = NULL;
92
93 return self;
94
95}
96
97
114GiTable *
115giraffe_table_create(cpl_table *table, cpl_propertylist *properties)
116{
117
118 GiTable *self = NULL;
119
120 if (table) {
121 self = giraffe_table_new();
122
123 self->data = cpl_table_duplicate(table);
124 if (!self->data) {
125 return NULL;
126 }
127
128 if (properties) {
129 self->properties = cpl_propertylist_duplicate(properties);
130 if (!self->properties) {
132 return NULL;
133 }
134 }
135 }
136
137 return self;
138
139}
140
141
153void
155{
156
157 if (self) {
158 _giraffe_table_clear(self);
159 cx_free(self);
160 }
161
162 return;
163
164}
165
175GiTable *
176giraffe_table_duplicate(const GiTable *src)
177{
178
179 GiTable *self = NULL;
180
181 if (src != NULL) {
182
183 cpl_propertylist *properties = giraffe_table_get_properties(src);
184 cpl_table *data = giraffe_table_get(src);
185
186
187 self = cx_calloc(1, sizeof(GiTable));
188
189 if (properties) {
190 self->properties = cpl_propertylist_duplicate(properties);
191 }
192
193 if (data) {
194 self->data = cpl_table_duplicate(data);
195 }
196
197 }
198
199 return self;
200
201}
202
203
204
205
206
219void
221{
222
223 if (self) {
224 _giraffe_table_clear(self);
225 }
226
227 return;
228
229}
230
231
258cxint
259giraffe_table_copy_matrix(GiTable *table, const cxchar *name,
260 cpl_matrix *matrix)
261{
262
263 const cxchar *fctid = "giraffe_table_copy_matrix";
264
265 cxint nrow = 0;
266 cxint ncol = 0;
267 cxint count = 0;
268
269 cpl_array *labels = NULL;
270 cpl_table *_table = NULL;
271
272
273 cx_assert(table != NULL);
274
275 if (!matrix) {
276 return 1;
277 }
278
279 nrow = cpl_matrix_get_nrow(matrix);
280 ncol = cpl_matrix_get_ncol(matrix);
281 cx_assert(nrow > 0 && ncol > 0);
282
283 _table = giraffe_table_get(table);
284
285 labels = cpl_table_get_column_names(_table);
286 cx_assert(cpl_array_get_size(labels) > 0);
287
288
289 if (name != NULL) {
290
291 if (cpl_table_has_column(_table, name) == 0) {
292
293 cpl_array_delete(labels);
294 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
295
296 return 1;
297
298 }
299 else {
300
301 /*
302 * Move to the first target column. No check whether count goes
303 * out of range is needed here since it is already known that
304 * a column with name 'name' exists.
305 */
306
307 while (strcmp(cpl_array_get_string(labels, count), name) != 0) {
308 ++count;
309 }
310
311 }
312
313 }
314
315
316 if (cpl_table_get_nrow(_table) != nrow ||
317 cpl_table_get_ncol(_table) - count < ncol) {
318
319 cpl_array_delete(labels);
320 cpl_error_set(fctid, CPL_ERROR_INCOMPATIBLE_INPUT);
321
322 return 1;
323
324 }
325 else {
326
327 cxint i;
328
329 cxdouble *elements = cpl_matrix_get_data(matrix);
330
331
332 for (i = 0; i < ncol; ++i) {
333
334 const cxchar *label = cpl_array_get_string(labels, count + i);
335
336 cpl_type type = cpl_table_get_column_type(_table, label);
337
338
339 switch (type) {
340 case CPL_TYPE_INT:
341 {
342 register cxint j;
343
344 for (j = 0; j < nrow; ++j) {
345 cpl_table_set_int(_table, label, j,
346 (cxint) elements[j * ncol + i]);
347 }
348 break;
349 }
350
351 case CPL_TYPE_FLOAT:
352 {
353 register cxint j;
354
355 for (j = 0; j < nrow; ++j) {
356 cpl_table_set_float(_table, label, j,
357 (cxfloat) elements[j * ncol + i]);
358 }
359 break;
360 }
361
362 case CPL_TYPE_DOUBLE:
363 {
364 register cxint j;
365
366 for (j = 0; j < nrow; ++j) {
367 cpl_table_set_double(_table, label, j,
368 elements[j * ncol + i]);
369 }
370 break;
371 }
372
373 case CPL_TYPE_STRING:
374 default:
375 {
376 cpl_array_delete(labels);
377 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
378
379 return 1;
380 break;
381 }
382 }
383
384 }
385
386 }
387
388 cpl_array_delete(labels);
389
390 return 0;
391
392}
393
394
407cxint
409{
410
411 if (self->data) {
412 return 0;
413 }
414
415 return self->properties == NULL ? 1 : 0;
416
417}
418
419
432cpl_table *
433giraffe_table_get(const GiTable *self)
434{
435
436 cx_assert(self != NULL);
437
438 return self->data;
439
440}
441
442
455cxint
456giraffe_table_set(GiTable *self, cpl_table *table)
457{
458
459 cpl_table *tmp = NULL;
460
461 tmp = giraffe_table_get(self);
462
463 cx_assert(table != NULL);
464
465 if (tmp != NULL) {
466 cpl_table_delete(tmp);
467 }
468
469 self->data = cpl_table_duplicate(table);
470
471 return 0;
472
473}
474
488cpl_propertylist *
490{
491
492 cx_assert(self != NULL);
493
494 return self->properties;
495
496}
497
515cxint
516giraffe_table_set_properties(GiTable *self, cpl_propertylist *properties)
517 {
518
519 if (self == NULL) {
520 return 1;
521 }
522
523 if (self->properties) {
524 cpl_propertylist_delete(self->properties);
525 self->properties = NULL;
526 }
527
528 self->properties = cpl_propertylist_duplicate(properties);
529
530 return self->properties ? 0 : 1;
531
532}
533
561cxint
562giraffe_table_load(GiTable *self, const cxchar *filename, cxint position,
563 const cxchar *id)
564{
565
566 const cxchar *fctid = "giraffe_table_load";
567
568
569 if (!self || !filename) {
570 return 1;
571 }
572
573 self->data = cpl_table_load((cxchar *)filename, position, 0);
574 if (!self->data) {
575 if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) {
576 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
577 return 2;
578 }
579
580 return 1;
581 }
582
583 self->properties = cpl_propertylist_load(filename, position);
584
585 if (self->properties == NULL) {
586 _giraffe_table_clear(self);
587 return 1;
588 }
589
590 if (id) {
591 cxint status = 1;
592
593 if (self->properties &&
594 cpl_propertylist_has(self->properties, GIALIAS_EXTNAME)) {
595
596 const cxchar *magic;
597
598 magic = cpl_propertylist_get_string(self->properties,
599 GIALIAS_EXTNAME);
600
601 if (strcmp(id, magic) == 0) {
602 status = 0;
603 }
604
605 }
606
607 if (status != 0) {
608 _giraffe_table_clear(self);
609 cpl_error_set(fctid, CPL_ERROR_BAD_FILE_FORMAT);
610 return 1;
611 }
612
613 }
614
615 return 0;
616
617}
618
619
635cxint
636giraffe_table_save(GiTable *self, const cxchar *filename)
637{
638
639 if (filename == NULL) {
640 return 1;
641 }
642
643 if (self) {
644
645 cxint code;
646
647 cpl_table *table = giraffe_table_get(self);
648 cpl_propertylist *plist0 = giraffe_table_get_properties(self);
649 cpl_propertylist *plist1 = NULL;
650
651
652 if (cpl_propertylist_is_empty(plist0)) {
653 plist0 = NULL;
654 }
655
656 plist0 = cpl_propertylist_duplicate(plist0);
657
658
659 /*
660 * Remove keywords which may not appear in table headers.
661 */
662
663 cpl_propertylist_erase(plist0, "BSCALE");
664 cpl_propertylist_erase(plist0, "BZERO");
665 cpl_propertylist_erase(plist0, "BUNIT");
666
667 cpl_propertylist_erase(plist0, "DATAMIN");
668 cpl_propertylist_erase(plist0, "DATAMAX");
669
670
671 /* FIXME: Workaround for CPL deficiency. World coordinate
672 * keywords are not removed from table headers.
673 */
674
675 cpl_propertylist_erase_regexp(plist0, "^CRPIX[0-9]$", 0);
676 cpl_propertylist_erase_regexp(plist0, "^CRVAL[0-9]$", 0);
677 cpl_propertylist_erase_regexp(plist0, "^CDELT[0-9]$", 0);
678 cpl_propertylist_erase_regexp(plist0, "^CTYPE[0-9]$", 0);
679
680
681 /*
682 * Split properties into separate property lists for the primary
683 * and the secondary header
684 */
685
686 plist1 = cpl_propertylist_duplicate(plist0);
687
688
689 /*
690 * Remove header specific keywords from the respective
691 * property list.
692 */
693
694 cpl_propertylist_erase(plist0, "EXTNAME");
695
696 cpl_propertylist_erase(plist1, "DATAMD5");
697 cpl_propertylist_erase(plist1, "INHERIT");
698 cpl_propertylist_erase(plist1, "PIPEFILE");
699 cpl_propertylist_erase(plist1, GIALIAS_ANCESTOR);
700
701
702 /*
703 * Save the table to disk
704 */
705
706 code = cpl_table_save(table, plist0, plist1, filename, CPL_IO_CREATE);
707
708 if (code != CPL_ERROR_NONE) {
709 cpl_propertylist_delete(plist0);
710 plist0 = NULL;
711
712 cpl_propertylist_delete(plist1);
713 plist1 = NULL;
714
715 return 1;
716 }
717
718 cpl_propertylist_delete(plist0);
719 plist0 = NULL;
720
721 cpl_propertylist_delete(plist1);
722 plist1 = NULL;
723
724 }
725
726 return 0;
727
728}
729
730
748cxint
749giraffe_table_attach(GiTable *self, const cxchar *filename, cxint position,
750 const cxchar *id)
751{
752
753 cxint code;
754
755 cpl_table *table = NULL;
756 cpl_propertylist *plist = NULL;
757
758
759 cx_assert(self != NULL);
760
761 if (filename == NULL) {
762 return 1;
763 }
764
765 if (position < 1) {
766 return 1;
767 }
768
769 table = giraffe_table_get(self);
770 plist = giraffe_table_get_properties(self);
771
772 plist = cpl_propertylist_duplicate(plist);
773
774
775 /*
776 * Remove keywords which may not appear in table headers.
777 */
778
779 cpl_propertylist_erase(plist, "BSCALE");
780 cpl_propertylist_erase(plist, "BZERO");
781 cpl_propertylist_erase(plist, "BUNIT");
782
783 cpl_propertylist_erase(plist, "DATAMIN");
784 cpl_propertylist_erase(plist, "DATAMAX");
785 cpl_propertylist_erase(plist, "DATAMD5");
786 cpl_propertylist_erase(plist, "INHERIT");
787 cpl_propertylist_erase(plist, "PIPEFILE");
788 cpl_propertylist_erase(plist, GIALIAS_ANCESTOR);
789
790 /* FIXME: Workaround for CPL deficiency. World coordinate
791 * keywords are not removed from table headers.
792 */
793
794 cpl_propertylist_erase_regexp(plist, "^CRPIX[0-9]$", 0);
795 cpl_propertylist_erase_regexp(plist, "^CRVAL[0-9]$", 0);
796 cpl_propertylist_erase_regexp(plist, "^CDELT[0-9]$", 0);
797 cpl_propertylist_erase_regexp(plist, "^CTYPE[0-9]$", 0);
798
799
800 if (id != NULL) {
801 cpl_propertylist_update_string(plist, GIALIAS_EXTNAME, id);
802 cpl_propertylist_set_comment(plist, GIALIAS_EXTNAME,
803 "FITS Extension name");
804 }
805 else {
806 if (cpl_propertylist_is_empty(plist)) {
807 plist = NULL;
808 }
809 }
810
811 code = cpl_table_save(table, NULL, plist, filename, CPL_IO_EXTEND);
812
813 if (code != CPL_ERROR_NONE) {
814 cpl_propertylist_delete(plist);
815 plist = NULL;
816
817 return 1;
818 }
819
820 cpl_propertylist_delete(plist);
821 plist = NULL;
822
823 return 0;
824
825}
826
827
835cxint
836giraffe_table_add_info(GiTable *table, const GiRecipeInfo *info ,
837 const cpl_frameset *set)
838{
839
840 cxint status = 0;
841
842 cpl_propertylist *properties = NULL;
843
844
845 if (table == NULL) {
846 return -1;
847 }
848
849 properties = giraffe_table_get_properties(table);
850
851 if (properties == NULL) {
852 return -2;
853 }
854
855 if (info != NULL) {
856 status = giraffe_add_recipe_info(properties, info);
857
858 if (status != 0) {
859 return -3;
860 }
861
862 if (set != NULL) {
863 status = giraffe_add_frameset_info(properties, set,
864 info->sequence);
865
866
867 if (status != 0) {
868 return -4;
869 }
870 }
871 }
872
873 return 0;
874
875}
cxint giraffe_table_set(GiTable *self, cpl_table *table)
Sets the table data.
Definition: gitable.c:456
GiTable * giraffe_table_create(cpl_table *table, cpl_propertylist *properties)
Creates a Giraffe table from a table and a property list.
Definition: gitable.c:115
cxint giraffe_table_save(GiTable *self, const cxchar *filename)
Write a Giraffe table to a file.
Definition: gitable.c:636
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe table.
Definition: gitable.c:85
GiTable * giraffe_table_duplicate(const GiTable *src)
Duplicate a Giraffe table.
Definition: gitable.c:176
cxint giraffe_table_load(GiTable *self, const cxchar *filename, cxint position, const cxchar *id)
Reads a data set from a file into a Giraffe table.
Definition: gitable.c:562
cxint giraffe_table_copy_matrix(GiTable *table, const cxchar *name, cpl_matrix *matrix)
Copies matrix elements into a table.
Definition: gitable.c:259
void giraffe_table_clear(GiTable *self)
Clears a Giraffe table.
Definition: gitable.c:220
cxint giraffe_table_attach(GiTable *self, const cxchar *filename, cxint position, const cxchar *id)
Attach a Giraffe table to a file.
Definition: gitable.c:749
void giraffe_table_delete(GiTable *self)
Destroys a Giraffe table.
Definition: gitable.c:154
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
Definition: gitable.c:433
cxint giraffe_table_is_empty(GiTable *self)
Check whether a Giraffe table is empty.
Definition: gitable.c:408
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
Definition: gitable.c:489
cxint giraffe_table_add_info(GiTable *table, const GiRecipeInfo *info, const cpl_frameset *set)
Add additional frame information to a table.
Definition: gitable.c:836
cxint giraffe_table_set_properties(GiTable *self, cpl_propertylist *properties)
Attaches a property list to an table.
Definition: gitable.c:516
cxint giraffe_add_recipe_info(cpl_propertylist *plist, const GiRecipeInfo *info)
Add recipe specific information to a property list.
Definition: giutils.c:623
cxint giraffe_add_frameset_info(cpl_propertylist *plist, const cpl_frameset *set, cxint sequence)
Add frameset specific information to a property list.
Definition: giutils.c:782

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.11.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Apr 18 2024 20:20:59 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004