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 <math.h>
00033
00034 #include <cxslist.h>
00035 #include <cxstrutils.h>
00036
00037 #include <cpl_array.h>
00038 #include <cpl_propertylist.h>
00039
00040 #include "gialias.h"
00041 #include "gimessages.h"
00042 #include "gigrating.h"
00043 #include "gifov.h"
00044 #include "gifiberutils.h"
00045 #include "gisutils.h"
00046 #include "giutils.h"
00047
00048
00058 inline static cxint
00059 _giraffe_compare_int(cxcptr first, cxcptr second)
00060 {
00061
00062 cxint *_first = (cxint *)first;
00063 cxint *_second = (cxint *)second;
00064
00065 return *_first - *_second;
00066
00067 }
00068
00069
00070 inline static GiCube*
00071 _giraffe_fov_create_cube(const GiImage* spectra,
00072 const cpl_table* fibers,
00073 const GiRange* limits)
00074 {
00075
00076 cxint first = 0;
00077 cxint last = 0;
00078 cxint nx = 0;
00079 cxint ny = 0;
00080 cxint nz = 0;
00081
00082 cxdouble wmin = 0.;
00083 cxdouble wmax = 0.;
00084 cxdouble wstep = 0.;
00085 cxdouble fstart = 1.;
00086 cxdouble fend = 1.;
00087
00088 cpl_propertylist* properties = giraffe_image_get_properties(spectra);
00089
00090 cpl_image* _spectra = giraffe_image_get(spectra);
00091
00092 GiCube* cube = NULL;
00093
00094
00095 if ((properties == NULL) || (_spectra == NULL)) {
00096 return NULL;
00097 }
00098
00099
00100
00101
00102
00103
00104 if (cpl_propertylist_has(properties, GIALIAS_BINWLMIN) == FALSE) {
00105 return NULL;
00106 }
00107 else {
00108 wmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
00109 }
00110
00111 if (cpl_propertylist_has(properties, GIALIAS_BINWLMAX) == FALSE) {
00112 return NULL;
00113 }
00114 else {
00115 wmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
00116 }
00117
00118 if (cpl_propertylist_has(properties, GIALIAS_BINSTEP) == FALSE) {
00119 return NULL;
00120 }
00121 else {
00122 wstep = cpl_propertylist_get_double(properties, GIALIAS_BINSTEP);
00123 }
00124
00125
00126
00127
00128
00129
00130 first = 0;
00131 last = cpl_image_get_size_y(_spectra) - 1;
00132
00133 if (limits != NULL) {
00134
00135 if (giraffe_range_get_min(limits) > wmin) {
00136
00137 cxdouble pixel = (giraffe_range_get_min(limits) - wmin) / wstep;
00138
00139
00140 first = ceil(pixel);
00141 fstart = pixel - first;
00142
00143 }
00144
00145 if (giraffe_range_get_max(limits) < wmax) {
00146
00147 cxdouble pixel = last - (wmax - giraffe_range_get_max(limits)) / wstep;
00148
00149
00150 last = floor(pixel);
00151 fend = pixel - last;
00152
00153 }
00154
00155 }
00156
00157
00158
00159
00160
00161
00162 nx = (cxint) cpl_table_get_column_max(fibers, "X");
00163 ny = (cxint) cpl_table_get_column_max(fibers, "Y");
00164 nz = last - first + 1;
00165
00166
00167
00168
00169
00170
00171 cube = giraffe_cube_create(nx, ny, nz, NULL);
00172
00173 giraffe_cube_set_xaxis(cube, 1., 1.);
00174 giraffe_cube_set_yaxis(cube, 1., 1.);
00175 giraffe_cube_set_zaxis(cube, wmin, wstep);
00176
00177 if (cube != NULL) {
00178
00179 register cxint i = 0;
00180 register cxint nf = cpl_table_get_nrow(fibers);
00181
00182 cxint ns = cpl_image_get_size_x(_spectra);
00183
00184 cxdouble* spixels = cpl_image_get_data_double(_spectra);
00185 cxdouble* cpixels = giraffe_cube_get_data(cube);
00186
00187
00188 cx_assert(spixels != NULL);
00189 cx_assert(cpixels != NULL);
00190 cx_assert(nf <= ns);
00191
00192 for (i = 0; i < nf; ++i) {
00193
00194 register cxint j = 0;
00195
00196 cxint idx = cpl_table_get_int(fibers, "INDEX", i, NULL) - 1;
00197 cxint x = cpl_table_get_int(fibers, "X", i, NULL) - 1;
00198 cxint y = cpl_table_get_int(fibers, "Y", i, NULL) - 1;
00199
00200
00201
00202
00203
00204
00205
00206 if ((x >= 0) && (y >= 0)) {
00207
00208 for (j = 0; j < nz; ++j) {
00209 cpixels[(ny * j + y) * nx + x] =
00210 spixels[(first + j) * ns + idx];
00211 }
00212
00213 }
00214
00215 }
00216
00217 }
00218
00219 return cube;
00220
00221 }
00222
00223
00224
00225
00226
00227
00228 inline static cpl_image*
00229 _giraffe_fov_arrange_images(const cx_slist* subimages,
00230 cxsize nrows, cxsize ncolumns, cxint offset)
00231 {
00232
00233 cxint x = 0;
00234 cxint y = 0;
00235 cxint nx = 0;
00236 cxint ny = 0;
00237 cxint sx = 0;
00238 cxint sy = 0;
00239 cxint xshift = offset;
00240 cxint yshift = offset;
00241
00242 cxsize nslit = 0;
00243 cxsize column = 0;
00244
00245 cx_slist_iterator pos;
00246
00247 cpl_image* image = NULL;
00248
00249
00250 cx_assert(subimages != NULL);
00251 cx_assert(nrows > 0);
00252 cx_assert(ncolumns > 0);
00253
00254
00255
00256
00257
00258
00259
00260
00261 pos = cx_slist_begin(subimages);
00262
00263 while (pos != cx_slist_end(subimages)) {
00264
00265 const cpl_image* simage = cx_slist_get(subimages, pos);
00266
00267 if (simage != NULL) {
00268
00269 cxint _nx = cpl_image_get_size_x(simage);
00270 cxint _ny = cpl_image_get_size_y(simage);
00271
00272 sx = CX_MAX(nx, _nx);
00273 sy = CX_MAX(ny, _ny);
00274
00275 }
00276
00277 pos = cx_slist_next(subimages, pos);
00278
00279 }
00280
00281
00282
00283
00284
00285
00286 nslit = cx_slist_size(subimages);
00287 nrows = CX_MAX(nslit / ncolumns, nrows);
00288
00289 if (nslit % ncolumns != 0) {
00290 ++nrows;
00291 }
00292
00293
00294
00295
00296
00297
00298 nx = sx * ncolumns;
00299 ny = sy * nrows;
00300
00301
00302 if (offset < 0) {
00303 xshift = nx / -offset + 1;
00304 yshift = ny / -offset + 1;
00305 }
00306
00307 nx += ncolumns * xshift - (xshift % 2);
00308 ny += nrows * yshift - (yshift % 2);
00309
00310
00311
00312
00313
00314
00315 image = cpl_image_new(nx, ny, CPL_TYPE_DOUBLE);
00316
00317 y = yshift / 2;
00318 x = xshift / 2;
00319
00320 pos = cx_slist_begin(subimages);
00321
00322 while (pos != cx_slist_end(subimages)) {
00323
00324 const cpl_image* simage = cx_slist_get(subimages, pos);
00325
00326 if (simage != NULL) {
00327
00328 cpl_error_code status = cpl_image_copy(image, simage,
00329 x + 1, y + 1);
00330
00331 if (status != CPL_ERROR_NONE) {
00332 cpl_image_delete(image);
00333 return NULL;
00334 }
00335
00336 }
00337
00338 ++column;
00339
00340 if (column < ncolumns) {
00341 x += sx + xshift;
00342 }
00343 else {
00344 column = 0;
00345
00346 x = xshift / 2;
00347 y += sy + yshift;
00348 }
00349
00350 pos = cx_slist_next(subimages, pos);
00351
00352 }
00353
00354 return image;
00355
00356 }
00357
00358
00359 inline static cpl_image*
00360 _giraffe_fov_integrate_cube(const GiCube* cube, const GiRange* limits)
00361 {
00362
00363 cxsize depth = 0;
00364
00365 cxdouble wmin = 0.;
00366 cxdouble wmax = 0.;
00367 cxdouble wstep = 0.;
00368 cxdouble start = 0.;
00369 cxdouble end = 0.;
00370
00371 cpl_image* image = NULL;
00372
00373
00374 cx_assert(cube != NULL);
00375
00376 depth = giraffe_cube_get_depth(cube);
00377 giraffe_cube_get_zaxis(cube, &wmin, &wstep);
00378
00379 wmax = wmin + depth * wstep;
00380 end = depth;
00381
00382 if (giraffe_range_get_min(limits) > wmin) {
00383 start = (giraffe_range_get_min(limits) - wmin) / wstep;
00384 }
00385
00386 if (giraffe_range_get_max(limits) < wmax) {
00387 end = (giraffe_range_get_max(limits) - wmin) / wstep;
00388 }
00389
00390 image = giraffe_cube_integrate(cube, start, end);
00391
00392 return image;
00393
00394 }
00395
00396
00418 cxint
00419 giraffe_fov_build(GiFieldOfView* result, GiRebinning* rebinning,
00420 GiTable* fibers, GiTable* wsolution,
00421 GiTable* grating, GiTable* slitgeometry,
00422 GiFieldOfViewConfig* config)
00423 {
00424
00425 const cxchar* const fctid = "giraffe_fov_build";
00426
00427 cx_slist* simages = NULL;
00428 cx_slist* eimages = NULL;
00429 cx_slist* scubes = NULL;
00430 cx_slist* ecubes = NULL;
00431
00432 cpl_propertylist* properties = NULL;
00433
00434 cpl_array* ssn = NULL;
00435
00436 cpl_image* fov = NULL;
00437
00438 cpl_table* _fibers = NULL;
00439
00440 GiInstrumentMode mode;
00441
00442 GiRange* limits = NULL;
00443
00444
00445 if (result == NULL) {
00446 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00447 return -1;
00448 }
00449 else {
00450
00451
00452
00453
00454
00455 giraffe_fov_clear(result);
00456
00457 }
00458
00459 if (rebinning == NULL) {
00460 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00461 return -1;
00462 }
00463
00464 if (rebinning->spectra == NULL || rebinning->errors == NULL) {
00465 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00466 return -1;
00467 }
00468
00469 if (fibers == NULL) {
00470 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00471 return -1;
00472 }
00473
00474 _fibers = giraffe_table_get(fibers);
00475
00476 if (_fibers == NULL) {
00477 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00478 return -1;
00479 }
00480
00481 if (!cpl_table_has_column(_fibers, "X") ||
00482 !cpl_table_has_column(_fibers, "Y")) {
00483 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00484 return -2;
00485 }
00486
00487 if (config == NULL) {
00488 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00489 return -1;
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 properties = giraffe_image_get_properties(rebinning->spectra);
00501
00502 if (properties == NULL) {
00503 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00504 return -1;
00505 }
00506
00507 mode = giraffe_get_mode(properties);
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517 limits = giraffe_rebin_get_wavelength_range(rebinning->spectra, wsolution,
00518 grating, slitgeometry, TRUE);
00519
00520 if (limits == NULL) {
00521 cpl_msg_error(fctid, "Computation of spectra common wavelength "
00522 "range failed!");
00523 return 1;
00524 }
00525
00526 if (config->minimum > 0.) {
00527 if (config->minimum < giraffe_range_get_min(limits)) {
00528 cpl_msg_warning(fctid, "Ignoring invalid wavelength range "
00529 "minimum %.3f nm", config->minimum);
00530 }
00531 else {
00532 giraffe_range_set_min(limits, config->minimum);
00533 }
00534 }
00535
00536 if (config->maximum > 0.) {
00537 if (config->maximum > giraffe_range_get_max(limits)) {
00538 cpl_msg_warning(fctid, "Ignoring invalid wavelength range "
00539 "maximum %.3f nm", config->maximum);
00540 }
00541 else {
00542 giraffe_range_set_max(limits, config->maximum);
00543 }
00544 }
00545
00546 cpl_msg_info(fctid, "Building image for wavelength range [%.3f nm, "
00547 "%.3f nm].", giraffe_range_get_min(limits),
00548 giraffe_range_get_max(limits));
00549
00550
00551
00552
00553
00554
00555 if (cpl_propertylist_has(properties, GIALIAS_BINSCALE)) {
00556
00557 const cxchar* s = cpl_propertylist_get_string(properties,
00558 GIALIAS_BINSCALE);
00559
00560 if (cx_strncasecmp(s, "log", 3) == 0) {
00561 giraffe_range_set_min(limits, log(giraffe_range_get_min(limits)));
00562 giraffe_range_set_max(limits, log(giraffe_range_get_max(limits)));
00563 }
00564 }
00565 else {
00566 cpl_msg_warning(fctid, "Could not determine spectrum wavelength "
00567 "scaling method. Missing property `%s'. Assuming "
00568 "scaling method `linear'!", GIALIAS_BINSCALE);
00569 }
00570
00571
00572
00573
00574
00575
00576
00577 simages = cx_slist_new();
00578 eimages = cx_slist_new();
00579 scubes = cx_slist_new();
00580 ecubes = cx_slist_new();
00581
00582
00583 switch (mode) {
00584 case GIMODE_IFU:
00585 {
00586
00587 cxint i = 0;
00588
00589 cpl_image* smosaic = NULL;
00590 cpl_image* emosaic = NULL;
00591
00592 GiImage* variance = NULL;
00593
00594
00595
00596
00597
00598
00599 ssn = giraffe_fiberlist_get_subslits(_fibers);
00600
00601 if (ssn == NULL) {
00602 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
00603 simages = NULL;
00604
00605 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
00606 eimages = NULL;
00607
00608 cx_slist_destroy(scubes, (cx_free_func)giraffe_cube_delete);
00609 scubes = NULL;
00610
00611 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
00612 ecubes = NULL;
00613
00614 giraffe_range_delete(limits);
00615 limits = NULL;
00616
00617 cpl_msg_error(fctid, "Sub-slit data missing in fiber table!");
00618
00619 return 1;
00620 }
00621
00622
00623
00624
00625
00626
00627 variance = giraffe_image_duplicate(rebinning->errors);
00628
00629 if (variance == NULL) {
00630 cpl_array_delete(ssn);
00631 ssn = NULL;
00632
00633 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
00634 simages = NULL;
00635
00636 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
00637 eimages = NULL;
00638
00639 cx_slist_destroy(scubes, (cx_free_func)giraffe_cube_delete);
00640 scubes = NULL;
00641
00642 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
00643 ecubes = NULL;
00644
00645 giraffe_range_delete(limits);
00646 limits = NULL;
00647
00648 cpl_msg_error(fctid, "Failed to create variance map!");
00649
00650 return 1;
00651 }
00652
00653 cpl_image_power(giraffe_image_get(variance), 2.);
00654
00655
00656
00657
00658
00659
00660 for (i = 0; i < cpl_array_get_size(ssn); ++i) {
00661
00662 cxbool failed = FALSE;
00663
00664 cxint nss = cpl_array_get_int(ssn, i, NULL);
00665
00666 cpl_table* ssf = NULL;
00667
00668 cpl_table_unselect_all(_fibers);
00669 cpl_table_or_selected_int(_fibers, "SSN", CPL_EQUAL_TO, nss);
00670
00671 ssf = cpl_table_extract_selected(_fibers);
00672
00673 if (ssf != NULL) {
00674
00675 cpl_image* _simage = NULL;
00676 cpl_image* _eimage = NULL;
00677
00678 GiCube* _scube = NULL;
00679 GiCube* _ecube = NULL;
00680
00681
00682 _scube = _giraffe_fov_create_cube(rebinning->spectra,
00683 ssf, NULL);
00684
00685 if (_scube != NULL) {
00686 _simage = _giraffe_fov_integrate_cube(_scube, limits);
00687 }
00688
00689 if ((_scube == NULL) || (_simage == NULL)) {
00690
00691 cpl_image_delete(_simage);
00692 _simage = NULL;
00693
00694 giraffe_cube_delete(_scube);
00695 _scube = NULL;
00696
00697 failed = TRUE;
00698
00699 cpl_msg_error(fctid, "Cannot create data cube for "
00700 "sub-slit %d", nss);
00701 }
00702 else {
00703 cx_slist_push_back(scubes, _scube);
00704 cx_slist_push_back(simages, _simage);
00705 }
00706
00707 if (!failed) {
00708
00709 _ecube = _giraffe_fov_create_cube(variance,
00710 ssf, NULL);
00711
00712 if (_ecube != NULL) {
00713 _eimage = _giraffe_fov_integrate_cube(_ecube,
00714 limits);
00715 }
00716
00717 if ((_ecube == NULL) || (_eimage == NULL)) {
00718
00719 cpl_image_delete(_eimage);
00720 _eimage = NULL;
00721
00722 giraffe_cube_delete(_ecube);
00723 _ecube = NULL;
00724
00725 failed = TRUE;
00726
00727 cpl_msg_error(fctid, "Cannot create error "
00728 "cube for sub-slit %d", nss);
00729 }
00730 else {
00731 giraffe_cube_sqrt(_ecube);
00732 cpl_image_power(_eimage, 0.5);
00733
00734 cx_slist_push_back(ecubes, _ecube);
00735 cx_slist_push_back(eimages, _eimage);
00736 }
00737
00738 }
00739
00740 cpl_table_delete(ssf);
00741 ssf = NULL;
00742
00743 if (failed) {
00744
00745 giraffe_image_delete(variance);
00746 variance = NULL;
00747
00748 cpl_array_delete(ssn);
00749 ssn = NULL;
00750
00751 cx_slist_destroy(simages,
00752 (cx_free_func)cpl_image_delete);
00753 simages = NULL;
00754
00755 cx_slist_destroy(eimages,
00756 (cx_free_func)cpl_image_delete);
00757 eimages = NULL;
00758
00759 cx_slist_destroy(scubes,
00760 (cx_free_func)giraffe_cube_delete);
00761 scubes = NULL;
00762
00763 cx_slist_destroy(ecubes,
00764 (cx_free_func)giraffe_cube_delete);
00765 ecubes = NULL;
00766
00767 giraffe_range_delete(limits);
00768 limits = NULL;
00769
00770 return 1;
00771
00772 }
00773
00774 }
00775
00776 }
00777
00778 giraffe_image_delete(variance);
00779 variance = NULL;
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789 smosaic = _giraffe_fov_arrange_images(simages, 5, 3, -4);
00790 emosaic = _giraffe_fov_arrange_images(eimages, 5, 3, -4);
00791
00792 if ((smosaic == NULL) || (emosaic == NULL)) {
00793
00794 cpl_image_delete(smosaic);
00795 smosaic = NULL;
00796
00797 cpl_image_delete(emosaic);
00798 emosaic = NULL;
00799
00800 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
00801 simages = NULL;
00802
00803 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
00804 eimages = NULL;
00805
00806 cx_slist_destroy(scubes, (cx_free_func)giraffe_cube_delete);
00807 scubes = NULL;
00808
00809 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
00810 ecubes = NULL;
00811
00812 cpl_array_delete(ssn);
00813 ssn = NULL;
00814
00815 giraffe_range_delete(limits);
00816 limits = NULL;
00817
00818 return 1;
00819
00820 }
00821
00822 cx_slist_push_front(simages, smosaic);
00823 cx_slist_push_front(eimages, emosaic);
00824 break;
00825
00826 }
00827
00828 case GIMODE_ARGUS:
00829 {
00830 cxbool failed = FALSE;
00831
00832 cpl_image* simage = NULL;
00833 cpl_image* eimage = NULL;
00834
00835 GiImage* variance = NULL;
00836
00837 GiCube* scube = NULL;
00838 GiCube* ecube = NULL;
00839
00840
00841
00842
00843
00844
00845 variance = giraffe_image_duplicate(rebinning->errors);
00846
00847 if (variance == NULL) {
00848
00849 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
00850 simages = NULL;
00851
00852 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
00853 eimages = NULL;
00854
00855 cx_slist_destroy(scubes, (cx_free_func)giraffe_cube_delete);
00856 scubes = NULL;
00857
00858 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
00859 ecubes = NULL;
00860
00861 giraffe_range_delete(limits);
00862 limits = NULL;
00863
00864 cpl_msg_error(fctid, "Failed to create variance map!");
00865 return 1;
00866
00867 }
00868
00869 cpl_image_power(giraffe_image_get(variance), 2.);
00870
00871
00872
00873
00874
00875
00876 scube = _giraffe_fov_create_cube(rebinning->spectra,
00877 _fibers, NULL);
00878
00879 if (scube != NULL) {
00880 simage = _giraffe_fov_integrate_cube(scube, limits);
00881 }
00882
00883 if ((scube == NULL) || (simage == NULL)) {
00884
00885 cpl_image_delete(simage);
00886 simage = NULL;
00887
00888 giraffe_cube_delete(scube);
00889 scube = NULL;
00890
00891 failed = TRUE;
00892
00893 cpl_msg_error(fctid, "Cannot create data cube!");
00894 return 1;
00895
00896 }
00897 else {
00898
00899 cx_slist_push_back(scubes, scube);
00900 cx_slist_push_back(simages, simage);
00901
00902 }
00903
00904
00905 if (!failed) {
00906
00907 ecube = _giraffe_fov_create_cube(variance, _fibers, NULL);
00908 eimage = _giraffe_fov_integrate_cube(ecube, limits);
00909
00910 if ((ecube == NULL) || (eimage == NULL)) {
00911
00912 cpl_image_delete(eimage);
00913 eimage = NULL;
00914
00915 giraffe_cube_delete(ecube);
00916 ecube = NULL;
00917
00918 failed = TRUE;
00919
00920 cpl_msg_error(fctid, "Cannot create error cube!");
00921 return 1;
00922
00923 }
00924 else {
00925
00926 giraffe_cube_sqrt(ecube);
00927 cpl_image_power(eimage, 0.5);
00928
00929 cx_slist_push_back(ecubes, ecube);
00930 cx_slist_push_back(eimages, eimage);
00931
00932 }
00933
00934 }
00935
00936 if (failed) {
00937
00938 giraffe_image_delete(variance);
00939 variance = NULL;
00940
00941 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
00942 simages = NULL;
00943
00944 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
00945 eimages = NULL;
00946
00947 cx_slist_destroy(scubes, (cx_free_func)giraffe_cube_delete);
00948 scubes = NULL;
00949
00950 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
00951 ecubes = NULL;
00952
00953 giraffe_range_delete(limits);
00954 limits = NULL;
00955
00956 return 1;
00957
00958 }
00959
00960 giraffe_image_delete(variance);
00961 variance = NULL;
00962 break;
00963 }
00964
00965 default:
00966 return 1;
00967 break;
00968 }
00969
00970
00971
00972
00973
00974
00975 result->mode = mode;
00976 result->ssn = ssn;
00977 ssn = NULL;
00978
00979 properties = giraffe_image_get_properties(rebinning->spectra);
00980 fov = cx_slist_pop_front(simages);
00981
00982 result->fov.spectra = giraffe_image_new(CPL_TYPE_DOUBLE);
00983 giraffe_image_set(result->fov.spectra, fov);
00984 giraffe_image_set_properties(result->fov.spectra, properties);
00985
00986 properties = giraffe_image_get_properties(result->fov.spectra);
00987
00988 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMIN,
00989 giraffe_range_get_min(limits));
00990 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMIN,
00991 "Minimum wavelength of FOV band");
00992
00993 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMAX,
00994 giraffe_range_get_max(limits));
00995 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMAX,
00996 "Maximum wavelength of FOV band");
00997
00998 cpl_image_delete(fov);
00999 fov = NULL;
01000
01001
01002 properties = giraffe_image_get_properties(rebinning->errors);
01003 fov = cx_slist_pop_front(eimages);
01004
01005 result->fov.errors = giraffe_image_new(CPL_TYPE_DOUBLE);
01006 giraffe_image_set(result->fov.errors, fov);
01007 giraffe_image_set_properties(result->fov.errors, properties);
01008
01009 properties = giraffe_image_get_properties(result->fov.errors);
01010
01011 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMIN,
01012 giraffe_range_get_min(limits));
01013 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMIN,
01014 "Minimum wavelength of FOV band");
01015
01016 cpl_propertylist_update_double(properties, GIALIAS_FOV_BANDMAX,
01017 giraffe_range_get_max(limits));
01018 cpl_propertylist_set_comment(properties, GIALIAS_FOV_BANDMAX,
01019 "Maximum wavelength of FOV band");
01020
01021 cpl_image_delete(fov);
01022 fov = NULL;
01023
01024 if (!cx_slist_empty(simages)) {
01025
01026 cx_slist_iterator pos = cx_slist_begin(simages);
01027
01028 result->images.spectra = cx_slist_new();
01029
01030 while (pos != cx_slist_end(simages)) {
01031
01032 GiImage* image = giraffe_image_new(CPL_TYPE_DOUBLE);
01033
01034 giraffe_image_set(image, cx_slist_get(simages, pos));
01035 cx_slist_push_back(result->images.spectra, image);
01036
01037 pos = cx_slist_next(simages, pos);
01038 }
01039
01040 }
01041
01042 if (!cx_slist_empty(eimages)) {
01043
01044 cx_slist_iterator pos = cx_slist_begin(eimages);
01045
01046 result->images.errors = cx_slist_new();
01047
01048 while (pos != cx_slist_end(eimages)) {
01049
01050 GiImage* image = giraffe_image_new(CPL_TYPE_DOUBLE);
01051
01052 giraffe_image_set(image, cx_slist_get(eimages, pos));
01053 cx_slist_push_back(result->images.errors, image);
01054
01055 pos = cx_slist_next(eimages, pos);
01056 }
01057
01058 }
01059
01060 if (config->cube == TRUE) {
01061
01062 if (!cx_slist_empty(scubes)) {
01063 result->cubes.spectra = scubes;
01064 scubes = NULL;
01065 }
01066
01067 if (!cx_slist_empty(ecubes)) {
01068 result->cubes.errors = ecubes;
01069 ecubes = NULL;
01070 }
01071
01072 }
01073
01074
01075
01076
01077
01078
01079 giraffe_range_delete(limits);
01080 limits = NULL;
01081
01082 cx_slist_destroy(simages, (cx_free_func)cpl_image_delete);
01083 simages = NULL;
01084
01085 cx_slist_destroy(eimages, (cx_free_func)cpl_image_delete);
01086 eimages = NULL;
01087
01088 if (scubes != NULL) {
01089 cx_slist_destroy(scubes, (cx_free_func)giraffe_cube_delete);
01090 scubes = NULL;
01091 }
01092
01093 if (ecubes != NULL) {
01094 cx_slist_destroy(ecubes, (cx_free_func)giraffe_cube_delete);
01095 ecubes = NULL;
01096 }
01097
01098 return 0;
01099
01100 }
01101
01102
01116 GiFieldOfView*
01117 giraffe_fov_new(void)
01118 {
01119 GiFieldOfView* self = cx_malloc(sizeof *self);
01120
01121 self->mode = GIMODE_NONE;
01122 self->ssn = NULL;
01123
01124 self->fov.spectra = NULL;
01125 self->fov.errors = NULL;
01126
01127 self->images.spectra = NULL;
01128 self->images.errors = NULL;
01129
01130 self->cubes.spectra = NULL;
01131 self->cubes.errors = NULL;
01132
01133 return self;
01134
01135 }
01136
01137
01150 void
01151 giraffe_fov_clear(GiFieldOfView* self)
01152 {
01153
01154 if (self != NULL) {
01155
01156 if (self->cubes.errors != NULL) {
01157 cx_slist_destroy(self->cubes.errors,
01158 (cx_free_func)giraffe_cube_delete);
01159 self->cubes.errors = NULL;
01160 }
01161
01162 if (self->cubes.spectra != NULL) {
01163 cx_slist_destroy(self->cubes.spectra,
01164 (cx_free_func)giraffe_cube_delete);
01165 self->cubes.spectra = NULL;
01166 }
01167
01168 if (self->images.errors != NULL) {
01169 cx_slist_destroy(self->images.errors,
01170 (cx_free_func)giraffe_image_delete);
01171 self->images.errors = NULL;
01172 }
01173
01174 if (self->images.spectra != NULL) {
01175 cx_slist_destroy(self->images.spectra,
01176 (cx_free_func)giraffe_image_delete);
01177 self->images.spectra = NULL;
01178 }
01179
01180 if (self->fov.errors != NULL) {
01181 giraffe_image_delete(self->fov.errors);
01182 self->fov.errors = NULL;
01183 }
01184
01185 if (self->fov.spectra != NULL) {
01186 giraffe_image_delete(self->fov.spectra);
01187 self->fov.spectra = NULL;
01188 }
01189
01190 if (self->ssn != NULL) {
01191 cpl_array_delete(self->ssn);
01192 self->ssn = NULL;
01193 }
01194
01195 self->mode = GIMODE_NONE;
01196
01197 }
01198
01199 return;
01200
01201 }
01202
01203
01217 void
01218 giraffe_fov_delete(GiFieldOfView* self)
01219 {
01220
01221 if (self != NULL) {
01222 giraffe_fov_clear(self);
01223 cx_free(self);
01224 }
01225
01226 return;
01227
01228 }
01229
01230
01253 cxint
01254 giraffe_fov_save_cubes(const GiFieldOfView* self,
01255 cpl_propertylist* properties,
01256 const cxchar* filename, cxptr data)
01257 {
01258
01259
01260 cxint component = 0;
01261
01262 cx_slist* cubes = NULL;
01263
01264
01265 if ((self == NULL) || (properties == NULL) || (filename == NULL)) {
01266 return -1;
01267 }
01268
01269
01270
01271
01272
01273
01274 if (data != NULL) {
01275 component = *((cxuint*)data);
01276 }
01277
01278 if (component == 0) {
01279 cubes = self->cubes.spectra;
01280 }
01281 else {
01282 cubes = self->cubes.errors;
01283 }
01284
01285 if (cubes == NULL) {
01286 return -2;
01287 }
01288
01289
01290 if (!cx_slist_empty(cubes)) {
01291
01292 if (self->mode == GIMODE_ARGUS) {
01293
01294 cxint status = 0;
01295 cxint iomode = CPL_IO_CREATE;
01296
01297 GiCube* cube = cx_slist_front(cubes);
01298
01299 status = giraffe_cube_save(cube, properties, filename, &iomode);
01300
01301 if (status != 0) {
01302 return 1;
01303 }
01304
01305 }
01306 else {
01307
01308 cxint nss = 0;
01309 cxint status = 0;
01310 cxint iomode = CPL_IO_CREATE;
01311
01312 cx_slist_const_iterator pos = cx_slist_begin(cubes);
01313
01314 cx_string* name = NULL;
01315
01316 cpl_propertylist* xproperties = NULL;
01317
01318
01319 status = giraffe_cube_save(NULL, properties, filename, &iomode);
01320
01321 if (status != 0) {
01322 return 1;
01323 }
01324
01325
01326 name = cx_string_new();
01327 xproperties = cpl_propertylist_new();
01328
01329 iomode = CPL_IO_EXTEND;
01330
01331 while (pos != cx_slist_end(cubes)) {
01332
01333 cxint ssn = cpl_array_get_int(self->ssn, nss, NULL);
01334
01335 GiCube* cube = cx_slist_get(cubes, pos);
01336
01337
01338 cx_string_sprintf(name, "SSN%-d", ssn);
01339 cpl_propertylist_update_string(xproperties, "EXTNAME",
01340 cx_string_get(name));
01341
01342 status = giraffe_cube_save(cube, xproperties, filename,
01343 &iomode);
01344
01345 if (status != 0) {
01346
01347 cpl_propertylist_delete(xproperties);
01348 xproperties = NULL;
01349
01350 cx_string_delete(name);
01351 name = NULL;
01352
01353 return 1;
01354
01355 }
01356
01357 pos = cx_slist_next(cubes, pos);
01358 ++nss;
01359
01360 }
01361
01362 cpl_propertylist_delete(xproperties);
01363 xproperties = NULL;
01364
01365 cx_string_delete(name);
01366 name = NULL;
01367
01368 }
01369
01370 }
01371
01372 return 0;
01373
01374 }
01375
01376
01388 GiFieldOfViewConfig*
01389 giraffe_fov_config_create(cpl_parameterlist* list)
01390 {
01391
01392 cpl_parameter* p;
01393
01394 GiFieldOfViewConfig* config = NULL;
01395
01396
01397 if (list == NULL) {
01398 return NULL;
01399 }
01400
01401 config = cx_calloc(1, sizeof *config);
01402
01403
01404 p = cpl_parameterlist_find(list, "giraffe.fov.range.minimum");
01405 config->minimum = cpl_parameter_get_double(p);
01406
01407 p = cpl_parameterlist_find(list, "giraffe.fov.range.maximum");
01408 config->maximum = cpl_parameter_get_double(p);
01409
01410 p = cpl_parameterlist_find(list, "giraffe.fov.cube");
01411 config->cube = cpl_parameter_get_bool(p);
01412
01413 return config;
01414
01415 }
01416
01417
01431 void
01432 giraffe_fov_config_destroy(GiFieldOfViewConfig* config)
01433 {
01434
01435 if (config != NULL) {
01436 cx_free(config);
01437 }
01438
01439 return;
01440
01441 }
01442
01443
01453 void
01454 giraffe_fov_config_add(cpl_parameterlist* list)
01455 {
01456
01457 cpl_parameter* p;
01458
01459
01460 if (list == NULL) {
01461 return;
01462 }
01463
01464 p = cpl_parameter_new_value("giraffe.fov.range.minimum",
01465 CPL_TYPE_DOUBLE,
01466 "Minimum wavelength for image reconstruction",
01467 "giraffe.fov.range",
01468 0.);
01469 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-min");
01470 cpl_parameterlist_append(list, p);
01471
01472
01473 p = cpl_parameter_new_value("giraffe.fov.range.maximum",
01474 CPL_TYPE_DOUBLE,
01475 "Maximum wavelength for image reconstruction",
01476 "giraffe.fov.range",
01477 0.);
01478 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-max");
01479 cpl_parameterlist_append(list, p);
01480
01481
01482 p = cpl_parameter_new_value("giraffe.fov.cube",
01483 CPL_TYPE_BOOL,
01484 "Turns data cube creation on and off",
01485 "giraffe.fov.cube",
01486 TRUE);
01487 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-cube");
01488 cpl_parameterlist_append(list, p);
01489
01490 return;
01491
01492 }