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_pfits.h"
00040 #include "vircam_dfs.h"
00041 #include "vircam_mods.h"
00042 #include "vircam_channel.h"
00043 #include "vircam_stats.h"
00044 #include "vircam_paf.h"
00045
00046
00047
00048 static int vircam_linearity_analyse_create(cpl_plugin *) ;
00049 static int vircam_linearity_analyse_exec(cpl_plugin *) ;
00050 static int vircam_linearity_analyse_destroy(cpl_plugin *) ;
00051 static int vircam_linearity_analyse(cpl_parameterlist *, cpl_frameset *) ;
00052 static int vircam_linearity_analyse_lastbit(int jext, cpl_frameset *framelist,
00053 cpl_parameterlist *parlist);
00054 static int vircam_linearity_analyse_save(cpl_frameset *framelist,
00055 cpl_parameterlist *parlist);
00056 static int vircam_linearity_analyse_domedark_groups(void);
00057 static double *vircam_linearity_analyse_genstat(vir_fits *fframe, int *bpm,
00058 parquet *p, int np);
00059 static double *vircam_linearity_tweakfac(double **fdata, double *mjd, int nim,
00060 int nchan, double *facrng,
00061 double *maxdiff);
00062 static void vircam_mjdsort(double **fdata, double *mjd, int n);
00063 static cpl_table *vircam_linearity_analyse_diagtab_init(int np, int nrows);
00064 static void vircam_linearity_analyse_init(void);
00065 static void vircam_linearity_analyse_tidy(int level);
00066
00067
00068
00069 static struct {
00070
00071
00072
00073 int norder;
00074 float lthr;
00075 float hthr;
00076 int maxbpmfr;
00077 int adjust;
00078 int diagnostic;
00079 int extenum;
00080
00081
00082
00083 float linearity;
00084 float linerror;
00085 float bad_pixel_stat;
00086 int bad_pixel_num;
00087 float facrng;
00088 float maxdiff;
00089
00090 } vircam_linearity_analyse_config;
00091
00092 typedef struct {
00093 cpl_frameset *darks;
00094 cpl_frameset *domes;
00095 int ndarks;
00096 int ndomes;
00097 float exptime;
00098 unsigned char flag;
00099 vir_fits **proc;
00100 } ddgrp;
00101
00102 #define OK_FLAG 0
00103 #define SATURATE_FLAG 1
00104
00105 #define SUBSET 128
00106 #define SUBSET2 (SUBSET/2)
00107
00108 static struct {
00109 int *labels;
00110 cpl_frameset *domelist;
00111 int ndomes;
00112 cpl_frameset *darklist;
00113 int ndarks;
00114 cpl_frameset *domecheck;
00115 int ndomecheck;
00116 cpl_frameset *darkcheck;
00117 int ndarkcheck;
00118 cpl_frameset *sorted;
00119 cpl_frame *chanfrm;
00120 vir_tfits *chantab;
00121 cpl_table *lchantab;
00122 cpl_array *bpm_array;
00123 ddgrp *ddg;
00124 int nddg;
00125 vir_fits **flatlist;
00126 int nflatlist;
00127 cpl_propertylist *plist;
00128 cpl_propertylist *elist;
00129 int nx;
00130 int ny;
00131 cpl_propertylist *phupaf;
00132 cpl_table *diag1;
00133 cpl_table *diag2;
00134 } ps;
00135
00136 static int isfirst;
00137 static int dummy;
00138 static cpl_frame *product_frame_chantab = NULL;
00139 static cpl_frame *product_frame_bpm = NULL;
00140 static cpl_frame *product_frame_diag1 = NULL;
00141 static cpl_frame *product_frame_diag2 = NULL;
00142
00143 static char vircam_linearity_analyse_description[] =
00144 "vircam_linearity_analyse -- VIRCAM linearity mapping recipe.\n\n"
00145 "Form master dark images from the input raw frames and use these to\n"
00146 "dark correct a series of dome flat exposures Using the dark\n"
00147 "corrected dome flat series, work out linearity coefficients for\n"
00148 "each data channel. The program expects the following files in the SOF\n"
00149 " Tag Description\n"
00150 " -----------------------------------------------------------------------\n"
00151 " %-21s A list of raw dome flat images\n"
00152 " %-21s A list of raw dark images\n"
00153 " %-21s The channel table\n"
00154 " %-21s A list of raw dome flat images at the monitor exposure time"
00155 " %-21s A list of raw dark images at the monitor exposure time"
00156 "The first three of these are required. The last two are only required if"
00157 "the light source monitoring algorithm is to be used"
00158 "\n";
00159
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_linearity_analyse_description,
00298 VIRCAM_LIN_DOME_RAW,VIRCAM_LIN_DARK_RAW,
00299 VIRCAM_CAL_CHANTAB_INIT,VIRCAM_LIN_DOME_CHECK,
00300 VIRCAM_LIN_DARK_CHECK);
00301
00302 cpl_plugin_init(plugin,
00303 CPL_PLUGIN_API,
00304 VIRCAM_BINARY_VERSION,
00305 CPL_PLUGIN_TYPE_RECIPE,
00306 "vircam_linearity_analyse",
00307 "VIRCAM linearity analysis recipe",
00308 alldesc,
00309 "Jim Lewis",
00310 "jrl@ast.cam.ac.uk",
00311 vircam_get_license(),
00312 vircam_linearity_analyse_create,
00313 vircam_linearity_analyse_exec,
00314 vircam_linearity_analyse_destroy);
00315
00316 cpl_pluginlist_append(list,plugin);
00317
00318 return(0);
00319 }
00320
00321
00322
00331
00332
00333 static int vircam_linearity_analyse_create(cpl_plugin *plugin) {
00334 cpl_recipe *recipe;
00335 cpl_parameter *p;
00336
00337
00338
00339 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00340 recipe = (cpl_recipe *)plugin;
00341 else
00342 return(-1);
00343
00344
00345
00346 recipe->parameters = cpl_parameterlist_new();
00347
00348
00349
00350 p = cpl_parameter_new_range("vircam.vircam_linearity_analyse.norder",
00351 CPL_TYPE_INT,
00352 "Order of polynomial fit",
00353 "vircam.vircam_linearity_analyse",
00354 2,1,6);
00355 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"nord");
00356 cpl_parameterlist_append(recipe->parameters,p);
00357
00358
00359
00360 p = cpl_parameter_new_value("vircam.vircam_linearity_analyse.lthr",
00361 CPL_TYPE_DOUBLE,
00362 "Lower bad pixel threshold",
00363 "vircam.vircam_linearity_analyse",8.0);
00364 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"lthr");
00365 cpl_parameterlist_append(recipe->parameters,p);
00366
00367
00368
00369 p = cpl_parameter_new_value("vircam.vircam_linearity_analyse.hthr",
00370 CPL_TYPE_DOUBLE,
00371 "Upper bad pixel threshold",
00372 "vircam.vircam_linearity_analyse",8.0);
00373 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"hthr");
00374 cpl_parameterlist_append(recipe->parameters,p);
00375
00376
00377
00378 p = cpl_parameter_new_value("vircam.vircam_linearity_analyse.maxbpmfr",
00379 CPL_TYPE_INT,
00380 "Maximum # frames used in bpm analysis",
00381 "vircam.vircam_linearity_analyse",10);
00382 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"maxbpmfr");
00383 cpl_parameterlist_append(recipe->parameters,p);
00384
00385
00386
00387
00388 p = cpl_parameter_new_value("vircam.vircam_linearity_analyse.adjust",
00389 CPL_TYPE_BOOL,
00390 "Adjust stats with monitor set",
00391 "vircam.vircam_linearity_analyse",1);
00392 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"adjust");
00393 cpl_parameterlist_append(recipe->parameters,p);
00394
00395
00396
00397 p = cpl_parameter_new_value("vircam.vircam_linearity_analyse.diagnostic",
00398 CPL_TYPE_BOOL,
00399 "Write out diagnostic tables",
00400 "vircam.vircam_linearity_analyse",0);
00401 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"diagnostic");
00402 cpl_parameterlist_append(recipe->parameters,p);
00403
00404
00405
00406 p = cpl_parameter_new_range("vircam.vircam_linearity_analyse.extenum",
00407 CPL_TYPE_INT,
00408 "Extension number to be done, 0 == all",
00409 "vircam.vircam_linearity_analyse",
00410 1,0,16);
00411 cpl_parameter_set_alias(p,CPL_PARAMETER_MODE_CLI,"ext");
00412 cpl_parameterlist_append(recipe->parameters,p);
00413
00414
00415
00416 return(0);
00417 }
00418
00419
00425
00426
00427 static int vircam_linearity_analyse_exec(cpl_plugin *plugin) {
00428 cpl_recipe *recipe;
00429
00430
00431
00432 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00433 recipe = (cpl_recipe *)plugin;
00434 else
00435 return(-1);
00436
00437 return(vircam_linearity_analyse(recipe->parameters,recipe->frames));
00438 }
00439
00440
00446
00447
00448 static int vircam_linearity_analyse_destroy(cpl_plugin *plugin) {
00449 cpl_recipe *recipe ;
00450
00451
00452
00453 if (cpl_plugin_get_type(plugin) == CPL_PLUGIN_TYPE_RECIPE)
00454 recipe = (cpl_recipe *)plugin;
00455 else
00456 return(-1);
00457
00458 cpl_parameterlist_delete(recipe->parameters);
00459 return(0);
00460 }
00461
00462
00469
00470
00471 static int vircam_linearity_analyse(cpl_parameterlist *parlist,
00472 cpl_frameset *framelist) {
00473 const char *fctid="vircam_linearity_analyse";
00474 char colname[16];
00475 int i,jst,jfn,j,status,nlab,k,nbad,ntimes,init,ngood,nuse,krem,irem,n;
00476 int ndarks,ndomes,kk,live,nbmax,ngood_flats,*bpm,nalloc,nfdata,adjust,ndit;
00477 long np,npi;
00478 float *idata,low,high,med,sig,mindit,sat,*exps,badfrac,exp;
00479 unsigned char *rejmask,*rejplus;
00480 double *dexps,**fdata,*d,*mjds,*mjdcheck,mjd,**cdata,*cf,fac;
00481 double facrng,maxdiff,*lindata;
00482 vir_fits **darks,**domes,*outfits,*test,*outdark,*fframe;
00483 parquet *pp;
00484 cpl_parameter *p;
00485 cpl_propertylist *drs,*plist;
00486 cpl_image *master_img,*im,*outimage;
00487 cpl_frame *frame;
00488
00489
00490
00491 if (framelist == NULL || cpl_frameset_get_size(framelist) <= 0) {
00492 cpl_msg_error(fctid,"Input framelist NULL or has no input data\n");
00493 return(-1);
00494 }
00495
00496
00497
00498 vircam_linearity_analyse_init();
00499
00500
00501
00502 p = cpl_parameterlist_find(parlist,
00503 "vircam.vircam_linearity_analyse.norder");
00504 vircam_linearity_analyse_config.norder = cpl_parameter_get_int(p);
00505 p = cpl_parameterlist_find(parlist,
00506 "vircam.vircam_linearity_analyse.lthr");
00507 vircam_linearity_analyse_config.lthr = (float)cpl_parameter_get_double(p);
00508 p = cpl_parameterlist_find(parlist,
00509 "vircam.vircam_linearity_analyse.hthr");
00510 vircam_linearity_analyse_config.hthr = (float)cpl_parameter_get_double(p);
00511 p = cpl_parameterlist_find(parlist,
00512 "vircam.vircam_linearity_analyse.maxbpmfr");
00513 vircam_linearity_analyse_config.maxbpmfr = cpl_parameter_get_int(p);
00514 p = cpl_parameterlist_find(parlist,
00515 "vircam.vircam_linearity_analyse.adjust");
00516 vircam_linearity_analyse_config.adjust = cpl_parameter_get_bool(p);
00517 p = cpl_parameterlist_find(parlist,
00518 "vircam.vircam_linearity_analyse.diagnostic");
00519 vircam_linearity_analyse_config.diagnostic = cpl_parameter_get_bool(p);
00520 p = cpl_parameterlist_find(parlist,
00521 "vircam.vircam_linearity_analyse.extenum");
00522 vircam_linearity_analyse_config.extenum = cpl_parameter_get_int(p);
00523
00524
00525
00526 if (vircam_dfs_set_groups(framelist) != VIR_OK) {
00527 cpl_msg_error(fctid,"Cannot identify RAW and CALIB frames");
00528 vircam_linearity_analyse_tidy(2);
00529 return(-1);
00530 }
00531
00532
00533
00534 if ((ps.labels = cpl_frameset_labelise(framelist,vircam_compare_tags,
00535 &nlab)) == NULL) {
00536 cpl_msg_error(fctid,"Cannot labelise the input frames");
00537 vircam_linearity_analyse_tidy(2);
00538 return(-1);
00539 }
00540
00541
00542
00543 if ((ps.domelist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00544 VIRCAM_LIN_DOME_RAW)) == NULL) {
00545 cpl_msg_error(fctid,"Cannot find dome flat frames in input frameset");
00546 vircam_linearity_analyse_tidy(2);
00547 return(-1);
00548 }
00549 ps.ndomes = cpl_frameset_get_size(ps.domelist);
00550
00551
00552
00553 plist = cpl_propertylist_load(cpl_frame_get_filename(cpl_frameset_get_frame(ps.domelist,0)),0);
00554 (void)vircam_pfits_get_ndit(plist,&ndit);
00555 freepropertylist(plist);
00556 if (ndit != 1) {
00557 cpl_msg_error(fctid,"NDIT=%d. Recipe requires that ndit == 1",ndit);
00558 vircam_linearity_analyse_tidy(2);
00559 return(-1);
00560 }
00561
00562
00563
00564 if ((ps.darklist = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00565 VIRCAM_LIN_DARK_RAW)) == NULL) {
00566 cpl_msg_error(fctid,"Cannot find dark frames in input frameset");
00567 vircam_linearity_analyse_tidy(2);
00568 return(-1);
00569 }
00570 ps.ndarks = cpl_frameset_get_size(ps.darklist);
00571
00572
00573
00574
00575 if (vircam_linearity_analyse_config.adjust) {
00576 if ((ps.domecheck = vircam_frameset_subgroup(framelist,ps.labels,nlab,
00577 VIRCAM_LIN_DOME_CHECK)) == NULL) {
00578 cpl_msg_info(fctid,"No monitor frames found in sof. No adjustments made to stats");
00579 vircam_linearity_analyse_config.adjust = 0;
00580 ps.ndomecheck = 0;
00581 } else {
00582 ps.ndomecheck = cpl_frameset_get_size(ps.domecheck);
00583 if ((ps.darkcheck = vircam_frameset_subgroup(framelist,ps.labels,
00584 nlab,VIRCAM_LIN_DARK_CHECK)) == NULL) {
00585 cpl_msg_info(fctid,"No darks for monitor frames found in sof. No adjustments made to stats");
00586 vircam_linearity_analyse_config.adjust = 0;
00587 ps.ndomecheck = 0;
00588 freeframeset(ps.domecheck);
00589 ps.ndarkcheck = 0;
00590 } else {
00591 ps.ndarkcheck = cpl_frameset_get_size(ps.darkcheck);
00592 }
00593 }
00594 }
00595
00596
00597
00598 if ((ps.chanfrm = vircam_frameset_subgroup_1(framelist,ps.labels,nlab,
00599 VIRCAM_CAL_CHANTAB_INIT)) == NULL) {
00600 cpl_msg_error(fctid,"No initial channel table found");
00601 vircam_linearity_analyse_tidy(2);
00602 return(-1);
00603 }
00604
00605
00606
00607
00608 ps.sorted = cpl_frameset_new();
00609 for (j = 0; j < ps.ndomes; j++)
00610 cpl_frameset_insert(ps.sorted,cpl_frame_duplicate(cpl_frameset_get_frame(ps.domelist,j)));
00611 for (j = 0; j < ps.ndarks; j++)
00612 cpl_frameset_insert(ps.sorted,cpl_frame_duplicate(cpl_frameset_get_frame(ps.darklist,j)));
00613 cpl_frameset_insert(ps.sorted,cpl_frame_duplicate(ps.chanfrm));
00614
00615
00616
00617 if (vircam_linearity_analyse_domedark_groups() != 0) {
00618 vircam_linearity_analyse_tidy(2);
00619 return(-1);
00620 }
00621
00622
00623
00624
00625 if (ps.nddg < vircam_linearity_analyse_config.norder+1) {
00626 cpl_msg_warning(fctid,
00627 "Number of exposure times is too small: %d, order: %d\nTaking fit down to order %d",
00628 ps.nddg,vircam_linearity_analyse_config.norder,
00629 ps.nddg-1);
00630 vircam_linearity_analyse_config.norder = ps.nddg - 1;
00631 }
00632
00633
00634
00635
00636
00637 vircam_exten_range(vircam_linearity_analyse_config.extenum,
00638 (const cpl_frame *)cpl_frameset_get_frame(ps.ddg[0].darks,0),
00639 &jst,&jfn);
00640 if (jst == -1 || jfn == -1) {
00641 cpl_msg_error(fctid,"Unable to continue");
00642 vircam_linearity_analyse_tidy(2);
00643 return(-1);
00644 }
00645
00646
00647
00648 for (j = jst; j <= jfn; j++) {
00649 cpl_msg_info(fctid,"Beginning BPM work on extension %d",j);
00650 isfirst = (j == jst);
00651 dummy = 0;
00652 vircam_linearity_analyse_config.bad_pixel_stat = 0.0;
00653 vircam_linearity_analyse_config.bad_pixel_num = 0;
00654 vircam_linearity_analyse_config.linerror = 0.0;
00655 vircam_linearity_analyse_config.linearity = 0.0;
00656 vircam_linearity_analyse_config.facrng = 0.0;
00657 vircam_linearity_analyse_config.maxdiff = 0.0;
00658
00659
00660
00661 test = vircam_fits_load(cpl_frameset_get_first(ps.ddg[0].domes),
00662 CPL_TYPE_FLOAT,j);
00663 ps.plist = cpl_propertylist_duplicate(vircam_fits_get_phu(test));
00664 ps.elist = cpl_propertylist_duplicate(vircam_fits_get_ehu(test));
00665 ps.nx = cpl_image_get_size_x(vircam_fits_get_image(test));
00666 ps.ny = cpl_image_get_size_y(vircam_fits_get_image(test));
00667 vircam_fits_delete(test);
00668
00669
00670
00671
00672 ps.chantab = vircam_tfits_load(ps.chanfrm,j);
00673 if (ps.chantab == NULL) {
00674 cpl_msg_error(fctid,"Channel table extension %d failed to load",j);
00675 dummy = 1;
00676 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00677 return(-1);
00678 continue;
00679 } else if (vircam_chantab_verify(vircam_tfits_get_table(ps.chantab))
00680 != VIR_OK) {
00681 cpl_msg_error(fctid,"Channel table extension %d has errors",j);
00682 dummy = 1;
00683 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00684 return(-1);
00685 continue;
00686 }
00687 if (vircam_pfits_get_saturation(vircam_tfits_get_ehu(ps.chantab),
00688 &sat) != VIR_OK) {
00689 cpl_msg_error(fctid,"Channel table extension header %d missing saturation info",j);
00690 dummy = 1;
00691 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00692 return(-1);
00693 vircam_linearity_analyse_tidy(1);
00694 continue;
00695 }
00696
00697
00698
00699 vircam_chan_fill(vircam_tfits_get_table(ps.chantab),&pp,&np);
00700
00701
00702
00703 if (vircam_linearity_analyse_config.diagnostic) {
00704 ps.diag1 = vircam_linearity_analyse_diagtab_init(np,ps.ndomes);
00705 if (vircam_linearity_analyse_config.adjust)
00706 ps.diag2 = vircam_linearity_analyse_diagtab_init(np,ps.ndomecheck);
00707 }
00708
00709
00710
00711 if (vircam_pfits_get_detlive((const cpl_propertylist *)ps.elist,&live)
00712 != VIR_OK) {
00713 cpl_msg_error(fctid,"No DET LIVE keyword in this extension");
00714 dummy = 1;
00715 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00716 return(-1);
00717 vircam_linearity_analyse_tidy(1);
00718 continue;
00719 }
00720 if (! live) {
00721 cpl_msg_info(fctid,"Detector flagged dead");
00722 dummy = 1;
00723 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00724 return(-1);
00725 vircam_linearity_analyse_tidy(1);
00726 continue;
00727 }
00728
00729
00730
00731
00732 if (vircam_pfits_get_mindit((const cpl_propertylist *)ps.elist,
00733 &mindit) != VIR_OK) {
00734 cpl_msg_error(fctid,"No value of MINDIT found in extension %d",j);
00735 dummy = 1;
00736 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00737 return(-1);
00738 continue;
00739 }
00740
00741
00742
00743
00744
00745 ngood = 0;
00746 exps = cpl_malloc(ps.nddg*sizeof(float));
00747 ngood_flats = 0;
00748 for (i = 0; i < ps.nddg; i++) {
00749 test = vircam_fits_load(cpl_frameset_get_first(ps.ddg[i].domes),
00750 CPL_TYPE_FLOAT,j);
00751 med = cpl_image_get_median((const cpl_image*)vircam_fits_get_image(test));
00752 med *= (1.0 + mindit/ps.ddg[i].exptime);
00753 if (med > sat) {
00754 ps.ddg[i].flag = SATURATE_FLAG;
00755 } else {
00756 ngood++;
00757 exps[ngood-1] = ps.ddg[i].exptime;
00758 ngood_flats += ps.ddg[i].ndomes;
00759 }
00760 vircam_fits_delete(test);
00761 }
00762 exps = cpl_realloc(exps,ngood*sizeof(float));
00763
00764
00765
00766 if (ngood < vircam_linearity_analyse_config.norder+1) {
00767 cpl_msg_info(fctid,"Too few unsaturated flats for linearity fit for extension %d",j);
00768 dummy = 1;
00769 cpl_free(exps);
00770 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
00771 return(-1);
00772 continue;
00773 }
00774
00775
00776
00777 vircam_sort(&exps,ngood,1);
00778
00779
00780
00781
00782 nuse = min(vircam_linearity_analyse_config.maxbpmfr,ngood_flats);
00783 ps.nflatlist = 0;
00784 ps.flatlist = cpl_malloc(nuse*sizeof(vir_fits *));
00785 for (i = ngood-1; i >= 0; i--) {
00786 for (k = 0; k <= ps.nddg; k++) {
00787 if (ps.ddg[k].exptime == exps[i]) {
00788 krem = k;
00789 break;
00790 }
00791 }
00792
00793
00794
00795 darks = vircam_fits_load_list(ps.ddg[krem].darks,CPL_TYPE_FLOAT,j);
00796 ndarks = ps.ddg[krem].ndarks;
00797 if (darks == NULL) {
00798 cpl_msg_error(fctid,"Error loading darks extension %d, exptime %g",
00799 j,ps.ddg[krem].exptime);
00800 continue;
00801 }
00802
00803
00804
00805
00806 if (ndarks == 1) {
00807 outdark = vircam_fits_duplicate(darks[0]);
00808 } else {
00809 status = VIR_OK;
00810 (void)vircam_imcombine(darks,ndarks,1,1,1,5.0,&outimage,
00811 &rejmask,&rejplus,&drs,&status);
00812 freespace(rejmask);
00813 freespace(rejplus);
00814 freepropertylist(drs);
00815 if (status != VIR_OK) {
00816 cpl_msg_error(fctid,"Dark combine failure extension %d exposure %g",
00817 j,ps.ddg[krem].exptime);
00818 freefitslist(darks,ndarks);
00819 continue;
00820 }
00821 outdark = vircam_fits_wrap(outimage,darks[0],NULL,NULL);
00822 }
00823 freefitslist(darks,ndarks);
00824
00825
00826
00827 domes = vircam_fits_load_list(ps.ddg[krem].domes,CPL_TYPE_FLOAT,j);
00828 ndomes = ps.ddg[krem].ndomes;
00829 if (domes == NULL) {
00830 cpl_msg_error(fctid,"Error loading domes extension %d, exptime %g",
00831 j,ps.ddg[i].exptime);
00832 freefits(outdark);
00833 continue;
00834 }
00835
00836
00837
00838
00839 for (kk = 0; kk < ndomes; kk++) {
00840 status = VIR_OK;
00841 vircam_darkcor(domes[kk],outdark,1.0,&status);
00842 ps.flatlist[ps.nflatlist] = vircam_fits_duplicate(domes[kk]);
00843 ps.ddg[krem].proc[kk] = ps.flatlist[ps.nflatlist];
00844 ps.nflatlist++;
00845 if (ps.nflatlist == nuse)
00846 break;
00847 }
00848
00849
00850
00851 freefitslist(domes,ndomes);
00852 freefits(outdark);
00853
00854
00855
00856 if (ps.nflatlist == nuse)
00857 break;
00858 }
00859 freespace(exps);
00860 ps.flatlist = cpl_realloc(ps.flatlist,
00861 (ps.nflatlist)*sizeof(vir_fits *));
00862
00863
00864
00865 status = VIR_OK;
00866 (void)vircam_genbpm(ps.flatlist,ps.nflatlist,
00867 vircam_linearity_analyse_config.lthr,
00868 vircam_linearity_analyse_config.hthr,
00869 &(ps.bpm_array),&nbad,&badfrac,&status);
00870 bpm = cpl_array_get_data_int(ps.bpm_array);
00871
00872
00873
00874 vircam_linearity_analyse_config.bad_pixel_num = nbad;
00875 vircam_linearity_analyse_config.bad_pixel_stat = badfrac;
00876
00877
00878
00879
00880
00881 freespace(ps.flatlist);
00882 ps.nflatlist = 0;
00883
00884
00885
00886 nalloc = 16;
00887 fdata = cpl_malloc(nalloc*sizeof(double *));
00888 dexps = cpl_malloc(nalloc*sizeof(double));
00889 mjds = cpl_malloc(nalloc*sizeof(double));
00890
00891
00892
00893
00894
00895 cpl_msg_info(fctid,"Beginning linearity work on extension %d",j);
00896 nfdata = 0;
00897 outdark = NULL;
00898 for (i = 0; i < ps.nddg; i++) {
00899 if (ps.ddg[i].flag == SATURATE_FLAG)
00900 continue;
00901 for (k = 0; k < ps.ddg[i].ndomes; k++) {
00902
00903
00904
00905
00906 if (ps.ddg[i].proc[k] == NULL) {
00907 if (outdark == NULL) {
00908
00909
00910
00911 darks = vircam_fits_load_list(ps.ddg[i].darks,
00912 CPL_TYPE_FLOAT,j);
00913 ndarks = ps.ddg[i].ndarks;
00914 if (darks == NULL) {
00915 cpl_msg_error(fctid,"Error loading darks extension %d, exptime %g",
00916 j,ps.ddg[i].exptime);
00917 continue;
00918 }
00919
00920
00921
00922
00923
00924 if (ps.ddg[i].ndarks == 1) {
00925 outdark = vircam_fits_duplicate(darks[0]);
00926 } else {
00927 status = VIR_OK;
00928 (void)vircam_imcombine(darks,ndarks,1,1,1,5.0,
00929 &outimage,&rejmask,&rejplus,
00930 &drs,&status);
00931 freespace(rejmask);
00932 freespace(rejplus);
00933 freepropertylist(drs);
00934 if (status != VIR_OK) {
00935 cpl_msg_error(fctid,
00936 "Dark combine failure extension %d exposure %g",
00937 j,ps.ddg[i].exptime);
00938 freefitslist(darks,ndarks);
00939 continue;
00940 }
00941 outdark = vircam_fits_wrap(outimage,darks[0],
00942 NULL,NULL);
00943 }
00944 freefitslist(darks,ndarks);
00945 }
00946
00947
00948
00949 frame = cpl_frameset_get_frame(ps.ddg[i].domes,k);
00950 fframe = vircam_fits_load(frame,CPL_TYPE_FLOAT,j);
00951 vircam_darkcor(fframe,outdark,1.0,&status);
00952
00953
00954
00955 } else {
00956 fframe = ps.ddg[i].proc[k];
00957 }
00958
00959
00960
00961 d = vircam_linearity_analyse_genstat(fframe,bpm,pp,np);
00962 if (nfdata >= nalloc) {
00963 nalloc += 16;
00964 fdata = cpl_realloc(fdata,nalloc*sizeof(double *));
00965 dexps = cpl_realloc(dexps,nalloc*sizeof(double));
00966 mjds = cpl_realloc(mjds,nalloc*sizeof(double));
00967 }
00968 (void)vircam_pfits_get_mjd(vircam_fits_get_phu(fframe),&mjd);
00969 mjds[nfdata] = mjd;
00970 dexps[nfdata] = (double)(ps.ddg[i].exptime);
00971 fdata[nfdata] = d;
00972
00973
00974
00975
00976 if (ps.diag1 != NULL) {
00977 cpl_table_set_string(ps.diag1,"filename",nfdata,
00978 vircam_fits_get_filename(fframe));
00979 cpl_table_set_double(ps.diag1,"exptime",nfdata,
00980 dexps[nfdata]);
00981 cpl_table_set_double(ps.diag1,"mjd",nfdata,mjd);
00982 for (n = 1; n <= np; n++) {
00983 snprintf(colname,16,"rawflux_%02d",n);
00984 cpl_table_set_double(ps.diag1,colname,nfdata,d[n-1]);
00985 }
00986 }
00987 if (ps.ddg[i].proc[k] != NULL) {
00988 freefits(ps.ddg[i].proc[k]);
00989 } else {
00990 freefits(fframe);
00991 }
00992 nfdata++;
00993 }
00994 freefits(outdark);
00995 }
00996 freefits(outdark);
00997 if (ps.diag1 != NULL)
00998 cpl_table_set_size(ps.diag1,nfdata);
00999
01000
01001
01002
01003 if (vircam_linearity_analyse_config.adjust) {
01004
01005
01006
01007 cdata = cpl_malloc(ps.ndomecheck*sizeof(double *));
01008
01009
01010
01011
01012 test = vircam_fits_load(cpl_frameset_get_first(ps.domecheck),
01013 CPL_TYPE_FLOAT,j);
01014 (void)vircam_pfits_get_exptime(vircam_fits_get_phu(test),&exp);
01015 med = cpl_image_get_median((const cpl_image*)vircam_fits_get_image(test));
01016 med *= (1.0 + mindit/exp);
01017 adjust = 1;
01018 if (med > sat) {
01019 cpl_msg_info(fctid,"Monitor exposures saturated. No drift adjustment made");
01020 adjust = 0;
01021 }
01022 vircam_fits_delete(test);
01023
01024
01025
01026 if (adjust) {
01027
01028 darks = vircam_fits_load_list(ps.darkcheck,CPL_TYPE_FLOAT,j);
01029 ndarks = ps.ndarkcheck;
01030 if (darks == NULL) {
01031 cpl_msg_error(fctid,
01032 "Error loading check darks extension %d",j);
01033 continue;
01034 }
01035
01036
01037
01038
01039
01040 if (ndarks == 1) {
01041 outdark = vircam_fits_duplicate(darks[0]);
01042 } else {
01043 status = VIR_OK;
01044 (void)vircam_imcombine(darks,ndarks,1,1,1,5.0,
01045 &outimage,&rejmask,&rejplus,
01046 &drs,&status);
01047 freespace(rejmask);
01048 freespace(rejplus);
01049 freepropertylist(drs);
01050 if (status != VIR_OK) {
01051 cpl_msg_error(fctid,
01052 "Dark combine failure extension %d exposure %g",
01053 j,ps.ddg[irem].exptime);
01054 freefitslist(darks,ndarks);
01055 continue;
01056 }
01057 outdark = vircam_fits_wrap(outimage,darks[0],
01058 NULL,NULL);
01059 }
01060 freefitslist(darks,ndarks);
01061
01062
01063
01064
01065 mjdcheck = cpl_malloc(ps.ndomecheck*sizeof(double));
01066 for (i = 0; i < ps.ndomecheck; i++) {
01067 frame = cpl_frameset_get_frame(ps.domecheck,i);
01068 fframe = vircam_fits_load(frame,CPL_TYPE_FLOAT,j);
01069 vircam_darkcor(fframe,outdark,1.0,&status);
01070 d = vircam_linearity_analyse_genstat(fframe,bpm,pp,np);
01071 cdata[i] = d;
01072 vircam_pfits_get_mjd(vircam_fits_get_phu(fframe),&mjd);
01073 vircam_pfits_get_exptime(vircam_fits_get_phu(fframe),&exp);
01074 mjdcheck[i] = mjd;
01075
01076
01077
01078 if (ps.diag2 != NULL) {
01079 cpl_table_set_string(ps.diag2,"filename",i,
01080 vircam_fits_get_filename(fframe));
01081 cpl_table_set_double(ps.diag2,"exptime",i,(double)exp);
01082 cpl_table_set_double(ps.diag2,"mjd",i,mjd);
01083 for (n = 1; n <= np; n++) {
01084 snprintf(colname,16,"rawflux_%02d",n);
01085 cpl_table_set_double(ps.diag2,colname,i,
01086 d[n-1]);
01087 snprintf(colname,16,"linflux_%02d",n);
01088 cpl_table_set_double(ps.diag2,colname,i,
01089 d[n-1]);
01090 }
01091 }
01092 freefits(fframe);
01093 }
01094 freefits(outdark);
01095
01096
01097
01098 cf = vircam_linearity_tweakfac(cdata,mjdcheck,ps.ndomecheck,
01099 np,&facrng,&maxdiff);
01100 vircam_linearity_analyse_config.facrng = 100.0*(float)facrng;
01101 vircam_linearity_analyse_config.maxdiff = 100.0*(float)maxdiff;
01102 if (ps.diag2 != NULL) {
01103 for (i = 0; i < ps.ndomecheck; i++)
01104 cpl_table_set_double(ps.diag2,"adjust_fac",i,cf[i]);
01105 }
01106
01107
01108
01109
01110 for (i = 0; i < nfdata; i++) {
01111 mjd = mjds[i];
01112 krem = -1;
01113 for (k = 0; k < ps.ndomecheck; k++) {
01114 if (mjd < mjdcheck[k]) {
01115 krem = k;
01116 break;
01117 }
01118 }
01119 if (krem == -1) {
01120 fac = cf[ps.ndomecheck-1];
01121 } else if (krem == 0) {
01122 fac = cf[0];
01123 } else {
01124 fac = 0.5*(cf[krem -1] + cf[krem]);
01125 }
01126 for (k = 0; k < np; k++)
01127 fdata[i][k] /= fac;
01128 if (ps.diag1 != NULL)
01129 cpl_table_set_double(ps.diag1,"adjust_fac",i,fac);
01130 }
01131
01132
01133
01134 freespace2(cdata,ps.ndomecheck);
01135 freespace(cf);
01136 freespace(mjdcheck);
01137 }
01138 }
01139
01140
01141
01142 freespace(mjds);
01143 vircam_chan_free(np,&pp);
01144
01145
01146
01147
01148 (void)vircam_genlincur(fdata,nfdata,dexps,(double)mindit,ps.chantab,
01149 vircam_linearity_analyse_config.norder,
01150 &(ps.lchantab),&lindata,&status);
01151 if (ps.diag1 != NULL) {
01152 for (i = 0; i < nfdata; i++) {
01153 for (n = 0; n < np; n++) {
01154 snprintf(colname,16,"linflux_%02d",n+1);
01155 cpl_table_set_double(ps.diag1,colname,i,lindata[i*np+n]);
01156 }
01157 }
01158 }
01159 freespace2(fdata,nfdata);
01160 freespace(dexps);
01161 freespace(lindata);
01162 if (status != VIR_OK) {
01163 cpl_msg_error(fctid,"Linearity curve fit failed extension %d",j);
01164 dummy = 1;
01165 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
01166 return(-1);
01167 vircam_linearity_analyse_tidy(1);
01168 continue;
01169 }
01170
01171
01172
01173
01174 vircam_linearity_analyse_config.linearity =
01175 (float)cpl_table_get_column_mean(ps.lchantab,"lin_10000");
01176 vircam_linearity_analyse_config.linerror =
01177 (float)cpl_table_get_column_mean(ps.lchantab,"lin_10000_err");
01178
01179
01180
01181 if (vircam_linearity_analyse_lastbit(j,framelist,parlist) != 0)
01182 return(-1);
01183 }
01184
01185
01186
01187 vircam_linearity_analyse_tidy(2);
01188 return(0);
01189 }
01190
01191
01192
01199
01200
01201 static int vircam_linearity_analyse_save(cpl_frameset *framelist,
01202 cpl_parameterlist *parlist) {
01203 cpl_propertylist *plist,*elist,*pafprop;
01204 cpl_image *outimg;
01205 const char *outtab = "lchantab.fits";
01206 const char *outbpm = "bpm.fits";
01207 const char *outtabpaf = "lchantab";
01208 const char *outbpmpaf = "bpm";
01209 const char *outdiag1 = "ldiag1.fits";
01210 const char *outdiag2 = "ldiag2.fits";
01211 const char *fctid = "vircam_linearity_analyse_save";
01212 const char *recipeid = "vircam_linearity_analyse";
01213 int nx,ny,nord,*bpm,i;
01214
01215
01216
01217 nord = vircam_linearity_analyse_config.norder;
01218 if (isfirst) {
01219
01220
01221
01222 product_frame_chantab = cpl_frame_new();
01223 cpl_frame_set_filename(product_frame_chantab,outtab);
01224 cpl_frame_set_tag(product_frame_chantab,VIRCAM_PRO_CHANTAB);
01225 cpl_frame_set_type(product_frame_chantab,CPL_FRAME_TYPE_TABLE);
01226 cpl_frame_set_group(product_frame_chantab,CPL_FRAME_GROUP_PRODUCT);
01227 cpl_frame_set_level(product_frame_chantab,CPL_FRAME_LEVEL_FINAL);
01228
01229
01230
01231 ps.phupaf = vircam_paf_phu_items(ps.plist);
01232 plist = cpl_propertylist_duplicate(ps.plist);
01233 vircam_dfs_set_product_primary_header(plist,product_frame_chantab,
01234 ps.sorted,parlist,
01235 (char *)recipeid,
01236 "PRO-1.15");
01237
01238
01239
01240
01241 elist = cpl_propertylist_duplicate(ps.elist);
01242 vircam_dfs_set_product_exten_header(elist,product_frame_chantab,
01243 ps.sorted,parlist,
01244 (char *)recipeid,
01245 "PRO-1.15");
01246
01247
01248
01249 cpl_propertylist_update_float(elist,"ESO QC LINEARITY",
01250 vircam_linearity_analyse_config.linearity);
01251 cpl_propertylist_set_comment(elist,"ESO QC LINEARITY",
01252 "% non-linearity at 10000 ADU");
01253 cpl_propertylist_update_float(elist,"ESO QC LINERROR",
01254 vircam_linearity_analyse_config.linerror);
01255 cpl_propertylist_set_comment(elist,"ESO QC LINERROR",
01256 "% error non-linearity at 10000 ADU");
01257 cpl_propertylist_update_float(elist,"ESO QC SCREEN_TOTAL",
01258 vircam_linearity_analyse_config.facrng);
01259 cpl_propertylist_set_comment(elist,"ESO QC SCREEN_TOTAL",
01260 "total % range in screen variation");
01261 cpl_propertylist_update_float(elist,"ESO QC SCREEN_STEP",
01262 vircam_linearity_analyse_config.maxdiff);
01263 cpl_propertylist_set_comment(elist,"ESO QC SCREEN_STEP",
01264 "maximum % step in screen variation");
01265
01266
01267
01268 if (dummy == 1) {
01269 vircam_dummy_property(elist);
01270 if (ps.lchantab == NULL)
01271 ps.lchantab = vircam_chantab_new(nord,vircam_tfits_get_table(ps.chantab));
01272 }
01273
01274
01275
01276 if (cpl_table_save(ps.lchantab,plist,elist,outtab,CPL_IO_DEFAULT)
01277 != CPL_ERROR_NONE) {
01278 cpl_msg_error(fctid,"Cannot save product table extension");
01279 freepropertylist(plist);
01280 freepropertylist(elist);
01281 return(-1);
01282 }
01283 cpl_frameset_insert(framelist,product_frame_chantab);
01284
01285
01286
01287 pafprop = vircam_paf_req_items(elist);
01288 vircam_merge_propertylists(pafprop,ps.phupaf);
01289 vircam_paf_append(pafprop,ps.plist,"ESO INS FILT1 NAME");
01290 if (vircam_paf_print((char *)outtabpaf,"VIRCAM/vircam_linearity_analyse",
01291 "QC file",pafprop) != VIR_OK)
01292 cpl_msg_warning(fctid,"Unable to save PAF for linearity table");
01293 cpl_propertylist_delete(pafprop);
01294
01295
01296
01297 freepropertylist(plist);
01298 freepropertylist(elist);
01299
01300
01301
01302 product_frame_bpm = cpl_frame_new();
01303 cpl_frame_set_filename(product_frame_bpm,outbpm);
01304 cpl_frame_set_tag(product_frame_bpm,VIRCAM_PRO_BPM);
01305 cpl_frame_set_type(product_frame_bpm,CPL_FRAME_TYPE_IMAGE);
01306 cpl_frame_set_group(product_frame_bpm,CPL_FRAME_GROUP_PRODUCT);
01307 cpl_frame_set_level(product_frame_bpm,CPL_FRAME_LEVEL_FINAL);
01308
01309
01310
01311 plist = ps.plist;
01312 vircam_dfs_set_product_primary_header(plist,product_frame_bpm,
01313 ps.sorted,parlist,
01314 (char *)recipeid,
01315 "PRO-1.15");
01316
01317
01318
01319 if (cpl_image_save(NULL,outbpm,CPL_BPP_8_UNSIGNED,plist,
01320 CPL_IO_DEFAULT) != CPL_ERROR_NONE) {
01321 cpl_msg_error(fctid,"Cannot save product PHU");
01322 cpl_frame_delete(product_frame_bpm);
01323 return(-1);
01324 }
01325 cpl_frameset_insert(framelist,product_frame_bpm);
01326
01327
01328
01329
01330 if (ps.diag1 != NULL) {
01331
01332
01333
01334 product_frame_diag1 = cpl_frame_new();
01335 cpl_frame_set_filename(product_frame_diag1,outdiag1);
01336 cpl_frame_set_tag(product_frame_diag1,VIRCAM_PRO_LIN_DIAG1);
01337 cpl_frame_set_type(product_frame_diag1,CPL_FRAME_TYPE_TABLE);
01338 cpl_frame_set_group(product_frame_diag1,CPL_FRAME_GROUP_PRODUCT);
01339 cpl_frame_set_level(product_frame_diag1,CPL_FRAME_LEVEL_FINAL);
01340
01341
01342
01343 plist = cpl_propertylist_duplicate(ps.plist);
01344 vircam_dfs_set_product_primary_header(plist,product_frame_diag1,
01345 ps.sorted,parlist,
01346 (char *)recipeid,
01347 "PRO-1.15");
01348
01349
01350
01351
01352 elist = cpl_propertylist_duplicate(ps.elist);
01353 vircam_dfs_set_product_exten_header(elist,product_frame_diag1,
01354 ps.sorted,parlist,
01355 (char *)recipeid,
01356 "PRO-1.15");
01357
01358
01359
01360 if (dummy == 1)
01361 vircam_dummy_property(elist);
01362
01363
01364
01365 if (cpl_table_save(ps.diag1,plist,elist,outdiag1,CPL_IO_DEFAULT)
01366 != CPL_ERROR_NONE) {
01367 cpl_msg_error(fctid,"Cannot save product table extension");
01368 freepropertylist(plist);
01369 freepropertylist(elist);
01370 return(-1);
01371 }
01372 cpl_frameset_insert(framelist,product_frame_diag1);
01373 freepropertylist(plist);
01374 freepropertylist(elist);
01375 }
01376
01377
01378
01379 if (ps.diag2 != NULL) {
01380
01381
01382
01383 product_frame_diag2 = cpl_frame_new();
01384 cpl_frame_set_filename(product_frame_diag2,outdiag2);
01385 cpl_frame_set_tag(product_frame_diag2,VIRCAM_PRO_LIN_DIAG2);
01386 cpl_frame_set_type(product_frame_diag2,CPL_FRAME_TYPE_TABLE);
01387 cpl_frame_set_group(product_frame_diag2,CPL_FRAME_GROUP_PRODUCT);
01388 cpl_frame_set_level(product_frame_diag2,CPL_FRAME_LEVEL_FINAL);
01389
01390
01391
01392 plist = cpl_propertylist_duplicate(ps.plist);
01393 vircam_dfs_set_product_primary_header(plist,product_frame_diag2,
01394 ps.sorted,parlist,
01395 (char *)recipeid,
01396 "PRO-1.15");
01397
01398
01399
01400
01401 elist = cpl_propertylist_duplicate(ps.elist);
01402 vircam_dfs_set_product_exten_header(elist,product_frame_diag2,
01403 ps.sorted,parlist,
01404 (char *)recipeid,
01405 "PRO-1.15");
01406
01407
01408
01409 if (dummy == 1)
01410 vircam_dummy_property(elist);
01411
01412
01413
01414 if (cpl_table_save(ps.diag2,plist,elist,outdiag2,CPL_IO_DEFAULT)
01415 != CPL_ERROR_NONE) {
01416 cpl_msg_error(fctid,"Cannot save product table extension");
01417 freepropertylist(plist);
01418 freepropertylist(elist);
01419 return(-1);
01420 }
01421 cpl_frameset_insert(framelist,product_frame_diag2);
01422 freepropertylist(plist);
01423 freepropertylist(elist);
01424 }
01425
01426
01427
01428
01429 } else {
01430
01431
01432
01433 elist = cpl_propertylist_duplicate(ps.elist);
01434 vircam_dfs_set_product_exten_header(elist,product_frame_chantab,
01435 ps.sorted,parlist,
01436 (char *)recipeid,
01437 "PRO-1.15");
01438
01439
01440
01441 cpl_propertylist_update_float(elist,"ESO QC LINEARITY",
01442 vircam_linearity_analyse_config.linearity);
01443 cpl_propertylist_set_comment(elist,"ESO QC LINEARITY",
01444 "% non-linearity at 10000 ADU");
01445 cpl_propertylist_update_float(elist,"ESO QC LINERROR",
01446 vircam_linearity_analyse_config.linerror);
01447 cpl_propertylist_set_comment(elist,"ESO QC LINERROR",
01448 "% error non-linearity at 10000 ADU");
01449 cpl_propertylist_update_float(elist,"ESO QC SCREEN_TOTAL",
01450 vircam_linearity_analyse_config.facrng);
01451 cpl_propertylist_set_comment(elist,"ESO QC SCREEN_TOTAL",
01452 "total % range in screen variation");
01453 cpl_propertylist_update_float(elist,"ESO QC SCREEN_STEP",
01454 vircam_linearity_analyse_config.maxdiff);
01455 cpl_propertylist_set_comment(elist,"ESO QC SCREEN_STEP",
01456 "maximum % step in screen variation");
01457
01458
01459
01460 if (dummy == 1) {
01461 vircam_dummy_property(elist);
01462 if (ps.lchantab == NULL)
01463 ps.lchantab = vircam_chantab_new(nord,vircam_tfits_get_table(ps.chantab));
01464 }
01465
01466
01467
01468 if (cpl_table_save(ps.lchantab,NULL,elist,outtab,CPL_IO_EXTEND)
01469 != CPL_ERROR_NONE) {
01470 cpl_msg_error(fctid,"Cannot save product table extension");
01471 freepropertylist(elist);
01472 return(-1);
01473 }
01474
01475
01476
01477 pafprop = vircam_paf_req_items(elist);
01478 vircam_merge_propertylists(pafprop,ps.phupaf);
01479 vircam_paf_append(pafprop,ps.plist,"ESO INS FILT1 NAME");
01480 if (vircam_paf_print((char *)outtabpaf,"VIRCAM/vircam_linearity_analyse",
01481 "QC file",pafprop) != VIR_OK)
01482 cpl_msg_warning(fctid,"Unable to save PAF for BPM");
01483 cpl_propertylist_delete(pafprop);
01484
01485
01486
01487 freepropertylist(elist);
01488
01489
01490
01491 if (ps.diag1 != NULL) {
01492 elist = cpl_propertylist_duplicate(ps.elist);
01493 vircam_dfs_set_product_exten_header(elist,product_frame_diag1,
01494 ps.sorted,parlist,
01495 (char *)recipeid,
01496 "PRO-1.15");
01497
01498
01499
01500 if (dummy == 1)
01501 vircam_dummy_property(elist);
01502
01503
01504
01505 if (cpl_table_save(ps.diag1,NULL,elist,outdiag1,CPL_IO_EXTEND)
01506 != CPL_ERROR_NONE) {
01507 cpl_msg_error(fctid,"Cannot save product table extension");
01508 freepropertylist(elist);
01509 return(-1);
01510 }
01511 freepropertylist(elist);
01512 }
01513 if (ps.diag2 != NULL) {
01514 elist = cpl_propertylist_duplicate(ps.elist);
01515 vircam_dfs_set_product_exten_header(elist,product_frame_diag2,
01516 ps.sorted,parlist,
01517 (char *)recipeid,
01518 "PRO-1.15");
01519
01520
01521
01522 if (dummy == 1)
01523 vircam_dummy_property(elist);
01524
01525
01526
01527 if (cpl_table_save(ps.diag2,NULL,elist,outdiag2,CPL_IO_EXTEND)
01528 != CPL_ERROR_NONE) {
01529 cpl_msg_error(fctid,"Cannot save product table extension");
01530 freepropertylist(elist);
01531 return(-1);
01532 }
01533 freepropertylist(elist);
01534 }
01535
01536 }
01537
01538
01539
01540 plist = ps.elist;
01541 nx = ps.nx;
01542 ny = ps.ny;
01543 if (dummy && ps.bpm_array == NULL) {
01544 ps.bpm_array = cpl_array_new(nx*ny,CPL_TYPE_INT);
01545 bpm = cpl_array_get_data_int(ps.bpm_array);
01546 for (i = 0; i < nx*ny; i++)
01547 bpm[i] = 0;
01548 }
01549 bpm = cpl_array_get_data_int(ps.bpm_array);
01550 vircam_dfs_set_product_exten_header(plist,product_frame_bpm,
01551 ps.sorted,parlist,
01552 (char *)recipeid,
01553 "PRO-1.15");
01554 cpl_propertylist_update_float(plist,"ESO QC BAD_PIXEL_STAT",
01555 vircam_linearity_analyse_config.bad_pixel_stat);
01556 cpl_propertylist_set_comment(plist,"ESO QC BAD_PIXEL_STAT",
01557 "Fraction of pixels that are bad");
01558 cpl_propertylist_update_int(plist,"ESO QC BAD_PIXEL_NUM",
01559 vircam_linearity_analyse_config.bad_pixel_num);
01560 cpl_propertylist_set_comment(plist,"ESO QC BAD_PIXEL_NUM",
01561 "Number of pixels that are bad");
01562 if (dummy)
01563 vircam_dummy_property(plist);
01564 outimg = cpl_image_wrap_int(nx,ny,bpm);
01565 if (cpl_image_save(outimg,outbpm,CPL_BPP_8_UNSIGNED,plist,
01566 CPL_IO_EXTEND) != CPL_ERROR_NONE) {
01567 cpl_msg_error(fctid,"Cannot save product image extension");
01568 return(-1);
01569 }
01570
01571
01572
01573 pafprop = vircam_paf_req_items(plist);
01574 vircam_merge_propertylists(pafprop,ps.phupaf);
01575 vircam_paf_append(pafprop,ps.plist,"ESO INS FILT1 NAME");
01576 if (vircam_paf_print((char *)outbpmpaf,"VIRCAM/vircam_linearity_analyse",
01577 "QC file",pafprop) != VIR_OK)
01578 cpl_msg_warning(fctid,"Unable to save PAF for linearity table");
01579 cpl_propertylist_delete(pafprop);
01580
01581
01582
01583 cpl_image_unwrap(outimg);
01584
01585 return(0);
01586 }
01587
01588
01596
01597
01598 static int vircam_linearity_analyse_lastbit(int jext, cpl_frameset *framelist,
01599 cpl_parameterlist *parlist) {
01600 int retval;
01601 const char *fctid = "vircam_linearity_analyse_lastbit";
01602
01603
01604
01605 cpl_msg_info(fctid,"Saving linearity table and bpm for extension %d",jext);
01606 retval = vircam_linearity_analyse_save(framelist,parlist);
01607 if (retval != 0) {
01608 vircam_linearity_analyse_tidy(2);
01609 return(-1);
01610 }
01611
01612
01613
01614 vircam_linearity_analyse_tidy(1);
01615 return(0);
01616 }
01617
01618
01622
01623
01624 static int vircam_linearity_analyse_domedark_groups(void) {
01625 int i,j,found;
01626 float texp;
01627 cpl_frame *frame;
01628 cpl_propertylist *plist;
01629 const char *fctid = "vircam_linearity_analyse_domedark_groups";
01630
01631
01632
01633 ps.ddg = cpl_calloc(ps.ndomes,sizeof(ddgrp));
01634 ps.nddg = 0;
01635
01636
01637
01638
01639 for (i = 0; i < ps.ndomes; i++) {
01640 frame = cpl_frameset_get_frame(ps.domelist,i);
01641 plist = cpl_propertylist_load(cpl_frame_get_filename(frame),0);
01642 if (vircam_pfits_get_exptime(plist,&texp) != VIR_OK) {
01643 cpl_msg_warning(fctid,"No exposure time found in %s",
01644 cpl_frame_get_filename(frame));
01645 cpl_propertylist_delete(plist);
01646 continue;
01647 }
01648 cpl_propertylist_delete(plist);
01649
01650
01651
01652
01653
01654 found = 0;
01655 for (j = 0; j < ps.nddg; j++) {
01656 if (ps.ddg[j].exptime == texp) {
01657 found = 1;
01658 break;
01659 }
01660 }
01661 if (found) {
01662 cpl_frameset_insert(ps.ddg[j].domes,cpl_frame_duplicate(frame));
01663 ps.ddg[j].ndomes += 1;
01664 } else {
01665 ps.ddg[ps.nddg].exptime = texp;
01666 ps.ddg[ps.nddg].darks = cpl_frameset_new();
01667 ps.ddg[ps.nddg].domes = cpl_frameset_new();
01668 ps.ddg[ps.nddg].ndarks = 0;
01669 ps.ddg[ps.nddg].ndomes = 1;
01670 ps.ddg[ps.nddg].flag = OK_FLAG;
01671 cpl_frameset_insert(ps.ddg[ps.nddg].domes,
01672 cpl_frame_duplicate(frame));
01673 ps.nddg += 1;
01674 }
01675 }
01676
01677
01678
01679 for (i = 0; i < ps.ndarks; i++) {
01680 frame = cpl_frameset_get_frame(ps.darklist,i);
01681 plist = cpl_propertylist_load(cpl_frame_get_filename(frame),0);
01682 if (vircam_pfits_get_exptime(plist,&texp) != VIR_OK) {
01683 cpl_msg_warning(fctid,"No exposure time found in %s",
01684 cpl_frame_get_filename(frame));
01685 cpl_propertylist_delete(plist);
01686 continue;
01687 }
01688 cpl_propertylist_delete(plist);
01689
01690
01691
01692
01693
01694 found = 0;
01695 for (j = 0; j < ps.nddg; j++) {
01696 if (ps.ddg[j].exptime == texp) {
01697 found = 1;
01698 break;
01699 }
01700 }
01701 if (found) {
01702 cpl_frameset_insert(ps.ddg[j].darks,cpl_frame_duplicate(frame));
01703 ps.ddg[j].ndarks += 1;
01704 }
01705 }
01706
01707
01708
01709
01710 i = 0;
01711 while (i < ps.nddg) {
01712 if (ps.ddg[i].ndarks == 0) {
01713 cpl_msg_error(fctid,"No dark frames exist for exposure %g\n",
01714 ps.ddg[i].exptime);
01715 freeframeset(ps.ddg[i].darks);
01716 freeframeset(ps.ddg[i].domes);
01717 for (j = i+1; j < ps.nddg; j++)
01718 ps.ddg[j-1] = ps.ddg[j];
01719 ps.nddg -= 1;
01720 } else
01721 i++;
01722 }
01723
01724
01725
01726 for (i = 0; i < ps.nddg; i++) {
01727 ps.ddg[i].proc = cpl_malloc(ps.ddg[i].ndomes*sizeof(vir_fits *));
01728 for (j = 0; j < ps.ddg[i].ndomes; j++)
01729 ps.ddg[i].proc[j] = NULL;
01730 }
01731
01732
01733
01734
01735 if (ps.nddg > 0) {
01736 ps.ddg = cpl_realloc(ps.ddg,ps.nddg*sizeof(ddgrp));
01737 return(0);
01738 } else {
01739 cpl_msg_error(fctid,"There are no darks defined for input domes");
01740 return(-1);
01741 }
01742 }
01743
01744
01753
01754
01755 static double *vircam_linearity_analyse_genstat(vir_fits *fframe, int *bpm,
01756 parquet *p, int np) {
01757 int i,ist,ifn,jst,jfn,n,jind2,iind2,jj,nx,ii;
01758 parquet *pp;
01759 double *d;
01760 float *tmp,*data;
01761
01762
01763
01764 d = cpl_malloc(np*sizeof(double));
01765
01766
01767
01768 nx = cpl_image_get_size_x(vircam_fits_get_image(fframe));
01769 data = cpl_image_get_data_float(vircam_fits_get_image(fframe));
01770
01771
01772
01773 tmp = cpl_malloc(SUBSET*SUBSET*sizeof(float));
01774
01775
01776
01777 for (i = 0; i < np; i++) {
01778 pp = p + i;
01779
01780
01781
01782 ist = ((pp->delta_i)/2 - SUBSET2);
01783 ifn = ist + SUBSET - 1;
01784 jst = ((pp->delta_j)/2 - SUBSET2);
01785 jfn = jst + SUBSET - 1;
01786
01787
01788
01789 n = 0;
01790 for (jj = jst; jj <= jfn; jj++) {
01791 jind2 = (jj + pp->iymin - 1)*nx;
01792 for (ii = ist; ii <= ifn; ii++) {
01793 iind2 = jind2 + ii + pp->ixmin - 1;
01794 if (bpm[iind2] == 0)
01795 tmp[n++] = data[iind2];
01796 }
01797 }
01798 d[i] = (double)vircam_med(tmp,NULL,(long)n);
01799 }
01800
01801
01802
01803 freespace(tmp);
01804 return(d);
01805 }
01806
01807
01819
01820
01821 static double *vircam_linearity_tweakfac(double **fdata, double *mjd, int nim,
01822 int nchan, double *facrng,
01823 double *maxdiff) {
01824 int i,ist,ifn,j;
01825 double *factors,sum,midval,minfac,maxfac;
01826
01827
01828
01829 factors = cpl_malloc(nim*sizeof(double));
01830
01831
01832
01833 vircam_mjdsort(fdata,mjd,nim);
01834
01835
01836
01837 if (nim % 2 == 0) {
01838 ist = nim/2 - 1;
01839 ifn = ist + 1;
01840 } else {
01841 ist = nim/2;
01842 ifn = ist;
01843 }
01844
01845
01846
01847 for (i = 0; i < nchan; i++) {
01848
01849
01850
01851 midval = 0.5*(fdata[ist][i] + fdata[ifn][i]);
01852
01853
01854
01855 for (j = 0; j < nim; j++)
01856 fdata[j][i] /= midval;
01857 }
01858
01859
01860
01861
01862 *maxdiff = 0.0;
01863 for (j = 0; j < nim; j++) {
01864 sum = 0.0;
01865 for (i = 0; i < nchan; i++)
01866 sum += fdata[j][i];
01867 factors[j] = sum/(double)nchan;
01868 if (j == 0) {
01869 maxfac = factors[j];
01870 minfac = factors[j];
01871 } else {
01872 minfac = min(minfac,factors[j]);
01873 maxfac = max(maxfac,factors[j]);
01874 *maxdiff = max(*maxdiff,fabs(factors[j]-factors[j-1]));
01875 }
01876 }
01877 *facrng = maxfac - minfac;
01878
01879
01880
01881 return(factors);
01882 }
01883
01884
01892
01893
01894 static void vircam_mjdsort(double **fdata, double *mjd, int n) {
01895 int iii,ii,i,ifin,j,it;
01896 double tmpmjd,*tmpdata;
01897
01898
01899 iii = 2;
01900 while (iii < n)
01901 iii *= 2;
01902 iii = min(n,(3*iii)/4 - 1);
01903
01904 while (iii > 1) {
01905 iii /= 2;
01906 ifin = n - iii;
01907 for (ii = 0; ii < ifin; ii++) {
01908 i = ii;
01909 j = i + iii;
01910 if (mjd[i] > mjd[j]) {
01911 tmpmjd = mjd[j];
01912 tmpdata = fdata[j];
01913 while (1) {
01914 mjd[j] = mjd[i];
01915 fdata[j] = fdata[i];
01916 j = i;
01917 i = i - iii;
01918 if (i < 0 || mjd[0] <= tmpmjd)
01919 break;
01920 }
01921 mjd[j] = tmpmjd;
01922 fdata[j] = tmpdata;
01923 }
01924 }
01925 }
01926 }
01927
01928
01935
01936
01937 static cpl_table *vircam_linearity_analyse_diagtab_init(int np, int nrows) {
01938 int i;
01939 char colname[16];
01940 cpl_table *t;
01941
01942
01943
01944 t = cpl_table_new(nrows);
01945
01946
01947
01948 cpl_table_new_column(t,"filename",CPL_TYPE_STRING);
01949 cpl_table_new_column(t,"exptime",CPL_TYPE_DOUBLE);
01950 cpl_table_set_column_unit(t,"exptime","seconds");
01951 cpl_table_new_column(t,"mjd",CPL_TYPE_DOUBLE);
01952 cpl_table_set_column_unit(t,"mjd","days");
01953
01954
01955
01956
01957 for (i = 1; i <= 16; i++) {
01958 (void)snprintf(colname,16,"rawflux_%02d",i);
01959 cpl_table_new_column(t,colname,CPL_TYPE_DOUBLE);
01960 cpl_table_set_column_unit(t,colname,"ADU");
01961 (void)snprintf(colname,16,"linflux_%02d",i);
01962 cpl_table_new_column(t,colname,CPL_TYPE_DOUBLE);
01963 cpl_table_set_column_unit(t,colname,"ADU");
01964 }
01965
01966
01967
01968 cpl_table_new_column(t,"adjust_fac",CPL_TYPE_DOUBLE);
01969
01970
01971
01972 return(t);
01973 }
01974
01975
01979
01980
01981 static void vircam_linearity_analyse_init(void) {
01982 ps.labels = NULL;
01983 ps.domelist = NULL;
01984 ps.darklist = NULL;
01985 ps.domecheck = NULL;
01986 ps.darkcheck = NULL;
01987 ps.ndomes = 0;
01988 ps.ndarks = 0;
01989 ps.ndomecheck = 0;
01990 ps.ndarkcheck = 0;
01991 ps.chanfrm = NULL;
01992 ps.chantab = NULL;
01993 ps.lchantab = NULL;
01994 ps.flatlist = NULL;
01995 ps.bpm_array = NULL;
01996 ps.ddg = NULL;
01997 ps.plist = NULL;
01998 ps.elist = NULL;
01999 ps.phupaf = NULL;
02000 ps.diag1 = NULL;
02001 ps.diag2 = NULL;
02002 }
02003
02004
02008
02009
02010 static void vircam_linearity_analyse_tidy(int level) {
02011 int i;
02012
02013 freetfits(ps.chantab);
02014 freearray(ps.bpm_array);
02015 freefitslist(ps.flatlist,ps.nflatlist);
02016 freetable(ps.lchantab);
02017 freepropertylist(ps.plist);
02018 freepropertylist(ps.elist);
02019 freetable(ps.diag1);
02020 freetable(ps.diag2);
02021 if (level == 1)
02022 return;
02023
02024 freespace(ps.labels);
02025 freeframeset(ps.domelist);
02026 freeframeset(ps.darklist);
02027 freeframeset(ps.domecheck);
02028 freeframeset(ps.darkcheck);
02029 freeframeset(ps.sorted);
02030 freeframe(ps.chanfrm);
02031 if (ps.ddg != NULL) {
02032 for (i = 0; i < ps.nddg; i++) {
02033 freeframeset(ps.ddg[i].darks);
02034 freeframeset(ps.ddg[i].domes);
02035 freefitslist(ps.ddg[i].proc,ps.ddg[i].ndomes);
02036 }
02037 freespace(ps.ddg);
02038 }
02039 freepropertylist(ps.phupaf);
02040 }
02041
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065
02066
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211
02212
02213
02214
02215
02216