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 #ifdef HAVE_SYS_TYPES_H
00033 # include <sys/types.h>
00034 #endif
00035 #include <time.h>
00036 #include <string.h>
00037 #include <regex.h>
00038
00039 #include <cxstring.h>
00040 #include <cxstrutils.h>
00041
00042 #include <cpl_error.h>
00043 #include <cpl_matrix.h>
00044
00045 #include "gialias.h"
00046 #include "gimessages.h"
00047 #include "giutils.h"
00048
00049
00058
00059
00060
00061
00062 static const cxchar *_giraffe_license =
00063 " This file is part of the GIRAFFE Instrument Pipeline\n"
00064 " Copyright (C) 2002-2006 European Southern Observatory\n"
00065 "\n"
00066 " This program is free software; you can redistribute it and/or modify\n"
00067 " it under the terms of the GNU General Public License as published by\n"
00068 " the Free Software Foundation; either version 2 of the License, or\n"
00069 " (at your option) any later version.\n"
00070 "\n"
00071 " This program is distributed in the hope that it will be useful,\n"
00072 " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00073 " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
00074 " GNU General Public License for more details.\n"
00075 "\n"
00076 " You should have received a copy of the GNU General Public License\n"
00077 " along with this program; if not, write to the Free Software\n"
00078 " Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301"
00079 " USA";
00080
00081
00082 inline static cxint
00083 _giraffe_plist_append(cpl_propertylist *self, cpl_property *p)
00084 {
00085
00086 const cxchar *name = cpl_property_get_name(p);
00087 const cxchar *comment = cpl_property_get_comment(p);
00088
00089
00090 switch (cpl_property_get_type(p)) {
00091 case CPL_TYPE_BOOL:
00092 {
00093 cxbool value = cpl_property_get_bool(p);
00094
00095 cpl_propertylist_append_bool(self, name, value);
00096 break;
00097 }
00098
00099 case CPL_TYPE_CHAR:
00100 {
00101 cxchar value = cpl_property_get_char(p);
00102
00103 cpl_propertylist_append_char(self, name, value);
00104 break;
00105 }
00106
00107 case CPL_TYPE_INT:
00108 {
00109 cxint value = cpl_property_get_int(p);
00110
00111 cpl_propertylist_append_int(self, name, value);
00112 break;
00113 }
00114
00115 case CPL_TYPE_LONG:
00116 {
00117 cxlong value = cpl_property_get_long(p);
00118
00119 cpl_propertylist_append_long(self, name, value);
00120 break;
00121 }
00122
00123 case CPL_TYPE_FLOAT:
00124 {
00125 cxfloat value = cpl_property_get_float(p);
00126
00127 cpl_propertylist_append_float(self, name, value);
00128 break;
00129 }
00130
00131 case CPL_TYPE_DOUBLE:
00132 {
00133 cxdouble value = cpl_property_get_double(p);
00134
00135 cpl_propertylist_append_double(self, name, value);
00136 break;
00137 }
00138
00139 case CPL_TYPE_STRING:
00140 {
00141 const cxchar *value = cpl_property_get_string(p);
00142
00143 cpl_propertylist_append_string(self, name, value);
00144 break;
00145 }
00146
00147 default:
00148
00149
00150
00151
00152
00153
00154
00155 return 1;
00156 break;
00157 }
00158
00159 if (comment != NULL) {
00160 cpl_propertylist_set_comment(self, name, comment);
00161 }
00162
00163 return 0;
00164
00165 }
00166
00167
00168 inline static cxint
00169 _giraffe_add_frame_info(cpl_propertylist *plist, const cxchar *name,
00170 const cxchar *tag, cxint sequence, cxint frame_index,
00171 cxint mode)
00172 {
00173
00174 const cxchar *id = NULL;
00175 const cxchar *group = NULL;
00176
00177 cxint status = 0;
00178
00179 cx_string *key = NULL;
00180 cx_string *comment = NULL;
00181
00182
00183 if (plist == NULL) {
00184 return 1;
00185 }
00186
00187 switch (mode) {
00188 case 0:
00189 id = "RAW";
00190 group = "raw";
00191 break;
00192
00193 case 1:
00194 id = "CAL";
00195 group = "calibration";
00196 break;
00197
00198 default:
00199 return 2;
00200 break;
00201 }
00202
00203 key = cx_string_new();
00204 comment = cx_string_new();
00205
00206
00207
00208
00209
00210
00211 cx_string_sprintf(key, "%s%-d %s%-d %s", "ESO PRO REC", sequence, id,
00212 frame_index, "NAME");
00213 cx_string_sprintf(comment, "%s %s %s", "File name of", group, "frame");
00214
00215 status = cpl_propertylist_update_string(plist, cx_string_get(key), name);
00216
00217 if (status != CPL_ERROR_NONE) {
00218 cx_string_delete(key);
00219 cx_string_delete(comment);
00220
00221 return 3;
00222 }
00223
00224 status = cpl_propertylist_set_comment(plist, cx_string_get(key),
00225 cx_string_get(comment));
00226
00227 if (status != 0) {
00228 cx_string_delete(key);
00229 cx_string_delete(comment);
00230
00231 return 3;
00232 }
00233
00234
00235
00236
00237
00238
00239 cx_string_sprintf(key, "%s%-d %s%-d %s", "ESO PRO REC", sequence, id,
00240 frame_index, "CATG");
00241 cx_string_sprintf(comment, "%s %s %s", "Frame category of", group,
00242 "frame");
00243
00244 status = cpl_propertylist_update_string(plist, cx_string_get(key), tag);
00245
00246 if (status != CPL_ERROR_NONE) {
00247 cx_string_delete(key);
00248 cx_string_delete(comment);
00249
00250 return 4;
00251 }
00252
00253 status = cpl_propertylist_set_comment(plist, cx_string_get(key),
00254 cx_string_get(comment));
00255
00256 if (status != 0) {
00257 cx_string_delete(key);
00258 cx_string_delete(comment);
00259
00260 return 4;
00261 }
00262
00263 cx_string_delete(key);
00264 cx_string_delete(comment);
00265
00266 return 0;
00267
00268 }
00269
00270
00281 const cxchar *
00282 giraffe_get_license(void)
00283 {
00284
00285 return _giraffe_license;
00286
00287 }
00288
00289
00303 GiInstrumentMode
00304 giraffe_get_mode(cpl_propertylist *properties)
00305 {
00306
00307 const cxchar *fctid = "giraffe_get_mode";
00308 const cxchar *mode;
00309
00310 cx_string *s = NULL;
00311
00312 GiInstrumentMode insmode;
00313
00314
00315 if (!properties) {
00316 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00317 return GIMODE_NONE;
00318 }
00319
00320
00321 if (!cpl_propertylist_has(properties, GIALIAS_INSMODE)) {
00322 gi_warning("%s: Property (%s) not found\n", fctid, GIALIAS_INSMODE);
00323
00324 if (!cpl_propertylist_has(properties, GIALIAS_SLITNAME)) {
00325 cx_warning("%s: Property (%s) not found\n", fctid,
00326 GIALIAS_SLITNAME);
00327 return GIMODE_NONE;
00328 }
00329 else {
00330 mode = cpl_propertylist_get_string(properties, GIALIAS_SLITNAME);
00331 }
00332 }
00333 else {
00334 mode = cpl_propertylist_get_string(properties, GIALIAS_SLITNAME);
00335 }
00336
00337 if (!mode || strlen(mode) == 0) {
00338 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00339 return GIMODE_NONE;
00340 }
00341
00342
00343 s = cx_string_create(mode);
00344 cx_string_lower(s);
00345
00346 if (strncmp(cx_string_get(s), "med", 3) == 0) {
00347 insmode = GIMODE_MEDUSA;
00348 }
00349 else if (strncmp(cx_string_get(s), "ifu", 3) == 0) {
00350 insmode = GIMODE_IFU;
00351 }
00352 else if (strncmp(cx_string_get(s), "arg", 3) == 0) {
00353 insmode = GIMODE_ARGUS;
00354 }
00355 else {
00356 cpl_error_set(fctid, CPL_ERROR_UNSUPPORTED_MODE);
00357 insmode = GIMODE_NONE;
00358 }
00359
00360 cx_string_delete(s);
00361
00362 return insmode;
00363
00364 }
00365
00381 cxchar *
00382 giraffe_path_get_basename(const cxchar *path)
00383 {
00384
00385 register cxssize base;
00386 register cxssize last_nonslash;
00387
00388 cxsize len;
00389
00390 cxchar *result;
00391
00392
00393 if (path == NULL) {
00394 return NULL;
00395 }
00396
00397 if (path[0] == '\0') {
00398 return cx_strdup(".");
00399 }
00400
00401 last_nonslash = strlen(path) - 1;
00402
00403 while (last_nonslash >= 0 && path[last_nonslash] == '/') {
00404 --last_nonslash;
00405 }
00406
00407
00408
00409
00410 if (last_nonslash == -1) {
00411 return cx_strdup("/");
00412 }
00413
00414 base = last_nonslash;
00415
00416 while (base >=0 && path[base] != '/') {
00417 --base;
00418 }
00419
00420 len = last_nonslash - base;
00421
00422 result = cx_malloc(len + 1);
00423 memcpy(result, path + base + 1, len);
00424 result[len] = '\0';
00425
00426 return result;
00427
00428 }
00429
00430
00443 cxchar *
00444 giraffe_localtime_iso8601(void)
00445 {
00446
00447 struct tm *ts;
00448
00449 time_t seconds = time(NULL);
00450
00451 cxchar *sdate = NULL;
00452
00453 cxulong milliseconds = 0;
00454
00455 cx_string *self = cx_string_new();
00456
00457
00458 cx_assert(self != NULL);
00459
00460 ts = localtime(&seconds);
00461
00462 cx_string_sprintf(self, "%4d-%02d-%02dT%02d:%02d:%02d.%03ld",
00463 ts->tm_year + 1900,
00464 ts->tm_mon + 1,
00465 ts->tm_mday,
00466 ts->tm_hour,
00467 ts->tm_min,
00468 ts->tm_sec,
00469 milliseconds);
00470
00471 sdate = cx_strdup(cx_string_get(self));
00472 cx_string_delete(self);
00473
00474 return sdate;
00475
00476 }
00477
00478
00486 cxint
00487 giraffe_add_recipe_info(cpl_propertylist *plist, const GiRecipeInfo *info)
00488 {
00489
00490 if (plist == NULL) {
00491 return -1;
00492 }
00493
00494 if (info != NULL) {
00495
00496 cxint status = 0;
00497
00498 cx_string *name = cx_string_new();
00499 cx_string *value = cx_string_new();
00500
00501
00502 cx_string_sprintf(name, "%s%-d %s", "ESO PRO REC", info->sequence,
00503 "PIPE ID");
00504 cx_string_sprintf(value, "%s/%s", PACKAGE, VERSION);
00505
00506 status = cpl_propertylist_update_string(plist, cx_string_get(name),
00507 cx_string_get(value));
00508
00509
00510 if (status != CPL_ERROR_NONE) {
00511 cx_string_delete(name);
00512 cx_string_delete(value);
00513
00514 return 1;
00515 }
00516
00517 status = cpl_propertylist_set_comment(plist, cx_string_get(name),
00518 "Pipeline (unique) identifier");
00519
00520 if (status != 0) {
00521 cx_string_delete(name);
00522 cx_string_delete(value);
00523
00524 return 1;
00525 }
00526
00527 if (info->start != NULL) {
00528 cx_string_sprintf(name, "%s%-d %s", "ESO PRO REC",
00529 info->sequence, "START");
00530 status = cpl_propertylist_update_string(plist,
00531 cx_string_get(name),
00532 info->start);
00533
00534 if (status != CPL_ERROR_NONE) {
00535 cx_string_delete(name);
00536 cx_string_delete(value);
00537
00538 return 1;
00539 }
00540
00541 status = cpl_propertylist_set_comment(plist, cx_string_get(name),
00542 "Date when recipe execution "
00543 "started.");
00544
00545 if (status != 0) {
00546 cx_string_delete(name);
00547 cx_string_delete(value);
00548
00549 return 1;
00550 }
00551 }
00552
00553 cx_string_delete(name);
00554 cx_string_delete(value);
00555
00556 }
00557
00558 return 0;
00559
00560 }
00561
00562
00584 cxint
00585 giraffe_add_frameset_info(cpl_propertylist *plist, const cpl_frameset *set,
00586 cxint sequence)
00587 {
00588
00589 if (plist == NULL) {
00590 return -1;
00591 }
00592
00593 if (set != NULL) {
00594
00595 cxsize nraw = 0;
00596 cxsize ncalib = 0;
00597
00598 cx_string *key = cx_string_new();
00599
00600 const cpl_frame *frame = cpl_frameset_get_first_const(set);
00601
00602 while (frame != NULL) {
00603
00604 cxint status = 0;
00605
00606 cpl_frame_group group = cpl_frame_get_group(frame);
00607
00608 const cxchar *name = cpl_frame_get_filename(frame);
00609 const cxchar *tag = cpl_frame_get_tag(frame);
00610 const cxchar *base = giraffe_path_get_basename(name);
00611
00612
00613 cx_assert(base != NULL);
00614
00615 switch (group) {
00616 case CPL_FRAME_GROUP_RAW:
00617 {
00618 ++nraw;
00619 status = _giraffe_add_frame_info(plist, base, tag, sequence,
00620 nraw, 0);
00621
00622 if (status != 0) {
00623 if (base != NULL) {
00624 cx_free((cxchar *)base);
00625 }
00626
00627 cx_string_delete(key);
00628 return -2;
00629 }
00630
00631 break;
00632 }
00633
00634 case CPL_FRAME_GROUP_CALIB:
00635 {
00636
00637 cpl_propertylist *_plist = NULL;
00638
00639
00640 ++ncalib;
00641 status = _giraffe_add_frame_info(plist, base, tag, sequence,
00642 ncalib, 1);
00643
00644 if (status != 0) {
00645 if (base != NULL) {
00646 cx_free((cxchar *)base);
00647 }
00648
00649 cx_string_delete(key);
00650 return -3;
00651 }
00652
00653 _plist = cpl_propertylist_load(name, 0);
00654
00655 if (_plist == NULL) {
00656 if (base != NULL) {
00657 cx_free((cxchar *)base);
00658 }
00659
00660 cx_string_delete(key);
00661 return -3;
00662 }
00663
00664
00665 if (cpl_propertylist_has(_plist, GIALIAS_DATAMD5)) {
00666
00667 const cxchar *s =
00668 cpl_propertylist_get_string(_plist, GIALIAS_DATAMD5);
00669
00670 if (strcmp(s, "Not computed") != 0) {
00671
00672 cx_string* md5 = cx_string_new();
00673
00674 cx_string_sprintf(md5, "%s%d %s%d %s", "ESO PRO REC",
00675 sequence, "CAL", ncalib, "DATAMD5");
00676
00677 status =
00678 cpl_propertylist_update_string(plist,
00679 cx_string_get(md5),
00680 s);
00681
00682 if (status != CPL_ERROR_NONE) {
00683 cx_string_delete(md5);
00684 cpl_propertylist_delete(_plist);
00685
00686 if (base != NULL) {
00687 cx_free((cxchar *)base);
00688 }
00689
00690 cx_string_delete(key);
00691 return -3;
00692 }
00693
00694 cx_string_delete(md5);
00695 }
00696
00697 }
00698
00699 cpl_propertylist_delete(_plist);
00700 break;
00701 }
00702
00703 default:
00704 break;
00705 }
00706
00707
00708 if (base != NULL) {
00709 cx_free((cxchar *)base);
00710 }
00711
00712 frame = cpl_frameset_get_next_const(set);
00713
00714 }
00715
00716 cx_string_delete(key);
00717
00718 }
00719
00720 return 0;
00721
00722 }
00723
00724
00745 cxint
00746 giraffe_propertylist_update(cpl_propertylist *self,
00747 cpl_propertylist *properties,
00748 const cxchar *regexp)
00749 {
00750
00751 const cxchar *fctid = "giraffe_propertylist_update";
00752
00753 cxlong i;
00754 cxlong sz = 0;
00755
00756
00757 cx_assert(self != NULL);
00758
00759 if (properties == NULL) {
00760 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00761 return -1;
00762 }
00763
00764 sz = cpl_propertylist_get_size(properties);
00765
00766 if (regexp == NULL || regexp[0] == '\0') {
00767
00768 for (i = 0; i < sz; i++) {
00769
00770 cpl_property *p = cpl_propertylist_get(properties, i);
00771 const cxchar *name = cpl_property_get_name(p);
00772
00773
00774 if (!cpl_propertylist_has(self, name)) {
00775
00776 cxint status = _giraffe_plist_append(self, p);
00777
00778 if (status) {
00779 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00780 return 1;
00781 }
00782 }
00783 }
00784 }
00785 else {
00786
00787 cxint status = 0;
00788
00789 regex_t re;
00790
00791
00792 status = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
00793
00794 if (status) {
00795 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00796 return 1;
00797 }
00798
00799 for (i = 0; i < sz; i++) {
00800
00801 cpl_property *p = cpl_propertylist_get(properties, i);
00802 const cxchar *name = cpl_property_get_name(p);
00803
00804
00805 if (regexec(&re, name, (size_t)0, NULL, 0) == REG_NOMATCH) {
00806 continue;
00807 }
00808
00809 if (!cpl_propertylist_has(self, name)) {
00810
00811 status = _giraffe_plist_append(self, p);
00812
00813 if (status) {
00814 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00815 return 1;
00816 }
00817 }
00818 }
00819
00820 regfree(&re);
00821
00822 }
00823
00824 return 0;
00825
00826 }
00827
00828
00836 cxint
00837 giraffe_propertylist_copy(cpl_propertylist *self,
00838 const cxchar *name,
00839 const cpl_propertylist *other,
00840 const cxchar *othername)
00841 {
00842
00843 const cxchar *fctid = "giraffe_propertylist_copy";
00844
00845
00846 const cxchar *s;
00847 const cxchar *comment;
00848
00849 cpl_type type;
00850
00851
00852
00853 cx_assert(self != NULL);
00854
00855 if (other == NULL) {
00856 return -1;
00857 }
00858
00859 if (othername == NULL) {
00860 return -2;
00861 }
00862
00863 if (!cpl_propertylist_has(other, othername)) {
00864 return 1;
00865 }
00866
00867 type = cpl_propertylist_get_type(other, othername);
00868
00869
00870
00871
00872
00873
00874 s = name == NULL ? othername : name;
00875
00876
00877
00878
00879
00880
00881 switch (type) {
00882 case CPL_TYPE_CHAR:
00883 {
00884 cxchar value = cpl_propertylist_get_char(other, othername);
00885
00886 if (cpl_propertylist_has(self, s)) {
00887 cpl_propertylist_set_char(self, s, value);
00888 }
00889 else {
00890 cpl_propertylist_append_char(self, s, value);
00891 }
00892 }
00893 break;
00894
00895 case CPL_TYPE_BOOL:
00896 {
00897 cxbool value = cpl_propertylist_get_bool(other, othername);
00898
00899 if (cpl_propertylist_has(self, s)) {
00900 cpl_propertylist_set_bool(self, s, value);
00901 }
00902 else {
00903 cpl_propertylist_append_bool(self, s, value);
00904 }
00905 }
00906 break;
00907
00908 case CPL_TYPE_INT:
00909 {
00910 cxint value = cpl_propertylist_get_int(other, othername);
00911
00912 if (cpl_propertylist_has(self, s)) {
00913 cpl_propertylist_set_int(self, s, value);
00914 }
00915 else {
00916 cpl_propertylist_append_int(self, s, value);
00917 }
00918 }
00919 break;
00920
00921 case CPL_TYPE_LONG:
00922 {
00923 cxlong value = cpl_propertylist_get_long(other, othername);
00924
00925 if (cpl_propertylist_has(self, s)) {
00926 cpl_propertylist_set_long(self, s, value);
00927 }
00928 else {
00929 cpl_propertylist_append_long(self, s, value);
00930 }
00931 }
00932 break;
00933
00934 case CPL_TYPE_FLOAT:
00935 {
00936 cxfloat value = cpl_propertylist_get_float(other, othername);
00937
00938 if (cpl_propertylist_has(self, s)) {
00939 cpl_propertylist_set_float(self, s, value);
00940 }
00941 else {
00942 cpl_propertylist_append_float(self, s, value);
00943 }
00944 }
00945 break;
00946
00947 case CPL_TYPE_DOUBLE:
00948 {
00949 cxdouble value = cpl_propertylist_get_double(other, othername);
00950
00951 if (cpl_propertylist_has(self, s)) {
00952 cpl_propertylist_set_double(self, s, value);
00953 }
00954 else {
00955 cpl_propertylist_append_double(self, s, value);
00956 }
00957 }
00958 break;
00959
00960 case CPL_TYPE_STRING:
00961 {
00962 const cxchar *value = cpl_propertylist_get_string(other,
00963 othername);
00964
00965 if (cpl_propertylist_has(self, s)) {
00966 cpl_propertylist_set_string(self, s, value);
00967 }
00968 else {
00969 cpl_propertylist_append_string(self, s, value);
00970 }
00971 }
00972 break;
00973
00974 default:
00975 cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
00976 return 2;
00977 break;
00978 }
00979
00980 comment = cpl_propertylist_get_comment(other, othername);
00981
00982 if (comment != NULL) {
00983 cpl_propertylist_set_comment(self, s, comment);
00984 }
00985
00986 return 0;
00987
00988 }
00989
00990
00991 cxint
00992 giraffe_propertylist_update_wcs(cpl_propertylist* properties, cxsize naxis,
00993 const cxdouble* crpix, const cxdouble* crval,
00994 const cxchar** ctype, const cxchar** cunit,
00995 const cpl_matrix* cd)
00996 {
00997
00998 if (properties == NULL) {
00999 return 0;
01000 }
01001
01002 cpl_propertylist_erase_regexp(properties, "^CRPIX[0-9]", 0);
01003 cpl_propertylist_erase_regexp(properties, "^CRVAL[0-9]", 0);
01004 cpl_propertylist_erase_regexp(properties, "^CDELT[0-9]", 0);
01005 cpl_propertylist_erase_regexp(properties, "^CTYPE[0-9]", 0);
01006 cpl_propertylist_erase_regexp(properties, "^CUNIT[0-9]", 0);
01007 cpl_propertylist_erase_regexp(properties, "^CROTA[0-9]", 0);
01008 cpl_propertylist_erase_regexp(properties, "^CD[0-9]*_[0-9]", 0);
01009 cpl_propertylist_erase_regexp(properties, "^PC[0-9]*_[0-9]", 0);
01010
01011
01012 if (naxis > 0) {
01013
01014
01015 register cxsize i = 0;
01016
01017 cx_string* keyword = cx_string_new();
01018 cx_string* comment = cx_string_new();
01019
01020
01021 cx_assert(cpl_matrix_get_nrow(cd) == cpl_matrix_get_ncol(cd));
01022
01023 for (i = 0; i < naxis; i++) {
01024
01025 cx_string_sprintf(keyword, "CTYPE%-d", i + 1);
01026 cx_string_sprintf(comment, "Coordinate system of axis %d", i + 1);
01027 cpl_propertylist_append_string(properties,
01028 cx_string_get(keyword), ctype[i]);
01029 cpl_propertylist_set_comment(properties, cx_string_get(keyword),
01030 cx_string_get(comment));
01031
01032 }
01033
01034 for (i = 0; i < naxis; i++) {
01035
01036 cx_string_sprintf(keyword, "CRPIX%-d", i + 1);
01037 cx_string_sprintf(comment, "Reference pixel of axis %d", i + 1);
01038 cpl_propertylist_append_double(properties,
01039 cx_string_get(keyword), crpix[i]);
01040 cpl_propertylist_set_comment(properties, cx_string_get(keyword),
01041 cx_string_get(comment));
01042
01043 }
01044
01045 for (i = 0; i < naxis; i++) {
01046
01047 cx_string_sprintf(keyword, "CRVAL%-d", i + 1);
01048 cx_string_sprintf(comment, "Coordinate of axis %d at reference "
01049 "pixel", i + 1);
01050 cpl_propertylist_append_double(properties,
01051 cx_string_get(keyword), crval[i]);
01052 cpl_propertylist_set_comment(properties, cx_string_get(keyword),
01053 cx_string_get(comment));
01054
01055 }
01056
01057 for (i = 0; i < naxis; i++) {
01058
01059 if (cunit[i] != NULL) {
01060 cx_string_sprintf(keyword, "CUNIT%-d", i + 1);
01061 cx_string_sprintf(comment, "Unit of coordinate axis %d",
01062 i + 1);
01063 cpl_propertylist_append_string(properties,
01064 cx_string_get(keyword),
01065 cunit[i]);
01066 cpl_propertylist_set_comment(properties,
01067 cx_string_get(keyword),
01068 cx_string_get(comment));
01069 }
01070
01071 }
01072
01073
01074
01075
01076
01077
01078 for (i = 0; i < naxis; i++) {
01079
01080 register cxsize j = 0;
01081
01082
01083 for (j = 0; j < naxis; j++) {
01084
01085 cx_string_sprintf(keyword, "CD%-d_%-d", i + 1, j + 1);
01086 cx_string_sprintf(comment, "Coordinate transformation matrix "
01087 "element", i + 1);
01088 cpl_propertylist_append_double(properties,
01089 cx_string_get(keyword),
01090 cpl_matrix_get(cd, i, j));
01091 cpl_propertylist_set_comment(properties,
01092 cx_string_get(keyword),
01093 cx_string_get(comment));
01094 }
01095
01096 }
01097
01098 cx_string_delete(keyword);
01099 keyword = NULL;
01100
01101 cx_string_delete(comment);
01102 comment = NULL;
01103
01104 }
01105
01106 return 0;
01107
01108 }
01109
01110
01111 cxint
01112 giraffe_frameset_set_groups(cpl_frameset* set, GiGroupInfo *groups)
01113 {
01114
01115 cpl_frame* frame = NULL;
01116
01117
01118 if (set == NULL) {
01119 return -1;
01120 }
01121
01122 if (groups == NULL || groups->tag == NULL) {
01123 return 0;
01124 }
01125
01126 frame = cpl_frameset_get_first(set);
01127
01128 while (frame != NULL) {
01129
01130 const cxchar* tag = cpl_frame_get_tag(frame);
01131
01132 if (tag != NULL &&
01133 cpl_frame_get_group(frame) == CPL_FRAME_GROUP_NONE) {
01134
01135 const GiGroupInfo* g = groups;
01136
01137 while (g->tag != NULL) {
01138 if (strcmp(tag, g->tag) == 0) {
01139 cpl_frame_set_group(frame, g->group);
01140 break;
01141 }
01142 ++g;
01143 }
01144
01145 }
01146
01147 frame = cpl_frameset_get_next(set);
01148
01149 }
01150
01151 return 0;
01152
01153 }