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_propertylist.h>
00038
00039 #include "gialias.h"
00040 #include "gimessages.h"
00041 #include "gigrating.h"
00042 #include "gireconstruct.h"
00043 #include "gisutils.h"
00044 #include "giutils.h"
00045
00046
00055 inline static cxint
00056 _giraffe_compare_int(cxcptr first, cxcptr second)
00057 {
00058
00059 cxint *_first = (cxint *)first;
00060 cxint *_second = (cxint *)second;
00061
00062 return *_first - *_second;
00063
00064 }
00065
00066
00067 inline static GiImage*
00068 _giraffe_reconstruct_image(GiImage* flux, cpl_table* fibers)
00069 {
00070
00071 cxint nx;
00072 cxint ny;
00073 cxint nf;
00074
00075 GiImage* image = NULL;
00076
00077
00078 cx_assert(flux != NULL);
00079 cx_assert(fibers != NULL);
00080
00081 nf = cpl_table_get_nrow(fibers);
00082
00083 if (nf <= 0) {
00084 return NULL;
00085 }
00086
00087 nx = (cxint) cpl_table_get_column_max(fibers, "X");
00088 ny = (cxint) cpl_table_get_column_max(fibers, "Y");
00089
00090 if ((nx < 1) || (ny < 1)) {
00091 return NULL;
00092 }
00093
00094 image = giraffe_image_create(CPL_TYPE_DOUBLE, nx, ny);
00095
00096 if (image != NULL) {
00097
00098 cxint j;
00099
00100 cxdouble* _flux = cpl_image_get_data(giraffe_image_get(flux));
00101 cxdouble* _pixels = cpl_image_get_data(giraffe_image_get(image));
00102
00103 cpl_propertylist* properties = giraffe_image_get_properties(flux);
00104
00105
00106 for (j = 0; j < nf; j++) {
00107
00108 cxint idx = cpl_table_get_int(fibers, "INDEX", j, NULL);
00109 cxint x = cpl_table_get_int(fibers, "X", j, NULL);
00110 cxint y = cpl_table_get_int(fibers, "Y", j, NULL);
00111
00112
00113
00114
00115
00116
00117
00118 if (x > 0 && y > 0) {
00119 _pixels[(y - 1) * nx + (x - 1)] = _flux[idx - 1];
00120 }
00121
00122 }
00123
00124 if (properties != NULL) {
00125 giraffe_image_set_properties(image, properties);
00126 }
00127
00128 }
00129
00130 return image;
00131
00132 }
00133
00134
00135 inline static GiCube*
00136 _giraffe_reconstruct_create_cube(GiImage* spectra, cpl_table* fibers,
00137 GiRange* limits)
00138 {
00139
00140 cxint first = 0;
00141 cxint last = 0;
00142 cxint nx = 0;
00143 cxint ny = 0;
00144 cxint nz = 0;
00145
00146 cxdouble wmin = 0.;
00147 cxdouble wmax = 0.;
00148 cxdouble wstep = 0.;
00149 cxdouble fstart = 1.;
00150 cxdouble fend = 1.;
00151
00152 cpl_propertylist* properties = giraffe_image_get_properties(spectra);
00153
00154 cpl_image* _spectra = giraffe_image_get(spectra);
00155
00156 GiCube* cube = NULL;
00157
00158
00159 if ((properties == NULL) || (_spectra == NULL)) {
00160 return NULL;
00161 }
00162
00163
00164
00165
00166
00167
00168 if (cpl_propertylist_has(properties, GIALIAS_BINWLMIN) == FALSE) {
00169 return NULL;
00170 }
00171 else {
00172 wmin = cpl_propertylist_get_double(properties, GIALIAS_BINWLMIN);
00173 }
00174
00175 if (cpl_propertylist_has(properties, GIALIAS_BINWLMAX) == FALSE) {
00176 return NULL;
00177 }
00178 else {
00179 wmax = cpl_propertylist_get_double(properties, GIALIAS_BINWLMAX);
00180 }
00181
00182 if (cpl_propertylist_has(properties, GIALIAS_BINSTEP) == FALSE) {
00183 return NULL;
00184 }
00185 else {
00186 wstep = cpl_propertylist_get_double(properties, GIALIAS_BINSTEP);
00187 }
00188
00189
00190
00191
00192
00193
00194 first = 0;
00195 last = cpl_image_get_size_y(_spectra) - 1;
00196
00197 if (giraffe_range_get_min(limits) > wmin) {
00198
00199 cxdouble pixel = (giraffe_range_get_min(limits) - wmin) / wstep;
00200
00201
00202 first += ceil(pixel);
00203 fstart = pixel - first;
00204
00205 }
00206
00207 if (giraffe_range_get_max(limits) < wmax) {
00208
00209 cxdouble pixel = last - (wmax - giraffe_range_get_max(limits)) / wstep;
00210
00211
00212 last = floor(pixel);
00213 fend = pixel - last;
00214
00215 }
00216
00217
00218
00219
00220
00221
00222 nx = (cxint) cpl_table_get_column_max(fibers, "X");
00223 ny = (cxint) cpl_table_get_column_max(fibers, "Y");
00224 nz = last - first + 1;
00225
00226
00227
00228
00229
00230
00231 cube = giraffe_cube_create(nx, ny, nz, NULL);
00232
00233 giraffe_cube_set_xaxis(cube, 1., 1.);
00234 giraffe_cube_set_yaxis(cube, 1., 1.);
00235 giraffe_cube_set_zaxis(cube, wmin, wstep);
00236
00237 if (cube != NULL) {
00238
00239 register cxint i = 0;
00240 register cxint nf = cpl_table_get_nrow(fibers);
00241
00242 cxdouble* spixels = cpl_image_get_data_double(_spectra);
00243 cxdouble* cpixels = giraffe_cube_get_data(cube);
00244
00245
00246 cx_assert(spixels != NULL);
00247 cx_assert(cpixels != NULL);
00248 cx_assert(nf == cpl_image_get_size_x(_spectra));
00249
00250 for (i = 0; i < nf; i++) {
00251
00252 register cxint j = 0;
00253
00254 cxint idx = cpl_table_get_int(fibers, "INDEX", i, NULL) - 1;
00255 cxint x = cpl_table_get_int(fibers, "X", i, NULL) - 1;
00256 cxint y = cpl_table_get_int(fibers, "Y", i, NULL) - 1;
00257
00258
00259
00260
00261
00262
00263
00264 for (j = 0; j < nz; j++) {
00265
00266 if ((x >= 0) && (y >= 0)) {
00267 cpixels[(ny * j + y) * nx + x] =
00268 spixels[(first + j) * nf + idx];
00269 }
00270
00271 }
00272
00273 }
00274
00275 }
00276
00277 return cube;
00278
00279 }
00280
00281
00282 inline static cxint
00283 _giraffe_reconstruct_build_images(cx_slist* images, cx_slist* fluxes,
00284 cpl_table* fibers)
00285 {
00286
00287 cx_slist_iterator first = cx_slist_begin(fluxes);
00288
00289 while (first != cx_slist_end(fluxes)) {
00290
00291 GiImage* flux = cx_slist_get(fluxes, first);
00292 GiImage* image = NULL;
00293
00294
00295 image = _giraffe_reconstruct_image(flux, fibers);
00296
00297 if (image == NULL) {
00298 return -1;
00299 }
00300
00301 cx_slist_push_back(images, image);
00302 first = cx_slist_next(fluxes, first);
00303
00304 }
00305
00306 cx_assert(cx_slist_size(images) == cx_slist_size(fluxes));
00307
00308 return 0;
00309
00310 }
00311
00312
00313 inline static cxint
00314 _giraffe_reconstruct_get_subslits(cxint** ssn, cpl_table* fibers)
00315 {
00316
00317 cxint i;
00318 cxint nfibers = 0;
00319 cxint nss = 0;
00320
00321
00322 cx_assert(ssn != NULL);
00323
00324 if (fibers == NULL) {
00325 return 0;
00326 }
00327
00328 nfibers = cpl_table_get_nrow(fibers);
00329
00330 if (nfibers > 0) {
00331
00332 *ssn = cx_malloc(nfibers * sizeof(cxint));
00333 (*ssn)[nss] = cpl_table_get_int(fibers, "SSN", 0, NULL);
00334 ++nss;
00335
00336 for (i = 1; i < nfibers; i++) {
00337
00338 cxint _ssn = cpl_table_get_int(fibers, "SSN", i, NULL);
00339
00340 if (_ssn != (*ssn)[nss - 1]) {
00341 (*ssn)[nss] = _ssn;
00342 ++nss;
00343 }
00344
00345 }
00346
00347 *ssn = cx_realloc(*ssn, nss * sizeof(cxint));
00348 qsort(*ssn, nss, sizeof(cxint), _giraffe_compare_int);
00349
00350 }
00351
00352 return nss;
00353
00354 }
00355
00356
00357 inline static cxint
00358 _giraffe_reconstruct_build_subslits(cx_slist* subslits, const cx_slist* fluxes,
00359 const cpl_table* fibers, cxint nslits,
00360 const cxint* slits)
00361 {
00362
00363 cxint i;
00364
00365 cx_slist* subfibers = NULL;
00366
00367 cx_slist_iterator first;
00368
00369
00370 if (!cx_slist_empty(subslits)) {
00371 return 1;
00372 }
00373
00374 subfibers = cx_slist_new();
00375
00376 for (i = 0; i < nslits; i++) {
00377
00378 cpl_table* _fibers = NULL;
00379
00380 cpl_table_unselect_all((cpl_table*) fibers);
00381 cpl_table_or_selected_int((cpl_table*) fibers, "SSN", CPL_EQUAL_TO,
00382 slits[i]);
00383
00384 _fibers = cpl_table_extract_selected((cpl_table*) fibers);
00385
00386 if (_fibers == NULL || cpl_table_get_nrow(_fibers) <= 0) {
00387 cx_slist_destroy(subfibers, (cx_free_func)cpl_table_delete);
00388 return 2;
00389 }
00390
00391 cx_slist_push_back(subfibers, _fibers);
00392
00393 }
00394
00395 first = cx_slist_begin(fluxes);
00396
00397 while (first != cx_slist_end(fluxes)) {
00398
00399 cx_slist* subimages = cx_slist_new();
00400 cx_slist_iterator fpos = cx_slist_begin(subfibers);
00401
00402
00403 while (fpos != cx_slist_end(subfibers)) {
00404
00405 cpl_table* _fibers = cx_slist_get(subfibers, fpos);
00406
00407 GiImage* subimage = NULL;
00408 GiImage* flux = cx_slist_get(fluxes, first);
00409
00410 subimage = _giraffe_reconstruct_image(flux, _fibers);
00411
00412 cx_slist_push_back(subimages, subimage);
00413 fpos = cx_slist_next(subfibers, fpos);
00414
00415 }
00416
00417 cx_assert(cx_slist_size(subimages) == (cxsize) nslits);
00418
00419 cx_slist_push_back(subslits, subimages);
00420 first = cx_slist_next(fluxes, first);
00421
00422 }
00423
00424 cx_slist_destroy(subfibers, (cx_free_func) cpl_table_delete);
00425 cx_assert(cx_slist_size(subslits) == cx_slist_size(fluxes));
00426
00427 return 0;
00428
00429 }
00430
00431
00432 inline static cxint
00433 _giraffe_reconstruct_arrange_subslits(cx_slist* images,
00434 const cx_slist* subimages,
00435 cxint nrow, cxint ncolumn,
00436 cxint offset)
00437 {
00438
00439 cx_slist_iterator spos;
00440
00441
00442 cx_assert(images != NULL);
00443
00444 if (subimages == NULL || cx_slist_empty(subimages)) {
00445 return 1;
00446 }
00447
00448 if (ncolumn <= 0) {
00449 return 1;
00450 }
00451
00452 spos = cx_slist_begin(subimages);
00453
00454 while (spos != cx_slist_end(subimages)) {
00455
00456 cx_slist* subslits = cx_slist_get(subimages, spos);
00457
00458 cx_slist_iterator ipos = NULL;
00459
00460 cxint x = 0;
00461 cxint y = 0;
00462 cxint nx = 0;
00463 cxint ny = 0;
00464 cxint sx = 0;
00465 cxint sy = 0;
00466 cxint column = 0;
00467 cxint xshift = offset;
00468 cxint yshift = offset;
00469 cxint nslit = cx_slist_size(subslits);
00470
00471 cpl_propertylist* properties = NULL;
00472
00473 GiImage* image = NULL;
00474
00475
00476
00477
00478
00479
00480
00481
00482 ipos = cx_slist_begin(subslits);
00483
00484 while (ipos != cx_slist_end(subslits)) {
00485
00486 const GiImage* simage = cx_slist_get(subslits, ipos);
00487
00488 if (simage != NULL) {
00489
00490 cxint _nx = cpl_image_get_size_x(giraffe_image_get(simage));
00491 cxint _ny = cpl_image_get_size_y(giraffe_image_get(simage));
00492
00493 sx = CX_MAX(nx, _nx);
00494 sy = CX_MAX(ny, _ny);
00495
00496 if (properties == NULL) {
00497 properties = giraffe_image_get_properties(simage);
00498 }
00499
00500 }
00501
00502 ipos = cx_slist_next(subslits, ipos);
00503
00504 }
00505
00506 if (properties == NULL) {
00507 return 1;
00508 }
00509
00510
00511
00512
00513
00514
00515 nrow = CX_MAX(nslit / ncolumn, nrow);
00516
00517 if (nslit % ncolumn != 0) {
00518 ++nrow;
00519 }
00520
00521
00522
00523
00524
00525
00526 nx = sx * ncolumn;
00527 ny = sy * nrow;
00528
00529
00530 if (offset < 0) {
00531 xshift = nx / -offset + 1;
00532 yshift = ny / -offset + 1;
00533 }
00534
00535 nx += ncolumn * xshift - (xshift % 2);
00536 ny += nrow * yshift - (yshift % 2);
00537
00538
00539
00540
00541
00542
00543 image = giraffe_image_create(CPL_TYPE_DOUBLE, nx, ny);
00544 giraffe_image_set_properties(image, properties);
00545
00546 y = yshift / 2;
00547 x = xshift / 2;
00548
00549 ipos = cx_slist_begin(subslits);
00550
00551 while (ipos != cx_slist_end(subslits)) {
00552
00553 const GiImage* simage = cx_slist_get(subslits, ipos);
00554
00555 if (simage != NULL) {
00556
00557 cxint status = giraffe_image_paste(image, simage,
00558 x, y, TRUE);
00559
00560 if (status != 0) {
00561 giraffe_image_delete(image);
00562 return 1;
00563 }
00564
00565 }
00566
00567 ++column;
00568
00569 if (column < ncolumn) {
00570 x += sx + xshift;
00571 }
00572 else {
00573
00574 column = 0;
00575
00576 x = xshift / 2;
00577 y += sy + yshift;
00578
00579 }
00580
00581 ipos = cx_slist_next(subslits, ipos);
00582
00583 }
00584
00585 cx_slist_push_back(images, image);
00586 spos = cx_slist_next(subimages, spos);
00587
00588 }
00589
00590 return 0;
00591
00592 }
00593
00594
00616 cxint
00617 giraffe_reconstruction_build(GiReconstruction* result, GiRebinning* rebinning,
00618 GiTable* fibers, GiTable* wsolution,
00619 GiTable* grating, GiTable* slitgeometry,
00620 GiReconstructConfig* config)
00621 {
00622
00623 const cxchar* const fctid = "giraffe_reconstruction_build";
00624
00625 cxint status = 0;
00626
00627 cx_slist* fluxes = NULL;
00628 cx_slist* images = NULL;
00629
00630 cpl_propertylist* properties = NULL;
00631
00632 cpl_table* _fibers = NULL;
00633
00634 GiInstrumentMode mode;
00635
00636 GiRange* limits = NULL;
00637
00638 GiImage* tmp = NULL;
00639
00640 GiCube* scube = NULL;
00641 GiCube* ecube = NULL;
00642
00643
00644 if (result == NULL) {
00645 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00646 return -1;
00647 }
00648
00649 if ((result->spectra != NULL) || (result->errors != NULL) ||
00650 (result->cube_spectra != NULL) || (result->cube_errors != NULL)) {
00651 gi_warning("Results structure at %p is not empty! Contents "
00652 "might be lost.", fctid, result);
00653 }
00654
00655 if (rebinning == NULL) {
00656 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00657 return -1;
00658 }
00659
00660 if (rebinning->spectra == NULL || rebinning->errors == NULL) {
00661 cpl_error_set(fctid, CPL_ERROR_ILLEGAL_INPUT);
00662 return -1;
00663 }
00664
00665 if (fibers == NULL) {
00666 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00667 return -1;
00668 }
00669
00670 _fibers = giraffe_table_get(fibers);
00671
00672 if (_fibers == NULL) {
00673 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00674 return -1;
00675 }
00676
00677 if (!cpl_table_has_column(_fibers, "X") ||
00678 !cpl_table_has_column(_fibers, "Y")) {
00679 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00680 return -2;
00681 }
00682
00683 if (config == NULL) {
00684 cpl_error_set(fctid, CPL_ERROR_NULL_INPUT);
00685 return -1;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696 properties = giraffe_image_get_properties(rebinning->spectra);
00697
00698 if (properties == NULL) {
00699 cpl_error_set(fctid, CPL_ERROR_DATA_NOT_FOUND);
00700 return -1;
00701 }
00702
00703 mode = giraffe_get_mode(properties);
00704
00705
00706
00707
00708
00709
00710
00711
00712 limits = giraffe_rebin_get_wavelength_range(rebinning->spectra, wsolution,
00713 grating, slitgeometry, TRUE);
00714
00715 if (limits == NULL) {
00716 cpl_msg_error(fctid, "Computation of spectra common wavelength "
00717 "range failed!");
00718 return 1;
00719 }
00720
00721 if (config->minimum > 0.) {
00722 if (config->minimum < giraffe_range_get_min(limits)) {
00723 cpl_msg_warning(fctid, "Ignoring invalid wavelength range "
00724 "minimum %.3f nm", config->minimum);
00725 }
00726 else {
00727 giraffe_range_set_min(limits, config->minimum);
00728 }
00729 }
00730
00731 if (config->maximum > 0.) {
00732 if (config->maximum > giraffe_range_get_max(limits)) {
00733 cpl_msg_warning(fctid, "Ignoring invalid wavelength range "
00734 "maximum %.3f nm", config->maximum);
00735 }
00736 else {
00737 giraffe_range_set_max(limits, config->maximum);
00738 }
00739 }
00740
00741 cpl_msg_info(fctid, "Building image for wavelength range [%.3f nm, "
00742 "%.3f nm].", giraffe_range_get_min(limits),
00743 giraffe_range_get_max(limits));
00744
00745
00746
00747
00748
00749
00750 if (cpl_propertylist_has(properties, GIALIAS_BINSCALE)) {
00751
00752 const cxchar* s = cpl_propertylist_get_string(properties,
00753 GIALIAS_BINSCALE);
00754
00755 if (cx_strncasecmp(s, "log", 3) == 0) {
00756 giraffe_range_set_min(limits, log(giraffe_range_get_min(limits)));
00757 giraffe_range_set_max(limits, log(giraffe_range_get_max(limits)));
00758 }
00759 }
00760 else {
00761 cpl_msg_warning(fctid, "Could not determine spectrum wavelength "
00762 "scaling method. Missing property `%s'. Assuming "
00763 "scaling method `linear'!", GIALIAS_BINSCALE);
00764 }
00765
00766
00767
00768
00769
00770
00771
00772
00773 fluxes = cx_slist_new();
00774
00775 tmp = giraffe_integrate_flux(rebinning->spectra, limits);
00776
00777 if (tmp == NULL) {
00778 giraffe_range_delete(limits);
00779 return 1;
00780 }
00781
00782 cx_slist_push_back(fluxes, tmp);
00783
00784 if (rebinning->errors != NULL) {
00785
00786 GiImage* errors = giraffe_image_duplicate(rebinning->errors);
00787
00788 cpl_image_power(giraffe_image_get(errors), 2.);
00789
00790 tmp = giraffe_integrate_flux(errors, limits);
00791 giraffe_image_delete(errors);
00792
00793 if (tmp == NULL) {
00794 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00795 giraffe_range_delete(limits);
00796 return 1;
00797 }
00798
00799 cx_slist_push_back(fluxes, tmp);
00800 }
00801
00802 images = cx_slist_new();
00803
00804
00805 switch (mode) {
00806 case GIMODE_IFU:
00807 {
00808
00809 cxint nssn = 0;
00810 cxint* ssn = NULL;
00811
00812 cx_slist* subslits = NULL;
00813
00814
00815
00816
00817
00818
00819 nssn = _giraffe_reconstruct_get_subslits(&ssn, _fibers);
00820
00821 subslits = cx_slist_new();
00822
00823 status = _giraffe_reconstruct_build_subslits(subslits, fluxes,
00824 _fibers, nssn, ssn);
00825
00826 if (status) {
00827 cx_free(ssn);
00828 ssn = NULL;
00829
00830 cx_slist_destroy(subslits, (cx_free_func)giraffe_image_delete);
00831 subslits = NULL;
00832
00833 cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00834 images = NULL;
00835
00836 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00837 fluxes = NULL;
00838
00839 return 1;
00840 }
00841
00842 cx_free(ssn);
00843 ssn = NULL;
00844
00845 status = _giraffe_reconstruct_arrange_subslits(images, subslits,
00846 5, 3, -4);
00847
00848 if (status) {
00849 cx_slist_destroy(subslits, (cx_free_func)giraffe_image_delete);
00850 subslits = NULL;
00851
00852 cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00853 images = NULL;
00854
00855 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00856 fluxes = NULL;
00857
00858 return 1;
00859 }
00860
00861 break;
00862 }
00863
00864 case GIMODE_ARGUS:
00865 {
00866 status = _giraffe_reconstruct_build_images(images, fluxes,
00867 _fibers);
00868
00869 if (status) {
00870 cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00871 images = NULL;
00872
00873 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00874 fluxes = NULL;
00875
00876 return 1;
00877 }
00878
00879 if (config->cube == TRUE) {
00880
00881 scube = _giraffe_reconstruct_create_cube(rebinning->spectra,
00882 _fibers, limits);
00883
00884 if (scube == NULL) {
00885
00886 cx_slist_destroy(images,
00887 (cx_free_func)giraffe_image_delete);
00888 images = NULL;
00889
00890 cx_slist_destroy(fluxes,
00891 (cx_free_func)giraffe_image_delete);
00892 fluxes = NULL;
00893
00894 return 1;
00895
00896 }
00897
00898 ecube = _giraffe_reconstruct_create_cube(rebinning->errors,
00899 _fibers, limits);
00900
00901 if (ecube == NULL) {
00902
00903 giraffe_cube_delete(scube);
00904 scube = NULL;
00905
00906 cx_slist_destroy(images,
00907 (cx_free_func)giraffe_image_delete);
00908 images = NULL;
00909
00910 cx_slist_destroy(fluxes,
00911 (cx_free_func)giraffe_image_delete);
00912 fluxes = NULL;
00913
00914 return 1;
00915
00916 }
00917
00918 }
00919
00920 break;
00921 }
00922
00923 default:
00924 result->spectra = NULL;
00925 result->errors = NULL;
00926 result->cube_spectra = NULL;
00927 result->cube_errors = NULL;
00928
00929 return 1;
00930 break;
00931 }
00932
00933
00934
00935
00936
00937
00938
00939 cx_slist_destroy(fluxes, (cx_free_func)giraffe_image_delete);
00940
00941 giraffe_range_delete(limits);
00942
00943
00944
00945
00946
00947
00948 result->spectra = cx_slist_pop_front(images);
00949
00950 if (!cx_slist_empty(images)) {
00951
00952
00953
00954
00955
00956 GiImage* errors = cx_slist_pop_front(images);
00957
00958 cpl_image* _errors = giraffe_image_get(errors);
00959
00960 cxint i;
00961 cxint nx = cpl_image_get_size_x(_errors);
00962 cxint ny = cpl_image_get_size_y(_errors);
00963
00964 cxdouble* pixels = cpl_image_get_data(_errors);
00965
00966
00967 for (i = 0; i < nx * ny - 1; i++) {
00968 if (pixels[i] > 0.) {
00969 pixels[i] = sqrt(pixels[i]);
00970 }
00971 }
00972
00973 result->errors = errors;
00974
00975 }
00976
00977 if (scube != NULL) {
00978 result->cube_spectra = scube;
00979 }
00980
00981 if (ecube != NULL) {
00982 result->cube_errors = ecube;
00983 }
00984
00985 cx_assert(cx_slist_empty(images));
00986 cx_slist_destroy(images, (cx_free_func)giraffe_image_delete);
00987
00988 return 0;
00989
00990 }
00991
00992
01003 GiReconstruction*
01004 giraffe_reconstruction_new(void)
01005 {
01006
01007 GiReconstruction* self = cx_malloc(sizeof *self);
01008
01009 self->spectra = NULL;
01010 self->errors = NULL;
01011 self->cube_spectra = NULL;
01012 self->cube_errors = NULL;
01013
01014 return self;
01015
01016 }
01017
01018
01035 void
01036 giraffe_reconstruction_delete(GiReconstruction* reconstruction)
01037 {
01038
01039 if (reconstruction != NULL) {
01040 cx_free(reconstruction);
01041 reconstruction = NULL;
01042 }
01043
01044 return;
01045
01046 }
01047
01048
01062 void
01063 giraffe_reconstruction_destroy(GiReconstruction* reconstruction)
01064 {
01065
01066 if (reconstruction != NULL) {
01067
01068 if (reconstruction->spectra != NULL) {
01069 giraffe_image_delete(reconstruction->spectra);
01070 reconstruction->spectra = NULL;
01071 }
01072
01073 if (reconstruction->errors != NULL) {
01074 giraffe_image_delete(reconstruction->errors);
01075 reconstruction->errors = NULL;
01076 }
01077
01078 if (reconstruction->cube_spectra != NULL) {
01079 giraffe_cube_delete(reconstruction->cube_spectra);
01080 reconstruction->cube_spectra = NULL;
01081 }
01082
01083 if (reconstruction->cube_errors != NULL) {
01084 giraffe_cube_delete(reconstruction->cube_errors);
01085 reconstruction->cube_errors = NULL;
01086 }
01087
01088 cx_free(reconstruction);
01089 reconstruction = NULL;
01090
01091 }
01092
01093 return;
01094
01095 }
01096
01097
01108 GiReconstructConfig*
01109 giraffe_reconstruct_config_create(cpl_parameterlist* list)
01110 {
01111
01112 cpl_parameter* p;
01113
01114 GiReconstructConfig* config = NULL;
01115
01116
01117 if (list == NULL) {
01118 return NULL;
01119 }
01120
01121 config = cx_calloc(1, sizeof *config);
01122
01123
01124 p = cpl_parameterlist_find(list, "giraffe.reconstruction.range.minimum");
01125 config->minimum = cpl_parameter_get_double(p);
01126
01127 p = cpl_parameterlist_find(list, "giraffe.reconstruction.range.maximum");
01128 config->maximum = cpl_parameter_get_double(p);
01129
01130 p = cpl_parameterlist_find(list, "giraffe.reconstruction.cube");
01131 config->cube = cpl_parameter_get_bool(p);
01132
01133 return config;
01134
01135 }
01136
01137
01150 void
01151 giraffe_reconstruct_config_destroy(GiReconstructConfig* config)
01152 {
01153
01154 if (config != NULL) {
01155 cx_free(config);
01156 }
01157
01158 return;
01159
01160 }
01161
01162
01174 void
01175 giraffe_reconstruct_config_add(cpl_parameterlist* list)
01176 {
01177
01178 cpl_parameter* p;
01179
01180
01181 if (list == NULL) {
01182 return;
01183 }
01184
01185 p = cpl_parameter_new_value("giraffe.reconstruction.range.minimum",
01186 CPL_TYPE_DOUBLE,
01187 "Minimum wavelength for image reconstruction",
01188 "giraffe.reconstruction.range",
01189 0.);
01190 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-min");
01191 cpl_parameterlist_append(list, p);
01192
01193
01194 p = cpl_parameter_new_value("giraffe.reconstruction.range.maximum",
01195 CPL_TYPE_DOUBLE,
01196 "Maximum wavelength for image reconstruction",
01197 "giraffe.reconstruction.range",
01198 0.);
01199 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-max");
01200 cpl_parameterlist_append(list, p);
01201
01202
01203 p = cpl_parameter_new_value("giraffe.reconstruction.cube",
01204 CPL_TYPE_BOOL,
01205 "Turns data cube creation on and off "
01206 "(Argus only!)",
01207 "giraffe.reconstruction.cube",
01208 TRUE);
01209 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, "recon-cube");
01210 cpl_parameterlist_append(list, p);
01211
01212 return;
01213
01214 }