MUSE Pipeline Reference Manual  2.1.1
muse_astrometry.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  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25 
26 /*---------------------------------------------------------------------------*
27  * Includes *
28  *---------------------------------------------------------------------------*/
29 #include <string.h>
30 
31 #include <muse.h>
32 #include "muse_astrometry_z.h"
33 
34 /*---------------------------------------------------------------------------*
35  * Functions code *
36  *---------------------------------------------------------------------------*/
37 
38 /*----------------------------------------------------------------------------*/
51 /*----------------------------------------------------------------------------*/
52 int
53 muse_astrometry_compute(muse_processing *aProcessing,
54  muse_astrometry_params_t *aParams)
55 {
56  cpl_errorstate state = cpl_errorstate_get();
57 
58  muse_postproc_properties *prop = muse_postproc_properties_new(MUSE_POSTPROC_ASTROMETRY);
59  /* per-exposure parameters */
60  prop->lambdamin = aParams->lambdamin;
61  prop->lambdamax = aParams->lambdamax;
62  prop->lambdaref = aParams->lambdaref;
63  prop->darcheck = MUSE_POSTPROC_DARCHECK_NONE;
64  if (aParams->darcheck == MUSE_ASTROMETRY_PARAM_DARCHECK_CHECK) {
65  prop->darcheck = MUSE_POSTPROC_DARCHECK_CHECK;
66  } else if (aParams->darcheck == MUSE_ASTROMETRY_PARAM_DARCHECK_CORRECT) {
67  prop->darcheck = MUSE_POSTPROC_DARCHECK_CORRECT;
68  }
69  /* setup and check astrometric calibration parameters and centroiding method */
70  prop->detsigma = aParams->detsigma;
71  prop->radius = aParams->radius;
72  prop->faccuracy = aParams->faccuracy;
73  prop->rejsigma = aParams->rejsigma;
74  prop->niter = aParams->niter;
76  if (aParams->centroid == MUSE_ASTROMETRY_PARAM_CENTROID_MOFFAT) {
78  } else if (aParams->centroid == MUSE_ASTROMETRY_PARAM_CENTROID_BOX) {
80  } else if (aParams->centroid != MUSE_ASTROMETRY_PARAM_CENTROID_GAUSSIAN) {
81  cpl_msg_error(__func__, "unknown centroiding method \"%s\"", aParams->centroid_s);
83  return -1;
84  }
85  /* set up rotation center from parameter string */
86  cpl_array *rotcenter = muse_cplarray_new_from_delimited_string(aParams->rotcenter, ",");
87  if (rotcenter && cpl_array_get_size(rotcenter) >= 2) {
88  prop->crpix1 = atof(cpl_array_get_string(rotcenter, 0));
89  prop->crpix2 = atof(cpl_array_get_string(rotcenter, 1));
90  }
91  cpl_array_delete(rotcenter);
92  /* per-exposure parameters */
93  /* flux calibration */
94  prop->response = muse_processing_load_table(aProcessing,
95  MUSE_TAG_STD_RESPONSE, 0);
96  prop->telluric = muse_processing_load_table(aProcessing,
97  MUSE_TAG_STD_TELLURIC, 0);
98  prop->extinction = muse_processing_load_ctable(aProcessing,
99  MUSE_TAG_EXTINCT_TABLE, 0);
100  /* astrometric reference */
101  prop->refframe = muse_frameset_find_master(aProcessing->inframes,
102  MUSE_TAG_ASTROMETRY_REFERENCE, 0);
103  if (!prop->refframe) {
104  cpl_msg_error(__func__, "Required input %s not found in input files",
105  MUSE_TAG_ASTROMETRY_REFERENCE);
106  cpl_error_set_message(__func__, CPL_ERROR_NULL_INPUT,
107  MUSE_TAG_ASTROMETRY_REFERENCE" missing");
109  return -1;
110  }
111  muse_processing_append_used(aProcessing, prop->refframe,
112  CPL_FRAME_GROUP_CALIB, 1);
113 
114  /* sort input pixel tables into different exposures */
115  prop->exposures = muse_processing_sort_exposures(aProcessing);
116  if (!prop->exposures) {
117  cpl_msg_error(__func__, "no astrometric exposures found in input");
119  return -1;
120  }
121  int nexposures = cpl_table_get_nrow(prop->exposures);
122 
123  /* now process all the pixel tables, do it separately for each exposure */
124  muse_wcs_object **wcsobjs = cpl_calloc(nexposures, sizeof(muse_wcs_object *));
125  int i;
126  for (i = 0; i < nexposures; i++) {
127  wcsobjs[i] = muse_postproc_process_exposure(prop, i, NULL);
128  if (!wcsobjs[i]) {
129  int i2;
130  for (i2 = 0; i2 <= i; i2++) {
131  muse_wcs_object_delete(wcsobjs[i2]);
132  } /* for i2 */
133  cpl_free(wcsobjs);
135  return -1; /* enough error messages, just return */
136  }
137  } /* for i (exposures) */
139 
140  /* XXX now combine the possibly more than one astrometric WCSs?! */
141 
142  for (i = 0; i < nexposures; i++) {
143  /* convert DQ to NANs, do QC, then save cube; *
144  * it already contains the images */
145  muse_postproc_qc_fwhm(aProcessing, wcsobjs[i]->cube); /* before NANs! */
146  muse_datacube_convert_dq(wcsobjs[i]->cube);
147  muse_processing_save_cube(aProcessing, -1, wcsobjs[i]->cube,
148  MUSE_TAG_CUBE_ASTROMETRY, MUSE_CUBE_TYPE_FITS);
149 
150  /* save the astrometric solution */
151  char *object = cpl_sprintf("Astrometric calibration (%s)",
152  cpl_propertylist_get_string(wcsobjs[i]->cube->header,
153  "OBJECT"));
154  cpl_propertylist_update_string(wcsobjs[i]->wcs, "OBJECT", object);
155  cpl_error_code rc = muse_processing_save_header(aProcessing, -1,
156  wcsobjs[i]->wcs,
157  MUSE_TAG_ASTROMETRY_WCS);
158  cpl_free(object);
159  if (rc != CPL_ERROR_NONE) {
160  for ( ; i < nexposures; i++) {
161  muse_wcs_object_delete(wcsobjs[i]);
162  } /* for rest of i */
163  break;
164  } /* if */
165 
166  /* XXX add option to create cube using the derived calibration *
167  * curve to check quality of the computed astrometry */
168  muse_wcs_object_delete(wcsobjs[i]);
169  }
170  cpl_free(wcsobjs);
171 
172  return cpl_errorstate_is_equal(state) ? 0 : -1;
173 } /* muse_astrometry_compute() */
muse_postproc_properties * muse_postproc_properties_new(muse_postproc_type aType)
Create a post-processing properties object.
Definition: muse_postproc.c:77
muse_wcs_centroid_type centroid
double rejsigma
Rejection sigma level of the astrometric fit.
double lambdaref
Reference wavelength used for correction of differential atmospheric refraction. The R-band (peak wav...
cpl_error_code muse_postproc_qc_fwhm(muse_processing *aProcessing, muse_datacube *aCube)
Compute QC1 parameters for datacubes and save them in the FITS header.
void * muse_postproc_process_exposure(muse_postproc_properties *aProp, unsigned int aIndex, muse_postproc_sky_outputs *aSkyOut)
Merge and process pixel tables from one exposure.
WCS object to store data needed while computing the astrometric solution.
Definition: muse_wcs.h:70
cpl_array * muse_cplarray_new_from_delimited_string(const char *aString, const char *aDelim)
Convert a delimited string into an array of strings.
cpl_error_code muse_processing_save_header(muse_processing *aProcessing, int aIFU, cpl_propertylist *aHeader, const char *aTag)
Save a FITS header to disk.
double radius
Initial radius in pixels for pattern matching identification in the astrometric field.
cpl_error_code muse_datacube_convert_dq(muse_datacube *aCube)
Convert the DQ extension of a datacube to NANs in DATA and STAT.
double lambdamin
Cut off the data below this wavelength after loading the pixel table(s).
cpl_error_code muse_processing_save_cube(muse_processing *aProcessing, int aIFU, void *aCube, const char *aTag, muse_cube_type aType)
Save a MUSE datacube to disk.
int centroid
Centroiding method to use for objects in the field of view. "gaussian" and "moffat" use 2D fits to de...
muse_table * muse_processing_load_table(muse_processing *aProcessing, const char *aTag, unsigned char aIFU)
Load a MUSE table according to its tag and IFU/channel number.
Structure definition of the post-processing properties.
Definition: muse_postproc.h:91
void muse_postproc_properties_delete(muse_postproc_properties *aProp)
Free memory taken by a post-processing properties object and all its components.
const char * centroid_s
Centroiding method to use for objects in the field of view. "gaussian" and "moffat" use 2D fits to de...
void muse_processing_append_used(muse_processing *aProcessing, cpl_frame *aFrame, cpl_frame_group aGroup, int aDuplicate)
Add a frame to the set of used frames.
int niter
Number of iterations of the astrometric fit.
double detsigma
Source detection sigma level to use. If this is negative, values between its absolute and 1...
cpl_table * muse_processing_load_ctable(muse_processing *aProcessing, const char *aTag, unsigned char aIFU)
Load a CPL table according to its tag and IFU/channel number.
const char * rotcenter
Center of rotation of the instrument, given as two comma-separated floating point values in pixels...
cpl_frameset * inframes
Structure to hold the parameters of the muse_astrometry recipe.
double lambdamax
Cut off the data above this wavelength after loading the pixel table(s).
void muse_wcs_object_delete(muse_wcs_object *aWCSObj)
Deallocate memory associated to a muse_wcs_object.
Definition: muse_wcs.c:89
cpl_table * muse_processing_sort_exposures(muse_processing *aProcessing)
Sort input frames (containing lists of pixel table filenames) into different exposures.
muse_postproc_darcheck darcheck
Definition: muse_postproc.h:97
cpl_frame * muse_frameset_find_master(const cpl_frameset *aFrames, const char *aTag, unsigned char aIFU)
find the master frame according to its CCD number and tag
Definition: muse_utils.c:505
double faccuracy
Factor of initial accuracy relative to mean positional accuracy of the measured positions to use for ...
int darcheck
Carry out a check of the theoretical DAR correction using source centroiding. If "correct" it will al...