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