VIRCAM Pipeline 2.3.15
vircam_detector_noise.c
1/* $Id: vircam_detector_noise.c,v 1.57 2012-01-16 12:32:18 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 12:32:18 $
24 * $Revision: 1.57 $
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#include <string.h>
38
39#include <casu_utils.h>
40#include <casu_mods.h>
41#include <casu_mask.h>
42#include <casu_stats.h>
43
44#include "vircam_utils.h"
45#include "vircam_dfs.h"
46#include "vircam_pfits.h"
47#include "vircam_paf.h"
48
49/* Function prototypes */
50
51static int vircam_detector_noise_create(cpl_plugin *) ;
52static int vircam_detector_noise_exec(cpl_plugin *) ;
53static int vircam_detector_noise_destroy(cpl_plugin *) ;
54static int vircam_detector_noise(cpl_parameterlist *, cpl_frameset *) ;
55static int vircam_detector_noise_save(cpl_frameset *framelist,
56 cpl_parameterlist *parlist);
57static void vircam_detector_noise_init(void);
58static void vircam_detector_noise_tidy(void);
59
60/* Static global variables */
61
62static struct {
63
64 /* Input */
65
66 float thresh;
67 int extenum;
68
69 /* Output */
70
71 float gain;
72 float readnoise;
73 float counts;
74 float lampflux;
75} vircam_detector_noise_config ;
76
77static struct {
78 cpl_size *labels;
79 cpl_frameset *darklist;
80 cpl_frameset *domelist;
81 cpl_frame *inherit;
82 cpl_image *darkim1;
83 cpl_image *darkim2;
84 cpl_image *domeim1;
85 cpl_image *domeim2;
86 casu_mask *master_mask;
87 cpl_propertylist *ph;
88 cpl_propertylist *eh;
89 cpl_propertylist *phupaf;
90} ps;
91
92static cpl_frame *product_frame = NULL;
93static int isfirst;
94static int dummy;
95
96#define BUZZ_OFF {vircam_detector_noise_tidy(); return(-1);}
97
98static char vircam_detector_noise_description[] =
99"vircam_detector_noise -- VIRCAM readnoise and gain recipe.\n\n"
100"Measures the read noise and gain of a chip using two dome flat exposures\n"
101"and two dark exposures. The flats should have the same illumination.\n"
102"All four frames should have the same exposure time. If the SOF\n"
103"contains more than two files of a given type, the others are ignored.\n\n"
104"The program requires the following files in the SOF:\n\n"
105" Tag Description\n"
106" -----------------------------------------------------------------------\n"
107" %-21s A list of two raw dark images\n"
108" %-21s A list of two raw dome flat image\n"
109" %-21s Optional master bad pixel map or\n"
110" %-21s Optional master confidence map\n"
111"\n";
112
178/* Function code */
179
180/*---------------------------------------------------------------------------*/
188/*---------------------------------------------------------------------------*/
189
190int cpl_plugin_get_info(cpl_pluginlist *list) {
191 cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
192 cpl_plugin *plugin = &recipe->interface;
193 char alldesc[SZ_ALLDESC];
194 (void)snprintf(alldesc,SZ_ALLDESC,vircam_detector_noise_description,
195 VIRCAM_NOISE_DARK_RAW,VIRCAM_NOISE_FLAT_RAW,VIRCAM_CAL_BPM,
196 VIRCAM_CAL_CONF);
197
198 cpl_plugin_init(plugin,
199 CPL_PLUGIN_API,
200 VIRCAM_BINARY_VERSION,
201 CPL_PLUGIN_TYPE_RECIPE,
202 "vircam_detector_noise",
203 "VIRCAM recipe to determine readout noise and gain",
204 alldesc,
205 "Jim Lewis",
206 "jrl@ast.cam.ac.uk",
208 vircam_detector_noise_create,
209 vircam_detector_noise_exec,
210 vircam_detector_noise_destroy);
211
212 cpl_pluginlist_append(list,plugin);
213
214 return(0);
215}
216
217
218/*---------------------------------------------------------------------------*/
227/*---------------------------------------------------------------------------*/
228
229static int vircam_detector_noise_create(cpl_plugin *plugin) {
230 cpl_recipe *recipe;
231 cpl_parameter *p;
232
233 /* Get the recipe out of the plugin */
234
235 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
236 recipe = (cpl_recipe *)plugin;
237 else
238 return(-1);
239
240 /* Create the parameters list in the cpl_recipe object */
241
242 recipe->parameters = cpl_parameterlist_new();
243
244 /* Fill in the rejection threshold parameter */
245
246 p = cpl_parameter_new_value("vircam.vircam_detector_noise.thresh",
247 CPL_TYPE_DOUBLE,
248 "Rejection threshold in sigma above background", "vircam.vircam_detector_noise",5.0);
249 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
250 cpl_parameterlist_append(recipe->parameters,p);
251
252 /* Extension number of input frames to use */
253
254 p = cpl_parameter_new_range("vircam.vircam_detector_noise.extenum",
255 CPL_TYPE_INT,
256 "Extension number to be done, 0 == all",
257 "vircam.vircam_detector_noise",
258 0,0,16);
259 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
260 cpl_parameterlist_append(recipe->parameters,p);
261
262 /* Get out of here */
263
264 return(0);
265}
266
267/*---------------------------------------------------------------------------*/
273/*---------------------------------------------------------------------------*/
274
275static int vircam_detector_noise_destroy(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 cpl_parameterlist_delete(recipe->parameters);
286 return(0);
287}
288
289/*---------------------------------------------------------------------------*/
295/*---------------------------------------------------------------------------*/
296
297static int vircam_detector_noise_exec(cpl_plugin *plugin) {
298 cpl_recipe *recipe;
299
300 /* Get the recipe out of the plugin */
301
302 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
303 recipe = (cpl_recipe *)plugin;
304 else
305 return(-1);
306
307 return(vircam_detector_noise(recipe->parameters,recipe->frames));
308}
309
310/*---------------------------------------------------------------------------*/
317/*---------------------------------------------------------------------------*/
318
319static int vircam_detector_noise(cpl_parameterlist *parlist,
320 cpl_frameset *framelist) {
321 const char *fctid="vircam_detector_noise";
322 cpl_parameter *p;
323 int j,jst,jfn,retval,nx,ny,live;
324 cpl_size nlab;
325 long nptsdark;
326 float meandark1,meandome1,meandark2,meandome2,sigdark,lcut,hcut;
327 float meandarkdiff,sigdarkdiff,counts;
328 float meandomediff,sigdomediff,gain,readnoise,exptime;
329 cpl_frame *dark1,*dark2,*dome1,*dome2;
330 cpl_propertylist *plist;
331 unsigned char *bpm;
332
333 /* Check validity of input frameset */
334
335 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
336 cpl_msg_error(fctid,"Input framelist NULL or has no input data");
337 return(-1);
338 }
339
340 /* Initialise a few things */
341
342 vircam_detector_noise_init();
343
344 /* Get the parameters */
345
346 p = cpl_parameterlist_find(parlist,"vircam.vircam_detector_noise.thresh");
347 vircam_detector_noise_config.thresh = (float)cpl_parameter_get_double(p);
348 p = cpl_parameterlist_find(parlist,"vircam.vircam_detector_noise.extenum");
349 vircam_detector_noise_config.extenum = cpl_parameter_get_int(p);
350
351 /* Sort out raw from calib frames */
352
353 if (vircam_dfs_set_groups(framelist) != CASU_OK) {
354 cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
355 vircam_detector_noise_tidy();
356 return(-1);
357 }
358
359 /* Get dark and dome flat frames. Make sure there are at least 2 of each */
360
361 if ((ps.labels = cpl_frameset_labelise(framelist,casu_compare_tags,
362 &nlab)) == NULL) {
363 cpl_msg_error(fctid,"Cannot labelise the input frameset");
364 BUZZ_OFF
365 }
366 if ((ps.darklist = casu_frameset_subgroup(framelist,ps.labels,nlab,
367 VIRCAM_NOISE_DARK_RAW)) == NULL) {
368 cpl_msg_error(fctid,"Cannot find dark frames in input frameset");
369 BUZZ_OFF
370 }
371 if (cpl_frameset_get_size(ps.darklist) < 2) {
372 cpl_msg_error(fctid,"Dark frameset doesn't have enough frames");
373 BUZZ_OFF
374 }
375 if ((ps.domelist = casu_frameset_subgroup(framelist,ps.labels,nlab,
376 VIRCAM_NOISE_FLAT_RAW)) == NULL) {
377 cpl_msg_error(fctid,"Cannot find dome flat frames in input frameset");
378 BUZZ_OFF
379 }
380 if (cpl_frameset_get_size(ps.domelist) < 2) {
381 cpl_msg_error(fctid,"Dome flat frameset doesn't have enough frames");
382 BUZZ_OFF
383 }
384
385 /* Check to see if there is a master bad pixel map. If there isn't one
386 then look for a confidence map */
387
388 ps.master_mask = casu_mask_define(framelist,ps.labels,nlab,VIRCAM_CAL_CONF,
389 VIRCAM_CAL_BPM);
390
391 /* Set up some convenience variables */
392
393 dark1 = cpl_frameset_get_position(ps.darklist,0);
394 dark2 = cpl_frameset_get_position(ps.darklist,1);
395 dome1 = cpl_frameset_get_position(ps.domelist,0);
396 dome2 = cpl_frameset_get_position(ps.domelist,1);
397 ps.inherit = dome1;
398
399 /* Get a propertylist for the primary */
400
401 ps.ph = cpl_propertylist_load(cpl_frame_get_filename(dome1),0);
402 (void)vircam_pfits_get_exptime((const cpl_propertylist *)ps.ph,&exptime);
403
404 /* Loop for each of the image extensions */
405
406 vircam_exten_range(vircam_detector_noise_config.extenum,
407 (const cpl_frame *)dark1,&jst,&jfn);
408 if (jst == -1 || jfn == -1) {
409 cpl_msg_error(fctid,"Unable to continue");
410 vircam_detector_noise_tidy();
411 return(-1);
412 }
413 for (j = jst; j <= jfn; j++) {
414 cpl_msg_info(fctid,"Beginning work on extension %" CPL_SIZE_FORMAT,
415 (cpl_size)j);
416 isfirst = (j == jst);
417 vircam_detector_noise_config.readnoise = 0.0;
418 vircam_detector_noise_config.gain = 0.0;
419 vircam_detector_noise_config.counts = 0.0;
420 vircam_detector_noise_config.lampflux = 0.0;
421 dummy = 1;
422
423 /* Get the full set of images */
424
425 ps.darkim1 = cpl_image_load(cpl_frame_get_filename(dark1),
426 CPL_TYPE_FLOAT,0,(cpl_size)j);
427 ps.darkim2 = cpl_image_load(cpl_frame_get_filename(dark2),
428 CPL_TYPE_FLOAT,0,(cpl_size)j);
429 ps.domeim1 = cpl_image_load(cpl_frame_get_filename(dome1),
430 CPL_TYPE_FLOAT,0,(cpl_size)j);
431 ps.domeim2 = cpl_image_load(cpl_frame_get_filename(dome2),
432 CPL_TYPE_FLOAT,0,(cpl_size)j);
433 if (ps.darkim1 == NULL || ps.darkim2 == NULL || ps.domeim1 == NULL ||
434 ps.domeim2 == NULL) {
435 cpl_error_reset();
436 cpl_msg_error(fctid,
437 "NULL image input for extension %" CPL_SIZE_FORMAT,
438 (cpl_size)j);
439 retval = vircam_detector_noise_save(framelist,parlist);
440 freeimage(ps.darkim1);
441 freeimage(ps.darkim2);
442 freeimage(ps.domeim1);
443 freeimage(ps.domeim2);
444 continue;
445 }
446
447 /* Get some an extension propertylist */
448
449 ps.eh = cpl_propertylist_load(cpl_frame_get_filename(dome1),
450 (cpl_size)j);
451
452 /* Check that the current detectors are live */
453
454 plist = cpl_propertylist_load(cpl_frame_get_filename(dark1),
455 (cpl_size)j);
456 vircam_pfits_get_detlive(plist,&live);
457 if (! live) {
458 cpl_msg_warning(fctid,"First dark image detector not live");
459 retval = vircam_detector_noise_save(framelist,parlist);
460 cpl_propertylist_delete(plist);
461 freeimage(ps.darkim1);
462 freeimage(ps.darkim2);
463 freeimage(ps.domeim1);
464 freeimage(ps.domeim2);
465 freepropertylist(ps.eh);
466 continue;
467 }
468 cpl_propertylist_delete(plist);
469 plist = cpl_propertylist_load(cpl_frame_get_filename(dark2),
470 (cpl_size)j);
471 vircam_pfits_get_detlive(plist,&live);
472 if (! live) {
473 cpl_msg_warning(fctid,"Second dark image detector not live");
474 retval = vircam_detector_noise_save(framelist,parlist);
475 cpl_propertylist_delete(plist);
476 freeimage(ps.darkim1);
477 freeimage(ps.darkim2);
478 freeimage(ps.domeim1);
479 freeimage(ps.domeim2);
480 freepropertylist(ps.eh);
481 continue;
482 }
483 cpl_propertylist_delete(plist);
484 plist = cpl_propertylist_load(cpl_frame_get_filename(dome1),
485 (cpl_size)j);
486 vircam_pfits_get_detlive(plist,&live);
487 if (! live) {
488 cpl_msg_warning(fctid,"First dome image detector not live");
489 retval = vircam_detector_noise_save(framelist,parlist);
490 cpl_propertylist_delete(plist);
491 freeimage(ps.darkim1);
492 freeimage(ps.darkim2);
493 freeimage(ps.domeim1);
494 freeimage(ps.domeim2);
495 freepropertylist(ps.eh);
496 continue;
497 }
498 cpl_propertylist_delete(plist);
499 plist = cpl_propertylist_load(cpl_frame_get_filename(dome2),
500 (cpl_size)j);
501 vircam_pfits_get_detlive(plist,&live);
502 if (! live) {
503 cpl_msg_warning(fctid,"Second dome image detector not live");
504 retval = vircam_detector_noise_save(framelist,parlist);
505 cpl_propertylist_delete(plist);
506 freeimage(ps.darkim1);
507 freeimage(ps.darkim2);
508 freeimage(ps.domeim1);
509 freeimage(ps.domeim2);
510 freepropertylist(ps.eh);
511 continue;
512 }
513 cpl_propertylist_delete(plist);
514
515 /* Get the data array sizes */
516
517 nx = (int)cpl_image_get_size_x(ps.darkim1);
518 ny = (int)cpl_image_get_size_y(ps.darkim1);
519 nptsdark = (long)(nx*ny);
520
521 /* Load the mask */
522
523 if (casu_mask_load(ps.master_mask,j,nx,ny) == CASU_FATAL) {
524 cpl_msg_info(fctid,
525 "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
526 casu_mask_get_filename(ps.master_mask),(cpl_size)j);
527 cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
528 casu_mask_force(ps.master_mask,nx,ny);
529 }
530 bpm = casu_mask_get_data(ps.master_mask);
531
532 /* Get the mean of the first dark and the first dome */
533
534 casu_medmad((float *)cpl_image_get_data(ps.darkim1),bpm,
535 nptsdark,&meandark1,&sigdark);
536 sigdark *= 1.48;
537 lcut = meandark1 - vircam_detector_noise_config.thresh*sigdark;
538 hcut = meandark1 + vircam_detector_noise_config.thresh*sigdark;
539 casu_medmadcut((float *)cpl_image_get_data(ps.darkim1),bpm,
540 nptsdark,lcut,hcut,&meandark1,&sigdark);
541 casu_medmad((float *)cpl_image_get_data(ps.domeim1),bpm,
542 nptsdark,&meandome1,&sigdark);
543 sigdark *= 1.48;
544 lcut = meandome1 - vircam_detector_noise_config.thresh*sigdark;
545 hcut = meandome1 + vircam_detector_noise_config.thresh*sigdark;
546 casu_medmadcut((float *)cpl_image_get_data(ps.domeim1),bpm,
547 nptsdark,lcut,hcut,&meandome1,&sigdark);
548
549 /* Get the mean of the second dark and the second dome */
550
551 casu_medmad((float *)cpl_image_get_data(ps.darkim2),bpm,
552 nptsdark,&meandark2,&sigdark);
553 sigdark *= 1.48;
554 lcut = meandark2 - vircam_detector_noise_config.thresh*sigdark;
555 hcut = meandark2 + vircam_detector_noise_config.thresh*sigdark;
556 casu_medmadcut((float *)cpl_image_get_data(ps.darkim2),bpm,
557 nptsdark,lcut,hcut,&meandark2,&sigdark);
558 casu_medmad((float *)cpl_image_get_data(ps.domeim2),bpm,
559 nptsdark,&meandome2,&sigdark);
560 sigdark *= 1.48;
561 lcut = meandome2 - vircam_detector_noise_config.thresh*sigdark;
562 hcut = meandome2 + vircam_detector_noise_config.thresh*sigdark;
563 casu_medmadcut((float *)cpl_image_get_data(ps.domeim2),bpm,
564 nptsdark,lcut,hcut,&meandome2,&sigdark);
565
566 /* Form a difference image with each the of the dark and dome pairs */
567
568 cpl_image_subtract(ps.darkim1,ps.darkim2);
569 cpl_image_subtract(ps.domeim1,ps.domeim2);
570
571 /* Now measure the mean and sigma of each of the difference images */
572
573 casu_medmad((float *)cpl_image_get_data(ps.darkim1),bpm,
574 nptsdark,&meandarkdiff,&sigdarkdiff);
575 sigdarkdiff *= 1.48;
576 lcut = meandarkdiff - vircam_detector_noise_config.thresh*sigdarkdiff;
577 hcut = meandarkdiff + vircam_detector_noise_config.thresh*sigdarkdiff;
578 casu_medmadcut((float *)cpl_image_get_data(ps.darkim1),bpm,
579 nptsdark,lcut,hcut,&meandarkdiff,&sigdarkdiff);
580 sigdarkdiff *= 1.48;
581 casu_medmad((float *)cpl_image_get_data(ps.domeim1),bpm,
582 nptsdark,&meandomediff,&sigdomediff);
583 sigdomediff *= 1.48;
584 lcut = meandomediff - vircam_detector_noise_config.thresh*sigdomediff;
585 hcut = meandomediff + vircam_detector_noise_config.thresh*sigdomediff;
586 casu_medmadcut((float *)cpl_image_get_data(ps.domeim1),bpm,
587 nptsdark,lcut,hcut,&meandomediff,&sigdomediff);
588 sigdomediff *= 1.48;
589
590 /* Work out gain */
591
592 counts = (meandome1 + meandome2) - (meandark1 + meandark2);
593 vircam_detector_noise_config.counts = 0.5*counts;
594 vircam_detector_noise_config.lampflux = 0.5*counts/exptime;
595 gain = counts/(sigdomediff*sigdomediff - sigdarkdiff*sigdarkdiff);
596 vircam_detector_noise_config.gain = gain;
597
598 /* Now the read noise */
599
600 readnoise = gain*sigdarkdiff/sqrt(2.0);
601 vircam_detector_noise_config.readnoise = readnoise;
602 dummy = 0;
603
604 /* Save the products */
605
606 retval = vircam_detector_noise_save(framelist,parlist);
607 if (retval != 0) {
608 cpl_msg_error(fctid,"Error saving results");
609 BUZZ_OFF
610 }
611
612 /* Tidy up */
613
614 freeimage(ps.darkim1);
615 freeimage(ps.darkim2);
616 freeimage(ps.domeim1);
617 freeimage(ps.domeim2);
618 casu_mask_clear(ps.master_mask);
619 freepropertylist(ps.eh);
620 }
621 vircam_detector_noise_tidy();
622 return(0);
623}
624
625/*---------------------------------------------------------------------------*/
632/*---------------------------------------------------------------------------*/
633
634static int vircam_detector_noise_save(cpl_frameset *framelist,
635 cpl_parameterlist *parlist) {
636 const char *fctid = "vircam_detector_noise_save";
637 const char *outpaf = "vircam_detector_noise";
638 const char *outfile = "detector_noise.fits";
639 const char *recipeid = "vircam_detector_noise";
640 cpl_propertylist *plist,*p;
641 cpl_table *o;
642
643 /* If this is the first time through then create the output image */
644
645 if (isfirst) {
646
647 /* Create a new product frame object and define some tags */
648
649 product_frame = cpl_frame_new();
650 cpl_frame_set_filename(product_frame,outfile);
651 cpl_frame_set_tag(product_frame,VIRCAM_PRO_READGAINFILE);
652 cpl_frame_set_type(product_frame,CPL_FRAME_TYPE_IMAGE);
653 cpl_frame_set_group(product_frame,CPL_FRAME_GROUP_PRODUCT);
654 cpl_frame_set_level(product_frame,CPL_FRAME_LEVEL_FINAL);
655
656 /* Fiddle with the primary header */
657
658 plist = cpl_propertylist_duplicate(ps.ph);
659 ps.phupaf = vircam_paf_phu_items(plist);
660 vircam_dfs_set_product_primary_header(plist,product_frame,framelist,
661 parlist,(char *)recipeid,
662 "PRO-1.15",ps.inherit,0);
663 vircam_paf_append(ps.phupaf,plist,"ESO PRO CATG");
664 vircam_paf_append(ps.phupaf,plist,"ESO INS FILT1 NAME");
665
666 /* 'Save' the PHU image */
667
668 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
669 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
670 cpl_msg_error(fctid,"Cannot save product PHU");
671 cpl_frame_delete(product_frame);
672 cpl_propertylist_delete(plist);
673 return(-1);
674 }
675 cpl_propertylist_delete(plist);
676 cpl_frameset_insert(framelist,product_frame);
677 }
678
679 /* Create results header */
680
681 plist = cpl_propertylist_duplicate(ps.eh);
682
683 /* Now add the new data... */
684
685 cpl_propertylist_update_float(plist,"ESO QC READNOISE",
686 vircam_detector_noise_config.readnoise);
687 cpl_propertylist_set_comment(plist,"ESO QC READNOISE",
688 "[e-] Calculated detector readnoise");
689 cpl_propertylist_update_float(plist,"ESO QC CONAD",
690 vircam_detector_noise_config.gain);
691 cpl_propertylist_set_comment(plist,"ESO QC CONAD",
692 "[e-/ADU] Calculated detector gain");
693 cpl_propertylist_update_float(plist,"ESO QC COUNTS",
694 vircam_detector_noise_config.counts);
695 cpl_propertylist_set_comment(plist,"ESO QC COUNTS",
696 "[ADU] Dark corrected dome counts");
697 cpl_propertylist_update_float(plist,"ESO QC LAMPFLUX",
698 vircam_detector_noise_config.lampflux);
699 cpl_propertylist_set_comment(plist,"ESO QC LAMPFLUX",
700 "[ADU/sec] Dark corrected flux level");
701
702 /* Now fiddle with the extension header */
703
704 vircam_dfs_set_product_exten_header(plist,product_frame,framelist,
705 parlist,(char *)recipeid,
706 "PRO-1.15",ps.inherit);
707 if (dummy)
708 casu_dummy_property(plist);
709
710 /* Create the output table */
711
712 o = cpl_table_new(1);
713 cpl_table_new_column(o,"EXTNAME",CPL_TYPE_STRING);
714 cpl_table_new_column(o,"READNOISE",CPL_TYPE_FLOAT);
715 cpl_table_new_column(o,"GAIN",CPL_TYPE_FLOAT);
716
717 /* Write the values to the table */
718
719 cpl_table_set_string(o,"EXTNAME",0,
720 cpl_propertylist_get_string(plist,"EXTNAME"));
721 cpl_table_set_float(o,"READNOISE",0,
722 vircam_detector_noise_config.readnoise);
723 cpl_table_set_float(o,"GAIN",0,vircam_detector_noise_config.gain);
724
725 /* 'Save' the image */
726
727 if (cpl_table_save(o,NULL,plist,outfile,CPL_IO_EXTEND) != CPL_ERROR_NONE) {
728 cpl_msg_error(fctid,"Cannot save product");
729 cpl_propertylist_delete(plist);
730 cpl_frame_delete(product_frame);
731 freetable(o);
732 return(-1);
733 }
734 freetable(o);
735
736 /* Write the PAF */
737
738 p = vircam_paf_req_items(plist);
739 casu_merge_propertylists(p,ps.phupaf);
740 if (vircam_paf_print((char *)outpaf,"VIRCAM/vircam_detector_noise",
741 "QC file",p) != CASU_OK)
742 cpl_msg_warning(fctid,"Unable to write PAF");
743 cpl_propertylist_delete(p);
744
745 /* Tidy and exit */
746
747 freepropertylist(plist);
748 return(0);
749}
750
751/*---------------------------------------------------------------------------*/
755/*---------------------------------------------------------------------------*/
756
757static void vircam_detector_noise_init(void) {
758 ps.labels = NULL;
759 ps.darklist = NULL;
760 ps.domelist = NULL;
761 ps.darkim1 = NULL;
762 ps.darkim2 = NULL;
763 ps.domeim1 = NULL;
764 ps.domeim2 = NULL;
765 ps.master_mask = NULL;
766 ps.inherit = NULL;
767 ps.ph = NULL;
768 ps.eh = NULL;
769 ps.phupaf = NULL;
770 return;
771}
772
773/*---------------------------------------------------------------------------*/
777/*---------------------------------------------------------------------------*/
778
779static void vircam_detector_noise_tidy(void) {
780 freespace(ps.labels);
781 freeframeset(ps.darklist);
782 freeframeset(ps.domelist);
783 freeimage(ps.darkim1);
784 freeimage(ps.darkim2);
785 freeimage(ps.domeim1);
786 freeimage(ps.domeim2);
787 freemask(ps.master_mask);
788 freepropertylist(ps.ph);
789 freepropertylist(ps.eh);
790 freepropertylist(ps.phupaf);
791 return;
792}
793
797/*
798
799$Log: not supported by cvs2svn $
800Revision 1.56 2012/01/15 17:40:09 jim
801Minor modifications to take into accout the changes in cpl API for v6
802
803Revision 1.55 2010/12/09 13:19:19 jim
804Fixed bug where reported flux was a factor of two too high
805
806Revision 1.54 2010/06/30 12:42:00 jim
807A few fixes to stop compiler compaints
808
809Revision 1.53 2010/03/09 14:28:38 jim
810Added new QC values COUNTS and LAMPFLUX
811
812Revision 1.52 2010/01/31 18:55:30 jim
813Filter name written to PAF. QC GAIN changed to QC CONAD (in spite of the
814dreadful name)
815
816Revision 1.51 2009/09/09 09:50:21 jim
817Modified to try and get headers right
818
819Revision 1.50 2008/10/01 04:59:13 jim
820Added call to vircam_frameset_fexists to check input frameset
821
822Revision 1.49 2008/09/30 11:33:23 jim
823Added PRO CATG to pafs
824
825Revision 1.48 2007/10/25 18:39:22 jim
826Altered to remove some lint messages
827
828Revision 1.47 2007/10/15 12:52:39 jim
829Fixed little cockup which had duplicate entries in the ps structure
830
831Revision 1.46 2007/09/07 13:32:12 jim
832uses a sorted framelist to ensure that the correct information is given
833to the output product header
834
835Revision 1.45 2007/09/06 21:37:53 jim
836fixed call to vircam_dfs_setup_product_ routines to use the full input
837frameset
838
839Revision 1.44 2007/07/18 15:35:41 jim
840Added better error handling for missing or corrupt mask extensions
841
842Revision 1.43 2007/07/09 13:21:55 jim
843Modified to use new version of vircam_exten_range
844
845Revision 1.42 2007/06/13 08:11:27 jim
846Modified docs to reflect changes in DFS tags
847
848Revision 1.41 2007/04/04 10:36:18 jim
849Modified to use new dfs tags
850
851Revision 1.40 2007/03/29 12:19:38 jim
852Little changes to improve documentation
853
854Revision 1.39 2007/03/06 12:30:17 jim
855Now writes results to a table in addtion to a header and a paf.
856
857Revision 1.38 2007/03/01 12:41:49 jim
858Modified slightly after code checking
859
860Revision 1.37 2007/02/25 06:26:35 jim
861Plugged a few memory leaks
862
863Revision 1.36 2007/02/15 06:59:37 jim
864Added ability to write QC paf files
865
866Revision 1.35 2007/02/07 10:12:39 jim
867Removed calls to vircam_ndit_correct as this is now no longer necessary
868
869Revision 1.34 2007/02/06 13:11:12 jim
870Fixed entry for PRO dictionary in cpl_dfs_set_product_header
871
872Revision 1.33 2007/02/06 12:38:59 jim
873Creates a sorted version of the input frameset so that a dome flat is first
874in the list. This is done so that the header of the output product comes
875from one of the dome flats and so that you can see which filter it was done
876with.
877
878Revision 1.32 2007/02/06 11:59:38 jim
879Added call to vircam_medmadcut for a better estimate of dispersion
880
881Revision 1.31 2007/01/17 23:56:12 jim
882Plugged possible memory leak
883
884Revision 1.30 2006/12/14 14:46:32 jim
885Fixed typo
886
887Revision 1.29 2006/12/11 22:47:49 jim
888Fixed QC header names
889
890Revision 1.28 2006/11/27 12:16:33 jim
891Modified to change location in the header where the results are written
892
893Revision 1.27 2006/11/10 09:20:29 jim
894Fixed _save routine so that an extension name is written out to the file
895header
896
897Revision 1.26 2006/09/29 11:19:31 jim
898changed aliases on parameter names
899
900Revision 1.25 2006/09/09 16:49:39 jim
901Header comment update
902
903Revision 1.24 2006/09/08 09:17:27 jim
904Modified to flag dummy results
905
906Revision 1.23 2006/09/04 23:02:14 jim
907Modified to deal with det live issues. Also does a better job of dealing
908with duff input
909
910Revision 1.22 2006/06/20 19:07:01 jim
911Corrects for ndit != 1
912
913Revision 1.21 2006/06/15 09:58:58 jim
914Minor changes to docs
915
916Revision 1.20 2006/06/13 21:27:10 jim
917Changed output product to a MEF with null images and readnoise/gain estimates
918in the header. I HATE this solution
919
920Revision 1.19 2006/06/09 11:26:25 jim
921Small changes to keep lint happy
922
923Revision 1.18 2006/05/04 11:56:02 jim
924changed filename extension in default output file
925
926Revision 1.17 2006/05/04 11:53:14 jim
927Fixed the way the _save routine works to be more consistent with the
928standard CPL way of doing things
929
930Revision 1.16 2006/04/27 09:46:01 jim
931Modified DFS frame types to conform to new dictionary
932
933Revision 1.15 2006/03/22 14:02:51 jim
934cosmetic changes to keep lint happy
935
936Revision 1.14 2006/03/22 12:13:51 jim
937Modified to use new vircam_mask capability
938
939Revision 1.13 2006/03/15 10:43:40 jim
940Fixed a few things
941
942Revision 1.12 2006/01/23 10:36:39 jim
943Now allows a CPM or a BPM to be used as the mask
944
945Revision 1.11 2005/12/14 22:19:12 jim
946fixed docs
947
948Revision 1.10 2005/12/09 09:47:58 jim
949Many changes to add more documentation
950
951Revision 1.9 2005/12/02 10:45:37 jim
952The tags used in the sof are now written to the description string in the
953constructor. This is so that if they change in the vircam_dfs.h file, they
954aren't then hardcopied into each of the recipes...
955
956Revision 1.8 2005/11/29 16:10:58 jim
957Added clipping into stats for difference images
958
959Revision 1.7 2005/11/25 15:20:29 jim
960Fixed bug in mathematical description
961
962Revision 1.6 2005/11/25 09:56:14 jim
963Tidied up some more documentation
964
965Revision 1.5 2005/11/23 14:57:40 jim
966A bit of tidying in response to splint messages
967
968Revision 1.4 2005/11/21 16:16:23 jim
969Added some better garbage collection
970
971Revision 1.3 2005/11/07 13:14:18 jim
972Added some error trapping and some docs
973
974Revision 1.2 2005/08/09 11:09:39 jim
975Replaced dodgy call to cpl_framelist_delete with correct cpl_frameset_delete
976
977Revision 1.1.1.1 2005/08/05 08:29:09 jim
978Initial import
979
980
981*/
void casu_mask_force(casu_mask *m, int nx, int ny)
Definition: casu_mask.c:394
unsigned char * casu_mask_get_data(casu_mask *m)
Definition: casu_mask.c:544
int casu_mask_load(casu_mask *m, int nexten, int nx, int ny)
Definition: casu_mask.c:214
void casu_mask_clear(casu_mask *m)
Definition: casu_mask.c:357
casu_mask * casu_mask_define(cpl_frameset *framelist, cpl_size *labels, cpl_size nlab, const char *conftag, const char *bpmtag)
Definition: casu_mask.c:89
const char * casu_mask_get_filename(casu_mask *m)
Definition: casu_mask.c:447
void casu_medmad(float *data, unsigned char *bpm, long np, float *med, float *mad)
Definition: casu_stats.c:347
void casu_medmadcut(float *data, unsigned char *bpm, long np, float lcut, float hcut, float *med, float *mad)
Definition: casu_stats.c:406
int casu_compare_tags(const cpl_frame *frame1, const cpl_frame *frame2)
Compare input tags.
Definition: casu_utils.c:96
void casu_merge_propertylists(cpl_propertylist *p1, cpl_propertylist *p2)
Merge two propertylists.
Definition: casu_utils.c:399
void casu_dummy_property(cpl_propertylist *p)
Set dummy property keyword.
Definition: casu_utils.c:445
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
int vircam_pfits_get_detlive(const cpl_propertylist *plist, int *detlive)
Get the value of DET_LIVE.
Definition: vircam_pfits.c:624
int vircam_pfits_get_exptime(const cpl_propertylist *plist, float *exptime)
Get the value of exposure time.
Definition: vircam_pfits.c:245
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