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

This file is part of the GIRAFFE Pipeline Reference Manual 2.12.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Mon Mar 24 2014 11:43:53 by doxygen 1.8.2 written by Dimitri van Heesch, © 1997-2004