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