VIRCAM Pipeline 2.3.15
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
48static int vircam_imcombine_create(cpl_plugin *) ;
49static int vircam_imcombine_exec(cpl_plugin *) ;
50static int vircam_imcombine_destroy(cpl_plugin *) ;
51static int vircam_imcombine_test(cpl_parameterlist *, cpl_frameset *) ;
52static int vircam_imcombine_save(cpl_frameset *framelist,
53 cpl_parameterlist *parlist);
54static void vircam_imcombine_init(void);
55static void vircam_imcombine_tidy(void);
56
57/* Static global variables */
58
59static 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
72static struct {
73 cpl_size *labels;
74 cpl_frameset *imagelist;
75 casu_fits **images;
76 int nimages;
77 cpl_image *outimage;
78} ps;
79
80static int isfirst;
81static cpl_frame *product_frame = NULL;
82
83static 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
160int 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
197static 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
275static 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
296static 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
319static 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
444static 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
511static 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
524static 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 $
536Revision 1.16 2012/01/16 14:44:02 jim
537Fixed test recipes for cpl6 compliance
538
539Revision 1.15 2012/01/15 17:40:09 jim
540Minor modifications to take into accout the changes in cpl API for v6
541
542Revision 1.14 2009/09/09 09:51:13 jim
543modified to use new saving routines so that headers are right
544
545Revision 1.13 2007/10/25 19:38:22 jim
546modified to keep lint happy
547
548Revision 1.12 2007/10/15 12:53:55 jim
549Modified for compatibility with cpl_4.0
550
551Revision 1.11 2007/07/09 13:22:09 jim
552Modified to use new version of vircam_exten_range
553
554Revision 1.10 2007/05/02 12:53:11 jim
555typo fixes in docs
556
557Revision 1.9 2007/04/13 12:27:38 jim
558Added some extra docs
559
560Revision 1.8 2007/04/04 10:36:29 jim
561Modified to use new dfs tags
562
563Revision 1.7 2007/03/01 12:42:59 jim
564Modified slightly after code checking
565
566Revision 1.6 2006/06/15 09:58:59 jim
567Minor changes to docs
568
569Revision 1.5 2006/05/04 11:53:40 jim
570Fixed _save routine so that it's more consistent with the standard CPL
571way of doing things
572
573Revision 1.4 2006/05/02 11:29:14 jim
574Fixed problem where propertylist was being deleted incorrectly
575
576Revision 1.3 2006/04/28 08:51:00 jim
577Removed redundant parameter ncells
578
579Revision 1.2 2006/04/27 14:22:04 jim
580Fixed docs
581
582Revision 1.1 2006/04/24 10:42:44 jim
583New 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