VIRCAM Pipeline 2.3.15
vircam_twilight_flat_combine.c
1/* $Id: vircam_twilight_flat_combine.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
38#include <casu_utils.h>
39#include <casu_mods.h>
40#include <casu_mask.h>
41#include <casu_wcsutils.h>
42#include <casu_stats.h>
43
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"
50
51/* Define values for bit mask that flags dummy results */
52
53#define MEANTWI 1
54#define CONFMAP 2
55#define RATIMG 4
56#define STATS_TAB 8
57
58/* Function prototypes */
59
60static int vircam_twilight_flat_combine_create(cpl_plugin *) ;
61static int vircam_twilight_flat_combine_exec(cpl_plugin *) ;
62static int vircam_twilight_flat_combine_destroy(cpl_plugin *) ;
63static int vircam_twilight_flat_combine(cpl_parameterlist *, cpl_frameset *) ;
64static int vircam_twilight_flat_combine_save(cpl_frameset *framelist,
65 cpl_parameterlist *parlist);
66static void vircam_twilight_flat_combine_dummy_products(void);
67static void vircam_twilight_flat_combine_normal(int jext);
68static int vircam_twilight_flat_combine_lastbit(int jext,
69 cpl_frameset *framelist,
70 cpl_parameterlist *parlist);
71static void vircam_twilight_flat_combine_init(void);
72static void vircam_twilight_flat_combine_tidy(int level);
73
74/* Static global variables */
75
76static struct {
77
78 /* Input */
79
80 float lthr;
81 float hthr;
82 int combtype;
83 int scaletype;
84 int xrej;
85 float thresh;
86 int ncells;
87 int extenum;
88
89 /* Output */
90
91 float flatrms;
92 float flatratio_med;
93 float flatratio_rms;
94 float minv;
95 float maxv;
96 float avev;
97 float photnoise;
98 float snratio;
99
100} vircam_twilight_flat_combine_config;
101
102
103static struct {
104 cpl_size *labels;
105 cpl_frameset *twilightlist;
106 cpl_frameset *twilightlist_cull;
107 cpl_frame *master_dark;
108 cpl_frame *master_twilight_flat;
109 casu_mask *master_mask;
110 cpl_frame *chantab;
111 cpl_array *mins;
112 cpl_array *maxs;
113 cpl_array *aves;
114
115 cpl_image *outimage;
116 cpl_image *outconf;
117 casu_fits **twilights;
118 int ntwilights;
119 cpl_propertylist *drs;
120 cpl_propertylist *drs2;
121 unsigned char *rejmask;
122 unsigned char *rejplus;
123 casu_fits *mfimage;
124 cpl_image *ratioimg;
125 cpl_table *ratioimstats;
126 casu_tfits *ctable;
127 casu_fits *mdark;
128 cpl_propertylist *phupaf;
129} ps;
130
131static int isfirst;
132static cpl_frame *product_frame_mean_twi = NULL;
133static cpl_frame *product_frame_conf = NULL;
134static cpl_frame *product_frame_ratioimg = NULL;
135static cpl_frame *product_frame_ratioimg_stats = NULL;
136static int we_expect;
137static int we_get;
138
139static char vircam_twilight_flat_combine_description[] =
140"vircam_twilight_flat_combine -- VIRCAM twilight flat combine recipe.\n\n"
141"Combine a list of twilight flat frames into a mean frame. Optionally\n"
142"compare the output frame to a master twilight flat frame\n\n"
143"The program accepts the following files in the SOF:\n\n"
144" Tag Description\n"
145" -----------------------------------------------------------------------\n"
146" %-21s A list of raw twilight flat images\n"
147" %-21s A master dark frame\n"
148" %-21s Optional reference twilight flat frame\n"
149" %-21s Optional channel table or\n"
150" %-21s Optional initial channel table\n"
151" %-21s Optional master bad pixel map or\n"
152" %-21s Optional master confidence map\n"
153"If no reference twilight flat is made available, then no comparison will be\n"
154"done. This means there will be no output ratio image. If a master twilight\n"
155"is available, but no channel table is, then a ratio image will be formed\n"
156"but no stats will be written."
157"\n";
158
301/* Function code */
302
303/*---------------------------------------------------------------------------*/
311/*---------------------------------------------------------------------------*/
312
313int cpl_plugin_get_info(cpl_pluginlist *list) {
314 cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
315 cpl_plugin *plugin = &recipe->interface;
316 char alldesc[SZ_ALLDESC];
317 (void)snprintf(alldesc,SZ_ALLDESC,vircam_twilight_flat_combine_description,
318 VIRCAM_TWI_RAW,VIRCAM_CAL_DARK,VIRCAM_REF_TWILIGHT_FLAT,
319 VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT,VIRCAM_CAL_BPM,
320 VIRCAM_CAL_CONF);
321
322 cpl_plugin_init(plugin,
323 CPL_PLUGIN_API,
324 VIRCAM_BINARY_VERSION,
325 CPL_PLUGIN_TYPE_RECIPE,
326 "vircam_twilight_flat_combine",
327 "VIRCAM twilight combination recipe",
328 alldesc,
329 "Jim Lewis",
330 "jrl@ast.cam.ac.uk",
332 vircam_twilight_flat_combine_create,
333 vircam_twilight_flat_combine_exec,
334 vircam_twilight_flat_combine_destroy);
335
336 cpl_pluginlist_append(list,plugin);
337
338 return(0);
339}
340
341/*---------------------------------------------------------------------------*/
350/*---------------------------------------------------------------------------*/
351
352static int vircam_twilight_flat_combine_create(cpl_plugin *plugin) {
353 cpl_recipe *recipe;
354 cpl_parameter *p;
355
356 /* Get the recipe out of the plugin */
357
358 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
359 recipe = (cpl_recipe *)plugin;
360 else
361 return(-1);
362
363 /* Create the parameters list in the cpl_recipe object */
364
365 recipe->parameters = cpl_parameterlist_new();
366
367 /* Lower threshold for rejecting underexposed images */
368
369 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.lthr",
370 CPL_TYPE_DOUBLE,
371 "Low rejection threshold for underexpsed images",
372 "vircam.vircam_twilight_flat_combine",
373 4000.0);
374 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"lthr");
375 cpl_parameterlist_append(recipe->parameters,p);
376
377 /* Upper threshold for rejecting overexposed images */
378
379 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.hthr",
380 CPL_TYPE_DOUBLE,
381 "High rejection threshold for overexposed images",
382 "vircam.vircam_twilight_flat_combine",
383 12000.0);
384 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"hthr");
385 cpl_parameterlist_append(recipe->parameters,p);
386
387 /* Fill in the parameters. First the combination type */
388
389 p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.combtype",
390 CPL_TYPE_INT,
391 "1 == Median,\n 2 == Mean",
392 "vircam.vircam_twilight_flat_combine",
393 1,1,2);
394 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
395 cpl_parameterlist_append(recipe->parameters,p);
396
397 /* The requested scaling */
398
399 p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.scaletype",
400 CPL_TYPE_INT,
401 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
402 "vircam.vircam_twilight_flat_combine",
403 2,0,3);
404 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
405 cpl_parameterlist_append(recipe->parameters,p);
406
407 /* Extra rejection cycle */
408
409 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.xrej",
410 CPL_TYPE_BOOL,
411 "True if using extra rejection cycle",
412 "vircam.vircam_twilight_flat_combine",
413 TRUE);
414 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
415 cpl_parameterlist_append(recipe->parameters,p);
416
417 /* Rejection threshold */
418
419 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.thresh",
420 CPL_TYPE_DOUBLE,
421 "Rejection threshold in sigma above background",
422 "vircam.vircam_twilight_flat_combine",5.0);
423 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
424 cpl_parameterlist_append(recipe->parameters,p);
425
426 /* How many cells to divide each data channel */
427
428 p = cpl_parameter_new_enum("vircam.vircam_twilight_flat_combine.ncells",
429 CPL_TYPE_INT,
430 "Number of cells for data channel stats",
431 "vircam.vircam_twilight_flat_combine",8,7,1,2,4,
432 8,16,32,64);
433 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
434 cpl_parameterlist_append(recipe->parameters,p);
435
436 /* Extension number of input frames to use */
437
438 p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.extenum",
439 CPL_TYPE_INT,
440 "Extension number to be done, 0 == all",
441 "vircam.vircam_twilight_flat_combine",
442 0,0,16);
443 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
444 cpl_parameterlist_append(recipe->parameters,p);
445
446 /* Get out of here */
447
448 return(0);
449}
450
451
452/*---------------------------------------------------------------------------*/
458/*---------------------------------------------------------------------------*/
459
460static int vircam_twilight_flat_combine_exec(cpl_plugin *plugin) {
461 cpl_recipe *recipe;
462
463 /* Get the recipe out of the plugin */
464
465 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
466 recipe = (cpl_recipe *)plugin;
467 else
468 return(-1);
469
470 return(vircam_twilight_flat_combine(recipe->parameters,recipe->frames));
471}
472
473/*---------------------------------------------------------------------------*/
479/*---------------------------------------------------------------------------*/
480
481static int vircam_twilight_flat_combine_destroy(cpl_plugin *plugin) {
482 cpl_recipe *recipe ;
483
484 /* Get the recipe out of the plugin */
485
486 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
487 recipe = (cpl_recipe *)plugin;
488 else
489 return(-1);
490
491 cpl_parameterlist_delete(recipe->parameters);
492 return(0);
493}
494
495/*---------------------------------------------------------------------------*/
502/*---------------------------------------------------------------------------*/
503
504static int vircam_twilight_flat_combine(cpl_parameterlist *parlist,
505 cpl_frameset *framelist) {
506 const char *fctid="vircam_twilight_flat_combine";
507 int j = 1,jst,jfn,retval,status,nx,ny,ndit,npts,cstat;
508 cpl_size nlab;
509 long i;
510 cpl_parameter *p;
511 cpl_propertylist *pp;
512 cpl_image *im1,*im2,*newim,*diffim;
513 double val1,val2,scl;
514 float *data,med,mad;
515 unsigned char *bpm;
516
517 /* Check validity of input frameset */
518
519 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
520 cpl_msg_error(fctid,"Input framelist NULL or has no input data");
521 return(-1);
522 }
523
524 /* Initialise some things */
525
526 vircam_twilight_flat_combine_init();
527 we_expect = MEANTWI + CONFMAP;
528
529 /* Get the parameters */
530
531 p = cpl_parameterlist_find(parlist,"vircam.vircam_twilight_flat_combine.lthr");
532 vircam_twilight_flat_combine_config.lthr =
533 (float)cpl_parameter_get_double(p);
534 p = cpl_parameterlist_find(parlist,
535 "vircam.vircam_twilight_flat_combine.hthr");
536 vircam_twilight_flat_combine_config.hthr =
537 (float)cpl_parameter_get_double(p);
538 p = cpl_parameterlist_find(parlist,
539 "vircam.vircam_twilight_flat_combine.combtype");
540 vircam_twilight_flat_combine_config.combtype = cpl_parameter_get_int(p);
541 p = cpl_parameterlist_find(parlist,
542 "vircam.vircam_twilight_flat_combine.scaletype");
543 vircam_twilight_flat_combine_config.scaletype = cpl_parameter_get_int(p);
544 p = cpl_parameterlist_find(parlist,
545 "vircam.vircam_twilight_flat_combine.xrej");
546 vircam_twilight_flat_combine_config.xrej = cpl_parameter_get_bool(p);
547 p = cpl_parameterlist_find(parlist,
548 "vircam.vircam_twilight_flat_combine.thresh");
549 vircam_twilight_flat_combine_config.thresh =
550 (float)cpl_parameter_get_double(p);
551 p = cpl_parameterlist_find(parlist,
552 "vircam.vircam_twilight_flat_combine.ncells");
553 vircam_twilight_flat_combine_config.ncells = cpl_parameter_get_int(p);
554 p = cpl_parameterlist_find(parlist,
555 "vircam.vircam_twilight_flat_combine.extenum");
556 vircam_twilight_flat_combine_config.extenum = cpl_parameter_get_int(p);
557
558 /* Sort out raw from calib frames */
559
560 if (vircam_dfs_set_groups(framelist) != CASU_OK) {
561 cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
562 vircam_twilight_flat_combine_tidy(2);
563 return(-1);
564 }
565
566 /* Get the twilight frames */
567
568 if ((ps.labels = cpl_frameset_labelise(framelist,casu_compare_tags,
569 &nlab)) == NULL) {
570 cpl_msg_error(fctid,"Cannot labelise the input frames");
571 vircam_twilight_flat_combine_tidy(2);
572 return(-1);
573 }
574 if ((ps.twilightlist = casu_frameset_subgroup(framelist,ps.labels,nlab,
575 VIRCAM_TWI_RAW)) == NULL) {
576 cpl_msg_error(fctid,"Cannot find twilight frames in input frameset");
577 vircam_twilight_flat_combine_tidy(2);
578 return(-1);
579 }
580 ps.ntwilights = cpl_frameset_get_size(ps.twilightlist);
581
582 /* Check to see if there is a master dark frame */
583
584 if ((ps.master_dark = casu_frameset_subgroup_1(framelist,ps.labels,nlab,
585 VIRCAM_CAL_DARK)) == NULL) {
586 cpl_msg_error(fctid,"No master dark found");
587 vircam_twilight_flat_combine_tidy(2);
588 return(-1);
589 }
590
591 /* Check to see if there is a master twilight flat frame */
592
593 if ((ps.master_twilight_flat = casu_frameset_subgroup_1(framelist,
594 ps.labels,nlab,VIRCAM_REF_TWILIGHT_FLAT)) == NULL)
595 cpl_msg_info(fctid,"No master twilight flat found -- no ratio image will be formed");
596 else
597 we_expect |= RATIMG;
598
599 /* Check to see if there is a master bad pixel map. If there isn't one
600 then look for a confidence map */
601
602 ps.master_mask = casu_mask_define(framelist,ps.labels,nlab,VIRCAM_CAL_CONF,
603 VIRCAM_CAL_BPM);
604
605 /* Check to see if there is a channel table */
606
607 if ((ps.chantab = casu_frameset_subgroup_1(framelist,ps.labels,nlab,
608 VIRCAM_CAL_CHANTAB)) == NULL) {
609 if ((ps.chantab = casu_frameset_subgroup_1(framelist,ps.labels,nlab,
610 VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
611 cpl_msg_info(fctid,"No channel table found -- no ratio image stats and no linearisation will be done");
612 } else {
613 cpl_msg_info(fctid,"Channel table is labelled INIT -- no linearisation will be done");
614 if (we_expect & RATIMG)
615 we_expect |= STATS_TAB;
616 }
617 } else if (we_expect & RATIMG) {
618 we_expect |= STATS_TAB;
619 }
620
621 /* Get the number of DITs */
622
623 pp = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_position(ps.twilightlist,0)),0);
624 if (vircam_pfits_get_ndit(pp,&ndit) != CASU_OK) {
625 cpl_msg_error(fctid,"No value for NDIT available");
626 freepropertylist(pp);
627 vircam_twilight_flat_combine_tidy(2);
628 return(-1);
629 }
630 cpl_propertylist_delete(pp);
631
632 /* Now, how many image extensions do we want to do? If the extension
633 number is zero, then we loop for all possible extensions. If it
634 isn't then we just do the extension specified */
635
636 vircam_exten_range(vircam_twilight_flat_combine_config.extenum,
637 (const cpl_frame *)cpl_frameset_get_position(ps.twilightlist,0),
638 &jst,&jfn);
639 if (jst == -1 || jfn == -1) {
640 cpl_msg_error(fctid,"Unable to continue");
641 vircam_twilight_flat_combine_tidy(2);
642 return(-1);
643 }
644
645 /* Get some stats on the input flats and work out which ones need
646 to be removed as being either over or under exposed */
647
648 vircam_cull(ps.twilightlist,vircam_twilight_flat_combine_config.lthr,
649 vircam_twilight_flat_combine_config.hthr,ndit,jst,jfn,
650 &(ps.mins),&(ps.maxs),&(ps.aves),&(ps.twilightlist_cull),
651 &cstat);
652 ps.ntwilights = cpl_frameset_get_size(ps.twilightlist_cull);
653
654 /* OK look at some of the error conditions. First -- where we are
655 only looking at one extension and that detector is dead */
656
657 if (cstat == 1) {
658 cpl_msg_info(fctid,"Detector is flagged as dead");
659 we_get = 0;
660 isfirst = 1;
661 ps.twilights = casu_fits_load_list(ps.twilightlist,CPL_TYPE_FLOAT,j);
662 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
663 if (retval != 0)
664 return(-1);
665 vircam_twilight_flat_combine_tidy(2);
666 return(0);
667 }
668
669 /* All the images in the nominated detector are either over or under
670 exposed */
671
672 if (cstat == 2) {
673 cpl_msg_info(fctid,"All images either under or overexposed");
674 for (j = jst; j <= jfn; j++) {
675 we_get = 0;
676 isfirst = (j == jst);
677 ps.twilights = casu_fits_load_list(ps.twilightlist,
678 CPL_TYPE_FLOAT,j);
679 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
680 if (retval != 0)
681 return(-1);
682 }
683 vircam_twilight_flat_combine_tidy(2);
684 return(0);
685 }
686
687 /* OK, we have good images. So loop for all the extensions... */
688
689 for (j = jst; j <= jfn; j++) {
690 status = CASU_OK;
691 we_get = 0;
692 isfirst = (j == jst);
693
694 /* Load the images */
695
696 ps.twilights = casu_fits_load_list(ps.twilightlist_cull,
697 CPL_TYPE_FLOAT,j);
698 if (ps.twilights == NULL) {
699 cpl_msg_info(fctid,
700 "Extension %" CPL_SIZE_FORMAT " twilights wouldn't load",
701 (cpl_size)j);
702 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
703 if (retval != 0)
704 return(-1);
705 continue;
706 }
707
708 /* Load up the mask */
709
710 nx = (int)cpl_image_get_size_x(casu_fits_get_image(ps.twilights[0]));
711 ny = (int)cpl_image_get_size_y(casu_fits_get_image(ps.twilights[0]));
712 if (casu_mask_load(ps.master_mask,j,nx,ny) == CASU_FATAL) {
713 cpl_msg_info(fctid,
714 "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
715 casu_mask_get_filename(ps.master_mask),
716 (cpl_size)j);
717 cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
718 casu_mask_force(ps.master_mask,nx,ny);
719 }
720
721 /* Load up some results */
722
723 vircam_twilight_flat_combine_config.minv = cpl_array_get(ps.mins,j-jst,
724 NULL);
725 vircam_twilight_flat_combine_config.maxv = cpl_array_get(ps.maxs,j-jst,
726 NULL);
727 vircam_twilight_flat_combine_config.avev = cpl_array_get(ps.aves,j-jst,
728 NULL);
729
730 /* Take the middle two exposures and create a scaled difference image
731 estimate */
732
733 if (ps.ntwilights > 1) {
734 i = ps.ntwilights/2 - 1;
735 im1 = casu_fits_get_image(ps.twilights[i]);
736 im2 = casu_fits_get_image(ps.twilights[i+1]);
737 val1 = cpl_image_get_median_window(im1,500,500,1000,1000);
738 val2 = cpl_image_get_median_window(im2,500,500,1000,1000);
739 val1 /= (double)ndit;
740 val2 /= (double)ndit;
741 scl = val1/val2;
742 newim = cpl_image_multiply_scalar_create(im2,scl);
743 diffim = cpl_image_subtract_create(im1,newim);
744 cpl_image_delete(newim);
745 data = cpl_image_get_data_float(diffim);
746 bpm = casu_mask_get_data(ps.master_mask);
747 npts = nx*ny;
748 casu_medmad(data,bpm,npts,&med,&mad);
749 mad *= 1.48/CPL_MATH_SQRT2;
750 vircam_twilight_flat_combine_config.photnoise = mad;
751 vircam_twilight_flat_combine_config.snratio =
752 val1*sqrt((double)(ps.ntwilights))/mad;
753 cpl_image_delete(diffim);
754 } else {
755 vircam_twilight_flat_combine_config.photnoise = 0.0;
756 vircam_twilight_flat_combine_config.snratio = 0.0;
757 }
758
759 /* Right, we want to dark correct, so we need to load the mean
760 dark and make sure it isn't a dummy */
761
762 ps.mdark = casu_fits_load(ps.master_dark,CPL_TYPE_FLOAT,j);
763 if (ps.mdark == NULL) {
764 cpl_msg_info(fctid,
765 "Can't load master dark for extension %" CPL_SIZE_FORMAT,
766 (cpl_size)j);
767 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
768 if (retval != 0)
769 return(-1);
770 continue;
771 } else if (vircam_is_dummy(casu_fits_get_ehu(ps.mdark))) {
772 cpl_msg_info(fctid,
773 "Can't master dark extension %" CPL_SIZE_FORMAT " is a dummy",
774 (cpl_size)j);
775 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
776 if (retval != 0)
777 return(-1);
778 continue;
779 }
780
781 /* Loop for each image and dark correct */
782
783 cpl_msg_info(fctid,"Dark correcting extension %" CPL_SIZE_FORMAT,
784 (cpl_size)j);
785 for (i = 0; i < ps.ntwilights; i++)
786 casu_darkcor((ps.twilights)[i],ps.mdark,1.0,&status);
787
788 /* We need to load the channel table (if it exists) for linearisation
789 and for the ratio image stats table */
790
791 if (ps.chantab != NULL) {
792 ps.ctable = casu_tfits_load(ps.chantab,j);
793 if (ps.ctable == NULL) {
794 cpl_msg_info(fctid,
795 "Channel table extension %" CPL_SIZE_FORMAT " won't load",
796 (cpl_size)j);
797 } else if (vircam_chantab_verify(casu_tfits_get_table(ps.ctable)) != CASU_OK) {
798 cpl_msg_info(fctid,
799 "Channel table extension %" CPL_SIZE_FORMAT " has errors",
800 (cpl_size)j);
801 freetfits(ps.ctable);
802 } else {
803 pp = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
804 (cpl_size)j);
805 if (vircam_is_dummy(pp)) {
806 cpl_msg_info(fctid,
807 "Channel table extensions %" CPL_SIZE_FORMAT " is a dummy",
808 (cpl_size)j);
809 freetfits(ps.ctable);
810 }
811 freepropertylist(pp);
812 }
813 } else
814 ps.ctable = NULL;
815
816 /* Loop for each of the input images and linearise it if there
817 is a channel table */
818
819 if (ps.ctable != NULL) {
820 cpl_msg_info(fctid,
821 "Linearising extension %" CPL_SIZE_FORMAT,
822 (cpl_size)j);
823 for (i = 0; i < ps.ntwilights; i++)
824 (void)vircam_lincor((ps.twilights)[i],ps.ctable,1,ndit,&status);
825 }
826
827 /* Correct for ndit */
828
829 for (i = 0; i < ps.ntwilights; i++)
830 (void)casu_nditcor((ps.twilights)[i],ndit,"EXPTIME",&status);
831
832 /* Call the combine module */
833
834 cpl_msg_info(fctid,
835 "Doing combination for extension %" CPL_SIZE_FORMAT,
836 (cpl_size)j);
837 (void)casu_imcombine(ps.twilights,NULL,ps.ntwilights,
838 vircam_twilight_flat_combine_config.combtype,
839 vircam_twilight_flat_combine_config.scaletype,
840 vircam_twilight_flat_combine_config.xrej,
841 vircam_twilight_flat_combine_config.thresh,
842 "EXPTIME",&(ps.outimage),NULL,&(ps.rejmask),
843 &(ps.rejplus),&(ps.drs),&status);
844
845 /* If these correction and combination routines failed at any stage
846 then get out of here */
847
848 if (status == CASU_OK) {
849 we_get |= MEANTWI;
850 vircam_twilight_flat_combine_normal(j);
851 } else {
852 cpl_msg_info(fctid,"A processing step failed");
853 }
854
855 /* Create any dummies and save the products */
856
857 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
858 if (retval != 0)
859 return(-1);
860
861 }
862 vircam_twilight_flat_combine_tidy(2);
863 return(0);
864}
865
866
867/*---------------------------------------------------------------------------*/
874/*---------------------------------------------------------------------------*/
875
876static int vircam_twilight_flat_combine_save(cpl_frameset *framelist,
877 cpl_parameterlist *parlist) {
878 cpl_propertylist *plist,*elist,*p,*pafprop;
879 float val;
880 const char *fctid = "vircam_twilight_flat_combine_save";
881 const char *outfile = "twilightcomb.fits";
882 const char *outdiff = "twilightratio.fits";
883 const char *outdimst = "twilightratiotab.fits";
884 const char *outconf = "twilightconf.fits";
885 const char *outfilepaf = "twilightcomb";
886 const char *outdiffpaf = "twilightratio";
887 const char *recipeid = "vircam_twilight_flat_combine";
888
889 /* If we need to make a PHU then do that now based on the first frame
890 in the input frame list */
891
892 if (isfirst) {
893
894 /* Create a new product frame object and define some tags */
895
896 product_frame_mean_twi = cpl_frame_new();
897 cpl_frame_set_filename(product_frame_mean_twi,outfile);
898 cpl_frame_set_tag(product_frame_mean_twi,VIRCAM_PRO_TWILIGHT_FLAT);
899 cpl_frame_set_type(product_frame_mean_twi,CPL_FRAME_TYPE_IMAGE);
900 cpl_frame_set_group(product_frame_mean_twi,CPL_FRAME_GROUP_PRODUCT);
901 cpl_frame_set_level(product_frame_mean_twi,CPL_FRAME_LEVEL_FINAL);
902
903 /* Set up the PHU header */
904
905 plist = casu_fits_get_phu(ps.twilights[0]);
906 ps.phupaf = vircam_paf_phu_items(plist);
907 if (ps.master_twilight_flat != NULL) {
908 cpl_propertylist_update_string(ps.phupaf,"REF_TWILIGHT",
909 cpl_frame_get_filename(ps.master_twilight_flat));
910 cpl_propertylist_set_comment(ps.phupaf,"REF_TWILIGHT",
911 "Reference twilight flat used");
912 }
913 vircam_dfs_set_product_primary_header(plist,product_frame_mean_twi,
914 framelist,parlist,
915 (char *)recipeid,
916 "PRO-1.15",NULL,0);
917
918 /* 'Save' the PHU image */
919
920 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
921 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
922 cpl_msg_error(fctid,"Cannot save product PHU");
923 cpl_frame_delete(product_frame_mean_twi);
924 return(-1);
925 }
926 cpl_frameset_insert(framelist,product_frame_mean_twi);
927
928 /* Create a new product frame object and define some tags for the
929 output confidence map */
930
931 product_frame_conf = cpl_frame_new();
932 cpl_frame_set_filename(product_frame_conf,outconf);
933 cpl_frame_set_tag(product_frame_conf,VIRCAM_PRO_CONF);
934 cpl_frame_set_type(product_frame_conf,CPL_FRAME_TYPE_IMAGE);
935 cpl_frame_set_group(product_frame_conf,CPL_FRAME_GROUP_PRODUCT);
936 cpl_frame_set_level(product_frame_conf,CPL_FRAME_LEVEL_FINAL);
937
938 /* Set up the PHU header */
939
940 plist = casu_fits_get_phu(ps.twilights[0]);
941 vircam_dfs_set_product_primary_header(plist,product_frame_conf,
942 framelist,parlist,
943 (char *)recipeid,"PRO-1.15",
944 NULL,0);
945
946 /* 'Save' the PHU image */
947
948 if (cpl_image_save(NULL,outconf,CPL_TYPE_UCHAR,plist,
949 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
950 cpl_msg_error(fctid,"Cannot save product PHU");
951 cpl_frame_delete(product_frame_conf);
952 return(-1);
953 }
954 cpl_frameset_insert(framelist,product_frame_conf);
955
956 /* Create a new product frame object for the difference image */
957
958 if (we_expect & RATIMG) {
959 product_frame_ratioimg = cpl_frame_new();
960 cpl_frame_set_filename(product_frame_ratioimg,outdiff);
961 cpl_frame_set_tag(product_frame_ratioimg,
962 VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT);
963 cpl_frame_set_type(product_frame_ratioimg,CPL_FRAME_TYPE_IMAGE);
964 cpl_frame_set_group(product_frame_ratioimg,
965 CPL_FRAME_GROUP_PRODUCT);
966 cpl_frame_set_level(product_frame_ratioimg,CPL_FRAME_LEVEL_FINAL);
967
968 /* Set up the PHU header */
969
970 plist = casu_fits_get_phu(ps.twilights[0]);
971 vircam_dfs_set_product_primary_header(plist,product_frame_ratioimg,
972 framelist,parlist,
973 (char *)recipeid,"PRO-1.15",
974 NULL,0);
975
976 /* 'Save' the PHU image */
977
978 if (cpl_image_save(NULL,outdiff,CPL_TYPE_CHAR,plist,
979 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
980 cpl_msg_error(fctid,"Cannot save product PHU");
981 cpl_frame_delete(product_frame_ratioimg);
982 return(-1);
983 }
984 cpl_frameset_insert(framelist,product_frame_ratioimg);
985 }
986
987 /* Create a new product frame object for the difference image stats
988 table */
989
990 if (we_expect & STATS_TAB) {
991 product_frame_ratioimg_stats = cpl_frame_new();
992 cpl_frame_set_filename(product_frame_ratioimg_stats,outdimst);
993 cpl_frame_set_tag(product_frame_ratioimg_stats,
994 VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT_STATS);
995 cpl_frame_set_type(product_frame_ratioimg_stats,
996 CPL_FRAME_TYPE_TABLE);
997 cpl_frame_set_group(product_frame_ratioimg_stats,
998 CPL_FRAME_GROUP_PRODUCT);
999 cpl_frame_set_level(product_frame_ratioimg_stats,
1000 CPL_FRAME_LEVEL_FINAL);
1001
1002 /* Set up PHU header */
1003
1004 plist = casu_fits_get_phu(ps.twilights[0]);
1006 product_frame_ratioimg_stats,
1007 framelist,parlist,
1008 (char *)recipeid,"PRO-1.15",
1009 NULL,0);
1010
1011 /* Fiddle with the extension header now */
1012
1013 elist = casu_fits_get_ehu(ps.twilights[0]);
1014 p = cpl_propertylist_duplicate(elist);
1015 casu_merge_propertylists(p,ps.drs);
1016 if (! (we_get & STATS_TAB))
1018 casu_removewcs(p, &(int){CASU_OK});
1019 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
1020 framelist,parlist,
1021 (char *)recipeid,
1022 "PRO-1.15",NULL);
1023
1024 /* And finally the difference image stats table */
1025
1026 if (cpl_table_save(ps.ratioimstats,plist,p,outdimst,
1027 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
1028 cpl_msg_error(fctid,"Cannot save product table extension");
1029 cpl_propertylist_delete(p);
1030 return(-1);
1031 }
1032 cpl_propertylist_delete(p);
1033 cpl_frameset_insert(framelist,product_frame_ratioimg_stats);
1034 }
1035 }
1036
1037 /* Get the extension property list */
1038
1039 plist = casu_fits_get_ehu(ps.twilights[0]);
1040 casu_merge_propertylists(plist,ps.drs);
1041 cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ntwilights);
1042
1043 /* Fiddle with the header now */
1044
1045 p = cpl_propertylist_duplicate(plist);
1046 if (! (we_get & MEANTWI))
1048 vircam_dfs_set_product_exten_header(p,product_frame_mean_twi,framelist,
1049 parlist,(char *)recipeid,
1050 "PRO-1.15",NULL);
1051
1052 /* Now save the mean twilight flat image extension */
1053
1054 cpl_propertylist_update_float(p,"ESO QC FLATRMS",
1055 vircam_twilight_flat_combine_config.flatrms);
1056 cpl_propertylist_set_comment(p,"ESO QC FLATRMS","RMS of output flat");
1057 cpl_propertylist_update_float(p,"ESO QC FLATMIN",
1058 vircam_twilight_flat_combine_config.minv);
1059 cpl_propertylist_set_comment(p,"ESO QC FLATMIN","Ensemble minimum");
1060 cpl_propertylist_update_float(p,"ESO QC FLATMAX",
1061 vircam_twilight_flat_combine_config.maxv);
1062 cpl_propertylist_set_comment(p,"ESO QC FLATMAX","Ensemble maximum");
1063 cpl_propertylist_update_float(p,"ESO QC FLATAVG",
1064 vircam_twilight_flat_combine_config.avev);
1065 cpl_propertylist_set_comment(p,"ESO QC FLATAVG","Ensemble average");
1066 val = vircam_twilight_flat_combine_config.maxv -
1067 vircam_twilight_flat_combine_config.minv;
1068 cpl_propertylist_update_float(p,"ESO QC FLATRNG",val);
1069 cpl_propertylist_set_comment(p,"ESO QC FLATRNG","Ensemble range");
1070 cpl_propertylist_update_float(p,"ESO QC TWIPHOT",
1071 vircam_twilight_flat_combine_config.photnoise);
1072 cpl_propertylist_set_comment(p,"ESO QC TWIPHOT",
1073 "[adu] Estimated photon noise");
1074 cpl_propertylist_update_float(p,"ESO QC TWISNRATIO",
1075 vircam_twilight_flat_combine_config.snratio);
1076 cpl_propertylist_set_comment(p,"ESO QC TWISNRATIO","Estimated S/N ratio");
1077 if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
1078 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
1079 cpl_msg_error(fctid,"Cannot save product image extension");
1080 cpl_propertylist_delete(p);
1081 return(-1);
1082 }
1083
1084 /* Write out PAF for mean image */
1085
1086 pafprop = vircam_paf_req_items(p);
1087 casu_merge_propertylists(pafprop,ps.phupaf);
1088 vircam_paf_append(pafprop,casu_fits_get_phu(ps.twilights[0]),
1089 "ESO INS FILT1 NAME");
1090 vircam_paf_append(pafprop,p,"ESO PRO CATG");
1091 vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
1092 vircam_paf_append(pafprop,p,"ESO DET NDIT");
1093 if (vircam_paf_print((char *)outfilepaf,
1094 "VIRCAM/vircam_twilight_flat_combine",
1095 "QC file",pafprop) != CASU_OK)
1096 cpl_msg_warning(fctid,"Unable to save PAF for mean twilight");
1097 cpl_propertylist_delete(pafprop);
1098 cpl_propertylist_delete(p);
1099
1100 /* Now save the twilight ratio image extension */
1101
1102 if (we_expect & RATIMG) {
1103 p = cpl_propertylist_duplicate(plist);
1104 if (! (we_get & RATIMG))
1106 cpl_propertylist_update_float(p,"ESO QC FLATRATIO_MED",
1107 vircam_twilight_flat_combine_config.flatratio_med);
1108 cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_MED",
1109 "Median of ratio map");
1110 cpl_propertylist_update_float(p,"ESO QC FLATRATIO_RMS",
1111 vircam_twilight_flat_combine_config.flatratio_rms);
1112 cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_RMS",
1113 "RMS of ratio map");
1114 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg,
1115 framelist,parlist,(char *)recipeid,
1116 "PRO-1.15",NULL);
1117 if (cpl_image_save(ps.ratioimg,outdiff,CPL_TYPE_FLOAT,p,
1118 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
1119 cpl_propertylist_delete(p);
1120 cpl_msg_error(fctid,"Cannot save product image extension");
1121 return(-1);
1122 }
1123
1124 /* Write out PAF for difference image */
1125
1126 pafprop = vircam_paf_req_items(p);
1127 casu_merge_propertylists(pafprop,ps.phupaf);
1128 vircam_paf_append(pafprop,casu_fits_get_phu(ps.twilights[0]),
1129 "ESO INS FILT1 NAME");
1130 vircam_paf_append(pafprop,p,"ESO PRO CATG");
1131 if (vircam_paf_print((char *)outdiffpaf,
1132 "VIRCAM/vircam_twilight_flat_combine",
1133 "QC file",pafprop) != CASU_OK)
1134 cpl_msg_warning(fctid,"Unable to save PAF for twilight ratio image");
1135 cpl_propertylist_delete(pafprop);
1136 cpl_propertylist_delete(p);
1137 }
1138
1139 /* Now any further ratio image stats tables */
1140
1141 if (! isfirst && (we_expect & STATS_TAB)) {
1142 p = cpl_propertylist_duplicate(plist);
1143 if (! (we_get & STATS_TAB))
1145 casu_removewcs(p, &(int){CASU_OK});
1146 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
1147 framelist,parlist,(char *)recipeid,
1148 "PRO-1.15",NULL);
1149 if (cpl_table_save(ps.ratioimstats,NULL,p,outdimst,CPL_IO_EXTEND)
1150 != CPL_ERROR_NONE) {
1151 cpl_msg_error(fctid,"Cannot save product table extension");
1152 cpl_propertylist_delete(p);
1153 return(-1);
1154 }
1155 cpl_propertylist_delete(p);
1156 }
1157
1158 /* Fiddle with the header now */
1159
1160 casu_merge_propertylists(plist,ps.drs2);
1161 p = cpl_propertylist_duplicate(plist);
1162 if (! (we_get & CONFMAP))
1164
1165 /* Now save the confidence map */
1166
1167 vircam_dfs_set_product_exten_header(p,product_frame_conf,framelist,
1168 parlist,(char *)recipeid,"PRO-1.15",
1169 NULL);
1170 if (cpl_image_save(ps.outconf,outconf,CPL_TYPE_SHORT,p,
1171 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
1172 cpl_msg_error(fctid,"Cannot save product image extension");
1173 cpl_propertylist_delete(p);
1174 return(-1);
1175 }
1176 cpl_propertylist_delete(p);
1177
1178 /* Get out of here */
1179
1180 return(0);
1181}
1182
1183/*---------------------------------------------------------------------------*/
1187/*---------------------------------------------------------------------------*/
1188
1189static void vircam_twilight_flat_combine_dummy_products(void) {
1190
1191 /* See if you even need to be here */
1192
1193 if (we_get == we_expect)
1194 return;
1195
1196 /* First an output combined twilight frame */
1197
1198 if (! (we_get & MEANTWI)) {
1199 ps.outimage = casu_dummy_image(ps.twilights[0]);
1200 vircam_twilight_flat_combine_config.flatrms = 0.0;
1201 }
1202
1203 /* Now the confidence map */
1204
1205 if (! (we_get & CONFMAP)) {
1206 ps.outconf = casu_dummy_image(ps.twilights[0]);
1207 vircam_twilight_flat_combine_config.flatrms = 0.0;
1208 }
1209
1210 /* Do a ratio image */
1211
1212 if ((we_expect & RATIMG) && ! (we_get & RATIMG)) {
1213 vircam_twilight_flat_combine_config.flatratio_med = 0.0;
1214 vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
1215 ps.ratioimg = casu_dummy_image(ps.twilights[0]);
1216 }
1217
1218 /* If a ratio image stats table is required, then do that now */
1219
1220 if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
1221 ps.ratioimstats = vircam_create_diffimg_stats(0);
1222
1223 return;
1224}
1225
1226/*---------------------------------------------------------------------------*/
1231/*---------------------------------------------------------------------------*/
1232
1233static void vircam_twilight_flat_combine_normal(int jext) {
1234 int nx,ny,ncells,status;
1235 long i,npi;
1236 unsigned char *bpm;
1237 float *idata,med,sig,gdiff,grms;
1238 const char *fctid="vircam_twilight_flat_combine_normal";
1239
1240 /* Load up a bad pixel mask */
1241
1242 nx = (int)cpl_image_get_size_x(ps.outimage);
1243 ny = (int)cpl_image_get_size_y(ps.outimage);
1244 npi = nx*ny;
1245 casu_mask_load(ps.master_mask,jext,nx,ny);
1246 bpm = casu_mask_get_data(ps.master_mask);
1247
1248 /* Create the bad pixel mask */
1249
1250 status = CASU_OK;
1251 (void)casu_mkconf(ps.outimage,(char *)"None Available",ps.master_mask,
1252 &(ps.outconf),&(ps.drs2),&status);
1253 if (status == CASU_OK)
1254 we_get |= CONFMAP;
1255 else {
1256 cpl_msg_info(fctid,
1257 "Confidence map creation failed extension %" CPL_SIZE_FORMAT,
1258 (cpl_size)jext);
1259 status = CASU_OK;
1260 }
1261
1262 /* Work out the RMS of the mean twilight frame */
1263
1264 idata = cpl_image_get_data(ps.outimage);
1265 casu_medsig(idata,bpm,npi,&med,&sig);
1266
1267 /* Fill in the bad bits... */
1268
1269 for (i = 0; i < npi; i++)
1270 if (bpm[i])
1271 idata[i] = med;
1272
1273 /* Divide through by the median */
1274
1275 cpl_propertylist_update_float(ps.drs,"ESO DRS MEDFLAT",med);
1276 cpl_propertylist_set_comment(ps.drs,"ESO DRS MEDFLAT",
1277 "Median value before normalisation");
1278 cpl_image_divide_scalar(ps.outimage,med);
1279 casu_medmad(idata,bpm,npi,&med,&sig);
1280 sig *= 1.48;
1281 vircam_twilight_flat_combine_config.flatrms = sig;
1282
1283 /* Load up the master twilight flat */
1284
1285 if (ps.master_twilight_flat != NULL) {
1286 ps.mfimage = casu_fits_load(ps.master_twilight_flat,CPL_TYPE_FLOAT,jext);
1287 if (ps.mfimage == NULL) {
1288 cpl_msg_info(fctid,
1289 "Master twilight extension %" CPL_SIZE_FORMAT " won't load",
1290 (cpl_size)jext);
1291 } else if (vircam_is_dummy(casu_fits_get_ehu(ps.mfimage))) {
1292 cpl_msg_info(fctid,
1293 "Master twilight extension %" CPL_SIZE_FORMAT " is a dummy",
1294 (cpl_size)jext);
1295 freefits(ps.mfimage);
1296 }
1297 } else
1298 ps.mfimage = NULL;
1299
1300
1301 /* Create a ratio image. NB: the difference image routine copes if the
1302 input mean image or the channel tables are null. Thus if either or
1303 both are null because of a failure to load, then the routine will do
1304 as much as it can and return, allowing you to fill in the rest with
1305 dummy products */
1306
1307 vircam_twilight_flat_combine_config.flatratio_med = 0.0;
1308 vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
1309 ncells = vircam_twilight_flat_combine_config.ncells;
1310 vircam_difference_image(casu_fits_get_image(ps.mfimage),ps.outimage,bpm,
1311 casu_tfits_get_table(ps.ctable),ncells,2,
1312 &gdiff,&grms,&(ps.ratioimg),
1313 &(ps.ratioimstats));
1314 casu_mask_clear(ps.master_mask);
1315 vircam_twilight_flat_combine_config.flatratio_med = gdiff;
1316 vircam_twilight_flat_combine_config.flatratio_rms = grms;
1317 if (ps.ratioimg != NULL)
1318 we_get |= RATIMG;
1319 if (ps.ratioimstats != NULL)
1320 we_get |= STATS_TAB;
1321 return;
1322}
1323
1324/*---------------------------------------------------------------------------*/
1332/*---------------------------------------------------------------------------*/
1333
1334
1335static int vircam_twilight_flat_combine_lastbit(int jext,
1336 cpl_frameset *framelist,
1337 cpl_parameterlist *parlist) {
1338 int retval;
1339 const char *fctid="vircam_twilight_flat_combine_lastbit";
1340
1341 /* Make whatever dummy products you need */
1342
1343 vircam_twilight_flat_combine_dummy_products();
1344
1345 /* Save everything */
1346
1347 cpl_msg_info(fctid,
1348 "Saving products for extension %" CPL_SIZE_FORMAT,
1349 (cpl_size)jext);
1350 retval = vircam_twilight_flat_combine_save(framelist,parlist);
1351 if (retval != 0) {
1352 vircam_twilight_flat_combine_tidy(2);
1353 return(-1);
1354 }
1355
1356 /* Free some stuff up */
1357
1358 vircam_twilight_flat_combine_tidy(1);
1359 return(0);
1360}
1361
1362/*---------------------------------------------------------------------------*/
1366/*---------------------------------------------------------------------------*/
1367
1368static void vircam_twilight_flat_combine_init(void) {
1369 ps.labels = NULL;
1370 ps.twilightlist = NULL;
1371 ps.twilightlist_cull = NULL;
1372 ps.master_dark = NULL;
1373 ps.master_twilight_flat = NULL;
1374 ps.master_mask = NULL;
1375 ps.chantab = NULL;
1376 ps.phupaf = NULL;
1377 ps.mins = NULL;
1378 ps.maxs = NULL;
1379 ps.aves = NULL;
1380
1381 ps.outimage = NULL;
1382 ps.outconf = NULL;
1383 ps.twilights = NULL;
1384 ps.drs = NULL;
1385 ps.drs2 = NULL;
1386 ps.rejmask = NULL;
1387 ps.rejplus = NULL;
1388 ps.mfimage = NULL;
1389 ps.ratioimg = NULL;
1390 ps.ratioimstats = NULL;
1391 ps.ctable = NULL;
1392 ps.mdark = NULL;
1393}
1394
1395/*---------------------------------------------------------------------------*/
1399/*---------------------------------------------------------------------------*/
1400
1401static void vircam_twilight_flat_combine_tidy(int level) {
1402 freeimage(ps.outimage);
1403 freeimage(ps.outconf);
1404 freefitslist(ps.twilights,ps.ntwilights);
1405 freepropertylist(ps.drs);
1406 freepropertylist(ps.drs2);
1407 freespace(ps.rejmask);
1408 freespace(ps.rejplus);
1409 freefits(ps.mfimage);
1410 freeimage(ps.ratioimg);
1411 freetable(ps.ratioimstats);
1412 freetfits(ps.ctable);
1413 freefits(ps.mdark);
1414 if (level == 1)
1415 return;
1416
1417 freespace(ps.labels);
1418 freeframeset(ps.twilightlist);
1419 freeframeset(ps.twilightlist_cull);
1420 freeframe(ps.master_dark);
1421 freeframe(ps.master_twilight_flat);
1422 freemask(ps.master_mask);
1423 freeframe(ps.chantab);
1424 freepropertylist(ps.phupaf);
1425 freearray(ps.mins);
1426 freearray(ps.maxs);
1427 freearray(ps.aves);
1428}
1429
1432/*
1433
1434$Log: not supported by cvs2svn $
1435Revision 1.56 2012/01/15 17:40:09 jim
1436Minor modifications to take into accout the changes in cpl API for v6
1437
1438Revision 1.55 2011/05/09 09:58:10 jim
1439Cosmetic changes to stop compiler warnings
1440
1441Revision 1.54 2010/12/09 13:21:36 jim
1442Added code to calculate rough photon noise and s/n ratio
1443
1444Revision 1.53 2010/03/21 06:48:21 jim
1445Fixed bug where DATANCOM wasn't being updated in all products
1446
1447Revision 1.52 2010/03/09 14:27:40 jim
1448Now updates ESO PRO DATANCOM to reflect the number of images used
1449
1450Revision 1.51 2010/02/05 09:42:22 jim
1451Fixed call to non-existent cpl routine
1452
1453Revision 1.50 2010/01/31 18:53:22 jim
1454Reference flat included in paf
1455
1456Revision 1.49 2009/12/11 06:52:56 jim
1457Minor mods to documentation
1458
1459Revision 1.48 2009/11/18 21:32:40 jim
1460Modified to write NDIT to the paf
1461
1462Revision 1.47 2009/09/21 11:59:37 jim
1463Modified to use new version of vircam_overexp and to write ensemble stats
1464to QC headers
1465
1466Revision 1.46 2009/09/09 09:50:21 jim
1467Modified to try and get headers right
1468
1469Revision 1.45 2008/12/05 13:28:32 jim
1470Fixed save routine so that the correct version of PRO CATG is written to the
1471paf file
1472
1473Revision 1.44 2008/11/26 18:33:59 jim
1474Now fills bad pixels in the output flat with a median value before normalisation
1475
1476Revision 1.43 2008/10/01 04:59:13 jim
1477Added call to vircam_frameset_fexists to check input frameset
1478
1479Revision 1.42 2008/09/30 11:33:23 jim
1480Added PRO CATG to pafs
1481
1482Revision 1.41 2008/09/29 11:21:47 jim
1483Default is to form medians
1484
1485Revision 1.40 2007/11/26 09:59:06 jim
1486Recipe now takes ndit into account when doing linearity correction
1487
1488Revision 1.39 2007/10/19 09:25:09 jim
1489Fixed problems with missing includes
1490
1491Revision 1.38 2007/10/15 12:53:26 jim
1492Modified for compatibiliity with cpl_4.0
1493
1494Revision 1.37 2007/07/18 15:35:42 jim
1495Added better error handling for missing or corrupt mask extensions
1496
1497Revision 1.36 2007/07/09 13:21:56 jim
1498Modified to use new version of vircam_exten_range
1499
1500Revision 1.35 2007/06/13 08:11:27 jim
1501Modified docs to reflect changes in DFS tags
1502
1503Revision 1.34 2007/05/08 10:42:33 jim
1504Added DRS MEDFLAT keyword
1505
1506Revision 1.33 2007/04/30 09:40:17 jim
1507Added more stuff to paf files
1508
1509Revision 1.32 2007/04/04 10:36:18 jim
1510Modified to use new dfs tags
1511
1512Revision 1.31 2007/03/29 12:19:39 jim
1513Little changes to improve documentation
1514
1515Revision 1.30 2007/03/02 12:37:16 jim
1516Removed WCS stuff from table headers
1517
1518Revision 1.29 2007/03/01 12:41:49 jim
1519Modified slightly after code checking
1520
1521Revision 1.28 2007/02/25 06:27:41 jim
1522plugged a few memory leaks
1523
1524Revision 1.27 2007/02/15 11:54:09 jim
1525Modified to make a distinction between initial channel table and one that
1526has the proper linearity information
1527
1528Revision 1.26 2007/02/15 06:59:38 jim
1529Added ability to write QC paf files
1530
1531Revision 1.25 2007/02/07 10:12:40 jim
1532Removed calls to vircam_ndit_correct as this is now no longer necessary
1533
1534Revision 1.24 2007/02/06 13:11:12 jim
1535Fixed entry for PRO dictionary in cpl_dfs_set_product_header
1536
1537Revision 1.23 2007/02/05 14:14:05 jim
1538Input master frame is now tagged as REFERENCE. QC removed from stats table
1539headers
1540
1541Revision 1.22 2007/01/08 19:09:11 jim
1542Fixed memory leak
1543
1544Revision 1.21 2006/12/13 13:26:09 jim
1545Fxied bad sigma estimate
1546
1547Revision 1.20 2006/11/27 12:15:08 jim
1548changed calls to cpl_propertylist_append to cpl_propertylist_update
1549
1550Revision 1.19 2006/11/10 09:24:49 jim
1551Fixed bug in save routine where the wrong propertylist was being saved
1552
1553Revision 1.18 2006/09/29 11:19:31 jim
1554changed aliases on parameter names
1555
1556Revision 1.17 2006/09/10 20:47:03 jim
1557Small documentation fix
1558
1559Revision 1.16 2006/09/09 16:49:40 jim
1560Header comment update
1561
1562Revision 1.15 2006/08/27 20:30:02 jim
1563Major mods to structure of the main processing routine to deal with missing
1564and dummy frames. Deals better with lower level failures too
1565
1566Revision 1.14 2006/07/11 14:55:12 jim
1567Now checks for zeros in the output flat and replaces them
1568
1569Revision 1.13 2006/06/20 19:07:01 jim
1570Corrects for ndit != 1
1571
1572Revision 1.12 2006/06/15 09:58:58 jim
1573Minor changes to docs
1574
1575Revision 1.11 2006/06/09 11:26:25 jim
1576Small changes to keep lint happy
1577
1578Revision 1.10 2006/06/06 13:01:40 jim
1579Fixed so that the QC parameters go into the correct headers
1580
1581Revision 1.9 2006/05/26 19:34:18 jim
1582Fixed recipe to normalise the flats
1583
1584Revision 1.8 2006/05/17 14:43:58 jim
1585Fixed problem in save routine which messed up the PRO CATG keywords
1586
1587Revision 1.7 2006/05/16 13:58:47 jim
1588Fixed memory leaks that occur from not closing images at the end of
1589the image extension loop
1590
1591Revision 1.6 2006/05/09 08:54:40 jim
1592Fixed _save routine so that the confidence map is saved as a signed 16 bit
1593integer
1594
1595Revision 1.5 2006/05/08 14:54:03 jim
1596Fixed little bug where the confidence map file name wasn't being declared to
1597the header correctly
1598
1599Revision 1.4 2006/05/08 13:20:23 jim
1600Fixed bug where the fitslist for the flats got deleted twice
1601
1602Revision 1.3 2006/05/04 11:53:15 jim
1603Fixed the way the _save routine works to be more consistent with the
1604standard CPL way of doing things
1605
1606Revision 1.2 2006/04/27 14:21:26 jim
1607Renamed undefined tag
1608
1609Revision 1.1 2006/04/27 09:44:47 jim
1610new file
1611
1612*/
cpl_image * casu_fits_get_image(casu_fits *p)
Definition: casu_fits.c:436
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
casu_fits * casu_fits_load(cpl_frame *frame, cpl_type type, int nexten)
Definition: casu_fits.c:80
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
int casu_mkconf(cpl_image *flat, char *flatfile, casu_mask *bpm, cpl_image **outconf, cpl_propertylist **drs, int *status)
Create a confidence map.
Definition: casu_mkconf.c:87
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_nditcor(casu_fits *infile, int ndit, const char *expkey, int *status)
Correct input data for number of dits.
Definition: casu_nditcor.c:85
int casu_darkcor(casu_fits *infile, casu_fits *darksrc, float darkscl, int *status)
Correct input data for dark current.
Definition: casu_darkcor.c:86
void casu_medmad(float *data, unsigned char *bpm, long np, float *med, float *mad)
Definition: casu_stats.c:347
void casu_medsig(float *data, unsigned char *bpm, long np, float *med, float *sig)
Definition: casu_stats.c:672
casu_tfits * casu_tfits_load(cpl_frame *table, int nexten)
Definition: casu_tfits.c:78
cpl_table * casu_tfits_get_table(casu_tfits *p)
Definition: casu_tfits.c:364
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_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.
Definition: casu_utils.c:206
cpl_image * casu_dummy_image(casu_fits *model)
Create a dummy image of zeros based on a model.
Definition: casu_utils.c:533
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 casu_removewcs(cpl_propertylist *p, int *status)
int vircam_lincor(casu_fits *infile, casu_tfits *lchantab, int kconst, int ndit, int *status)
Apply linearity curves to data.
int vircam_chantab_verify(cpl_table *intab)
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_ndit(const cpl_propertylist *plist, int *ndit)
Get the value of NDIT.
Definition: vircam_pfits.c:583
const char * vircam_get_license(void)
Definition: vircam_utils.c:116
void vircam_cull(cpl_frameset *in, float lthr, float hthr, int ndit, int jst, int jfn, cpl_array **mins, cpl_array **maxs, cpl_array **aves, cpl_frameset **out, int *status)
cpl_table * vircam_create_diffimg_stats(int nrows)
Definition: vircam_utils.c:960
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)
Definition: vircam_utils.c:762
int vircam_is_dummy(cpl_propertylist *p)
void vircam_exten_range(int inexten, const cpl_frame *fr, int *out1, int *out2)
Definition: vircam_utils.c:165