38 #include "vircam_utils.h"
39 #include "vircam_mask.h"
40 #include "vircam_dfs.h"
41 #include "vircam_mods.h"
42 #include "vircam_stats.h"
43 #include "vircam_fits.h"
44 #include "vircam_pfits.h"
45 #include "vircam_channel.h"
46 #include "vircam_paf.h"
47 #include "vircam_wcsutils.h"
57 static int vircam_reset_combine_create(cpl_plugin *) ;
58 static int vircam_reset_combine_exec(cpl_plugin *) ;
59 static int vircam_reset_combine_destroy(cpl_plugin *) ;
60 static int vircam_reset_combine(cpl_parameterlist *, cpl_frameset *) ;
61 static int vircam_reset_combine_save(cpl_frameset *framelist,
62 cpl_parameterlist *parlist);
63 static void vircam_reset_combine_dummy_products(
void);
64 static void vircam_reset_combine_normal(
int jext);
65 static int vircam_reset_combine_lastbit(
int jext, cpl_frameset *framelist,
66 cpl_parameterlist *parlist);
67 static void vircam_reset_combine_init(
void);
68 static void vircam_reset_combine_tidy(
int level);
90 } vircam_reset_combine_config ;
94 cpl_frameset *resetlist;
99 cpl_frame *master_reset;
100 vir_mask *master_mask;
103 cpl_propertylist *drs;
104 unsigned char *rejmask;
105 unsigned char *rejplus;
108 cpl_table *diffimstats;
109 cpl_propertylist *phupaf;
113 static cpl_frame *product_frame_mean_reset = NULL;
114 static cpl_frame *product_frame_diffimg = NULL;
115 static cpl_frame *product_frame_diffimg_stats = NULL;
116 static int we_expect;
119 static char vircam_reset_combine_description[] =
120 "vircam_reset_combine -- VIRCAM reset combine recipe.\n\n"
121 "Combine a list of reset frames into a mean reset frame. Optionally compare \n"
122 "the output frame to a master reset frame\n\n"
123 "The program requires the following files in the SOF:\n\n"
125 " -----------------------------------------------------------------------\n"
126 " %-21s A list of raw reset images\n"
127 " %-21s Optional reference reset frame\n"
128 " %-21s Optional master bad pixel map or\n"
129 " %-21s Optional master confidence map\n"
130 " %-21s Optional channel table or\n"
131 " %-21s Optional initial channel table\n"
133 "If no master reset frame is made available, then no comparison will be done\n"
134 "This means there will be no output difference image. If a master reset is\n"
135 "available, but no channel table is, then a difference image will be formed\n"
136 "but no stats will be written."
265 int cpl_plugin_get_info(cpl_pluginlist *list) {
266 cpl_recipe *recipe = cpl_calloc(1,
sizeof(*recipe));
267 cpl_plugin *plugin = &recipe->interface;
268 char alldesc[SZ_ALLDESC];
269 (void)snprintf(alldesc,SZ_ALLDESC,vircam_reset_combine_description,
270 VIRCAM_RESET_RAW,VIRCAM_REF_RESET,VIRCAM_CAL_BPM,
271 VIRCAM_CAL_CONF,VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT);
273 cpl_plugin_init(plugin,
275 VIRCAM_BINARY_VERSION,
276 CPL_PLUGIN_TYPE_RECIPE,
277 "vircam_reset_combine",
278 "VIRCAM reset combination recipe",
283 vircam_reset_combine_create,
284 vircam_reset_combine_exec,
285 vircam_reset_combine_destroy);
287 cpl_pluginlist_append(list,plugin);
303 static int vircam_reset_combine_create(cpl_plugin *plugin) {
309 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
310 recipe = (cpl_recipe *)plugin;
316 recipe->parameters = cpl_parameterlist_new();
320 p = cpl_parameter_new_range(
"vircam.vircam_reset_combine.combtype",
322 "1 == Median,\n 2 == Mean",
323 "vircam.vircam_reset_combine",
325 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"combtype");
326 cpl_parameterlist_append(recipe->parameters,p);
330 p = cpl_parameter_new_range(
"vircam.vircam_reset_combine.scaletype",
332 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
333 "vircam.vircam_reset_combine",
335 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"scaletype");
336 cpl_parameterlist_append(recipe->parameters,p);
340 p = cpl_parameter_new_value(
"vircam.vircam_reset_combine.xrej",
342 "True if using extra rejection cycle",
343 "vircam.vircam_reset_combine",
345 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"xrej");
346 cpl_parameterlist_append(recipe->parameters,p);
350 p = cpl_parameter_new_value(
"vircam.vircam_reset_combine.thresh",
352 "Rejection threshold in sigma above background",
353 "vircam.vircam_reset_combine",5.0);
354 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"thresh");
355 cpl_parameterlist_append(recipe->parameters,p);
359 p = cpl_parameter_new_enum(
"vircam.vircam_reset_combine.ncells",
361 "Number of cells for data channel stats",
362 "vircam.vircam_reset_combine",8,7,1,2,4,8,
364 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ncells");
365 cpl_parameterlist_append(recipe->parameters,p);
369 p = cpl_parameter_new_range(
"vircam.vircam_reset_combine.extenum",
371 "Extension number to be done, 0 == all",
372 "vircam.vircam_reset_combine",
374 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ext");
375 cpl_parameterlist_append(recipe->parameters,p);
391 static int vircam_reset_combine_exec(cpl_plugin *plugin) {
396 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
397 recipe = (cpl_recipe *)plugin;
401 return(vircam_reset_combine(recipe->parameters,recipe->frames));
412 static int vircam_reset_combine_destroy(cpl_plugin *plugin) {
417 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
418 recipe = (cpl_recipe *)plugin;
422 cpl_parameterlist_delete(recipe->parameters);
435 static int vircam_reset_combine(cpl_parameterlist *parlist,
436 cpl_frameset *framelist) {
437 const char *fctid=
"vircam_reset_combine";
438 int j,jst,jfn,retval,status,i,live,nx,ny;
445 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
446 cpl_msg_error(fctid,
"Input framelist NULL or has no input data");
453 cpl_msg_error(fctid,
"Input frameset is missing files. Check SOF");
459 vircam_reset_combine_init();
460 we_expect |= MEANRESET;
464 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.combtype");
465 vircam_reset_combine_config.combtype = cpl_parameter_get_int(p);
466 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.scaletype");
467 vircam_reset_combine_config.scaletype = cpl_parameter_get_int(p);
468 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.xrej");
469 vircam_reset_combine_config.xrej = cpl_parameter_get_bool(p);
470 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.thresh");
471 vircam_reset_combine_config.thresh = (float)cpl_parameter_get_double(p);
472 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.ncells");
473 vircam_reset_combine_config.ncells = cpl_parameter_get_int(p);
474 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.extenum");
475 vircam_reset_combine_config.extenum = cpl_parameter_get_int(p);
480 cpl_msg_error(fctid,
"Cannot identify RAW and CALIB frames");
488 cpl_msg_error(fctid,
"Cannot labelise the input frames");
492 VIRCAM_RESET_RAW)) == NULL) {
493 cpl_msg_error(fctid,
"Cannot find reset frames in input frameset");
496 ps.nresets = cpl_frameset_get_size(ps.resetlist);
501 VIRCAM_REF_RESET)) == NULL)
502 cpl_msg_info(fctid,
"No master reset found -- no difference image will be formed");
504 we_expect |= DIFFIMG;
514 VIRCAM_CAL_CHANTAB)) == NULL) {
516 VIRCAM_CAL_CHANTAB_INIT)) == NULL)
517 cpl_msg_info(fctid,
"No channel table found -- no difference image stats will be done");
518 }
else if (we_expect & DIFFIMG)
519 we_expect |= STATS_TAB;
526 (
const cpl_frame *)cpl_frameset_get_frame(ps.resetlist,0),
528 if (jst == -1 || jfn == -1) {
529 cpl_msg_error(fctid,
"Unable to continue");
530 vircam_reset_combine_tidy(2);
536 ps.good = cpl_malloc(ps.nresets*
sizeof(vir_fits *));
540 for (j = jst; j <= jfn; j++) {
543 isfirst = (j == jst);
548 if (ps.resets == NULL) {
550 "Extension %" CPL_SIZE_FORMAT
" resets wouldn't load",
552 retval = vircam_reset_combine_lastbit(j,framelist,parlist);
561 for (i = 0; i < ps.nresets; i++) {
565 cpl_msg_info(fctid,
"Detector flagged dead %s",
569 ps.good[ps.ngood] = ff;
578 cpl_msg_info(fctid,
"All images flagged bad for this extension");
579 retval = vircam_reset_combine_lastbit(j,framelist,parlist);
591 "Unable to load mask image %s[%" CPL_SIZE_FORMAT
"]",
594 cpl_msg_info(fctid,
"Forcing all pixels to be good from now on");
601 cpl_msg_info(fctid,
"Doing combination for extension %" CPL_SIZE_FORMAT,
604 vircam_reset_combine_config.combtype,
605 vircam_reset_combine_config.scaletype,
606 vircam_reset_combine_config.xrej,
607 vircam_reset_combine_config.thresh,
608 &(ps.outimage),&(ps.rejmask),
609 &(ps.rejplus),&(ps.drs),&status);
610 if (status == VIR_OK) {
612 vircam_reset_combine_normal(j);
617 retval = vircam_reset_combine_lastbit(j,framelist,parlist);
621 vircam_reset_combine_tidy(2);
634 static int vircam_reset_combine_save(cpl_frameset *framelist,
635 cpl_parameterlist *parlist) {
636 cpl_propertylist *plist,*elist,*p,*pafprop;
638 const char *fctid =
"vircam_reset_combine_save";
639 const char *outfile =
"resetcomb.fits";
640 const char *outdiff =
"resetdiff.fits";
641 const char *outdimst =
"resetdifftab.fits";
642 const char *outfilepaf =
"resetcomb";
643 const char *outdiffpaf =
"resetdiff";
644 const char *recipeid =
"vircam_reset_combine";
653 product_frame_mean_reset = cpl_frame_new();
654 cpl_frame_set_filename(product_frame_mean_reset,outfile);
655 cpl_frame_set_tag(product_frame_mean_reset,VIRCAM_PRO_RESET);
656 cpl_frame_set_type(product_frame_mean_reset,CPL_FRAME_TYPE_IMAGE);
657 cpl_frame_set_group(product_frame_mean_reset,CPL_FRAME_GROUP_PRODUCT);
658 cpl_frame_set_level(product_frame_mean_reset,CPL_FRAME_LEVEL_FINAL);
663 ps.phupaf = vircam_paf_phu_items(plist);
664 if (ps.master_reset != NULL) {
665 cpl_propertylist_update_string(ps.phupaf,
"REF_RESET",
666 cpl_frame_get_filename(ps.master_reset));
667 cpl_propertylist_set_comment(ps.phupaf,
"REF_RESET",
668 "Reference reset used");
677 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
678 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
679 cpl_msg_error(fctid,
"Cannot save product PHU");
680 cpl_frame_delete(product_frame_mean_reset);
683 cpl_frameset_insert(framelist,product_frame_mean_reset);
687 if (we_expect & DIFFIMG) {
688 product_frame_diffimg = cpl_frame_new();
689 cpl_frame_set_filename(product_frame_diffimg,outdiff);
690 cpl_frame_set_tag(product_frame_diffimg,
691 VIRCAM_PRO_DIFFIMG_RESET);
692 cpl_frame_set_type(product_frame_diffimg,CPL_FRAME_TYPE_IMAGE);
693 cpl_frame_set_group(product_frame_diffimg,CPL_FRAME_GROUP_PRODUCT);
694 cpl_frame_set_level(product_frame_diffimg,CPL_FRAME_LEVEL_FINAL);
705 if (cpl_image_save(NULL,outdiff,CPL_TYPE_UCHAR,plist,
706 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
707 cpl_msg_error(fctid,
"Cannot save product PHU");
708 cpl_frame_delete(product_frame_diffimg);
711 cpl_frameset_insert(framelist,product_frame_diffimg);
717 if (we_expect & STATS_TAB) {
718 product_frame_diffimg_stats = cpl_frame_new();
719 cpl_frame_set_filename(product_frame_diffimg_stats,outdimst);
720 cpl_frame_set_tag(product_frame_diffimg_stats,
721 VIRCAM_PRO_DIFFIMG_RESET_STATS);
722 cpl_frame_set_type(product_frame_diffimg_stats,
723 CPL_FRAME_TYPE_TABLE);
724 cpl_frame_set_group(product_frame_diffimg_stats,
725 CPL_FRAME_GROUP_PRODUCT);
726 cpl_frame_set_level(product_frame_diffimg_stats,
727 CPL_FRAME_LEVEL_FINAL);
733 product_frame_diffimg_stats,
741 p = cpl_propertylist_duplicate(elist);
743 if (! (we_get & STATS_TAB))
751 if (cpl_table_save(ps.diffimstats,plist,p,outdimst,
752 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
753 cpl_msg_error(fctid,
"Cannot save product table extension");
754 cpl_propertylist_delete(p);
757 cpl_propertylist_delete(p);
758 cpl_frameset_insert(framelist,product_frame_diffimg_stats);
765 cpl_propertylist_update_int(plist,
"ESO PRO DATANCOM",ps.ngood);
770 p = cpl_propertylist_duplicate(plist);
771 if (! (we_get & MEANRESET))
774 parlist,(
char *)recipeid,
"PRO-1.15",
779 cpl_propertylist_update_float(p,
"ESO QC RESETMED",
780 vircam_reset_combine_config.resetmed);
781 cpl_propertylist_set_comment(p,
"ESO QC RESETMED",
782 "Median of mean reset frame");
783 cpl_propertylist_update_float(p,
"ESO QC RESETRMS",
784 vircam_reset_combine_config.resetrms);
785 cpl_propertylist_set_comment(p,
"ESO QC RESETRMS",
786 "RMS of mean reset frame");
787 if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
788 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
789 cpl_msg_error(fctid,
"Cannot save product image extension");
790 cpl_propertylist_delete(p);
796 pafprop = vircam_paf_req_items(p);
798 vircam_paf_append(pafprop,p,
"ESO PRO CATG");
799 vircam_paf_append(pafprop,p,
"ESO PRO DATANCOM");
800 if (vircam_paf_print((
char *)outfilepaf,
"VIRCAM/vircam_reset_combine",
801 "QC file",pafprop) != VIR_OK)
802 cpl_msg_warning(fctid,
"Unable to save PAF for mean reset");
803 cpl_propertylist_delete(pafprop);
804 cpl_propertylist_delete(p);
808 if (we_expect & DIFFIMG) {
809 p = cpl_propertylist_duplicate(plist);
810 if (! (we_get & DIFFIMG))
812 cpl_propertylist_update_float(p,
"ESO QC RESETDIFF_MED",
813 vircam_reset_combine_config.resetdiff_med);
814 cpl_propertylist_set_comment(p,
"ESO QC RESETDIFF_MED",
815 "Median value of difference image");
816 cpl_propertylist_update_float(p,
"ESO QC RESETDIFF_RMS",
817 vircam_reset_combine_config.resetdiff_rms);
818 cpl_propertylist_set_comment(p,
"ESO QC RESETDIFF_RMS",
819 "RMS value of difference image");
821 framelist,parlist,(
char *)recipeid,
823 if (cpl_image_save(ps.diffimg,outdiff,CPL_TYPE_FLOAT,p,
824 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
825 cpl_propertylist_delete(p);
826 cpl_msg_error(fctid,
"Cannot save product image extension");
831 pafprop = vircam_paf_req_items(p);
833 vircam_paf_append(pafprop,p,
"ESO PRO CATG");
834 if (vircam_paf_print((
char *)outdiffpaf,
"VIRCAM/vircam_reset_combine",
835 "QC file",pafprop) != VIR_OK)
836 cpl_msg_warning(fctid,
"Unable to save PAF for difference image");
837 cpl_propertylist_delete(pafprop);
838 cpl_propertylist_delete(p);
843 if (! isfirst && (we_expect & STATS_TAB)) {
844 p = cpl_propertylist_duplicate(plist);
845 if (! (we_get & STATS_TAB))
848 framelist,parlist,(
char *)recipeid,
852 if (cpl_table_save(ps.diffimstats,NULL,p,outdimst,CPL_IO_EXTEND)
854 cpl_msg_error(fctid,
"Cannot save product table extension");
855 cpl_propertylist_delete(p);
858 cpl_propertylist_delete(p);
870 static void vircam_reset_combine_dummy_products(
void) {
874 if (we_get == we_expect)
879 if (! (we_get & MEANRESET)) {
884 vircam_reset_combine_config.resetmed = 0.0;
885 vircam_reset_combine_config.resetrms = 0.0;
890 if ((we_expect & DIFFIMG) && ! (we_get & DIFFIMG)) {
891 vircam_reset_combine_config.resetdiff_med = 0.0;
892 vircam_reset_combine_config.resetdiff_rms = 0.0;
901 if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
915 static void vircam_reset_combine_normal(
int jext) {
919 float med,sig,*idata,grms,gdiff;
920 const char *fctid=
"vircam_reset_combine_normal";
926 nx = (int)cpl_image_get_size_x(ps.outimage);
927 ny = (int)cpl_image_get_size_y(ps.outimage);
933 idata = cpl_image_get_data(ps.outimage);
936 vircam_reset_combine_config.resetmed = med;
937 vircam_reset_combine_config.resetrms = sig;
941 if (ps.master_reset != NULL) {
943 if (ps.mrimage == NULL)
945 "Master reset extension %" CPL_SIZE_FORMAT
" won't load",
949 "Master reset extension %" CPL_SIZE_FORMAT
" is a dummy!",
951 freefits(ps.mrimage);
958 if (ps.chantab != NULL) {
959 ctable = cpl_table_load(cpl_frame_get_filename(ps.chantab),jext,0);
960 if (ctable == NULL) {
963 "Channel table extension %" CPL_SIZE_FORMAT
" won't load",
967 "Channel table extension %" CPL_SIZE_FORMAT
" has errors",
971 p = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
975 "Channel table extensions %" CPL_SIZE_FORMAT
" is a dummy",
990 vircam_reset_combine_config.resetdiff_med = 0.0;
991 vircam_reset_combine_config.resetdiff_rms = 0.0;
992 ncells = vircam_reset_combine_config.ncells;
994 ps.outimage,bpm,ctable,ncells,1,
995 &gdiff,&grms,&(ps.diffimg),
998 vircam_reset_combine_config.resetdiff_med = gdiff;
999 vircam_reset_combine_config.resetdiff_rms = grms;
1001 if (ps.diffimg != NULL)
1003 if (ps.diffimstats != NULL)
1004 we_get |= STATS_TAB;
1018 static int vircam_reset_combine_lastbit(
int jext, cpl_frameset *framelist,
1019 cpl_parameterlist *parlist) {
1021 const char *fctid=
"vircam_reset_combine_lastbit";
1025 vircam_reset_combine_dummy_products();
1030 "Saving products for extension %" CPL_SIZE_FORMAT,
1032 retval = vircam_reset_combine_save(framelist,parlist);
1034 vircam_reset_combine_tidy(2);
1040 vircam_reset_combine_tidy(1);
1050 static void vircam_reset_combine_init(
void) {
1052 ps.resetlist = NULL;
1056 ps.master_reset = NULL;
1057 ps.master_mask = NULL;
1065 ps.diffimstats = NULL;
1075 static void vircam_reset_combine_tidy(
int level) {
1076 freeimage(ps.outimage);
1077 freefitslist(ps.resets,ps.nresets);
1078 freespace(ps.rejmask);
1079 freespace(ps.rejplus);
1080 freepropertylist(ps.drs);
1081 freefits(ps.mrimage);
1082 freeimage(ps.diffimg);
1083 freetable(ps.diffimstats);
1086 freespace(ps.labels);
1087 freeframeset(ps.resetlist);
1088 freeframe(ps.master_reset);
1089 freemask(ps.master_mask);
1090 freeframe(ps.chantab);
1092 freepropertylist(ps.phupaf);
const char * vircam_get_license(void)
void vircam_mask_force(vir_mask *m, int nx, int ny)
int vircam_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
int vircam_chantab_verify(cpl_table *intab)
int vircam_is_dummy(cpl_propertylist *p)
void vircam_merge_propertylists(cpl_propertylist *p1, cpl_propertylist *p2)
vir_fits ** vircam_fits_load_list(cpl_frameset *f, cpl_type type, int exten)
cpl_frame * vircam_frameset_subgroup_1(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
void vircam_mask_clear(vir_mask *m)
cpl_image * vircam_dummy_image(vir_fits *model)
int vircam_mask_load(vir_mask *m, int nexten, int nx, int ny)
char * vircam_fits_get_fullname(vir_fits *p)
unsigned char * vircam_mask_get_data(vir_mask *m)
cpl_image * vircam_fits_get_image(vir_fits *p)
cpl_table * vircam_create_diffimg_stats(int nrows)
cpl_frameset * vircam_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
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)
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)
int vircam_fits_set_error(vir_fits *p, int status)
void vircam_medmad(float *data, unsigned char *bpm, long np, float *med, float *mad)
void vircam_dummy_property(cpl_propertylist *p)
cpl_propertylist * vircam_fits_get_phu(vir_fits *p)
vir_fits * vircam_fits_load(cpl_frame *frame, cpl_type type, int nexten)
cpl_propertylist * vircam_fits_get_ehu(vir_fits *p)
int vircam_frameset_fexists(cpl_frameset *frameset)
const char * vircam_mask_get_filename(vir_mask *m)
vir_mask * vircam_mask_define(cpl_frameset *framelist, cpl_size *labels, cpl_size nlab)
int vircam_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
int vircam_imcombine(vir_fits **fset, int nfits, int combtype, int scaletype, int xrej, float thresh, cpl_image **outimage, unsigned char **rejmask, unsigned char **rejplus, cpl_propertylist **drs, int *status)
Stack images into a mean or median image with rejection.
void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1, int *out2)
void vircam_difference_image(cpl_image *master, cpl_image *prog, unsigned char *bpm, cpl_table *chantab, int ncells, int oper, float *global_diff, float *global_rms, cpl_image **diffim, cpl_table **diffimstats)
int vircam_removewcs(cpl_propertylist *p, int *status)
int vircam_dfs_set_groups(cpl_frameset *set)