GIRAFFE Pipeline Reference Manual

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

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004