00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033
00034 #include <stdio.h>
00035 #include <cpl.h>
00036 #include <math.h>
00037
00038 #include "vircam_utils.h"
00039 #include "vircam_mask.h"
00040 #include "vircam_dfs.h"
00041 #include "vircam_mods.h"
00042 #include "vircam_stats.h"
00043 #include "vircam_fits.h"
00044 #include "vircam_pfits.h"
00045 #include "vircam_channel.h"
00046 #include "vircam_paf.h"
00047 #include "vircam_wcsutils.h"
00048
00049
00050
00051 #define MEANTWI 1
00052 #define CONFMAP 2
00053 #define RATIMG 4
00054 #define STATS_TAB 8
00055
00056
00057
00058 static int vircam_twilight_flat_combine_create(cpl_plugin *) ;
00059 static int vircam_twilight_flat_combine_exec(cpl_plugin *) ;
00060 static int vircam_twilight_flat_combine_destroy(cpl_plugin *) ;
00061 static int vircam_twilight_flat_combine(cpl_parameterlist *, cpl_frameset *) ;
00062 static int vircam_twilight_flat_combine_save(cpl_frameset *framelist,
00063 cpl_parameterlist *parlist);
00064 static void vircam_twilight_flat_combine_dummy_products(void);
00065 static void vircam_twilight_flat_combine_normal(int jext);
00066 static int vircam_twilight_flat_combine_lastbit(int jext,
00067 cpl_frameset *framelist,
00068 cpl_parameterlist *parlist);
00069 static void vircam_twilight_flat_combine_init(void);
00070 static void vircam_twilight_flat_combine_tidy(int level);
00071
00072
00073
00074 static struct {
00075
00076
00077
00078 float lthr;
00079 float hthr;
00080 int combtype;
00081 int scaletype;
00082 int xrej;
00083 float thresh;
00084 int ncells;
00085 int extenum;
00086
00087
00088
00089 float flatrms;
00090 float flatratio_med;
00091 float flatratio_rms;
00092 float minv;
00093 float maxv;
00094 float avev;
00095 float photnoise;
00096 float snratio;
00097
00098 } vircam_twilight_flat_combine_config;
00099
00100
00101 static struct {
00102 vir_fits **good;
00103 int ngood;
00104 int *labels;
00105 cpl_frameset *twilightlist;
00106 cpl_frame *master_dark;
00107 cpl_frame *master_twilight_flat;
00108 vir_mask *master_mask;
00109 cpl_frame *chantab;
00110
00111 cpl_image *outimage;
00112 cpl_image *outconf;
00113 vir_fits **twilights;
00114 int ntwilights;
00115 cpl_propertylist *drs;
00116 cpl_propertylist *drs2;
00117 unsigned char *rejmask;
00118 unsigned char *rejplus;
00119 vir_fits *mfimage;
00120 cpl_image *ratioimg;
00121 cpl_table *ratioimstats;
00122 vir_tfits *ctable;
00123 vir_fits *mdark;
00124 cpl_propertylist *phupaf;
00125 } ps;
00126
00127 static int isfirst;
00128 static cpl_frame *product_frame_mean_twi = NULL;
00129 static cpl_frame *product_frame_conf = NULL;
00130 static cpl_frame *product_frame_ratioimg = NULL;
00131 static cpl_frame *product_frame_ratioimg_stats = NULL;
00132 static int we_expect;
00133 static int we_get;
00134
00135 static char vircam_twilight_flat_combine_description[] =
00136 "vircam_twilight_flat_combine -- VIRCAM twilight flat combine recipe.\n\n"
00137 "Combine a list of twilight flat frames into a mean frame. Optionally\n"
00138 "compare the output frame to a master twilight flat frame\n\n"
00139 "The program accepts the following files in the SOF:\n\n"
00140 " Tag Description\n"
00141 " -----------------------------------------------------------------------\n"
00142 " %-21s A list of raw twilight flat images\n"
00143 " %-21s A master dark frame\n"
00144 " %-21s Optional reference twilight flat frame\n"
00145 " %-21s Optional channel table or\n"
00146 " %-21s Optional initial channel table\n"
00147 " %-21s Optional master bad pixel map or\n"
00148 " %-21s Optional master confidence map\n"
00149 "If no reference twilight flat is made available, then no comparison will be\n"
00150 "done. This means there will be no output ratio image. If a master twilight\n"
00151 "is available, but no channel table is, then a ratio image will be formed\n"
00152 "but no stats will be written."
00153 "\n";
00154
00297
00298
00299
00307
00308
00309 int cpl_plugin_get_info(cpl_pluginlist *list) {
00310 cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
00311 cpl_plugin *plugin = &recipe->interface;
00312 char alldesc[SZ_ALLDESC];
00313 (void)snprintf(alldesc,SZ_ALLDESC,vircam_twilight_flat_combine_description,
00314 VIRCAM_TWI_RAW,VIRCAM_CAL_DARK,VIRCAM_REF_TWILIGHT_FLAT,
00315 VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT,VIRCAM_CAL_BPM,
00316 VIRCAM_CAL_CONF);
00317
00318 cpl_plugin_init(plugin,
00319 CPL_PLUGIN_API,
00320 VIRCAM_BINARY_VERSION,
00321 CPL_PLUGIN_TYPE_RECIPE,
00322 "vircam_twilight_flat_combine",
00323 "VIRCAM twilight combination recipe",
00324 alldesc,
00325 "Jim Lewis",
00326 "jrl@ast.cam.ac.uk",
00327 vircam_get_license(),
00328 vircam_twilight_flat_combine_create,
00329 vircam_twilight_flat_combine_exec,
00330 vircam_twilight_flat_combine_destroy);
00331
00332 cpl_pluginlist_append(list,plugin);
00333
00334 return(0);
00335 }
00336
00337
00346
00347
00348 static int vircam_twilight_flat_combine_create(cpl_plugin *plugin) {
00349 cpl_recipe *recipe;
00350 cpl_parameter *p;
00351
00352
00353
00354 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00355 recipe = (cpl_recipe *)plugin;
00356 else
00357 return(-1);
00358
00359
00360
00361 recipe->parameters = cpl_parameterlist_new();
00362
00363
00364
00365 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.lthr",
00366 CPL_TYPE_DOUBLE,
00367 "Low rejection threshold for underexpsed images",
00368 "vircam.vircam_twilight_flat_combine",
00369 4000.0);
00370 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"lthr");
00371 cpl_parameterlist_append(recipe->parameters,p);
00372
00373
00374
00375 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.hthr",
00376 CPL_TYPE_DOUBLE,
00377 "High rejection threshold for overexposed images",
00378 "vircam.vircam_twilight_flat_combine",
00379 12000.0);
00380 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"hthr");
00381 cpl_parameterlist_append(recipe->parameters,p);
00382
00383
00384
00385 p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.combtype",
00386 CPL_TYPE_INT,
00387 "1 == Median,\n 2 == Mean",
00388 "vircam.vircam_twilight_flat_combine",
00389 1,1,2);
00390 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
00391 cpl_parameterlist_append(recipe->parameters,p);
00392
00393
00394
00395 p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.scaletype",
00396 CPL_TYPE_INT,
00397 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
00398 "vircam.vircam_twilight_flat_combine",
00399 2,0,3);
00400 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
00401 cpl_parameterlist_append(recipe->parameters,p);
00402
00403
00404
00405 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.xrej",
00406 CPL_TYPE_BOOL,
00407 "True if using extra rejection cycle",
00408 "vircam.vircam_twilight_flat_combine",
00409 TRUE);
00410 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
00411 cpl_parameterlist_append(recipe->parameters,p);
00412
00413
00414
00415 p = cpl_parameter_new_value("vircam.vircam_twilight_flat_combine.thresh",
00416 CPL_TYPE_DOUBLE,
00417 "Rejection threshold in sigma above background",
00418 "vircam.vircam_twilight_flat_combine",5.0);
00419 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
00420 cpl_parameterlist_append(recipe->parameters,p);
00421
00422
00423
00424 p = cpl_parameter_new_enum("vircam.vircam_twilight_flat_combine.ncells",
00425 CPL_TYPE_INT,
00426 "Number of cells for data channel stats",
00427 "vircam.vircam_twilight_flat_combine",8,7,1,2,4,
00428 8,16,32,64);
00429 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
00430 cpl_parameterlist_append(recipe->parameters,p);
00431
00432
00433
00434 p = cpl_parameter_new_range("vircam.vircam_twilight_flat_combine.extenum",
00435 CPL_TYPE_INT,
00436 "Extension number to be done, 0 == all",
00437 "vircam.vircam_twilight_flat_combine",
00438 1,0,16);
00439 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00440 cpl_parameterlist_append(recipe->parameters,p);
00441
00442
00443
00444 return(0);
00445 }
00446
00447
00448
00454
00455
00456 static int vircam_twilight_flat_combine_exec(cpl_plugin *plugin) {
00457 cpl_recipe *recipe;
00458
00459
00460
00461 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00462 recipe = (cpl_recipe *)plugin;
00463 else
00464 return(-1);
00465
00466 return(vircam_twilight_flat_combine(recipe->parameters,recipe->frames));
00467 }
00468
00469
00475
00476
00477 static int vircam_twilight_flat_combine_destroy(cpl_plugin *plugin) {
00478 cpl_recipe *recipe ;
00479
00480
00481
00482 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00483 recipe = (cpl_recipe *)plugin;
00484 else
00485 return(-1);
00486
00487 cpl_parameterlist_delete(recipe->parameters);
00488 return(0);
00489 }
00490
00491
00498
00499
00500 static int vircam_twilight_flat_combine(cpl_parameterlist *parlist,
00501 cpl_frameset *framelist) {
00502 const char *fctid="vircam_twilight_flat_combine";
00503 int nlab,j,jst,jfn,retval,status,live,nx,ny,ndit,npts;
00504 long i;
00505 cpl_parameter *p;
00506 vir_fits *ff;
00507 cpl_propertylist *pp;
00508 cpl_image *im1,*im2,*newim,*diffim;
00509 double val1,val2,scl;
00510 float *data,med,mad;
00511 unsigned char *bpm;
00512
00513
00514
00515 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00516 cpl_msg_error(fctid,"Input framelist NULL or has no input data\n");
00517 return(-1);
00518 }
00519
00520
00521
00522 if (vircam_frameset_fexists(framelist) != VIR_OK) {
00523 cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00524 return(-1);
00525 }
00526
00527
00528
00529 vircam_twilight_flat_combine_init();
00530 we_expect = MEANTWI + CONFMAP;
00531
00532
00533
00534 p = cpl_parameterlist_find(parlist,"vircam.vircam_twilight_flat_combine.lthr");
00535 vircam_twilight_flat_combine_config.lthr =
00536 (float)cpl_parameter_get_double(p);
00537 p = cpl_parameterlist_find(parlist,
00538 "vircam.vircam_twilight_flat_combine.hthr");
00539 vircam_twilight_flat_combine_config.hthr =
00540 (float)cpl_parameter_get_double(p);
00541 p = cpl_parameterlist_find(parlist,
00542 "vircam.vircam_twilight_flat_combine.combtype");
00543 vircam_twilight_flat_combine_config.combtype = cpl_parameter_get_int(p);
00544 p = cpl_parameterlist_find(parlist,
00545 "vircam.vircam_twilight_flat_combine.scaletype");
00546 vircam_twilight_flat_combine_config.scaletype = cpl_parameter_get_int(p);
00547 p = cpl_parameterlist_find(parlist,
00548 "vircam.vircam_twilight_flat_combine.xrej");
00549 vircam_twilight_flat_combine_config.xrej = cpl_parameter_get_bool(p);
00550 p = cpl_parameterlist_find(parlist,
00551 "vircam.vircam_twilight_flat_combine.thresh");
00552 vircam_twilight_flat_combine_config.thresh =
00553 (float)cpl_parameter_get_double(p);
00554 p = cpl_parameterlist_find(parlist,
00555 "vircam.vircam_twilight_flat_combine.ncells");
00556 vircam_twilight_flat_combine_config.ncells = cpl_parameter_get_int(p);
00557 p = cpl_parameterlist_find(parlist,
00558 "vircam.vircam_twilight_flat_combine.extenum");
00559 vircam_twilight_flat_combine_config.extenum = cpl_parameter_get_int(p);
00560
00561
00562
00563 if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00564 cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00565 vircam_twilight_flat_combine_tidy(2);
00566 return(-1);
00567 }
00568
00569
00570
00571 if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00572 &nlab)) == NULL) {
00573 cpl_msg_error(fctid,"Cannot labelise the input frames");
00574 vircam_twilight_flat_combine_tidy(2);
00575 return(-1);
00576 }
00577 if ((ps.twilightlist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00578 VIRCAM_TWI_RAW)) == NULL) {
00579 cpl_msg_error(fctid,"Cannot find twilight frames in input frameset");
00580 vircam_twilight_flat_combine_tidy(2);
00581 return(-1);
00582 }
00583 ps.ntwilights = cpl_frameset_get_size(ps.twilightlist);
00584
00585
00586
00587 if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00588 VIRCAM_CAL_DARK)) == NULL) {
00589 cpl_msg_error(fctid,"No master dark found");
00590 vircam_twilight_flat_combine_tidy(2);
00591 return(-1);
00592 }
00593
00594
00595
00596 if ((ps.master_twilight_flat = vircam_frameset_subgroup_1(framelist,
00597 ps.labels,nlab,VIRCAM_REF_TWILIGHT_FLAT)) == NULL)
00598 cpl_msg_info(fctid,"No master twilight flat found -- no ratio image will be formed");
00599 else
00600 we_expect |= RATIMG;
00601
00602
00603
00604
00605 ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00606
00607
00608
00609 if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00610 VIRCAM_CAL_CHANTAB)) == NULL) {
00611 if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00612 VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
00613 cpl_msg_info(fctid,"No channel table found -- no ratio image stats and no linearisation will be done");
00614 } else {
00615 cpl_msg_info(fctid,"Channel table is labelled INIT -- no linearisation will be done");
00616 if (we_expect & RATIMG)
00617 we_expect |= STATS_TAB;
00618 }
00619 } else if (we_expect & RATIMG) {
00620 we_expect |= STATS_TAB;
00621 }
00622
00623
00624
00625 pp = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_frame(ps.twilightlist,0)),0);
00626 if (vircam_pfits_get_ndit(pp,&ndit) != VIR_OK) {
00627 cpl_msg_error(fctid,"No value for NDIT available");
00628 freepropertylist(pp);
00629 vircam_twilight_flat_combine_tidy(2);
00630 return(-1);
00631 }
00632 cpl_propertylist_delete(pp);
00633
00634
00635
00636
00637
00638 vircam_exten_range(vircam_twilight_flat_combine_config.extenum,
00639 (const cpl_frame *)cpl_frameset_get_frame(ps.twilightlist,0),
00640 &jst,&jfn);
00641 if (jst == -1 || jfn == -1) {
00642 cpl_msg_error(fctid,"Unable to continue");
00643 vircam_twilight_flat_combine_tidy(2);
00644 return(-1);
00645 }
00646
00647
00648
00649 ps.good = cpl_malloc(ps.ntwilights*sizeof(vir_fits *));
00650
00651
00652
00653 for (j = jst; j <= jfn; j++) {
00654 status = VIR_OK;
00655 we_get = 0;
00656 isfirst = (j == jst);
00657
00658
00659
00660 ps.twilights = vircam_fits_load_list(ps.twilightlist,CPL_TYPE_FLOAT,j);
00661 if (ps.twilights == NULL) {
00662 cpl_msg_info(fctid,"Extension %d twilights wouldn't load",j);
00663 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00664 if (retval != 0)
00665 return(-1);
00666 continue;
00667 }
00668
00669
00670
00671 ps.ngood = 0;
00672 for (i = 0; i < ps.ntwilights; i++) {
00673 ff = ps.twilights[i];
00674 vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00675 if (! live) {
00676 cpl_msg_info(fctid,"Detector flagged dead %s",
00677 vircam_fits_get_fullname(ff));
00678 vircam_fits_set_error(ff,VIR_FATAL);
00679 } else {
00680 ps.good[ps.ngood] = ff;
00681 ps.ngood += 1;
00682 }
00683 }
00684
00685
00686
00687
00688 if (ps.ngood == 0) {
00689 cpl_msg_info(fctid,"All images flagged bad for this extension");
00690 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00691 if (retval != 0)
00692 return(-1);
00693 continue;
00694 }
00695
00696
00697
00698 vircam_overexp(ps.good,&(ps.ngood),ndit,
00699 vircam_twilight_flat_combine_config.lthr,
00700 vircam_twilight_flat_combine_config.hthr,0,
00701 &(vircam_twilight_flat_combine_config.minv),
00702 &(vircam_twilight_flat_combine_config.maxv),
00703 &(vircam_twilight_flat_combine_config.avev));
00704
00705
00706
00707
00708 if (ps.ngood == 0) {
00709 cpl_msg_info(fctid,"All images either under or overexposed");
00710 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00711 if (retval != 0)
00712 return(-1);
00713 continue;
00714 }
00715
00716
00717
00718 nx = cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00719 ny = cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00720 if (vircam_mask_load(ps.master_mask,j,nx,ny) == VIR_FATAL) {
00721 cpl_msg_info(fctid,"Unable to load mask image %s[%d]",
00722 vircam_mask_get_filename(ps.master_mask),j);
00723 cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00724 vircam_mask_force(ps.master_mask,nx,ny);
00725 }
00726
00727
00728
00729
00730 if (ps.ngood > 1) {
00731 i = ps.ngood/2 - 1;
00732 im1 = vircam_fits_get_image(ps.good[i]);
00733 im2 = vircam_fits_get_image(ps.good[i+1]);
00734 val1 = cpl_image_get_median_window(im1,500,500,1000,1000);
00735 val2 = cpl_image_get_median_window(im2,500,500,1000,1000);
00736 val1 /= (double)ndit;
00737 val2 /= (double)ndit;
00738 scl = val1/val2;
00739 newim = cpl_image_multiply_scalar_create(im2,scl);
00740 diffim = cpl_image_subtract_create(im1,newim);
00741 cpl_image_delete(newim);
00742 data = cpl_image_get_data_float(diffim);
00743 bpm = vircam_mask_get_data(ps.master_mask);
00744 npts = nx*ny;
00745 vircam_medmad(data,bpm,npts,&med,&mad);
00746 mad *= 1.48/M_SQRT2;
00747 vircam_twilight_flat_combine_config.photnoise = mad;
00748 vircam_twilight_flat_combine_config.snratio =
00749 val1*sqrt((double)(ps.ngood))/mad;
00750 cpl_image_delete(diffim);
00751 } else {
00752 vircam_twilight_flat_combine_config.photnoise = 0.0;
00753 vircam_twilight_flat_combine_config.snratio = 0.0;
00754 }
00755
00756
00757
00758
00759 ps.mdark = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,j);
00760 if (ps.mdark == NULL) {
00761 cpl_msg_info(fctid,"Can't load master dark for extension %d",j);
00762 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00763 if (retval != 0)
00764 return(-1);
00765 continue;
00766 } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdark))) {
00767 cpl_msg_info(fctid,"Can't master dark extension %d is a dummy",j);
00768 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00769 if (retval != 0)
00770 return(-1);
00771 continue;
00772 }
00773
00774
00775
00776 cpl_msg_info(fctid,"Dark correcting extension %d\n",j);
00777 for (i = 0; i < ps.ngood; i++)
00778 vircam_darkcor((ps.good)[i],ps.mdark,1.0,&status);
00779
00780
00781
00782
00783 if (ps.chantab != NULL) {
00784 ps.ctable = vircam_tfits_load(ps.chantab,j);
00785 if (ps.ctable == NULL) {
00786 cpl_msg_info(fctid,"Channel table extension %d won't load",j);
00787 } else if (vircam_chantab_verify(vircam_tfits_get_table(ps.ctable)) != VIR_OK) {
00788 cpl_msg_info(fctid,"Channel table extension %d has errors",j);
00789 freetfits(ps.ctable);
00790 } else {
00791 pp = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
00792 j);
00793 if (vircam_is_dummy(pp)) {
00794 cpl_msg_info(fctid,
00795 "Channel table extensions %d is a dummy",j);
00796 freetfits(ps.ctable);
00797 }
00798 freepropertylist(pp);
00799 }
00800 } else
00801 ps.ctable = NULL;
00802
00803
00804
00805
00806 if (ps.ctable != NULL) {
00807 cpl_msg_info(fctid,"Linearising extension %d\n",j);
00808 for (i = 0; i < ps.ngood; i++)
00809 (void)vircam_lincor((ps.good)[i],ps.ctable,1,ndit,&status);
00810 }
00811
00812
00813
00814 for (i = 0; i < ps.ngood; i++)
00815 (void)vircam_nditcor((ps.good)[i],ndit,&status);
00816
00817
00818
00819 cpl_msg_info(fctid,"Doing combination for extension %d\n",j);
00820 (void)vircam_imcombine(ps.good,ps.ngood,
00821 vircam_twilight_flat_combine_config.combtype,
00822 vircam_twilight_flat_combine_config.scaletype,
00823 vircam_twilight_flat_combine_config.xrej,
00824 vircam_twilight_flat_combine_config.thresh,
00825 &(ps.outimage),&(ps.rejmask),&(ps.rejplus),
00826 &(ps.drs),&status);
00827
00828
00829
00830
00831 if (status == VIR_OK) {
00832 we_get |= MEANTWI;
00833 vircam_twilight_flat_combine_normal(j);
00834 } else {
00835 cpl_msg_info(fctid,"A processing step failed");
00836 }
00837
00838
00839
00840 retval = vircam_twilight_flat_combine_lastbit(j,framelist,parlist);
00841 if (retval != 0)
00842 return(-1);
00843
00844 }
00845 vircam_twilight_flat_combine_tidy(2);
00846 return(0);
00847 }
00848
00849
00850
00857
00858
00859 static int vircam_twilight_flat_combine_save(cpl_frameset *framelist,
00860 cpl_parameterlist *parlist) {
00861 cpl_propertylist *plist,*elist,*p,*pafprop;
00862 int status;
00863 float val;
00864 const char *fctid = "vircam_twilight_flat_combine_save";
00865 const char *outfile = "twilightcomb.fits";
00866 const char *outdiff = "twilightratio.fits";
00867 const char *outdimst = "twilightratiotab.fits";
00868 const char *outconf = "twilightconf.fits";
00869 const char *outfilepaf = "twilightcomb";
00870 const char *outdiffpaf = "twilightratio";
00871 const char *recipeid = "vircam_twilight_flat_combine";
00872
00873
00874
00875
00876 if (isfirst) {
00877
00878
00879
00880 product_frame_mean_twi = cpl_frame_new();
00881 cpl_frame_set_filename(product_frame_mean_twi,outfile);
00882 cpl_frame_set_tag(product_frame_mean_twi,VIRCAM_PRO_TWILIGHT_FLAT);
00883 cpl_frame_set_type(product_frame_mean_twi,CPL_FRAME_TYPE_IMAGE);
00884 cpl_frame_set_group(product_frame_mean_twi,CPL_FRAME_GROUP_PRODUCT);
00885 cpl_frame_set_level(product_frame_mean_twi,CPL_FRAME_LEVEL_FINAL);
00886
00887
00888
00889 plist = vircam_fits_get_phu(ps.twilights[0]);
00890 ps.phupaf = vircam_paf_phu_items(plist);
00891 if (ps.master_twilight_flat != NULL) {
00892 cpl_propertylist_update_string(ps.phupaf,"REF_TWILIGHT",
00893 cpl_frame_get_filename(ps.master_twilight_flat));
00894 cpl_propertylist_set_comment(ps.phupaf,"REF_TWILIGHT",
00895 "Reference twilight flat used");
00896 }
00897 vircam_dfs_set_product_primary_header(plist,product_frame_mean_twi,
00898 framelist,parlist,
00899 (char *)recipeid,
00900 "PRO-1.15",NULL,0);
00901
00902
00903
00904 if (cpl_image_save(NULL,outfile,CPL_BPP_8_UNSIGNED,plist,
00905 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00906 cpl_msg_error(fctid,"Cannot save product PHU");
00907 cpl_frame_delete(product_frame_mean_twi);
00908 return(-1);
00909 }
00910 cpl_frameset_insert(framelist,product_frame_mean_twi);
00911
00912
00913
00914
00915 product_frame_conf = cpl_frame_new();
00916 cpl_frame_set_filename(product_frame_conf,outconf);
00917 cpl_frame_set_tag(product_frame_conf,VIRCAM_PRO_CONF);
00918 cpl_frame_set_type(product_frame_conf,CPL_FRAME_TYPE_IMAGE);
00919 cpl_frame_set_group(product_frame_conf,CPL_FRAME_GROUP_PRODUCT);
00920 cpl_frame_set_level(product_frame_conf,CPL_FRAME_LEVEL_FINAL);
00921
00922
00923
00924 plist = vircam_fits_get_phu(ps.twilights[0]);
00925 vircam_dfs_set_product_primary_header(plist,product_frame_conf,
00926 framelist,parlist,
00927 (char *)recipeid,"PRO-1.15",
00928 NULL,0);
00929
00930
00931
00932 if (cpl_image_save(NULL,outconf,CPL_BPP_8_UNSIGNED,plist,
00933 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00934 cpl_msg_error(fctid,"Cannot save product PHU");
00935 cpl_frame_delete(product_frame_conf);
00936 return(-1);
00937 }
00938 cpl_frameset_insert(framelist,product_frame_conf);
00939
00940
00941
00942 if (we_expect & RATIMG) {
00943 product_frame_ratioimg = cpl_frame_new();
00944 cpl_frame_set_filename(product_frame_ratioimg,outdiff);
00945 cpl_frame_set_tag(product_frame_ratioimg,
00946 VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT);
00947 cpl_frame_set_type(product_frame_ratioimg,CPL_FRAME_TYPE_IMAGE);
00948 cpl_frame_set_group(product_frame_ratioimg,
00949 CPL_FRAME_GROUP_PRODUCT);
00950 cpl_frame_set_level(product_frame_ratioimg,CPL_FRAME_LEVEL_FINAL);
00951
00952
00953
00954 plist = vircam_fits_get_phu(ps.twilights[0]);
00955 vircam_dfs_set_product_primary_header(plist,product_frame_ratioimg,
00956 framelist,parlist,
00957 (char *)recipeid,"PRO-1.15",
00958 NULL,0);
00959
00960
00961
00962 if (cpl_image_save(NULL,outdiff,CPL_BPP_8_UNSIGNED,plist,
00963 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00964 cpl_msg_error(fctid,"Cannot save product PHU");
00965 cpl_frame_delete(product_frame_ratioimg);
00966 return(-1);
00967 }
00968 cpl_frameset_insert(framelist,product_frame_ratioimg);
00969 }
00970
00971
00972
00973
00974 if (we_expect & STATS_TAB) {
00975 product_frame_ratioimg_stats = cpl_frame_new();
00976 cpl_frame_set_filename(product_frame_ratioimg_stats,outdimst);
00977 cpl_frame_set_tag(product_frame_ratioimg_stats,
00978 VIRCAM_PRO_RATIOIMG_TWILIGHT_FLAT_STATS);
00979 cpl_frame_set_type(product_frame_ratioimg_stats,
00980 CPL_FRAME_TYPE_TABLE);
00981 cpl_frame_set_group(product_frame_ratioimg_stats,
00982 CPL_FRAME_GROUP_PRODUCT);
00983 cpl_frame_set_level(product_frame_ratioimg_stats,
00984 CPL_FRAME_LEVEL_FINAL);
00985
00986
00987
00988 plist = vircam_fits_get_phu(ps.twilights[0]);
00989 vircam_dfs_set_product_primary_header(plist,
00990 product_frame_ratioimg_stats,
00991 framelist,parlist,
00992 (char *)recipeid,"PRO-1.15",
00993 NULL,0);
00994
00995
00996
00997 elist = vircam_fits_get_ehu(ps.twilights[0]);
00998 p = cpl_propertylist_duplicate(elist);
00999 vircam_merge_propertylists(p,ps.drs);
01000 if (! (we_get & STATS_TAB))
01001 vircam_dummy_property(p);
01002 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01003 framelist,parlist,
01004 (char *)recipeid,
01005 "PRO-1.15",NULL);
01006 status = VIR_OK;
01007 vircam_removewcs(p,&status);
01008
01009
01010
01011 if (cpl_table_save(ps.ratioimstats,plist,p,outdimst,
01012 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
01013 cpl_msg_error(fctid,"Cannot save product table extension");
01014 cpl_propertylist_delete(p);
01015 return(-1);
01016 }
01017 cpl_propertylist_delete(p);
01018 cpl_frameset_insert(framelist,product_frame_ratioimg_stats);
01019 }
01020 }
01021
01022
01023
01024 plist = vircam_fits_get_ehu(ps.twilights[0]);
01025 vircam_merge_propertylists(plist,ps.drs);
01026 cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
01027
01028
01029
01030 p = cpl_propertylist_duplicate(plist);
01031 if (! (we_get & MEANTWI))
01032 vircam_dummy_property(p);
01033 vircam_dfs_set_product_exten_header(p,product_frame_mean_twi,framelist,
01034 parlist,(char *)recipeid,
01035 "PRO-1.15",NULL);
01036
01037
01038
01039 cpl_propertylist_update_float(p,"ESO QC FLATRMS",
01040 vircam_twilight_flat_combine_config.flatrms);
01041 cpl_propertylist_set_comment(p,"ESO QC FLATRMS","RMS of output flat");
01042 cpl_propertylist_update_float(p,"ESO QC FLATMIN",
01043 vircam_twilight_flat_combine_config.minv);
01044 cpl_propertylist_set_comment(p,"ESO QC FLATMIN","Ensemble minimum");
01045 cpl_propertylist_update_float(p,"ESO QC FLATMAX",
01046 vircam_twilight_flat_combine_config.maxv);
01047 cpl_propertylist_set_comment(p,"ESO QC FLATMAX","Ensemble maximum");
01048 cpl_propertylist_update_float(p,"ESO QC FLATAVG",
01049 vircam_twilight_flat_combine_config.avev);
01050 cpl_propertylist_set_comment(p,"ESO QC FLATAVG","Ensemble average");
01051 val = vircam_twilight_flat_combine_config.maxv -
01052 vircam_twilight_flat_combine_config.minv;
01053 cpl_propertylist_update_float(p,"ESO QC FLATRNG",val);
01054 cpl_propertylist_set_comment(p,"ESO QC FLATRNG","Ensemble range");
01055 cpl_propertylist_update_float(p,"ESO QC TWIPHOT",
01056 vircam_twilight_flat_combine_config.photnoise);
01057 cpl_propertylist_set_comment(p,"ESO QC TWIPHOT",
01058 "[adu] Estimated photon noise");
01059 cpl_propertylist_update_float(p,"ESO QC TWISNRATIO",
01060 vircam_twilight_flat_combine_config.snratio);
01061 cpl_propertylist_set_comment(p,"ESO QC TWISNRATIO","Estimated S/N ratio");
01062 if (cpl_image_save(ps.outimage,outfile,CPL_BPP_IEEE_FLOAT,p,
01063 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01064 cpl_msg_error(fctid,"Cannot save product image extension");
01065 cpl_propertylist_delete(p);
01066 return(-1);
01067 }
01068
01069
01070
01071 pafprop = vircam_paf_req_items(p);
01072 vircam_merge_propertylists(pafprop,ps.phupaf);
01073 vircam_paf_append(pafprop,vircam_fits_get_phu(ps.twilights[0]),
01074 "ESO INS FILT1 NAME");
01075 vircam_paf_append(pafprop,p,"ESO PRO CATG");
01076 vircam_paf_append(pafprop,p,"ESO PRO DATANCOM");
01077 vircam_paf_append(pafprop,p,"ESO DET NDIT");
01078 if (vircam_paf_print((char *)outfilepaf,
01079 "VIRCAM/vircam_twilight_flat_combine",
01080 "QC file",pafprop) != VIR_OK)
01081 cpl_msg_warning(fctid,"Unable to save PAF for mean twilight");
01082 cpl_propertylist_delete(pafprop);
01083 cpl_propertylist_delete(p);
01084
01085
01086
01087 if (we_expect & RATIMG) {
01088 p = cpl_propertylist_duplicate(plist);
01089 if (! (we_get & RATIMG))
01090 vircam_dummy_property(p);
01091 cpl_propertylist_update_float(p,"ESO QC FLATRATIO_MED",
01092 vircam_twilight_flat_combine_config.flatratio_med);
01093 cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_MED",
01094 "Median of ratio map");
01095 cpl_propertylist_update_float(p,"ESO QC FLATRATIO_RMS",
01096 vircam_twilight_flat_combine_config.flatratio_rms);
01097 cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_RMS",
01098 "RMS of ratio map");
01099 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg,
01100 framelist,parlist,(char *)recipeid,
01101 "PRO-1.15",NULL);
01102 if (cpl_image_save(ps.ratioimg,outdiff,CPL_BPP_IEEE_FLOAT,p,
01103 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01104 cpl_propertylist_delete(p);
01105 cpl_msg_error(fctid,"Cannot save product image extension");
01106 return(-1);
01107 }
01108
01109
01110
01111 pafprop = vircam_paf_req_items(p);
01112 vircam_merge_propertylists(pafprop,ps.phupaf);
01113 vircam_paf_append(pafprop,vircam_fits_get_phu(ps.twilights[0]),
01114 "ESO INS FILT1 NAME");
01115 vircam_paf_append(pafprop,p,"ESO PRO CATG");
01116 if (vircam_paf_print((char *)outdiffpaf,
01117 "VIRCAM/vircam_twilight_flat_combine",
01118 "QC file",pafprop) != VIR_OK)
01119 cpl_msg_warning(fctid,"Unable to save PAF for twilight ratio image");
01120 cpl_propertylist_delete(pafprop);
01121 cpl_propertylist_delete(p);
01122 }
01123
01124
01125
01126 if (! isfirst && (we_expect & STATS_TAB)) {
01127 p = cpl_propertylist_duplicate(plist);
01128 if (! (we_get & STATS_TAB))
01129 vircam_dummy_property(p);
01130 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01131 framelist,parlist,(char *)recipeid,
01132 "PRO-1.15",NULL);
01133 status = VIR_OK;
01134 vircam_removewcs(p,&status);
01135 if (cpl_table_save(ps.ratioimstats,NULL,p,outdimst,CPL_IO_EXTEND)
01136 != CPL_ERROR_NONE) {
01137 cpl_msg_error(fctid,"Cannot save product table extension");
01138 cpl_propertylist_delete(p);
01139 return(-1);
01140 }
01141 cpl_propertylist_delete(p);
01142 }
01143
01144
01145
01146 vircam_merge_propertylists(plist,ps.drs2);
01147 p = cpl_propertylist_duplicate(plist);
01148 if (! (we_get & CONFMAP))
01149 vircam_dummy_property(p);
01150
01151
01152
01153 vircam_dfs_set_product_exten_header(p,product_frame_conf,framelist,
01154 parlist,(char *)recipeid,"PRO-1.15",
01155 NULL);
01156 if (cpl_image_save(ps.outconf,outconf,CPL_BPP_16_SIGNED,p,
01157 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01158 cpl_msg_error(fctid,"Cannot save product image extension");
01159 cpl_propertylist_delete(p);
01160 return(-1);
01161 }
01162 cpl_propertylist_delete(p);
01163
01164
01165
01166 return(0);
01167 }
01168
01169
01173
01174
01175 static void vircam_twilight_flat_combine_dummy_products(void) {
01176
01177
01178
01179 if (we_get == we_expect)
01180 return;
01181
01182
01183
01184 if (! (we_get & MEANTWI)) {
01185 ps.outimage = vircam_dummy_image(ps.twilights[0]);
01186 vircam_twilight_flat_combine_config.flatrms = 0.0;
01187 }
01188
01189
01190
01191 if (! (we_get & CONFMAP)) {
01192 ps.outconf = vircam_dummy_image(ps.twilights[0]);
01193 vircam_twilight_flat_combine_config.flatrms = 0.0;
01194 }
01195
01196
01197
01198 if ((we_expect & RATIMG) && ! (we_get & RATIMG)) {
01199 vircam_twilight_flat_combine_config.flatratio_med = 0.0;
01200 vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
01201 ps.ratioimg = vircam_dummy_image(ps.twilights[0]);
01202 }
01203
01204
01205
01206 if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
01207 ps.ratioimstats = vircam_create_diffimg_stats(0);
01208
01209 return;
01210 }
01211
01212
01217
01218
01219 static void vircam_twilight_flat_combine_normal(int jext) {
01220 int nx,ny,ncells,status;
01221 long i,npi;
01222 unsigned char *bpm;
01223 float *idata,med,sig,gdiff,grms;
01224 const char *fctid="vircam_twilight_flat_combine_normal";
01225
01226
01227
01228 nx = cpl_image_get_size_x(ps.outimage);
01229 ny = cpl_image_get_size_y(ps.outimage);
01230 npi = nx*ny;
01231 vircam_mask_load(ps.master_mask,jext,nx,ny);
01232 bpm = vircam_mask_get_data(ps.master_mask);
01233
01234
01235
01236 status = VIR_OK;
01237 (void)vircam_mkconf(ps.outimage,(char *)"None Available",ps.master_mask,
01238 &(ps.outconf),&(ps.drs2),&status);
01239 if (status == VIR_OK)
01240 we_get |= CONFMAP;
01241 else {
01242 cpl_msg_info(fctid,"Confidence map creation failed extension %d",jext);
01243 status = VIR_OK;
01244 }
01245
01246
01247
01248 idata = cpl_image_get_data(ps.outimage);
01249 vircam_medsig(idata,bpm,npi,&med,&sig);
01250
01251
01252
01253 for (i = 0; i < npi; i++)
01254 if (bpm[i])
01255 idata[i] = med;
01256
01257
01258
01259 cpl_propertylist_update_float(ps.drs,"ESO DRS MEDFLAT",med);
01260 cpl_propertylist_set_comment(ps.drs,"ESO DRS MEDFLAT",
01261 "Median value before normalisation");
01262 cpl_image_divide_scalar(ps.outimage,med);
01263 vircam_medmad(idata,bpm,npi,&med,&sig);
01264 sig *= 1.48;
01265 vircam_twilight_flat_combine_config.flatrms = sig;
01266
01267
01268
01269 if (ps.master_twilight_flat != NULL) {
01270 ps.mfimage = vircam_fits_load(ps.master_twilight_flat,CPL_TYPE_FLOAT,jext);
01271 if (ps.mfimage == NULL) {
01272 cpl_msg_info(fctid,"Master twilight extension %d won't load",jext);
01273 } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mfimage))) {
01274 cpl_msg_info(fctid,"Master twilight extension %d is a dummy",jext);
01275 freefits(ps.mfimage);
01276 }
01277 } else
01278 ps.mfimage = NULL;
01279
01280
01281
01282
01283
01284
01285
01286
01287 vircam_twilight_flat_combine_config.flatratio_med = 0.0;
01288 vircam_twilight_flat_combine_config.flatratio_rms = 0.0;
01289 ncells = vircam_twilight_flat_combine_config.ncells;
01290 vircam_difference_image(vircam_fits_get_image(ps.mfimage),ps.outimage,bpm,
01291 vircam_tfits_get_table(ps.ctable),ncells,2,
01292 &gdiff,&grms,&(ps.ratioimg),
01293 &(ps.ratioimstats));
01294 vircam_mask_clear(ps.master_mask);
01295 vircam_twilight_flat_combine_config.flatratio_med = gdiff;
01296 vircam_twilight_flat_combine_config.flatratio_rms = grms;
01297 if (ps.ratioimg != NULL)
01298 we_get |= RATIMG;
01299 if (ps.ratioimstats != NULL)
01300 we_get |= STATS_TAB;
01301 return;
01302 }
01303
01304
01312
01313
01314
01315 static int vircam_twilight_flat_combine_lastbit(int jext,
01316 cpl_frameset *framelist,
01317 cpl_parameterlist *parlist) {
01318 int retval;
01319 const char *fctid="vircam_twilight_flat_combine_lastbit";
01320
01321
01322
01323 vircam_twilight_flat_combine_dummy_products();
01324
01325
01326
01327 cpl_msg_info(fctid,"Saving products for extension %d",jext);
01328 retval = vircam_twilight_flat_combine_save(framelist,parlist);
01329 if (retval != 0) {
01330 vircam_twilight_flat_combine_tidy(2);
01331 return(-1);
01332 }
01333
01334
01335
01336 vircam_twilight_flat_combine_tidy(1);
01337 return(0);
01338 }
01339
01340
01344
01345
01346 static void vircam_twilight_flat_combine_init(void) {
01347 ps.labels = NULL;
01348 ps.twilightlist = NULL;
01349 ps.twilights = NULL;
01350 ps.good = NULL;
01351 ps.master_dark = NULL;
01352 ps.master_twilight_flat = NULL;
01353 ps.master_mask = NULL;
01354 ps.chantab = NULL;
01355 ps.ctable = NULL;
01356 ps.outimage = NULL;
01357 ps.outconf = NULL;
01358 ps.drs = NULL;
01359 ps.drs2 = NULL;
01360 ps.rejmask = NULL;
01361 ps.rejplus = NULL;
01362 ps.mfimage = NULL;
01363 ps.ratioimg = NULL;
01364 ps.ratioimstats = NULL;
01365 ps.phupaf = NULL;
01366 }
01367
01368
01372
01373
01374 static void vircam_twilight_flat_combine_tidy(int level) {
01375 freeimage(ps.outimage);
01376 freeimage(ps.outconf);
01377 freefitslist(ps.twilights,ps.ntwilights);
01378 freepropertylist(ps.drs);
01379 freepropertylist(ps.drs2);
01380 freespace(ps.rejmask);
01381 freespace(ps.rejplus);
01382 freefits(ps.mfimage);
01383 freeimage(ps.ratioimg);
01384 freetable(ps.ratioimstats);
01385 freetfits(ps.ctable);
01386 freefits(ps.mdark);
01387 if (level == 1)
01388 return;
01389
01390 freespace(ps.good);
01391 freespace(ps.labels);
01392 freeframeset(ps.twilightlist);
01393 freeframe(ps.master_dark);
01394 freeframe(ps.master_twilight_flat);
01395 freemask(ps.master_mask);
01396 freeframe(ps.chantab);
01397 freepropertylist(ps.phupaf);
01398 }
01399
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576