GIRAFFE Pipeline Reference Manual

giutils.c
1 /* $Id$
2  *
3  * This file is part of the GIRAFFE Pipeline
4  * Copyright (C) 2002-2006 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
21 /*
22  * $Author$
23  * $Date$
24  * $Revision$
25  * $Name$
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31 
32 #ifdef HAVE_SYS_TYPES_H
33 # include <sys/types.h>
34 #endif
35 #include <time.h>
36 #include <string.h>
37 #include <regex.h>
38 
39 #include <cxstring.h>
40 #include <cxstrutils.h>
41 
42 #include <cpl_msg.h>
43 #include <cpl_error.h>
44 #include <cpl_matrix.h>
45 
46 #include "gialias.h"
47 #include "gimessages.h"
48 #include "gierror.h"
49 #include "giutils.h"
50 
51 
60 /*
61  * Giraffe version and license
62  */
63 
64 static const cxchar *_giraffe_license =
65  " This file is part of the GIRAFFE Instrument Pipeline\n"
66  " Copyright (C) 2002-2014 European Southern Observatory\n"
67  "\n"
68  " This program is free software; you can redistribute it and/or modify\n"
69  " it under the terms of the GNU General Public License as published by\n"
70  " the Free Software Foundation; either version 2 of the License, or\n"
71  " (at your option) any later version.\n"
72  "\n"
73  " This program is distributed in the hope that it will be useful,\n"
74  " but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
75  " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
76  " GNU General Public License for more details.\n"
77  "\n"
78  " You should have received a copy of the GNU General Public License\n"
79  " along with this program; if not, write to the Free Software\n"
80  " Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301"
81  " USA";
82 
83 
84 inline static cxint
85 _giraffe_plist_append(cpl_propertylist *self, cpl_property *p)
86 {
87 
88  const cxchar *name = cpl_property_get_name(p);
89  const cxchar *comment = cpl_property_get_comment(p);
90 
91 
92  switch (cpl_property_get_type(p)) {
93  case CPL_TYPE_BOOL:
94  {
95  cxbool value = cpl_property_get_bool(p);
96 
97  cpl_propertylist_append_bool(self, name, value);
98  break;
99  }
100 
101  case CPL_TYPE_CHAR:
102  {
103  cxchar value = cpl_property_get_char(p);
104 
105  cpl_propertylist_append_char(self, name, value);
106  break;
107  }
108 
109  case CPL_TYPE_INT:
110  {
111  cxint value = cpl_property_get_int(p);
112 
113  cpl_propertylist_append_int(self, name, value);
114  break;
115  }
116 
117  case CPL_TYPE_LONG:
118  {
119  cxlong value = cpl_property_get_long(p);
120 
121  cpl_propertylist_append_long(self, name, value);
122  break;
123  }
124 
125  case CPL_TYPE_FLOAT:
126  {
127  cxfloat value = cpl_property_get_float(p);
128 
129  cpl_propertylist_append_float(self, name, value);
130  break;
131  }
132 
133  case CPL_TYPE_DOUBLE:
134  {
135  cxdouble value = cpl_property_get_double(p);
136 
137  cpl_propertylist_append_double(self, name, value);
138  break;
139  }
140 
141  case CPL_TYPE_STRING:
142  {
143  const cxchar *value = cpl_property_get_string(p);
144 
145  cpl_propertylist_append_string(self, name, value);
146  break;
147  }
148 
149  default:
150 
151  /*
152  * We should never reach this point! Since the property
153  * was a valid property it has a valid type. But this
154  * protects against addition of new types.
155  */
156 
157  return 1;
158  break;
159  }
160 
161  if (comment != NULL) {
162  cpl_propertylist_set_comment(self, name, comment);
163  }
164 
165  return 0;
166 
167 }
168 
169 
170 inline static cxint
171 _giraffe_add_frame_info(cpl_propertylist *plist, const cxchar *name,
172  const cxchar *tag, cxint sequence, cxint frame_index,
173  cxint mode)
174 {
175 
176  const cxchar *id = NULL;
177  const cxchar *group = NULL;
178 
179  cxint status = 0;
180 
181  cx_string *key = NULL;
182  cx_string *comment = NULL;
183 
184 
185  if (plist == NULL) {
186  return 1;
187  }
188 
189  switch (mode) {
190  case 0:
191  id = "RAW";
192  group = "raw";
193  break;
194 
195  case 1:
196  id = "CAL";
197  group = "calibration";
198  break;
199 
200  default:
201  return 2;
202  break;
203  }
204 
205  key = cx_string_new();
206  comment = cx_string_new();
207 
208 
209  /*
210  * Frame name
211  */
212 
213  cx_string_sprintf(key, "%s%-d %s%-d %s", "ESO PRO REC", sequence, id,
214  frame_index, "NAME");
215  cx_string_sprintf(comment, "%s %s %s", "File name of", group, "frame");
216 
217  status = cpl_propertylist_update_string(plist, cx_string_get(key), name);
218 
219  if (status != CPL_ERROR_NONE) {
220  cx_string_delete(key);
221  cx_string_delete(comment);
222 
223  return 3;
224  }
225 
226  status = cpl_propertylist_set_comment(plist, cx_string_get(key),
227  cx_string_get(comment));
228 
229  if (status != 0) {
230  cx_string_delete(key);
231  cx_string_delete(comment);
232 
233  return 3;
234  }
235 
236 
237  /*
238  * Frame category
239  */
240 
241  cx_string_sprintf(key, "%s%-d %s%-d %s", "ESO PRO REC", sequence, id,
242  frame_index, "CATG");
243  cx_string_sprintf(comment, "%s %s %s", "Frame category of", group,
244  "frame");
245 
246  status = cpl_propertylist_update_string(plist, cx_string_get(key), tag);
247 
248  if (status != CPL_ERROR_NONE) {
249  cx_string_delete(key);
250  cx_string_delete(comment);
251 
252  return 4;
253  }
254 
255  status = cpl_propertylist_set_comment(plist, cx_string_get(key),
256  cx_string_get(comment));
257 
258  if (status != 0) {
259  cx_string_delete(key);
260  cx_string_delete(comment);
261 
262  return 4;
263  }
264 
265  cx_string_delete(key);
266  cx_string_delete(comment);
267 
268  return 0;
269 
270 }
271 
272 
283 const cxchar *
285 {
286 
287  return _giraffe_license;
288 
289 }
290 
291 
305 GiInstrumentMode
306 giraffe_get_mode(cpl_propertylist *properties)
307 {
308 
309  const cxchar *fctid = "giraffe_get_mode";
310  const cxchar *mode;
311 
312  cx_string *s = NULL;
313 
314  GiInstrumentMode insmode;
315 
316 
317  if (!properties) {
318  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
319  return GIMODE_NONE;
320  }
321 
322 
323  if (!cpl_propertylist_has(properties, GIALIAS_INSMODE)) {
324  gi_warning("%s: Property (%s) not found\n", fctid, GIALIAS_INSMODE);
325 
326  if (!cpl_propertylist_has(properties, GIALIAS_SLITNAME)) {
327  cx_warning("%s: Property (%s) not found\n", fctid,
328  GIALIAS_SLITNAME);
329  return GIMODE_NONE;
330  }
331  else {
332  mode = cpl_propertylist_get_string(properties, GIALIAS_SLITNAME);
333  }
334  }
335  else {
336  mode = cpl_propertylist_get_string(properties, GIALIAS_SLITNAME);
337  }
338 
339  if (!mode || strlen(mode) == 0) {
340  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
341  return GIMODE_NONE;
342  }
343 
344 
345  s = cx_string_create(mode);
346  cx_string_lower(s);
347 
348  if (strncmp(cx_string_get(s), "med", 3) == 0) {
349  insmode = GIMODE_MEDUSA;
350  }
351  else if (strncmp(cx_string_get(s), "ifu", 3) == 0) {
352  insmode = GIMODE_IFU;
353  }
354  else if (strncmp(cx_string_get(s), "arg", 3) == 0) {
355  insmode = GIMODE_ARGUS;
356  }
357  else {
358  cpl_error_set(fctid, CPL_ERROR_UNSUPPORTED_MODE);
359  insmode = GIMODE_NONE;
360  }
361 
362  cx_string_delete(s);
363 
364  return insmode;
365 
366 }
367 
383 cxchar *
384 giraffe_path_get_basename(const cxchar *path)
385 {
386 
387  register cxssize base;
388  register cxssize last_nonslash;
389 
390  cxsize len;
391 
392  cxchar *result;
393 
394 
395  if (path == NULL) {
396  return NULL;
397  }
398 
399  if (path[0] == '\0') {
400  return cx_strdup(".");
401  }
402 
403  last_nonslash = strlen(path) - 1;
404 
405  while (last_nonslash >= 0 && path[last_nonslash] == '/') {
406  --last_nonslash;
407  }
408 
409 
410  /* String only containing slashes */
411 
412  if (last_nonslash == -1) {
413  return cx_strdup("/");
414  }
415 
416  base = last_nonslash;
417 
418  while (base >=0 && path[base] != '/') {
419  --base;
420  }
421 
422  len = last_nonslash - base;
423 
424  result = cx_malloc(len + 1);
425  memcpy(result, path + base + 1, len);
426  result[len] = '\0';
427 
428  return result;
429 
430 }
431 
432 
445 cxchar *
447 {
448 
449  struct tm *ts;
450 
451  time_t seconds = time(NULL);
452 
453  cxchar *sdate = NULL;
454 
455  cxulong milliseconds = 0;
456 
457  cx_string *self = cx_string_new();
458 
459 
460  cx_assert(self != NULL);
461 
462  ts = localtime(&seconds);
463 
464  cx_string_sprintf(self, "%4d-%02d-%02dT%02d:%02d:%02d.%03ld",
465  ts->tm_year + 1900,
466  ts->tm_mon + 1,
467  ts->tm_mday,
468  ts->tm_hour,
469  ts->tm_min,
470  ts->tm_sec,
471  milliseconds);
472 
473  sdate = cx_strdup(cx_string_get(self));
474  cx_string_delete(self);
475 
476  return sdate;
477 
478 }
479 
480 
488 cxint
489 giraffe_add_recipe_info(cpl_propertylist *plist, const GiRecipeInfo *info)
490 {
491 
492  if (plist == NULL) {
493  return -1;
494  }
495 
496  if (info != NULL) {
497 
498  cxint status = 0;
499 
500  cx_string *name = cx_string_new();
501  cx_string *value = cx_string_new();
502 
503 
504  cx_string_sprintf(name, "%s%-d %s", "ESO PRO REC", info->sequence,
505  "PIPE ID");
506  cx_string_sprintf(value, "%s/%s", PACKAGE, VERSION);
507 
508  status = cpl_propertylist_update_string(plist, cx_string_get(name),
509  cx_string_get(value));
510 
511 
512  if (status != CPL_ERROR_NONE) {
513  cx_string_delete(name);
514  cx_string_delete(value);
515 
516  return 1;
517  }
518 
519  status = cpl_propertylist_set_comment(plist, cx_string_get(name),
520  "Pipeline (unique) identifier");
521 
522  if (status != 0) {
523  cx_string_delete(name);
524  cx_string_delete(value);
525 
526  return 1;
527  }
528 
529  if (info->start != NULL) {
530  cx_string_sprintf(name, "%s%-d %s", "ESO PRO REC",
531  info->sequence, "START");
532  status = cpl_propertylist_update_string(plist,
533  cx_string_get(name),
534  info->start);
535 
536  if (status != CPL_ERROR_NONE) {
537  cx_string_delete(name);
538  cx_string_delete(value);
539 
540  return 1;
541  }
542 
543  status = cpl_propertylist_set_comment(plist, cx_string_get(name),
544  "Date when recipe execution "
545  "started.");
546 
547  if (status != 0) {
548  cx_string_delete(name);
549  cx_string_delete(value);
550 
551  return 1;
552  }
553  }
554 
555  cx_string_delete(name);
556  cx_string_delete(value);
557 
558  }
559 
560  return 0;
561 
562 }
563 
564 
586 cxint
587 giraffe_add_frameset_info(cpl_propertylist *plist, const cpl_frameset *set,
588  cxint sequence)
589 {
590 
591  if (plist == NULL) {
592  return -1;
593  }
594 
595  if (set != NULL) {
596 
597  cxsize nraw = 0;
598  cxsize ncalib = 0;
599 
600  cx_string *key = cx_string_new();
601 
602  const cpl_frame *frame = NULL;
603 
604  cpl_frameset_iterator *it = cpl_frameset_iterator_new(set);
605 
606 
607  while ((frame = cpl_frameset_iterator_get_const(it)) != NULL) {
608 
609  cpl_frame_group group = cpl_frame_get_group(frame);
610 
611  const cxchar *name = cpl_frame_get_filename(frame);
612  const cxchar *tag = cpl_frame_get_tag(frame);
613  const cxchar *base = giraffe_path_get_basename(name);
614 
615 
616  cx_assert(base != NULL);
617 
618  switch (group) {
619  case CPL_FRAME_GROUP_RAW:
620  {
621 
622  cxint status = 0;
623 
624  ++nraw;
625 
626 
627  /*
628  * Get the product's ancestor as the archive name of the
629  * first raw file in the reference set
630  */
631 
632  if (!cpl_propertylist_has(plist, GIALIAS_ANCESTOR)) {
633 
634  if (nraw == 1) {
635 
636  cpl_propertylist *_plist = cpl_propertylist_load(name, 0);
637 
638  if (_plist == NULL) {
639 
640  if (base != NULL) {
641  cx_free((cxchar *)base);
642  }
643 
644  cpl_frameset_iterator_delete(it);
645  cx_string_delete(key);
646 
647  return -2;
648 
649  }
650 
651  if (cpl_propertylist_has(_plist, GIALIAS_ANCESTOR)) {
652  cpl_propertylist_copy_property(plist, _plist,
653  GIALIAS_ANCESTOR);
654  }
655  else {
656 
657  const cxchar *s =
658  cpl_propertylist_get_string(_plist,
659  GIALIAS_ARCFILE);
660  const cxchar *c = "Inherited archive file name "
661  "of the first raw data frame";
662 
663  if (s != NULL) {
664  cpl_propertylist_append_string(plist,
665  GIALIAS_ANCESTOR, s);
666  cpl_propertylist_set_comment(plist,
667  GIALIAS_ANCESTOR, c);
668  }
669 
670  }
671 
672  cpl_propertylist_delete(_plist);
673 
674  }
675 
676  }
677 
678 
679  status = _giraffe_add_frame_info(plist, base, tag,
680  sequence, nraw, 0);
681 
682  if (status != 0) {
683  if (base != NULL) {
684  cx_free((cxchar *)base);
685  }
686 
687  cpl_frameset_iterator_delete(it);
688  cx_string_delete(key);
689 
690  return -2;
691  }
692 
693 
694  break;
695  }
696 
697  case CPL_FRAME_GROUP_CALIB:
698  {
699 
700  cpl_propertylist *_plist = NULL;
701 
702 
703  ++ncalib;
704  cxint status = _giraffe_add_frame_info(plist, base, tag,
705  sequence, ncalib, 1);
706 
707  if (status != 0) {
708  if (base != NULL) {
709  cx_free((cxchar *)base);
710  }
711 
712  cpl_frameset_iterator_delete(it);
713  cx_string_delete(key);
714 
715  return -3;
716  }
717 
718  _plist = cpl_propertylist_load(name, 0);
719 
720  if (_plist == NULL) {
721  if (base != NULL) {
722  cx_free((cxchar *)base);
723  }
724 
725  cpl_frameset_iterator_delete(it);
726  cx_string_delete(key);
727 
728  return -3;
729  }
730 
731 
732  if (cpl_propertylist_has(_plist, GIALIAS_DATAMD5)) {
733 
734  const cxchar *s =
735  cpl_propertylist_get_string(_plist, GIALIAS_DATAMD5);
736 
737  if (strcmp(s, "Not computed") != 0) {
738 
739  cx_string* md5 = cx_string_new();
740 
741  cx_string_sprintf(md5, "%s%d %s%"
742  CX_PRINTF_FORMAT_SIZE_TYPE "%s",
743  "ESO PRO REC", sequence, "CAL",
744  ncalib, " DATAMD5");
745 
746  status =
747  cpl_propertylist_update_string(plist,
748  cx_string_get(md5),
749  s);
750 
751  if (status != CPL_ERROR_NONE) {
752  cx_string_delete(md5);
753  cpl_propertylist_delete(_plist);
754 
755  if (base != NULL) {
756  cx_free((cxchar *)base);
757  }
758 
759  cpl_frameset_iterator_delete(it);
760  cx_string_delete(key);
761 
762  return -3;
763  }
764 
765  cx_string_delete(md5);
766  }
767 
768  }
769 
770  cpl_propertylist_delete(_plist);
771  break;
772  }
773 
774  default:
775  break;
776  }
777 
778 
779  if (base != NULL) {
780  cx_free((cxchar *)base);
781  }
782 
783  cpl_frameset_iterator_advance(it, 1);
784 
785  }
786 
787  cpl_frameset_iterator_delete(it);
788  cx_string_delete(key);
789 
790  }
791 
792  return 0;
793 
794 }
795 
796 
817 cxint
818 giraffe_propertylist_update(cpl_propertylist *self,
819  cpl_propertylist *properties,
820  const cxchar *regexp)
821 {
822 
823  const cxchar *fctid = "giraffe_propertylist_update";
824 
825  cxlong i;
826  cxlong sz = 0;
827 
828 
829  cx_assert(self != NULL);
830 
831  if (properties == NULL) {
832  cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
833  return -1;
834  }
835 
836  sz = cpl_propertylist_get_size(properties);
837 
838  if (regexp == NULL || regexp[0] == '\0') {
839 
840  for (i = 0; i < sz; i++) {
841 
842  cpl_property *p = cpl_propertylist_get(properties, i);
843  const cxchar *name = cpl_property_get_name(p);
844 
845 
846  if (!cpl_propertylist_has(self, name)) {
847 
848  cxint status = _giraffe_plist_append(self, p);
849 
850  if (status) {
851  cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
852  return 1;
853  }
854  }
855  }
856  }
857  else {
858 
859  cxint status = 0;
860 
861  regex_t re;
862 
863 
864  status = regcomp(&re, regexp, REG_EXTENDED | REG_NOSUB);
865 
866  if (status) {
867  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
868  return 1;
869  }
870 
871  for (i = 0; i < sz; i++) {
872 
873  cpl_property *p = cpl_propertylist_get(properties, i);
874  const cxchar *name = cpl_property_get_name(p);
875 
876 
877  if (regexec(&re, name, (size_t)0, NULL, 0) == REG_NOMATCH) {
878  continue;
879  }
880 
881  if (!cpl_propertylist_has(self, name)) {
882 
883  status = _giraffe_plist_append(self, p);
884 
885  if (status) {
886  cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
887  return 1;
888  }
889  }
890  }
891 
892  regfree(&re);
893 
894  }
895 
896  return 0;
897 
898 }
899 
900 
908 cxint
909 giraffe_propertylist_copy(cpl_propertylist *self,
910  const cxchar *name,
911  const cpl_propertylist *other,
912  const cxchar *othername)
913 {
914 
915  const cxchar *fctid = "giraffe_propertylist_copy";
916 
917 
918  const cxchar *s;
919  const cxchar *comment;
920 
921  cpl_type type;
922 
923 
924 
925  cx_assert(self != NULL);
926 
927  if (other == NULL) {
928  return -1;
929  }
930 
931  if (othername == NULL) {
932  return -2;
933  }
934 
935  if (!cpl_propertylist_has(other, othername)) {
936  return 1;
937  }
938 
939  type = cpl_propertylist_get_type(other, othername);
940 
941 
942  /*
943  * Determine the name the new property should have in self.
944  */
945 
946  s = name == NULL ? othername : name;
947 
948 
949  /*
950  * Add the property to the destination list.
951  */
952 
953  switch (type) {
954  case CPL_TYPE_CHAR:
955  {
956  cxchar value = cpl_propertylist_get_char(other, othername);
957 
958  if (cpl_propertylist_has(self, s)) {
959  cpl_propertylist_set_char(self, s, value);
960  }
961  else {
962  cpl_propertylist_append_char(self, s, value);
963  }
964  }
965  break;
966 
967  case CPL_TYPE_BOOL:
968  {
969  cxbool value = cpl_propertylist_get_bool(other, othername);
970 
971  if (cpl_propertylist_has(self, s)) {
972  cpl_propertylist_set_bool(self, s, value);
973  }
974  else {
975  cpl_propertylist_append_bool(self, s, value);
976  }
977  }
978  break;
979 
980  case CPL_TYPE_INT:
981  {
982  cxint value = cpl_propertylist_get_int(other, othername);
983 
984  if (cpl_propertylist_has(self, s)) {
985  cpl_propertylist_set_int(self, s, value);
986  }
987  else {
988  cpl_propertylist_append_int(self, s, value);
989  }
990  }
991  break;
992 
993  case CPL_TYPE_LONG:
994  {
995  cxlong value = cpl_propertylist_get_long(other, othername);
996 
997  if (cpl_propertylist_has(self, s)) {
998  cpl_propertylist_set_long(self, s, value);
999  }
1000  else {
1001  cpl_propertylist_append_long(self, s, value);
1002  }
1003  }
1004  break;
1005 
1006  case CPL_TYPE_FLOAT:
1007  {
1008  cxfloat value = cpl_propertylist_get_float(other, othername);
1009 
1010  if (cpl_propertylist_has(self, s)) {
1011  cpl_propertylist_set_float(self, s, value);
1012  }
1013  else {
1014  cpl_propertylist_append_float(self, s, value);
1015  }
1016  }
1017  break;
1018 
1019  case CPL_TYPE_DOUBLE:
1020  {
1021  cxdouble value = cpl_propertylist_get_double(other, othername);
1022 
1023  if (cpl_propertylist_has(self, s)) {
1024  cpl_propertylist_set_double(self, s, value);
1025  }
1026  else {
1027  cpl_propertylist_append_double(self, s, value);
1028  }
1029  }
1030  break;
1031 
1032  case CPL_TYPE_STRING:
1033  {
1034  const cxchar *value = cpl_propertylist_get_string(other,
1035  othername);
1036 
1037  if (cpl_propertylist_has(self, s)) {
1038  cpl_propertylist_set_string(self, s, value);
1039  }
1040  else {
1041  cpl_propertylist_append_string(self, s, value);
1042  }
1043  }
1044  break;
1045 
1046  default:
1047  cpl_error_set(fctid, CPL_ERROR_INVALID_TYPE);
1048  return 2;
1049  break;
1050  }
1051 
1052  comment = cpl_propertylist_get_comment(other, othername);
1053 
1054  if (comment != NULL) {
1055  cpl_propertylist_set_comment(self, s, comment);
1056  }
1057 
1058  return 0;
1059 
1060 }
1061 
1062 
1063 cxint
1064 giraffe_propertylist_update_wcs(cpl_propertylist* properties, cxsize naxis,
1065  const cxdouble* crpix, const cxdouble* crval,
1066  const cxchar** ctype, const cxchar** cunit,
1067  const cpl_matrix* cd)
1068 {
1069 
1070  if (properties == NULL) {
1071  return 0;
1072  }
1073 
1074  cpl_propertylist_erase_regexp(properties, "^CRPIX[0-9]", 0);
1075  cpl_propertylist_erase_regexp(properties, "^CRVAL[0-9]", 0);
1076  cpl_propertylist_erase_regexp(properties, "^CDELT[0-9]", 0);
1077  cpl_propertylist_erase_regexp(properties, "^CTYPE[0-9]", 0);
1078  cpl_propertylist_erase_regexp(properties, "^CUNIT[0-9]", 0);
1079  cpl_propertylist_erase_regexp(properties, "^CROTA[0-9]", 0);
1080  cpl_propertylist_erase_regexp(properties, "^CD[0-9]*_[0-9]", 0);
1081  cpl_propertylist_erase_regexp(properties, "^PC[0-9]*_[0-9]", 0);
1082 
1083 
1084  if (naxis > 0) {
1085 
1086 
1087  register cxsize i = 0;
1088 
1089  cx_string* keyword = cx_string_new();
1090  cx_string* comment = cx_string_new();
1091 
1092 
1093  cx_assert(cpl_matrix_get_nrow(cd) == cpl_matrix_get_ncol(cd));
1094 
1095  for (i = 0; i < naxis; i++) {
1096 
1097  cx_string_sprintf(keyword, "CTYPE%-" CX_PRINTF_FORMAT_SIZE_TYPE,
1098  i + 1);
1099  cx_string_sprintf(comment, "Coordinate system of axis %"
1100  CX_PRINTF_FORMAT_SIZE_TYPE, i + 1);
1101  cpl_propertylist_append_string(properties,
1102  cx_string_get(keyword), ctype[i]);
1103  cpl_propertylist_set_comment(properties, cx_string_get(keyword),
1104  cx_string_get(comment));
1105 
1106  }
1107 
1108  for (i = 0; i < naxis; i++) {
1109 
1110  cx_string_sprintf(keyword, "CRPIX%-" CX_PRINTF_FORMAT_SIZE_TYPE,
1111  i + 1);
1112  cx_string_sprintf(comment, "Reference pixel of axis %"
1113  CX_PRINTF_FORMAT_SIZE_TYPE, i + 1);
1114  cpl_propertylist_append_double(properties,
1115  cx_string_get(keyword), crpix[i]);
1116  cpl_propertylist_set_comment(properties, cx_string_get(keyword),
1117  cx_string_get(comment));
1118 
1119  }
1120 
1121  for (i = 0; i < naxis; i++) {
1122 
1123  cx_string_sprintf(keyword, "CRVAL%-" CX_PRINTF_FORMAT_SIZE_TYPE,
1124  i + 1);
1125  cx_string_sprintf(comment, "Coordinate of axis %"
1126  CX_PRINTF_FORMAT_SIZE_TYPE " at reference "
1127  "pixel", i + 1);
1128  cpl_propertylist_append_double(properties,
1129  cx_string_get(keyword), crval[i]);
1130  cpl_propertylist_set_comment(properties, cx_string_get(keyword),
1131  cx_string_get(comment));
1132 
1133  }
1134 
1135  for (i = 0; i < naxis; i++) {
1136 
1137  if (cunit[i] != NULL) {
1138  cx_string_sprintf(keyword, "CUNIT%-"
1139  CX_PRINTF_FORMAT_SIZE_TYPE, i + 1);
1140  cx_string_sprintf(comment, "Unit of coordinate axis %"
1141  CX_PRINTF_FORMAT_SIZE_TYPE, i + 1);
1142  cpl_propertylist_append_string(properties,
1143  cx_string_get(keyword),
1144  cunit[i]);
1145  cpl_propertylist_set_comment(properties,
1146  cx_string_get(keyword),
1147  cx_string_get(comment));
1148  }
1149 
1150  }
1151 
1152 
1153  /*
1154  * CD matrix
1155  */
1156 
1157  for (i = 0; i < naxis; i++) {
1158 
1159  register cxsize j = 0;
1160 
1161 
1162  for (j = 0; j < naxis; j++) {
1163 
1164  cx_string_sprintf(keyword, "CD%-" CX_PRINTF_FORMAT_SIZE_TYPE
1165  "_%-" CX_PRINTF_FORMAT_SIZE_TYPE, i + 1,
1166  j + 1);
1167  cx_string_sprintf(comment, "Coordinate transformation matrix "
1168  "element");
1169  cpl_propertylist_append_double(properties,
1170  cx_string_get(keyword),
1171  cpl_matrix_get(cd, i, j));
1172  cpl_propertylist_set_comment(properties,
1173  cx_string_get(keyword),
1174  cx_string_get(comment));
1175  }
1176 
1177  }
1178 
1179  cx_string_delete(keyword);
1180  keyword = NULL;
1181 
1182  cx_string_delete(comment);
1183  comment = NULL;
1184 
1185  }
1186 
1187  return 0;
1188 
1189 }
1190 
1191 
1192 cxint
1193 giraffe_frameset_set_groups(cpl_frameset* set, GiGroupInfo *groups)
1194 {
1195 
1196  cpl_frame* frame = NULL;
1197 
1198  cpl_frameset_iterator *it = NULL;
1199 
1200 
1201  if (set == NULL) {
1202  return -1;
1203  }
1204 
1205  if (groups == NULL || groups->tag == NULL) {
1206  return 0;
1207  }
1208 
1209  it = cpl_frameset_iterator_new(set);
1210 
1211  while ((frame = cpl_frameset_iterator_get(it)) != NULL) {
1212 
1213  const cxchar* tag = cpl_frame_get_tag(frame);
1214 
1215  if (tag != NULL &&
1216  cpl_frame_get_group(frame) == CPL_FRAME_GROUP_NONE) {
1217 
1218  const GiGroupInfo* g = groups;
1219 
1220  while (g->tag != NULL) {
1221  if (strcmp(tag, g->tag) == 0) {
1222  cpl_frame_set_group(frame, g->group);
1223  break;
1224  }
1225  ++g;
1226  }
1227 
1228  }
1229 
1230  cpl_frameset_iterator_advance(it, 1);
1231 
1232  }
1233 
1234  cpl_frameset_iterator_delete(it);
1235 
1236  return 0;
1237 
1238 }
1239 
1240 
1274 cxdouble giraffe_propertylist_get_conad(const cpl_propertylist* properties)
1275 {
1276 
1277  const cxchar* const fctid = "giraffe_propertylist_get_conad";
1278 
1279  const cxchar *names[2] = {GIALIAS_CONAD, GIALIAS_CONAD_LEGACY};
1280  const cxchar *name = NULL;
1281 
1282  cxdouble conad = 1.;
1283 
1284 
1285  cx_assert(properties != NULL);
1286 
1287 
1288  if (!cpl_propertylist_has(properties, GIALIAS_CONAD)) {
1289 
1290  if (!cpl_propertylist_has(properties, GIALIAS_CONAD_LEGACY)) {
1291 
1292  cpl_msg_error(fctid, "Missing detector gain property (%s, %s)! ",
1293  GIALIAS_CONAD, GIALIAS_CONAD_LEGACY);
1294  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
1295 
1296  return 0.;
1297 
1298  }
1299  else {
1300  name = names[1];
1301  }
1302 
1303 
1304  }
1305  else {
1306  name = names[0];
1307  }
1308 
1309  conad = cpl_propertylist_get_double(properties, name);
1310 
1311  if (conad < 0.) {
1312 
1313  cpl_msg_error(fctid, "Invalid conversion factor (%s) %.3g "
1314  "[e-/ADU]", name, conad);
1315  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
1316 
1317  return 0.;
1318 
1319  }
1320 
1321  return conad;
1322 
1323 }
1324 
1325 
1357 cxdouble
1358 giraffe_propertylist_get_ron(const cpl_propertylist* properties)
1359 {
1360 
1361  const cxchar* const fctid = "giraffe_propertylist_get_ron";
1362 
1363 
1364  cxdouble ron = 0.;
1365 
1366 
1367  cx_assert(properties != NULL);
1368 
1369  if (!cpl_propertylist_has(properties, GIALIAS_BIASSIGMA)) {
1370  if (!cpl_propertylist_has(properties, GIALIAS_RON)) {
1371  cpl_msg_error(fctid, "Missing detector read-out noise "
1372  "property (%s)!", GIALIAS_RON);
1373  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
1374 
1375  return 0.;
1376  }
1377  else {
1378 
1379  /*
1380  * Get default detector read-out noise. Note that this value
1381  * is already given in electrons. No conversion needed.
1382  */
1383 
1384  cpl_msg_warning(fctid, "Missing bias RMS property (%s)! "
1385  "Using detector read-out noise property (%s).",
1386  GIALIAS_BIASSIGMA, GIALIAS_RON);
1387  ron = cpl_propertylist_get_double(properties, GIALIAS_RON);
1388  }
1389  }
1390  else {
1391 
1392  cxdouble conad = 0.;
1393 
1394 
1395  /*
1396  * Get measured detector read-out noise. This is given in ADU and
1397  * has to be converted into electrons.
1398  */
1399 
1400  giraffe_error_push();
1401 
1402  conad = giraffe_propertylist_get_conad(properties);
1403 
1404  if (cpl_error_get_code() != CPL_ERROR_NONE) {
1405  return 0.;
1406  }
1407 
1408  giraffe_error_pop();
1409 
1410  ron = cpl_propertylist_get_double(properties, GIALIAS_BIASSIGMA) *
1411  conad;
1412 
1413  }
1414 
1415  return ron;
1416 
1417 }
void gi_warning(const cxchar *format,...)
Log a warning.
Definition: gimessages.c:127
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
Definition: giutils.c:306
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:587
cxdouble giraffe_propertylist_get_conad(const cpl_propertylist *properties)
Retrieve the ADU to electrons conversion factor from the given properties.
Definition: giutils.c:1274
cxint giraffe_propertylist_copy(cpl_propertylist *self, const cxchar *name, const cpl_propertylist *other, const cxchar *othername)
Copy a property from one list to another.
Definition: giutils.c:909
const cxchar * giraffe_get_license(void)
Get the pipeline copyright and license.
Definition: giutils.c:284
cxint giraffe_add_recipe_info(cpl_propertylist *plist, const GiRecipeInfo *info)
Add recipe specific information to a property list.
Definition: giutils.c:489
cxdouble giraffe_propertylist_get_ron(const cpl_propertylist *properties)
Retrieve the read-out noise from the given properties.
Definition: giutils.c:1358
cxint giraffe_propertylist_update(cpl_propertylist *self, cpl_propertylist *properties, const cxchar *regexp)
Update a property list.
Definition: giutils.c:818
cxchar * giraffe_path_get_basename(const cxchar *path)
Gets the name of a file without any leading directory components.
Definition: giutils.c:384
cxchar * giraffe_localtime_iso8601(void)
Get the current date and time in ISO 8601 format.
Definition: giutils.c:446

This file is part of the GIRAFFE Pipeline Reference Manual 2.14.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Wed Mar 11 2015 13:19:42 by doxygen 1.8.9.1 written by Dimitri van Heesch, © 1997-2004