MUSE Pipeline Reference Manual  2.1.1
muse_rvcorrect.c
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim:set sw=2 sts=2 et cin: */
3 /*
4  * This file is part of the MUSE Instrument Pipeline
5  * Copyright (C) 2005-2014 European Southern Observatory
6  * (C) 2001 Enrico Marchetti, European Southern Observatory
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 /*----------------------------------------------------------------------------*
28  * Includes *
29  *----------------------------------------------------------------------------*/
30 #include <cpl.h>
31 #include <math.h>
32 #include <string.h>
33 
34 #include "muse_rvcorrect.h"
35 
36 #include "muse_astro.h"
37 
38 /*----------------------------------------------------------------------------*
39  * Debugging/feature Macros *
40  *----------------------------------------------------------------------------*/
41 
42 /*----------------------------------------------------------------------------*/
46 /*----------------------------------------------------------------------------*/
47 
50 /* corresponds to muse_rvcorrect_type, keep in sync with those values! */
51 const char *muse_rvcorrect_typestring[] = {
52  "none",
53  "bary",
54  "helio",
55  "geo",
56  "unknown"
57 };
58 
59 /*----------------------------------------------------------------------------*/
71 /*----------------------------------------------------------------------------*/
72 muse_rvcorrect_type
73 muse_rvcorrect_select_type(const char *aTypeString)
74 {
75  cpl_ensure(aTypeString, CPL_ERROR_NULL_INPUT, MUSE_RVCORRECT_UNKNOWN);
76  muse_rvcorrect_type type = MUSE_RVCORRECT_NONE;
77  if (!strncmp(aTypeString, muse_rvcorrect_typestring[MUSE_RVCORRECT_BARY],
78  strlen(muse_rvcorrect_typestring[MUSE_RVCORRECT_BARY]) + 1)) {
79  type = MUSE_RVCORRECT_BARY;
80  } else if (!strncmp(aTypeString, muse_rvcorrect_typestring[MUSE_RVCORRECT_HELIO],
81  strlen(muse_rvcorrect_typestring[MUSE_RVCORRECT_HELIO]) + 1)) {
82  type = MUSE_RVCORRECT_HELIO;
83  } else if (!strncmp(aTypeString, muse_rvcorrect_typestring[MUSE_RVCORRECT_GEO],
84  strlen(muse_rvcorrect_typestring[MUSE_RVCORRECT_GEO]) + 1)) {
85  type = MUSE_RVCORRECT_GEO;
86  } else if (strncmp(aTypeString, muse_rvcorrect_typestring[MUSE_RVCORRECT_NONE],
87  strlen(muse_rvcorrect_typestring[MUSE_RVCORRECT_NONE]) + 1)) {
88  cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_INPUT, "Unknown type of "
89  "radial velocity correction requested:" " \"%s\"",
90  aTypeString);
91  type = MUSE_RVCORRECT_UNKNOWN;
92  } /* else */
93  return type;
94 } /* muse_rvcorrect_select_type() */
95 
96 /*----------------------------------------------------------------------------*/
118 /*----------------------------------------------------------------------------*/
119 cpl_error_code
120 muse_rvcorrect(muse_pixtable *aPixtable, muse_rvcorrect_type aType)
121 {
122  cpl_ensure_code(aPixtable && aPixtable->table && aPixtable->header,
123  CPL_ERROR_NULL_INPUT);
124  if (aType == MUSE_RVCORRECT_NONE) {
125  return CPL_ERROR_NONE;
126  }
127 
128  if (cpl_propertylist_has(aPixtable->header, MUSE_HDR_PT_RVCORR) &&
129  fabs(cpl_propertylist_get_double(aPixtable->header, MUSE_HDR_PT_RVCORR)) > 0.) {
130  cpl_msg_info(__func__, "pixel table already corrected: skipping radial "
131  "velocity correction");
132  return CPL_ERROR_NONE;
133  }
134 
135  cpl_errorstate state = cpl_errorstate_get();
137  if (!cpl_errorstate_is_equal(state)) {
138  return cpl_error_set_message(__func__, cpl_error_get_code(), "Computing "
139  "radial velocity correction failed: %s",
140  cpl_error_get_message());
141  }
142  double rvoffset = 0.;
143  if (aType == MUSE_RVCORRECT_BARY) {
144  rvoffset = rvcorr.bary;
145  } else if (aType == MUSE_RVCORRECT_HELIO) {
146  rvoffset = rvcorr.helio;
147  } else if (aType == MUSE_RVCORRECT_GEO) {
148  rvoffset = rvcorr.geo;
149  } else { /* unknown type */
150  return cpl_error_set_message(__func__, CPL_ERROR_ILLEGAL_INPUT, "Unknown "
151  "type of radial velocity correction, no "
152  "correction performed!");
153  }
154  cpl_msg_info(__func__, "Correcting data for %scentric radial velocity of %.2f"
155  " km/s", muse_rvcorrect_typestring[aType], rvoffset);
156 
157  /* apply the velocity offset to all pixel table rows */
158  const double cinv = 1000. / CPL_PHYS_C; /* inverse speed of light in km/s */
159  float *lbda = cpl_table_get_data_float(aPixtable->table, MUSE_PIXTABLE_LAMBDA);
160  cpl_size irow, nrow = muse_pixtable_get_nrow(aPixtable);
161  #pragma omp parallel for default(none) \
162  shared(lbda, nrow, rvoffset) /* cinv is const, shared automatically */
163  for (irow = 0; irow < nrow; irow++) {
164  /* use the relativistic velocity correction formula, see e.g. IRAF dopcor */
165  lbda[irow] *= sqrt((1. + rvoffset * cinv) / (1. - rvoffset * cinv));
166  } /* for irow (all pixel table rows) */
167 
168  /* add the header to the pixel table to show that the correction was done */
169  cpl_propertylist_update_double(aPixtable->header, MUSE_HDR_PT_RVCORR,
170  rvoffset);
171  char *comment = cpl_sprintf(MUSE_HDR_PT_RVCORR_C,
172  muse_rvcorrect_typestring[aType]);
173  cpl_propertylist_set_comment(aPixtable->header, MUSE_HDR_PT_RVCORR, comment);
174  cpl_free(comment);
175  return CPL_ERROR_NONE;
176 } /* muse_rvcorrect() */
177 
cpl_error_code muse_rvcorrect(muse_pixtable *aPixtable, muse_rvcorrect_type aType)
Correct the wavelengths of all pixels of a given pixel table for radial velocity shift.
cpl_size muse_pixtable_get_nrow(const muse_pixtable *aPixtable)
get the number of rows within the pixel table
muse_rvcorrect_type muse_rvcorrect_select_type(const char *aTypeString)
Select type of radial velocity correction to be done from type string.
Structure to store bary-, helio-, and geocentric velocity corrections.
Definition: muse_astro.h:43
cpl_table * table
The pixel table.
Structure definition of MUSE pixel table.
muse_astro_rvcorr muse_astro_rvcorr_compute(const cpl_propertylist *aHeader)
Compute radial velocity corrections given the header of an exposure.
Definition: muse_astro.c:1197
#define MUSE_PIXTABLE_LAMBDA
Definition: muse_pixtable.h:53
#define MUSE_HDR_PT_RVCORR
cpl_propertylist * header
The FITS header.