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)) {
778 _giraffe_psfdata_clear(
self);
783 const cxchar* name = NULL;
785 p = cpl_propertylist_load(filename, i);
789 cpl_image_delete(buffer);
796 if (cpl_propertylist_has(p, GIALIAS_EXTNAME) == 0) {
798 cpl_propertylist_delete(p);
801 cpl_image_delete(buffer);
808 name = cpl_propertylist_get_string(p, GIALIAS_EXTNAME);
809 cx_map_insert(self->values, cx_strdup(name), buffer);
811 cpl_propertylist_delete(p);
824 giraffe_psfdata_save(
const GiPsfData*
self, cpl_propertylist* properties,
825 const cxchar* filename, cxcptr data)
828 const cxchar*
const fctid =
"giraffe_psfdata_save";
830 cx_map_const_iterator position;
832 cpl_propertylist* p = NULL;
838 if (
self == NULL || properties == NULL || filename == NULL) {
842 cpl_propertylist_update_string(properties, GIALIAS_PSFMODEL,
844 cpl_propertylist_update_int(properties, GIALIAS_PSFPRMS,
845 cx_map_size(self->values));
846 cpl_propertylist_update_int(properties, GIALIAS_PSFXBINS,
848 cpl_propertylist_update_int(properties, GIALIAS_PSFNX,
850 cpl_propertylist_update_int(properties, GIALIAS_PSFNY,
852 cpl_propertylist_update_int(properties, GIALIAS_PSFNS,
855 giraffe_error_push();
857 cpl_image_save(NULL, filename, CPL_BPP_IEEE_FLOAT,
858 properties, CPL_IO_DEFAULT);
860 if (cpl_error_get_code() != CPL_ERROR_NONE) {
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");
870 giraffe_error_push();
872 cpl_image_save(self->bins, filename, CPL_BPP_IEEE_FLOAT, p,
875 if (cpl_error_get_code() != CPL_ERROR_NONE) {
877 cpl_propertylist_delete(p);
885 position = cx_map_begin(self->values);
886 while (position != cx_map_end(self->values)) {
890 const cpl_image* psfdata = cx_map_get_value(self->values, position);
893 switch (cpl_image_get_type(psfdata)) {
895 format = CPL_BPP_32_SIGNED;
899 format = CPL_BPP_IEEE_FLOAT;
902 case CPL_TYPE_DOUBLE:
903 format = CPL_BPP_IEEE_FLOAT;
907 cpl_propertylist_delete(p);
910 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
916 giraffe_error_push();
918 cpl_propertylist_set_string(p, GIALIAS_EXTNAME,
919 cx_map_get_key(self->values, position));
921 cpl_image_save(psfdata, filename, format, p, CPL_IO_EXTEND);
923 if (cpl_error_get_code() != CPL_ERROR_NONE) {
924 cpl_propertylist_delete(p);
932 position = cx_map_next(self->values, position);
936 cpl_propertylist_delete(p);