00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 # include <config.h>
00030 #endif
00031
00032 #include <string.h>
00033
00034 #include <cxtypes.h>
00035 #include <cxmemory.h>
00036 #include <cxmessages.h>
00037 #include <cxstrutils.h>
00038 #include <cxmap.h>
00039
00040 #include <cpl_type.h>
00041
00042 #include "gialias.h"
00043 #include "gierror.h"
00044 #include "gipsfdata.h"
00045
00046
00047
00048
00049
00050
00051
00052
00055 struct GiPsfData {
00056
00057 const cxchar* model;
00058
00059 cxint nfibers;
00060 cxint nbins;
00061 cxint width;
00062 cxint height;
00063
00064 cpl_image* bins;
00065 cx_map* values;
00066
00067 };
00068
00069
00070 inline static cxbool
00071 _giraffe_psfdata_compare(cxcptr s, cxcptr t)
00072 {
00073
00074 return strcmp(s, t) < 0 ? TRUE : FALSE;
00075
00076 }
00077
00078
00079 inline static void
00080 _giraffe_psfdata_clear(GiPsfData* self)
00081 {
00082
00083 if (self->model != NULL) {
00084 cx_free((cxptr)self->model);
00085 self->model = NULL;
00086 }
00087
00088 if (self->bins != NULL) {
00089 cpl_image_delete(self->bins);
00090 self->bins = NULL;
00091 }
00092
00093 if (self->values != NULL) {
00094 cx_map_clear(self->values);
00095 }
00096
00097 self->nfibers = 0;
00098 self->nbins = 0;
00099 self->width = 0;
00100 self->height = 0;
00101
00102 return;
00103
00104 }
00105
00106
00107 inline static void
00108 _giraffe_psfdata_resize(GiPsfData* self, cxint nfibers, cxint nbins,
00109 cxint width, cxint height)
00110 {
00111
00112 cx_assert(self->values != NULL);
00113
00114 self->nfibers = nfibers;
00115 self->nbins = nbins;
00116 self->width = width;
00117 self->height = height;
00118
00119 if (self->bins != NULL) {
00120 cpl_image_delete(self->bins);
00121 self->bins = NULL;
00122 }
00123
00124 if (cx_map_empty(self->values) == FALSE) {
00125 cx_map_clear(self->values);
00126 cx_assert(cx_map_empty(self->values));
00127 }
00128
00129 return;
00130
00131 }
00132
00133
00134 inline static cxint
00135 _giraffe_psfdata_assign(GiPsfData* self, cx_map* map, const cxchar* name,
00136 const cpl_image* values)
00137 {
00138
00139 cx_map_iterator position = cx_map_find(map, name);
00140
00141
00142 if (cpl_image_get_size_x(values) != self->nfibers) {
00143 return 1;
00144 }
00145
00146 if (cpl_image_get_size_y(values) != self->nbins) {
00147 return 2;
00148 }
00149
00150 if (position == cx_map_end(map)) {
00151 cx_map_insert(map, cx_strdup(name), values);
00152 }
00153 else {
00154
00155 cpl_image* previous = cx_map_assign(map, position, values);
00156
00157 if (previous != NULL) {
00158 cpl_image_delete(previous);
00159 previous = NULL;
00160 }
00161
00162 }
00163
00164 return 0;
00165
00166 }
00167
00168
00169 inline static cxint
00170 _giraffe_psfdata_set(GiPsfData* self, cx_map* map, const cxchar* name,
00171 cxint i, cxint j, cxdouble value)
00172 {
00173
00174 cxdouble* data = NULL;
00175
00176 cx_map_const_iterator position = cx_map_find(map, name);
00177
00178
00179 if (position == cx_map_end(map)) {
00180
00181 cpl_image* buffer = cpl_image_new(self->nfibers, self->nbins,
00182 CPL_TYPE_DOUBLE);
00183 cx_map_insert(map, cx_strdup(name), buffer);
00184
00185 data = cpl_image_get_data(buffer);
00186
00187 }
00188 else {
00189
00190 data = cpl_image_get_data(cx_map_get_value(map, position));
00191
00192 }
00193
00194 data[self->nfibers * j + i] = value;
00195
00196 return 0;
00197
00198 }
00199
00200
00201 inline static cxint
00202 _giraffe_psfdata_get(const GiPsfData* self, const cx_map* map,
00203 const cxchar* name, cxint i, cxint j, cxdouble* value)
00204 {
00205
00206 cxdouble* data = NULL;
00207
00208 cx_map_const_iterator position = cx_map_find(map, name);
00209
00210 if (position == cx_map_end(map)) {
00211 return 1;
00212 }
00213
00214 data = cpl_image_get_data(cx_map_get_value(map, position));
00215 *value = data[self->nfibers * j + i];
00216
00217 return 0;
00218
00219 }
00220
00221
00222 GiPsfData*
00223 giraffe_psfdata_new(void)
00224 {
00225
00226 GiPsfData* self = cx_calloc(1, sizeof *self);
00227
00228 self->nfibers = 0;
00229 self->nbins = 0;
00230 self->width = 0;
00231 self->height = 0;
00232
00233 self->model = NULL;
00234
00235 self->bins = NULL;
00236 self->values = cx_map_new(_giraffe_psfdata_compare, cx_free,
00237 (cx_free_func)cpl_image_delete);
00238 cx_assert(cx_map_empty(self->values));
00239
00240 return self;
00241
00242 }
00243
00244
00245 GiPsfData*
00246 giraffe_psfdata_create(cxint nfibers, cxint nbins, cxint width, cxint height)
00247 {
00248
00249 GiPsfData* self = giraffe_psfdata_new();
00250
00251 self->nfibers = nfibers;
00252 self->nbins = nbins;
00253 self->width = width;
00254 self->height = height;
00255
00256 self->model = NULL;
00257
00258 self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
00259
00260 return self;
00261
00262 }
00263
00264
00265 void
00266 giraffe_psfdata_delete(GiPsfData* self)
00267 {
00268
00269 if (self != NULL) {
00270
00271 if (self->model != NULL) {
00272 cx_free((cxptr)self->model);
00273 self->model = NULL;
00274 }
00275
00276 if (self->bins != NULL) {
00277 cpl_image_delete(self->bins);
00278 self->bins = NULL;
00279 }
00280
00281 if (self->values != NULL) {
00282 cx_map_delete(self->values);
00283 self->values = NULL;
00284 }
00285
00286 cx_free(self);
00287
00288 }
00289
00290 return;
00291
00292 }
00293
00294
00295 void
00296 giraffe_psfdata_clear(GiPsfData* self)
00297 {
00298 _giraffe_psfdata_clear(self);
00299 return;
00300 }
00301
00302
00303 void
00304 giraffe_psfdata_resize(GiPsfData* self, cxint nfibers, cxint nbins,
00305 cxint width, cxint height)
00306 {
00307
00308 cx_assert(self != NULL);
00309
00310 _giraffe_psfdata_resize(self, nfibers, nbins, width, height);
00311 self->bins = cpl_image_new(self->nfibers, self->nbins, CPL_TYPE_DOUBLE);
00312
00313 return;
00314
00315 }
00316
00317
00318 cxsize
00319 giraffe_psfdata_fibers(const GiPsfData* self)
00320 {
00321
00322 cx_assert(self != NULL);
00323 return self->nfibers;
00324
00325 }
00326
00327
00328 cxsize
00329 giraffe_psfdata_bins(const GiPsfData* self)
00330 {
00331
00332 cx_assert(self != NULL);
00333 return self->nbins;
00334
00335 }
00336
00337
00338 cxsize
00339 giraffe_psfdata_xsize(const GiPsfData* self)
00340 {
00341
00342 cx_assert(self != NULL);
00343 return self->width;
00344
00345 }
00346
00347
00348 cxsize
00349 giraffe_psfdata_ysize(const GiPsfData* self)
00350 {
00351
00352 cx_assert(self != NULL);
00353 return self->height;
00354
00355 }
00356
00357
00358 cxsize
00359 giraffe_psfdata_parameters(const GiPsfData* self)
00360 {
00361
00362 cx_assert(self != NULL);
00363 return cx_map_size(self->values);
00364
00365 }
00366
00367
00368 cxbool
00369 giraffe_psfdata_contains(const GiPsfData* self, const cxchar* name)
00370 {
00371
00372 cx_map_const_iterator position;
00373
00374
00375 cx_assert(self != NULL);
00376
00377 if (name == NULL) {
00378 return FALSE;
00379 }
00380
00381 position = cx_map_find(self->values, name);
00382
00383 if (position == cx_map_end(self->values)) {
00384 return FALSE;
00385 }
00386
00387 return TRUE;
00388
00389 }
00390
00391
00392 const cxchar*
00393 giraffe_psfdata_get_name(const GiPsfData* self, cxsize position)
00394 {
00395
00396 const cxchar* name = NULL;
00397
00398
00399 cx_assert(self != NULL);
00400
00401 if (position < cx_map_size(self->values)) {
00402
00403 cxsize i = 0;
00404
00405 cx_map_const_iterator pos = cx_map_begin(self->values);
00406
00407
00408 while (i < position) {
00409 pos = cx_map_next(self->values, pos);
00410 ++i;
00411 }
00412
00413 name = cx_map_get_key(self->values, pos);
00414
00415 }
00416
00417 return name;
00418
00419 }
00420
00421
00422 cxint
00423 giraffe_psfdata_set_model(GiPsfData* self, const cxchar* name)
00424 {
00425
00426 cx_assert(self != NULL);
00427
00428 if (name == NULL) {
00429 return 1;
00430 }
00431
00432 if (self->model != NULL) {
00433 cx_free((cxptr)self->model);
00434 self->model = NULL;
00435 }
00436
00437 self->model = cx_strdup(name);
00438
00439 return 0;
00440
00441 }
00442
00443
00444 const cxchar*
00445 giraffe_psfdata_get_model(const GiPsfData* self)
00446 {
00447
00448 cx_assert(self != NULL);
00449 return self->model;
00450
00451 }
00452
00453
00454 cxint
00455 giraffe_psfdata_set_bin(GiPsfData* self, cxint fiber, cxint bin,
00456 cxdouble position)
00457 {
00458
00459 cxdouble* data = NULL;
00460
00461
00462 cx_assert(self != NULL);
00463
00464 if ((fiber < 0) || (fiber >= self->nfibers) ||
00465 (bin < 0) || (bin >= self->nbins)) {
00466 return 1;
00467 }
00468 else {
00469
00470 if (self->bins == NULL) {
00471 self->bins = cpl_image_new(self->nfibers, self->nbins,
00472 CPL_TYPE_DOUBLE);
00473 }
00474
00475 data = cpl_image_get_data_double(self->bins);
00476 data[self->nfibers * bin + fiber] = position;
00477
00478 }
00479
00480 return 0;
00481
00482 }
00483
00484
00485 cxdouble
00486 giraffe_psfdata_get_bin(const GiPsfData* self, cxint fiber, cxint bin)
00487 {
00488
00489 const cxchar* const fctid = "giraffe_psfdata_get_bin";
00490
00491 cxdouble* data = NULL;
00492
00493
00494 cx_assert(self != NULL);
00495
00496 if ((fiber < 0) || (fiber >= self->nfibers) ||
00497 (bin < 0) || (bin >= self->nbins)) {
00498 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00499 return 0.;
00500 }
00501
00502 if (self->bins == NULL) {
00503
00504 GiPsfData* _self = (GiPsfData*) self;
00505
00506 _self->bins = cpl_image_new(self->nfibers, self->nbins,
00507 CPL_TYPE_DOUBLE);
00508
00509 }
00510
00511 data = cpl_image_get_data_double(self->bins);
00512
00513 return data[self->nfibers * bin + fiber];
00514
00515 }
00516
00517
00518 const cpl_image*
00519 giraffe_psfdata_get_bins(const GiPsfData* self)
00520 {
00521 cx_assert(self != NULL);
00522 return self->bins;
00523 }
00524
00525
00526 cxint
00527 giraffe_psfdata_set(GiPsfData* self, const cxchar* name, cxint fiber,
00528 cxint bin, cxdouble value)
00529 {
00530
00531 cxint status = 0;
00532
00533 cx_assert(self != NULL);
00534
00535 if (name == NULL) {
00536 return 1;
00537 }
00538
00539 if (fiber >= self->nfibers) {
00540 return 1;
00541 }
00542
00543 if (bin >= self->nbins) {
00544 return 1;
00545 }
00546
00547 status = _giraffe_psfdata_set(self, self->values, name, fiber, bin,
00548 value);
00549
00550 if (status != 0) {
00551 return 1;
00552 }
00553
00554 return 0;
00555
00556 }
00557
00558
00559 cxdouble
00560 giraffe_psfdata_get(const GiPsfData* self, const cxchar* name, cxint fiber,
00561 cxint bin)
00562 {
00563
00564 const cxchar* const fctid = "giraffe_psfdata_get";
00565
00566 cxint status = 0;
00567
00568 cxdouble value = 0.;
00569
00570
00571 cx_assert(self != NULL);
00572
00573 if (name == NULL) {
00574 return 1;
00575 }
00576
00577 if (fiber >= self->nfibers) {
00578 return 1;
00579 }
00580
00581 if (bin >= self->nbins) {
00582 return 1;
00583 }
00584
00585 status = _giraffe_psfdata_get(self, self->values, name, fiber, bin,
00586 &value);
00587
00588 if (status != 0) {
00589 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00590 return 0.;
00591 }
00592
00593 return value;
00594
00595 }
00596
00597
00598 cxint
00599 giraffe_psfdata_set_data(GiPsfData* self, const cxchar* name,
00600 const cpl_image* data)
00601 {
00602
00603 cxint status = 0;
00604
00605
00606 cx_assert(self != NULL);
00607
00608 if (name == NULL) {
00609 return 1;
00610 }
00611
00612 if (data == NULL) {
00613 return 1;
00614 }
00615
00616 status = _giraffe_psfdata_assign(self, self->values, name, data);
00617
00618 if (status != 0) {
00619 return 1;
00620 }
00621
00622 return 0;
00623
00624 }
00625
00626
00627 const cpl_image*
00628 giraffe_psfdata_get_data(const GiPsfData* self, const cxchar* name)
00629 {
00630
00631 cx_assert(self != NULL);
00632
00633 if (name == NULL) {
00634 return NULL;
00635 }
00636
00637 return cx_map_get(self->values, name);
00638
00639 }
00640
00641
00642 cxint giraffe_psfdata_load(GiPsfData* self, const cxchar* filename)
00643 {
00644
00645 const cxchar* model = NULL;
00646
00647 cxint nfibers = 0;
00648 cxint nbins = 0;
00649 cxint nx = 0;
00650 cxint ny = 0;
00651 cxint nparameters = 0;
00652
00653 cxsize i = 0;
00654 cxsize extension = 1;
00655
00656 cpl_propertylist* p = NULL;
00657
00658
00659 if (self == NULL || filename == NULL) {
00660 return -1;
00661 }
00662
00663 giraffe_error_push();
00664
00665 p = cpl_propertylist_load(filename, 0);
00666
00667 if (p == NULL) {
00668 return 1;
00669 }
00670
00671 if (cpl_propertylist_has(p, GIALIAS_PSFMODEL) == 0) {
00672 return 1;
00673 }
00674 else {
00675 model = cpl_propertylist_get_string(p, GIALIAS_PSFMODEL);
00676 }
00677
00678 if (cpl_propertylist_has(p, GIALIAS_PSFNS) == 0) {
00679 return 1;
00680 }
00681 else {
00682 nfibers = cpl_propertylist_get_int(p, GIALIAS_PSFNS);
00683 }
00684
00685 if (cpl_propertylist_has(p, GIALIAS_PSFXBINS) == 0) {
00686 return 1;
00687 }
00688 else {
00689 nbins = cpl_propertylist_get_int(p, GIALIAS_PSFXBINS);
00690 }
00691
00692 if (cpl_propertylist_has(p, GIALIAS_PSFPRMS) == 0) {
00693 return 1;
00694 }
00695 else {
00696 nparameters = cpl_propertylist_get_int(p, GIALIAS_PSFPRMS);
00697 }
00698
00699 if (cpl_propertylist_has(p, GIALIAS_PSFNX) == 0) {
00700 return 1;
00701 }
00702 else {
00703 nx = cpl_propertylist_get_int(p, GIALIAS_PSFNX);
00704 }
00705
00706 if (cpl_propertylist_has(p, GIALIAS_PSFNY) == 0) {
00707 return 1;
00708 }
00709 else {
00710 ny = cpl_propertylist_get_int(p, GIALIAS_PSFNY);
00711 }
00712
00713 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00714
00715 if (p != NULL) {
00716 cpl_propertylist_delete(p);
00717 p = NULL;
00718 }
00719
00720 return 1;
00721
00722 }
00723
00724 giraffe_error_pop();
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735 giraffe_psfdata_set_model(self, model);
00736 _giraffe_psfdata_resize(self, nfibers, nbins, ny, nx);
00737
00738 cpl_propertylist_delete(p);
00739 p = NULL;
00740
00741
00742
00743
00744
00745
00746 self->bins = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, extension);
00747
00748 if (self->bins == NULL) {
00749 _giraffe_psfdata_clear(self);
00750 return 2;
00751 }
00752
00753 if ((cpl_image_get_size_x(self->bins) != self->nfibers) ||
00754 (cpl_image_get_size_y(self->bins) != self->nbins)) {
00755 _giraffe_psfdata_clear(self);
00756 return 2;
00757 }
00758
00759 ++extension;
00760
00761
00762
00763
00764
00765
00766
00767 for (i = extension; i < extension + nparameters; i++) {
00768
00769 cpl_image* buffer = cpl_image_load(filename, CPL_TYPE_DOUBLE, 0, i);
00770
00771 if (buffer == NULL) {
00772 _giraffe_psfdata_clear(self);
00773 return 2;
00774 }
00775
00776 if ((cpl_image_get_size_x(buffer) != self->nfibers) ||
00777 (cpl_image_get_size_y(buffer) != self->nbins)) {
00778 _giraffe_psfdata_clear(self);
00779 return 2;
00780 }
00781 else {
00782
00783 const cxchar* name = NULL;
00784
00785 p = cpl_propertylist_load(filename, i);
00786
00787 if (p == NULL) {
00788
00789 cpl_image_delete(buffer);
00790 buffer = NULL;
00791
00792 return 2;
00793
00794 }
00795
00796 if (cpl_propertylist_has(p, GIALIAS_EXTNAME) == 0) {
00797
00798 cpl_propertylist_delete(p);
00799 p = NULL;
00800
00801 cpl_image_delete(buffer);
00802 buffer = NULL;
00803
00804 return 2;
00805
00806 }
00807
00808 name = cpl_propertylist_get_string(p, GIALIAS_EXTNAME);
00809 cx_map_insert(self->values, cx_strdup(name), buffer);
00810
00811 cpl_propertylist_delete(p);
00812 p = NULL;
00813
00814 }
00815
00816 }
00817
00818 return 0;
00819
00820 }
00821
00822
00823 cxint
00824 giraffe_psfdata_save(const GiPsfData* self, cpl_propertylist* properties,
00825 const cxchar* filename, cxcptr data)
00826 {
00827
00828 const cxchar* const fctid = "giraffe_psfdata_save";
00829
00830 cx_map_const_iterator position;
00831
00832 cpl_propertylist* p = NULL;
00833
00834
00835
00836 data = NULL;
00837
00838 if (self == NULL || properties == NULL || filename == NULL) {
00839 return -1;
00840 }
00841
00842 cpl_propertylist_update_string(properties, GIALIAS_PSFMODEL,
00843 self->model);
00844 cpl_propertylist_update_int(properties, GIALIAS_PSFPRMS,
00845 cx_map_size(self->values));
00846 cpl_propertylist_update_int(properties, GIALIAS_PSFXBINS,
00847 self->nbins);
00848 cpl_propertylist_update_int(properties, GIALIAS_PSFNX,
00849 self->height);
00850 cpl_propertylist_update_int(properties, GIALIAS_PSFNY,
00851 self->width);
00852 cpl_propertylist_update_int(properties, GIALIAS_PSFNS,
00853 self->nfibers);
00854
00855 giraffe_error_push();
00856
00857 cpl_image_save(NULL, filename, CPL_BPP_IEEE_FLOAT,
00858 properties, CPL_IO_DEFAULT);
00859
00860 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00861 return 1;
00862 }
00863
00864 giraffe_error_pop();
00865
00866 p = cpl_propertylist_new();
00867 cpl_propertylist_append_string(p, GIALIAS_EXTNAME, "Bin");
00868 cpl_propertylist_set_comment(p, GIALIAS_EXTNAME, "FITS Extension name");
00869
00870 giraffe_error_push();
00871
00872 cpl_image_save(self->bins, filename, CPL_BPP_IEEE_FLOAT, p,
00873 CPL_IO_EXTEND);
00874
00875 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00876
00877 cpl_propertylist_delete(p);
00878 p = NULL;
00879
00880 return 1;
00881 }
00882
00883 giraffe_error_pop();
00884
00885 position = cx_map_begin(self->values);
00886 while (position != cx_map_end(self->values)) {
00887
00888 cxint format = 0;
00889
00890 const cpl_image* psfdata = cx_map_get_value(self->values, position);
00891
00892
00893 switch (cpl_image_get_type(psfdata)) {
00894 case CPL_TYPE_INT:
00895 format = CPL_BPP_32_SIGNED;
00896 break;
00897
00898 case CPL_TYPE_FLOAT:
00899 format = CPL_BPP_IEEE_FLOAT;
00900 break;
00901
00902 case CPL_TYPE_DOUBLE:
00903 format = CPL_BPP_IEEE_FLOAT;
00904 break;
00905
00906 default:
00907 cpl_propertylist_delete(p);
00908 p = NULL;
00909
00910 cpl_error_set(fctid, CPL_ERROR_TYPE_MISMATCH);
00911 return 2;
00912
00913 break;
00914 }
00915
00916 giraffe_error_push();
00917
00918 cpl_propertylist_set_string(p, GIALIAS_EXTNAME,
00919 cx_map_get_key(self->values, position));
00920
00921 cpl_image_save(psfdata, filename, format, p, CPL_IO_EXTEND);
00922
00923 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00924 cpl_propertylist_delete(p);
00925 p = NULL;
00926
00927 return 2;
00928 }
00929
00930 giraffe_error_pop();
00931
00932 position = cx_map_next(self->values, position);
00933
00934 }
00935
00936 cpl_propertylist_delete(p);
00937 p = NULL;
00938
00939 return 0;
00940
00941 }