00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include <string.h>
00033
00034 #include <cxmemory.h>
00035 #include <cxmessages.h>
00036 #include <cxstring.h>
00037
00038 #include <cpl_error.h>
00039
00040 #include "gialias.h"
00041 #include "gitable.h"
00042
00043
00052 struct GiTable {
00053 cpl_table *data;
00054 cpl_propertylist *properties;
00055 };
00056
00057
00058
00059
00060
00061
00062 inline static void
00063 _giraffe_table_clear(GiTable *self)
00064 {
00065
00066 if (self->data) {
00067 cpl_table_delete(self->data);
00068 self->data = NULL;
00069 }
00070
00071 if (self->properties) {
00072 cpl_propertylist_delete(self->properties);
00073 self->properties = NULL;
00074 }
00075
00076 return;
00077
00078 }
00079
00080
00091 GiTable *
00092 giraffe_table_new(void)
00093 {
00094
00095 GiTable *self = cx_calloc(1, sizeof(GiTable));
00096
00097 self->data = NULL;
00098 self->properties = NULL;
00099
00100 return self;
00101
00102 }
00103
00104
00121 GiTable *
00122 giraffe_table_create(cpl_table *table, cpl_propertylist *properties)
00123 {
00124
00125 GiTable *self = NULL;
00126
00127 if (table) {
00128 self = giraffe_table_new();
00129
00130 self->data = cpl_table_duplicate(table);
00131 if (!self->data) {
00132 return NULL;
00133 }
00134
00135 if (properties) {
00136 self->properties = cpl_propertylist_duplicate(properties);
00137 if (!self->properties) {
00138 giraffe_table_delete(self);
00139 return NULL;
00140 }
00141 }
00142 }
00143
00144 return self;
00145
00146 }
00147
00148
00160 void
00161 giraffe_table_delete(GiTable *self)
00162 {
00163
00164 if (self) {
00165 _giraffe_table_clear(self);
00166 cx_free(self);
00167 }
00168
00169 return;
00170
00171 }
00172
00182 GiTable *
00183 giraffe_table_duplicate(const GiTable *src)
00184 {
00185
00186 GiTable *self = NULL;
00187
00188 if (src != NULL) {
00189
00190 cpl_propertylist *properties = giraffe_table_get_properties(src);
00191 cpl_table *data = giraffe_table_get(src);
00192
00193
00194 self = cx_calloc(1, sizeof(GiTable));
00195
00196 if (properties) {
00197 self->properties = cpl_propertylist_duplicate(properties);
00198 }
00199
00200 if (data) {
00201 self->data = cpl_table_duplicate(data);
00202 }
00203
00204 }
00205
00206 return self;
00207
00208 }
00209
00210
00211
00212
00213
00226 void
00227 giraffe_table_clear(GiTable *self)
00228 {
00229
00230 if (self) {
00231 _giraffe_table_clear(self);
00232 }
00233
00234 return;
00235
00236 }
00237
00238
00265 cxint
00266 giraffe_table_copy_matrix(GiTable *table, const cxchar *name,
00267 cpl_matrix *matrix)
00268 {
00269
00270 const cxchar *fctid = "giraffe_table_copy_matrix";
00271
00272 const cxchar *label = NULL;
00273
00274 cxint nrow = 0;
00275 cxint ncol = 0;
00276 cxint count = 0;
00277
00278 cpl_table *_table;
00279
00280
00281 cx_assert(table != NULL);
00282
00283 if (!matrix) {
00284 return 1;
00285 }
00286
00287 nrow = cpl_matrix_get_nrow(matrix);
00288 ncol = cpl_matrix_get_ncol(matrix);
00289 cx_assert(nrow > 0 && ncol > 0);
00290
00291 _table = giraffe_table_get(table);
00292
00293 label = cpl_table_get_column_name(_table);
00294
00295 if (name != NULL) {
00296
00297 if (cpl_table_has_column(_table, name) == 0) {
00298 return 1;
00299 }
00300 else {
00301
00302
00303
00304
00305
00306 while (label && strcmp(label, name) != 0) {
00307 label = cpl_table_get_column_name(NULL);
00308 ++count;
00309 }
00310
00311 }
00312
00313 }
00314
00315 if (cpl_table_get_nrow(_table) != nrow ||
00316 cpl_table_get_ncol(_table) - count < ncol) {
00317 return 1;
00318 }
00319 else {
00320
00321 cxint i;
00322
00323 cxdouble *elements = cpl_matrix_get_data(matrix);
00324
00325
00326 if (!label) {
00327 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00328 return 1;
00329 }
00330
00331 for (i = 0; i < ncol; i++) {
00332
00333 cpl_type type = cpl_table_get_column_type(_table, label);
00334
00335
00336 switch (type) {
00337 case CPL_TYPE_INT:
00338 {
00339 cxint j;
00340
00341 for (j = 0; j < nrow; j++) {
00342 cpl_table_set_int(_table, label, j,
00343 (cxint) elements[j * ncol + i]);
00344 }
00345 break;
00346 }
00347
00348 case CPL_TYPE_FLOAT:
00349 {
00350 cxint j;
00351
00352 for (j = 0; j < nrow; j++) {
00353 cpl_table_set_float(_table, label, j,
00354 (cxfloat) elements[j * ncol + i]);
00355 }
00356 break;
00357 }
00358
00359 case CPL_TYPE_DOUBLE:
00360 {
00361 cxint j;
00362
00363 for (j = 0; j < nrow; j++) {
00364 cpl_table_set_double(_table, label, j,
00365 elements[j * ncol + i]);
00366 }
00367 break;
00368 }
00369
00370 case CPL_TYPE_STRING:
00371 default:
00372 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00373 return 1;
00374 break;
00375 }
00376
00377 if (i < ncol - 1) {
00378
00379 label = cpl_table_get_column_name(NULL);
00380
00381 if (!label) {
00382 cpl_error_set(fctid, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00383 return 1;
00384 }
00385
00386 }
00387 }
00388
00389 }
00390
00391 return 0;
00392
00393 }
00394
00395
00408 cxint
00409 giraffe_table_is_empty(GiTable *self)
00410 {
00411
00412 if (self->data) {
00413 return 0;
00414 }
00415
00416 return self->properties == NULL ? 1 : 0;
00417
00418 }
00419
00420
00433 cpl_table *
00434 giraffe_table_get(const GiTable *self)
00435 {
00436
00437 cx_assert(self != NULL);
00438
00439 return self->data;
00440
00441 }
00442
00443
00456 cxint
00457 giraffe_table_set(GiTable *self, cpl_table *table)
00458 {
00459
00460 cpl_table *tmp = NULL;
00461
00462 tmp = giraffe_table_get(self);
00463
00464 cx_assert(table != NULL);
00465
00466 if (tmp != NULL) {
00467 cpl_table_delete(tmp);
00468 }
00469
00470 self->data = cpl_table_duplicate(table);
00471
00472 return 0;
00473
00474 }
00475
00489 cpl_propertylist *
00490 giraffe_table_get_properties(const GiTable *self)
00491 {
00492
00493 cx_assert(self != NULL);
00494
00495 return self->properties;
00496
00497 }
00498
00516 cxint
00517 giraffe_table_set_properties(GiTable *self, cpl_propertylist *properties)
00518 {
00519
00520 if (self == NULL) {
00521 return 1;
00522 }
00523
00524 if (self->properties) {
00525 cpl_propertylist_delete(self->properties);
00526 self->properties = NULL;
00527 }
00528
00529 self->properties = cpl_propertylist_duplicate(properties);
00530
00531 return self->properties ? 0 : 1;
00532
00533 }
00534
00562 cxint
00563 giraffe_table_load(GiTable *self, const cxchar *filename, cxint position,
00564 const cxchar *id)
00565 {
00566
00567 const cxchar *fctid = "giraffe_table_load";
00568
00569
00570 if (!self || !filename) {
00571 return 1;
00572 }
00573
00574 self->data = cpl_table_load((cxchar *)filename, position, 0);
00575 if (!self->data) {
00576 if (cpl_error_get_code() == CPL_ERROR_NULL_INPUT) {
00577 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00578 return 2;
00579 }
00580
00581 return 1;
00582 }
00583
00584 self->properties = cpl_propertylist_load(filename, position);
00585
00586 if (self->properties == NULL) {
00587 _giraffe_table_clear(self);
00588 return 1;
00589 }
00590
00591 if (id) {
00592 cxint status = 1;
00593
00594 if (self->properties &&
00595 cpl_propertylist_has(self->properties, GIALIAS_EXTNAME)) {
00596
00597 const cxchar *magic;
00598
00599 magic = cpl_propertylist_get_string(self->properties,
00600 GIALIAS_EXTNAME);
00601
00602 if (strcmp(id, magic) == 0) {
00603 status = 0;
00604 }
00605
00606 }
00607
00608 if (status != 0) {
00609 _giraffe_table_clear(self);
00610 cpl_error_set(fctid, CPL_ERROR_BAD_FILE_FORMAT);
00611 return 1;
00612 }
00613
00614 }
00615
00616 return 0;
00617
00618 }
00619
00620
00636 cxint
00637 giraffe_table_save(GiTable *self, const cxchar *filename)
00638 {
00639
00640 if (filename == NULL) {
00641 return 1;
00642 }
00643
00644 if (self) {
00645
00646 cxint code;
00647
00648 cpl_table *table = giraffe_table_get(self);
00649 cpl_propertylist *plist = giraffe_table_get_properties(self);
00650
00651
00652 if (cpl_propertylist_is_empty(plist)) {
00653 plist = NULL;
00654 }
00655
00656 plist = cpl_propertylist_duplicate(plist);
00657
00658
00659
00660
00661
00662
00663 cpl_propertylist_erase_regexp(plist, "^CRPIX[0-9]$", 0);
00664 cpl_propertylist_erase_regexp(plist, "^CRVAL[0-9]$", 0);
00665 cpl_propertylist_erase_regexp(plist, "^CDELT[0-9]$", 0);
00666 cpl_propertylist_erase_regexp(plist, "^CTYPE[0-9]$", 0);
00667
00668
00669 code = cpl_table_save(table, plist, plist, filename, CPL_IO_CREATE);
00670
00671 if (code != CPL_ERROR_NONE) {
00672 cpl_propertylist_delete(plist);
00673 plist = NULL;
00674
00675 return 1;
00676 }
00677
00678 cpl_propertylist_delete(plist);
00679 plist = NULL;
00680
00681 }
00682
00683 return 0;
00684
00685 }
00686
00687
00705 cxint
00706 giraffe_table_attach(GiTable *self, const cxchar *filename, cxint position,
00707 const cxchar *id)
00708 {
00709
00710 cxint code;
00711
00712 cpl_table *table = NULL;
00713 cpl_propertylist *plist = NULL;
00714
00715
00716 cx_assert(self != NULL);
00717
00718 if (filename == NULL) {
00719 return 1;
00720 }
00721
00722 if (position < 1) {
00723 return 1;
00724 }
00725
00726 table = giraffe_table_get(self);
00727 plist = giraffe_table_get_properties(self);
00728
00729 plist = cpl_propertylist_duplicate(plist);
00730
00731
00732
00733
00734
00735
00736 cpl_propertylist_erase_regexp(plist, "^CRPIX[0-9]$", 0);
00737 cpl_propertylist_erase_regexp(plist, "^CRVAL[0-9]$", 0);
00738 cpl_propertylist_erase_regexp(plist, "^CDELT[0-9]$", 0);
00739 cpl_propertylist_erase_regexp(plist, "^CTYPE[0-9]$", 0);
00740
00741
00742 if (id != NULL) {
00743 cpl_propertylist_update_string(plist, GIALIAS_EXTNAME, id);
00744 cpl_propertylist_set_comment(plist, GIALIAS_EXTNAME,
00745 "FITS Extension name");
00746 }
00747 else {
00748 if (cpl_propertylist_is_empty(plist)) {
00749 plist = NULL;
00750 }
00751 }
00752
00753 code = cpl_table_save(table, NULL, plist, filename, CPL_IO_EXTEND);
00754
00755 if (code != CPL_ERROR_NONE) {
00756 cpl_propertylist_delete(plist);
00757 plist = NULL;
00758
00759 return 1;
00760 }
00761
00762 cpl_propertylist_delete(plist);
00763 plist = NULL;
00764
00765 return 0;
00766
00767 }
00768
00769
00777 cxint
00778 giraffe_table_add_info(GiTable *table, const GiRecipeInfo *info ,
00779 const cpl_frameset *set)
00780 {
00781
00782 cxint status = 0;
00783
00784 cpl_propertylist *properties = NULL;
00785
00786
00787 if (table == NULL) {
00788 return -1;
00789 }
00790
00791 properties = giraffe_table_get_properties(table);
00792
00793 if (properties == NULL) {
00794 return -2;
00795 }
00796
00797 if (info != NULL) {
00798 status = giraffe_add_recipe_info(properties, info);
00799
00800 if (status != 0) {
00801 return -3;
00802 }
00803
00804 if (set != NULL) {
00805 status = giraffe_add_frameset_info(properties, set,
00806 info->sequence);
00807
00808
00809 if (status != 0) {
00810 return -4;
00811 }
00812 }
00813 }
00814
00815 return 0;
00816
00817 }