GIRAFFE Pipeline Reference Manual

gitransmission.c
1/*
2 * This file is part of the GIRAFFE Pipeline
3 * Copyright (C) 2002-2019 European Southern Observatory
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include <math.h>
25
26#include <cxmemory.h>
27#include <cxmessages.h>
28#include <cxstrutils.h>
29
30#include <cpl_msg.h>
31#include <cpl_parameterlist.h>
32#include <cpl_propertylist.h>
33#include <cpl_image.h>
34
35#include "gialias.h"
36#include "gierror.h"
37#include "gimessages.h"
38#include "gifiberutils.h"
39#include "gigrating.h"
40#include "giwlsolution.h"
41#include "giextraction.h"
42#include "girebinning.h"
43#include "gitransmission.h"
44
45
54inline static cxint
55_giraffe_transmission_apply(cpl_image *spectra, cpl_table *fibers)
56{
57
58 cxint i;
59 cxint nx = 0;
60 cxint ny = 0;
61
62
63 cxdouble *pixels = NULL;
64
65
66 cx_assert(spectra != NULL);
67 cx_assert(fibers != NULL);
68
69 nx = cpl_image_get_size_x(spectra);
70 ny = cpl_image_get_size_y(spectra);
71
72 pixels = cpl_image_get_data(spectra);
73
74 if (pixels == NULL) {
75 return 1;
76 }
77
78
79 /*
80 * For each fiber spectrum each wavelength resolution element is
81 * corrected for the relative fiber transmission effects.
82 */
83
84 for (i = 0; i < cpl_table_get_nrow(fibers); i++) {
85
86 register cxint j;
87
88 register cxdouble tc = cpl_table_get_double(fibers, "TRANSMISSION",
89 i, NULL);
90
91
92 for (j = 0; j < ny; j++) {
93 pixels[j * nx + i] /= tc;
94 }
95
96 }
97
98 return 0;
99
100}
101
102
103cxint
104giraffe_transmission_compute(GiExtraction *extraction, GiTable *fibers,
105 GiLocalization *localization,
106 GiTable *wcalcoeff, GiTable *grating,
107 GiTable *slitgeometry)
108{
109
110 const cxchar *idx = NULL;
111
112 cxint i;
113 cxint pos = 0;
114 cxint status = 0;
115
116 cxdouble peak = 0.;
117 cxdouble *flux = NULL;
118 cxdouble *error = NULL;
119
120 cpl_image *tflux = NULL;
121 cpl_image *tvariance = NULL;
122 cpl_image *variance = NULL;
123
124 cpl_table *_fibers = NULL;
125
126 GiImage *spectra = NULL;
127
128 GiTable *_wcalcoeff = NULL;
129
130 GiRebinning *fspectra = giraffe_rebinning_new();
131
132 GiRebinConfig rebin_config = {
133 GIREBIN_METHOD_LINEAR,
134 TRUE,
135 0.005,
136 GIREBIN_SCALE_LINEAR,
137 0,
138 GIREBIN_RANGE_COMMON
139 };
140
141
142 if (extraction == NULL) {
143 return 1;
144 }
145
146 if (extraction->spectra == NULL || extraction->error == NULL) {
147 return 1;
148 }
149
150 spectra = extraction->spectra;
151
152
153 /*
154 * If no wavelength solution table was provided create a default one.
155 * The wavelength solution residuals are not available in this case
156 * and are therefore disabled for the rebinning.
157 */
158
159 if (wcalcoeff == NULL) {
160
161 cxint nx = 0;
162
163 cxdouble pixsize = 0.;
164
165 cpl_propertylist *properties = giraffe_image_get_properties(spectra);
166
167 cpl_image *_spectra = giraffe_image_get(spectra);
168
169 GiGrating *setup = NULL;
170
171 GiWlSolution *solution = NULL;
172
173
174 if (!cpl_propertylist_has(properties, GIALIAS_PIXSIZX)) {
175
176 giraffe_rebinning_delete(fspectra);
177 return 1;
178
179 }
180 else {
181
182 pixsize = cpl_propertylist_get_double(properties,
183 GIALIAS_PIXSIZX);
184 pixsize /= 1000.;
185
186 }
187
188 nx = cpl_image_get_size_y(_spectra);
189
190 setup = giraffe_grating_create(spectra, grating);
191
192 if (setup == NULL) {
193
194 giraffe_rebinning_delete(fspectra);
195 return 1;
196
197 }
198
199 solution = giraffe_wlsolution_new("xoptmod2", 1, nx, pixsize, setup);
200
201 if (solution == NULL) {
202
204 giraffe_rebinning_delete(fspectra);
205
206 return 1;
207
208 }
209
210 _wcalcoeff = giraffe_wlsolution_create_table(solution);
211
212 if (_wcalcoeff == NULL) {
213
214 giraffe_wlsolution_delete(solution);
216 giraffe_rebinning_delete(fspectra);
217
218 return 1;
219 }
220
222 setup = NULL;
223
224 giraffe_wlsolution_delete(solution);
225 solution = NULL;
226
227 rebin_config.xresiduals = FALSE;
228
229 wcalcoeff = _wcalcoeff;
230
231 }
232
233
234 status = giraffe_rebin_spectra(fspectra, extraction, fibers,
235 localization, grating, slitgeometry,
236 wcalcoeff, &rebin_config);
237
238 if (status) {
239
240 if (_wcalcoeff != NULL) {
241 giraffe_table_delete(_wcalcoeff);
242 _wcalcoeff = NULL;
243 }
244
245 giraffe_rebinning_delete(fspectra);
246 fspectra = NULL;
247
248 return 1;
249
250 }
251
252 if (_wcalcoeff != NULL) {
253 giraffe_table_delete(_wcalcoeff);
254 _wcalcoeff = NULL;
255 }
256
257
258 tflux = cpl_image_collapse_create(giraffe_image_get(fspectra->spectra),
259 0);
260
261 if (tflux == NULL) {
262 giraffe_rebinning_delete(fspectra);
263 return 1;
264 }
265
266
267 /*
268 * The spectrum errors are the standard deviation. i.e. to get the
269 * error of the total flux the variances have to be summed.
270 */
271
272 variance = cpl_image_power_create(giraffe_image_get(fspectra->errors),
273 2.);
274
275 if (variance == NULL) {
276 cpl_image_delete(tflux);
277 tflux = NULL;
278
279 giraffe_rebinning_delete(fspectra);
280 fspectra = NULL;
281
282 return 1;
283 }
284
285 tvariance = cpl_image_collapse_create(variance, 0);
286
287 if (tvariance == NULL) {
288 cpl_image_delete(variance);
289 variance = NULL;
290
291 cpl_image_delete(tflux);
292 tflux = NULL;
293
294 giraffe_rebinning_delete(fspectra);
295 fspectra = NULL;
296
297 return 1;
298 }
299
300
301 cpl_image_delete(variance);
302 variance = NULL;
303
304 _fibers = giraffe_table_get(fibers);
305 idx = giraffe_fiberlist_query_index(_fibers);
306
307 flux = cpl_image_get_data(tflux);
308
309 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
310
311 register cxint rp = cpl_table_get_int(_fibers, "RP", i, NULL);
312
313 if (rp != -1) {
314
315 register cxint j = cpl_table_get_int(_fibers, idx, i , NULL) - 1;
316
317 if (flux[j] > peak) {
318 peak = flux[j];
319 pos = i;
320 }
321
322 }
323
324 }
325
326 giraffe_error_push();
327
328 cpl_table_new_column(_fibers, "TRANSMISSION", CPL_TYPE_DOUBLE);
329 cpl_table_new_column(_fibers, "DTRANSMISSION", CPL_TYPE_DOUBLE);
330
331 if (cpl_error_get_code() != CPL_ERROR_NONE) {
332
333 cpl_image_delete(tflux);
334 tflux = NULL;
335
336 cpl_image_delete(tvariance);
337 tvariance = NULL;
338
339 giraffe_rebinning_delete(fspectra);
340 fspectra = NULL;
341
342 return 1;
343 }
344
345 giraffe_error_pop();
346
347
348 error = cpl_image_get_data(tvariance);
349
350 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
351
352 cxint rp = cpl_table_get_int(_fibers, "RP", i, NULL);
353
354 if (rp == -1 || i == pos) {
355 cpl_table_set_double(_fibers, "TRANSMISSION", i, 1.);
356 cpl_table_set_double(_fibers, "DTRANSMISSION", i, 0.);
357 }
358 else {
359
360 cxint j = cpl_table_get_int(_fibers, idx, i , NULL) - 1;
361
362 cpl_table_set_double(_fibers, "TRANSMISSION", i, flux[j] / peak);
363 cpl_table_set_double(_fibers, "DTRANSMISSION", i,
364 sqrt(error[j]) / peak);
365
366 }
367
368 }
369
370 cpl_image_delete(tflux);
371 cpl_image_delete(tvariance);
372
374
375 return 0;
376
377}
378
379
380cxint
381giraffe_transmission_setup(GiTable *fibers, GiTable *reference)
382{
383
384 cxint i;
385
386 cpl_table *_fibers = NULL;
387 cpl_table *_reference = NULL;
388
389
390 if (fibers == NULL) {
391 return -1;
392 }
393
394 if (reference == NULL) {
395 return -2;
396 }
397
398 _fibers = giraffe_table_get(fibers);
399 _reference = giraffe_table_get(reference);
400
401 if (_fibers == NULL || cpl_table_has_column(_fibers, "FPS") == 0) {
402 return -3;
403 }
404
405 if (_reference == NULL) {
406 return -4;
407 }
408
409 if (cpl_table_has_column(_reference, "FPS") == 0 ||
410 cpl_table_has_column(_reference, "TRANSMISSION") == 0) {
411 return -4;
412 }
413
414 if (cpl_table_has_column(_fibers, "TRANSMISSION") == 0) {
415
416 cxint status = cpl_table_new_column(_fibers, "TRANSMISSION",
417 CPL_TYPE_DOUBLE);
418
419 if (status) {
420 return 1;
421 }
422
423 }
424
425 for (i = 0; i < cpl_table_get_nrow(_fibers); i++) {
426
427 cxint j;
428 cxint nrows = cpl_table_get_nrow(_reference);
429 cxint fps = cpl_table_get_int(_fibers, "FPS", i, NULL);
430
431 cxdouble t = -1.;
432
433
434 for (j = 0; j < nrows; j++) {
435
436 cxint _fps = cpl_table_get_int(_reference, "FPS", j, NULL);
437
438 if (fps == _fps) {
439 t = cpl_table_get_double(_reference, "TRANSMISSION", j, NULL);
440 break;
441 }
442 }
443
444 if (t < 0.) {
445 cpl_table_erase_column(_fibers, "TRANSMISSION");
446 return 2;
447 }
448 else {
449
450 cxint status = cpl_table_set_double(_fibers, "TRANSMISSION",
451 i, t);
452
453 if (status) {
454 return 3;
455 }
456
457 }
458
459 }
460
461 return 0;
462
463}
464
465
466cxint
467giraffe_transmission_apply(GiExtraction *extraction, GiTable *fibers)
468{
469
470 cxint status;
471
472 cpl_image *_spectra = NULL;
473
474 cpl_table *_fibers = NULL;
475
476
477
478 if (extraction == NULL) {
479 return -1;
480 }
481
482 if (fibers == NULL) {
483 return -2;
484 }
485
486
487 if (extraction->spectra == NULL) {
488 return -3;
489 }
490
491 _fibers = giraffe_table_get(fibers);
492
493 if (_fibers == NULL) {
494 return -4;
495 }
496
497
498 if (cpl_table_has_column(_fibers, "TRANSMISSION") == 0) {
499 return -5;
500 }
501
502
503 _spectra = giraffe_image_get(extraction->spectra);
504 status = _giraffe_transmission_apply(_spectra, _fibers);
505
506 if (status != 0) {
507 return 1;
508 }
509
510 if (extraction->error != NULL) {
511
512 _spectra = giraffe_image_get(extraction->error);
513 status = _giraffe_transmission_apply(_spectra, _fibers);
514
515 if (status != 0) {
516 return 1;
517 }
518 }
519
520 return 0;
521
522}
523
524
544cxint
545giraffe_transmission_attach(GiTable* fibers, const cxchar* filename)
546{
547
548 const cxchar* const _id = "giraffe_transmission_attach";
549
550 cxint status = 0;
551
552 GiTable* _fibers = NULL;
553
554
555 if ((fibers == NULL) || (filename == NULL)) {
556 return -1;
557 }
558
559
560 _fibers = giraffe_fiberlist_load(filename, 1, "FIBER_SETUP");
561
562 if (fibers == NULL) {
563 cpl_error_set(_id, CPL_ERROR_ILLEGAL_INPUT);
564 return 1;
565 }
566
567
568 status = giraffe_transmission_setup(fibers, _fibers);
569
570 giraffe_table_delete(_fibers);
571 _fibers = NULL;
572
573 if (status < 0) {
574 cpl_error_set(_id, CPL_ERROR_DATA_NOT_FOUND);
575 return 2;
576 }
577
578 if (status > 0) {
579 cpl_error_set(_id, CPL_ERROR_INCOMPATIBLE_INPUT);
580 return 3;
581 }
582
583 return status;
584
585}
586
587
600GiTransmissionConfig *
602{
603
604 GiTransmissionConfig *config = NULL;
605
606
607 if (!list) {
608 return NULL;
609 }
610
611 config = cx_calloc(1, sizeof *config);
612
613 return config;
614
615}
616
617
632void
633giraffe_transmission_config_destroy(GiTransmissionConfig *config)
634{
635
636 if (config) {
637 cx_free(config);
638 }
639
640 return;
641}
642
643
655void
656giraffe_transmission_config_add(cpl_parameterlist *list)
657{
658
659 if (!list) {
660 return;
661 }
662
663 return;
664
665}
GiTable * giraffe_fiberlist_load(const cxchar *filename, cxint dataset, const cxchar *tag)
Load a fiber table from a file.
Definition: gifiberutils.c:753
const cxchar * giraffe_fiberlist_query_index(const cpl_table *fibers)
Query a fiber list for the name of the fiber reference index column.
GiGrating * giraffe_grating_create(const GiImage *spectra, const GiTable *grating)
Create a GiGrating from a reference image.
Definition: gigrating.c:218
void giraffe_grating_delete(GiGrating *self)
Destroys an GiGrating object.
Definition: gigrating.c:421
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
Definition: giimage.c:218
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
cxint giraffe_rebin_spectra(GiRebinning *rebinning, const GiExtraction *extraction, const GiTable *fibers, const GiLocalization *localization, const GiTable *grating, const GiTable *slitgeo, const GiTable *solution, const GiRebinConfig *config)
Rebin an Extracted Spectra Frame and associated Errors Frame.
Definition: girebinning.c:4051
void giraffe_rebinning_delete(GiRebinning *rebinning)
Destroys a rebinning results container.
Definition: girebinning.c:4759
GiRebinning * giraffe_rebinning_new(void)
Create an empty rebinning results container.
Definition: girebinning.c:4693
void giraffe_rebinning_destroy(GiRebinning *rebinning)
Destroys a rebinning results container and its contents.
Definition: girebinning.c:4787
void giraffe_table_delete(GiTable *self)
Destroys a Giraffe table.
Definition: gitable.c:154
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
Definition: gitable.c:433
GiTransmissionConfig * giraffe_transmission_config_create(cpl_parameterlist *list)
Creates a setup structure for the relative transmission computation.
void giraffe_transmission_config_add(cpl_parameterlist *list)
Adds parameters for the transmission correction computation.
void giraffe_transmission_config_destroy(GiTransmissionConfig *config)
Destroys a transmission field setup structure.
cxint giraffe_transmission_attach(GiTable *fibers, const cxchar *filename)
Load relative fiber transmission data from a file and add it to a fiber table.
Structure to handle Grating Information.
Definition: gigrating.h:44

This file is part of the GIRAFFE Pipeline Reference Manual 2.16.14.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Wed Jun 11 2025 18:41:44 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2004