36 #include <cxmessages.h>
37 #include <cxstrutils.h>
44 #include "gipsfdata.h"
71 _giraffe_psfdata_compare(cxcptr s, cxcptr t)
74 return strcmp(s, t) < 0 ? TRUE : FALSE;
80 _giraffe_psfdata_clear(GiPsfData*
self)
83 if (self->model != NULL) {
84 cx_free((cxptr)self->model);
88 if (self->bins != NULL) {
89 cpl_image_delete(self->bins);
93 if (self->values != NULL) {
94 cx_map_clear(self->values);
108 _giraffe_psfdata_resize(GiPsfData*
self, cxint nfibers, cxint nbins,
109 cxint width, cxint height)
112 cx_assert(self->values != NULL);
114 self->nfibers = nfibers;
117 self->height = height;
119 if (self->bins != NULL) {
120 cpl_image_delete(self->bins);
124 if (cx_map_empty(self->values) == FALSE) {
125 cx_map_clear(self->values);
126 cx_assert(cx_map_empty(self->values));
135 _giraffe_psfdata_assign(GiPsfData*
self, cx_map* map,
const cxchar* name,
136 const cpl_image* values)
139 cx_map_iterator position = cx_map_find(map, name);
142 if (cpl_image_get_size_x(values) != self->nfibers) {
146 if (cpl_image_get_size_y(values) != self->nbins) {
150 if (position == cx_map_end(map)) {
151 cx_map_insert(map, cx_strdup(name), values);
155 cpl_image* previous = cx_map_assign(map, position, values);
157 if (previous != NULL) {
158 cpl_image_delete(previous);
170 _giraffe_psfdata_set(GiPsfData*
self, cx_map* map,
const cxchar* name,
171 cxint i, cxint j, cxdouble value)
174 cxdouble* data = NULL;
176 cx_map_const_iterator position = cx_map_find(map, name);
179 if (position == cx_map_end(map)) {
181 cpl_image* buffer = cpl_image_new(self->nfibers, self->nbins,
183 cx_map_insert(map, cx_strdup(name), buffer);
185 data = cpl_image_get_data(buffer);
190 data = cpl_image_get_data(cx_map_get_value(map, position));
194 data[
self->nfibers * j + i] = value;
202 _giraffe_psfdata_get(
const GiPsfData*
self,
const cx_map* map,
203 const cxchar* name, cxint i, cxint j, cxdouble* value)
206 cxdouble* data = NULL;
208 cx_map_const_iterator position = cx_map_find(map, name);
210 if (position == cx_map_end(map)) {
214 data = cpl_image_get_data(cx_map_get_value(map, position));
215 *value = data[
self->nfibers * j + i];
223 giraffe_psfdata_new(
void)
226 GiPsfData*
self = cx_calloc(1,
sizeof *
self);
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));
246 giraffe_psfdata_create(cxint nfibers, cxint nbins, cxint width, cxint height)
249 GiPsfData*
self = giraffe_psfdata_new();
251 self->nfibers = nfibers;
254 self->height = height;
258 self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
266 giraffe_psfdata_delete(GiPsfData*
self)
271 if (self->model != NULL) {
272 cx_free((cxptr)self->model);
276 if (self->bins != NULL) {
277 cpl_image_delete(self->bins);
281 if (self->values != NULL) {
282 cx_map_delete(self->values);
296 giraffe_psfdata_clear(GiPsfData*
self)
298 _giraffe_psfdata_clear(
self);
304 giraffe_psfdata_resize(GiPsfData*
self, cxint nfibers, cxint nbins,
305 cxint width, cxint height)
308 cx_assert(
self != NULL);
310 _giraffe_psfdata_resize(
self, nfibers, nbins, width, height);
311 self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
319 giraffe_psfdata_fibers(
const GiPsfData*
self)
322 cx_assert(
self != NULL);
323 return self->nfibers;
329 giraffe_psfdata_bins(
const GiPsfData*
self)
332 cx_assert(
self != NULL);
339 giraffe_psfdata_xsize(
const GiPsfData*
self)
342 cx_assert(
self != NULL);
349 giraffe_psfdata_ysize(
const GiPsfData*
self)
352 cx_assert(
self != NULL);
359 giraffe_psfdata_parameters(
const GiPsfData*
self)
362 cx_assert(
self != NULL);
363 return cx_map_size(self->values);
369 giraffe_psfdata_contains(
const GiPsfData*
self,
const cxchar* name)
372 cx_map_const_iterator position;
375 cx_assert(
self != NULL);
381 position = cx_map_find(self->values, name);
383 if (position == cx_map_end(self->values)) {
393 giraffe_psfdata_get_name(
const GiPsfData*
self, cxsize position)
396 const cxchar* name = NULL;
399 cx_assert(
self != NULL);
401 if (position < cx_map_size(self->values)) {
405 cx_map_const_iterator pos = cx_map_begin(self->values);
408 while (i < position) {
409 pos = cx_map_next(self->values, pos);
413 name = cx_map_get_key(self->values, pos);
423 giraffe_psfdata_set_model(GiPsfData*
self,
const cxchar* name)
426 cx_assert(
self != NULL);
432 if (self->model != NULL) {
433 cx_free((cxptr)self->model);
437 self->model = cx_strdup(name);
445 giraffe_psfdata_get_model(
const GiPsfData*
self)
448 cx_assert(
self != NULL);
455 giraffe_psfdata_set_bin(GiPsfData*
self, cxint fiber, cxint bin,
459 cxdouble* data = NULL;
462 cx_assert(
self != NULL);
464 if ((fiber < 0) || (fiber >= self->nfibers) ||
465 (bin < 0) || (bin >= self->nbins)) {
470 if (self->bins == NULL) {
471 self->bins = cpl_image_new(self->nfibers, self->nbins,
475 data = cpl_image_get_data_double(self->bins);
476 data[
self->nfibers * bin + fiber] = position;
486 giraffe_psfdata_get_bin(
const GiPsfData*
self, cxint fiber, cxint bin)
489 const cxchar*
const fctid =
"giraffe_psfdata_get_bin";
491 cxdouble* data = NULL;
494 cx_assert(
self != NULL);
496 if ((fiber < 0) || (fiber >= self->nfibers) ||
497 (bin < 0) || (bin >= self->nbins)) {
498 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
502 if (self->bins == NULL) {
504 GiPsfData* _self = (GiPsfData*)
self;
506 _self->bins = cpl_image_new(self->nfibers, self->nbins,
511 data = cpl_image_get_data_double(self->bins);
513 return data[
self->nfibers * bin + fiber];
519 giraffe_psfdata_get_bins(
const GiPsfData*
self)
521 cx_assert(
self != NULL);
527 giraffe_psfdata_set(GiPsfData*
self,
const cxchar* name, cxint fiber,
528 cxint bin, cxdouble value)
533 cx_assert(
self != NULL);
539 if (fiber >= self->nfibers) {
543 if (bin >= self->nbins) {
547 status = _giraffe_psfdata_set(
self, self->values, name, fiber, bin,
560 giraffe_psfdata_get(
const GiPsfData*
self,
const cxchar* name, cxint fiber,
564 const cxchar*
const fctid =
"giraffe_psfdata_get";
571 cx_assert(
self != NULL);
577 if (fiber >= self->nfibers) {
581 if (bin >= self->nbins) {
585 status = _giraffe_psfdata_get(
self, self->values, name, fiber, bin,
589 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
599 giraffe_psfdata_set_data(GiPsfData*
self,
const cxchar* name,
600 const cpl_image* data)
606 cx_assert(
self != NULL);
616 status = _giraffe_psfdata_assign(
self, self->values, name, data);
628 giraffe_psfdata_get_data(
const GiPsfData*
self,
const cxchar* name)
631 cx_assert(
self != NULL);
637 return cx_map_get(self->values, name);
642 cxint giraffe_psfdata_load(GiPsfData*
self,
const cxchar* filename)
645 const cxchar* model = NULL;
651 cxint nparameters = 0;
654 cxsize extension = 1;
656 cpl_propertylist* p = NULL;
659 if (
self == NULL || filename == NULL) {
663 giraffe_error_push();
665 p = cpl_propertylist_load(filename, 0);
671 if (cpl_propertylist_has(p, GIALIAS_PSFMODEL) == 0) {
675 model = cpl_propertylist_get_string(p, GIALIAS_PSFMODEL);
678 if (cpl_propertylist_has(p, GIALIAS_PSFNS) == 0) {
682 nfibers = cpl_propertylist_get_int(p, GIALIAS_PSFNS);
685 if (cpl_propertylist_has(p, GIALIAS_PSFXBINS) == 0) {
689 nbins = cpl_propertylist_get_int(p, GIALIAS_PSFXBINS);
692 if (cpl_propertylist_has(p, GIALIAS_PSFPRMS) == 0) {
696 nparameters = cpl_propertylist_get_int(p, GIALIAS_PSFPRMS);
699 if (cpl_propertylist_has(p, GIALIAS_PSFNX) == 0) {
703 nx = cpl_propertylist_get_int(p, GIALIAS_PSFNX);
706 if (cpl_propertylist_has(p, GIALIAS_PSFNY) == 0) {
710 ny = cpl_propertylist_get_int(p, GIALIAS_PSFNY);
713 if (cpl_error_get_code() != CPL_ERROR_NONE) {
716 cpl_propertylist_delete(p);
735 giraffe_psfdata_set_model(
self, model);
736 _giraffe_psfdata_resize(
self, nfibers, nbins, ny, nx);
738 cpl_propertylist_delete(p);
746 self->bins = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, extension);
748 if (self->bins == NULL) {
749 _giraffe_psfdata_clear(
self);
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);
767 for (i = extension; i < extension + nparameters; i++) {
769 cpl_image* buffer = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, i);
771 if (buffer == NULL) {
772 _giraffe_psfdata_clear(
self);
776 if ((cpl_image_get_size_x(buffer) != self->nfibers) ||
777 (cpl_image_get_size_y(buffer) != self->nbins)) {
779 cpl_image_delete(buffer);
782 _giraffe_psfdata_clear(
self);
784 cpl_image_delete(buffer);
790 const cxchar* name = NULL;
792 p = cpl_propertylist_load(filename, i);
796 cpl_image_delete(buffer);
803 if (cpl_propertylist_has(p, GIALIAS_EXTNAME) == 0) {
805 cpl_propertylist_delete(p);
808 cpl_image_delete(buffer);
815 name = cpl_propertylist_get_string(p, GIALIAS_EXTNAME);
816 cx_map_insert(self->values, cx_strdup(name), buffer);
818 cpl_propertylist_delete(p);
831 giraffe_psfdata_save(
const GiPsfData*
self, cpl_propertylist* properties,
832 const cxchar* filename, cxcptr data)
835 const cxchar*
const fctid =
"giraffe_psfdata_save";
837 cx_map_const_iterator position;
839 cpl_propertylist* p = NULL;
845 if (
self == NULL || properties == NULL || filename == NULL) {
849 cpl_propertylist_update_string(properties, GIALIAS_PSFMODEL,
851 cpl_propertylist_update_int(properties, GIALIAS_PSFPRMS,
852 cx_map_size(self->values));
853 cpl_propertylist_update_int(properties, GIALIAS_PSFXBINS,
855 cpl_propertylist_update_int(properties, GIALIAS_PSFNX,
857 cpl_propertylist_update_int(properties, GIALIAS_PSFNY,
859 cpl_propertylist_update_int(properties, GIALIAS_PSFNS,
862 cpl_propertylist_erase(properties,
"BSCALE");
863 cpl_propertylist_erase(properties,
"BZERO");
864 cpl_propertylist_erase(properties,
"BUNIT");
866 cpl_propertylist_erase_regexp(properties,
"^CRPIX[0-9]$", 0);
867 cpl_propertylist_erase_regexp(properties,
"^CRVAL[0-9]$", 0);
868 cpl_propertylist_erase_regexp(properties,
"^CDELT[0-9]$", 0);
869 cpl_propertylist_erase_regexp(properties,
"^CTYPE[0-9]$", 0);
871 cpl_propertylist_erase_regexp(properties,
"^DATA(MIN|MAX)", 0);
873 giraffe_error_push();
876 cpl_image_save(NULL, filename, CPL_BPP_IEEE_FLOAT,
877 properties, CPL_IO_DEFAULT);
879 if (cpl_error_get_code() != CPL_ERROR_NONE) {
885 p = cpl_propertylist_new();
886 cpl_propertylist_append_string(p, GIALIAS_EXTNAME,
"Bin");
887 cpl_propertylist_set_comment(p, GIALIAS_EXTNAME,
"FITS Extension name");
889 giraffe_error_push();
891 cpl_image_save(self->bins, filename, CPL_BPP_IEEE_FLOAT, p,
894 if (cpl_error_get_code() != CPL_ERROR_NONE) {
896 cpl_propertylist_delete(p);
904 position = cx_map_begin(self->values);
905 while (position != cx_map_end(self->values)) {
909 const cpl_image* psfdata = cx_map_get_value(self->values, position);
912 switch (cpl_image_get_type(psfdata)) {
914 format = CPL_BPP_32_SIGNED;
918 format = CPL_BPP_IEEE_FLOAT;
921 case CPL_TYPE_DOUBLE:
922 format = CPL_BPP_IEEE_FLOAT;
926 cpl_propertylist_delete(p);
929 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
935 giraffe_error_push();
937 cpl_propertylist_set_string(p, GIALIAS_EXTNAME,
938 cx_map_get_key(self->values, position));
940 cpl_image_save(psfdata, filename, format, p, CPL_IO_EXTEND);
942 if (cpl_error_get_code() != CPL_ERROR_NONE) {
943 cpl_propertylist_delete(p);
951 position = cx_map_next(self->values, position);
955 cpl_propertylist_delete(p);