MUSE Pipeline Reference Manual  1.0.2
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  muse_postproc_properties *prop = muse_postproc_properties_new(MUSE_POSTPROC_ASTROMETRY);
57  /* per-exposure parameters */
58  prop->lambdamin = aParams->lambdamin;
59  prop->lambdamax = aParams->lambdamax;
60  prop->lambdaref = aParams->lambdaref;
61  prop->darcheck = MUSE_POSTPROC_DARCHECK_NONE;
62  if (aParams->darcheck == MUSE_ASTROMETRY_PARAM_DARCHECK_CHECK) {
63  prop->darcheck = MUSE_POSTPROC_DARCHECK_CHECK;
64  } else if (aParams->darcheck == MUSE_ASTROMETRY_PARAM_DARCHECK_CORRECT) {
65  prop->darcheck = MUSE_POSTPROC_DARCHECK_CORRECT;
66  }
67  /* setup and check astrometric calibration parameters and centroiding method */
68  prop->detsigma = aParams->detsigma;
69  prop->radius = aParams->radius;
70  prop->faccuracy = aParams->faccuracy;
71  prop->rejsigma = aParams->rejsigma;
72  prop->niter = aParams->niter;
74  if (aParams->centroid == MUSE_ASTROMETRY_PARAM_CENTROID_MOFFAT) {
76  } else if (aParams->centroid == MUSE_ASTROMETRY_PARAM_CENTROID_BOX) {
78  } else if (aParams->centroid != MUSE_ASTROMETRY_PARAM_CENTROID_GAUSSIAN) {
79  cpl_msg_error(__func__, "unknown centroiding method \"%s\"", aParams->centroid_s);
81  return -1;
82  }
83  /* set up rotation center from parameter string */
84  cpl_array *rotcenter = muse_cplarray_new_from_delimited_string(aParams->rotcenter, ",");
85  if (rotcenter && cpl_array_get_size(rotcenter) >= 2) {
86  prop->crpix1 = atof(cpl_array_get_string(rotcenter, 0));
87  prop->crpix2 = atof(cpl_array_get_string(rotcenter, 1));
88  }
89  cpl_array_delete(rotcenter);
90  /* per-exposure parameters */
91  /* flux calibration */
92  prop->response = muse_table_load(aProcessing, MUSE_TAG_STD_RESPONSE, 0);
93  prop->extinction = muse_table_load(aProcessing, MUSE_TAG_EXTINCT_TABLE, 0);
94  prop->telluric = muse_table_load(aProcessing, MUSE_TAG_STD_TELLURIC, 0);
95  /* astrometric reference */
96  prop->refframe = muse_frameset_find_master(aProcessing->inframes,
97  MUSE_TAG_ASTROMETRY_REFERENCE, 0);
98  if (!prop->refframe) {
99  cpl_msg_error(__func__, "Required input %s not found in input files",
100  MUSE_TAG_ASTROMETRY_REFERENCE);
101  cpl_error_set_message(__func__, CPL_ERROR_NULL_INPUT,
102  MUSE_TAG_ASTROMETRY_REFERENCE" missing");
104  return -1;
105  }
106 
107  /* sort input pixel tables into different exposures */
108  prop->exposures = muse_processing_sort_exposures(aProcessing);
109  if (!prop->exposures) {
110  cpl_msg_error(__func__, "no astrometric exposures found in input");
112  return -1;
113  }
114  int nexposures = cpl_table_get_nrow(prop->exposures);
115 
116  /* now process all the pixel tables, do it separately for each exposure */
117  muse_wcs_object **wcsobjs = cpl_calloc(nexposures, sizeof(muse_wcs_object *));
118  int i;
119  for (i = 0; i < nexposures; i++) {
120  wcsobjs[i] = muse_postproc_process_exposure(prop, i, NULL);
121  if (!wcsobjs[i]) {
122  int i2;
123  for (i2 = 0; i2 <= i; i2++) {
124  muse_wcs_object_delete(wcsobjs[i2]);
125  } /* for i2 */
126  cpl_free(wcsobjs);
128  return -1; /* enough error messages, just return */
129  }
130  } /* for i (exposures) */
132 
133  /* XXX now combine the possibly more than one astrometric WCSs?! */
134 
135  cpl_error_code rc = CPL_ERROR_NONE;
136  cpl_table *fwhite = muse_table_load_filter(NULL, "white");
137  for (i = 0; i < nexposures; i++) {
138  /* add white-light image to cube, convert DQ to NANs, do QC, then save it */
139  muse_image *fov = muse_datacube_collapse(wcsobjs[i]->cube, fwhite);
140  wcsobjs[i]->cube->recimages = muse_imagelist_new();
141  wcsobjs[i]->cube->recnames = cpl_array_new(1, CPL_TYPE_STRING);
142  muse_imagelist_set(wcsobjs[i]->cube->recimages, fov, 0);
143  cpl_array_set_string(wcsobjs[i]->cube->recnames, 0, "white");
144  muse_postproc_qc_fwhm(aProcessing, wcsobjs[i]->cube); /* before NANs! */
145  muse_datacube_convert_dq(wcsobjs[i]->cube);
146  muse_processing_save_cube(aProcessing, -1, wcsobjs[i]->cube,
147  MUSE_TAG_CUBE_ASTROMETRY, MUSE_CUBE_TYPE_FITS);
148 
149  /* save the astrometric solution */
150  char *object = cpl_sprintf("Astrometric calibration (%s)",
151  cpl_propertylist_get_string(wcsobjs[i]->cube->header,
152  "OBJECT"));
153  cpl_propertylist_update_string(wcsobjs[i]->wcs, "OBJECT", object);
154  rc = muse_processing_save_header(aProcessing, -1, wcsobjs[i]->wcs,
155  MUSE_TAG_ASTROMETRY_WCS);
156  cpl_free(object);
157  if (rc != CPL_ERROR_NONE) {
158  for ( ; i < nexposures; i++) {
159  muse_wcs_object_delete(wcsobjs[i]);
160  } /* for rest of i */
161  break;
162  } /* if */
163 
164  /* XXX add option to create cube using the derived calibration *
165  * curve to check quality of the computed astrometry */
166  muse_wcs_object_delete(wcsobjs[i]);
167  }
168  cpl_table_delete(fwhite);
169  cpl_free(wcsobjs);
170 
171  return rc == CPL_ERROR_NONE ? 0 : -1;
172 } /* muse_astrometry_compute() */
muse_postproc_properties * muse_postproc_properties_new(muse_postproc_type aType)
Create a post-processing properties object.
Definition: muse_postproc.c:67
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...
muse_image * muse_datacube_collapse(muse_datacube *aCube, cpl_table *aFilter)
Integrate a FITS NAXIS=3 datacube along the wavelength direction.
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:58
Structure definition of MUSE three extension FITS file.
Definition: muse_image.h:40
cpl_array * recnames
the reconstructed image filter names
Definition: muse_datacube.h:70
cpl_table * muse_table_load_filter(muse_processing *aProcessing, const char *aFilterName)
Load a table for a given filter name.
Definition: muse_utils.c:853
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...
Structure definition of the post-processing properties.
Definition: muse_postproc.h:89
void muse_postproc_properties_delete(muse_postproc_properties *aProp)
Free memory taken by a post-processing properties object and all its components.
Definition: muse_postproc.c:94
const char * centroid_s
Centroiding method to use for objects in the field of view. "gaussian" and "moffat" use 2D fits to de...
int niter
Number of iterations of the astrometric fit.
double detsigma
Source detection sigma level to use.
const char * rotcenter
Center of rotation of the instrument, given as two comma-separated floating point values in pixels...
muse_imagelist * muse_imagelist_new(void)
Create a new (empty) MUSE image list.
cpl_frameset * inframes
Structure to hold the parameters of the muse_astrometry recipe.
cpl_table * muse_table_load(muse_processing *aProcessing, const char *aTag, unsigned char aIFU)
load a table according to its tag and IFU/channel number
Definition: muse_utils.c:721
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:95
cpl_error_code muse_imagelist_set(muse_imagelist *aList, muse_image *aImage, unsigned int aIdx)
Set the muse_image of given list index.
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:468
muse_imagelist * recimages
the reconstructed image data
Definition: muse_datacube.h:63
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...