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_pfits.h"
00041 #include "vircam_dfs.h"
00042 #include "vircam_mods.h"
00043 #include "vircam_stats.h"
00044 #include "vircam_fits.h"
00045 #include "vircam_tfits.h"
00046 #include "vircam_channel.h"
00047 #include "vircam_paf.h"
00048 #include "vircam_wcsutils.h"
00049
00050
00051
00052 #define MEANDOME 1
00053 #define RATIMG 2
00054 #define STATS_TAB 4
00055
00056
00057
00058 static int vircam_dome_flat_combine_create(cpl_plugin *) ;
00059 static int vircam_dome_flat_combine_exec(cpl_plugin *) ;
00060 static int vircam_dome_flat_combine_destroy(cpl_plugin *) ;
00061 static int vircam_dome_flat_combine(cpl_parameterlist *, cpl_frameset *) ;
00062 static int vircam_dome_flat_combine_save(cpl_frameset *framelist,
00063 cpl_parameterlist *parlist);
00064 static void vircam_dome_flat_combine_dummy_products(void);
00065 static void vircam_dome_flat_combine_normal(int jext);
00066 static int vircam_dome_flat_combine_lastbit(int jext, cpl_frameset *framelist,
00067 cpl_parameterlist *parlist);
00068 static void vircam_dome_flat_combine_init(void);
00069 static void vircam_dome_flat_combine_tidy(int level);
00070
00071
00072
00073 static struct {
00074
00075
00076
00077 float lthr;
00078 float hthr;
00079 int combtype;
00080 int scaletype;
00081 int xrej;
00082 float thresh;
00083 int ncells;
00084 int extenum;
00085
00086
00087
00088 float flatrms;
00089 float flatratio_med;
00090 float flatratio_rms;
00091 float minv;
00092 float maxv;
00093 float avev;
00094
00095 } vircam_dome_flat_combine_config;
00096
00097
00098 static struct {
00099 cpl_size *labels;
00100 cpl_frameset *domelist;
00101 cpl_frame *master_dark;
00102 cpl_frame *master_dome_flat;
00103 cpl_frame *chantab;
00104 vir_fits **good;
00105 int ngood;
00106 vir_mask *master_mask;
00107 cpl_image *outimage;
00108 vir_fits **domes;
00109 int ndomes;
00110 cpl_propertylist *drs;
00111 unsigned char *rejmask;
00112 unsigned char *rejplus;
00113 vir_tfits *ctable;
00114 vir_fits *mfimage;
00115 vir_fits *mdark;
00116 cpl_image *ratioimg;
00117 cpl_table *ratioimstats;
00118 cpl_propertylist *phupaf;
00119 } ps;
00120
00121 static int isfirst;
00122 static cpl_frame *product_frame_mean_dome = NULL;
00123 static cpl_frame *product_frame_ratioimg = NULL;
00124 static cpl_frame *product_frame_ratioimg_stats = NULL;
00125 static int we_expect;
00126 static int we_get;
00127
00128 static char vircam_dome_flat_combine_description[] =
00129 "vircam_dome_flat_combine -- VIRCAM dome flat combine recipe.\n\n"
00130 "Combine a list of dome flat frames into a mean frame. Optionally compare \n"
00131 "the output frame to a master dome flat frame\n\n"
00132 "The program accepts the following files in the SOF:\n\n"
00133 " Tag Description\n"
00134 " -----------------------------------------------------------------------\n"
00135 " %-21s A list of raw dome flat images\n"
00136 " %-21s A master dark frame\n"
00137 " %-21s Optional reference dome flat frame\n"
00138 " %-21s Optional channel table or\n"
00139 " %-21s Optional initial channel table\n"
00140 " %-21s Optional master bad pixel map or\n"
00141 " %-21s Optional master confidence map\n"
00142 "If no master dome flat is made available, then no comparison will be done\n"
00143 "This means there will be no output ratio image. If a master dome is\n"
00144 "available, but no channel table is, then a ratio image will be formed\n"
00145 "but no stats will be written."
00146 "\n";
00147
00281
00282
00283
00291
00292
00293 int cpl_plugin_get_info(cpl_pluginlist *list) {
00294 cpl_recipe *recipe = cpl_calloc(1,sizeof(*recipe));
00295 cpl_plugin *plugin = &recipe->interface;
00296 char alldesc[SZ_ALLDESC];
00297 (void)snprintf(alldesc,SZ_ALLDESC,vircam_dome_flat_combine_description,
00298 VIRCAM_DOME_RAW,VIRCAM_CAL_DARK,VIRCAM_REF_DOME_FLAT,
00299 VIRCAM_CAL_CHANTAB,VIRCAM_CAL_CHANTAB_INIT,VIRCAM_CAL_BPM,
00300 VIRCAM_CAL_CONF);
00301
00302 cpl_plugin_init(plugin,
00303 CPL_PLUGIN_API,
00304 VIRCAM_BINARY_VERSION,
00305 CPL_PLUGIN_TYPE_RECIPE,
00306 "vircam_dome_flat_combine",
00307 "VIRCAM dome flat combination recipe",
00308 alldesc,
00309 "Jim Lewis",
00310 "jrl@ast.cam.ac.uk",
00311 vircam_get_license(),
00312 vircam_dome_flat_combine_create,
00313 vircam_dome_flat_combine_exec,
00314 vircam_dome_flat_combine_destroy);
00315
00316 cpl_pluginlist_append(list,plugin);
00317
00318 return(0);
00319 }
00320
00321
00330
00331
00332 static int vircam_dome_flat_combine_create(cpl_plugin *plugin) {
00333 cpl_recipe *recipe;
00334 cpl_parameter *p;
00335
00336
00337
00338 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00339 recipe = (cpl_recipe *)plugin;
00340 else
00341 return(-1);
00342
00343
00344
00345 recipe->parameters = cpl_parameterlist_new();
00346
00347
00348
00349 p = cpl_parameter_new_value("vircam.vircam_dome_flat_combine.lthr",
00350 CPL_TYPE_DOUBLE,
00351 "Low rejection threshold for underexpsed images",
00352 "vircam.vircam_dome_flat_combine",
00353 0.0);
00354 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"lthr");
00355 cpl_parameterlist_append(recipe->parameters,p);
00356
00357
00358
00359 p = cpl_parameter_new_value("vircam.vircam_dome_flat_combine.hthr",
00360 CPL_TYPE_DOUBLE,
00361 "High rejection threshold for overexposed images",
00362 "vircam.vircam_dome_flat_combine",
00363 65535.0);
00364 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"hthr");
00365 cpl_parameterlist_append(recipe->parameters,p);
00366
00367
00368
00369 p = cpl_parameter_new_range("vircam.vircam_dome_flat_combine.combtype",
00370 CPL_TYPE_INT,
00371 "1 == Median,\n 2 == Mean",
00372 "vircam.vircam_dome_flat_combine",
00373 1,1,2);
00374 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"combtype");
00375 cpl_parameterlist_append(recipe->parameters,p);
00376
00377
00378
00379 p = cpl_parameter_new_range("vircam.vircam_dome_flat_combine.scaletype",
00380 CPL_TYPE_INT,
00381 "0 == none,\n 1 == additive offset,\n 2 == multiplicative offset,\n 3 == exposure time scaling + additive offset",
00382 "vircam.vircam_dome_flat_combine",
00383 1,0,3);
00384 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"scaletype");
00385 cpl_parameterlist_append(recipe->parameters,p);
00386
00387
00388
00389 p = cpl_parameter_new_value("vircam.vircam_dome_flat_combine.xrej",
00390 CPL_TYPE_BOOL,
00391 "True if using extra rejection cycle",
00392 "vircam.vircam_dome_flat_combine",
00393 TRUE);
00394 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"xrej");
00395 cpl_parameterlist_append(recipe->parameters,p);
00396
00397
00398
00399 p = cpl_parameter_new_value("vircam.vircam_dome_flat_combine.thresh",
00400 CPL_TYPE_DOUBLE,
00401 "Rejection threshold in sigma above background",
00402 "vircam.vircam_dome_flat_combine",5.0);
00403 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"thresh");
00404 cpl_parameterlist_append(recipe->parameters,p);
00405
00406
00407
00408 p = cpl_parameter_new_enum("vircam.vircam_dome_flat_combine.ncells",
00409 CPL_TYPE_INT,
00410 "Number of cells for data channel stats",
00411 "vircam.vircam_dome_flat_combine",8,7,1,2,4,8,
00412 16,32,64);
00413 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ncells");
00414 cpl_parameterlist_append(recipe->parameters,p);
00415
00416
00417
00418 p = cpl_parameter_new_range("vircam.vircam_dome_flat_combine.extenum",
00419 CPL_TYPE_INT,
00420 "Extension number to be done, 0 == all",
00421 "vircam.vircam_dome_flat_combine",
00422 1,0,16);
00423 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00424 cpl_parameterlist_append(recipe->parameters,p);
00425
00426
00427
00428 return(0);
00429 }
00430
00431
00432
00438
00439
00440 static int vircam_dome_flat_combine_exec(cpl_plugin *plugin) {
00441 cpl_recipe *recipe;
00442
00443
00444
00445 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00446 recipe = (cpl_recipe *)plugin;
00447 else
00448 return(-1);
00449
00450 return(vircam_dome_flat_combine(recipe->parameters,recipe->frames));
00451 }
00452
00453
00459
00460
00461 static int vircam_dome_flat_combine_destroy(cpl_plugin *plugin) {
00462 cpl_recipe *recipe ;
00463
00464
00465
00466 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00467 recipe = (cpl_recipe *)plugin;
00468 else
00469 return(-1);
00470
00471 cpl_parameterlist_delete(recipe->parameters);
00472 return(0);
00473 }
00474
00475
00482
00483
00484 static int vircam_dome_flat_combine(cpl_parameterlist *parlist,
00485 cpl_frameset *framelist) {
00486 const char *fctid="vircam_dome_flat_combine";
00487 int j,jst,jfn,retval,status,live,nx,ny,ndit;
00488 cpl_size nlab;
00489 long i;
00490 cpl_parameter *p;
00491 cpl_propertylist *pp;
00492 vir_fits *ff;
00493
00494
00495
00496 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00497 cpl_msg_error(fctid,"Input framelist NULL or has no input data");
00498 return(-1);
00499 }
00500
00501
00502
00503 if (vircam_frameset_fexists(framelist) != VIR_OK) {
00504 cpl_msg_error(fctid,"Input frameset is missing files. Check SOF");
00505 return(-1);
00506 }
00507
00508
00509
00510 vircam_dome_flat_combine_init();
00511 we_expect = MEANDOME;
00512
00513
00514
00515 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.lthr");
00516 vircam_dome_flat_combine_config.lthr = (float)cpl_parameter_get_double(p);
00517 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.hthr");
00518 vircam_dome_flat_combine_config.hthr = (float)cpl_parameter_get_double(p);
00519 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.combtype");
00520 vircam_dome_flat_combine_config.combtype = cpl_parameter_get_int(p);
00521 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.scaletype");
00522 vircam_dome_flat_combine_config.scaletype = cpl_parameter_get_int(p);
00523 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.xrej");
00524 vircam_dome_flat_combine_config.xrej = cpl_parameter_get_bool(p);
00525 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.thresh");
00526 vircam_dome_flat_combine_config.thresh = (float)cpl_parameter_get_double(p);
00527 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.ncells");
00528 vircam_dome_flat_combine_config.ncells = cpl_parameter_get_int(p);
00529 p = cpl_parameterlist_find(parlist,"vircam.vircam_dome_flat_combine.extenum");
00530 vircam_dome_flat_combine_config.extenum = cpl_parameter_get_int(p);
00531
00532
00533
00534 if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00535 cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00536 vircam_dome_flat_combine_tidy(2);
00537 return(-1);
00538 }
00539
00540
00541
00542 if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00543 &nlab)) == NULL) {
00544 cpl_msg_error(fctid,"Cannot labelise the input frames");
00545 vircam_dome_flat_combine_tidy(2);
00546 return(-1);
00547 }
00548 if ((ps.domelist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00549 VIRCAM_DOME_RAW)) == NULL) {
00550 cpl_msg_error(fctid,"Cannot find dome frames in input frameset");
00551 vircam_dome_flat_combine_tidy(2);
00552 return(-1);
00553 }
00554 ps.ndomes = cpl_frameset_get_size(ps.domelist);
00555
00556
00557
00558 if ((ps.master_dark = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00559 VIRCAM_CAL_DARK)) == NULL) {
00560 cpl_msg_error(fctid,"No master dark found");
00561 vircam_dome_flat_combine_tidy(2);
00562 return(-1);
00563 }
00564
00565
00566
00567 if ((ps.master_dome_flat = vircam_frameset_subgroup_1(framelist,ps.labels,
00568 nlab,VIRCAM_REF_DOME_FLAT)) == NULL)
00569 cpl_msg_info(fctid,"No master dome flat found -- no ratio image will be formed");
00570 else
00571 we_expect |= RATIMG;
00572
00573
00574
00575
00576 ps.master_mask = vircam_mask_define(framelist,ps.labels,nlab);
00577
00578
00579
00580 if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00581 VIRCAM_CAL_CHANTAB)) == NULL) {
00582 if ((ps.chantab = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00583 VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
00584 cpl_msg_info(fctid,"No channel table found -- no ratio image stats and no linearisation will be done");
00585 } else {
00586 cpl_msg_info(fctid,"Channel table is labelled INIT -- no linearisation will be done");
00587 if (we_expect & RATIMG)
00588 we_expect |= STATS_TAB;
00589 }
00590 } else if (we_expect & RATIMG) {
00591 we_expect |= STATS_TAB;
00592 }
00593
00594
00595
00596
00597
00598 vircam_exten_range(vircam_dome_flat_combine_config.extenum,
00599 (const cpl_frame *)cpl_frameset_get_frame(ps.domelist,0),
00600 &jst,&jfn);
00601 if (jst == -1 || jfn == -1) {
00602 cpl_msg_error(fctid,"Unable to continue");
00603 vircam_dome_flat_combine_tidy(2);
00604 return(-1);
00605 }
00606
00607
00608
00609 pp = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_frame(ps.domelist,0)),0);
00610 if (vircam_pfits_get_ndit(pp,&ndit) != VIR_OK) {
00611 cpl_msg_error(fctid,"No value for NDIT available");
00612 freepropertylist(pp);
00613 vircam_dome_flat_combine_tidy(2);
00614 return(-1);
00615 }
00616 cpl_propertylist_delete(pp);
00617
00618
00619
00620 ps.good = cpl_malloc(ps.ndomes*sizeof(vir_fits *));
00621
00622
00623
00624 for (j = jst; j <= jfn; j++) {
00625 status = VIR_OK;
00626 we_get = 0;
00627 isfirst = (j == jst);
00628
00629
00630
00631 ps.domes = vircam_fits_load_list(ps.domelist,CPL_TYPE_FLOAT,j);
00632 if (ps.domes == NULL) {
00633 cpl_msg_info(fctid,
00634 "Extension %" CPL_SIZE_FORMAT " domes wouldn't load",
00635 (cpl_size)j);
00636 retval = vircam_dome_flat_combine_lastbit(j,framelist,parlist);
00637 if (retval != 0)
00638 return(-1);
00639 continue;
00640 }
00641
00642
00643
00644 ps.ngood = 0;
00645 for (i = 0; i < ps.ndomes; i++) {
00646 ff = ps.domes[i];
00647 vircam_pfits_get_detlive(vircam_fits_get_ehu(ff),&live);
00648 if (! live) {
00649 cpl_msg_info(fctid,"Detector flagged dead %s",
00650 vircam_fits_get_fullname(ff));
00651 vircam_fits_set_error(ff,VIR_FATAL);
00652 } else {
00653 ps.good[ps.ngood] = ff;
00654 ps.ngood += 1;
00655 }
00656 }
00657
00658
00659
00660
00661 if (ps.ngood == 0) {
00662 cpl_msg_info(fctid,"All images flagged bad for this extension");
00663 retval = vircam_dome_flat_combine_lastbit(j,framelist,parlist);
00664 if (retval != 0)
00665 return(-1);
00666 continue;
00667 }
00668
00669
00670
00671 nx = (int)cpl_image_get_size_x(vircam_fits_get_image(ps.good[0]));
00672 ny = (int)cpl_image_get_size_y(vircam_fits_get_image(ps.good[0]));
00673 if (vircam_mask_load(ps.master_mask,j,nx,ny) == VIR_FATAL) {
00674 cpl_msg_info(fctid,
00675 "Unable to load mask image %s[%" CPL_SIZE_FORMAT "]",
00676 vircam_mask_get_filename(ps.master_mask),(cpl_size)j);
00677 cpl_msg_info(fctid,"Forcing all pixels to be good from now on");
00678 vircam_mask_force(ps.master_mask,nx,ny);
00679 }
00680
00681
00682
00683 vircam_overexp(ps.good,&(ps.ngood),ndit,
00684 vircam_dome_flat_combine_config.lthr,
00685 vircam_dome_flat_combine_config.hthr,0,
00686 &(vircam_dome_flat_combine_config.minv),
00687 &(vircam_dome_flat_combine_config.maxv),
00688 &(vircam_dome_flat_combine_config.avev));
00689
00690
00691
00692
00693 if (ps.ngood == 0) {
00694 cpl_msg_info(fctid,"All images either under or overexposed");
00695 retval = vircam_dome_flat_combine_lastbit(j,framelist,parlist);
00696 if (retval != 0)
00697 return(-1);
00698 continue;
00699 }
00700
00701
00702
00703
00704 ps.mdark = vircam_fits_load(ps.master_dark,CPL_TYPE_FLOAT,j);
00705 if (ps.mdark == NULL) {
00706 cpl_msg_info(fctid,
00707 "Can't load master dark for extension %" CPL_SIZE_FORMAT,
00708 (cpl_size)j);
00709 retval = vircam_dome_flat_combine_lastbit(j,framelist,parlist);
00710 if (retval != 0)
00711 return(-1);
00712 continue;
00713 } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mdark))) {
00714 cpl_msg_info(fctid,
00715 "Can't master dark extension %" CPL_SIZE_FORMAT " is a dummy",
00716 (cpl_size)j);
00717 retval = vircam_dome_flat_combine_lastbit(j,framelist,parlist);
00718 if (retval != 0)
00719 return(-1);
00720 continue;
00721 }
00722
00723
00724
00725 cpl_msg_info(fctid,"Dark correcting extension %" CPL_SIZE_FORMAT,
00726 (cpl_size)j);
00727 for (i = 0; i < ps.ngood; i++)
00728 vircam_darkcor((ps.good)[i],ps.mdark,1.0,&status);
00729
00730
00731
00732
00733 if (ps.chantab != NULL) {
00734 ps.ctable = vircam_tfits_load(ps.chantab,j);
00735 if (ps.ctable == NULL) {
00736 cpl_msg_info(fctid,
00737 "Channel table extension %" CPL_SIZE_FORMAT " won't load",
00738 (cpl_size)j);
00739 } else if (vircam_chantab_verify(vircam_tfits_get_table(ps.ctable)) != VIR_OK) {
00740 cpl_msg_info(fctid,
00741 "Channel table extension %" CPL_SIZE_FORMAT " has errors",
00742 (cpl_size)j);
00743 freetfits(ps.ctable);
00744 } else {
00745 pp = cpl_propertylist_load(cpl_frame_get_filename(ps.chantab),
00746 (cpl_size)j);
00747 if (vircam_is_dummy(pp)) {
00748 cpl_msg_info(fctid,
00749 "Channel table extensions %" CPL_SIZE_FORMAT " is a dummy",
00750 (cpl_size)j);
00751 freetfits(ps.ctable);
00752 }
00753 freepropertylist(pp);
00754 }
00755 } else
00756 ps.ctable = NULL;
00757
00758
00759
00760
00761 if (ps.ctable != NULL) {
00762 cpl_msg_info(fctid,"Linearising extension %" CPL_SIZE_FORMAT,
00763 (cpl_size)j);
00764 for (i = 0; i < ps.ngood; i++)
00765 (void)vircam_lincor((ps.good)[i],ps.ctable,1,ndit,&status);
00766 }
00767
00768
00769
00770 for (i = 0; i < ps.ngood; i++)
00771 (void)vircam_nditcor((ps.good)[i],ndit,&status);
00772
00773
00774
00775 cpl_msg_info(fctid,"Doing combination for extension %" CPL_SIZE_FORMAT,
00776 (cpl_size)j);
00777 (void)vircam_imcombine(ps.good,ps.ngood,
00778 vircam_dome_flat_combine_config.combtype,
00779 vircam_dome_flat_combine_config.scaletype,
00780 vircam_dome_flat_combine_config.xrej,
00781 vircam_dome_flat_combine_config.thresh,
00782 &(ps.outimage),&(ps.rejmask),&(ps.rejplus),
00783 &(ps.drs),&status);
00784
00785
00786
00787
00788 if (status == VIR_OK) {
00789 we_get |= MEANDOME;
00790 vircam_dome_flat_combine_normal(j);
00791 } else {
00792 cpl_msg_info(fctid,"A processing step failed");
00793 }
00794
00795
00796
00797 retval = vircam_dome_flat_combine_lastbit(j,framelist,parlist);
00798 if (retval != 0)
00799 return(-1);
00800
00801 }
00802 vircam_dome_flat_combine_tidy(2);
00803 return(0);
00804 }
00805
00806
00807
00814
00815
00816 static int vircam_dome_flat_combine_save(cpl_frameset *framelist,
00817 cpl_parameterlist *parlist) {
00818 cpl_propertylist *plist,*elist,*p,*paf;
00819 int status;
00820 float val;
00821 const char *fctid = "vircam_dome_flat_combine_save";
00822 const char *outfile = "domecomb.fits";
00823 const char *outdiff = "domeratio.fits";
00824 const char *outdimst = "domeratiotab.fits";
00825 const char *outpaf = "domecomb";
00826 const char *outdpaf = "domeratio";
00827 const char *recipeid = "vircam_dome_flat_combine";
00828
00829
00830
00831
00832 if (isfirst) {
00833
00834
00835
00836 product_frame_mean_dome = cpl_frame_new();
00837 cpl_frame_set_filename(product_frame_mean_dome,outfile);
00838 cpl_frame_set_tag(product_frame_mean_dome,VIRCAM_PRO_DOME_FLAT);
00839 cpl_frame_set_type(product_frame_mean_dome,CPL_FRAME_TYPE_IMAGE);
00840 cpl_frame_set_group(product_frame_mean_dome,CPL_FRAME_GROUP_PRODUCT);
00841 cpl_frame_set_level(product_frame_mean_dome,CPL_FRAME_LEVEL_FINAL);
00842
00843
00844
00845 plist = vircam_fits_get_phu(ps.domes[0]);
00846 ps.phupaf = vircam_paf_phu_items(plist);
00847 if (ps.master_dome_flat != NULL) {
00848 cpl_propertylist_update_string(ps.phupaf,"REF_DOME",
00849 cpl_frame_get_filename(ps.master_dome_flat));
00850 cpl_propertylist_set_comment(ps.phupaf,"REF_DOME",
00851 "Reference dome flat used");
00852 }
00853 vircam_dfs_set_product_primary_header(plist,product_frame_mean_dome,
00854 framelist,parlist,
00855 (char *)recipeid,
00856 "PRO-1.15",NULL,0);
00857
00858
00859
00860 if (cpl_image_save(NULL,outfile,CPL_TYPE_UCHAR,plist,
00861 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00862 cpl_msg_error(fctid,"Cannot save product PHU");
00863 cpl_frame_delete(product_frame_mean_dome);
00864 return(-1);
00865 }
00866 cpl_frameset_insert(framelist,product_frame_mean_dome);
00867
00868
00869
00870 if (we_expect & RATIMG) {
00871 product_frame_ratioimg = cpl_frame_new();
00872 cpl_frame_set_filename(product_frame_ratioimg,outdiff);
00873 cpl_frame_set_tag(product_frame_ratioimg,
00874 VIRCAM_PRO_RATIOIMG_DOME_FLAT);
00875 cpl_frame_set_type(product_frame_ratioimg,CPL_FRAME_TYPE_IMAGE);
00876 cpl_frame_set_group(product_frame_ratioimg,
00877 CPL_FRAME_GROUP_PRODUCT);
00878 cpl_frame_set_level(product_frame_ratioimg,CPL_FRAME_LEVEL_FINAL);
00879
00880
00881
00882 plist = vircam_fits_get_phu(ps.domes[0]);
00883 vircam_dfs_set_product_primary_header(plist,product_frame_ratioimg,
00884 framelist,parlist,
00885 (char *)recipeid,
00886 "PRO-1.15",NULL,0);
00887
00888
00889
00890 if (cpl_image_save(NULL,outdiff,CPL_TYPE_UCHAR,plist,
00891 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00892 cpl_msg_error(fctid,"Cannot save product PHU");
00893 cpl_frame_delete(product_frame_ratioimg);
00894 return(-1);
00895 }
00896 cpl_frameset_insert(framelist,product_frame_ratioimg);
00897 }
00898
00899
00900
00901
00902 if (we_expect & STATS_TAB) {
00903 product_frame_ratioimg_stats = cpl_frame_new();
00904 cpl_frame_set_filename(product_frame_ratioimg_stats,outdimst);
00905 cpl_frame_set_tag(product_frame_ratioimg_stats,
00906 VIRCAM_PRO_RATIOIMG_DOME_FLAT_STATS);
00907 cpl_frame_set_type(product_frame_ratioimg_stats,
00908 CPL_FRAME_TYPE_TABLE);
00909 cpl_frame_set_group(product_frame_ratioimg_stats,
00910 CPL_FRAME_GROUP_PRODUCT);
00911 cpl_frame_set_level(product_frame_ratioimg_stats,
00912 CPL_FRAME_LEVEL_FINAL);
00913
00914
00915
00916 plist = vircam_fits_get_phu(ps.domes[0]);
00917 vircam_dfs_set_product_primary_header(plist,
00918 product_frame_ratioimg_stats,
00919 framelist,parlist,
00920 (char *)recipeid,
00921 "PRO-1.15",NULL,0);
00922
00923
00924
00925 elist = vircam_fits_get_ehu(ps.domes[0]);
00926 p = cpl_propertylist_duplicate(elist);
00927 vircam_merge_propertylists(p,ps.drs);
00928 vircam_paf_append(p,vircam_fits_get_phu(ps.domes[0]),
00929 "ESO INS FILT1 NAME");
00930 if (! (we_get & STATS_TAB))
00931 vircam_dummy_property(p);
00932 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
00933 framelist,parlist,
00934 (char *)recipeid,
00935 "PRO-1.15",NULL);
00936 status = VIR_OK;
00937 vircam_removewcs(p,&status);
00938
00939
00940
00941 if (cpl_table_save(ps.ratioimstats,plist,p,outdimst,
00942 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
00943 cpl_msg_error(fctid,"Cannot save product table extension");
00944 cpl_propertylist_delete(p);
00945 return(-1);
00946 }
00947 cpl_propertylist_delete(p);
00948 cpl_frameset_insert(framelist,product_frame_ratioimg_stats);
00949 }
00950 }
00951
00952
00953
00954 plist = vircam_fits_get_ehu(ps.domes[0]);
00955 cpl_propertylist_update_int(plist,"ESO PRO DATANCOM",ps.ngood);
00956
00957
00958
00959 vircam_merge_propertylists(plist,ps.drs);
00960 p = cpl_propertylist_duplicate(plist);
00961 if (! (we_get & MEANDOME))
00962 vircam_dummy_property(p);
00963 vircam_dfs_set_product_exten_header(p,product_frame_mean_dome,
00964 framelist,parlist,
00965 (char *)recipeid,
00966 "PRO-1.15",NULL);
00967
00968
00969
00970 cpl_propertylist_update_float(p,"ESO QC FLATRMS",
00971 vircam_dome_flat_combine_config.flatrms);
00972 cpl_propertylist_set_comment(p,"ESO QC FLATRMS","RMS of output flat");
00973 cpl_propertylist_update_float(p,"ESO QC FLATMIN",
00974 vircam_dome_flat_combine_config.minv);
00975 cpl_propertylist_set_comment(p,"ESO QC FLATMIN","Ensemble minimum");
00976 cpl_propertylist_update_float(p,"ESO QC FLATMAX",
00977 vircam_dome_flat_combine_config.maxv);
00978 cpl_propertylist_set_comment(p,"ESO QC FLATMAX","Ensemble maximum");
00979 cpl_propertylist_update_float(p,"ESO QC FLATAVG",
00980 vircam_dome_flat_combine_config.avev);
00981 cpl_propertylist_set_comment(p,"ESO QC FLATAVG","Ensemble average");
00982 val = vircam_dome_flat_combine_config.maxv -
00983 vircam_dome_flat_combine_config.minv;
00984 cpl_propertylist_update_float(p,"ESO QC FLATRNG",val);
00985 cpl_propertylist_set_comment(p,"ESO QC FLATRNG","Ensemble range");
00986 if (cpl_image_save(ps.outimage,outfile,CPL_TYPE_FLOAT,p,
00987 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
00988 cpl_propertylist_delete(p);
00989 cpl_msg_error(fctid,"Cannot save product image extension");
00990 return(-1);
00991 }
00992
00993
00994
00995 paf = vircam_paf_req_items(p);
00996 vircam_merge_propertylists(paf,ps.phupaf);
00997 vircam_paf_append(paf,vircam_fits_get_phu(ps.domes[0]),
00998 "ESO INS FILT1 NAME");
00999 vircam_paf_append(paf,p,"ESO PRO CATG");
01000 vircam_paf_append(paf,p,"ESO PRO DATANCOM");
01001 if (vircam_paf_print((char *)outpaf,"VIRCAM/vircam_dome_flat_combine",
01002 "QC file",paf) != VIR_OK)
01003 cpl_msg_warning(fctid,"Unable to save PAF for mean dome");
01004 cpl_propertylist_delete(paf);
01005 cpl_propertylist_delete(p);
01006
01007
01008
01009 if (we_expect & RATIMG) {
01010 p = cpl_propertylist_duplicate(plist);
01011 if (! (we_get & RATIMG))
01012 vircam_dummy_property(p);
01013 cpl_propertylist_update_float(p,"ESO QC FLATRATIO_MED",
01014 vircam_dome_flat_combine_config.flatratio_med);
01015 cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_MED",
01016 "Median of ratio map");
01017 cpl_propertylist_update_float(p,"ESO QC FLATRATIO_RMS",
01018 vircam_dome_flat_combine_config.flatratio_rms);
01019 cpl_propertylist_set_comment(p,"ESO QC FLATRATIO_RMS",
01020 "RMS of ratio map");
01021 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg,
01022 framelist,parlist,
01023 (char *)recipeid,
01024 "PRO-1.15",NULL);
01025 if (cpl_image_save(ps.ratioimg,outdiff,CPL_TYPE_FLOAT,p,
01026 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01027 cpl_propertylist_delete(p);
01028 cpl_msg_error(fctid,"Cannot save product image extension");
01029 return(-1);
01030 }
01031
01032
01033
01034 paf = vircam_paf_req_items(p);
01035 vircam_merge_propertylists(paf,ps.phupaf);
01036 vircam_paf_append(paf,vircam_fits_get_phu(ps.domes[0]),
01037 "ESO INS FILT1 NAME");
01038 vircam_paf_append(paf,p,"ESO PRO CATG");
01039 if (vircam_paf_print((char *)outdpaf,"VIRCAM/vircam_dome_flat_combine",
01040 "QC file",paf) != VIR_OK)
01041 cpl_msg_warning(fctid,"Unable to save PAF for ratio image");
01042 cpl_propertylist_delete(paf);
01043 cpl_propertylist_delete(p);
01044 }
01045
01046
01047
01048 if (! isfirst && (we_expect & STATS_TAB)) {
01049 p = cpl_propertylist_duplicate(plist);
01050 if (! (we_get & STATS_TAB))
01051 vircam_dummy_property(p);
01052 vircam_dfs_set_product_exten_header(p,product_frame_ratioimg_stats,
01053 framelist,parlist,
01054 (char *)recipeid,
01055 "PRO-1.15",NULL);
01056 status = VIR_OK;
01057 vircam_removewcs(p,&status);
01058 if (cpl_table_save(ps.ratioimstats,NULL,p,outdimst,CPL_IO_EXTEND)
01059 != CPL_ERROR_NONE) {
01060 cpl_propertylist_delete(p);
01061 cpl_msg_error(fctid,"Cannot save product table extension");
01062 return(-1);
01063 }
01064 cpl_propertylist_delete(p);
01065 }
01066
01067
01068
01069 return(0);
01070 }
01071
01072
01076
01077
01078 static void vircam_dome_flat_combine_dummy_products(void) {
01079
01080
01081
01082 if (we_get == we_expect)
01083 return;
01084
01085
01086
01087 if (! (we_get & MEANDOME)) {
01088 ps.outimage = vircam_dummy_image(ps.domes[0]);
01089 vircam_dome_flat_combine_config.flatrms = 0.0;
01090 }
01091
01092
01093
01094 if ((we_expect & RATIMG) && ! (we_get & RATIMG)) {
01095 vircam_dome_flat_combine_config.flatratio_med = 0.0;
01096 vircam_dome_flat_combine_config.flatratio_rms = 0.0;
01097 ps.ratioimg = vircam_dummy_image(ps.domes[0]);
01098 }
01099
01100
01101
01102 if ((we_expect & STATS_TAB) && ! (we_get & STATS_TAB))
01103 ps.ratioimstats = vircam_create_diffimg_stats(0);
01104
01105 return;
01106 }
01107
01108
01113
01114
01115 static void vircam_dome_flat_combine_normal(int jext) {
01116 int nx,ny,ncells;
01117 long npi;
01118 unsigned char *bpm;
01119 float *idata,med,sig,gdiff,grms;
01120 const char *fctid="vircam_dome_flat_combine_normal";
01121
01122
01123
01124 nx = (int)cpl_image_get_size_x(ps.outimage);
01125 ny = (int)cpl_image_get_size_y(ps.outimage);
01126 npi = nx*ny;
01127 bpm = vircam_mask_get_data(ps.master_mask);
01128
01129
01130
01131 idata = cpl_image_get_data(ps.outimage);
01132 vircam_medsig(idata,bpm,npi,&med,&sig);
01133
01134
01135
01136 cpl_image_divide_scalar(ps.outimage,med);
01137 vircam_medmad(idata,bpm,npi,&med,&sig);
01138 sig *= 1.48;
01139 vircam_dome_flat_combine_config.flatrms = sig;
01140
01141
01142
01143 if (ps.master_dome_flat != NULL) {
01144 ps.mfimage = vircam_fits_load(ps.master_dome_flat,CPL_TYPE_FLOAT,jext);
01145 if (ps.mfimage == NULL) {
01146 cpl_msg_error(fctid,
01147 "Master dome extension %" CPL_SIZE_FORMAT " won't load",
01148 (cpl_size)jext);
01149 } else if (vircam_is_dummy(vircam_fits_get_ehu(ps.mfimage))) {
01150 cpl_msg_error(fctid,
01151 "Master dome extension %" CPL_SIZE_FORMAT " is a dummy",
01152 (cpl_size)jext);
01153 freefits(ps.mfimage);
01154 }
01155 } else
01156 ps.mfimage = NULL;
01157
01158
01159
01160
01161
01162
01163
01164
01165 vircam_dome_flat_combine_config.flatratio_med = 0.0;
01166 vircam_dome_flat_combine_config.flatratio_rms = 0.0;
01167 ncells = vircam_dome_flat_combine_config.ncells;
01168 vircam_difference_image(vircam_fits_get_image(ps.mfimage),ps.outimage,bpm,
01169 vircam_tfits_get_table(ps.ctable),ncells,2,
01170 &gdiff,&grms,&(ps.ratioimg),
01171 &(ps.ratioimstats));
01172 vircam_mask_clear(ps.master_mask);
01173 vircam_dome_flat_combine_config.flatratio_med = gdiff;
01174 vircam_dome_flat_combine_config.flatratio_rms = grms;
01175 if (ps.ratioimg != NULL)
01176 we_get |= RATIMG;
01177 if (ps.ratioimstats != NULL)
01178 we_get |= STATS_TAB;
01179 return;
01180 }
01181
01182
01190
01191
01192 static int vircam_dome_flat_combine_lastbit(int jext, cpl_frameset *framelist,
01193 cpl_parameterlist *parlist) {
01194 int retval;
01195 const char *fctid="vircam_dome_flat_combine_lastbit";
01196
01197
01198
01199 vircam_dome_flat_combine_dummy_products();
01200
01201
01202
01203 cpl_msg_info(fctid,"Saving products for extension %" CPL_SIZE_FORMAT,
01204 (cpl_size)jext);
01205 retval = vircam_dome_flat_combine_save(framelist,parlist);
01206 if (retval != 0) {
01207 vircam_dome_flat_combine_tidy(2);
01208 return(-1);
01209 }
01210
01211
01212
01213 vircam_dome_flat_combine_tidy(1);
01214 return(0);
01215 }
01216
01217
01221
01222
01223 static void vircam_dome_flat_combine_init(void) {
01224 ps.labels = NULL;
01225 ps.domelist = NULL;
01226 ps.domes = NULL;
01227 ps.good = NULL;
01228 ps.master_dark = NULL;
01229 ps.master_dome_flat = NULL;
01230 ps.master_mask = NULL;
01231 ps.chantab = NULL;
01232 ps.ctable = NULL;
01233 ps.outimage = NULL;
01234 ps.drs = NULL;
01235 ps.rejmask = NULL;
01236 ps.rejplus = NULL;
01237 ps.mfimage = NULL;
01238 ps.ratioimg = NULL;
01239 ps.ratioimstats = NULL;
01240 ps.phupaf = NULL;
01241 }
01242
01243
01247
01248
01249 static void vircam_dome_flat_combine_tidy(int level) {
01250 freeimage(ps.outimage);
01251 freefitslist(ps.domes,ps.ndomes);
01252 freepropertylist(ps.drs);
01253 freespace(ps.rejmask);
01254 freespace(ps.rejplus);
01255 freetfits(ps.ctable);
01256 freefits(ps.mfimage);
01257 freefits(ps.mdark);
01258 freeimage(ps.ratioimg);
01259 freetable(ps.ratioimstats);
01260 if (level == 1)
01261 return;
01262
01263 freespace(ps.labels);
01264 freeframeset(ps.domelist);
01265 freeframe(ps.master_dark);
01266 freeframe(ps.master_dome_flat);
01267 freeframe(ps.chantab);
01268 freespace(ps.good);
01269 freemask(ps.master_mask);
01270 freepropertylist(ps.phupaf);
01271
01272 }
01273
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
01363
01364
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
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