28 #include <cxmessages.h>
29 #include <cxstrutils.h>
36 #include "gipsfdata.h"
63 _giraffe_psfdata_compare(cxcptr s, cxcptr t)
66 return strcmp(s, t) < 0 ? TRUE : FALSE;
72 _giraffe_psfdata_clear(GiPsfData*
self)
75 if (self->model != NULL) {
76 cx_free((cxptr)self->model);
80 if (self->bins != NULL) {
81 cpl_image_delete(self->bins);
85 if (self->values != NULL) {
86 cx_map_clear(self->values);
100 _giraffe_psfdata_resize(GiPsfData*
self, cxint nfibers, cxint nbins,
101 cxint width, cxint height)
104 cx_assert(self->values != NULL);
106 self->nfibers = nfibers;
109 self->height = height;
111 if (self->bins != NULL) {
112 cpl_image_delete(self->bins);
116 if (cx_map_empty(self->values) == FALSE) {
117 cx_map_clear(self->values);
118 cx_assert(cx_map_empty(self->values));
127 _giraffe_psfdata_assign(GiPsfData*
self, cx_map* map,
const cxchar* name,
128 const cpl_image* values)
131 cx_map_iterator position = cx_map_find(map, name);
134 if (cpl_image_get_size_x(values) != self->nfibers) {
138 if (cpl_image_get_size_y(values) != self->nbins) {
142 if (position == cx_map_end(map)) {
143 cx_map_insert(map, cx_strdup(name), values);
147 cpl_image* previous = cx_map_assign(map, position, values);
149 if (previous != NULL) {
150 cpl_image_delete(previous);
162 _giraffe_psfdata_set(GiPsfData*
self, cx_map* map,
const cxchar* name,
163 cxint i, cxint j, cxdouble value)
166 cxdouble* data = NULL;
168 cx_map_const_iterator position = cx_map_find(map, name);
171 if (position == cx_map_end(map)) {
173 cpl_image* buffer = cpl_image_new(self->nfibers, self->nbins,
175 cx_map_insert(map, cx_strdup(name), buffer);
177 data = cpl_image_get_data(buffer);
182 data = cpl_image_get_data(cx_map_get_value(map, position));
186 data[
self->nfibers * j + i] = value;
194 _giraffe_psfdata_get(
const GiPsfData*
self,
const cx_map* map,
195 const cxchar* name, cxint i, cxint j, cxdouble* value)
198 cxdouble* data = NULL;
200 cx_map_const_iterator position = cx_map_find(map, name);
202 if (position == cx_map_end(map)) {
206 data = cpl_image_get_data(cx_map_get_value(map, position));
207 *value = data[
self->nfibers * j + i];
215 giraffe_psfdata_new(
void)
218 GiPsfData*
self = cx_calloc(1,
sizeof *
self);
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));
238 giraffe_psfdata_create(cxint nfibers, cxint nbins, cxint width, cxint height)
241 GiPsfData*
self = giraffe_psfdata_new();
243 self->nfibers = nfibers;
246 self->height = height;
250 self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
258 giraffe_psfdata_delete(GiPsfData*
self)
263 if (self->model != NULL) {
264 cx_free((cxptr)self->model);
268 if (self->bins != NULL) {
269 cpl_image_delete(self->bins);
273 if (self->values != NULL) {
274 cx_map_delete(self->values);
288 giraffe_psfdata_clear(GiPsfData*
self)
290 _giraffe_psfdata_clear(
self);
296 giraffe_psfdata_resize(GiPsfData*
self, cxint nfibers, cxint nbins,
297 cxint width, cxint height)
300 cx_assert(
self != NULL);
302 _giraffe_psfdata_resize(
self, nfibers, nbins, width, height);
303 self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
311 giraffe_psfdata_fibers(
const GiPsfData*
self)
314 cx_assert(
self != NULL);
315 return self->nfibers;
321 giraffe_psfdata_bins(
const GiPsfData*
self)
324 cx_assert(
self != NULL);
331 giraffe_psfdata_xsize(
const GiPsfData*
self)
334 cx_assert(
self != NULL);
341 giraffe_psfdata_ysize(
const GiPsfData*
self)
344 cx_assert(
self != NULL);
351 giraffe_psfdata_parameters(
const GiPsfData*
self)
354 cx_assert(
self != NULL);
355 return cx_map_size(self->values);
361 giraffe_psfdata_contains(
const GiPsfData*
self,
const cxchar* name)
364 cx_map_const_iterator position;
367 cx_assert(
self != NULL);
373 position = cx_map_find(self->values, name);
375 if (position == cx_map_end(self->values)) {
385 giraffe_psfdata_get_name(
const GiPsfData*
self, cxsize position)
388 const cxchar* name = NULL;
391 cx_assert(
self != NULL);
393 if (position < cx_map_size(self->values)) {
397 cx_map_const_iterator pos = cx_map_begin(self->values);
400 while (i < position) {
401 pos = cx_map_next(self->values, pos);
405 name = cx_map_get_key(self->values, pos);
415 giraffe_psfdata_set_model(GiPsfData*
self,
const cxchar* name)
418 cx_assert(
self != NULL);
424 if (self->model != NULL) {
425 cx_free((cxptr)self->model);
429 self->model = cx_strdup(name);
437 giraffe_psfdata_get_model(
const GiPsfData*
self)
440 cx_assert(
self != NULL);
447 giraffe_psfdata_set_bin(GiPsfData*
self, cxint fiber, cxint bin,
451 cxdouble* data = NULL;
454 cx_assert(
self != NULL);
456 if ((fiber < 0) || (fiber >= self->nfibers) ||
457 (bin < 0) || (bin >= self->nbins)) {
462 if (self->bins == NULL) {
463 self->bins = cpl_image_new(self->nfibers, self->nbins,
467 data = cpl_image_get_data_double(self->bins);
468 data[
self->nfibers * bin + fiber] = position;
478 giraffe_psfdata_get_bin(
const GiPsfData*
self, cxint fiber, cxint bin)
481 const cxchar*
const fctid =
"giraffe_psfdata_get_bin";
483 cxdouble* data = NULL;
486 cx_assert(
self != NULL);
488 if ((fiber < 0) || (fiber >= self->nfibers) ||
489 (bin < 0) || (bin >= self->nbins)) {
490 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
494 if (self->bins == NULL) {
496 GiPsfData* _self = (GiPsfData*)
self;
498 _self->bins = cpl_image_new(self->nfibers, self->nbins,
503 data = cpl_image_get_data_double(self->bins);
505 return data[
self->nfibers * bin + fiber];
511 giraffe_psfdata_get_bins(
const GiPsfData*
self)
513 cx_assert(
self != NULL);
519 giraffe_psfdata_set(GiPsfData*
self,
const cxchar* name, cxint fiber,
520 cxint bin, cxdouble value)
525 cx_assert(
self != NULL);
531 if (fiber >= self->nfibers) {
535 if (bin >= self->nbins) {
539 status = _giraffe_psfdata_set(
self, self->values, name, fiber, bin,
552 giraffe_psfdata_get(
const GiPsfData*
self,
const cxchar* name, cxint fiber,
556 const cxchar*
const fctid =
"giraffe_psfdata_get";
563 cx_assert(
self != NULL);
569 if (fiber >= self->nfibers) {
573 if (bin >= self->nbins) {
577 status = _giraffe_psfdata_get(
self, self->values, name, fiber, bin,
581 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
591 giraffe_psfdata_set_data(GiPsfData*
self,
const cxchar* name,
592 const cpl_image* data)
598 cx_assert(
self != NULL);
608 status = _giraffe_psfdata_assign(
self, self->values, name, data);
620 giraffe_psfdata_get_data(
const GiPsfData*
self,
const cxchar* name)
623 cx_assert(
self != NULL);
629 return cx_map_get(self->values, name);
634 cxint giraffe_psfdata_load(GiPsfData*
self,
const cxchar* filename)
637 const cxchar* model = NULL;
643 cxint nparameters = 0;
646 cxsize extension = 1;
648 cpl_propertylist* p = NULL;
651 if (
self == NULL || filename == NULL) {
655 giraffe_error_push();
657 p = cpl_propertylist_load(filename, 0);
663 if (cpl_propertylist_has(p, GIALIAS_PSFMODEL) == 0) {
667 model = cpl_propertylist_get_string(p, GIALIAS_PSFMODEL);
670 if (cpl_propertylist_has(p, GIALIAS_PSFNS) == 0) {
674 nfibers = cpl_propertylist_get_int(p, GIALIAS_PSFNS);
677 if (cpl_propertylist_has(p, GIALIAS_PSFXBINS) == 0) {
681 nbins = cpl_propertylist_get_int(p, GIALIAS_PSFXBINS);
684 if (cpl_propertylist_has(p, GIALIAS_PSFPRMS) == 0) {
688 nparameters = cpl_propertylist_get_int(p, GIALIAS_PSFPRMS);
691 if (cpl_propertylist_has(p, GIALIAS_PSFNX) == 0) {
695 nx = cpl_propertylist_get_int(p, GIALIAS_PSFNX);
698 if (cpl_propertylist_has(p, GIALIAS_PSFNY) == 0) {
702 ny = cpl_propertylist_get_int(p, GIALIAS_PSFNY);
705 if (cpl_error_get_code() != CPL_ERROR_NONE) {
708 cpl_propertylist_delete(p);
727 giraffe_psfdata_set_model(
self, model);
728 _giraffe_psfdata_resize(
self, nfibers, nbins, ny, nx);
730 cpl_propertylist_delete(p);
738 self->bins = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, extension);
740 if (self->bins == NULL) {
741 _giraffe_psfdata_clear(
self);
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);
759 for (i = extension; i < extension + nparameters; i++) {
761 cpl_image* buffer = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, i);
763 if (buffer == NULL) {
764 _giraffe_psfdata_clear(
self);
768 if ((cpl_image_get_size_x(buffer) != self->nfibers) ||
769 (cpl_image_get_size_y(buffer) != self->nbins)) {
771 cpl_image_delete(buffer);
774 _giraffe_psfdata_clear(
self);
776 cpl_image_delete(buffer);
782 const cxchar* name = NULL;
784 p = cpl_propertylist_load(filename, i);
788 cpl_image_delete(buffer);
795 if (cpl_propertylist_has(p, GIALIAS_EXTNAME) == 0) {
797 cpl_propertylist_delete(p);
800 cpl_image_delete(buffer);
807 name = cpl_propertylist_get_string(p, GIALIAS_EXTNAME);
808 cx_map_insert(self->values, cx_strdup(name), buffer);
810 cpl_propertylist_delete(p);
823 giraffe_psfdata_save(
const GiPsfData*
self, cpl_propertylist* properties,
824 const cxchar* filename, cxcptr data)
827 const cxchar*
const fctid =
"giraffe_psfdata_save";
829 cx_map_const_iterator position;
831 cpl_propertylist* p = NULL;
837 if (
self == NULL || properties == NULL || filename == NULL) {
841 cpl_propertylist_update_string(properties, GIALIAS_PSFMODEL,
843 cpl_propertylist_update_int(properties, GIALIAS_PSFPRMS,
844 cx_map_size(self->values));
845 cpl_propertylist_update_int(properties, GIALIAS_PSFXBINS,
847 cpl_propertylist_update_int(properties, GIALIAS_PSFNX,
849 cpl_propertylist_update_int(properties, GIALIAS_PSFNY,
851 cpl_propertylist_update_int(properties, GIALIAS_PSFNS,
854 cpl_propertylist_erase(properties,
"BSCALE");
855 cpl_propertylist_erase(properties,
"BZERO");
856 cpl_propertylist_erase(properties,
"BUNIT");
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);
863 cpl_propertylist_erase_regexp(properties,
"^DATA(MIN|MAX)", 0);
865 giraffe_error_push();
868 cpl_image_save(NULL, filename, CPL_BPP_IEEE_FLOAT,
869 properties, CPL_IO_DEFAULT);
871 if (cpl_error_get_code() != CPL_ERROR_NONE) {
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");
881 giraffe_error_push();
883 cpl_image_save(self->bins, filename, CPL_BPP_IEEE_FLOAT, p,
886 if (cpl_error_get_code() != CPL_ERROR_NONE) {
888 cpl_propertylist_delete(p);
896 position = cx_map_begin(self->values);
897 while (position != cx_map_end(self->values)) {
901 const cpl_image* psfdata = cx_map_get_value(self->values, position);
904 switch (cpl_image_get_type(psfdata)) {
906 format = CPL_BPP_32_SIGNED;
910 format = CPL_BPP_IEEE_FLOAT;
913 case CPL_TYPE_DOUBLE:
914 format = CPL_BPP_IEEE_FLOAT;
918 cpl_propertylist_delete(p);
921 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
927 giraffe_error_push();
929 cpl_propertylist_set_string(p, GIALIAS_EXTNAME,
930 cx_map_get_key(self->values, position));
932 cpl_image_save(psfdata, filename, format, p, CPL_IO_EXTEND);
934 if (cpl_error_get_code() != CPL_ERROR_NONE) {
935 cpl_propertylist_delete(p);
943 position = cx_map_next(self->values, position);
947 cpl_propertylist_delete(p);