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 
45 struct 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 
55 inline 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 
84 GiTable *
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 
114 GiTable *
115 giraffe_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) {
131  giraffe_table_delete(self);
132  return NULL;
133  }
134  }
135  }
136 
137  return self;
138 
139 }
140 
141 
153 void
154 giraffe_table_delete(GiTable *self)
155 {
156 
157  if (self) {
158  _giraffe_table_clear(self);
159  cx_free(self);
160  }
161 
162  return;
163 
164 }
165 
175 GiTable *
176 giraffe_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 
219 void
220 giraffe_table_clear(GiTable *self)
221 {
222 
223  if (self) {
224  _giraffe_table_clear(self);
225  }
226 
227  return;
228 
229 }
230 
231 
258 cxint
259 giraffe_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 
407 cxint
409 {
410 
411  if (self->data) {
412  return 0;
413  }
414 
415  return self->properties == NULL ? 1 : 0;
416 
417 }
418 
419 
432 cpl_table *
433 giraffe_table_get(const GiTable *self)
434 {
435 
436  cx_assert(self != NULL);
437 
438  return self->data;
439 
440 }
441 
442 
455 cxint
456 giraffe_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 
488 cpl_propertylist *
489 giraffe_table_get_properties(const GiTable *self)
490 {
491 
492  cx_assert(self != NULL);
493 
494  return self->properties;
495 
496 }
497 
515 cxint
516 giraffe_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 
561 cxint
562 giraffe_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 
635 cxint
636 giraffe_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 
748 cxint
749 giraffe_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 
835 cxint
836 giraffe_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
cxint giraffe_table_save(GiTable *self, const cxchar *filename)
Write a Giraffe table to a file.
Definition: gitable.c:636
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
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
cpl_propertylist * giraffe_table_get_properties(const GiTable *self)
Gets the table properties.
Definition: gitable.c:489
GiTable * giraffe_table_new(void)
Creates a new, empty Giraffe table.
Definition: gitable.c:85
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
GiTable * giraffe_table_duplicate(const GiTable *src)
Duplicate a Giraffe table.
Definition: gitable.c:176
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.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004