GIRAFFE Pipeline Reference Manual

gipsfdata.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 #include <string.h>
33 
34 #include <cxtypes.h>
35 #include <cxmemory.h>
36 #include <cxmessages.h>
37 #include <cxstrutils.h>
38 #include <cxmap.h>
39 
40 #include <cpl_type.h>
41 
42 #include "gialias.h"
43 #include "gierror.h"
44 #include "gipsfdata.h"
45 
46 
47 /*
48  * @defgroup gipsfdata PSF Profile Data Storage
49  *
50  * TBD
51  */
52 
55 struct GiPsfData {
56 
57  const cxchar* model;
58 
59  cxint nfibers;
60  cxint nbins;
61  cxint width;
62  cxint height;
63 
64  cpl_image* bins;
65  cx_map* values;
66 
67 };
68 
69 
70 inline static cxbool
71 _giraffe_psfdata_compare(cxcptr s, cxcptr t)
72 {
73 
74  return strcmp(s, t) < 0 ? TRUE : FALSE;
75 
76 }
77 
78 
79 inline static void
80 _giraffe_psfdata_clear(GiPsfData* self)
81 {
82 
83  if (self->model != NULL) {
84  cx_free((cxptr)self->model);
85  self->model = NULL;
86  }
87 
88  if (self->bins != NULL) {
89  cpl_image_delete(self->bins);
90  self->bins = NULL;
91  }
92 
93  if (self->values != NULL) {
94  cx_map_clear(self->values);
95  }
96 
97  self->nfibers = 0;
98  self->nbins = 0;
99  self->width = 0;
100  self->height = 0;
101 
102  return;
103 
104 }
105 
106 
107 inline static void
108 _giraffe_psfdata_resize(GiPsfData* self, cxint nfibers, cxint nbins,
109  cxint width, cxint height)
110 {
111 
112  cx_assert(self->values != NULL);
113 
114  self->nfibers = nfibers;
115  self->nbins = nbins;
116  self->width = width;
117  self->height = height;
118 
119  if (self->bins != NULL) {
120  cpl_image_delete(self->bins);
121  self->bins = NULL;
122  }
123 
124  if (cx_map_empty(self->values) == FALSE) {
125  cx_map_clear(self->values);
126  cx_assert(cx_map_empty(self->values));
127  }
128 
129  return;
130 
131 }
132 
133 
134 inline static cxint
135 _giraffe_psfdata_assign(GiPsfData* self, cx_map* map, const cxchar* name,
136  const cpl_image* values)
137 {
138 
139  cx_map_iterator position = cx_map_find(map, name);
140 
141 
142  if (cpl_image_get_size_x(values) != self->nfibers) {
143  return 1;
144  }
145 
146  if (cpl_image_get_size_y(values) != self->nbins) {
147  return 2;
148  }
149 
150  if (position == cx_map_end(map)) {
151  cx_map_insert(map, cx_strdup(name), values);
152  }
153  else {
154 
155  cpl_image* previous = cx_map_assign(map, position, values);
156 
157  if (previous != NULL) {
158  cpl_image_delete(previous);
159  previous = NULL;
160  }
161 
162  }
163 
164  return 0;
165 
166 }
167 
168 
169 inline static cxint
170 _giraffe_psfdata_set(GiPsfData* self, cx_map* map, const cxchar* name,
171  cxint i, cxint j, cxdouble value)
172 {
173 
174  cxdouble* data = NULL;
175 
176  cx_map_const_iterator position = cx_map_find(map, name);
177 
178 
179  if (position == cx_map_end(map)) {
180 
181  cpl_image* buffer = cpl_image_new(self->nfibers, self->nbins,
182  CPL_TYPE_DOUBLE);
183  cx_map_insert(map, cx_strdup(name), buffer);
184 
185  data = cpl_image_get_data(buffer);
186 
187  }
188  else {
189 
190  data = cpl_image_get_data(cx_map_get_value(map, position));
191 
192  }
193 
194  data[self->nfibers * j + i] = value;
195 
196  return 0;
197 
198 }
199 
200 
201 inline static cxint
202 _giraffe_psfdata_get(const GiPsfData* self, const cx_map* map,
203  const cxchar* name, cxint i, cxint j, cxdouble* value)
204 {
205 
206  cxdouble* data = NULL;
207 
208  cx_map_const_iterator position = cx_map_find(map, name);
209 
210  if (position == cx_map_end(map)) {
211  return 1;
212  }
213 
214  data = cpl_image_get_data(cx_map_get_value(map, position));
215  *value = data[self->nfibers * j + i];
216 
217  return 0;
218 
219 }
220 
221 
222 GiPsfData*
223 giraffe_psfdata_new(void)
224 {
225 
226  GiPsfData* self = cx_calloc(1, sizeof *self);
227 
228  self->nfibers = 0;
229  self->nbins = 0;
230  self->width = 0;
231  self->height = 0;
232 
233  self->model = NULL;
234 
235  self->bins = NULL;
236  self->values = cx_map_new(_giraffe_psfdata_compare, cx_free,
237  (cx_free_func)cpl_image_delete);
238  cx_assert(cx_map_empty(self->values));
239 
240  return self;
241 
242 }
243 
244 
245 GiPsfData*
246 giraffe_psfdata_create(cxint nfibers, cxint nbins, cxint width, cxint height)
247 {
248 
249  GiPsfData* self = giraffe_psfdata_new();
250 
251  self->nfibers = nfibers;
252  self->nbins = nbins;
253  self->width = width;
254  self->height = height;
255 
256  self->model = NULL;
257 
258  self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
259 
260  return self;
261 
262 }
263 
264 
265 void
266 giraffe_psfdata_delete(GiPsfData* self)
267 {
268 
269  if (self != NULL) {
270 
271  if (self->model != NULL) {
272  cx_free((cxptr)self->model);
273  self->model = NULL;
274  }
275 
276  if (self->bins != NULL) {
277  cpl_image_delete(self->bins);
278  self->bins = NULL;
279  }
280 
281  if (self->values != NULL) {
282  cx_map_delete(self->values);
283  self->values = NULL;
284  }
285 
286  cx_free(self);
287 
288  }
289 
290  return;
291 
292 }
293 
294 
295 void
296 giraffe_psfdata_clear(GiPsfData* self)
297 {
298  _giraffe_psfdata_clear(self);
299  return;
300 }
301 
302 
303 void
304 giraffe_psfdata_resize(GiPsfData* self, cxint nfibers, cxint nbins,
305  cxint width, cxint height)
306 {
307 
308  cx_assert(self != NULL);
309 
310  _giraffe_psfdata_resize(self, nfibers, nbins, width, height);
311  self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
312 
313  return;
314 
315 }
316 
317 
318 cxsize
319 giraffe_psfdata_fibers(const GiPsfData* self)
320 {
321 
322  cx_assert(self != NULL);
323  return self->nfibers;
324 
325 }
326 
327 
328 cxsize
329 giraffe_psfdata_bins(const GiPsfData* self)
330 {
331 
332  cx_assert(self != NULL);
333  return self->nbins;
334 
335 }
336 
337 
338 cxsize
339 giraffe_psfdata_xsize(const GiPsfData* self)
340 {
341 
342  cx_assert(self != NULL);
343  return self->width;
344 
345 }
346 
347 
348 cxsize
349 giraffe_psfdata_ysize(const GiPsfData* self)
350 {
351 
352  cx_assert(self != NULL);
353  return self->height;
354 
355 }
356 
357 
358 cxsize
359 giraffe_psfdata_parameters(const GiPsfData* self)
360 {
361 
362  cx_assert(self != NULL);
363  return cx_map_size(self->values);
364 
365 }
366 
367 
368 cxbool
369 giraffe_psfdata_contains(const GiPsfData* self, const cxchar* name)
370 {
371 
372  cx_map_const_iterator position;
373 
374 
375  cx_assert(self != NULL);
376 
377  if (name == NULL) {
378  return FALSE;
379  }
380 
381  position = cx_map_find(self->values, name);
382 
383  if (position == cx_map_end(self->values)) {
384  return FALSE;
385  }
386 
387  return TRUE;
388 
389 }
390 
391 
392 const cxchar*
393 giraffe_psfdata_get_name(const GiPsfData* self, cxsize position)
394 {
395 
396  const cxchar* name = NULL;
397 
398 
399  cx_assert(self != NULL);
400 
401  if (position < cx_map_size(self->values)) {
402 
403  cxsize i = 0;
404 
405  cx_map_const_iterator pos = cx_map_begin(self->values);
406 
407 
408  while (i < position) {
409  pos = cx_map_next(self->values, pos);
410  ++i;
411  }
412 
413  name = cx_map_get_key(self->values, pos);
414 
415  }
416 
417  return name;
418 
419 }
420 
421 
422 cxint
423 giraffe_psfdata_set_model(GiPsfData* self, const cxchar* name)
424 {
425 
426  cx_assert(self != NULL);
427 
428  if (name == NULL) {
429  return 1;
430  }
431 
432  if (self->model != NULL) {
433  cx_free((cxptr)self->model);
434  self->model = NULL;
435  }
436 
437  self->model = cx_strdup(name);
438 
439  return 0;
440 
441 }
442 
443 
444 const cxchar*
445 giraffe_psfdata_get_model(const GiPsfData* self)
446 {
447 
448  cx_assert(self != NULL);
449  return self->model;
450 
451 }
452 
453 
454 cxint
455 giraffe_psfdata_set_bin(GiPsfData* self, cxint fiber, cxint bin,
456  cxdouble position)
457 {
458 
459  cxdouble* data = NULL;
460 
461 
462  cx_assert(self != NULL);
463 
464  if ((fiber < 0) || (fiber >= self->nfibers) ||
465  (bin < 0) || (bin >= self->nbins)) {
466  return 1;
467  }
468  else {
469 
470  if (self->bins == NULL) {
471  self->bins = cpl_image_new(self->nfibers, self->nbins,
472  CPL_TYPE_DOUBLE);
473  }
474 
475  data = cpl_image_get_data_double(self->bins);
476  data[self->nfibers * bin + fiber] = position;
477 
478  }
479 
480  return 0;
481 
482 }
483 
484 
485 cxdouble
486 giraffe_psfdata_get_bin(const GiPsfData* self, cxint fiber, cxint bin)
487 {
488 
489  const cxchar* const fctid = "giraffe_psfdata_get_bin";
490 
491  cxdouble* data = NULL;
492 
493 
494  cx_assert(self != NULL);
495 
496  if ((fiber < 0) || (fiber >= self->nfibers) ||
497  (bin < 0) || (bin >= self->nbins)) {
498  cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
499  return 0.;
500  }
501 
502  if (self->bins == NULL) {
503 
504  GiPsfData* _self = (GiPsfData*) self;
505 
506  _self->bins = cpl_image_new(self->nfibers, self->nbins,
507  CPL_TYPE_DOUBLE);
508 
509  }
510 
511  data = cpl_image_get_data_double(self->bins);
512 
513  return data[self->nfibers * bin + fiber];
514 
515 }
516 
517 
518 const cpl_image*
519 giraffe_psfdata_get_bins(const GiPsfData* self)
520 {
521  cx_assert(self != NULL);
522  return self->bins;
523 }
524 
525 
526 cxint
527 giraffe_psfdata_set(GiPsfData* self, const cxchar* name, cxint fiber,
528  cxint bin, cxdouble value)
529 {
530 
531  cxint status = 0;
532 
533  cx_assert(self != NULL);
534 
535  if (name == NULL) {
536  return 1;
537  }
538 
539  if (fiber >= self->nfibers) {
540  return 1;
541  }
542 
543  if (bin >= self->nbins) {
544  return 1;
545  }
546 
547  status = _giraffe_psfdata_set(self, self->values, name, fiber, bin,
548  value);
549 
550  if (status != 0) {
551  return 1;
552  }
553 
554  return 0;
555 
556 }
557 
558 
559 cxdouble
560 giraffe_psfdata_get(const GiPsfData* self, const cxchar* name, cxint fiber,
561  cxint bin)
562 {
563 
564  const cxchar* const fctid = "giraffe_psfdata_get";
565 
566  cxint status = 0;
567 
568  cxdouble value = 0.;
569 
570 
571  cx_assert(self != NULL);
572 
573  if (name == NULL) {
574  return 1;
575  }
576 
577  if (fiber >= self->nfibers) {
578  return 1;
579  }
580 
581  if (bin >= self->nbins) {
582  return 1;
583  }
584 
585  status = _giraffe_psfdata_get(self, self->values, name, fiber, bin,
586  &value);
587 
588  if (status != 0) {
589  cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
590  return 0.;
591  }
592 
593  return value;
594 
595 }
596 
597 
598 cxint
599 giraffe_psfdata_set_data(GiPsfData* self, const cxchar* name,
600  const cpl_image* data)
601 {
602 
603  cxint status = 0;
604 
605 
606  cx_assert(self != NULL);
607 
608  if (name == NULL) {
609  return 1;
610  }
611 
612  if (data == NULL) {
613  return 1;
614  }
615 
616  status = _giraffe_psfdata_assign(self, self->values, name, data);
617 
618  if (status != 0) {
619  return 1;
620  }
621 
622  return 0;
623 
624 }
625 
626 
627 const cpl_image*
628 giraffe_psfdata_get_data(const GiPsfData* self, const cxchar* name)
629 {
630 
631  cx_assert(self != NULL);
632 
633  if (name == NULL) {
634  return NULL;
635  }
636 
637  return cx_map_get(self->values, name);
638 
639 }
640 
641 
642 cxint giraffe_psfdata_load(GiPsfData* self, const cxchar* filename)
643 {
644 
645  const cxchar* model = NULL;
646 
647  cxint nfibers = 0;
648  cxint nbins = 0;
649  cxint nx = 0;
650  cxint ny = 0;
651  cxint nparameters = 0;
652 
653  cxsize i = 0;
654  cxsize extension = 1;
655 
656  cpl_propertylist* p = NULL;
657 
658 
659  if (self == NULL || filename == NULL) {
660  return -1;
661  }
662 
663  giraffe_error_push();
664 
665  p = cpl_propertylist_load(filename, 0);
666 
667  if (p == NULL) {
668  return 1;
669  }
670 
671  if (cpl_propertylist_has(p, GIALIAS_PSFMODEL) == 0) {
672  return 1;
673  }
674  else {
675  model = cpl_propertylist_get_string(p, GIALIAS_PSFMODEL);
676  }
677 
678  if (cpl_propertylist_has(p, GIALIAS_PSFNS) == 0) {
679  return 1;
680  }
681  else {
682  nfibers = cpl_propertylist_get_int(p, GIALIAS_PSFNS);
683  }
684 
685  if (cpl_propertylist_has(p, GIALIAS_PSFXBINS) == 0) {
686  return 1;
687  }
688  else {
689  nbins = cpl_propertylist_get_int(p, GIALIAS_PSFXBINS);
690  }
691 
692  if (cpl_propertylist_has(p, GIALIAS_PSFPRMS) == 0) {
693  return 1;
694  }
695  else {
696  nparameters = cpl_propertylist_get_int(p, GIALIAS_PSFPRMS);
697  }
698 
699  if (cpl_propertylist_has(p, GIALIAS_PSFNX) == 0) {
700  return 1;
701  }
702  else {
703  nx = cpl_propertylist_get_int(p, GIALIAS_PSFNX);
704  }
705 
706  if (cpl_propertylist_has(p, GIALIAS_PSFNY) == 0) {
707  return 1;
708  }
709  else {
710  ny = cpl_propertylist_get_int(p, GIALIAS_PSFNY);
711  }
712 
713  if (cpl_error_get_code() != CPL_ERROR_NONE) {
714 
715  if (p != NULL) {
716  cpl_propertylist_delete(p);
717  p = NULL;
718  }
719 
720  return 1;
721 
722  }
723 
724  giraffe_error_pop();
725 
726 
727  /*
728  * Prepare the psf data object. The model must be set before
729  * the property list is deallocated, since a reference is used!
730  *
731  * Note that the x-axis corresponds to the fibers, while the y-axis
732  * corresponds to the bins. Stick to OGL terminology.
733  */
734 
735  giraffe_psfdata_set_model(self, model);
736  _giraffe_psfdata_resize(self, nfibers, nbins, ny, nx);
737 
738  cpl_propertylist_delete(p);
739  p = NULL;
740 
741 
742  /*
743  * Load bin positions from the first extension.
744  */
745 
746  self->bins = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, extension);
747 
748  if (self->bins == NULL) {
749  _giraffe_psfdata_clear(self);
750  return 2;
751  }
752 
753  if ((cpl_image_get_size_x(self->bins) != self->nfibers) ||
754  (cpl_image_get_size_y(self->bins) != self->nbins)) {
755  _giraffe_psfdata_clear(self);
756  return 2;
757  }
758 
759  ++extension;
760 
761  /*
762  * Load the data buffers from the nparameters following extensions.
763  * The extension labels are used as names to look up the individual
764  * parameters.
765  */
766 
767  for (i = extension; i < extension + nparameters; i++) {
768 
769  cpl_image* buffer = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, i);
770 
771  if (buffer == NULL) {
772  _giraffe_psfdata_clear(self);
773  return 2;
774  }
775 
776  if ((cpl_image_get_size_x(buffer) != self->nfibers) ||
777  (cpl_image_get_size_y(buffer) != self->nbins)) {
778  _giraffe_psfdata_clear(self);
779  return 2;
780  }
781  else {
782 
783  const cxchar* name = NULL;
784 
785  p = cpl_propertylist_load(filename, i);
786 
787  if (p == NULL) {
788 
789  cpl_image_delete(buffer);
790  buffer = NULL;
791 
792  return 2;
793 
794  }
795 
796  if (cpl_propertylist_has(p, GIALIAS_EXTNAME) == 0) {
797 
798  cpl_propertylist_delete(p);
799  p = NULL;
800 
801  cpl_image_delete(buffer);
802  buffer = NULL;
803 
804  return 2;
805 
806  }
807 
808  name = cpl_propertylist_get_string(p, GIALIAS_EXTNAME);
809  cx_map_insert(self->values, cx_strdup(name), buffer);
810 
811  cpl_propertylist_delete(p);
812  p = NULL;
813 
814  }
815 
816  }
817 
818  return 0;
819 
820 }
821 
822 
823 cxint
824 giraffe_psfdata_save(const GiPsfData* self, cpl_propertylist* properties,
825  const cxchar* filename, cxcptr data)
826 {
827 
828  const cxchar* const fctid = "giraffe_psfdata_save";
829 
830  cx_map_const_iterator position;
831 
832  cpl_propertylist* p = NULL;
833 
834 
835  /* Unused */
836  data = NULL;
837 
838  if (self == NULL || properties == NULL || filename == NULL) {
839  return -1;
840  }
841 
842  cpl_propertylist_update_string(properties, GIALIAS_PSFMODEL,
843  self->model);
844  cpl_propertylist_update_int(properties, GIALIAS_PSFPRMS,
845  cx_map_size(self->values));
846  cpl_propertylist_update_int(properties, GIALIAS_PSFXBINS,
847  self->nbins);
848  cpl_propertylist_update_int(properties, GIALIAS_PSFNX,
849  self->height);
850  cpl_propertylist_update_int(properties, GIALIAS_PSFNY,
851  self->width);
852  cpl_propertylist_update_int(properties, GIALIAS_PSFNS,
853  self->nfibers);
854 
855  giraffe_error_push();
856 
857  cpl_image_save(NULL, filename, CPL_BPP_IEEE_FLOAT,
858  properties, CPL_IO_DEFAULT);
859 
860  if (cpl_error_get_code() != CPL_ERROR_NONE) {
861  return 1;
862  }
863 
864  giraffe_error_pop();
865 
866  p = cpl_propertylist_new();
867  cpl_propertylist_append_string(p, GIALIAS_EXTNAME, "Bin");
868  cpl_propertylist_set_comment(p, GIALIAS_EXTNAME, "FITS Extension name");
869 
870  giraffe_error_push();
871 
872  cpl_image_save(self->bins, filename, CPL_BPP_IEEE_FLOAT, p,
873  CPL_IO_EXTEND);
874 
875  if (cpl_error_get_code() != CPL_ERROR_NONE) {
876 
877  cpl_propertylist_delete(p);
878  p = NULL;
879 
880  return 1;
881  }
882 
883  giraffe_error_pop();
884 
885  position = cx_map_begin(self->values);
886  while (position != cx_map_end(self->values)) {
887 
888  cxint format = 0;
889 
890  const cpl_image* psfdata = cx_map_get_value(self->values, position);
891 
892 
893  switch (cpl_image_get_type(psfdata)) {
894  case CPL_TYPE_INT:
895  format = CPL_BPP_32_SIGNED;
896  break;
897 
898  case CPL_TYPE_FLOAT:
899  format = CPL_BPP_IEEE_FLOAT;
900  break;
901 
902  case CPL_TYPE_DOUBLE:
903  format = CPL_BPP_IEEE_FLOAT;
904  break;
905 
906  default:
907  cpl_propertylist_delete(p);
908  p = NULL;
909 
910  cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
911  return 2;
912 
913  break;
914  }
915 
916  giraffe_error_push();
917 
918  cpl_propertylist_set_string(p, GIALIAS_EXTNAME,
919  cx_map_get_key(self->values, position));
920 
921  cpl_image_save(psfdata, filename, format, p, CPL_IO_EXTEND);
922 
923  if (cpl_error_get_code() != CPL_ERROR_NONE) {
924  cpl_propertylist_delete(p);
925  p = NULL;
926 
927  return 2;
928  }
929 
930  giraffe_error_pop();
931 
932  position = cx_map_next(self->values, position);
933 
934  }
935 
936  cpl_propertylist_delete(p);
937  p = NULL;
938 
939  return 0;
940 
941 }

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:52 by doxygen 1.8.2 written by Dimitri van Heesch, © 1997-2004