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