38 #include <casu_utils.h>
39 #include <casu_mask.h>
40 #include <casu_stats.h>
42 #include "vircam_utils.h"
43 #include "vircam_pfits.h"
44 #include "vircam_dfs.h"
45 #include "vircam_paf.h"
49 static int vircam_dark_current_create(cpl_plugin *) ;
50 static int vircam_dark_current_exec(cpl_plugin *) ;
51 static int vircam_dark_current_destroy(cpl_plugin *) ;
52 static int vircam_dark_current(cpl_parameterlist *, cpl_frameset *) ;
53 static int vircam_dark_current_save(cpl_frameset *filelist,
54 cpl_parameterlist *parlist);
55 static int vircam_dark_current_lastbit(
int jext, cpl_frameset *framelist,
56 cpl_parameterlist *parlist);
57 static void vircam_dark_current_init(
void);
58 static void vircam_dark_current_tidy(
void);
71 float mean_dark_current;
72 } vircam_dark_current_config;
76 cpl_frameset *darklist;
77 casu_mask *master_mask;
86 cpl_propertylist *phupaf;
89 static cpl_frame *product_frame = NULL;
93 static char vircam_dark_current_description[] =
94 "vircam_dark_current -- VIRCAM recipe for measuring dark current.\n"
95 "A list of dark frames is given. A robust estimate of the dark current\n"
96 "is calculated by fitting a median slope to the dark value vs exposure time\n"
97 "for each pixel. The output is to a dark current map which shows the dark\n"
98 "current in counts per second for each input pixel.\n\n"
99 "The program requires the following files in the SOF:\n\n"
101 " -----------------------------------------------------------------------\n"
102 " %-21s A list of raw dark images with various exposure times\n"
103 " %-21s Optional master bad pixel map or\n"
104 " %-21s Optional master confidence map\n"
181 int cpl_plugin_get_info(cpl_pluginlist *list) {
182 cpl_recipe *recipe = cpl_calloc(1,
sizeof(*recipe));
183 cpl_plugin *plugin = &recipe->interface;
184 char alldesc[SZ_ALLDESC];
185 (void)snprintf(alldesc,SZ_ALLDESC,vircam_dark_current_description,
186 VIRCAM_DARKCUR_RAW,VIRCAM_CAL_BPM,VIRCAM_CAL_CONF);
188 cpl_plugin_init(plugin,
190 VIRCAM_BINARY_VERSION,
191 CPL_PLUGIN_TYPE_RECIPE,
192 "vircam_dark_current",
193 "VIRCAM recipe to determine detector dark current",
198 vircam_dark_current_create,
199 vircam_dark_current_exec,
200 vircam_dark_current_destroy);
202 cpl_pluginlist_append(list,plugin);
218 static int vircam_dark_current_create(cpl_plugin *plugin) {
224 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
225 recipe = (cpl_recipe *)plugin;
231 recipe->parameters = cpl_parameterlist_new();
235 p = cpl_parameter_new_value(
"vircam.vircam_dark_current.thresh",
237 "Rejection threshold in sigma above background",
"vircam.vircam_dark_current",5.0);
238 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"thresh");
239 cpl_parameterlist_append(recipe->parameters,p);
243 p = cpl_parameter_new_range(
"vircam.vircam_dark_current.extenum",
245 "Extension number to be done, 0 == all",
246 "vircam.vircam_dark_current",
248 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,
"ext");
249 cpl_parameterlist_append(recipe->parameters,p);
265 static int vircam_dark_current_destroy(cpl_plugin *plugin) {
270 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
271 recipe = (cpl_recipe *)plugin;
275 cpl_parameterlist_delete(recipe->parameters);
288 static int vircam_dark_current_exec(cpl_plugin *plugin) {
293 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
294 recipe = (cpl_recipe *)plugin;
298 return(vircam_dark_current(recipe->parameters,recipe->frames));
310 static int vircam_dark_current(cpl_parameterlist *parlist,
311 cpl_frameset *framelist) {
312 int jst,jfn,i,j,nx,ny,n,retval,live;
315 double intercept,slope,sig;
316 const char *fctid =
"vircam_dark_current";
320 cpl_frame *cur_frame;
321 cpl_propertylist *plist;
326 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
327 cpl_msg_error(fctid,
"Input framelist NULL or has no input data");
333 vircam_dark_current_init();
337 p = cpl_parameterlist_find(parlist,
"vircam.vircam_dark_current.thresh");
338 vircam_dark_current_config.thresh = (float)cpl_parameter_get_double(p);
339 p = cpl_parameterlist_find(parlist,
"vircam.vircam_dark_current.extenum");
340 vircam_dark_current_config.extenum = cpl_parameter_get_int(p);
345 cpl_msg_error(fctid,
"Cannot identify RAW and CALIB frames");
353 cpl_msg_error(fctid,
"Cannot labelise the input frameset");
354 vircam_dark_current_tidy();
358 VIRCAM_DARKCUR_RAW)) == NULL) {
359 cpl_msg_error(fctid,
"Cannot find dark frames in input frameset");
360 vircam_dark_current_tidy();
363 ps.nframes = cpl_frameset_get_size(ps.darklist);
364 if (ps.nframes < 2) {
365 cpl_msg_error(fctid,
"Dark frameset doesn't have enough frames");
366 vircam_dark_current_tidy();
378 ps.data = cpl_malloc(ps.nframes*
sizeof(
float *));
379 ps.subset = cpl_malloc(ps.nframes*
sizeof(
double));
380 ps.exps = cpl_malloc(ps.nframes*
sizeof(
double));
384 for (i = 0; i < ps.nframes; i++) {
385 cur_frame = cpl_frameset_get_position(ps.darklist,i);
386 plist = cpl_propertylist_load(cpl_frame_get_filename(cur_frame),0);
388 cpl_msg_error(fctid,
"Unable to get exposure time for %s",
389 cpl_frame_get_filename(cur_frame));
392 ps.exps[i] = (double)val;
393 cpl_propertylist_delete(plist);
401 (
const cpl_frame *)cpl_frameset_get_position(ps.darklist,0),
403 if (jst == -1 || jfn == -1) {
404 cpl_msg_error(fctid,
"Unable to continue");
405 vircam_dark_current_tidy();
411 ps.good = cpl_malloc(ps.nframes*
sizeof(casu_fits *));
415 for (j = jst; j <= jfn; j++) {
416 isfirst = (j == jst);
418 vircam_dark_current_config.mean_dark_current = 0.0;
424 if (ps.allfits == NULL) {
426 "Extension %" CPL_SIZE_FORMAT
" darks wouldn't load",
429 retval = vircam_dark_current_lastbit(j,framelist,parlist);
438 for (i = 0; i < ps.nframes; i++) {
442 cpl_msg_info(fctid,
"Detector flagged dead %s",
446 ps.good[ps.ngood] = ff;
455 cpl_msg_warning(fctid,
456 "Need at least 2 good images -- %" CPL_SIZE_FORMAT
" found",
457 (cpl_size)(ps.ngood));
459 retval = vircam_dark_current_lastbit(j,framelist,parlist);
460 freefitslist(ps.allfits,ps.nframes);
461 freeimage(ps.outimage);
469 for (i = 0; i < ps.ngood; i++)
477 if (retval == CASU_FATAL) {
479 "Unable to load mask image %s[%" CPL_SIZE_FORMAT
"]",
481 cpl_msg_info(fctid,
"Forcing all pixels to be good from now on");
488 ps.outimage = cpl_image_new((cpl_size)nx,(cpl_size)ny,CPL_TYPE_FLOAT);
489 outdata = cpl_image_get_data(ps.outimage);
494 "Doing dark current fits for extension %" CPL_SIZE_FORMAT,
496 npts = (long)(nx*ny);
497 for (n = 0; n < npts; n++) {
501 for (i = 0; i < ps.ngood; i++)
502 ps.subset[i] = (
double)(ps.data[i][n]);
509 outdata[n] = (float)slope;
514 vircam_dark_current_config.mean_dark_current =
519 (void)vircam_dark_current_lastbit(j,framelist,parlist);
523 freeimage(ps.outimage);
525 freefitslist(ps.allfits,ps.nframes);
530 vircam_dark_current_tidy();
544 static int vircam_dark_current_save(cpl_frameset *framelist,
545 cpl_parameterlist *parlist) {
546 cpl_propertylist *plist,*p;
547 const char *fctid =
"vircam_dark_current_save";
548 const char *outfile =
"darkcurrent.fits";
549 const char *outpaf =
"darkcurrent";
550 const char *recipeid =
"vircam_dark_current";
556 darkcur_med = vircam_dark_current_config.mean_dark_current;
561 product_frame = cpl_frame_new();
562 cpl_frame_set_filename(product_frame,outfile);
563 cpl_frame_set_tag(product_frame,VIRCAM_PRO_DARKCUR);
564 cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
565 cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
566 cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
571 ps.phupaf = vircam_paf_phu_items(plist);
573 parlist,(
char *)recipeid,
575 vircam_paf_append(ps.phupaf,plist,
"ESO PRO CATG");
579 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
580 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
581 cpl_msg_error(fctid,
"Cannot save product PHU");
582 cpl_propertylist_delete(plist);
585 cpl_frameset_insert(framelist,product_frame);
592 parlist,(
char *)recipeid,
597 cpl_propertylist_update_float(plist,
"ESO QC DARKCURRENT",darkcur_med);
598 cpl_propertylist_set_comment(plist,
"ESO QC DARKCURRENT",
599 "[ADU/s] Median dark current");
605 if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,plist,
606 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
607 cpl_msg_error(fctid,
"Cannot save product image extension");
608 cpl_propertylist_delete(plist);
614 p = vircam_paf_req_items(plist);
616 if (vircam_paf_print((
char *)outpaf,
"VIRCAM/vircam_dark_current",
"QC file",
618 cpl_msg_warning(fctid,
"Unable to write PAF");
619 cpl_propertylist_delete(p);
636 static int vircam_dark_current_lastbit(
int jext, cpl_frameset *framelist,
637 cpl_parameterlist *parlist) {
639 const char *fctid=
"vircam_dark_current_lastbit";
648 cpl_msg_info(fctid,
"Saving products for extension %" CPL_SIZE_FORMAT,
650 retval = vircam_dark_current_save(framelist,parlist);
652 vircam_dark_current_tidy();
665 static void vircam_dark_current_init(
void) {
668 ps.master_mask = NULL;
685 static void vircam_dark_current_tidy(
void) {
687 freespace(ps.labels);
688 freeframeset(ps.darklist);
689 freemask(ps.master_mask);
691 freespace(ps.subset);
693 freeimage(ps.outimage);
694 freefitslist(ps.allfits,ps.nframes);
697 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)
char * casu_fits_get_fullname(casu_fits *p)
int casu_fits_set_error(casu_fits *p, int status)
cpl_propertylist * casu_fits_get_phu(casu_fits *p)
cpl_propertylist * casu_fits_get_ehu(casu_fits *p)
void casu_mask_force(casu_mask *m, int nx, int ny)
unsigned char * casu_mask_get_data(casu_mask *m)
const char * casu_mask_get_filename(casu_mask *m)
int casu_mask_load(casu_mask *m, int nexten, int nx, int ny)
casu_mask * casu_mask_define(cpl_frameset *framelist, cpl_size *labels, cpl_size nlab, const char *conftag, const char *bpmtag)
void casu_mask_clear(casu_mask *m)
float casu_med(float *data, unsigned char *bpm, long npts)
cpl_image * casu_dummy_image(casu_fits *model)
Create a dummy image of zeros based on a model.
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_frameset * casu_frameset_subgroup(cpl_frameset *frameset, cpl_size *labels, cpl_size nlab, const char *tag)
Extract a frameset from another frameset.
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.
int vircam_pfits_get_exptime(const cpl_propertylist *plist, float *exptime)
Get the value of exposure time.
void vircam_linfit(int npts, double *xdata, double *ydata, double *intercept, double *slope, double *sig)
const char * vircam_get_license(void)
void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1, int *out2)