OMEGA Pipeline Reference Manual  1.0.5
omega_coadd.c
1 /* $Id: omega_coadd.c,v 1.6 2011-06-27 12:59:41 agabasch Exp $
2  *
3  * This file is part of the OMEGA Pipeline
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: agabasch $
23  * $Date: 2011-06-27 12:59:41 $
24  * $Revision: 1.6 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31 
32 /*-----------------------------------------------------------------------------
33  Includes
34  -----------------------------------------------------------------------------*/
35 #include <string.h>
36 #include <math.h>
37 #include <stdio.h>
38 
39 
40 #include "omega_coadd.h"
41 #include "omega_fits.h"
42 #include "omega_dfs.h"
43 #include "omega_utils.h"
44 #include "omega_pfits.h"
45 
75 cpl_image **omega_jitter_stack(cpl_frameset *jset, cpl_frameset *jset_mask, cpl_bivector *offsets, int refine,
76  cpl_parameterlist *pars, int ext)
77 {
78 
79  int n = 0;
80  int n_mask=0;
81  int i=0;
82  cpl_mask * mask=NULL;
83  double psigmas[] = {10.0, 5.0, 2.0};
84  const int nsigmas = (int)(sizeof(psigmas)/sizeof(double));
85  int shx, shy, mhx, mhy, minrej, maxrej;
86  const char *sval;
87  cpl_geom_combine comb_meth;
88  cpl_imagelist *ilist;
89  cpl_imagelist *ilist_mask;
90  cpl_vector *sigmas;
91  cpl_parameter *par;
92  cpl_image **combined = NULL;
93  cpl_vector * offset_x = NULL;
94  cpl_vector * offset_y = NULL;
95 
96  if((jset == NULL) || (pars == NULL))
97  return NULL;
98 
99  /* Get parameters */
100  par = cpl_parameterlist_find(pars, "omega.omega_science.xcorr") ;
101  sval = cpl_parameter_get_string(par);
102 
103  if (sscanf(sval, "%d,%d,%d,%d",&shx,&shy,&mhx,&mhy)!=4)
104  return NULL;
105 
106  par = cpl_parameterlist_find(pars, "omega.omega_science.CombMode");
107  sval = cpl_parameter_get_string(par);
108  if (!strcmp(sval, "union"))
109  comb_meth = CPL_GEOM_UNION;
110  else if (!strcmp(sval, "intersect"))
111  comb_meth = CPL_GEOM_INTERSECT;
112  else if (!strcmp(sval, "first"))
113  comb_meth = CPL_GEOM_FIRST;
114  else
115  return NULL;
116 
117  /* Overule combination method if offsets are too big */
118 
119  offset_x=cpl_bivector_get_x(offsets);
120  offset_y=cpl_bivector_get_y(offsets);
121 
122  if (cpl_vector_get_max(offset_x)-cpl_vector_get_min(offset_x) > 3000 ||
123  cpl_vector_get_max(offset_y)-cpl_vector_get_min(offset_y) > 6000)
124  {
125  cpl_msg_warning(cpl_func, "Dithering offsets are very large. "
126  "Combination method changed to \"first\" ");
127  comb_meth = CPL_GEOM_FIRST;
128  }
129 
130  par = cpl_parameterlist_find(pars, "omega.omega_science.StackRej");
131  sval = cpl_parameter_get_string(par);
132  if(sscanf(sval, "%d,%d",&minrej,&maxrej) !=2)
133  return NULL;
134 
135  n = cpl_frameset_get_size(jset);
136  n_mask = cpl_frameset_get_size(jset_mask);
137 
138  if(n != n_mask){
139  cpl_vector_unwrap(sigmas);
140  cpl_msg_warning(cpl_func,"Number of images and masks differ!");
141  return NULL;
142  }
143 
144 
145  /* Create vector of sigmas for aperture extraction */
146  sigmas = cpl_vector_wrap(nsigmas, psigmas);
147 
148  /* Load frameset into an image list */
149  ilist = cpl_imagelist_load_frameset(jset, CPL_TYPE_FLOAT, 1, ext);
150  if(ilist == NULL){
151  cpl_vector_unwrap(sigmas);
152  return NULL;
153  }
154 
155  ilist_mask = cpl_imagelist_load_frameset(jset_mask, CPL_TYPE_INT, 1, ext);
156  if(ilist_mask == NULL){
157  cpl_vector_unwrap(sigmas);
158  return NULL;
159  }
160 
161  /*Add mask files to the images*/
162 
163  for (i=0; i<n; i++){
164  mask = cpl_mask_threshold_image_create(cpl_imagelist_get(ilist_mask,i), 0.5, 1.5);
165  cpl_image_reject_from_mask(cpl_imagelist_get(ilist,i), mask);
166  freemask(mask);
167  }
168 
169  freeilist(ilist_mask);
170  /*
171  * Create stack and confidence map
172  */
173  combined = cpl_geom_img_offset_combine(ilist,offsets,refine,NULL,sigmas,NULL,
174  shx,shy,mhx,mhy,minrej,maxrej,comb_meth);
175 
176  if(combined == NULL){
177  cpl_msg_debug(cpl_func,"Error in combination function. %s",cpl_error_get_message());
178  cpl_vector_unwrap(sigmas);
179  freeilist(ilist);
180  return NULL;
181  }
182 
183  /* Clean up */
184  cpl_vector_unwrap(sigmas);
185  freeilist(ilist);
186 
187  return combined;
188 }
189 
201 cpl_bivector *omega_tel_offsets(cpl_frameset *set, int mode)
202 {
203 
204  int i = 0;
205  double *offsets_x, *offsets_y;
206  double scale = 0.0;
207  cpl_frame *frame;
208  cpl_propertylist *plist;
209  cpl_bivector *offsets;
210 
211  if((set == NULL) || (mode <= 0) || (mode > 4))
212  return NULL;
213 
214  /* Get pixel scale of image, in arcsec */
215  frame = cpl_frameset_get_first(set);
216  plist = cpl_propertylist_load(cpl_frame_get_filename(frame), 1);
217 
218  if((scale = omega_pfits_get_cd22(plist)) != 0)
219  scale = scale*3600.;
220  else if((scale = omega_pfits_get_cdelt2(plist)) != 0)
221  scale = scale*3600;
222 
223  freeplist(plist);
224 
225  /* Allocate space for offsets */
226  offsets = cpl_bivector_new(cpl_frameset_get_size(set));
227  offsets_x = cpl_bivector_get_x_data(offsets);
228  offsets_y = cpl_bivector_get_y_data(offsets);
229 
230  /* Set reference offsets to 0 */
231  /* Here we are assuming that first image is the reference
232  * with X=Y=0. Is this correct?
233  */
234  offsets_x[0] = 0;
235  offsets_y[0] = 0;
236  frame = cpl_frameset_get_next(set);
237 
238  /* Starts from second image */
239  /* Write offsets in pixels */
240  for(i=1; i<cpl_frameset_get_size(set); i++){
241  plist = cpl_propertylist_load(cpl_frame_get_filename(frame), 0);
242  if(mode == 1){
243  /* STARE mode */
244  offsets_x[i] = offsets_y[i] = 0.0;
245  }
246  else if(mode == 2){
247  offsets_x[i] = omega_pfits_get_jitter_offset(plist)/scale;
248  /* For jitter mode, offsets X=Y */
249  offsets_y[i] = offsets_x[i];
250  }
251  else if(mode == 3){
252  /* DITHER mode */
253  offsets_x[i] = omega_pfits_get_dither_offsetx(plist)/scale;
254  offsets_y[i] = omega_pfits_get_dither_offsety(plist)/scale;
255  }
256  else if(mode == 4){
257  /* OFFSET mode */
258  offsets_x[i] = omega_pfits_get_offset_alpha(plist)/scale;
259  offsets_y[i] = omega_pfits_get_offset_delta(plist)/scale;
260  }
261  frame = cpl_frameset_get_next(set);
262  freeplist(plist);
263  cpl_msg_debug(cpl_func,"im=%d offset_x=%g offset_y=%g",i,offsets_x[i],offsets_y[i]);
264  }
265 
266  /* TEST */
267 // offsets_x[1] = -130;
268 // offsets_y[1] = 100;
269 // offsets_x[2] = 134;
270 // offsets_y[2] = 197;
271 
272 
273 
274  return offsets;
275 }
276 
277 /*----------------------------------------------------------------------------*/
288 /*----------------------------------------------------------------------------*/
290  const cpl_frameset * frameset,
291  const cpl_frame * ref_frame,
292  int ext)
293 {
294  cpl_bivector * offsets;
295  double * offsets_x;
296  double * offsets_y;
297  const cpl_frame * this_frame;
298  int nfiles;
299  int i;
300  cpl_propertylist *plist;
301  cpl_wcs *ref_wcs;
302 
303  /* Test entries */
304  if (frameset == NULL){
305  cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
306  return NULL;
307  }
308 
309  /* Create the offsets bivector */
310  nfiles = cpl_frameset_get_size(frameset);
311  offsets = cpl_bivector_new(nfiles);
312  offsets_x = cpl_bivector_get_x_data(offsets);
313  offsets_y = cpl_bivector_get_y_data(offsets);
314 
315  /* WCS of reference frame */
316  /* The nonlinear PV parameters cause WCSLIB to hiccup, so we
317  omit them from the propertylist */
318  plist = cpl_propertylist_load_regexp(
319  cpl_frame_get_filename(ref_frame),
320  ext, "PV", 1);
321  ref_wcs = cpl_wcs_new_from_propertylist(plist);
322  /* Get the WCS info */
323  if(cpl_error_get_code() == CPL_ERROR_NO_WCS)
324  {
325  cpl_msg_error(__func__,"Not compiled with WCS support.");
326  cpl_propertylist_delete(plist);
327  return NULL;
328  }
329 
330 
331  cpl_propertylist_delete(plist);
332 
333  /* Check whether WCS could be loaded */
334  if (ref_wcs == NULL){
335  cpl_msg_error(cpl_func, "Could not read WCS from %s",
336  cpl_frame_get_filename(ref_frame));
337  cpl_bivector_delete(offsets);
338  return NULL;
339  }
340 
341  for (i = 0; i < nfiles; i++){
342  cpl_matrix * exp_pixel;
343  cpl_matrix * exp_equat;
344  cpl_matrix * ref_pixel;
345  cpl_array * status =NULL;
346  cpl_wcs * exp_wcs;
347  cpl_error_code error = CPL_ERROR_NONE;
348 
349  /* Pixel (1,1) */
350  exp_pixel = cpl_matrix_new(1, 2);
351  cpl_matrix_set(exp_pixel, 0, 0, 1.);
352  cpl_matrix_set(exp_pixel, 0, 1, 1.);
353 
354  /* WCS of exposure i */
355  this_frame = cpl_frameset_get_frame_const(frameset, i);
356  plist = cpl_propertylist_load_regexp(
357  cpl_frame_get_filename(this_frame),
358  ext, "PV", 1);
359  exp_wcs = cpl_wcs_new_from_propertylist(plist);
360  cpl_propertylist_delete(plist);
361 
362  /* Check whether WCS could be loaded */
363  if (exp_wcs == NULL){
364  cpl_msg_error(cpl_func, "Could not read WCS from %s",
365  cpl_frame_get_filename(this_frame));
366  cpl_matrix_delete(exp_pixel);
367  cpl_bivector_delete(offsets);
368  return NULL;
369  }
370 
371  /* transform pixel (1,1) to corresponding pixel in
372  reference exposure */
373  status = NULL;
374  if ((error = cpl_wcs_convert(exp_wcs, exp_pixel, &exp_equat, &status,
375  CPL_WCS_PHYS2WORLD))
376  != CPL_ERROR_NONE){
377  cpl_msg_error(cpl_func, cpl_error_get_message_default(error));
378  cpl_matrix_delete(exp_pixel);
379  cpl_wcs_delete(exp_wcs);
380  cpl_bivector_delete(offsets);
381  cpl_array_delete(status);
382  return NULL;
383  }
384  cpl_matrix_delete(exp_pixel);
385  cpl_array_delete(status);
386 
387  status = NULL;
388  if ((error = cpl_wcs_convert(ref_wcs, exp_equat, &ref_pixel, &status,
389  CPL_WCS_WORLD2PHYS))
390  != CPL_ERROR_NONE){
391  cpl_msg_error(cpl_func, cpl_error_get_message_default(error));
392  cpl_matrix_delete(exp_equat);
393  cpl_wcs_delete(exp_wcs);
394  cpl_bivector_delete(offsets);
395  cpl_array_delete(status);
396  return NULL;
397  }
398  cpl_matrix_delete(exp_equat);
399  cpl_wcs_delete(exp_wcs);
400  cpl_array_delete(status);
401 
402  /* get offsets */
403  offsets_x[i] = cpl_matrix_get(ref_pixel, 0, 0);
404  offsets_y[i] = cpl_matrix_get(ref_pixel, 0, 1);
405 
406  cpl_matrix_delete(ref_pixel);
407  }
408 
409  /* On success */
410  cpl_wcs_delete(ref_wcs);
411  return offsets;
412 }
413 
414