38#include <casu_utils.h>
40#include <casu_stats.h>
41#include <casu_wcsutils.h>
44#include "vircam_utils.h"
45#include "vircam_dfs.h"
46#include "vircam_mods.h"
47#include "vircam_pfits.h"
48#include "vircam_channel.h"
49#include "vircam_paf.h"
59static int vircam_reset_combine_create(cpl_plugin *) ;
60static int vircam_reset_combine_exec(cpl_plugin *) ;
61static int vircam_reset_combine_destroy(cpl_plugin *) ;
62static int vircam_reset_combine(cpl_parameterlist *, cpl_frameset *) ;
63static int vircam_reset_combine_save(cpl_frameset *framelist,
64 cpl_parameterlist *parlist);
65static void vircam_reset_combine_dummy_products(
void);
66static void vircam_reset_combine_normal(
int jext);
67static int vircam_reset_combine_lastbit(
int jext, cpl_frameset *framelist,
68 cpl_parameterlist *parlist);
69static void vircam_reset_combine_init(
void);
70static void vircam_reset_combine_tidy(
int level);
92} vircam_reset_combine_config ;
96 cpl_frameset *resetlist;
101 cpl_frame *master_reset;
102 casu_mask *master_mask;
105 cpl_propertylist *drs;
106 unsigned char *rejmask;
107 unsigned char *rejplus;
110 cpl_table *diffimstats;
111 cpl_propertylist *phupaf;
115static cpl_frame *product_frame_mean_reset = NULL;
116static cpl_frame *product_frame_diffimg = NULL;
117static cpl_frame *product_frame_diffimg_stats = NULL;
121static char vircam_reset_combine_description[] =
122"vircam_reset_combine -- VIRCAM reset combine recipe.\n\n"
123"Combine a list of reset frames into a mean reset frame. Optionally compare \n"
124"the output frame to a master reset frame\n\n"
125"The program requires the following files in the SOF:\n\n"
127" -----------------------------------------------------------------------\n"
128" %-21s A list of raw reset images\n"
129" %-21s Optional reference reset frame\n"
130" %-21s Optional master bad pixel map or\n"
131" %-21s Optional master confidence map\n"
132" %-21s Optional channel table or\n"
133" %-21s Optional initial channel table\n"
135"If no master reset frame is made available, then no comparison will be done\n"
136"This means there will be no output difference image. If a master reset is\n"
137"available, but no channel table is, then a difference image will be formed\n"
138"but no stats will be written."
267int cpl_plugin_get_info(cpl_pluginlist *list) {
268 cpl_recipe *recipe = cpl_calloc(1,
sizeof(*recipe));
269 cpl_plugin *plugin = &recipe->interface;
270 char alldesc[SZ_ALLDESC];
271 (void)snprintf(alldesc,SZ_ALLDESC,vircam_reset_combine_description,
272 VIRCAM_RESET_RAW,VIRCAM_REF_RESET,VIRCAM_CAL_BPM,
273 VIRCAM_CAL_CONF,VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT);
275 cpl_plugin_init(plugin,
277 VIRCAM_BINARY_VERSION,
278 CPL_PLUGIN_TYPE_RECIPE,
279 "vircam_reset_combine",
280 "VIRCAM reset combination recipe",
285 vircam_reset_combine_create,
286 vircam_reset_combine_exec,
287 vircam_reset_combine_destroy);
289 cpl_pluginlist_append(list,plugin);
305static int vircam_reset_combine_create(cpl_plugin *plugin) {
311 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
312 recipe = (cpl_recipe *)plugin;
318 recipe->parameters = cpl_parameterlist_new();
322 p = cpl_parameter_new_range(
"vircam.vircam_reset_combine.combtype",
324 "1 == Median,\n 2 == Mean",
325 "vircam.vircam_reset_combine",
327 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"combtype");
328 cpl_parameterlist_append(recipe->parameters,p);
332 p = cpl_parameter_new_range(
"vircam.vircam_reset_combine.scaletype",
334 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
335 "vircam.vircam_reset_combine",
337 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"scaletype");
338 cpl_parameterlist_append(recipe->parameters,p);
342 p = cpl_parameter_new_value(
"vircam.vircam_reset_combine.xrej",
344 "True if using extra rejection cycle",
345 "vircam.vircam_reset_combine",
347 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"xrej");
348 cpl_parameterlist_append(recipe->parameters,p);
352 p = cpl_parameter_new_value(
"vircam.vircam_reset_combine.thresh",
354 "Rejection threshold in sigma above background",
355 "vircam.vircam_reset_combine",5.0);
356 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"thresh");
357 cpl_parameterlist_append(recipe->parameters,p);
361 p = cpl_parameter_new_enum(
"vircam.vircam_reset_combine.ncells",
363 "Number of cells for data channel stats",
364 "vircam.vircam_reset_combine",8,7,1,2,4,8,
366 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ncells");
367 cpl_parameterlist_append(recipe->parameters,p);
371 p = cpl_parameter_new_range(
"vircam.vircam_reset_combine.extenum",
373 "Extension number to be done, 0 == all",
374 "vircam.vircam_reset_combine",
376 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ext");
377 cpl_parameterlist_append(recipe->parameters,p);
393static int vircam_reset_combine_exec(cpl_plugin *plugin) {
398 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
399 recipe = (cpl_recipe *)plugin;
403 return(vircam_reset_combine(recipe->parameters,recipe->frames));
414static int vircam_reset_combine_destroy(cpl_plugin *plugin) {
419 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
420 recipe = (cpl_recipe *)plugin;
424 cpl_parameterlist_delete(recipe->parameters);
437static int vircam_reset_combine(cpl_parameterlist *parlist,
438 cpl_frameset *framelist) {
439 const char *fctid=
"vircam_reset_combine";
440 int j,jst,jfn,retval,status,i,live,nx,ny;
447 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
448 cpl_msg_error(fctid,
"Input framelist NULL or has no input data");
454 vircam_reset_combine_init();
455 we_expect |= MEANRESET;
459 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.combtype");
460 vircam_reset_combine_config.combtype = cpl_parameter_get_int(p);
461 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.scaletype");
462 vircam_reset_combine_config.scaletype = cpl_parameter_get_int(p);
463 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.xrej");
464 vircam_reset_combine_config.xrej = cpl_parameter_get_bool(p);
465 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.thresh");
466 vircam_reset_combine_config.thresh = (float)cpl_parameter_get_double(p);
467 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.ncells");
468 vircam_reset_combine_config.ncells = cpl_parameter_get_int(p);
469 p = cpl_parameterlist_find(parlist,
"vircam.vircam_reset_combine.extenum");
470 vircam_reset_combine_config.extenum = cpl_parameter_get_int(p);
475 cpl_msg_error(fctid,
"Cannot identify RAW and CALIB frames");
483 cpl_msg_error(fctid,
"Cannot labelise the input frames");
487 VIRCAM_RESET_RAW)) == NULL) {
488 cpl_msg_error(fctid,
"Cannot find reset frames in input frameset");
491 ps.nresets = cpl_frameset_get_size(ps.resetlist);
496 VIRCAM_REF_RESET)) == NULL)
497 cpl_msg_info(fctid,
"No master reset found -- no difference image will be formed");
499 we_expect |= DIFFIMG;
510 VIRCAM_CAL_CHANTAB)) == NULL) {
512 VIRCAM_CAL_CHANTAB_INIT)) == NULL)
513 cpl_msg_info(fctid,
"No channel table found -- no difference image stats will be done");
514 }
else if (we_expect & DIFFIMG)
515 we_expect |= STATS_TAB;
522 (
const cpl_frame *)cpl_frameset_get_position(ps.resetlist,0),
524 if (jst == -1 || jfn == -1) {
525 cpl_msg_error(fctid,
"Unable to continue");
526 vircam_reset_combine_tidy(2);
532 ps.good = cpl_malloc(ps.nresets*
sizeof(casu_fits *));
536 for (j = jst; j <= jfn; j++) {
539 isfirst = (j == jst);
544 if (ps.resets == NULL) {
546 "Extension %" CPL_SIZE_FORMAT
" resets wouldn't load",
548 retval = vircam_reset_combine_lastbit(j,framelist,parlist);
557 for (i = 0; i < ps.nresets; i++) {
561 cpl_msg_info(fctid,
"Detector flagged dead %s",
565 ps.good[ps.ngood] = ff;
574 cpl_msg_info(fctid,
"All images flagged bad for this extension");
575 retval = vircam_reset_combine_lastbit(j,framelist,parlist);
587 "Unable to load mask image %s[%" CPL_SIZE_FORMAT
"]",
590 cpl_msg_info(fctid,
"Forcing all pixels to be good from now on");
597 cpl_msg_info(fctid,
"Doing combination for extension %" CPL_SIZE_FORMAT,
600 vircam_reset_combine_config.combtype,
601 vircam_reset_combine_config.scaletype,
602 vircam_reset_combine_config.xrej,
603 vircam_reset_combine_config.thresh,
"EXPTIME",
604 &(ps.outimage),NULL,&(ps.rejmask),
605 &(ps.rejplus),&(ps.drs),&status);
606 if (status == CASU_OK) {
608 vircam_reset_combine_normal(j);
613 retval = vircam_reset_combine_lastbit(j,framelist,parlist);
617 vircam_reset_combine_tidy(2);
630static int vircam_reset_combine_save(cpl_frameset *framelist,
631 cpl_parameterlist *parlist) {
632 cpl_propertylist *plist,*elist,*p,*pafprop;
633 const char *fctid =
"vircam_reset_combine_save";
634 const char *outfile =
"resetcomb.fits";
635 const char *outdiff =
"resetdiff.fits";
636 const char *outdimst =
"resetdifftab.fits";
637 const char *outfilepaf =
"resetcomb";
638 const char *outdiffpaf =
"resetdiff";
639 const char *recipeid =
"vircam_reset_combine";
648 product_frame_mean_reset = cpl_frame_new();
649 cpl_frame_set_filename(product_frame_mean_reset,outfile);
650 cpl_frame_set_tag(product_frame_mean_reset,VIRCAM_PRO_RESET);
651 cpl_frame_set_type(product_frame_mean_reset,CPL_FRAME_TYPE_IMAGE);
652 cpl_frame_set_group(product_frame_mean_reset,CPL_FRAME_GROUP_PRODUCT);
653 cpl_frame_set_level(product_frame_mean_reset,CPL_FRAME_LEVEL_FINAL);
658 ps.phupaf = vircam_paf_phu_items(plist);
659 if (ps.master_reset != NULL) {
660 cpl_propertylist_update_string(ps.phupaf,
"REF_RESET",
661 cpl_frame_get_filename(ps.master_reset));
662 cpl_propertylist_set_comment(ps.phupaf,
"REF_RESET",
663 "Reference reset used");
672 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
673 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
674 cpl_msg_error(fctid,
"Cannot save product PHU");
675 cpl_frame_delete(product_frame_mean_reset);
678 cpl_frameset_insert(framelist,product_frame_mean_reset);
682 if (we_expect & DIFFIMG) {
683 product_frame_diffimg = cpl_frame_new();
684 cpl_frame_set_filename(product_frame_diffimg,outdiff);
685 cpl_frame_set_tag(product_frame_diffimg,
686 VIRCAM_PRO_DIFFIMG_RESET);
687 cpl_frame_set_type(product_frame_diffimg,CPL_FRAME_TYPE_IMAGE);
688 cpl_frame_set_group(product_frame_diffimg,CPL_FRAME_GROUP_PRODUCT);
689 cpl_frame_set_level(product_frame_diffimg,CPL_FRAME_LEVEL_FINAL);
700 if (cpl_image_save(NULL,outdiff,CPL_TYPE_UCHAR,plist,
701 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
702 cpl_msg_error(fctid,
"Cannot save product PHU");
703 cpl_frame_delete(product_frame_diffimg);
706 cpl_frameset_insert(framelist,product_frame_diffimg);
712 if (we_expect & STATS_TAB) {
713 product_frame_diffimg_stats = cpl_frame_new();
714 cpl_frame_set_filename(product_frame_diffimg_stats,outdimst);
715 cpl_frame_set_tag(product_frame_diffimg_stats,
716 VIRCAM_PRO_DIFFIMG_RESET_STATS);
717 cpl_frame_set_type(product_frame_diffimg_stats,
718 CPL_FRAME_TYPE_TABLE);
719 cpl_frame_set_group(product_frame_diffimg_stats,
720 CPL_FRAME_GROUP_PRODUCT);
721 cpl_frame_set_level(product_frame_diffimg_stats,
722 CPL_FRAME_LEVEL_FINAL);
728 product_frame_diffimg_stats,
736 p = cpl_propertylist_duplicate(elist);
738 if (! (we_get & STATS_TAB))
745 if (cpl_table_save(ps.diffimstats,plist,p,outdimst,
746 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
747 cpl_msg_error(fctid,
"Cannot save product table extension");
748 cpl_propertylist_delete(p);
751 cpl_propertylist_delete(p);
752 cpl_frameset_insert(framelist,product_frame_diffimg_stats);
759 cpl_propertylist_update_int(plist,
"ESO PRO DATANCOM",ps.ngood);
764 p = cpl_propertylist_duplicate(plist);
765 if (! (we_get & MEANRESET))
768 parlist,(
char *)recipeid,
"PRO-1.15",
773 cpl_propertylist_update_float(p,
"ESO QC RESETMED",
774 vircam_reset_combine_config.resetmed);
775 cpl_propertylist_set_comment(p,
"ESO QC RESETMED",
776 "Median of mean reset frame");
777 cpl_propertylist_update_float(p,
"ESO QC RESETRMS",
778 vircam_reset_combine_config.resetrms);
779 cpl_propertylist_set_comment(p,
"ESO QC RESETRMS",
780 "RMS of mean reset frame");
781 if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
782 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
783 cpl_msg_error(fctid,
"Cannot save product image extension");
784 cpl_propertylist_delete(p);
790 pafprop = vircam_paf_req_items(p);
792 vircam_paf_append(pafprop,p,
"ESO PRO CATG");
793 vircam_paf_append(pafprop,p,
"ESO PRO DATANCOM");
794 if (vircam_paf_print((
char *)outfilepaf,
"VIRCAM/vircam_reset_combine",
795 "QC file",pafprop) != CASU_OK)
796 cpl_msg_warning(fctid,
"Unable to save PAF for mean reset");
797 cpl_propertylist_delete(pafprop);
798 cpl_propertylist_delete(p);
802 if (we_expect & DIFFIMG) {
803 p = cpl_propertylist_duplicate(plist);
804 if (! (we_get & DIFFIMG))
806 cpl_propertylist_update_float(p,
"ESO QC RESETDIFF_MED",
807 vircam_reset_combine_config.resetdiff_med);
808 cpl_propertylist_set_comment(p,
"ESO QC RESETDIFF_MED",
809 "Median value of difference image");
810 cpl_propertylist_update_float(p,
"ESO QC RESETDIFF_RMS",
811 vircam_reset_combine_config.resetdiff_rms);
812 cpl_propertylist_set_comment(p,
"ESO QC RESETDIFF_RMS",
813 "RMS value of difference image");
815 framelist,parlist,(
char *)recipeid,
817 if (cpl_image_save(ps.diffimg,outdiff,CPL_TYPE_FLOAT,p,
818 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
819 cpl_propertylist_delete(p);
820 cpl_msg_error(fctid,
"Cannot save product image extension");
825 pafprop = vircam_paf_req_items(p);
827 vircam_paf_append(pafprop,p,
"ESO PRO CATG");
828 if (vircam_paf_print((
char *)outdiffpaf,
"VIRCAM/vircam_reset_combine",
829 "QC file",pafprop) != CASU_OK)
830 cpl_msg_warning(fctid,
"Unable to save PAF for difference image");
831 cpl_propertylist_delete(pafprop);
832 cpl_propertylist_delete(p);
837 if (! isfirst && (we_expect & STATS_TAB)) {
838 p = cpl_propertylist_duplicate(plist);
839 if (! (we_get & STATS_TAB))
843 framelist,parlist,(
char *)recipeid,
845 if (cpl_table_save(ps.diffimstats,NULL,p,outdimst,CPL_IO_EXTEND)
847 cpl_msg_error(fctid,
"Cannot save product table extension");
848 cpl_propertylist_delete(p);
851 cpl_propertylist_delete(p);
863static void vircam_reset_combine_dummy_products(
void) {
867 if (we_get == we_expect)
872 if (! (we_get & MEANRESET)) {
877 vircam_reset_combine_config.resetmed = 0.0;
878 vircam_reset_combine_config.resetrms = 0.0;
883 if ((we_expect & DIFFIMG) && ! (we_get & DIFFIMG)) {
884 vircam_reset_combine_config.resetdiff_med = 0.0;
885 vircam_reset_combine_config.resetdiff_rms = 0.0;
894 if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
908static void vircam_reset_combine_normal(
int jext) {
912 float med,sig,*idata,grms,gdiff;
913 const char *fctid=
"vircam_reset_combine_normal";
919 nx = (int)cpl_image_get_size_x(ps.outimage);
920 ny = (int)cpl_image_get_size_y(ps.outimage);
926 idata = cpl_image_get_data(ps.outimage);
929 vircam_reset_combine_config.resetmed = med;
930 vircam_reset_combine_config.resetrms = sig;
934 if (ps.master_reset != NULL) {
936 if (ps.mrimage == NULL)
938 "Master reset extension %" CPL_SIZE_FORMAT
" won't load",
942 "Master reset extension %" CPL_SIZE_FORMAT
" is a dummy!",
944 freefits(ps.mrimage);
951 if (ps.chantab != NULL) {
952 ctable = cpl_table_load(cpl_frame_get_filename(ps.chantab),jext,0);
953 if (ctable == NULL) {
956 "Channel table extension %" CPL_SIZE_FORMAT
" won't load",
960 "Channel table extension %" CPL_SIZE_FORMAT
" has errors",
964 p = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
968 "Channel table extensions %" CPL_SIZE_FORMAT
" is a dummy",
983 vircam_reset_combine_config.resetdiff_med = 0.0;
984 vircam_reset_combine_config.resetdiff_rms = 0.0;
985 ncells = vircam_reset_combine_config.ncells;
987 ps.outimage,bpm,ctable,ncells,1,
988 &gdiff,&grms,&(ps.diffimg),
991 vircam_reset_combine_config.resetdiff_med = gdiff;
992 vircam_reset_combine_config.resetdiff_rms = grms;
994 if (ps.diffimg != NULL)
996 if (ps.diffimstats != NULL)
1011static int vircam_reset_combine_lastbit(
int jext, cpl_frameset *framelist,
1012 cpl_parameterlist *parlist) {
1014 const char *fctid=
"vircam_reset_combine_lastbit";
1018 vircam_reset_combine_dummy_products();
1023 "Saving products for extension %" CPL_SIZE_FORMAT,
1025 retval = vircam_reset_combine_save(framelist,parlist);
1027 vircam_reset_combine_tidy(2);
1033 vircam_reset_combine_tidy(1);
1043static void vircam_reset_combine_init(
void) {
1045 ps.resetlist = NULL;
1049 ps.master_reset = NULL;
1050 ps.master_mask = NULL;
1058 ps.diffimstats = NULL;
1068static void vircam_reset_combine_tidy(
int level) {
1069 freeimage(ps.outimage);
1070 freefitslist(ps.resets,ps.nresets);
1071 freespace(ps.rejmask);
1072 freespace(ps.rejplus);
1073 freepropertylist(ps.drs);
1074 freefits(ps.mrimage);
1075 freeimage(ps.diffimg);
1076 freetable(ps.diffimstats);
1079 freespace(ps.labels);
1080 freeframeset(ps.resetlist);
1081 freeframe(ps.master_reset);
1082 freemask(ps.master_mask);
1083 freeframe(ps.chantab);
1085 freepropertylist(ps.phupaf);
cpl_image * casu_fits_get_image(casu_fits *p)
casu_fits ** casu_fits_load_list(cpl_frameset *f, cpl_type type, int exten)
int casu_fits_set_error(casu_fits *p, int status)
char * casu_fits_get_fullname(casu_fits *p)
cpl_propertylist * casu_fits_get_phu(casu_fits *p)
cpl_propertylist * casu_fits_get_ehu(casu_fits *p)
casu_fits * casu_fits_load(cpl_frame *frame, cpl_type type, int nexten)
void casu_mask_force(casu_mask *m, int nx, int ny)
unsigned char * casu_mask_get_data(casu_mask *m)
int casu_mask_load(casu_mask *m, int nexten, int nx, int ny)
void casu_mask_clear(casu_mask *m)
casu_mask * casu_mask_define(cpl_frameset *framelist, cpl_size *labels, cpl_size nlab, const char *conftag, const char *bpmtag)
const char * casu_mask_get_filename(casu_mask *m)
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.
void casu_medmad(float *data, unsigned char *bpm, long np, float *med, float *mad)
int casu_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Compare input tags.
void casu_merge_propertylists(cpl_propertylist *p1, cpl_propertylist *p2)
Merge two propertylists.
void casu_dummy_property(cpl_propertylist *p)
Set dummy property keyword.
cpl_frame * casu_frameset_subgroup_1(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Extract a frame of a given label from a frameset.
cpl_image * casu_dummy_image(casu_fits *model)
Create a dummy image of zeros based on a model.
cpl_frameset * casu_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Extract a frameset from another frameset.
int casu_removewcs(cpl_propertylist *p, int *status)
int vircam_chantab_verify(cpl_table *intab)
int vircam_dfs_set_groups(cpl_frameset *set)
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)
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)
int vircam_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
const char * vircam_get_license(void)
cpl_table * vircam_create_diffimg_stats(int nrows)
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_is_dummy(cpl_propertylist *p)
void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1, int *out2)