GIRAFFE Pipeline Reference Manual

gigrating.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 "gimacros.h"
27#include "gialias.h"
28#include "gigrating.h"
29
30#define GIFITS_KEYWORD_MISSING_MSG "FITS KEYWORD [%s] not found!! Aborting..."
31
32
41static const cxdouble GI_WAVELENGTH_EPSILON = 1.e-8; /* 1.e-4 */
42
43
44inline static cxint
45_giraffe_grating_copy(GiGrating *self, cpl_table *grating, cxint row,
46 GiInstrumentMode mode)
47{
48
49 const cxchar *c_resolution = NULL;
50
51
52 cx_assert(self != NULL);
53 cx_assert(grating != NULL);
54
55
56 if (row >= cpl_table_get_nrow(grating)) {
57 return 1;
58 }
59
60
61 if (!cpl_table_has_column(grating, "ORDER")) {
62 return 2;
63 }
64 else {
65 self->order = cpl_table_get_int(grating, "ORDER", row, NULL);
66 }
67
68
69 if (!cpl_table_has_column(grating, "WLEN0")) {
70 return 2;
71 }
72 else {
73 self->wlen0 = cpl_table_get_double(grating, "WLEN0", row, NULL);
74 }
75
76
77 if (!cpl_table_has_column(grating, "WLMIN")) {
78 return 2;
79 }
80 else {
81 self->wlenmin = cpl_table_get_double(grating, "WLMIN", row, NULL);
82 }
83
84
85 if (!cpl_table_has_column(grating, "WLMAX")) {
86 return 2;
87 }
88 else {
89 self->wlenmax = cpl_table_get_double(grating, "WLMAX", row, NULL);
90 }
91
92
93 if (!cpl_table_has_column(grating, "BAND")) {
94 return 2;
95 }
96 else {
97 self->band = cpl_table_get_double(grating, "BAND", row, NULL);
98 }
99
100
101 switch (mode) {
102 case GIMODE_MEDUSA:
103 c_resolution = "RMED";
104 break;
105
106 case GIMODE_IFU:
107 case GIMODE_ARGUS:
108 c_resolution = "RIFA";
109 break;
110
111 default:
112 return 3;
113 break;
114 }
115
116 if (!cpl_table_has_column(grating, c_resolution)) {
117 return 2;
118 }
119 else {
120 self->resol = cpl_table_get_int(grating, c_resolution, row, NULL);
121 }
122
123
124 if (!cpl_table_has_column(grating, "THETA")) {
125 return 2;
126 }
127 else {
128 self->theta = cpl_table_get_double(grating, "THETA", row, NULL);
129 }
130
131
132 if (!cpl_table_has_column(grating, "FCOLL")) {
133 return 2;
134 }
135 else {
136 self->fcoll = cpl_table_get_double(grating, "FCOLL", row, NULL);
137 }
138
139
140 if (!cpl_table_has_column(grating, "GCAM")) {
141 return 2;
142 }
143 else {
144 self->gcam = cpl_table_get_double(grating, "GCAM", row, NULL);
145 }
146
147
148 if (!cpl_table_has_column(grating, "SDX")) {
149 return 2;
150 }
151 else {
152 self->sdx = cpl_table_get_double(grating, "SDX", row, NULL);
153 }
154
155
156 if (!cpl_table_has_column(grating, "SDY")) {
157 return 2;
158 }
159 else {
160 self->sdy = cpl_table_get_double(grating, "SDY", row, NULL);
161 }
162
163
164 if (!cpl_table_has_column(grating, "SPHI")) {
165 return 2;
166 }
167 else {
168 self->sphi = cpl_table_get_double(grating, "SPHI", row, NULL);
169 }
170
171 return 0;
172
173}
174
175
185GiGrating *
187{
188
189 GiGrating *grating = (GiGrating *) cx_calloc(1, sizeof *grating);
190
191 grating->name = cx_string_new();
192 grating->setup = cx_string_new();
193 grating->filter = cx_string_new();
194 grating->slit = cx_string_new();
195
196 return grating;
197
198}
199
200
217GiGrating *
218giraffe_grating_create(const GiImage *spectra, const GiTable *grating)
219{
220
221 const cxchar *const c_setup = "SETUP";
222
223 const cxchar *setup = NULL;
224
225 cxint i;
226 cxint order;
227 cxint row = -1;
228 cxint status = 0;
229
230 cxdouble wlen0;
231
232 cpl_propertylist *properties = NULL;
233
234 cpl_table *_grating = NULL;
235
236 GiGrating *self = NULL;
237
238 GiInstrumentMode mode;
239
240
241
242 if (spectra == NULL || grating == NULL) {
243 return NULL;
244 }
245
246 properties = giraffe_image_get_properties(spectra);
247
248 if (properties == NULL) {
249 return NULL;
250 }
251
252 _grating = giraffe_table_get(grating);
253
254 if (_grating == NULL) {
255 return NULL;
256 }
257
258
259 /*
260 * Get instrument setup information from the reference image
261 * and fill the grating setup structure with the appropriate
262 * data from the grating table. The central wavelength and the
263 * order information provided by the reference image is used
264 * to select the grating data.
265 */
266
267 self = giraffe_grating_new();
268
269 /* Grating name */
270
271 if (!cpl_propertylist_has(properties, GIALIAS_GRATNAME)) {
273 return NULL;
274 }
275 else {
276 cx_string_set(self->name,
277 cpl_propertylist_get_string(properties,
278 GIALIAS_GRATNAME));
279 }
280
281 /* Order sorting filter name */
282
283 if (!cpl_propertylist_has(properties, GIALIAS_FILTNAME)) {
285 return NULL;
286 }
287 else {
288 cx_string_set(self->filter,
289 cpl_propertylist_get_string(properties,
290 GIALIAS_FILTNAME));
291 }
292
293 /* Slit name */
294
295 if (!cpl_propertylist_has(properties, GIALIAS_SLITNAME)) {
297 return NULL;
298 }
299 else {
300 cx_string_set(self->slit,
301 cpl_propertylist_get_string(properties,
302 GIALIAS_SLITNAME));
303 }
304
305 /* Spacing of grating grooves */
306
307 if (!cpl_propertylist_has(properties, GIALIAS_GRATGRV)) {
309 return NULL;
310 }
311 else {
312
313 cxdouble grooves = cpl_propertylist_get_double(properties,
314 GIALIAS_GRATGRV);
315 self->space = 1. / fabs(GI_MM_TO_NM * grooves);
316
317 }
318
319 /* Instrument mode */
320
321 mode = giraffe_get_mode(properties);
322
323
324 /*
325 * Select the grating data for the current setup
326 */
327
328 if (!cpl_table_has_column(_grating, "ORDER") ||
329 !cpl_table_has_column(_grating, "WLEN0")) {
330
332 return NULL;
333
334 }
335
336 if (!cpl_propertylist_has(properties, GIALIAS_GRATWLEN)) {
338 return NULL;
339 }
340 else {
341 wlen0 = cpl_propertylist_get_double(properties, GIALIAS_GRATWLEN);
342 }
343
344 if (!cpl_propertylist_has(properties, GIALIAS_GRATORDER)) {
346 return NULL;
347 }
348 else {
349 order = cpl_propertylist_get_int(properties, GIALIAS_GRATORDER);
350 }
351
352
353 for (i = 0; i < cpl_table_get_nrow(_grating); i++) {
354
355 cxint _order = cpl_table_get_int(_grating, "ORDER", i, NULL);
356
357 if (order == _order) {
358
359 cxdouble _wlen0 = cpl_table_get_double(_grating, "WLEN0",
360 i, NULL);
361
362 if (fabs(wlen0 - _wlen0) < GI_WAVELENGTH_EPSILON) {
363 row = i;
364 break;
365 }
366
367 }
368
369 }
370
371 if (row < 0) {
373 return NULL;
374 }
375
376 /*
377 * Try to figure out the setup identifier.
378 */
379
380 /* FIXME: Check whether we can live with an empty setup string
381 * at later stages of the wavelength calibration.
382 */
383
384 if (cpl_propertylist_has(properties, GIALIAS_SETUPNAME)) {
385 setup = cpl_propertylist_get_string(properties, GIALIAS_SETUPNAME);
386 cx_string_set(self->setup, setup);
387 }
388 else {
389 if (cpl_table_has_column(_grating, c_setup)) {
390 setup = cpl_table_get_string(_grating, c_setup, row);
391 cx_string_set(self->setup, setup);
392 }
393 }
394
395
396 status = _giraffe_grating_copy(self, _grating, row, mode);
397
398 if (status != 0) {
400 return NULL;
401 }
402
403 return self;
404
405}
406
407
420void
422{
423
424 if (self == NULL) {
425 return;
426 }
427
428 if (self->name != NULL) {
429 cx_string_delete(self->name);
430 }
431
432 if (self->setup != NULL) {
433 cx_string_delete(self->setup);
434 }
435
436 if (self->filter != NULL) {
437 cx_string_delete(self->filter);
438 }
439
440 if (self->slit != NULL) {
441 cx_string_delete(self->slit);
442 }
443
444 cx_free(self);
445
446 return;
447
448}
449
450
473cxint
474giraffe_grating_setup(GiTable *grating_table, GiImage *spectra,
475 GiGrating *grating_setup)
476{
477
478 const cxchar* const fctid = "giraffe_grating_setup";
479
480 const cxchar* c_name_setup = "SETUP";
481 const cxchar* c_name_order = "ORDER";
482 const cxchar* c_name_wl0 = "WLEN0";
483 const cxchar* c_name_wlmin = "WLMIN";
484 const cxchar* c_name_wlmax = "WLMAX";
485 const cxchar* c_name_band = "BAND";
486 const cxchar* c_name_theta = "THETA";
487 const cxchar* c_name_fcoll = "FCOLL";
488 const cxchar* c_name_gcam = "GCAM";
489 const cxchar* c_name_sdx = "SDX";
490 const cxchar* c_name_sdy = "SDY";
491 const cxchar* c_name_sdphi = "SPHI";
492 const cxchar* c_name_rmed = "RMED";
493 const cxchar* c_name_rifa = "RIFA";
494
495 cxint i = 0;
496 cxint row_match = 0;
497 cxint row_nulls = 0;
498
499 cxdouble wlen_match = 0.;
500 cxdouble wlen = 0.;
501 cxdouble tmp_gratgrv = 0.;
502
503
504 cx_string* slit_name = NULL;
505
506 cpl_propertylist* ref_plimg = NULL;
507
508 cpl_table* ref_gtable = NULL;
509
510 GiInstrumentMode instrument_mode;
511
512
513 /************************************************************************
514 Preprocessing
515 ************************************************************************/
516
517 if (grating_table == NULL) {
518 return 1;
519 }
520
521 if (spectra == NULL) {
522 return 1;
523 }
524
525 if (grating_setup == NULL) {
526 return 1;
527 }
528
529 ref_plimg = giraffe_image_get_properties(spectra);
530 if (ref_plimg == NULL) {
531 return 128;
532 }
533
534 ref_gtable = giraffe_table_get(grating_table);
535 if (ref_gtable == NULL) {
536 return 128;
537 }
538
539 slit_name = cx_string_new();
540
541 /************************************************************************
542 Processing
543 ************************************************************************/
544
545 /*
546 * Retrieve Grating information from associated image...
547 */
548
549 if (cpl_propertylist_has(ref_plimg, GIALIAS_GRATWLEN) == FALSE) {
550 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATWLEN);
551 cx_string_delete(slit_name);
552 return 2;
553 }
554 else {
555 grating_setup->wlen0 = cpl_propertylist_get_double(ref_plimg,
556 GIALIAS_GRATWLEN);
557 }
558
559 if (cpl_propertylist_has(ref_plimg, GIALIAS_SLITNAME) == FALSE) {
560 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_SLITNAME);
561 cx_string_delete(slit_name);
562 return 2;
563 }
564 else {
565 cx_string_set(slit_name,
566 cpl_propertylist_get_string(ref_plimg,
567 GIALIAS_SLITNAME));
568 }
569
570 if (cpl_propertylist_has(ref_plimg, GIALIAS_GRATGRV) == FALSE) {
571 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATGRV);
572 cx_string_delete(slit_name);
573 return 2;
574 }
575 else {
576 tmp_gratgrv = cpl_propertylist_get_double(ref_plimg,
577 GIALIAS_GRATGRV);
578 }
579
580 if (cpl_propertylist_has(ref_plimg, GIALIAS_GRATNAME) == FALSE) {
581 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_GRATNAME);
582 cx_string_delete(slit_name);
583 return 2;
584 }
585 else {
586 cx_string_set(grating_setup->name,
587 cpl_propertylist_get_string(ref_plimg,
588 GIALIAS_GRATNAME));
589 }
590
591 if (cpl_propertylist_has(ref_plimg, GIALIAS_FILTNAME) == FALSE) {
592 cpl_msg_error(fctid, GIFITS_KEYWORD_MISSING_MSG, GIALIAS_FILTNAME);
593 cx_string_delete(slit_name);
594 return 2;
595 }
596 else {
597 cx_string_set(grating_setup->filter,
598 cpl_propertylist_get_string(ref_plimg,
599 GIALIAS_FILTNAME));
600 }
601
602
603 /*
604 * Find wavelength nearest to central wavelength...
605 */
606
607 for (i = 0; i < cpl_table_get_nrow(ref_gtable); i++) {
608
609 wlen = cpl_table_get(ref_gtable, c_name_wl0, i, &row_nulls);
610
611 if (fabs(wlen - grating_setup->wlen0) <
612 fabs(wlen_match - grating_setup->wlen0)) {
613 wlen_match = wlen;
614 row_match = i;
615 }
616
617 }
618
619
620 /*
621 * Have we found a match?...
622 */
623
624 if (fabs(wlen_match - grating_setup->wlen0) > GI_WAVELENGTH_EPSILON) {
625
626 cpl_msg_error(fctid, "Central wavelength [%f] nout found in grating "
627 "table, aborting...", grating_setup->wlen0);
628 cx_string_delete(slit_name);
629 return 3;
630 }
631 else {
632 cpl_msg_debug(fctid, "Found wlen0 in grating table at position %d",
633 row_match);
634 }
635
636
637 /*
638 * Retrieve values associated to matched wavelength from
639 * grating table...
640 */
641
642 cx_string_set(grating_setup->setup,
643 (cxchar*) cpl_table_get_string(ref_gtable, c_name_setup,
644 row_match));
645
646 cx_string_set(grating_setup->slit, cx_string_get(slit_name));
647
648 grating_setup->order = cpl_table_get(ref_gtable, c_name_order,
649 row_match, &row_nulls);
650
651 grating_setup->wlenmin = cpl_table_get(ref_gtable, c_name_wlmin,
652 row_match, &row_nulls);
653
654 grating_setup->wlenmax = cpl_table_get(ref_gtable, c_name_wlmax,
655 row_match, &row_nulls);
656
657 grating_setup->band = cpl_table_get(ref_gtable, c_name_band,
658 row_match, &row_nulls);
659
660 grating_setup->theta = cpl_table_get(ref_gtable, c_name_theta,
661 row_match, &row_nulls);
662
663 grating_setup->space = 1.0 / fabs(GI_MM_TO_NM * tmp_gratgrv);
664
665
666 instrument_mode = giraffe_get_mode(ref_plimg);
667
668 switch (instrument_mode) {
669 case GIMODE_MEDUSA:
670 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rmed,
671 row_match, &row_nulls);
672 break;
673
674 case GIMODE_IFU:
675 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
676 row_match, &row_nulls);
677 break;
678
679 case GIMODE_ARGUS:
680 grating_setup->resol = cpl_table_get(ref_gtable, c_name_rifa,
681 row_match, &row_nulls);
682 break;
683
684 default:
685 grating_setup->resol = -1.0;
686 break;
687 }
688
689 grating_setup->fcoll =
690 cpl_table_get(ref_gtable, c_name_fcoll, row_match, &row_nulls);
691
692 grating_setup->gcam =
693 cpl_table_get(ref_gtable, c_name_gcam, row_match, &row_nulls);
694
695 grating_setup->sdx =
696 cpl_table_get(ref_gtable, c_name_sdx, row_match, &row_nulls);
697
698 grating_setup->sdy =
699 cpl_table_get(ref_gtable, c_name_sdy, row_match, &row_nulls);
700
701 grating_setup->sphi =
702 cpl_table_get(ref_gtable, c_name_sdphi, row_match, &row_nulls);
703
704 cx_string_delete(slit_name);
705
706 return 0;
707
708}
709
710
721void
723{
724
725 const cxchar *fctid = "giraffe_grating_dump";
726
727 if (grating == NULL) {
728 return;
729 }
730
731 cpl_msg_debug(fctid, "---- GiGrating -------------------------");
732
733 cpl_msg_debug(fctid, "Grating Name : %s",
734 cx_string_get(grating->name));
735 cpl_msg_debug(fctid, "Grating Filter Name : %s",
736 cx_string_get(grating->filter));
737 cpl_msg_debug(fctid, "Grating Setup Name : %s",
738 cx_string_get(grating->setup));
739 cpl_msg_debug(fctid, "Grating Order : %12d", grating->order);
740 cpl_msg_debug(fctid, "Grating Wlen0 : %12.6f", grating->wlen0);
741 cpl_msg_debug(fctid, "Grating Wlen Min : %12.6f", grating->wlenmin);
742 cpl_msg_debug(fctid, "Grating Wlen Max : %12.6f", grating->wlenmax);
743 cpl_msg_debug(fctid, "Grating Band : %12.6f", grating->band);
744 cpl_msg_debug(fctid, "Grating Resol : %12d", grating->resol);
745 cpl_msg_debug(fctid, "Grating Space : %12.6f", grating->space);
746 cpl_msg_debug(fctid, "Grating Theta : %12.6f", grating->theta);
747 cpl_msg_debug(fctid, "Grating FColl : %12.6f", grating->fcoll);
748 cpl_msg_debug(fctid, "Grating GCam : %12.6f", grating->gcam);
749 cpl_msg_debug(fctid, "Grating SlitDx : %12.6f", grating->sdx);
750 cpl_msg_debug(fctid, "Grating SlitDy : %12.6f", grating->sdy);
751 cpl_msg_debug(fctid, "Grating SlitPhi : %12.6f", grating->sphi);
752
753 return;
754
755}
cxint giraffe_grating_setup(GiTable *grating_table, GiImage *spectra, GiGrating *grating_setup)
Retrieves grating information and returns it in a GiGrating structure.
Definition: gigrating.c:474
void giraffe_grating_dump(const GiGrating *grating)
Dump the the information contained in a GiGrating to output.
Definition: gigrating.c:722
GiGrating * giraffe_grating_new(void)
Create a new GiGrating.
Definition: gigrating.c:186
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_propertylist * giraffe_image_get_properties(const GiImage *self)
Get the properties of an image.
Definition: giimage.c:282
cpl_table * giraffe_table_get(const GiTable *self)
Get the table data from a Giraffe table.
Definition: gitable.c:433
GiInstrumentMode giraffe_get_mode(cpl_propertylist *properties)
Determines the instrument mode from a property list.
Definition: giutils.c:442
Structure to handle Grating Information.
Definition: gigrating.h:44
cxdouble wlenmax
Definition: gigrating.h:52
cxdouble sdy
Definition: gigrating.h:60
cx_string * name
Definition: gigrating.h:46
cx_string * setup
Definition: gigrating.h:45
cxdouble space
Definition: gigrating.h:55
cxdouble fcoll
Definition: gigrating.h:57
cxdouble wlen0
Definition: gigrating.h:50
cxdouble sdx
Definition: gigrating.h:59
cxint resol
Definition: gigrating.h:54
cxdouble gcam
Definition: gigrating.h:58
cx_string * slit
Definition: gigrating.h:48
cxdouble band
Definition: gigrating.h:53
cxdouble wlenmin
Definition: gigrating.h:51
cxdouble sphi
Definition: gigrating.h:61
cxint order
Definition: gigrating.h:49
cx_string * filter
Definition: gigrating.h:47
cxdouble theta
Definition: gigrating.h:56

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