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 
54 inline 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 
103 cxint
104 giraffe_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 
203  giraffe_grating_delete(setup);
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);
215  giraffe_grating_delete(setup);
216  giraffe_rebinning_delete(fspectra);
217 
218  return 1;
219  }
220 
221  giraffe_grating_delete(setup);
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 
373  giraffe_rebinning_destroy(fspectra);
374 
375  return 0;
376 
377 }
378 
379 
380 cxint
381 giraffe_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 
466 cxint
467 giraffe_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 
544 cxint
545 giraffe_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 
600 GiTransmissionConfig *
601 giraffe_transmission_config_create(cpl_parameterlist *list)
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 
632 void
633 giraffe_transmission_config_destroy(GiTransmissionConfig *config)
634 {
635 
636  if (config) {
637  cx_free(config);
638  }
639 
640  return;
641 }
642 
643 
655 void
656 giraffe_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:715
const cxchar * giraffe_fiberlist_query_index(const cpl_table *fibers)
Query a fiber list for the name of the fiber reference index column.
void giraffe_grating_delete(GiGrating *self)
Destroys an GiGrating object.
Definition: gigrating.c:421
GiGrating * giraffe_grating_create(const GiImage *spectra, const GiTable *grating)
Create a GiGrating from a reference image.
Definition: gigrating.c:218
cpl_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
cpl_image * giraffe_image_get(const GiImage *self)
Gets the image data.
Definition: giimage.c:218
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
void giraffe_rebinning_destroy(GiRebinning *rebinning)
Destroys a rebinning results container and its contents.
Definition: girebinning.c:4787
GiRebinning * giraffe_rebinning_new(void)
Create an empty rebinning results container.
Definition: girebinning.c:4693
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.10.
Documentation copyright © 2002-2006 European Southern Observatory.
Generated on Thu Dec 15 2022 21:18:51 by doxygen 1.9.1 written by Dimitri van Heesch, © 1997-2004