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 
41 static const cxdouble GI_WAVELENGTH_EPSILON = 1.e-8; /* 1.e-4 */
42 
43 
44 inline 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 
185 GiGrating *
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 
217 GiGrating *
218 giraffe_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 
420 void
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 
473 cxint
474 giraffe_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 
721 void
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 }
GiGrating * giraffe_grating_new(void)
Create a new GiGrating.
Definition: gigrating.c:186
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
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_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:440
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.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