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 <cxmemory.h>
00035 #include <cxmessages.h>
00036 #include <cxstrutils.h>
00037
00038 #include <cpl_msg.h>
00039 #include <cpl_parameterlist.h>
00040 #include <cpl_propertylist.h>
00041 #include <cpl_image.h>
00042
00043 #include "gialias.h"
00044 #include "gierror.h"
00045 #include "gimessages.h"
00046 #include "gifiberutils.h"
00047 #include "gigrating.h"
00048 #include "giwlsolution.h"
00049 #include "giextraction.h"
00050 #include "girebinning.h"
00051 #include "gitransmission.h"
00052
00053
00062 inline static cxint
00063 _giraffe_transmission_apply(cpl_image *spectra, cpl_table *fibers)
00064 {
00065
00066 cxint i;
00067 cxint nx = 0;
00068 cxint ny = 0;
00069
00070
00071 cxdouble *pixels = NULL;
00072
00073
00074 cx_assert(spectra != NULL);
00075 cx_assert(fibers != NULL);
00076
00077 nx = cpl_image_get_size_x(spectra);
00078 ny = cpl_image_get_size_y(spectra);
00079
00080 pixels = cpl_image_get_data(spectra);
00081
00082 if (pixels == NULL) {
00083 return 1;
00084 }
00085
00086
00087
00088
00089
00090
00091
00092 for (i = 0; i < cpl_table_get_nrow(fibers); i++) {
00093
00094 register cxint j;
00095
00096 register cxdouble tc = cpl_table_get_double(fibers, "TRANSMISSION",
00097 i, NULL);
00098
00099
00100 for (j = 0; j < ny; j++) {
00101 pixels[j * nx + i] /= tc;
00102 }
00103
00104 }
00105
00106 return 0;
00107
00108 }
00109
00110
00111 cxint
00112 giraffe_transmission_compute(GiExtraction *extraction, GiTable *fibers,
00113 GiLocalization *localization,
00114 GiTable *wcalcoeff, GiTable *grating,
00115 GiTable *slitgeometry)
00116 {
00117
00118 const cxchar *idx = NULL;
00119
00120 cxint i;
00121 cxint pos = 0;
00122 cxint status = 0;
00123
00124 cxdouble peak = 0.;
00125 cxdouble *flux = NULL;
00126 cxdouble *error = NULL;
00127
00128 cpl_image *tflux = NULL;
00129 cpl_image *tvariance = NULL;
00130 cpl_image *variance = NULL;
00131
00132 cpl_table *_fibers = NULL;
00133
00134 GiImage *spectra = NULL;
00135
00136 GiTable *_wcalcoeff = NULL;
00137
00138 GiRebinning *fspectra = giraffe_rebinning_new();
00139
00140 GiRebinConfig rebin_config = {
00141 GIREBIN_METHOD_LINEAR,
00142 TRUE,
00143 0.005,
00144 GIREBIN_SCALE_LINEAR,
00145 0,
00146 GIREBIN_RANGE_COMMON
00147 };
00148
00149
00150 if (extraction == NULL) {
00151 return 1;
00152 }
00153
00154 if (extraction->spectra == NULL || extraction->error == NULL) {
00155 return 1;
00156 }
00157
00158 spectra = extraction->spectra;
00159
00160
00161
00162
00163
00164
00165
00166
00167 if (wcalcoeff == NULL) {
00168
00169 cxint nx = 0;
00170
00171 cxdouble pixsize = 0.;
00172
00173 cpl_propertylist *properties = giraffe_image_get_properties(spectra);
00174
00175 cpl_image *_spectra = giraffe_image_get(spectra);
00176
00177 GiGrating *setup = NULL;
00178
00179 GiWlSolution *solution = NULL;
00180
00181
00182 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
00183
00184 giraffe_rebinning_delete(fspectra);
00185 return 1;
00186
00187 }
00188 else {
00189
00190 pixsize = cpl_propertylist_get_double(properties,
00191 GIALIAS_PIXSIZX);
00192 pixsize /= 1000.;
00193
00194 }
00195
00196 nx = cpl_image_get_size_y(_spectra);
00197
00198 setup = giraffe_grating_create(spectra, grating);
00199
00200 if (setup == NULL) {
00201
00202 giraffe_rebinning_delete(fspectra);
00203 return 1;
00204
00205 }
00206
00207 solution = giraffe_wlsolution_new("xoptmod2", 1, nx, pixsize, setup);
00208
00209 if (solution == NULL) {
00210
00211 giraffe_grating_delete(setup);
00212 giraffe_rebinning_delete(fspectra);
00213
00214 return 1;
00215
00216 }
00217
00218 _wcalcoeff = giraffe_wlsolution_create_table(solution);
00219
00220 if (_wcalcoeff == NULL) {
00221
00222 giraffe_wlsolution_delete(solution);
00223 giraffe_grating_delete(setup);
00224 giraffe_rebinning_delete(fspectra);
00225
00226 return 1;
00227 }
00228
00229 giraffe_grating_delete(setup);
00230 setup = NULL;
00231
00232 giraffe_wlsolution_delete(solution);
00233 solution = NULL;
00234
00235 rebin_config.xresiduals = FALSE;
00236
00237 wcalcoeff = _wcalcoeff;
00238
00239 }
00240
00241
00242 status = giraffe_rebin_spectra(fspectra, extraction, fibers,
00243 localization, grating, slitgeometry,
00244 wcalcoeff, &rebin_config);
00245
00246 if (status) {
00247
00248 if (_wcalcoeff != NULL) {
00249 giraffe_table_delete(_wcalcoeff);
00250 _wcalcoeff = NULL;
00251 }
00252
00253 giraffe_rebinning_delete(fspectra);
00254 fspectra = NULL;
00255
00256 return 1;
00257
00258 }
00259
00260 if (_wcalcoeff != NULL) {
00261 giraffe_table_delete(_wcalcoeff);
00262 _wcalcoeff = NULL;
00263 }
00264
00265
00266 tflux = cpl_image_collapse_create(giraffe_image_get(fspectra->spectra),
00267 0);
00268
00269 if (tflux == NULL) {
00270 giraffe_rebinning_delete(fspectra);
00271 return 1;
00272 }
00273
00274
00275
00276
00277
00278
00279
00280 variance = cpl_image_power_create(giraffe_image_get(fspectra->errors),
00281 2.);
00282
00283 if (variance == NULL) {
00284 cpl_image_delete(tflux);
00285 tflux = NULL;
00286
00287 giraffe_rebinning_delete(fspectra);
00288 fspectra = NULL;
00289
00290 return 1;
00291 }
00292
00293 tvariance = cpl_image_collapse_create(variance, 0);
00294
00295 if (tvariance == NULL) {
00296 cpl_image_delete(variance);
00297 variance = NULL;
00298
00299 cpl_image_delete(tflux);
00300 tflux = NULL;
00301
00302 giraffe_rebinning_delete(fspectra);
00303 fspectra = NULL;
00304
00305 return 1;
00306 }
00307
00308
00309 cpl_image_delete(variance);
00310 variance = NULL;
00311
00312 _fibers = giraffe_table_get(fibers);
00313 idx = giraffe_fiberlist_query_index(_fibers);
00314
00315 flux = cpl_image_get_data(tflux);
00316
00317 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
00318
00319 register cxint rp = cpl_table_get_int(_fibers, "RP", i, NULL);
00320
00321 if (rp != -1) {
00322
00323 register cxint j = cpl_table_get_int(_fibers, idx, i , NULL) - 1;
00324
00325 if (flux[j] > peak) {
00326 peak = flux[j];
00327 pos = i;
00328 }
00329
00330 }
00331
00332 }
00333
00334 giraffe_error_push();
00335
00336 cpl_table_new_column(_fibers, "TRANSMISSION", CPL_TYPE_DOUBLE);
00337 cpl_table_new_column(_fibers, "DTRANSMISSION", CPL_TYPE_DOUBLE);
00338
00339 if (cpl_error_get_code() != CPL_ERROR_NONE) {
00340
00341 cpl_image_delete(tflux);
00342 tflux = NULL;
00343
00344 cpl_image_delete(tvariance);
00345 tvariance = NULL;
00346
00347 giraffe_rebinning_delete(fspectra);
00348 fspectra = NULL;
00349
00350 return 1;
00351 }
00352
00353 giraffe_error_pop();
00354
00355
00356 error = cpl_image_get_data(tvariance);
00357
00358 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
00359
00360 cxint rp = cpl_table_get_int(_fibers, "RP", i, NULL);
00361
00362 if (rp == -1 || i == pos) {
00363 cpl_table_set_double(_fibers, "TRANSMISSION", i, 1.);
00364 cpl_table_set_double(_fibers, "DTRANSMISSION", i, 0.);
00365 }
00366 else {
00367
00368 cxint j = cpl_table_get_int(_fibers, idx, i , NULL) - 1;
00369
00370 cpl_table_set_double(_fibers, "TRANSMISSION", i, flux[j] / peak);
00371 cpl_table_set_double(_fibers, "DTRANSMISSION", i,
00372 sqrt(error[j]) / peak);
00373
00374 }
00375
00376 }
00377
00378 cpl_image_delete(tflux);
00379 cpl_image_delete(tvariance);
00380
00381 giraffe_rebinning_destroy(fspectra);
00382
00383 return 0;
00384
00385 }
00386
00387
00388 cxint
00389 giraffe_transmission_setup(GiTable *fibers, GiTable *reference)
00390 {
00391
00392 cxint i;
00393
00394 cpl_table *_fibers = NULL;
00395 cpl_table *_reference = NULL;
00396
00397
00398 if (fibers == NULL) {
00399 return -1;
00400 }
00401
00402 if (reference == NULL) {
00403 return -2;
00404 }
00405
00406 _fibers = giraffe_table_get(fibers);
00407 _reference = giraffe_table_get(reference);
00408
00409 if (_fibers == NULL || cpl_table_has_column(_fibers, "FPS") == 0) {
00410 return -3;
00411 }
00412
00413 if (_reference == NULL) {
00414 return -4;
00415 }
00416
00417 if (cpl_table_has_column(_reference, "FPS") == 0 ||
00418 cpl_table_has_column(_reference, "TRANSMISSION") == 0) {
00419 return -4;
00420 }
00421
00422 if (cpl_table_has_column(_fibers, "TRANSMISSION") == 0) {
00423
00424 cxint status = cpl_table_new_column(_fibers, "TRANSMISSION",
00425 CPL_TYPE_DOUBLE);
00426
00427 if (status) {
00428 return 1;
00429 }
00430
00431 }
00432
00433 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
00434
00435 cxint j;
00436 cxint nrows = cpl_table_get_nrow(_reference);
00437 cxint fps = cpl_table_get_int(_fibers, "FPS", i, NULL);
00438
00439 cxdouble t = -1.;
00440
00441
00442 for (j = 0; j < nrows; j++) {
00443
00444 cxint _fps = cpl_table_get_int(_reference, "FPS", j, NULL);
00445
00446 if (fps == _fps) {
00447 t = cpl_table_get_double(_reference, "TRANSMISSION", j, NULL);
00448 break;
00449 }
00450 }
00451
00452 if (t < 0.) {
00453 cpl_table_erase_column(_fibers, "TRANSMISSION");
00454 return 2;
00455 }
00456 else {
00457
00458 cxint status = cpl_table_set_double(_fibers, "TRANSMISSION",
00459 i, t);
00460
00461 if (status) {
00462 return 3;
00463 }
00464
00465 }
00466
00467 }
00468
00469 return 0;
00470
00471 }
00472
00473
00474 cxint
00475 giraffe_transmission_apply(GiExtraction *extraction, GiTable *fibers)
00476 {
00477
00478 cxint status;
00479
00480 cpl_image *_spectra = NULL;
00481
00482 cpl_table *_fibers = NULL;
00483
00484
00485
00486 if (extraction == NULL) {
00487 return -1;
00488 }
00489
00490 if (fibers == NULL) {
00491 return -2;
00492 }
00493
00494
00495 if (extraction->spectra == NULL) {
00496 return -3;
00497 }
00498
00499 _fibers = giraffe_table_get(fibers);
00500
00501 if (_fibers == NULL) {
00502 return -4;
00503 }
00504
00505
00506 if (cpl_table_has_column(_fibers, "TRANSMISSION") == 0) {
00507 return -5;
00508 }
00509
00510
00511 _spectra = giraffe_image_get(extraction->spectra);
00512 status = _giraffe_transmission_apply(_spectra, _fibers);
00513
00514 if (status != 0) {
00515 return 1;
00516 }
00517
00518 if (extraction->error != NULL) {
00519
00520 _spectra = giraffe_image_get(extraction->error);
00521 status = _giraffe_transmission_apply(_spectra, _fibers);
00522
00523 if (status != 0) {
00524 return 1;
00525 }
00526 }
00527
00528 return 0;
00529
00530 }
00531
00532
00552 cxint
00553 giraffe_transmission_attach(GiTable* fibers, const cxchar* filename)
00554 {
00555
00556 const cxchar* const _id = "giraffe_transmission_attach";
00557
00558 cxint status = 0;
00559
00560 GiTable* _fibers = NULL;
00561
00562
00563 if ((fibers == NULL) || (filename == NULL)) {
00564 return -1;
00565 }
00566
00567
00568 _fibers = giraffe_fiberlist_load(filename, 1, "FIBER_SETUP");
00569
00570 if (fibers == NULL) {
00571 cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
00572 return 1;
00573 }
00574
00575
00576 status = giraffe_transmission_setup(fibers, _fibers);
00577
00578 giraffe_table_delete(_fibers);
00579 _fibers = NULL;
00580
00581 if (status < 0) {
00582 cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
00583 return 2;
00584 }
00585
00586 if (status > 0) {
00587 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
00588 return 3;
00589 }
00590
00591 return status;
00592
00593 }
00594
00595
00608 GiTransmissionConfig *
00609 giraffe_transmission_config_create(cpl_parameterlist *list)
00610 {
00611
00612 GiTransmissionConfig *config = NULL;
00613
00614
00615 if (!list) {
00616 return NULL;
00617 }
00618
00619 config = cx_calloc(1, sizeof *config);
00620
00621 return config;
00622
00623 }
00624
00625
00640 void
00641 giraffe_transmission_config_destroy(GiTransmissionConfig *config)
00642 {
00643
00644 if (config) {
00645 cx_free(config);
00646 }
00647
00648 return;
00649 }
00650
00651
00663 void
00664 giraffe_transmission_config_add(cpl_parameterlist *list)
00665 {
00666
00667 if (!list) {
00668 return;
00669 }
00670
00671 return;
00672
00673 }