VIRCAM Pipeline  1.3.3
tests/vircam_imcombine.c
1 /* $Id: vircam_imcombine.c,v 1.17 2012-01-16 15:46:08 jim Exp $
2  *
3  * This file is part of the VIRCAM Pipeline
4  * Copyright (C) 2006 Cambridge Astronomy Survey Unit
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: jim $
23  * $Date: 2012-01-16 15:46:08 $
24  * $Revision: 1.17 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 /* Includes */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <stdio.h>
35 #include <cpl.h>
36 #include <math.h>
37 
38 #include "vircam_utils.h"
39 #include "vircam_mask.h"
40 #include "vircam_dfs.h"
41 #include "vircam_mods.h"
42 #include "vircam_fits.h"
43 
44 /* Function prototypes */
45 
46 static int vircam_imcombine_create(cpl_plugin *) ;
47 static int vircam_imcombine_exec(cpl_plugin *) ;
48 static int vircam_imcombine_destroy(cpl_plugin *) ;
49 static int vircam_imcombine_test(cpl_parameterlist *, cpl_frameset *) ;
50 static int vircam_imcombine_save(cpl_frameset *framelist,
51  cpl_parameterlist *parlist);
52 static void vircam_imcombine_init(void);
53 static void vircam_imcombine_tidy(void);
54 
55 /* Static global variables */
56 
57 static struct {
58 
59  /* Input */
60 
61  int combtype;
62  int scaletype;
63  int xrej;
64  float thresh;
65  int extenum;
66 
67 } vircam_imcombine_config;
68 
69 
70 static struct {
71  cpl_size *labels;
72  cpl_frameset *imagelist;
73  vir_fits **images;
74  int nimages;
75  cpl_image *outimage;
76 } ps;
77 
78 static int isfirst;
79 static cpl_frame *product_frame = NULL;
80 
81 static char vircam_imcombine_description[] =
82 "vircam_imcombine -- VIRCAM test imcombine recipe.\n\n"
83 "Combine a list of frames into a mean frame.\n\n"
84 "The program accepts the following files in the SOF:\n\n"
85 " Tag Description\n"
86 " -----------------------------------------------------------------------\n"
87 " %-21s A list of images\n"
88 "\n";
89 
146 /* Function code */
147 
148 /*---------------------------------------------------------------------------*/
156 /*---------------------------------------------------------------------------*/
157 
158 int cpl_plugin_get_info(cpl_pluginlist *list) {
159  cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
160  cpl_plugin *plugin = &recipe->interface;
161  char alldesc[SZ_ALLDESC];
162  (void)snprintf(alldesc,SZ_ALLDESC,vircam_imcombine_description,
163  VIRCAM_TEST_SCIENCE_RAW);
164 
165  cpl_plugin_init(plugin,
166  CPL_PLUGIN_API,
167  VIRCAM_BINARY_VERSION,
168  CPL_PLUGIN_TYPE_RECIPE,
169  "vircam_imcombine",
170  "VIRCAM test image combination recipe [test]",
171  alldesc,
172  "Jim Lewis",
173  "jrl@ast.cam.ac.uk",
175  vircam_imcombine_create,
176  vircam_imcombine_exec,
177  vircam_imcombine_destroy);
178 
179  cpl_pluginlist_append(list,plugin);
180 
181  return(0);
182 }
183 
184 /*---------------------------------------------------------------------------*/
193 /*---------------------------------------------------------------------------*/
194 
195 static int vircam_imcombine_create(cpl_plugin *plugin) {
196  cpl_recipe *recipe;
197  cpl_parameter *p;
198 
199  /* Get the recipe out of the plugin */
200 
201  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
202  recipe = (cpl_recipe *)plugin;
203  else
204  return(-1);
205 
206  /* Create the parameters list in the cpl_recipe object */
207 
208  recipe->parameters = cpl_parameterlist_new();
209 
210  /* Fill in the parameters. First the combination type */
211 
212  p = cpl_parameter_new_range("vircam.vircam_imcombine.combtype",
213  CPL_TYPE_INT,
214  "1 == Median,\n 2 == Mean",
215  "vircam.vircam_imcombine",
216  2,1,2);
217  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"comb");
218  cpl_parameterlist_append(recipe->parameters,p);
219 
220  /* The requested scaling */
221 
222  p = cpl_parameter_new_range("vircam.vircam_imcombine.scaletype",
223  CPL_TYPE_INT,
224  "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
225  "vircam.vircam_imcombine",
226  1,0,3);
227  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scale");
228  cpl_parameterlist_append(recipe->parameters,p);
229 
230  /* Extra rejection cycle */
231 
232  p = cpl_parameter_new_value("vircam.vircam_imcombine.xrej",
233  CPL_TYPE_BOOL,
234  "True if using extra rejection cycle",
235  "vircam.vircam_imcombine",
236  TRUE);
237  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
238  cpl_parameterlist_append(recipe->parameters,p);
239 
240  /* Rejection threshold */
241 
242  p = cpl_parameter_new_value("vircam.vircam_imcombine.thresh",
243  CPL_TYPE_DOUBLE,
244  "Rejection threshold in sigma above background",
245  "vircam.vircam_imcombine",5.0);
246  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thr");
247  cpl_parameterlist_append(recipe->parameters,p);
248 
249  /* Extension number of input frames to use */
250 
251  p = cpl_parameter_new_range("vircam.vircam_imcombine.extenum",
252  CPL_TYPE_INT,
253  "Extension number to be done, 0 == all",
254  "vircam.vircam_imcombine",
255  1,0,16);
256  cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
257  cpl_parameterlist_append(recipe->parameters,p);
258 
259  /* Get out of here */
260 
261  return(0);
262 }
263 
264 
265 /*---------------------------------------------------------------------------*/
271 /*---------------------------------------------------------------------------*/
272 
273 static int vircam_imcombine_exec(cpl_plugin *plugin) {
274  cpl_recipe *recipe;
275 
276  /* Get the recipe out of the plugin */
277 
278  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
279  recipe = (cpl_recipe *)plugin;
280  else
281  return(-1);
282 
283  return(vircam_imcombine_test(recipe->parameters,recipe->frames));
284 }
285 
286 /*---------------------------------------------------------------------------*/
292 /*---------------------------------------------------------------------------*/
293 
294 static int vircam_imcombine_destroy(cpl_plugin *plugin) {
295  cpl_recipe *recipe ;
296 
297  /* Get the recipe out of the plugin */
298 
299  if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
300  recipe = (cpl_recipe *)plugin;
301  else
302  return(-1);
303 
304  cpl_parameterlist_delete(recipe->parameters);
305  return(0);
306 }
307 
308 /*---------------------------------------------------------------------------*/
315 /*---------------------------------------------------------------------------*/
316 
317 static int vircam_imcombine_test(cpl_parameterlist *parlist,
318  cpl_frameset *framelist) {
319  const char *fctid="vircam_imcombine";
320  int j,jst,jfn,retval,status;
321  cpl_size nlab;
322  cpl_parameter *p;
323  unsigned char *rejmask,*rejplus;
324  cpl_propertylist *drs;
325 
326  /* Check validity of input frameset */
327 
328  if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
329  cpl_msg_error(fctid,"Input framelist NULL or has no input data");
330  return(-1);
331  }
332 
333  /* Initialise some things */
334 
335  vircam_imcombine_init();
336 
337  /* Get the parameters */
338 
339  p = cpl_parameterlist_find(parlist,"vircam.vircam_imcombine.combtype");
340  vircam_imcombine_config.combtype = cpl_parameter_get_int(p);
341  p = cpl_parameterlist_find(parlist,"vircam.vircam_imcombine.scaletype");
342  vircam_imcombine_config.scaletype = cpl_parameter_get_int(p);
343  p = cpl_parameterlist_find(parlist,"vircam.vircam_imcombine.xrej");
344  vircam_imcombine_config.xrej = cpl_parameter_get_bool(p);
345  p = cpl_parameterlist_find(parlist,"vircam.vircam_imcombine.thresh");
346  vircam_imcombine_config.thresh = (float)cpl_parameter_get_double(p);
347  p = cpl_parameterlist_find(parlist,"vircam.vircam_imcombine.extenum");
348  vircam_imcombine_config.extenum = cpl_parameter_get_int(p);
349 
350  /* Sort out raw from calib frames */
351 
352  if (vircam_dfs_set_groups(framelist) != VIR_OK) {
353  cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
354  vircam_imcombine_tidy();
355  return(-1);
356  }
357 
358  /* Get the frames frames */
359 
360  if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
361  &nlab)) == NULL) {
362  cpl_msg_error(fctid,"Cannot labelise the input frames");
363  vircam_imcombine_tidy();
364  return(-1);
365  }
366  if ((ps.imagelist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
367  VIRCAM_TEST_SCIENCE_RAW)) == NULL) {
368  cpl_msg_error(fctid,"Cannot find images in input frameset");
369  vircam_imcombine_tidy();
370  return(-1);
371  }
372  ps.nimages = cpl_frameset_get_size(ps.imagelist);
373 
374  /* Now, how many image extensions do we want to do? If the extension
375  number is zero, then we loop for all possible extensions. If it
376  isn't then we just do the extension specified */
377 
378  vircam_exten_range(vircam_imcombine_config.extenum,
379  (const cpl_frame *)cpl_frameset_get_frame(ps.imagelist,0),
380  &jst,&jfn);
381  if (jst == -1 || jfn == -1) {
382  cpl_msg_error(fctid,"Unable to continue");
383  vircam_imcombine_tidy();
384  return(-1);
385  }
386 
387  /* Now loop for all the extension... */
388 
389  status = VIR_OK;
390  for (j = jst; j <= jfn; j++) {
391  isfirst = (j == jst);
392 
393  /* Load the images */
394 
395  ps.images = vircam_fits_load_list(ps.imagelist,CPL_TYPE_FLOAT,j);
396 
397  /* Call the combine module */
398 
399  cpl_msg_info(fctid,"Doing combination for extension %" CPL_SIZE_FORMAT,
400  (cpl_size)j);
401  (void)vircam_imcombine(ps.images,ps.nimages,
402  vircam_imcombine_config.combtype,
403  vircam_imcombine_config.scaletype,
404  vircam_imcombine_config.xrej,
405  vircam_imcombine_config.thresh,
406  &(ps.outimage),&rejmask,&rejplus,&drs,&status);
407  freespace(rejmask);
408  freespace(rejplus);
409  freepropertylist(drs);
410  if (status != VIR_OK) {
411  vircam_imcombine_tidy();
412  return(-1);
413  }
414 
415  /* Save everything */
416 
417  cpl_msg_info(fctid,"Saving combined image extension %" CPL_SIZE_FORMAT,
418  (cpl_size)j);
419  retval = vircam_imcombine_save(framelist,parlist);
420  if (retval != 0) {
421  vircam_imcombine_tidy();
422  return(-1);
423  }
424  freefitslist(ps.images,ps.nimages);
425  freeimage(ps.outimage);
426  }
427  vircam_imcombine_tidy();
428  return(0);
429 }
430 
431 
432 /*---------------------------------------------------------------------------*/
439 /*---------------------------------------------------------------------------*/
440 
441 static int vircam_imcombine_save(cpl_frameset *framelist,
442  cpl_parameterlist *parlist) {
443  cpl_propertylist *plist;
444  const char *recipeid = "vircam_imcombine";
445  const char *fctid = "vircam_imcombine_save";
446  const char *outfile = "comb.fits";
447 
448  /* If we need to make a PHU then do that now based on the first frame
449  in the input frame list */
450 
451  if (isfirst) {
452 
453  /* Create a new product frame object and define some tags */
454 
455  product_frame = cpl_frame_new();
456  cpl_frame_set_filename(product_frame,outfile);
457  cpl_frame_set_tag(product_frame,VIRCAM_PRO_SIMPLE_TEST);
458  cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
459  cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
460  cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
461 
462  /* Set up the phu header */
463 
464  plist = vircam_fits_get_phu(ps.images[0]);
465  vircam_dfs_set_product_primary_header(plist,product_frame,framelist,
466  parlist,(char *)recipeid,
467  "?Dictionary?",NULL,0);
468  /* 'Save' the PHU image */
469 
470  if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
471  CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
472  cpl_msg_error(fctid,"Cannot save product PHU");
473  cpl_frame_delete(product_frame);
474  return(-1);
475  }
476  cpl_frameset_insert(framelist,product_frame);
477  }
478 
479  /* Get the extension property list */
480 
481  plist = vircam_fits_get_ehu(ps.images[0]);
482 
483  /* Fiddle with the header now */
484 
485  vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
486  parlist,(char *)recipeid,
487  "?Dictionary?",NULL);
488 
489  /* Now save the mean dome flat image extension */
490 
491  if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,plist,
492  CPL_IO_EXTEND) != CPL_ERROR_NONE) {
493  cpl_msg_error(fctid,"Cannot save product image extension");
494  return(-1);
495  }
496 
497  /* Get out of here */
498 
499  return(0);
500 }
501 
502 /*---------------------------------------------------------------------------*/
506 /*---------------------------------------------------------------------------*/
507 
508 static void vircam_imcombine_init(void) {
509  ps.labels = NULL;
510  ps.imagelist = NULL;
511  ps.images = NULL;
512  ps.outimage = NULL;
513 }
514 
515 /*---------------------------------------------------------------------------*/
519 /*---------------------------------------------------------------------------*/
520 
521 static void vircam_imcombine_tidy(void) {
522  freespace(ps.labels);
523  freeframeset(ps.imagelist);
524  freefitslist(ps.images,ps.nimages);
525  freeimage(ps.outimage);
526 }
527 
530 /*
531 
532 $Log: not supported by cvs2svn $
533 Revision 1.16 2012/01/16 14:44:02 jim
534 Fixed test recipes for cpl6 compliance
535 
536 Revision 1.15 2012/01/15 17:40:09 jim
537 Minor modifications to take into accout the changes in cpl API for v6
538 
539 Revision 1.14 2009/09/09 09:51:13 jim
540 modified to use new saving routines so that headers are right
541 
542 Revision 1.13 2007/10/25 19:38:22 jim
543 modified to keep lint happy
544 
545 Revision 1.12 2007/10/15 12:53:55 jim
546 Modified for compatibility with cpl_4.0
547 
548 Revision 1.11 2007/07/09 13:22:09 jim
549 Modified to use new version of vircam_exten_range
550 
551 Revision 1.10 2007/05/02 12:53:11 jim
552 typo fixes in docs
553 
554 Revision 1.9 2007/04/13 12:27:38 jim
555 Added some extra docs
556 
557 Revision 1.8 2007/04/04 10:36:29 jim
558 Modified to use new dfs tags
559 
560 Revision 1.7 2007/03/01 12:42:59 jim
561 Modified slightly after code checking
562 
563 Revision 1.6 2006/06/15 09:58:59 jim
564 Minor changes to docs
565 
566 Revision 1.5 2006/05/04 11:53:40 jim
567 Fixed _save routine so that it's more consistent with the standard CPL
568 way of doing things
569 
570 Revision 1.4 2006/05/02 11:29:14 jim
571 Fixed problem where propertylist was being deleted incorrectly
572 
573 Revision 1.3 2006/04/28 08:51:00 jim
574 Removed redundant parameter ncells
575 
576 Revision 1.2 2006/04/27 14:22:04 jim
577 Fixed docs
578 
579 Revision 1.1 2006/04/24 10:42:44 jim
580 New routine
581 
582 
583 */