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 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #ifdef HAVE_SFFTW
00037 #include <complex.h>
00038 #include <sfftw.h>
00039 #endif
00040
00041 #include <math.h>
00042 #include <string.h>
00043 #include <assert.h>
00044 #include <float.h>
00045
00046 #include <cpl.h>
00047
00048 #include "irplib_detmon.h"
00049
00050 #include "irplib_hist.h"
00051 #include "irplib_utils.h"
00052
00053
00054
00055 #define pdist(x1,y1,x2,y2) (((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))
00056
00057 #define cpl_drand() ((double)rand()/(double)RAND_MAX)
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #define HIST_FACT 2.354820045
00073
00074 enum pixeltypes
00075 {
00076 HOT = 0,
00077 DEAD = 1,
00078 NOISY = 2
00079 };
00080
00081 enum stackingtypes
00082 {
00083 MINMAX = 0,
00084 MEAN = 1,
00085 MEDIAN = 2,
00086 KSIGMA = 3
00087 };
00088
00089 enum readouts
00090 {
00091 HORIZONTAL = 1,
00092 VERTICAL = 2
00093 };
00094
00095
00096 static struct
00097 {
00098
00099 const char *method;
00100 const char *pmethod;
00101 ronbias_method method_bitmask;
00102 int prescan_llx;
00103 int prescan_lly;
00104 int prescan_urx;
00105 int prescan_ury;
00106 int overscan_llx;
00107 int overscan_lly;
00108 int overscan_urx;
00109 int overscan_ury;
00110 int preoverscan_degree;
00111 int random_nsamples;
00112 int random_sizex;
00113 int random_sizey;
00114 int criteria;
00115 int ref_llx;
00116 int ref_lly;
00117 int ref_urx;
00118 int ref_ury;
00119 const char *stacking_method;
00120 int stacking_ks_low;
00121 int stacking_ks_high;
00122 int stacking_ks_iter;
00123 int master_shift_x;
00124 int master_shift_y;
00125 int ron_llx;
00126 int ron_lly;
00127 int ron_urx;
00128 int ron_ury;
00129 int exts;
00130 int nb_extensions;
00131 } detmon_ronbias_config;
00132
00133 static struct
00134 {
00135 int mode;
00136 cpl_boolean direction;
00137 double speed;
00138 int llx;
00139 int lly;
00140 int urx;
00141 int ury;
00142 int kappa;
00143 int exts;
00144 int nb_extensions;
00145 } detmon_pernoise_config;
00146
00147 static struct
00148 {
00149 const char * ron_method;
00150 const char * dsnu_method;
00151 int exts;
00152 int nb_extensions;
00153 cpl_boolean opt_nir;
00154 } detmon_dark_config;
00155
00156 #define NIR TRUE
00157 #define OPT FALSE
00158
00159
00160
00161
00162
00163 static cpl_error_code
00164 irplib_ksigma_clip_double(const double * pi,
00165 int llx,
00166 int lly,
00167 int urx,
00168 int ury,
00169 int nx,
00170 double var_sum,
00171 int npixs,
00172 double kappa,
00173 int nclip,
00174 double tolerance,
00175 double * mean,
00176 double * stdev);
00177
00178 static cpl_error_code
00179 irplib_ksigma_clip_float(const float * pi,
00180 int llx,
00181 int lly,
00182 int urx,
00183 int ury,
00184 int nx,
00185 double var_sum,
00186 int npixs,
00187 double kappa,
00188 int nclip,
00189 double tolerance,
00190 double * mean,
00191 double * stdev);
00192
00193 static cpl_error_code
00194 irplib_ksigma_clip_int(const int * pi,
00195 int llx,
00196 int lly,
00197 int urx,
00198 int ury,
00199 int nx,
00200 double var_sum,
00201 int npixs,
00202 double kappa,
00203 int nclip,
00204 double tolerance,
00205 double * mean,
00206 double * stdev);
00207
00208
00209
00210
00211 static cpl_error_code
00212 irplib_detmon_ronbias_retrieve_parlist(const char *,
00213 const char *,
00214 const cpl_parameterlist *,
00215 cpl_boolean);
00216
00217 static cpl_error_code
00218 irplib_detmon_ronbias_random(const cpl_imagelist *,
00219 const cpl_image *, cpl_propertylist *);
00220
00221 static cpl_error_code
00222 irplib_detmon_ronbias_histo(const cpl_imagelist *,
00223 const cpl_image *, cpl_propertylist *);
00224
00225 static cpl_error_code
00226 irplib_detmon_ronbias_preoverscan(const cpl_imagelist *,
00227 cpl_propertylist *, cpl_image **);
00228
00229 static cpl_error_code
00230 irplib_detmon_ronbias_region(const cpl_imagelist *,
00231 const cpl_image *, cpl_propertylist *);
00232
00233 static cpl_image *
00234 irplib_detmon_ronbias_master(const cpl_imagelist *,
00235 cpl_mask **, cpl_mask **, cpl_mask **,
00236 cpl_propertylist *);
00237
00238 static cpl_error_code
00239 irplib_detmon_ronbias_save(const cpl_parameterlist *,
00240 cpl_frameset *,
00241 const char *,
00242 const char *,
00243 const char *,
00244 const cpl_propertylist *,
00245 const cpl_propertylist *,
00246 const cpl_propertylist *,
00247 const cpl_propertylist *,
00248 const cpl_propertylist *,
00249 const cpl_propertylist *,
00250 const cpl_propertylist *,
00251 const char *,
00252 const cpl_image *,
00253 const cpl_image *,
00254 const cpl_mask *,
00255 const cpl_mask *,
00256 const cpl_mask *,
00257 cpl_propertylist *,
00258 const int,
00259 const int,
00260 cpl_frameset *,
00261 int);
00262
00263 int
00264 irplib_detmon_ronbias_dfs_set_groups(cpl_frameset *, const char *);
00265
00266 static cpl_image *
00267 irplib_detmon_build_synthetic(cpl_image *,
00268 cpl_image *);
00269
00270 static cpl_error_code
00271 irplib_detmon_ronbias_histo_reduce(const cpl_image * c_raw,
00272 double * bias,
00273 double * fwhm,
00274 double * max);
00275
00276 static cpl_error_code
00277 irplib_detmon_ronbias_dutycycl(const cpl_frameset *, cpl_propertylist *);
00278
00279 cpl_error_code
00280 irplib_detmon_rm_bpixs(cpl_image **,
00281 const double,
00282 int ,
00283 int );
00284
00285
00286
00287 static cpl_error_code
00288 irplib_flux_get_bias_window(const cpl_image *,
00289 const int *,
00290 int ,
00291 int ,
00292 double *,
00293 double *);
00294
00295 static cpl_bivector *
00296 irplib_bivector_gen_rect_poisson(const int *r,
00297 const int np,
00298 const int homog);
00299
00300
00301
00302
00303 cpl_error_code
00304 irplib_detmon_ronbias_check_defaults(const cpl_frameset *, const int whichext);
00305
00306
00307
00308
00309 int
00310 irplib_detmon_pernoise_dfs_set_groups(cpl_frameset *,
00311 const char *);
00312
00313 static cpl_error_code
00314 irplib_detmon_pernoise_retrieve_parlist(const char *,
00315 const char *,
00316 const cpl_parameterlist *);
00317
00318 static cpl_error_code
00319 irplib_detmon_pernoise_qc(cpl_propertylist *,
00320 cpl_table *,
00321 int);
00322
00323 static cpl_error_code
00324 irplib_detmon_pernoise_save(const cpl_parameterlist *,
00325 cpl_frameset *,
00326 const char *,
00327 const char *,
00328 const char *,
00329 const char *,
00330 cpl_table **,
00331 cpl_propertylist **,
00332 const int,
00333 const int,
00334 const cpl_frameset *);
00335
00336 cpl_error_code
00337 irplib_detmon_pernoise_rm_bg(cpl_image *,
00338 int,
00339 int);
00340
00341 int
00342 irplib_detmon_dark_dfs_set_groups(cpl_frameset *,
00343 const char *);
00344
00345 cpl_error_code
00346 irplib_detmon_dark_dsnu(cpl_frameset *,
00347 cpl_imagelist *,
00348 cpl_table *,
00349 cpl_image *,
00350 int pos);
00351
00352
00353 static cpl_error_code
00354 irplib_detmon_dark_save(const cpl_parameterlist *,
00355 cpl_frameset *,
00356 const char *,
00357 const char *,
00358 const char *,
00359 const char *,
00360 const char *,
00361 const char *,
00362 cpl_imagelist **,
00363 cpl_table **,
00364 cpl_imagelist **,
00365 cpl_propertylist **,
00366 const int,
00367 const int,
00368 const cpl_frameset *);
00369
00370
00371
00372 static cpl_error_code
00373 irplib_detmon_retrieve_dark_params(const char *,
00374 const char *,
00375 const cpl_parameterlist *);
00376
00377 cpl_error_code
00378 irplib_detmon_dark_qc(cpl_propertylist *,
00379 cpl_image *);
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400 cpl_error_code
00401 irplib_detmon_ronbias_fill_parlist_default(cpl_parameterlist * parlist,
00402 const char *recipe_name,
00403 const char *pipeline_name)
00404 {
00405 const cpl_error_code error =
00406 irplib_detmon_ronbias_fill_parlist(parlist, recipe_name, pipeline_name,
00407 "ALL",
00408 "NORM",
00409 1,
00410 -1,
00411 -1,
00412 -1,
00413 0,
00414 -1,
00415 -1,
00416 -1,
00417 -1,
00418 "MEAN",
00419 3,
00420 3,
00421 5,
00422 0,
00423 0,
00424 -1,
00425 -1,
00426 -1,
00427 -1,
00428 0,
00429 OPT);
00430 cpl_ensure_code(!error, error);
00431
00432 return cpl_error_get_code();
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 cpl_error_code
00451 irplib_detmon_darkron_fill_parlist_default(cpl_parameterlist * parlist,
00452 const char *recipe_name,
00453 const char *pipeline_name)
00454 {
00455 const cpl_error_code error =
00456 irplib_detmon_ronbias_fill_parlist(parlist, recipe_name, pipeline_name,
00457 "ALL",
00458 "NORM",
00459 1,
00460 -1,
00461 -1,
00462 -1,
00463 0,
00464 -1,
00465 -1,
00466 -1,
00467 -1,
00468 "MEAN",
00469 3,
00470 3,
00471 5,
00472 0,
00473 0,
00474 -1,
00475 -1,
00476 -1,
00477 -1,
00478 0,
00479 NIR);
00480 cpl_ensure_code(!error, error);
00481
00482 return cpl_error_get_code();
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523 cpl_error_code
00524 irplib_detmon_ronbias_fill_parlist(cpl_parameterlist * parlist,
00525 const char *recipe_name,
00526 const char *pipeline_name,
00527 const char * method,
00528 const char * pmethod,
00529 const int preoverscan_degree,
00530 const int random_nsamples,
00531 const int random_sizex,
00532 const int random_sizey,
00533 const int criteria,
00534 const int ref_llx,
00535 const int ref_lly,
00536 const int ref_urx,
00537 const int ref_ury,
00538 const char * stacking_method,
00539 const int stacking_ks_low,
00540 const int stacking_ks_high,
00541 const int stacking_ks_iter,
00542 const int master_shift_x,
00543 const int master_shift_y,
00544 const int ron_llx,
00545 const int ron_lly,
00546 const int ron_urx,
00547 const int ron_ury,
00548 const int exts,
00549 cpl_boolean opt_nir)
00550 {
00551
00552 const char * meth_desc_opt =
00553 "Method to be used when computing bias. Methods appliable: "
00554 "<RANDOM | HISTO | PREOVERSCAN | REGION | ALL>. By default ALL "
00555 "methods are applied. More than a method can be chosen; in that "
00556 "case selected methods must be separated by a single space and put "
00557 "together between inverted commas (ex. --method=\"HISTO REGION\")."
00558 "\n RANDOM: Bias is computed as the mean value on a given number "
00559 "(--random.nsamples) of boxes (dimensions --random.sizex and "
00560 "--random.sizey) randomly taken accross the detector.\n HISTO: "
00561 "An histogram of the pixels of the image is built.\n PREOVERSCAN: "
00562 "Mean, median and RMS values computed and designated areas. \n "
00563 "REGION: Mean, median and RMS values on reference region.";
00564
00565 const char * meth_desc_nir =
00566 "Method to be used when computing bias. Methods appliable: "
00567 "<RANDOM | HISTO | REGION | ALL>. By default ALL "
00568 "methods are applied. More than a method can be chosen; in that "
00569 "case selected methods must be separated by a single space and put "
00570 "together between inverted commas (ex. --method=\"HISTO REGION\")."
00571 "\n RANDOM: Bias is computed as the mean value on a given number "
00572 "(--random.nsamples) of boxes (dimensions --random.sizex and "
00573 "--random.sizey) randomly taken accross the detector.\n HISTO: "
00574 "An histogram of the pixels of the image is built.\n "
00575 "REGION: Mean, median and RMS values on reference region.";
00576
00577 const char * method_desc = opt_nir == OPT ? meth_desc_opt : meth_desc_nir;
00578
00579 const cpl_error_code error =
00580 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 22,
00581 "method",
00582 method_desc,
00583 "CPL_TYPE_STRING", method,
00584
00585 "pmethod",
00586 "Pre-method for RANDOM, HISTO and REGION."
00587 "Difference raw frames or not",
00588 "CPL_TYPE_STRING", pmethod,
00589
00590 "preoverscan.degree",
00591 "Degree used for pre-overscan method",
00592 "CPL_TYPE_INT", preoverscan_degree,
00593
00594 "random.nsamples",
00595 "Number of samples",
00596 "CPL_TYPE_INT", random_nsamples,
00597
00598 "random.sizex",
00599 "X size of the boxes",
00600 "CPL_TYPE_INT", random_sizex,
00601
00602 "random.sizey",
00603 "Y size of the boxes",
00604 "CPL_TYPE_INT", random_sizey,
00605
00606 "criteria",
00607 "Criteria",
00608 "CPL_TYPE_INT", criteria,
00609
00610 "ref.llx",
00611 "x coordinate of the lower-left point "
00612 "of the reference region of the frame",
00613 "CPL_TYPE_INT", ref_llx,
00614
00615 "ref.lly",
00616 "y coordinate of the lower-left point "
00617 "of the reference region of the frame",
00618 "CPL_TYPE_INT", ref_lly,
00619
00620 "ref.urx",
00621 "x coordinate of the upper-right point "
00622 "of the reference region of the frame",
00623 "CPL_TYPE_INT", ref_urx,
00624
00625 "ref.ury",
00626 "y coordinate of the upper-right point "
00627 "of the reference region of the frame",
00628 "CPL_TYPE_INT", ref_ury,
00629
00630 "stacking.method",
00631 "Method to be used when stacking the master. Posible values < MINMAX | MEAN | MEDIAN | KSIGMA >",
00632 "CPL_TYPE_STRING", stacking_method,
00633
00634 "stacking.ks.low",
00635 "Low threshold for kappa-sigma clipping",
00636 "CPL_TYPE_INT", stacking_ks_low,
00637
00638 "stacking.ks.high",
00639 "High threshold for kappa-sigma clipping",
00640 "CPL_TYPE_INT", stacking_ks_high,
00641
00642 "stacking.ks.iter",
00643 "Nb of iterations for kappa-sigma clipping",
00644 "CPL_TYPE_INT", stacking_ks_iter,
00645
00646 "master.shift.x",
00647 "Master shift X",
00648 "CPL_TYPE_INT", master_shift_x,
00649
00650 "master.shift.y",
00651 "Master shift Y",
00652 "CPL_TYPE_INT", master_shift_y,
00653
00654 "ron.llx",
00655 "x coordinate of the lower-left point "
00656 "of the RON frame",
00657 "CPL_TYPE_INT", ron_llx,
00658
00659 "ron.lly",
00660 "y coordinate of the lower-left point "
00661 "of the RON frame",
00662 "CPL_TYPE_INT", ron_lly,
00663
00664 "ron.urx",
00665 "x coordinate of the upper-right point "
00666 "of the RON frame",
00667 "CPL_TYPE_INT", ron_urx,
00668
00669 "ron.ury",
00670 "y coordinate of the upper-right point "
00671 "of the RON frame", "CPL_TYPE_INT", ron_ury,
00672
00673 "exts",
00674 "Activate the multi-exts option",
00675 "CPL_TYPE_INT", exts);
00676
00677
00678 cpl_ensure_code(!error, error);
00679
00680 return cpl_error_get_code();
00681 }
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 cpl_error_code
00700 irplib_detmon_fill_parlist(cpl_parameterlist * parlist,
00701 const char *recipe_name,
00702 const char *pipeline_name,
00703 int npars, ...)
00704 {
00705
00706 va_list ap;
00707
00708 char *group_name;
00709
00710 int pars_counter = 0;
00711
00712 group_name = cpl_sprintf("%s.%s", pipeline_name, recipe_name);
00713 assert(group_name != NULL);
00714
00715 #define insert_par(PARNAME, PARDESC, PARVALUE, PARTYPE) \
00716 do { \
00717 char * par_name = cpl_sprintf("%s.%s", group_name, PARNAME); \
00718 cpl_parameter * p; \
00719 assert(par_name != NULL); \
00720 p = cpl_parameter_new_value(par_name, PARTYPE, \
00721 PARDESC, group_name, PARVALUE); \
00722 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, PARNAME); \
00723 cpl_parameter_disable(p, CPL_PARAMETER_MODE_ENV); \
00724 cpl_parameterlist_append(parlist, p); \
00725 cpl_free(par_name); \
00726 } while(0);
00727
00728
00729 va_start(ap, npars);
00730
00731 while(pars_counter < npars) {
00732 char *name = va_arg(ap, char *);
00733 char *desc = va_arg(ap, char *);
00734 char *type = va_arg(ap, char *);
00735
00736 if(!strcmp(type, "CPL_TYPE_INT")) {
00737 int v1 = va_arg(ap, int);
00738
00739 insert_par(name, desc, v1, CPL_TYPE_INT);
00740 } else if(!strcmp(type, "CPL_TYPE_BOOL")) {
00741 char *v2 = va_arg(ap, char *);
00742
00743 if(!strcmp(v2, "CPL_FALSE"))
00744 insert_par(name, desc, CPL_FALSE, CPL_TYPE_BOOL);
00745 if(!strcmp(v2, "CPL_TRUE"))
00746 insert_par(name, desc, CPL_TRUE, CPL_TYPE_BOOL);
00747 } else if(!strcmp(type, "CPL_TYPE_STRING")) {
00748 char *v2 = va_arg(ap, char *);
00749
00750 insert_par(name, desc, v2, CPL_TYPE_STRING);
00751 } else if(!strcmp(type, "CPL_TYPE_DOUBLE")) {
00752 double v3 = va_arg(ap, double);
00753 insert_par(name, desc, v3, CPL_TYPE_DOUBLE);
00754 }
00755
00756 pars_counter++;
00757 }
00758
00759 va_end(ap);
00760
00761 cpl_free(group_name);
00762
00763 #undef insert_par
00764 return 0;
00765 }
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 int
00779 irplib_detmon_retrieve_par_int(const char *parn,
00780 const char *pipeline_name,
00781 const char *recipe_name,
00782 const cpl_parameterlist * parlist)
00783 {
00784 char *par_name;
00785 cpl_parameter *par;
00786 int value;
00787
00788 par_name = cpl_sprintf("%s.%s.%s", pipeline_name, recipe_name, parn);
00789 assert(par_name != NULL);
00790 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
00791 value = cpl_parameter_get_int(par);
00792 cpl_free(par_name);
00793
00794 return value;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 double
00809 irplib_detmon_retrieve_par_double(const char *parn,
00810 const char *pipeline_name,
00811 const char *recipe_name,
00812 const cpl_parameterlist * parlist)
00813 {
00814 char *par_name;
00815 cpl_parameter *par;
00816 double value;
00817
00818 par_name = cpl_sprintf("%s.%s.%s", pipeline_name, recipe_name, parn);
00819 assert(par_name != NULL);
00820 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
00821 value = cpl_parameter_get_double(par);
00822 cpl_free(par_name);
00823
00824 return value;
00825 }
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838 int
00839 irplib_detmon_compare_dits(const cpl_frame * frame1, const cpl_frame * frame2)
00840 {
00841 int comparison;
00842 cpl_propertylist *plist1;
00843 cpl_propertylist *plist2;
00844 double dval1, dval2;
00845
00846
00847 if(frame1 == NULL || frame2 == NULL)
00848 return -1;
00849
00850
00851 if((plist1 = cpl_propertylist_load(cpl_frame_get_filename(frame1),
00852 0)) == NULL) {
00853 cpl_msg_error(cpl_func, "getting header from reference frame");
00854 return -1;
00855 }
00856 if((plist2 = cpl_propertylist_load(cpl_frame_get_filename(frame2),
00857 0)) == NULL) {
00858 cpl_msg_error(cpl_func, "getting header from reference frame");
00859 cpl_propertylist_delete(plist1);
00860 return -1;
00861 }
00862
00863
00864 if(cpl_error_get_code()) {
00865 cpl_propertylist_delete(plist1);
00866 cpl_propertylist_delete(plist2);
00867 return -1;
00868 }
00869
00870
00871 comparison = 1;
00872 dval1 = irplib_pfits_get_exptime(plist1);
00873 dval2 = irplib_pfits_get_exptime(plist2);
00874 if(cpl_error_get_code()) {
00875 cpl_msg_error(cpl_func, "cannot get exposure time");
00876 cpl_propertylist_delete(plist1);
00877 cpl_propertylist_delete(plist2);
00878 return -1;
00879 }
00880 if(fabs(dval1 - dval2) > 1e-3)
00881 comparison = 0;
00882
00883
00884 cpl_propertylist_delete(plist1);
00885 cpl_propertylist_delete(plist2);
00886 return comparison;
00887 }
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 double
00900 irplib_pfits_get_exptime(const cpl_propertylist * plist)
00901 {
00902 double exptime;
00903
00904 exptime = cpl_propertylist_get_double(plist, "EXPTIME");
00905
00906 return exptime;
00907 }
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921 static cpl_error_code
00922 irplib_detmon_ronbias_retrieve_parlist(const char *pipeline_name,
00923 const char *recipe_name,
00924 const cpl_parameterlist * parlist,
00925 cpl_boolean opt_nir)
00926 {
00927 char *par_name;
00928 cpl_parameter *par;
00929
00930 char m1[20] = "";
00931 char m2[20] = "";
00932 char m3[20] = "";
00933
00934
00935 par_name = cpl_sprintf("%s.%s.method", pipeline_name, recipe_name);
00936 assert(par_name != NULL);
00937 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
00938 detmon_ronbias_config.method = cpl_parameter_get_string(par);
00939 cpl_free(par_name);
00940
00941 detmon_ronbias_config.method_bitmask = 0;
00942
00943 sscanf(detmon_ronbias_config.method, "%s %s %s", m1, m2, m3);
00944
00945 if(!strcmp(m1, "RANDOM") || !strcmp(m2, "RANDOM")
00946 || !strcmp(m3, "RANDOM"))
00947 detmon_ronbias_config.method_bitmask += RANDOM;
00948
00949 if(!strcmp(m1, "HISTO") || !strcmp(m2, "HISTO") || !strcmp(m3, "HISTO"))
00950 detmon_ronbias_config.method_bitmask += HISTO;
00951
00952 if(!strcmp(m1, "PREOVERSCAN") || !strcmp(m2, "PREOVERSCAN")
00953 || !strcmp(m3, "PREOVERSCAN")) {
00954 if (opt_nir == NIR) {
00955
00956
00957
00958 cpl_msg_warning(cpl_func, "PREOVERSCAN is not appliable for NIR");
00959 } else {
00960 detmon_ronbias_config.method_bitmask += PREOVERSCAN;
00961 }
00962 }
00963 if(!strcmp(m1, "REGION") || !strcmp(m2, "REGION")
00964 || !strcmp(m3, "REGION"))
00965 detmon_ronbias_config.method_bitmask += REGION;
00966
00967 if(!strcmp(m1, "ALL")) {
00968 if (opt_nir == OPT) {
00969 detmon_ronbias_config.method_bitmask =
00970 RANDOM | HISTO | PREOVERSCAN | REGION;
00971 } else {
00972 detmon_ronbias_config.method_bitmask =
00973 RANDOM | HISTO | REGION;
00974 }
00975 }
00976
00977
00978 par_name = cpl_sprintf("%s.%s.pmethod", pipeline_name, recipe_name);
00979 assert(par_name != NULL);
00980 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
00981 detmon_ronbias_config.pmethod = cpl_parameter_get_string(par);
00982 cpl_free(par_name);
00983
00984
00985 detmon_ronbias_config.preoverscan_degree =
00986 irplib_detmon_retrieve_par_int("preoverscan.degree", pipeline_name,
00987 recipe_name, parlist);
00988
00989
00990 detmon_ronbias_config.random_nsamples =
00991 irplib_detmon_retrieve_par_int("random.nsamples", pipeline_name,
00992 recipe_name, parlist);
00993
00994
00995 detmon_ronbias_config.random_sizex =
00996 irplib_detmon_retrieve_par_int("random.sizex", pipeline_name,
00997 recipe_name, parlist);
00998
00999
01000 detmon_ronbias_config.random_sizey =
01001 irplib_detmon_retrieve_par_int("random.sizey", pipeline_name,
01002 recipe_name, parlist);
01003
01004
01005 detmon_ronbias_config.criteria =
01006 irplib_detmon_retrieve_par_int("criteria", pipeline_name, recipe_name,
01007 parlist);
01008
01009
01010 detmon_ronbias_config.ref_llx =
01011 irplib_detmon_retrieve_par_int("ref.llx", pipeline_name, recipe_name,
01012 parlist);
01013
01014 detmon_ronbias_config.ref_lly =
01015 irplib_detmon_retrieve_par_int("ref.lly", pipeline_name, recipe_name,
01016 parlist);
01017
01018 detmon_ronbias_config.ref_urx =
01019 irplib_detmon_retrieve_par_int("ref.urx", pipeline_name, recipe_name,
01020 parlist);
01021
01022 detmon_ronbias_config.ref_ury =
01023 irplib_detmon_retrieve_par_int("ref.ury", pipeline_name, recipe_name,
01024 parlist);
01025
01026
01027 par_name =
01028 cpl_sprintf("%s.%s.stacking.method", pipeline_name, recipe_name);
01029 assert(par_name != NULL);
01030 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01031 detmon_ronbias_config.stacking_method = cpl_parameter_get_string(par);
01032 cpl_free(par_name);
01033
01034
01035 detmon_ronbias_config.stacking_ks_low =
01036 irplib_detmon_retrieve_par_int("stacking.ks.low", pipeline_name,
01037 recipe_name, parlist);
01038
01039 detmon_ronbias_config.stacking_ks_high =
01040 irplib_detmon_retrieve_par_int("stacking.ks.high", pipeline_name,
01041 recipe_name, parlist);
01042
01043 detmon_ronbias_config.stacking_ks_iter =
01044 irplib_detmon_retrieve_par_int("stacking.ks.iter", pipeline_name,
01045 recipe_name, parlist);
01046
01047 detmon_ronbias_config.master_shift_x =
01048 irplib_detmon_retrieve_par_int("master.shift.x", pipeline_name,
01049 recipe_name, parlist);
01050
01051 detmon_ronbias_config.master_shift_y =
01052 irplib_detmon_retrieve_par_int("master.shift.y", pipeline_name,
01053 recipe_name, parlist);
01054
01055 detmon_ronbias_config.ron_llx =
01056 irplib_detmon_retrieve_par_int("ron.llx", pipeline_name, recipe_name,
01057 parlist);
01058
01059 detmon_ronbias_config.ron_lly =
01060 irplib_detmon_retrieve_par_int("ron.lly", pipeline_name, recipe_name,
01061 parlist);
01062
01063 detmon_ronbias_config.ron_urx =
01064 irplib_detmon_retrieve_par_int("ron.urx", pipeline_name, recipe_name,
01065 parlist);
01066
01067 detmon_ronbias_config.ron_ury =
01068 irplib_detmon_retrieve_par_int("ron.ury", pipeline_name, recipe_name,
01069 parlist);
01070
01071 detmon_ronbias_config.exts =
01072 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
01073 parlist);
01074
01075 if(cpl_error_get_code()) {
01076 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
01077 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
01078 }
01079
01080
01081 return CPL_ERROR_NONE;
01082 }
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094 cpl_error_code
01095 irplib_detmon_ronbias_check_defaults(const cpl_frameset * set,
01096 const int whichext)
01097 {
01098 const cpl_frame * fr = cpl_frameset_get_first_const(set);
01099
01100 cpl_propertylist * plist =
01101 cpl_propertylist_load(cpl_frame_get_filename(fr), whichext);
01102
01103 const int naxis1 = cpl_propertylist_get_int(plist, "NAXIS1");
01104 const int naxis2 = cpl_propertylist_get_int(plist, "NAXIS2");
01105
01106 cpl_error_code error;
01107
01108 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
01109 const int nx = cpl_propertylist_get_int(plist, "ESO DET OUT1 NX");
01110 const int ny = cpl_propertylist_get_int(plist, "ESO DET OUT1 NY");
01111
01112 int prscsize;
01113 int ovscsize;
01114
01115 if (naxis1 != nx) {
01116 prscsize =
01117 cpl_propertylist_get_int(plist, "ESO DET OUT1 PRSCX");
01118 ovscsize =
01119 cpl_propertylist_get_int(plist, "ESO DET OUT1 OVSCX");
01120 cpl_ensure_code(!cpl_error_get_code(), cpl_error_get_code());
01121
01122 detmon_ronbias_config.prescan_llx = 1;
01123 detmon_ronbias_config.prescan_lly = 1;
01124 detmon_ronbias_config.prescan_urx = prscsize;
01125 detmon_ronbias_config.prescan_ury = naxis2;
01126 detmon_ronbias_config.overscan_llx = naxis1 - ovscsize;
01127 detmon_ronbias_config.overscan_lly = 1;
01128 detmon_ronbias_config.overscan_urx = naxis1;
01129 detmon_ronbias_config.overscan_ury = naxis2;
01130 } else if (naxis2 != ny) {
01131 prscsize =
01132 cpl_propertylist_get_int(plist, "ESO DET OUT1 PRSCY");
01133 ovscsize =
01134 cpl_propertylist_get_int(plist, "ESO DET OUT1 OVSCY");
01135 cpl_ensure_code(!cpl_error_get_code(), cpl_error_get_code());
01136
01137 detmon_ronbias_config.prescan_llx = 1;
01138 detmon_ronbias_config.prescan_lly = 1;
01139 detmon_ronbias_config.prescan_urx = naxis1;
01140 detmon_ronbias_config.prescan_ury = prscsize;
01141 detmon_ronbias_config.overscan_llx = 1;
01142 detmon_ronbias_config.overscan_lly = naxis2 - ovscsize;
01143 detmon_ronbias_config.overscan_urx = naxis1;
01144 detmon_ronbias_config.overscan_ury = naxis2;
01145 } else {
01146 cpl_msg_error(cpl_func,
01147 "No PREOVERSCAN areas found");
01148 cpl_ensure_code(0, CPL_ERROR_NULL_INPUT);
01149 }
01150 cpl_propertylist_delete(plist);
01151 }
01152
01153 if(detmon_ronbias_config.ref_llx == -1)
01154 detmon_ronbias_config.ref_llx = naxis1 / 8;
01155 if(detmon_ronbias_config.ref_lly == -1)
01156 detmon_ronbias_config.ref_lly = naxis2 / 8;
01157 if(detmon_ronbias_config.ref_urx == -1)
01158 detmon_ronbias_config.ref_urx = naxis1 * 7 / 8;
01159 if(detmon_ronbias_config.ref_ury == -1)
01160 detmon_ronbias_config.ref_ury = naxis2 * 7 / 8;
01161
01162 if(detmon_ronbias_config.ron_llx == -1)
01163 detmon_ronbias_config.ron_llx = 1;
01164 if(detmon_ronbias_config.ron_lly == -1)
01165 detmon_ronbias_config.ron_lly = 1;
01166 if(detmon_ronbias_config.ron_urx == -1)
01167 detmon_ronbias_config.ron_urx = naxis1;
01168 if(detmon_ronbias_config.ron_ury == -1)
01169 detmon_ronbias_config.ron_ury = naxis2;
01170
01171 error = cpl_error_get_code();
01172 cpl_ensure_code(!error, error);
01173
01174 return CPL_ERROR_NONE;
01175 }
01176
01177
01178
01229
01230 cpl_error_code
01231 irplib_ksigma_clip(const cpl_image * img,
01232 int llx,
01233 int lly,
01234 int urx,
01235 int ury,
01236 double kappa,
01237 int nclip,
01238 double tolerance,
01239 double * kmean,
01240 double * kstdev)
01241 {
01242 cpl_errorstate inistate = cpl_errorstate_get();
01243
01244 int nx, ny;
01245
01246 cpl_stats * stats;
01247 double mean, stdev, var_sum;
01248 int npixs;
01249
01250 cpl_ensure_code(img != NULL, CPL_ERROR_NULL_INPUT);
01251
01252 nx = cpl_image_get_size_x(img);
01253 ny = cpl_image_get_size_y(img);
01254
01255 cpl_ensure_code(llx > 0 && urx > llx && urx <= nx &&
01256 lly > 0 && ury > lly && ury <= ny,
01257 CPL_ERROR_ILLEGAL_INPUT);
01258
01259 cpl_ensure_code(tolerance >= 0.0, CPL_ERROR_ILLEGAL_INPUT);
01260 cpl_ensure_code(kappa > 1.0, CPL_ERROR_ILLEGAL_INPUT);
01261 cpl_ensure_code(nclip > 0, CPL_ERROR_ILLEGAL_INPUT);
01262
01263 stats = cpl_stats_new_from_image_window(img,
01264 CPL_STATS_MEAN | CPL_STATS_STDEV,
01265 llx, lly, urx, ury);
01266
01267 npixs = cpl_stats_get_npix(stats);
01268 mean = cpl_stats_get_mean(stats);
01269 stdev = cpl_stats_get_stdev(stats);
01270 var_sum = stdev * stdev * (npixs - 1);
01271
01272 cpl_stats_delete(stats);
01273
01274
01275 cpl_ensure_code(cpl_errorstate_is_equal(inistate), cpl_error_get_code());
01276
01277 switch (cpl_image_get_type(img)) {
01278 case CPL_TYPE_DOUBLE:
01279 skip_if(irplib_ksigma_clip_double(cpl_image_get_data_double_const(img),
01280 llx, lly, urx, ury, nx, var_sum,
01281 npixs, kappa, nclip, tolerance,
01282 &mean, &stdev));
01283 break;
01284 case CPL_TYPE_FLOAT:
01285 skip_if(irplib_ksigma_clip_float(cpl_image_get_data_float_const(img),
01286 llx, lly, urx, ury, nx, var_sum,
01287 npixs, kappa, nclip, tolerance,
01288 &mean, &stdev));
01289 break;
01290 case CPL_TYPE_INT:
01291 skip_if(irplib_ksigma_clip_int(cpl_image_get_data_int_const(img),
01292 llx, lly, urx, ury, nx, var_sum,
01293 npixs, kappa, nclip, tolerance,
01294 &mean, &stdev));
01295 break;
01296 default:
01297
01298 assert( 0 );
01299 }
01300
01301 *kmean = mean;
01302 if (kstdev != NULL) *kstdev = stdev;
01303
01304 end_skip;
01305
01306 return cpl_error_get_code();
01307 }
01308
01309 #define CONCAT(a,b) a ## _ ## b
01310 #define CONCAT2X(a,b) CONCAT(a,b)
01311
01312 #define CPL_TYPE double
01313 #include "irplib_detmon_body.h"
01314 #undef CPL_TYPE
01315
01316 #define CPL_TYPE float
01317 #include "irplib_detmon_body.h"
01318 #undef CPL_TYPE
01319
01320 #define CPL_TYPE int
01321 #include "irplib_detmon_body.h"
01322 #undef CPL_TYPE
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335 cpl_error_code
01336 irplib_detmon_ronbias(cpl_frameset * frameset,
01337 const cpl_parameterlist * parlist,
01338 const char *tag,
01339 const char *recipe_name,
01340 const char *pipeline_name,
01341 const char *pafregexp,
01342 const cpl_propertylist * pro_master,
01343 const cpl_propertylist * pro_xstr,
01344 const cpl_propertylist * pro_ystr,
01345 const cpl_propertylist * pro_synth,
01346 const cpl_propertylist * pro_bpmhot,
01347 const cpl_propertylist * pro_bpmcold,
01348 const cpl_propertylist * pro_bpmdev,
01349 const char *package,
01350 int (*compare) (const cpl_frame *, const cpl_frame *),
01351 cpl_boolean opt_nir)
01352 {
01353
01354 int nsets;
01355 int i;
01356
01357 int * selection = NULL;
01358 cpl_frameset * cur_fset = NULL;
01359 cpl_propertylist * qclist = NULL;
01360 cpl_image * synthetic = NULL;
01361 cpl_image * masterbias = NULL;
01362 cpl_imagelist * rawbiases = NULL;
01363 cpl_mask * bpmhot = NULL;
01364 cpl_mask * bpmcold = NULL;
01365 cpl_mask * bpmdev = NULL;
01366
01367
01368 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
01369 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
01370 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
01371 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
01372 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
01373 cpl_ensure_code(pro_master != NULL, CPL_ERROR_NULL_INPUT);
01374 cpl_ensure_code(pro_bpmhot != NULL, CPL_ERROR_NULL_INPUT);
01375 cpl_ensure_code(pro_bpmcold != NULL, CPL_ERROR_NULL_INPUT);
01376 cpl_ensure_code(pro_bpmdev != NULL, CPL_ERROR_NULL_INPUT);
01377 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
01378
01379 if(irplib_detmon_ronbias_dfs_set_groups(frameset, tag)) {
01380 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
01381 }
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396 irplib_detmon_ronbias_retrieve_parlist(pipeline_name,
01397 recipe_name, parlist, opt_nir);
01398
01399
01400 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN)
01401 cpl_ensure_code(pro_synth != NULL, CPL_ERROR_NULL_INPUT);
01402
01403
01404
01405 if(compare == NULL)
01406 nsets = 1;
01407 else {
01408 cpl_msg_info(cpl_func, "Identify the different settings");
01409 selection = cpl_frameset_labelise(frameset, compare, &nsets);
01410 if(selection == NULL)
01411 cpl_msg_error(cpl_func, "Cannot labelise input frames");
01412 }
01413
01414
01415 for(i = 0; i < nsets; i++) {
01416 int j;
01417 int first_ext = 0;
01418 int last_ext = 1;
01419
01420 detmon_ronbias_config.nb_extensions = 1;
01421
01422
01423 cpl_msg_info(cpl_func, "Reduce data set nb %d out of %d",
01424 i + 1, nsets);
01425
01426 cur_fset = nsets == 1 ?
01427 cpl_frameset_duplicate(frameset) :
01428 cpl_frameset_extract(frameset, selection, i);
01429 skip_if(cur_fset == NULL);
01430
01431 if(detmon_ronbias_config.exts > 0) {
01432 first_ext = detmon_ronbias_config.exts;
01433 last_ext = first_ext + 1;
01434 } else if(detmon_ronbias_config.exts < 0) {
01435 const cpl_frame *cur_frame =
01436 cpl_frameset_get_first_const(cur_fset);
01437
01438 detmon_ronbias_config.nb_extensions =
01439 cpl_frame_get_nextensions(cur_frame);
01440 first_ext = 1;
01441 last_ext = detmon_ronbias_config.nb_extensions + 1;
01442 }
01443
01444 if (last_ext - first_ext > 1) {
01445 skip_if(irplib_detmon_ronbias_save(parlist, frameset,
01446 recipe_name,
01447 pipeline_name, pafregexp,
01448 pro_master, pro_xstr,
01449 pro_ystr, pro_synth,
01450 pro_bpmhot,
01451 pro_bpmcold, pro_bpmdev,
01452 package, NULL, NULL, NULL,
01453 NULL, NULL, NULL,
01454 0, 0, cur_fset, 0));
01455 }
01456
01457 for(j = first_ext; j < last_ext; j++) {
01458 int whichext;
01459
01460 qclist = cpl_propertylist_new();
01461
01462 rawbiases
01463 = cpl_imagelist_load_frameset(cur_fset,
01464 CPL_TYPE_FLOAT, 1, j);
01465 skip_if(rawbiases == NULL);
01466
01467 skip_if(irplib_detmon_ronbias_check_defaults(cur_fset, j));
01468
01469 skip_if(irplib_detmon_ronbias_dutycycl(cur_fset, qclist));
01470
01471 masterbias = irplib_detmon_ronbias_master(rawbiases,
01472 &bpmhot, &bpmcold,
01473 &bpmdev, qclist);
01474 skip_if(masterbias == NULL);
01475
01476
01477
01478
01479
01480
01481 if(detmon_ronbias_config.method_bitmask & RANDOM) {
01482 skip_if(irplib_detmon_ronbias_random(rawbiases, masterbias,
01483 qclist));
01484 }
01485
01486 if(detmon_ronbias_config.method_bitmask & HISTO) {
01487 skip_if(irplib_detmon_ronbias_histo(rawbiases, masterbias,
01488 qclist));
01489 }
01490
01491 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
01492 skip_if(irplib_detmon_ronbias_preoverscan(rawbiases,
01493
01494 qclist, &synthetic));
01495 }
01496
01497 if(detmon_ronbias_config.method_bitmask & REGION) {
01498 skip_if(irplib_detmon_ronbias_region(rawbiases, masterbias,
01499 qclist));
01500 }
01501
01502
01503
01504
01505
01506
01507 #if 0
01508 irplib_detmon_ronbias_check(qclist);
01509 #endif
01510
01511
01512
01513
01514 whichext = first_ext > 1 ? 0 : j;
01515
01516 skip_if(irplib_detmon_ronbias_save(parlist, frameset,
01517 recipe_name,
01518 pipeline_name, pafregexp,
01519 pro_master, pro_xstr,
01520 pro_ystr, pro_synth,
01521 pro_bpmhot,
01522 pro_bpmcold, pro_bpmdev,
01523 package, masterbias, synthetic,
01524 bpmhot, bpmcold, bpmdev,
01525 qclist, 0, 0, cur_fset,
01526 whichext));
01527
01528 cpl_image_delete(synthetic);
01529 cpl_image_delete(masterbias);
01530 cpl_mask_delete(bpmhot);
01531 cpl_mask_delete(bpmcold);
01532 cpl_mask_delete(bpmdev);
01533 cpl_imagelist_delete(rawbiases);
01534 cpl_propertylist_delete(qclist);
01535
01536 qclist = NULL;
01537 rawbiases = NULL;
01538 masterbias = NULL;
01539 bpmhot = NULL;
01540 bpmcold = NULL;
01541 bpmdev = NULL;
01542 synthetic = NULL;
01543 }
01544
01545 cpl_frameset_delete(cur_fset);
01546 cur_fset = NULL;
01547
01548 }
01549
01550 end_skip;
01551
01552 cpl_free(selection);
01553
01554 cpl_frameset_delete(cur_fset);
01555
01556 cpl_image_delete(synthetic);
01557 cpl_image_delete(masterbias);
01558 cpl_mask_delete(bpmhot);
01559 cpl_mask_delete(bpmcold);
01560 cpl_mask_delete(bpmdev);
01561 cpl_imagelist_delete(rawbiases);
01562 cpl_propertylist_delete(qclist);
01563
01564 return cpl_error_get_code();
01565 }
01566
01567
01568
01569
01570
01571
01572
01573
01574
01575
01576
01577
01578 static cpl_error_code
01579 irplib_detmon_ronbias_random(const cpl_imagelist * rawbiases,
01580 const cpl_image * masterbias,
01581 cpl_propertylist * qclist)
01582 {
01583 int nraws = cpl_imagelist_get_size(rawbiases);
01584 int i;
01585 double bias = DBL_MAX;
01586 double bias_error;
01587
01588 double ron_error;
01589 double *ron =
01590 (double *) cpl_malloc(sizeof(double) * nraws);
01591
01592 cpl_vector *v;
01593 double stdev;
01594 cpl_error_code error;
01595
01596
01597
01598 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) {
01599 nraws--;
01600
01601
01602 for(i = 0; i < nraws; i++) {
01603 const cpl_image *c1_raw =
01604 cpl_imagelist_get_const(rawbiases, i);
01605 const cpl_image *c2_raw =
01606 cpl_imagelist_get_const(rawbiases, i + 1);
01607
01608 const cpl_image *c_raw = cpl_image_subtract_create(c1_raw,
01609 c2_raw);
01610 cpl_flux_get_noise_window(c_raw, NULL,
01611 detmon_ronbias_config.random_sizex / 2,
01612 detmon_ronbias_config.random_nsamples,
01613 ron + i, &ron_error);
01614 cpl_image_delete((cpl_image*)c_raw);
01615
01616 }
01617 } else {
01618 for(i = 0; i < nraws; i++) {
01619 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
01620
01621 cpl_flux_get_noise_window(c_raw, NULL,
01622 detmon_ronbias_config.random_sizex / 2,
01623 detmon_ronbias_config.random_nsamples,
01624 ron + i, &ron_error);
01625 }
01626 }
01627
01628
01629
01630
01631 irplib_flux_get_bias_window(masterbias, NULL,
01632 detmon_ronbias_config.random_sizex / 2,
01633 detmon_ronbias_config.random_nsamples,
01634 &bias, &bias_error);
01635
01636 v = cpl_vector_wrap(nraws, ron);
01637 stdev = cpl_vector_get_median_const(v);
01638 cpl_vector_unwrap(v);
01639
01640 cpl_free(ron);
01641
01642 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_VAL, bias);
01643 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_VAL,
01644 DETMON_QC_BIAS_RANDOM_VAL_C);
01645
01646 cpl_ensure_code(!error, error);
01647 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_RON, stdev);
01648 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_RON,
01649 DETMON_QC_BIAS_RANDOM_RON_C);
01650 cpl_ensure_code(!error, error);
01651 return cpl_error_get_code();
01652 }
01653
01654 static cpl_error_code
01655 irplib_detmon_ronbias_histo(const cpl_imagelist * rawbiases,
01656 const cpl_image * masterbias,
01657 cpl_propertylist * qclist)
01658 {
01659 int nraws = cpl_imagelist_get_size(rawbiases);
01660 int i;
01661
01662 double mbias = DBL_MAX;
01663 double mfwhm = DBL_MAX;
01664 double mmax = DBL_MAX;
01665
01666 cpl_vector * fwhms;
01667 cpl_vector * maxs;
01668
01669 double mean_fwhm = DBL_MAX;
01670
01671 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) nraws--;
01672
01673 fwhms = cpl_vector_new(nraws);
01674 maxs = cpl_vector_new(nraws);
01675
01676 for(i = 0; i < nraws; i++) {
01677
01678 const cpl_image * c_raw;
01679 double bias = DBL_MAX;
01680 double fwhm = DBL_MAX;
01681 double max = DBL_MAX;
01682
01683 if(strcmp(detmon_ronbias_config.pmethod, "DIF")) {
01684 c_raw = cpl_imagelist_get_const(rawbiases, i);
01685 } else {
01686 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
01687 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
01688 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
01689 }
01690
01691 skip_if(irplib_detmon_ronbias_histo_reduce(c_raw, &bias, &fwhm, &max));
01692
01693 skip_if(bias == DBL_MAX || fwhm == DBL_MAX || max == DBL_MAX);
01694
01695 if(!strcmp(detmon_ronbias_config.pmethod, "DIF"))
01696 cpl_image_delete((cpl_image *)c_raw);
01697
01698 skip_if(cpl_vector_set(maxs, i, max));
01699 skip_if(cpl_vector_set(fwhms, i, fwhm));
01700
01701
01702 }
01703
01704 skip_if(cpl_vector_divide_scalar(fwhms, HIST_FACT));
01705
01706 irplib_detmon_ronbias_histo_reduce(masterbias, &mbias, &mfwhm, &mmax);
01707
01708 skip_if(mbias == DBL_MAX || mfwhm == DBL_MAX || mmax == DBL_MAX);
01709
01710 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_HISTO_VAL,
01711 mbias));
01712 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_HISTO_VAL,
01713 DETMON_QC_BIAS_HISTO_VAL_C));
01714 mean_fwhm = cpl_vector_get_mean(fwhms);
01715
01716 skip_if(mean_fwhm == DBL_MAX);
01717 skip_if(cpl_error_get_code());
01718
01719 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_HISTO_RON,
01720 mean_fwhm));
01721 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_HISTO_RON,
01722 DETMON_QC_BIAS_HISTO_RON_C));
01723
01724 end_skip;
01725
01726 cpl_vector_delete(fwhms);
01727 cpl_vector_delete(maxs);
01728
01729 return cpl_error_get_code();
01730 }
01731
01732 static cpl_error_code
01733 irplib_detmon_ronbias_histo_reduce(const cpl_image * c_raw,
01734 double * bias,
01735 double * fwhm,
01736 double * max)
01737 {
01738 unsigned long uj;
01739 irplib_hist *hist;
01740 unsigned long maxwhere = 0;
01741 unsigned long maxf;
01742
01743 double mean, stdev;
01744 cpl_image * dupi;
01745 unsigned long x1a = 1;
01746 unsigned long x2a = 1;
01747
01748 double x1 = 0;
01749 double x2 = 0;
01750
01751 double maxwhere_interp;
01752 double max_interp;
01753 double a, b, c;
01754 cpl_matrix * coeffs =cpl_matrix_new(3, 3);
01755 cpl_matrix * rhs =cpl_matrix_new(3, 1);
01756 int p, q;
01757 cpl_matrix * result = NULL;
01758 cpl_error_code error;
01759
01760 mean = cpl_image_get_mean(c_raw);
01761 stdev = cpl_image_get_stdev(c_raw);
01762 dupi = cpl_image_duplicate(c_raw);
01763
01764
01765
01766
01767 hist = irplib_hist_new();
01768 error = irplib_hist_fill(hist, dupi);
01769 cpl_ensure_code(!error, error);
01770
01771 cpl_image_delete(dupi);
01772
01773 maxf = irplib_hist_get_max(hist, &maxwhere);
01774
01775 for( p = 0; p< 3; p++){
01776 unsigned long bi = irplib_hist_get_value(hist, maxwhere-1+p);
01777 cpl_matrix_set(rhs, p, 0, bi);
01778 for( q= 0; q< 3; q++) {
01779 cpl_matrix_set(coeffs, p,q,pow((maxwhere-1+p),q));
01780 }
01781 }
01782
01783 result = cpl_matrix_solve(coeffs, rhs);
01784
01785 a = cpl_matrix_get(result, 2, 0);
01786 b = cpl_matrix_get(result, 1, 0);
01787 c = cpl_matrix_get(result, 0, 0);
01788
01789 maxwhere_interp = -0.5 * b / (2 * a);
01790 max_interp = -1 * b * b / (4 * a) + c;
01791
01792 cpl_matrix_delete(coeffs);
01793 cpl_matrix_delete(rhs);
01794 cpl_matrix_delete(result);
01795
01796
01797 for(uj = 0; uj < maxwhere; uj++) {
01798 if(irplib_hist_get_value(hist, uj) <= max_interp / 2 &&
01799 irplib_hist_get_value(hist, uj + 1) > max_interp / 2) {
01800 x1a = uj;
01801 }
01802 }
01803 for(uj = maxwhere; uj < irplib_hist_get_nbins(hist)-1; uj++) {
01804 if(irplib_hist_get_value(hist, uj) >= max_interp / 2 &&
01805 irplib_hist_get_value(hist, uj + 1) < max_interp / 2) {
01806 x2a = uj;
01807 }
01808 }
01809
01810 x1 = (max_interp / 2 - irplib_hist_get_value(hist, x1a)) /
01811 (irplib_hist_get_value(hist, x1a + 1) -
01812 irplib_hist_get_value(hist, x1a)) + x1a;
01813 x2 = (max_interp / 2 - irplib_hist_get_value(hist, x2a)) /
01814 (irplib_hist_get_value(hist, x2a + 1) -
01815 irplib_hist_get_value(hist, x2a)) + x2a;
01816
01817 *fwhm = (x2 - x1) * irplib_hist_get_bin_size(hist);
01818
01819 *max = max_interp;
01820
01821 *bias = maxwhere_interp * irplib_hist_get_bin_size(hist) +
01822 irplib_hist_get_start(hist);
01823
01824 irplib_hist_delete(hist);
01825
01826 return cpl_error_get_code();
01827 }
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839 static cpl_error_code
01840 irplib_detmon_ronbias_preoverscan(const cpl_imagelist * rawbiases,
01841 cpl_propertylist * qclist,
01842 cpl_image ** synthetic)
01843 {
01844 int i;
01845 int nx, ny;
01846 int nraws;
01847
01848 cpl_vector *meanspre;
01849 cpl_vector *medspre;
01850 cpl_vector *rmsspre;
01851 cpl_vector *meansover;
01852 cpl_vector *medsover;
01853 cpl_vector *rmssover;
01854
01855 cpl_error_code error;
01856
01857 nraws = cpl_imagelist_get_size(rawbiases);
01858 cpl_ensure_code(nraws != -1, CPL_ERROR_ILLEGAL_INPUT);
01859
01860 meanspre = cpl_vector_new(nraws);
01861 medspre = cpl_vector_new(nraws);
01862 rmsspre = cpl_vector_new(nraws);
01863 meansover = cpl_vector_new(nraws);
01864 medsover = cpl_vector_new(nraws);
01865 rmssover = cpl_vector_new(nraws);
01866
01867 nx = cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
01868 ny = cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
01869 cpl_ensure_code(nx != -1 && ny != -1, CPL_ERROR_ILLEGAL_INPUT);
01870
01871 if(nx < detmon_ronbias_config.prescan_urx ||
01872 nx < detmon_ronbias_config.overscan_urx ||
01873 ny < detmon_ronbias_config.prescan_ury ||
01874 ny < detmon_ronbias_config.overscan_ury) {
01875 cpl_msg_warning(cpl_func, "PREOVERSCAN method not applied. Given "
01876 "limits of prescan and overscan area "
01877 "exceed image size. Please check and rerun.");
01878 return CPL_ERROR_NONE;
01879 }
01880
01881 for(i = 0; i < nraws; i++) {
01882 double mean = 0;
01883 double stdev = 0;
01884
01885 cpl_image *prescan = NULL;
01886 cpl_image *overscan = NULL;
01887
01888 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
01889
01890 cpl_ensure_code(c_raw != NULL, CPL_ERROR_ILLEGAL_INPUT);
01891
01892 prescan =
01893 cpl_image_extract(c_raw,
01894 detmon_ronbias_config.prescan_llx,
01895 detmon_ronbias_config.prescan_lly,
01896 detmon_ronbias_config.prescan_urx,
01897 detmon_ronbias_config.prescan_ury);
01898 cpl_ensure_code(prescan != NULL, CPL_ERROR_ILLEGAL_INPUT);
01899 overscan =
01900 cpl_image_extract(c_raw,
01901 detmon_ronbias_config.overscan_llx,
01902 detmon_ronbias_config.overscan_lly,
01903 detmon_ronbias_config.overscan_urx,
01904 detmon_ronbias_config.overscan_ury);
01905 cpl_ensure_code(overscan != NULL, CPL_ERROR_ILLEGAL_INPUT);
01906
01907 if(i == 0) {
01908 *synthetic = irplib_detmon_build_synthetic(prescan, overscan);
01909 cpl_msg_info(cpl_func, "Creating SYNTHETIC frame");
01910 if(*synthetic == NULL) {
01911 cpl_msg_error(cpl_func, "Error creating SYNTHETIC frame");
01912 return CPL_ERROR_UNSPECIFIED;
01913 }
01914 }
01915
01916 error = irplib_ksigma_clip(c_raw,
01917 detmon_ronbias_config.
01918 prescan_llx,
01919 detmon_ronbias_config.
01920 prescan_lly,
01921 detmon_ronbias_config.
01922 prescan_urx,
01923 detmon_ronbias_config.
01924 prescan_ury,
01925 (double) detmon_ronbias_config.
01926 stacking_ks_low,
01927 detmon_ronbias_config.
01928 stacking_ks_iter, 1e-5,
01929 &mean, &stdev);
01930 cpl_ensure_code(!error, error);
01931
01932 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
01933
01934 error = cpl_vector_set(medspre, i, cpl_image_get_median(prescan));
01935 cpl_ensure_code(!error, error);
01936
01937 error = cpl_vector_set(meanspre, i, mean);
01938 cpl_ensure_code(!error, error);
01939 error = cpl_vector_set(rmsspre, i, stdev);
01940 cpl_ensure_code(!error, error);
01941 error = irplib_ksigma_clip(c_raw,
01942 detmon_ronbias_config.
01943 overscan_llx,
01944 detmon_ronbias_config.
01945 overscan_lly,
01946 detmon_ronbias_config.
01947 overscan_urx,
01948 detmon_ronbias_config.
01949 overscan_ury,
01950 (double) detmon_ronbias_config.
01951 stacking_ks_low,
01952 detmon_ronbias_config.
01953 stacking_ks_iter, 1e-5,
01954 &mean, &stdev);
01955 cpl_ensure_code(!error, error);
01956
01957 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
01958
01959 error = cpl_vector_set(medsover, i, cpl_image_get_median(overscan));
01960 cpl_ensure_code(!error, error);
01961
01962 error = cpl_vector_set(meansover, i, mean);
01963 cpl_ensure_code(!error, error);
01964 error = cpl_vector_set(rmssover, i, stdev);
01965 cpl_ensure_code(!error, error);
01966
01967 cpl_image_delete(prescan);
01968 cpl_image_delete(overscan);
01969 }
01970
01971 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
01972 cpl_vector_get_mean(meanspre));
01973
01974 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
01975 DETMON_QC_BIAS_PRESCAN_MEAN_C);
01976
01977 cpl_ensure_code(!error, error);
01978 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MED,
01979 cpl_vector_get_mean(medspre));
01980 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MED,
01981 DETMON_QC_BIAS_PRESCAN_MED_C);
01982
01983 cpl_ensure_code(!error, error);
01984 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_RON,
01985 cpl_vector_get_mean(rmsspre));
01986
01987 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_RON,
01988 DETMON_QC_BIAS_PRESCAN_RON_C);
01989 cpl_ensure_code(!error, error);
01990
01991 error =
01992 cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
01993 cpl_vector_get_mean(meansover));
01994 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
01995 DETMON_QC_BIAS_OVERSCAN_MEAN_C);
01996 cpl_ensure_code(!error, error);
01997 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
01998 cpl_vector_get_mean(medsover));
01999 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
02000 DETMON_QC_BIAS_OVERSCAN_MED_C);
02001 cpl_ensure_code(!error, error);
02002 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
02003 cpl_vector_get_mean(rmssover));
02004 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
02005 DETMON_QC_BIAS_OVERSCAN_RON_C);
02006 cpl_ensure_code(!error, error);
02007
02008
02009
02010
02011
02012
02013
02014
02015
02016
02017
02018
02019
02020
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044 cpl_vector_delete(meanspre);
02045 cpl_vector_delete(medspre);
02046 cpl_vector_delete(rmsspre);
02047 cpl_vector_delete(meansover);
02048 cpl_vector_delete(medsover);
02049 cpl_vector_delete(rmssover);
02050
02051 return CPL_ERROR_NONE;
02052 }
02053
02054
02055
02056
02057
02058
02059
02060
02061
02062
02063
02064
02065 static cpl_error_code
02066 irplib_detmon_ronbias_region(const cpl_imagelist * rawbiases,
02067 const cpl_image * masterbias,
02068 cpl_propertylist * qclist)
02069 {
02070
02071 int nraws = cpl_imagelist_get_size(rawbiases);
02072 int i;
02073
02074 int nx =
02075 cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
02076 int ny =
02077 cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
02078
02079 cpl_vector *rmssreg;
02080 cpl_error_code error;
02081
02082 const cpl_image * c_raw;
02083 double median, mbias, mstdev;
02084
02085 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) nraws--;
02086
02087 rmssreg = cpl_vector_new(nraws);
02088
02089 if(nx < detmon_ronbias_config.ref_urx ||
02090 ny < detmon_ronbias_config.ref_ury) {
02091 cpl_msg_warning(cpl_func, "REGION method not applied. Given "
02092 "limits of prescan and overscan area "
02093 "exceed image size. Please check and rerun.");
02094 return CPL_ERROR_NONE;
02095 }
02096
02097 for(i = 0; i < nraws; i++) {
02098 double mean = 0;
02099 double stdev = 0;
02100 if(strcmp(detmon_ronbias_config.pmethod, "DIF")) {
02101 c_raw = cpl_imagelist_get_const(rawbiases, i);
02102 } else {
02103 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
02104 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
02105 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
02106 }
02107 error = irplib_ksigma_clip(c_raw,
02108 detmon_ronbias_config.ref_llx,
02109 detmon_ronbias_config.ref_lly,
02110 detmon_ronbias_config.ref_urx,
02111 detmon_ronbias_config.ref_ury,
02112 (double) detmon_ronbias_config.
02113 stacking_ks_low,
02114 detmon_ronbias_config.
02115 stacking_ks_iter, 1e-5,
02116 &mean, &stdev);
02117 cpl_ensure_code(!error, error);
02118
02119
02120
02121
02122
02123
02124 error = cpl_vector_set(rmssreg, i, stdev);
02125 cpl_ensure_code(!error, error);
02126 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) cpl_image_delete((cpl_image *)c_raw);
02127 }
02128
02129 median = cpl_image_get_median_window(masterbias,
02130 detmon_ronbias_config.ref_llx,
02131 detmon_ronbias_config.ref_lly,
02132 detmon_ronbias_config.ref_urx,
02133 detmon_ronbias_config.ref_ury);
02134 error = irplib_ksigma_clip(masterbias,
02135 detmon_ronbias_config.ref_llx,
02136 detmon_ronbias_config.ref_lly,
02137 detmon_ronbias_config.ref_urx,
02138 detmon_ronbias_config.ref_ury,
02139 (double) detmon_ronbias_config.
02140 stacking_ks_low,
02141 detmon_ronbias_config.
02142 stacking_ks_iter, 1e-5,
02143 &mbias, &mstdev);
02144
02145 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_MED,
02146 median);
02147 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_MED,
02148 DETMON_QC_BIAS_REGION_MED_C);
02149 cpl_ensure_code(!error, error);
02150
02151 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_VAL,
02152 mbias);
02153 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_VAL,
02154 DETMON_QC_BIAS_REGION_VAL_C);
02155 cpl_ensure_code(!error, error);
02156 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_RON,
02157 cpl_vector_get_mean(rmssreg));
02158 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_RON,
02159 DETMON_QC_BIAS_REGION_RON_C);
02160 cpl_ensure_code(!error, error);
02161
02162
02163
02164
02165
02166
02167 cpl_vector_delete(rmssreg);
02168
02169 return cpl_error_get_code();
02170 }
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 static cpl_image *
02184 irplib_detmon_ronbias_master(const cpl_imagelist * rawbiases,
02185 cpl_mask ** bpmhot, cpl_mask ** bpmcold,
02186 cpl_mask ** bpmdev, cpl_propertylist * qclist)
02187 {
02188 double mean = 0;
02189 double stdev = 0;
02190 cpl_image *masterbias = NULL;
02191 double dark_med, stdev_med,lower, upper;
02192 int hotpix_nb, coldpix_nb, devpix_nb;
02193 cpl_image * stdev_im = NULL;
02194
02195 if(!strcmp(detmon_ronbias_config.stacking_method, "MEAN"))
02196 masterbias = cpl_imagelist_collapse_create(rawbiases);
02197 if(!strcmp(detmon_ronbias_config.stacking_method, "MINMAX"))
02198 masterbias =
02199 cpl_imagelist_collapse_minmax_create(rawbiases, 0, 10000);
02200 if(!strcmp(detmon_ronbias_config.stacking_method, "KSIGMA"))
02201 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02202 masterbias =
02203 cpl_imagelist_collapse_sigclip_create(rawbiases, 3, 0.0, 1.0, 1, NULL);
02204 #else
02205 masterbias = cpl_imagelist_collapse_sigclip_create(rawbiases, 3);
02206 #endif
02207 if(!strcmp(detmon_ronbias_config.stacking_method, "MEDIAN"))
02208 masterbias = cpl_imagelist_collapse_median_create(rawbiases);
02209
02210 skip_if(masterbias == NULL);
02211
02212 skip_if(irplib_ksigma_clip(masterbias, 1, 1,
02213 cpl_image_get_size_x(masterbias),
02214 cpl_image_get_size_y(masterbias),
02215 (double) detmon_ronbias_config.
02216 stacking_ks_low,
02217 detmon_ronbias_config.
02218 stacking_ks_iter, 1e-5,
02219 &mean, &stdev));
02220
02221 if(irplib_isnan(mean))
02222 cpl_msg_error(cpl_func, "We have an error in mean");
02223 if(irplib_isnan(stdev))
02224 cpl_msg_error(cpl_func, "We have an error in stdev");
02225
02226 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_MEAN,
02227 mean));
02228 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_MEAN,
02229 DETMON_QC_MASTER_MEAN_C));
02230
02231 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_RMS,
02232 stdev));
02233 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_RMS,
02234 DETMON_QC_MASTER_RMS_C));
02235
02236
02237 dark_med = cpl_image_get_median(masterbias);
02238
02239 lower = dark_med - stdev * detmon_ronbias_config.stacking_ks_low;
02240 upper = dark_med + stdev * detmon_ronbias_config.stacking_ks_high;
02241
02242
02243 cpl_mask_delete(*bpmhot);
02244 irplib_check(*bpmhot = cpl_mask_threshold_image_create(masterbias,
02245 upper, DBL_MAX),
02246 "Cannot compute the hot pixel map");
02247 hotpix_nb = cpl_mask_count(*bpmhot);
02248 skip_if (0);
02249
02250
02251 cpl_mask_delete(*bpmcold);
02252 irplib_check(*bpmcold = cpl_mask_threshold_image_create(masterbias,
02253 -FLT_MAX, lower),
02254 "Cannot compute the cold pixel map");
02255 coldpix_nb = cpl_mask_count(*bpmcold);
02256 skip_if (0);
02257
02258
02259 stdev_im = irplib_imagelist_collapse_stdev_create(rawbiases);
02260 stdev_med = cpl_image_get_median(stdev_im);
02261
02262 skip_if(irplib_ksigma_clip(stdev_im, 1, 1,
02263 cpl_image_get_size_x(stdev_im),
02264 cpl_image_get_size_y(stdev_im),
02265 (double) detmon_ronbias_config.
02266 stacking_ks_low,
02267 detmon_ronbias_config.
02268 stacking_ks_iter, 1e-5,
02269 &mean, &stdev));
02270
02271 lower = stdev_med - stdev * detmon_ronbias_config.stacking_ks_low;
02272 upper = stdev_med + stdev * detmon_ronbias_config.stacking_ks_high;
02273
02274 cpl_mask_delete(*bpmdev);
02275 irplib_check(*bpmdev = cpl_mask_threshold_image_create(stdev_im,
02276 lower, upper),
02277 "Cannot compute the cold pixel map");
02278 cpl_mask_not(*bpmdev);
02279 devpix_nb = cpl_mask_count(*bpmdev);
02280 skip_if (0);
02281
02282
02283 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBCOLDPIX,coldpix_nb));
02284 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBCOLDPIX,
02285 DETMON_QC_NBCOLDPIX_C));
02286
02287 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBHOTPIX, hotpix_nb));
02288 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBHOTPIX,
02289 DETMON_QC_NBHOTPIX_C));
02290
02291 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBDEVPIX, devpix_nb));
02292 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBDEVPIX,
02293 DETMON_QC_NBDEVPIX_C));
02294
02295 end_skip;
02296
02297 cpl_image_delete(stdev_im);
02298
02299 if (cpl_error_get_code()) {
02300 cpl_image_delete(masterbias);
02301 masterbias = NULL;
02302 }
02303
02304 return masterbias;
02305 }
02306
02307
02308
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318 static cpl_error_code
02319 irplib_detmon_ronbias_save(const cpl_parameterlist * parlist,
02320 cpl_frameset * frameset,
02321 const char *recipe_name,
02322 const char *pipeline_name,
02323 const char *pafregexp,
02324 const cpl_propertylist * pro_master,
02325 const cpl_propertylist * pro_xstr,
02326 const cpl_propertylist * pro_ystr,
02327 const cpl_propertylist * pro_synth,
02328 const cpl_propertylist * pro_bpmhot,
02329 const cpl_propertylist * pro_bpmcold,
02330 const cpl_propertylist * pro_bpmdev,
02331 const char *package,
02332 const cpl_image * masterbias,
02333 const cpl_image * synthetic,
02334 const cpl_mask * bpmhot,
02335 const cpl_mask * bpmcold,
02336 const cpl_mask * bpmdev,
02337 cpl_propertylist * qclist,
02338 const int flag_sets,
02339 const int which_set,
02340 cpl_frameset * usedframes,
02341 int whichext)
02342 {
02343
02344 cpl_frame *ref_frame;
02345 cpl_propertylist *plist = NULL;
02346 char *name_o = NULL;
02347
02348 cpl_propertylist * paflist = NULL;
02349 cpl_propertylist * mainplist = NULL;
02350 cpl_propertylist * xplist = NULL;
02351 cpl_image * image = NULL;
02352
02353 cpl_propertylist * mypro_master =
02354 cpl_propertylist_duplicate(pro_master);
02355
02356 cpl_propertylist * mypro_synth = NULL;
02357 cpl_propertylist * mypro_bpmhot =
02358 cpl_propertylist_duplicate(pro_bpmhot);
02359 cpl_propertylist * mypro_bpmcold =
02360 cpl_propertylist_duplicate(pro_bpmcold);
02361 cpl_propertylist * mypro_bpmdev =
02362 cpl_propertylist_duplicate(pro_bpmdev);
02363
02364 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
02365 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
02366 cpl_ensure_code(pafregexp != NULL, CPL_ERROR_NULL_INPUT);
02367 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
02368 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
02369 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
02370 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
02371
02372 if (pro_synth)
02373 mypro_synth = cpl_propertylist_duplicate(pro_synth);
02374
02375
02376 cpl_ensure_code(pro_xstr == NULL && pro_ystr == NULL,
02377 CPL_ERROR_UNSUPPORTED_MODE);
02378
02379
02380 if (detmon_ronbias_config.exts < 0) {
02381 const char * filename =
02382 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
02383
02384
02385 xplist = cpl_propertylist_load_regexp(filename, whichext,
02386 "ESO DET", 0);
02387 skip_if(cpl_propertylist_append(xplist, qclist));
02388 }
02389
02390 cpl_msg_info(cpl_func,"dealing with extention %d",whichext);
02391
02392
02393
02394 ref_frame = cpl_frameset_get_first(frameset);
02395 skip_if(ref_frame == NULL);
02396
02397 skip_if((mainplist =
02398 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02399 0)) == NULL);
02400
02401
02402
02403
02404
02405
02406 if(!flag_sets) {
02407 name_o = cpl_sprintf("%s_masterbias.fits", recipe_name);
02408 assert(name_o != NULL);
02409 } else {
02410 name_o =
02411 cpl_sprintf("%s_masterbias_set%02d.fits", recipe_name,
02412 which_set);
02413 assert(name_o != NULL);
02414 }
02415
02416 if (whichext == 0) {
02417 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02418 cpl_propertylist_append(mypro_master, qclist);
02419
02420 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02421 masterbias, CPL_BPP_IEEE_FLOAT, recipe_name,
02422 mypro_master, NULL, package, name_o));
02423 #else
02424 const char * procatg_master =
02425 cpl_propertylist_get_string(mypro_master, CPL_DFS_PRO_CATG);
02426
02427 cpl_propertylist_append(mypro_master, qclist);
02428
02429 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, masterbias,
02430 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_master,
02431 mypro_master, NULL, package, name_o));
02432 #endif
02433 } else
02434 skip_if(cpl_image_save(masterbias,
02435 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02436 CPL_IO_EXTEND));
02437
02438
02439 cpl_free(name_o);
02440 name_o = NULL;
02441
02442
02443
02444
02445
02446
02447 if(!flag_sets) {
02448 name_o = cpl_sprintf("%s_hotpixmap.fits", recipe_name);
02449 assert(name_o != NULL);
02450 } else {
02451 name_o =
02452 cpl_sprintf("%s_hotpixmap_set%02d.fits", recipe_name,
02453 which_set);
02454 assert(name_o != NULL);
02455 }
02456
02457 skip_if(0);
02458 image = cpl_image_new_from_mask(bpmhot);
02459 cpl_error_reset();
02460
02461 if (whichext == 0) {
02462 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02463 cpl_propertylist_append(mypro_bpmhot, qclist);
02464
02465 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02466 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02467 mypro_bpmhot, NULL, package, name_o));
02468 #else
02469 const char * procatg_bpmhot =
02470 cpl_propertylist_get_string(mypro_bpmhot, CPL_DFS_PRO_CATG);
02471
02472 cpl_propertylist_append(mypro_bpmhot, qclist);
02473
02474 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02475 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmhot,
02476 mypro_bpmhot, NULL, package, name_o));
02477 #endif
02478 } else
02479 skip_if(cpl_image_save(image,
02480 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02481 CPL_IO_EXTEND));
02482
02483
02484 cpl_free(name_o);
02485 cpl_image_delete(image);
02486 image = NULL;
02487 name_o = NULL;
02488
02489
02490
02491
02492
02493
02494 if(!flag_sets) {
02495 name_o = cpl_sprintf("%s_coldpixmap.fits", recipe_name);
02496 assert(name_o != NULL);
02497 } else {
02498 name_o =
02499 cpl_sprintf("%s_coldpixmap_set%02d.fits", recipe_name,
02500 which_set);
02501 assert(name_o != NULL);
02502 }
02503
02504 skip_if(0);
02505 image = cpl_image_new_from_mask(bpmcold);
02506 cpl_error_reset();
02507
02508 if (whichext == 0) {
02509 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02510 cpl_propertylist_append(mypro_bpmcold, qclist);
02511
02512 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02513 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02514 mypro_bpmcold, NULL, package, name_o));
02515 #else
02516 const char * procatg_bpmcold =
02517 cpl_propertylist_get_string(mypro_bpmcold, CPL_DFS_PRO_CATG);
02518
02519 cpl_propertylist_append(mypro_bpmcold, qclist);
02520
02521 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02522 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmcold,
02523 mypro_bpmcold, NULL, package, name_o));
02524 #endif
02525 } else
02526 skip_if(cpl_image_save(image,
02527 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02528 CPL_IO_EXTEND));
02529
02530
02531 cpl_free(name_o);
02532 cpl_image_delete(image);
02533 image = NULL;
02534 name_o = NULL;
02535
02536
02537
02538
02539
02540
02541 if(!flag_sets) {
02542 name_o = cpl_sprintf("%s_devpixmap.fits", recipe_name);
02543 assert(name_o != NULL);
02544 } else {
02545 name_o =
02546 cpl_sprintf("%s_devpixmap_set%02d.fits", recipe_name,
02547 which_set);
02548 assert(name_o != NULL);
02549 }
02550
02551 skip_if(0);
02552 image = cpl_image_new_from_mask(bpmdev);
02553 cpl_error_reset();
02554
02555 if (whichext == 0) {
02556 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02557 cpl_propertylist_append(mypro_bpmdev, qclist);
02558
02559 skip_if(cpl_dfs_save_image(frameset, NULL,parlist, usedframes, NULL,
02560 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02561 mypro_bpmdev, NULL, package, name_o));
02562 #else
02563 const char * procatg_bpmdev =
02564 cpl_propertylist_get_string(mypro_bpmdev, CPL_DFS_PRO_CATG);
02565
02566 cpl_propertylist_append(mypro_bpmdev, qclist);
02567
02568 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02569 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmdev,
02570 mypro_bpmdev, NULL, package, name_o));
02571 #endif
02572 } else
02573 skip_if(cpl_image_save(image,
02574 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02575 CPL_IO_EXTEND));
02576
02577
02578 cpl_free(name_o);
02579 cpl_image_delete(image);
02580 image = NULL;
02581 name_o = NULL;
02582
02583
02584
02585
02586 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
02587
02588 if(!flag_sets) {
02589 name_o = cpl_sprintf("%s_synthetic.fits", recipe_name);
02590 assert(name_o != NULL);
02591 } else {
02592 name_o =
02593 cpl_sprintf("%s_synthetic_set%02d.fits", recipe_name,
02594 which_set);
02595 assert(name_o != NULL);
02596 }
02597
02598 if (whichext == 0) {
02599 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02600
02601 cpl_propertylist_append(mypro_synth, qclist);
02602
02603 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
02604 NULL,synthetic, CPL_BPP_IEEE_DOUBLE,
02605 recipe_name, mypro_synth, NULL,
02606 package, name_o));
02607 #else
02608
02609 const char * procatg_synth =
02610 cpl_propertylist_get_string(mypro_synth, CPL_DFS_PRO_CATG);
02611
02612 cpl_propertylist_append(mypro_synth, qclist);
02613
02614 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, synthetic,
02615 CPL_BPP_IEEE_DOUBLE, recipe_name,
02616 procatg_synth,
02617 mypro_synth, NULL, package, name_o));
02618 #endif
02619 } else
02620 skip_if(cpl_image_save(synthetic, name_o, CPL_BPP_IEEE_FLOAT,
02621 xplist, CPL_IO_EXTEND));
02622
02623
02624 cpl_free(name_o);
02625 name_o = NULL;
02626 }
02627
02628
02629
02630
02631 if (qclist) {
02632 paflist = cpl_propertylist_new();
02633
02634
02635 if(detmon_ronbias_config.exts >= 0) {
02636 skip_if((plist =
02637 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02638 detmon_ronbias_config.exts)) == NULL);
02639
02640 if(!flag_sets) {
02641 name_o = cpl_sprintf("%s.paf", recipe_name);
02642 assert(name_o != NULL);
02643 } else {
02644 name_o = cpl_sprintf("%s_set%02d.paf",
02645 recipe_name, which_set);
02646 assert(name_o != NULL);
02647 }
02648 } else {
02649 skip_if((plist =
02650 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02651 whichext)) == NULL);
02652
02653
02654 if(!flag_sets) {
02655 name_o = cpl_sprintf("%s_ext%02d.paf",
02656 recipe_name, whichext);
02657 assert(name_o != NULL);
02658 } else {
02659 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf",
02660 recipe_name,
02661 which_set, whichext);
02662 assert(name_o != NULL);
02663 }
02664 }
02665
02666
02667 skip_if(cpl_propertylist_copy_property_regexp(paflist, plist,
02668 pafregexp, 0));
02669 skip_if(cpl_propertylist_copy_property_regexp(paflist, mainplist,
02670 pafregexp, 0));
02671
02672 skip_if(cpl_propertylist_append(paflist, qclist));
02673
02674
02675 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, paflist, name_o));
02676
02677 }
02678
02679 end_skip;
02680
02681 cpl_propertylist_delete(plist);
02682 cpl_propertylist_delete(paflist);
02683 cpl_propertylist_delete(mainplist);
02684 cpl_propertylist_delete(xplist);
02685 cpl_free(name_o);
02686 cpl_image_delete(image);
02687
02688 cpl_propertylist_delete(mypro_master);
02689 cpl_propertylist_delete(mypro_synth);
02690 cpl_propertylist_delete(mypro_bpmhot);
02691 cpl_propertylist_delete(mypro_bpmcold);
02692 cpl_propertylist_delete(mypro_bpmdev);
02693
02694 return cpl_error_get_code();
02695 }
02696
02697 cpl_propertylist *
02698 irplib_detmon_fill_prolist(const char * procatg,
02699 const char * protype,
02700 const char * protech,
02701 cpl_boolean proscience)
02702 {
02703 cpl_propertylist * prolist = cpl_propertylist_new();
02704
02705 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procatg);
02706 cpl_propertylist_append_bool(prolist, CPL_DFS_PRO_SCIENCE, proscience);
02707 if (protype)
02708 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TYPE, protype);
02709 if (protech)
02710 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TECH, protech);
02711
02712 return prolist;
02713 }
02714
02715
02716
02717
02718
02719
02720
02721
02722
02723
02724
02725
02726 int
02727 irplib_detmon_ronbias_dfs_set_groups(cpl_frameset * set, const char *tag)
02728 {
02729 cpl_frame *cur_frame;
02730 const char *cur_tag;
02731 int nframes;
02732 int i;
02733
02734
02735 if(set == NULL)
02736 return -1;
02737
02738
02739 nframes = cpl_frameset_get_size(set);
02740
02741
02742 for(i = 0; i < nframes; i++) {
02743 cur_frame = cpl_frameset_get_frame(set, i);
02744 cur_tag = cpl_frame_get_tag(cur_frame);
02745
02746
02747 if(!strcmp(cur_tag, tag))
02748 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
02749
02750
02751
02752
02753
02754 }
02755 return 0;
02756 }
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769 static cpl_image *
02770 irplib_detmon_build_synthetic(cpl_image * prescan, cpl_image * overscan)
02771 {
02772 int j;
02773
02774 int distance = detmon_ronbias_config.overscan_urx -
02775 detmon_ronbias_config.prescan_llx + 1;
02776
02777 double *mean_x =
02778 (double *) cpl_malloc(sizeof(double) * distance);
02779
02780 double *xvalues =
02781 (double *) cpl_malloc(sizeof(double) * distance);
02782
02783 cpl_vector *x = NULL;
02784 cpl_vector *y = NULL;
02785
02786 cpl_polynomial *poly = NULL;
02787 cpl_polynomial *poly2 = NULL;
02788
02789 cpl_matrix * samppos;
02790 cpl_vector * fitresidual;
02791
02792 double mse;
02793 int pows[2] = { 0, 0 };
02794
02795 cpl_image *synthetic = NULL;
02796
02797 double initial = 0;
02798
02799
02800 for(j = 0; j < distance; j++) {
02801 *(mean_x + j) = 0;
02802 *(xvalues + j) = j;
02803 }
02804
02805 for(j = 0; j < cpl_image_get_size_x(prescan); j++) {
02806 *(mean_x + j) =
02807 cpl_image_get_mean_window(prescan, j + 1, 1, j + 1,
02808 cpl_image_get_size_y(prescan));
02809 }
02810
02811 for(j = 0; j < cpl_image_get_size_x(overscan); j++) {
02812 *(mean_x + distance - cpl_image_get_size_x(overscan) + j) =
02813 cpl_image_get_mean_window(overscan, j + 1, 1, j + 1,
02814 cpl_image_get_size_y(overscan));
02815 }
02816
02817 x = cpl_vector_wrap(distance, xvalues);
02818 y = cpl_vector_wrap(distance, mean_x);
02819
02820 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02821 poly = cpl_polynomial_new(1);
02822 samppos =
02823 cpl_matrix_wrap(1, cpl_vector_get_size(x), cpl_vector_get_data(x));
02824 fitresidual = cpl_vector_new(cpl_vector_get_size(x));
02825
02826 cpl_polynomial_fit(poly, samppos, NULL, y, NULL,
02827 CPL_FALSE, NULL,
02828 &(detmon_ronbias_config.preoverscan_degree));
02829
02830 cpl_vector_fill_polynomial_fit_residual(fitresidual, y, NULL, poly,
02831 samppos, NULL);
02832 cpl_matrix_unwrap(samppos);
02833 mse = cpl_vector_product(fitresidual, fitresidual)
02834 / cpl_vector_get_size(fitresidual);
02835
02836 cpl_vector_delete(fitresidual);
02837 #else
02838 poly =
02839 cpl_polynomial_fit_1d_create(x, y,
02840 detmon_ronbias_config.preoverscan_degree,
02841 &mse);
02842 #endif
02843
02844 cpl_vector_unwrap(x);
02845 cpl_vector_unwrap(y);
02846
02847 initial = *mean_x;
02848
02849 cpl_free(xvalues);
02850 cpl_free(mean_x);
02851
02852 poly2 = cpl_polynomial_new(2);
02853
02854 j = 0;
02855 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
02856
02857 pows[0] = 1;
02858 j = 1;
02859 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
02860
02861 cpl_polynomial_delete(poly);
02862
02863 synthetic =
02864 cpl_image_new(distance, cpl_image_get_size_y(prescan),
02865 CPL_TYPE_DOUBLE);
02866
02867 if(cpl_image_fill_polynomial(synthetic, poly2, initial, 1, 1, 1)) {
02868 cpl_msg_error(cpl_func, "Error creating the synthetic frame");
02869 cpl_polynomial_delete(poly2);
02870 return NULL;
02871 }
02872
02873 cpl_polynomial_delete(poly2);
02874
02875 return synthetic;
02876 }
02877
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887
02888
02889 static cpl_error_code
02890 irplib_detmon_ronbias_dutycycl(const cpl_frameset * frameset,
02891 cpl_propertylist * qclist)
02892 {
02893 const cpl_frame *first;
02894 cpl_propertylist *plistfirst;
02895 double tfirst;
02896 int nraws;
02897 const cpl_frame *last;
02898 cpl_propertylist *plistlast;
02899 double tlast;
02900 double dutycycl;
02901 cpl_error_code error;
02902
02903 first = cpl_frameset_get_first_const(frameset);
02904 cpl_ensure_code(first != NULL, cpl_error_get_code());
02905
02906 plistfirst = cpl_propertylist_load(cpl_frame_get_filename(first), 0);
02907 cpl_ensure_code(plistfirst != NULL, cpl_error_get_code());
02908
02909 tfirst = cpl_propertylist_get_double(plistfirst, "MJD-OBS");
02910 cpl_ensure_code(tfirst != 0, cpl_error_get_code());
02911
02912 nraws = cpl_frameset_get_size(frameset);
02913 cpl_ensure_code(nraws != -1, cpl_error_get_code());
02914
02915 last = cpl_frameset_get_frame_const(frameset, nraws - 1);
02916 cpl_ensure_code(last != NULL, cpl_error_get_code());
02917
02918 plistlast = cpl_propertylist_load(cpl_frame_get_filename(last), 0);
02919 cpl_ensure_code(plistlast != NULL, cpl_error_get_code());
02920
02921 tlast = cpl_propertylist_get_double(plistlast, "MJD-OBS");
02922 cpl_ensure_code(tlast != 0, cpl_error_get_code());
02923
02924 dutycycl = (tlast - tfirst) / (nraws - 1);
02925
02926 error =
02927 cpl_propertylist_append_double(qclist,DETMON_QC_DUTYCYCL, dutycycl);
02928 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DUTYCYCL,
02929 DETMON_QC_DUTYCYCL_C);
02930 cpl_ensure_code(!error, error);
02931
02932 cpl_propertylist_delete(plistfirst);
02933 cpl_propertylist_delete(plistlast);
02934
02935 return CPL_ERROR_NONE;
02936 }
02937
02938
02939
02940
02941
02942
02943
02944
02945
02946
02947
02948
02949
02950
02951 #define HORIZONTAL TRUE
02952
02953 cpl_table *
02954 irplib_detmon_pernoise_reduce(cpl_image * image)
02955 {
02956 int nsamples, nffts;
02957 int i, j;
02958
02959 int status;
02960 float * hanning;
02961 float * data;
02962 float * power;
02963 cpl_image * power_im;
02964 cpl_image * output;
02965 cpl_image * pos_spec;
02966 cpl_table * table;
02967 double freq;
02968 cpl_error_code error;
02969 cpl_image * sub_image;
02970 int nffts_old;
02971
02972 #ifdef HAVE_SFFTW
02973 fftw_complex * fourier;
02974 fftw_complex * input;
02975 fftw_plan p;
02976 #endif
02977
02978 if(detmon_pernoise_config.direction == HORIZONTAL) {
02979 error = cpl_image_flip(image, 1);
02980 cpl_ensure(!error, error, NULL);
02981 }
02982
02983 nsamples = cpl_image_get_size_x(image);
02984 nffts = cpl_image_get_size_y(image);
02985
02986
02987
02988
02989
02990
02991
02992
02993
02994
02995 error = irplib_detmon_pernoise_rm_bg(image, nsamples, nffts);
02996 cpl_ensure(!error, error, NULL);
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013 sub_image = cpl_image_extract(image, nsamples/8 + 1, nffts/8+1,
03014 nsamples*7/8, nffts*7/8);
03015 nffts_old = nffts;
03016 nsamples = cpl_image_get_size_x(sub_image);
03017 nffts = cpl_image_get_size_y(sub_image);
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
03031 hanning = cpl_malloc(sizeof(float) * nsamples);
03032
03033 for(i = 0; i < nsamples; i++) {
03034 *(hanning + i) = 0.5 - 0.5 * cos(2 * CPL_MATH_PI * (float) i / nsamples);
03035 for(j = 0; j < nffts; j++) {
03036 double value =
03037 cpl_image_get(sub_image, i + 1, j + 1, &status);
03038 error = cpl_image_set(sub_image, i + 1, j + 1, (*(hanning + i)) * value);
03039 cpl_ensure(!error, error, NULL);
03040 }
03041 }
03042
03043 cpl_free(hanning);
03044
03045 data = cpl_image_get_data_float(sub_image);
03046
03047 power = (float *) cpl_calloc(sizeof(float), nsamples * nffts);
03048
03049 #ifdef HAVE_SFFTW
03050
03051 fourier =
03052 (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nsamples*nffts);
03053
03054 input =
03055 (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nsamples*nffts);
03056
03057 for(i = 0; i< nffts*nsamples; i++){
03058 *((float complex *)input + i) = data[i] + I * 0.0;
03059 }
03060
03061 p = fftw_create_plan(nsamples, FFTW_FORWARD, FFTW_ESTIMATE);
03062
03063 fftw(p, nffts, input, 1, nsamples,
03064 fourier, 1, nsamples);
03065
03066 fftw_destroy_plan(p);
03067
03068 for(i = 0; i < nffts; i++) {
03069 for(j = 0; j < nsamples; j++) {
03070 *(power + j + i * nsamples) = *((float complex *)fourier + j + i * nsamples) *
03071 conjf(*((float complex *)fourier +j + i * nsamples));
03072 }
03073
03074 }
03075
03076 fftw_free(fourier);
03077 fftw_free(input);
03078 #endif
03079
03080 power_im = cpl_image_wrap_float(nsamples, nffts, power);
03081 output = cpl_image_collapse_create(power_im, 0);
03082 pos_spec = cpl_image_extract(output, 1, 1, nsamples/2, 1);
03083
03084 cpl_image_unwrap(power_im);
03085 cpl_free(power);
03086
03087 cpl_image_delete(output);
03088
03089 table = cpl_table_new(nsamples/2);
03090 cpl_table_new_column(table, "FREQ", CPL_TYPE_DOUBLE);
03091 cpl_table_new_column(table, "POW", CPL_TYPE_DOUBLE);
03092
03093 freq = detmon_pernoise_config.speed*1000/nffts_old;
03094
03095 for(i = 0; i < nsamples/2; i++) {
03096 error = cpl_table_set(table, "FREQ", i, freq/(nsamples/2)*i);
03097 error = cpl_table_set(table, "POW", i, cpl_image_get(pos_spec, i+1, 1, &status));
03098 }
03099
03100 for(i= 0; i < 5; i++) {
03101 error = cpl_table_set(table, "POW", i, 0.0);
03102 }
03103
03104 cpl_ensure(!error, error, NULL);
03105
03106 cpl_image_delete(pos_spec);
03107
03108 cpl_image_delete(sub_image);
03109 return table;
03110 }
03111 #undef HORIZONTAL
03112
03113
03114
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128 cpl_error_code
03129 irplib_detmon_rm_bpixs(cpl_image ** image,
03130 const double kappa, int nffts, int nsamples)
03131 {
03132 int i, j;
03133
03134 float *data = cpl_image_get_data_float(*image);
03135 int k = 0;
03136 for(i = 0; i < nffts; i++) {
03137 for(j = 0; j < nsamples; j++) {
03138 float neighbours = 0;
03139 int nneighs = 0;
03140 float average = 0;
03141
03142
03143
03144
03145
03146
03147 if(i > 0) {
03148 neighbours += *(data + (i - 1) * nsamples + j);
03149 nneighs++;
03150 }
03151 if(i < nffts - 1) {
03152 neighbours += *(data + (i + 1) * nsamples + j);
03153 nneighs++;
03154 }
03155 if(j > 0) {
03156 neighbours += *(data + i * nsamples + (j - 1));
03157 nneighs++;
03158 }
03159 if(j < nsamples - 1) {
03160 neighbours += *(data + i * nsamples + (j + 1));
03161 nneighs++;
03162 }
03163 average = neighbours / nneighs;
03164 if(average > 0) {
03165 if(*(data + i * nsamples + j) < average * (-1 * kappa) ||
03166 *(data + i * nsamples + j) > average * (kappa)) {
03167 k++;
03168 *(data + i * nsamples + j) = average;
03169 }
03170 }
03171 if(average < 0) {
03172 if(*(data + i * nsamples + j) > average * (-1 * kappa) ||
03173 *(data + i * nsamples + j) < average * (kappa)) {
03174 k++;
03175 *(data + i * nsamples + j) = average;
03176 }
03177 }
03178
03179 }
03180 }
03181
03182
03183 return cpl_error_get_code();
03184
03185 }
03186
03187
03188
03189 #define RECT_RON_HS 4
03190 #define RECT_RON_SAMPLES 100
03191
03192
03193
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203 static cpl_error_code
03204 irplib_flux_get_bias_window(const cpl_image * diff,
03205 const int *zone_def,
03206 int ron_hsize,
03207 int ron_nsamp, double *bias, double *error)
03208 {
03209 const int hsize = ron_hsize < 0 ? RECT_RON_HS : ron_hsize;
03210 const int nsamples =
03211 ron_nsamp < 0 ? RECT_RON_SAMPLES : ron_nsamp;
03212 cpl_bivector *sample_reg;
03213 cpl_vector *rms_list;
03214 int rect[4];
03215 int zone[4];
03216 double *px;
03217 double *py;
03218 double *pr;
03219 int i;
03220
03221
03222 cpl_ensure_code(diff && bias, CPL_ERROR_NULL_INPUT);
03223
03224
03225 if(zone_def != NULL) {
03226 rect[0] = zone_def[0] + hsize + 1;
03227 rect[1] = zone_def[1] - hsize - 1;
03228 rect[2] = zone_def[2] + hsize + 1;
03229 rect[3] = zone_def[3] - hsize - 1;
03230 } else {
03231 rect[0] = hsize + 1;
03232 rect[1] = cpl_image_get_size_x(diff) - hsize - 1;
03233 rect[2] = hsize + 1;
03234 rect[3] = cpl_image_get_size_y(diff) - hsize - 1;
03235 }
03236
03237 cpl_ensure_code(rect[0] < rect[1] && rect[2] < rect[3],
03238 CPL_ERROR_ILLEGAL_INPUT);
03239
03240
03241
03242 sample_reg =
03243 irplib_bivector_gen_rect_poisson(rect, nsamples + 1, nsamples + 1);
03244 cpl_ensure(sample_reg != NULL, CPL_ERROR_ILLEGAL_INPUT,
03245 CPL_ERROR_ILLEGAL_INPUT);
03246
03247 px = cpl_bivector_get_x_data(sample_reg);
03248 py = cpl_bivector_get_y_data(sample_reg);
03249
03250
03251
03252 rms_list = cpl_vector_new(nsamples);
03253 cpl_ensure(rms_list != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
03254 pr = cpl_vector_get_data(rms_list);
03255
03256 for(i = 0; i < nsamples; i++) {
03257 zone[0] = (int) px[i + 1] - hsize;
03258 zone[1] = (int) px[i + 1] + hsize;
03259 zone[2] = (int) py[i + 1] - hsize;
03260 zone[3] = (int) py[i + 1] + hsize;
03261 pr[i] = cpl_image_get_mean_window(diff,
03262 zone[0], zone[2], zone[1], zone[3]);
03263 }
03264 cpl_bivector_delete(sample_reg);
03265
03266
03267 if(error != NULL)
03268 *error = cpl_vector_get_stdev(rms_list);
03269
03270
03271
03272 *bias = cpl_vector_get_median(rms_list);
03273
03274 cpl_vector_delete(rms_list);
03275
03276 return CPL_ERROR_NONE;
03277 }
03278
03279 #undef RECT_RON_HS
03280 #undef RECT_RON_SAMPLES
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293 static cpl_bivector *
03294 irplib_bivector_gen_rect_poisson(const int *r, const int np, const int homog)
03295 {
03296 double min_dist;
03297 int i;
03298 int gnp;
03299 cpl_bivector *list;
03300 double cand_x, cand_y;
03301 int ok;
03302 int start_ndx;
03303 int xmin, xmax, ymin, ymax;
03304
03305
03306 const int homogc = 0 < homog && homog < np ? homog : np;
03307 double *px;
03308 double *py;
03309
03310
03311 cpl_ensure(r, CPL_ERROR_NULL_INPUT, NULL);
03312 cpl_ensure(np > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
03313
03314 list = cpl_bivector_new(np);
03315 cpl_ensure(list, CPL_ERROR_NULL_INPUT, NULL);
03316 px = cpl_bivector_get_x_data(list);
03317 py = cpl_bivector_get_y_data(list);
03318
03319 xmin = r[0];
03320 xmax = r[1];
03321 ymin = r[2];
03322 ymax = r[3];
03323
03324 min_dist =
03325 CPL_MATH_SQRT1_2 * ((xmax - xmin) * (ymax - ymin) / (double) (homogc + 1));
03326 gnp = 1;
03327 px[0] = 0;
03328 py[0] = 0;
03329
03330
03331 while(gnp < homogc) {
03332
03333 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03334 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03335
03336
03337 ok = 1;
03338 for(i = 0; i < gnp; i++) {
03339 if(pdist(cand_x, cand_y, px[i], py[i]) < min_dist) {
03340
03341 ok = 0;
03342 break;
03343 }
03344 }
03345 if(ok) {
03346
03347 px[gnp] = cand_x;
03348 py[gnp] = cand_y;
03349 gnp++;
03350 }
03351 }
03352
03353
03354
03355 start_ndx = 0;
03356 while(gnp < np) {
03357
03358 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03359 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03360
03361
03362 ok = 1;
03363 for(i = 0; i < homogc; i++) {
03364 if(pdist(cand_x,
03365 cand_y,
03366 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03367
03368 ok = 0;
03369 break;
03370 }
03371 }
03372 if(ok) {
03373
03374 px[gnp] = cand_x;
03375 py[gnp] = cand_y;
03376 gnp++;
03377 }
03378 }
03379
03380
03381
03382 start_ndx = 0;
03383 while(gnp < np) {
03384
03385 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03386 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03387
03388
03389 ok = 1;
03390 for(i = 0; i < homogc; i++) {
03391 if(pdist(cand_x,
03392 cand_y,
03393 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03394
03395 ok = 0;
03396 break;
03397 }
03398 }
03399 if(ok) {
03400
03401 px[gnp] = cand_x;
03402 py[gnp] = cand_y;
03403 gnp++;
03404 start_ndx++;
03405 }
03406 }
03407 return list;
03408 }
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423 cpl_error_code
03424 irplib_detmon_pernoise(cpl_frameset * frameset,
03425 const cpl_parameterlist * parlist,
03426 const char * tag,
03427 const char * recipe_name,
03428 const char * pipeline_name,
03429 const char * procatg_tbl,
03430 const char * package,
03431 int (*compare)(const cpl_frame *,
03432 const cpl_frame *))
03433 {
03434 int nsets;
03435 int *selection = NULL;
03436 int i;
03437 cpl_error_code error;
03438
03439 if(irplib_detmon_pernoise_dfs_set_groups(frameset, tag)) {
03440 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
03441 }
03442
03443
03444
03445
03446
03447
03448 error = irplib_detmon_pernoise_retrieve_parlist(pipeline_name,
03449 recipe_name, parlist);
03450 cpl_ensure_code(!error, error);
03451
03452
03453 if(compare == NULL)
03454 nsets = 1;
03455 else {
03456 cpl_msg_info(cpl_func, "Identify the different settings");
03457 selection = cpl_frameset_labelise(frameset, compare, &nsets);
03458 if(selection == NULL)
03459 cpl_msg_error(cpl_func, "Cannot labelise input frames");
03460 }
03461
03462 detmon_pernoise_config.nb_extensions = 1;
03463 if(detmon_pernoise_config.exts < 0) {
03464 const cpl_frame *cur_frame =
03465 cpl_frameset_get_first_const(frameset);
03466
03467 detmon_pernoise_config.nb_extensions =
03468 cpl_frame_get_nextensions(cur_frame);
03469 }
03470
03471
03472 for(i = 0; i < nsets; i++) {
03473 int j;
03474 cpl_table ** freq_table;
03475 cpl_propertylist ** qclist =
03476 (cpl_propertylist **)
03477 cpl_malloc(detmon_pernoise_config.nb_extensions *
03478 sizeof(cpl_propertylist *));
03479
03480 cpl_imagelist ** raws = (cpl_imagelist **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_imagelist *));
03481 cpl_image ** input = (cpl_image **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_image *));
03482
03483
03484 if(detmon_pernoise_config.mode == 1) {
03485 freq_table =
03486 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03487 4 * sizeof(cpl_table *));
03488 } else {
03489 freq_table =
03490 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03491 sizeof(cpl_table *));
03492 }
03493
03494 if(detmon_pernoise_config.exts >= 0) {
03495 *raws =
03496 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03497 detmon_pernoise_config.exts);
03498 *input = cpl_image_subtract_create(cpl_imagelist_get(*raws,0),
03499 cpl_imagelist_get(*raws,1));
03500 } else {
03501 cpl_imagelist *raws_all_exts =
03502 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03503 -1);
03504 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
03505 int nframes = cpl_frameset_get_size(frameset);
03506 int k;
03507 for(k = 0; k < nframes; k++) {
03508 cpl_image *image =
03509 cpl_imagelist_unset(raws_all_exts,
03510 (detmon_pernoise_config.
03511 nb_extensions - 1 - j) * k);
03512 cpl_imagelist_set(raws[j], image, k);
03513 }
03514 input[j] =
03515 cpl_image_subtract_create(cpl_imagelist_get(raws[j],0),
03516 cpl_imagelist_get(raws[j],1));
03517 }
03518 }
03519
03520 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
03521 cpl_msg_info(cpl_func, "Starting reduction");
03522 if(detmon_pernoise_config.mode == 1){
03523 int nx = cpl_image_get_size_x(input[j]);
03524 int ny = cpl_image_get_size_y(input[j]);
03525
03526 cpl_image * quad1 = cpl_image_extract(input[j],
03527 1, 1, nx/2, ny/2);
03528 cpl_image * quad2 = cpl_image_extract(input[j],
03529 1, ny/2+1, nx/2, ny);
03530 cpl_image * quad3 = cpl_image_extract(input[j],
03531 nx/2+1, 1, nx, ny/2);
03532 cpl_image * quad4 = cpl_image_extract(input[j],
03533 nx/2+1, ny/2+1, nx, ny);
03534 freq_table[j * 4 ] = irplib_detmon_pernoise_reduce(quad1);
03535 cpl_ensure_code(freq_table[j * 4 ]!= NULL,
03536 cpl_error_get_code());
03537 freq_table[j * 4 + 1] = irplib_detmon_pernoise_reduce(quad2);
03538 cpl_ensure_code(freq_table[j * 4 + 1]!= NULL,
03539 cpl_error_get_code());
03540 freq_table[j * 4 + 2] = irplib_detmon_pernoise_reduce(quad3);
03541 cpl_ensure_code(freq_table[j * 4 + 2]!= NULL,
03542 cpl_error_get_code());
03543 freq_table[j * 4 + 3] = irplib_detmon_pernoise_reduce(quad4);
03544 cpl_ensure_code(freq_table[j * 4 + 3]!= NULL,
03545 cpl_error_get_code());
03546 qclist[j] = cpl_propertylist_new();
03547 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j], 1);
03548 cpl_ensure_code(!error, error);
03549 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j+1], 2);
03550 cpl_ensure_code(!error, error);
03551 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j+2], 3);
03552 cpl_ensure_code(!error, error);
03553 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j+3], 4);
03554 cpl_ensure_code(!error, error);
03555 cpl_image_delete(quad1);
03556 cpl_image_delete(quad2);
03557 cpl_image_delete(quad3);
03558 cpl_image_delete(quad4);
03559 } else {
03560 freq_table[j] = irplib_detmon_pernoise_reduce(input[j]);
03561 cpl_ensure_code(freq_table[j]!= NULL, cpl_error_get_code());
03562 qclist[j] = cpl_propertylist_new();
03563 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j], 0);
03564 cpl_ensure_code(!error, error);
03565 }
03566 }
03567 error = irplib_detmon_pernoise_save(parlist, frameset, recipe_name,
03568 pipeline_name, procatg_tbl,
03569 package, freq_table, qclist, 0,
03570 0, frameset);
03571 cpl_ensure_code(!error, error);
03572
03573 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
03574 cpl_propertylist_delete(qclist[j]);
03575 cpl_imagelist_delete(raws[j]);
03576 cpl_image_delete(input[j]);
03577 }
03578 cpl_free(qclist);
03579 cpl_free(raws);
03580 cpl_free(input);
03581 if(detmon_pernoise_config.mode == 1) {
03582 for(j= 0; j < detmon_pernoise_config.nb_extensions * 4; j++) {
03583 cpl_table_delete(freq_table[j]);
03584 }
03585 } else {
03586 for(j= 0; j < detmon_pernoise_config.nb_extensions; j++) {
03587 cpl_table_delete(freq_table[j]);
03588 }
03589 }
03590 cpl_free(freq_table);
03591 }
03592
03593 return cpl_error_get_code();
03594 }
03595
03596
03597
03598
03599
03600
03601
03602
03603
03604
03605
03606
03607 int
03608 irplib_detmon_pernoise_dfs_set_groups(cpl_frameset * set, const char *tag)
03609 {
03610 cpl_frame *cur_frame;
03611 const char *cur_tag;
03612 int nframes;
03613 int i;
03614
03615
03616 if(set == NULL)
03617 return -1;
03618
03619
03620 nframes = cpl_frameset_get_size(set);
03621
03622
03623 for(i = 0; i < nframes; i++) {
03624 cur_frame = cpl_frameset_get_frame(set, i);
03625 cur_tag = cpl_frame_get_tag(cur_frame);
03626
03627
03628 if(!strcmp(cur_tag, tag))
03629 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
03630
03631
03632
03633
03634
03635 }
03636 return 0;
03637 }
03638
03639
03640
03641
03642
03643
03644
03645
03646
03647
03648
03649
03650 cpl_error_code
03651 irplib_detmon_fill_pernoise_params(cpl_parameterlist * parlist,
03652 const char *recipe_name,
03653 const char *pipeline_name,
03654 int mode,
03655 const char * direction,
03656 double speed,
03657 int llx,
03658 int lly,
03659 int urx,
03660 int ury,
03661 int kappa,
03662 int exts)
03663 {
03664 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 9,
03665
03666 "mode",
03667 "Mode",
03668 "CPL_TYPE_INT", mode,
03669
03670 "direction",
03671 "Readout direction",
03672 "CPL_TYPE_BOOL", direction,
03673
03674 "speed",
03675 "Readout speed",
03676 "CPL_TYPE_DOUBLE", speed,
03677
03678 "llx",
03679 "(yet unsupported) x coordinate of the lower-left "
03680 "point of the region of interest. If not modified, default value will be 1.",
03681 "CPL_TYPE_INT", llx,
03682 "lly",
03683 "(yet unsupported) y coordinate of the lower-left "
03684 "point of the region of interest. If not modified, default value will be 1.",
03685 "CPL_TYPE_INT", lly,
03686 "urx",
03687 "(yet unsupported) x coordinate of the upper-right "
03688 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
03689 "CPL_TYPE_INT", urx,
03690 "ury",
03691 "(yet unsupported) y coordinate of the upper-right "
03692 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
03693 "CPL_TYPE_INT", ury,
03694
03695 "kappa",
03696 "Kappa used for determining threshold of bad (hot, cold) pixels",
03697 "CPL_TYPE_DOUBLE", kappa,
03698
03699 "exts",
03700 "Activate the multi-exts option",
03701 "CPL_TYPE_INT", exts);
03702
03703 return 0;
03704 }
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717 int
03718 irplib_detmon_fill_pernoise_params_default(cpl_parameterlist * parlist,
03719 const char *recipe_name,
03720 const char *pipeline_name)
03721 {
03722 irplib_detmon_fill_pernoise_params(parlist, recipe_name, pipeline_name,
03723 1,
03724 "CPL_TRUE",
03725 84.5,
03726 -1,
03727 -1,
03728 -1,
03729 -1,
03730 100,
03731 0);
03732
03733 return 0;
03734
03735 }
03736
03737
03738 static cpl_error_code
03739 irplib_detmon_pernoise_retrieve_parlist(const char *pipeline_name,
03740 const char *recipe_name,
03741 const cpl_parameterlist * parlist)
03742 {
03743 char *par_name;
03744 cpl_parameter *par;
03745
03746
03747 detmon_pernoise_config.mode =
03748 irplib_detmon_retrieve_par_int("mode", pipeline_name, recipe_name,
03749 parlist);
03750
03751
03752 par_name = cpl_sprintf("%s.%s.direction", pipeline_name, recipe_name);
03753 assert(par_name != NULL);
03754 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03755 detmon_pernoise_config.direction = cpl_parameter_get_bool(par);
03756 cpl_free(par_name);
03757
03758
03759 par_name = cpl_sprintf("%s.%s.speed", pipeline_name, recipe_name);
03760 assert(par_name != NULL);
03761 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03762 detmon_pernoise_config.speed = cpl_parameter_get_double(par);
03763 cpl_free(par_name);
03764
03765
03766 detmon_pernoise_config.llx =
03767 irplib_detmon_retrieve_par_int("llx", pipeline_name, recipe_name,
03768 parlist);
03769
03770
03771 detmon_pernoise_config.lly =
03772 irplib_detmon_retrieve_par_int("lly", pipeline_name, recipe_name,
03773 parlist);
03774
03775 detmon_pernoise_config.urx =
03776 irplib_detmon_retrieve_par_int("urx", pipeline_name, recipe_name,
03777 parlist);
03778
03779 detmon_pernoise_config.ury =
03780 irplib_detmon_retrieve_par_int("ury", pipeline_name, recipe_name,
03781 parlist);
03782
03783 detmon_pernoise_config.kappa =
03784 irplib_detmon_retrieve_par_double("kappa", pipeline_name, recipe_name,
03785 parlist);
03786
03787
03788 detmon_pernoise_config.exts =
03789 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
03790 parlist);
03791
03792 if(cpl_error_get_code()) {
03793 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
03794 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
03795 }
03796
03797 return cpl_error_get_code();
03798 }
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811 static cpl_error_code
03812 irplib_detmon_pernoise_save(const cpl_parameterlist * parlist,
03813 cpl_frameset * frameset,
03814 const char *recipe_name,
03815 const char *pipeline_name,
03816 const char *procatg_tbl,
03817 const char *package,
03818 cpl_table ** freq_table,
03819 cpl_propertylist ** qclist,
03820 const int flag_sets,
03821 const int which_set,
03822 const cpl_frameset * usedframes)
03823 {
03824
03825 cpl_frame *ref_frame;
03826 cpl_propertylist *plist;
03827 char *name_o = NULL;
03828 int i, j;
03829 cpl_propertylist *paflist;
03830 cpl_error_code error;
03831
03832 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03833 cpl_propertylist * pro_tbl = cpl_propertylist_new();
03834
03835 cpl_propertylist_append_string(pro_tbl,
03836 CPL_DFS_PRO_CATG, procatg_tbl);
03837
03838 cpl_propertylist_append(pro_tbl, qclist[0]);
03839
03840 #endif
03841
03842
03843
03844
03845
03846 if(detmon_pernoise_config.mode != 1) {
03847
03848 if(!flag_sets) {
03849 name_o = cpl_sprintf("%s_freq_table.fits", recipe_name);
03850 assert(name_o != NULL);
03851 } else {
03852 name_o =
03853 cpl_sprintf("%s_freq_table_set%02d.fits", recipe_name,
03854 which_set);
03855 assert(name_o != NULL);
03856 }
03857
03858 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03859
03860 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, freq_table[0],
03861 NULL, recipe_name, pro_tbl, NULL,
03862 package, name_o)) {
03863 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03864 cpl_free(name_o);
03865 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03866 }
03867 #else
03868
03869 if(cpl_dfs_save_table(frameset, parlist, usedframes, freq_table[0],
03870 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03871 package, name_o)) {
03872 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03873 cpl_free(name_o);
03874 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03875 }
03876 #endif
03877
03878 if(detmon_pernoise_config.exts < 0) {
03879
03880 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03881 error =
03882 cpl_table_save(freq_table[i], NULL, qclist[i], name_o,
03883 CPL_IO_EXTEND);
03884 cpl_ensure_code(!error, error);
03885 }
03886 }
03887
03888
03889 cpl_free(name_o);
03890
03891 } else {
03892 for (j = 1; j <= 4; j++) {
03893
03894 if(!flag_sets) {
03895 name_o = cpl_sprintf("%s_freq_table_quad%02d.fits",
03896 recipe_name, j);
03897 assert(name_o != NULL);
03898 } else {
03899 name_o =
03900 cpl_sprintf("%s_freq_table_quad%02d_set%02d.fits",
03901 recipe_name, j, which_set);
03902 assert(name_o != NULL);
03903 }
03904
03905 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03906
03907 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
03908 freq_table[j - 1],
03909 NULL, recipe_name, pro_tbl, NULL,
03910 package, name_o)) {
03911 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03912 cpl_free(name_o);
03913 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03914 }
03915 #else
03916
03917 if(cpl_dfs_save_table(frameset, parlist, usedframes,
03918 freq_table[j - 1],
03919 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03920 package, name_o)) {
03921 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03922 cpl_free(name_o);
03923 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03924 }
03925 #endif
03926
03927 if(detmon_pernoise_config.exts < 0) {
03928 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03929 error = cpl_table_save(freq_table[(j-1) + 4 * i],
03930 NULL, qclist[i], name_o,
03931 CPL_IO_EXTEND);
03932 cpl_ensure_code(!error, error);
03933 }
03934 }
03935
03936
03937 cpl_free(name_o);
03938 }
03939
03940 }
03941
03942
03943
03944
03945
03946 ref_frame = cpl_frameset_get_first(frameset);
03947 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03948 0)) == NULL) {
03949 cpl_msg_error(cpl_func, "getting header from reference frame");
03950 cpl_ensure_code(0, cpl_error_get_code());
03951 }
03952
03953
03954 paflist = cpl_propertylist_new();
03955 cpl_propertylist_copy_property_regexp(paflist, plist,
03956 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
03957 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
03958 "ESO DET NCORRS|"
03959 "ESO DET MODE NAME)$", 0);
03960
03961 for(i = 0; i < detmon_pernoise_config.nb_extensions; i++) {
03962 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
03963 error = cpl_propertylist_append(c_paflist, qclist[i]);
03964 cpl_ensure_code(!error, error);
03965
03966
03967 if(detmon_pernoise_config.exts >= 0) {
03968 if(!flag_sets) {
03969 name_o = cpl_sprintf("%s.paf", recipe_name);
03970 assert(name_o != NULL);
03971 } else {
03972 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
03973 assert(name_o != NULL);
03974 }
03975 } else {
03976 if(!flag_sets) {
03977 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
03978 assert(name_o != NULL);
03979 } else {
03980 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
03981 assert(name_o != NULL);
03982 }
03983 }
03984
03985 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
03986 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03987 cpl_free(name_o);
03988 cpl_propertylist_delete(paflist);
03989 cpl_propertylist_delete(plist);
03990 cpl_free(name_o);
03991 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03992 }
03993 cpl_propertylist_delete(c_paflist);
03994 cpl_free(name_o);
03995 }
03996
03997 cpl_propertylist_delete(plist);
03998 cpl_propertylist_delete(paflist);
03999 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04000 cpl_propertylist_delete(pro_tbl);
04001 #endif
04002 return cpl_error_get_code();
04003 }
04004
04005 static cpl_error_code
04006 irplib_detmon_pernoise_qc(cpl_propertylist * qclist,
04007 cpl_table * table,
04008 int iquad)
04009 {
04010 cpl_error_code error;
04011 char * propname;
04012
04013 double freqs[3] = {0, 0, 0};
04014 double pows[3] = {0, 0, 0};
04015
04016
04017
04018
04019
04020
04021
04022
04023 int nrows = cpl_table_get_nrow(table);
04024 int i;
04025
04026 double * all_freqs = cpl_table_get_data_double(table, "FREQ");
04027 double * all_pows = cpl_table_get_data_double(table, "POW");
04028
04029 for ( i= 1; i< nrows-1; i++){
04030 if (all_pows[i] > pows[0]) {
04031 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04032 pows[2]=pows[1];
04033 pows[1]=pows[0];
04034 pows[0]=all_pows[i];
04035
04036 freqs[2]=freqs[1];
04037 freqs[1]=freqs[0];
04038 freqs[0]=all_freqs[i];
04039 }
04040 } else if (all_pows[i] > pows[1]) {
04041 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04042 pows[2]=pows[1];
04043 pows[1]=all_pows[i];
04044
04045 freqs[2]=freqs[1];
04046 freqs[1]=all_freqs[i];
04047 }
04048
04049 } else if(all_pows[i] > pows[2]) {
04050 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04051 pows[2]=all_pows[i];
04052
04053 freqs[2]=all_freqs[i];
04054 }
04055
04056 }
04057 }
04058
04059 if (detmon_pernoise_config.mode == 1) {
04060 propname = cpl_sprintf("ESO QC FREQ1 %d", iquad);
04061 assert(propname != NULL);
04062 } else {
04063 propname = cpl_sprintf("ESO QC FREQ1");
04064 }
04065
04066 error = cpl_propertylist_append_double(qclist, propname, freqs[0]);
04067 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04068 cpl_ensure_code(!error, error);
04069
04070 cpl_free(propname);
04071
04072 if (detmon_pernoise_config.mode == 1) {
04073 propname = cpl_sprintf("ESO QC FREQ2 %d", iquad);
04074 assert(propname != NULL);
04075 } else {
04076 propname = cpl_sprintf("ESO QC FREQ2");
04077 }
04078
04079 error = cpl_propertylist_append_double(qclist, propname, freqs[1]);
04080 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04081 cpl_ensure_code(!error, error);
04082
04083 cpl_free(propname);
04084
04085 if (detmon_pernoise_config.mode == 1) {
04086 propname = cpl_sprintf("ESO QC FREQ3 %d", iquad);
04087 assert(propname != NULL);
04088 } else {
04089 propname = cpl_sprintf("ESO QC FREQ3");
04090 }
04091
04092 error = cpl_propertylist_append_double(qclist, propname, freqs[2]);
04093 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04094 cpl_ensure_code(!error, error);
04095
04096 cpl_free(propname);
04097
04098 if (detmon_pernoise_config.mode == 1) {
04099 propname = cpl_sprintf("ESO QC POW1 %d", iquad);
04100 assert(propname != NULL);
04101 } else {
04102 propname = cpl_sprintf("ESO QC POW1");
04103 }
04104
04105 error = cpl_propertylist_append_double(qclist, propname, pows[0]);
04106 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04107 cpl_ensure_code(!error, error);
04108
04109 cpl_free(propname);
04110
04111 if (detmon_pernoise_config.mode == 1) {
04112 propname = cpl_sprintf("ESO QC POW2 %d", iquad);
04113 assert(propname != NULL);
04114 } else {
04115 propname = cpl_sprintf("ESO QC POW2");
04116 }
04117
04118 error = cpl_propertylist_append_double(qclist, propname, pows[1]);
04119 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04120 cpl_ensure_code(!error, error);
04121
04122 cpl_free(propname);
04123
04124 if (detmon_pernoise_config.mode == 1) {
04125 propname = cpl_sprintf("ESO QC POW3 %d", iquad);
04126 assert(propname != NULL);
04127 } else {
04128 propname = cpl_sprintf("ESO QC POW3");
04129 }
04130
04131 error = cpl_propertylist_append_double(qclist, propname, pows[2]);
04132 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04133 cpl_ensure_code(!error, error);
04134
04135
04136 cpl_free(propname);
04137
04138 return cpl_error_get_code();
04139 }
04140
04141
04142
04143
04144
04145
04146
04147
04148
04149
04150
04151
04152 cpl_error_code
04153 irplib_detmon_pernoise_rm_bg(cpl_image * image, int nsamples, int nffts)
04154 {
04155 cpl_vector *values = cpl_vector_new(nsamples * nffts);
04156
04157 int rejected;
04158 int i, j;
04159 cpl_vector *xy_pos = cpl_vector_new(nsamples * nffts * 2);
04160 double mse;
04161 cpl_polynomial * poly_2d;
04162 cpl_image * poly_ima;
04163 int degree = 3;
04164
04165 cpl_matrix * samppos;
04166 cpl_vector * fitresidual;
04167
04168 for(i = 1; i <= nffts; i++) {
04169 for(j = 1; j <= nsamples; j++) {
04170 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1), j);
04171 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1) + nsamples * nffts, i);
04172 cpl_vector_set(values, (i - 1) * nsamples + (j - 1),
04173 cpl_image_get(image, j, i, &rejected));
04174 cpl_ensure_code(!cpl_error_get_code(), cpl_error_get_code());
04175 }
04176 }
04177
04178 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04179 poly_2d = cpl_polynomial_new(2);
04180 samppos =
04181 cpl_matrix_wrap(2, nsamples * nffts, cpl_vector_get_data(xy_pos));
04182 fitresidual = cpl_vector_new(nsamples * nffts);
04183 cpl_polynomial_fit(poly_2d, samppos, NULL, values, NULL,
04184 CPL_FALSE, NULL, °ree);
04185
04186 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, poly_2d,
04187 samppos, NULL);
04188 cpl_matrix_unwrap(samppos);
04189 mse = cpl_vector_product(fitresidual, fitresidual)
04190 / cpl_vector_get_size(fitresidual);
04191 cpl_vector_delete(fitresidual);
04192
04193 #else
04194 poly_2d = cpl_polynomial_fit_2d_create(xy_pos, values, 3, &mse);
04195 #endif
04196
04197 poly_ima = cpl_image_new(nsamples, nffts, CPL_TYPE_FLOAT);
04198
04199 cpl_image_fill_polynomial(poly_ima, poly_2d, 1, 1, 1, 1);
04200
04201 cpl_image_subtract(image, poly_ima);
04202
04203
04204
04205
04206
04207
04208
04209
04210
04211
04212
04213
04214
04215
04216
04217 cpl_polynomial_delete(poly_2d);
04218 cpl_image_delete(poly_ima);
04219 cpl_vector_delete(xy_pos);
04220 cpl_vector_delete(values);
04221
04222 return cpl_error_get_code();
04223 }
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236 cpl_error_code
04237 irplib_detmon_dark(cpl_frameset * frameset,
04238 const cpl_parameterlist * parlist,
04239 const char * tag,
04240 const char * recipe_name,
04241 const char * pipeline_name,
04242 const char * procatg_master,
04243 const char * procatg_dsnu,
04244 const char * procatg_tbl,
04245 const char * package,
04246 int (*compare)(const cpl_frame *,
04247 const cpl_frame *))
04248 {
04249 int nsets;
04250 int *selection = NULL;
04251 int i;
04252 cpl_error_code error;
04253
04254 if(irplib_detmon_dark_dfs_set_groups(frameset, tag)) {
04255 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
04256 }
04257
04258
04259
04260
04261
04262
04263 error = irplib_detmon_retrieve_dark_params(pipeline_name,
04264 recipe_name, parlist);
04265 cpl_ensure_code(!error, error);
04266
04267
04268 if(compare == NULL)
04269 nsets = 1;
04270 else {
04271 cpl_msg_info(cpl_func, "Identify the different settings");
04272 selection = cpl_frameset_labelise(frameset, compare, &nsets);
04273 if(selection == NULL)
04274 cpl_msg_error(cpl_func, "Cannot labelise input frames");
04275 }
04276
04277 detmon_dark_config.nb_extensions = 1;
04278 if(detmon_dark_config.exts < 0) {
04279 const cpl_frame *cur_frame =
04280 cpl_frameset_get_first_const(frameset);
04281
04282 detmon_dark_config.nb_extensions =
04283 cpl_frame_get_nextensions(cur_frame);
04284 }
04285
04286
04287 for(i = 0; i < nsets; i++) {
04288 int *select_dits = NULL;
04289 cpl_frameset *cur_fset =
04290 nsets == 1 ? cpl_frameset_duplicate(frameset) :
04291 cpl_frameset_extract(frameset, selection, i);
04292
04293 int ndits = 0;
04294 int j, k;
04295 cpl_table ** dsnu_table = NULL;
04296 cpl_imagelist ** dsnu = NULL;
04297
04298 cpl_propertylist ** qclist =
04299 (cpl_propertylist **)
04300 cpl_malloc(detmon_dark_config.nb_extensions *
04301 sizeof(cpl_propertylist *));
04302
04303
04304 cpl_imagelist ** masters =
04305 (cpl_imagelist **)
04306 cpl_malloc(detmon_dark_config.nb_extensions *
04307 sizeof(cpl_imagelist *));
04308
04309
04310 if(detmon_dark_config.opt_nir == OPT) {
04311 dsnu_table =
04312 (cpl_table **) cpl_malloc(detmon_dark_config.nb_extensions *
04313 sizeof(cpl_table *));
04314 dsnu =
04315 (cpl_imagelist **)
04316 cpl_malloc(detmon_dark_config.nb_extensions *
04317 sizeof(cpl_imagelist *));
04318 }
04319
04320 select_dits = cpl_frameset_labelise(cur_fset,
04321 irplib_detmon_compare_dits,
04322 &ndits);
04323
04324 if(detmon_dark_config.exts >= 0) {
04325 *masters = cpl_imagelist_new();
04326 if(detmon_dark_config.opt_nir == OPT) {
04327 *dsnu = cpl_imagelist_new();
04328 *dsnu_table = cpl_table_new(ndits);
04329 }
04330 *qclist = cpl_propertylist_new();
04331 cpl_table_new_column(*dsnu_table, "DIT", CPL_TYPE_DOUBLE);
04332 cpl_table_new_column(*dsnu_table, "STDEV", CPL_TYPE_DOUBLE);
04333 } else {
04334 for ( j = 0; j < detmon_dark_config.nb_extensions; j ++) {
04335 masters[j] = cpl_imagelist_new();
04336 if(detmon_dark_config.opt_nir == OPT) {
04337 dsnu[j] = cpl_imagelist_new();
04338 dsnu_table[j] = cpl_table_new(ndits);
04339 }
04340 qclist[j] = cpl_propertylist_new();
04341 cpl_table_new_column(dsnu_table[j], "DIT", CPL_TYPE_DOUBLE);
04342 cpl_table_new_column(dsnu_table[j], "STDEV", CPL_TYPE_DOUBLE);
04343 }
04344 }
04345
04346 for(j = 0; j < ndits; j++) {
04347 cpl_frameset * cur_fdit = cpl_frameset_extract(cur_fset,
04348 select_dits, j);
04349 cpl_imagelist ** raws =
04350 (cpl_imagelist **)
04351 cpl_malloc(detmon_dark_config.nb_extensions *
04352 sizeof(cpl_imagelist *));
04353
04354 if(detmon_dark_config.exts >= 0) {
04355 cpl_image * collapsed;
04356 *raws =
04357 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04358 detmon_dark_config.exts);
04359 collapsed = cpl_imagelist_collapse_create(*raws);
04360 cpl_imagelist_set(*masters, collapsed, j);
04361 if(detmon_dark_config.opt_nir == OPT) {
04362 irplib_detmon_dark_dsnu(cur_fdit, *dsnu, *dsnu_table,
04363 collapsed, j);
04364 }
04365 irplib_detmon_dark_qc(*qclist, collapsed);
04366 } else {
04367 cpl_imagelist *raws_all_exts =
04368 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04369 -1);
04370 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04371 int nframes = cpl_frameset_get_size(cur_fdit);
04372 int h;
04373 cpl_image * collapsed;
04374 for(h = 0; h < nframes; h++) {
04375 cpl_image *image =
04376 cpl_imagelist_unset(raws_all_exts,
04377 (detmon_dark_config.
04378 nb_extensions - 1 - k) * h);
04379 cpl_imagelist_set(raws[k], image, h);
04380 }
04381 collapsed = cpl_imagelist_collapse_create(raws[k]);
04382 cpl_imagelist_set(masters[k],collapsed, j);
04383 if(detmon_dark_config.opt_nir == OPT) {
04384 irplib_detmon_dark_dsnu(cur_fdit, dsnu[k],
04385 dsnu_table[j], collapsed, j);
04386 }
04387 irplib_detmon_dark_qc(qclist[k], collapsed);
04388 }
04389 }
04390
04391 cpl_frameset_delete(cur_fdit);
04392 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04393 cpl_imagelist_delete(raws[k]);
04394 }
04395 cpl_free(raws);
04396 }
04397
04398 cpl_frameset_delete(cur_fset);
04399
04400 irplib_detmon_dark_save(parlist, frameset, recipe_name, pipeline_name,
04401 procatg_master, procatg_tbl, procatg_dsnu,
04402 package, masters, dsnu_table, dsnu, qclist,
04403 0, 0, frameset);
04404
04405 if(detmon_dark_config.opt_nir == OPT) {
04406 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04407 cpl_table_delete(dsnu_table[j]);
04408 cpl_imagelist_delete(dsnu[j]);
04409 }
04410 cpl_free(dsnu_table);
04411 cpl_free(dsnu);
04412 }
04413
04414 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04415 cpl_propertylist_delete(qclist[j]);
04416 cpl_imagelist_delete(masters[j]);
04417 }
04418 cpl_free(qclist);
04419 cpl_free(masters);
04420 cpl_free(select_dits);
04421
04422 }
04423
04424 cpl_free(selection);
04425
04426 return cpl_error_get_code();
04427 }
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
04441 int
04442 irplib_detmon_dark_dfs_set_groups(cpl_frameset * set, const char *tag)
04443 {
04444 cpl_frame *cur_frame;
04445 const char *cur_tag;
04446 int nframes;
04447 int i;
04448
04449
04450 if(set == NULL)
04451 return -1;
04452
04453
04454 nframes = cpl_frameset_get_size(set);
04455
04456
04457 for(i = 0; i < nframes; i++) {
04458 cur_frame = cpl_frameset_get_frame(set, i);
04459 cur_tag = cpl_frame_get_tag(cur_frame);
04460
04461
04462 if(!strcmp(cur_tag, tag))
04463 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
04464
04465
04466
04467
04468
04469 }
04470 return 0;
04471 }
04472
04473
04474
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484 static cpl_error_code
04485 irplib_detmon_retrieve_dark_params(const char *pipeline_name,
04486 const char *recipe_name,
04487 const cpl_parameterlist * parlist)
04488 {
04489 char *par_name;
04490 cpl_parameter *par;
04491
04492
04493 par_name = cpl_sprintf("%s.%s.ron.method", pipeline_name, recipe_name);
04494 assert(par_name != NULL);
04495 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04496 detmon_dark_config.ron_method = cpl_parameter_get_string(par);
04497 cpl_free(par_name);
04498
04499
04500 par_name = cpl_sprintf("%s.%s.dsnu.method", pipeline_name, recipe_name);
04501 assert(par_name != NULL);
04502 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04503 detmon_dark_config.dsnu_method = cpl_parameter_get_string(par);
04504 cpl_free(par_name);
04505
04506
04507 par_name = cpl_sprintf("%s.%s.opt_nir", pipeline_name, recipe_name);
04508 assert(par_name != NULL);
04509 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04510 detmon_dark_config.opt_nir = cpl_parameter_get_bool(par);
04511 cpl_free(par_name);
04512
04513
04514 detmon_dark_config.exts =
04515 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
04516 parlist);
04517
04518 if(cpl_error_get_code()) {
04519 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
04520 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
04521 }
04522
04523
04524 return CPL_ERROR_NONE;
04525 }
04526
04527
04528
04529
04530
04531
04532
04533
04534
04535
04536
04537
04538
04539 cpl_error_code
04540 irplib_detmon_fill_dark_params(cpl_parameterlist * parlist,
04541 const char *recipe_name,
04542 const char *pipeline_name,
04543 const char * ron_method,
04544 const char * dsnu_method,
04545 const char * opt_nir,
04546 int exts)
04547 {
04548 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 4,
04549
04550 "ron.method",
04551 "Method used to compute RON. Currently no "
04552 "change is possible, RMS computed",
04553 "CPL_TYPE_STRING", ron_method,
04554
04555 "dsnu.method",
04556 "Method used to compute DSNU map. Currently no "
04557 "change is possible. Method used STDEV",
04558 "CPL_TYPE_STRING", dsnu_method,
04559
04560 "opt_nir",
04561 "Boolean, OPT (FALSE) or NIR(TRUE)",
04562 "CPL_TYPE_BOOL", opt_nir,
04563
04564 "exts",
04565 "Activate the multi-exts option. Default 0"
04566 "(primary unit), -1 (all exts)",
04567 "CPL_TYPE_INT", exts);
04568
04569 return cpl_error_get_code();
04570 }
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580
04581
04582
04583 int
04584 irplib_detmon_fill_dark_params_default(cpl_parameterlist * parlist,
04585 const char *recipe_name,
04586 const char *pipeline_name)
04587 {
04588 irplib_detmon_fill_dark_params(parlist, recipe_name, pipeline_name,
04589 "SIMPLE",
04590 "STDEV",
04591 "CPL_FALSE",
04592 0);
04593 return cpl_error_get_code();
04594 }
04595
04596
04597
04598
04599
04600
04601
04602
04603
04604
04605
04606
04607 cpl_error_code
04608 irplib_detmon_dark_dsnu(cpl_frameset * cur_fdit,
04609 cpl_imagelist * dsnu,
04610 cpl_table * dsnu_table,
04611 cpl_image * collapsed,
04612 int pos)
04613 {
04614 cpl_frame * first = cpl_frameset_get_first(cur_fdit);
04615 cpl_propertylist * plist =
04616 cpl_propertylist_load(cpl_frame_get_filename(first), 0);
04617 double dit = irplib_pfits_get_exptime(plist);
04618 double mean = cpl_image_get_mean(collapsed);
04619
04620 cpl_image * dsnu_map =
04621 cpl_image_subtract_scalar_create(collapsed, mean);
04622 double stdev;
04623 cpl_image_divide_scalar(dsnu_map, mean);
04624 stdev = cpl_image_get_stdev(dsnu_map);
04625
04626 cpl_imagelist_set(dsnu, dsnu_map, pos);
04627
04628 cpl_table_set(dsnu_table, "DIT", pos, dit);
04629 cpl_table_set(dsnu_table, "STDEV", pos, stdev);
04630
04631 cpl_propertylist_delete(plist);
04632
04633 return cpl_error_get_code();
04634
04635 }
04636
04637
04638
04639
04640
04641
04642
04643
04644
04645
04646
04647
04648 static cpl_error_code
04649 irplib_detmon_dark_save(const cpl_parameterlist * parlist,
04650 cpl_frameset * frameset,
04651 const char *recipe_name,
04652 const char *pipeline_name,
04653 const char *procatg_master,
04654 const char *procatg_tbl,
04655 const char *procatg_dsnu,
04656 const char *package,
04657 cpl_imagelist ** masters,
04658 cpl_table ** dsnu_table,
04659 cpl_imagelist ** dsnu,
04660 cpl_propertylist ** qclist,
04661 const int flag_sets,
04662 const int which_set,
04663 const cpl_frameset * usedframes)
04664 {
04665
04666 cpl_frame *ref_frame;
04667 cpl_propertylist *plist;
04668 char *name_o = NULL;
04669 int i, j;
04670 cpl_propertylist *paflist;
04671 cpl_error_code error;
04672 int nb_images;
04673
04674
04675
04676
04677
04678 nb_images = cpl_imagelist_get_size(masters[0]);
04679 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
04680
04681
04682 for(i = 0; i < nb_images; i++) {
04683
04684 if(!flag_sets) {
04685 name_o =
04686 cpl_sprintf("%s_master_dit_%d.fits", recipe_name, i+1);
04687 assert(name_o != NULL);
04688 } else {
04689 name_o =
04690 cpl_sprintf("%s_master_dit_%d_set%02d.fits",
04691 recipe_name, i, which_set);
04692 assert(name_o != NULL);
04693 }
04694
04695
04696
04697 if(detmon_dark_config.exts >= 0) {
04698 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04699 cpl_propertylist * pro_master = cpl_propertylist_new();
04700
04701 cpl_propertylist_append_string(pro_master,
04702 CPL_DFS_PRO_CATG, procatg_master);
04703
04704 cpl_propertylist_append(pro_master, qclist[0]);
04705
04706 if(cpl_dfs_save_image
04707 (frameset, NULL, parlist, usedframes, NULL,
04708 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04709 recipe_name, pro_master, NULL, package,
04710 name_o)) {
04711 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04712 name_o);
04713 cpl_free(name_o);
04714 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04715
04716 }
04717
04718 cpl_propertylist_delete(pro_master);
04719 #else
04720 if(cpl_dfs_save_image
04721 (frameset, parlist, usedframes,
04722 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04723 recipe_name, procatg_master, qclist[0], NULL, package,
04724 name_o)) {
04725 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04726 name_o);
04727 cpl_free(name_o);
04728 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04729
04730 }
04731 #endif
04732 } else {
04733 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04734 cpl_propertylist * pro_master = cpl_propertylist_new();
04735
04736 cpl_propertylist_append_string(pro_master,
04737 CPL_DFS_PRO_CATG, procatg_master);
04738
04739 cpl_propertylist_append(pro_master, qclist[0]);
04740
04741 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
04742 NULL, CPL_BPP_IEEE_FLOAT, recipe_name,
04743 pro_master, NULL,
04744 package, name_o)) {
04745 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04746 name_o);
04747 cpl_free(name_o);
04748 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04749 }
04750
04751 cpl_propertylist_delete(pro_master);
04752 #else
04753 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04754 CPL_BPP_IEEE_FLOAT, recipe_name,
04755 procatg_master, qclist[0], NULL,
04756 package, name_o)) {
04757 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04758 name_o);
04759 cpl_free(name_o);
04760 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04761 }
04762 #endif
04763 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04764 error =
04765 cpl_image_save(cpl_imagelist_get(masters[j], i),
04766 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04767 CPL_IO_EXTEND);
04768 cpl_ensure_code(!error, error);
04769 }
04770 }
04771 cpl_free(name_o);
04772 }
04773
04774 if (detmon_dark_config.opt_nir == OPT) {
04775 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04776 cpl_propertylist * pro_tbl = cpl_propertylist_new();
04777
04778 cpl_propertylist_append_string(pro_tbl,
04779 CPL_DFS_PRO_CATG, procatg_tbl);
04780
04781 cpl_propertylist_append(pro_tbl, qclist[0]);
04782 #endif
04783
04784
04785
04786
04787
04788 if(!flag_sets) {
04789 name_o = cpl_sprintf("%s_dsnu_table.fits", recipe_name);
04790 assert(name_o != NULL);
04791 } else {
04792 name_o =
04793 cpl_sprintf("%s_dsnu_table_set%02d.fits", recipe_name,
04794 which_set);
04795 assert(name_o != NULL);
04796 }
04797 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04798
04799 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
04800 dsnu_table[0], NULL, recipe_name, pro_tbl, NULL,
04801 package, name_o)) {
04802 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04803 cpl_free(name_o);
04804 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04805 }
04806 #else
04807
04808 if(cpl_dfs_save_table(frameset, parlist, usedframes, dsnu_table[0],
04809 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
04810 package, name_o)) {
04811 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04812 cpl_free(name_o);
04813 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04814 }
04815 #endif
04816
04817 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04818 cpl_propertylist_delete(pro_tbl);
04819 #endif
04820
04821 if(detmon_dark_config.exts < 0) {
04822
04823 for(i = 1; i < detmon_dark_config.nb_extensions; i++) {
04824 error =
04825 cpl_table_save(dsnu_table[i], NULL, qclist[i], name_o,
04826 CPL_IO_EXTEND);
04827 cpl_ensure_code(!error, error);
04828 }
04829 }
04830
04831
04832 cpl_free(name_o);
04833
04834
04835
04836
04837
04838 for(i = 0; i < nb_images; i++) {
04839
04840 if(!flag_sets) {
04841 name_o =
04842 cpl_sprintf("%s_dsnu_map_dit_%d.fits", recipe_name, i+1);
04843 assert(name_o != NULL);
04844 } else {
04845 name_o =
04846 cpl_sprintf("%s_dsnu_map_dit_%d_set%02d.fits",
04847 recipe_name, i, which_set);
04848 assert(name_o != NULL);
04849 }
04850
04851
04852
04853 if(detmon_dark_config.exts >= 0) {
04854 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04855 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04856
04857 cpl_propertylist_append_string(pro_dsnu,
04858 CPL_DFS_PRO_CATG, procatg_dsnu);
04859
04860 cpl_propertylist_append(pro_dsnu, qclist[0]);
04861
04862 if(cpl_dfs_save_image
04863 (frameset, NULL, parlist, usedframes, NULL,
04864 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04865 recipe_name, pro_dsnu, NULL, package,
04866 name_o)) {
04867 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04868 name_o);
04869 cpl_free(name_o);
04870 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04871
04872 }
04873
04874 cpl_propertylist_delete(pro_dsnu);
04875 #else
04876 if(cpl_dfs_save_image
04877 (frameset, parlist, usedframes,
04878 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04879 recipe_name, procatg_dsnu, qclist[0], NULL, package,
04880 name_o)) {
04881 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04882 name_o);
04883 cpl_free(name_o);
04884 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04885
04886 }
04887 #endif
04888 } else {
04889 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04890 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04891
04892 cpl_propertylist_append_string(pro_dsnu,
04893 CPL_DFS_PRO_CATG, procatg_dsnu);
04894
04895 cpl_propertylist_append(pro_dsnu, qclist[0]);
04896
04897 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
04898 NULL, NULL,
04899 CPL_BPP_IEEE_FLOAT, recipe_name,
04900 pro_dsnu, NULL,
04901 package, name_o)) {
04902 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04903 name_o);
04904 cpl_free(name_o);
04905 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04906 }
04907
04908 cpl_propertylist_delete(pro_dsnu);
04909 #else
04910 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04911 CPL_BPP_IEEE_FLOAT, recipe_name,
04912 procatg_dsnu, qclist[0], NULL,
04913 package, name_o)) {
04914 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04915 name_o);
04916 cpl_free(name_o);
04917 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04918 }
04919 #endif
04920 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04921 error =
04922 cpl_image_save(cpl_imagelist_get(dsnu[j], i),
04923 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04924 CPL_IO_EXTEND);
04925 cpl_ensure_code(!error, error);
04926 }
04927 }
04928 cpl_free(name_o);
04929 }
04930
04931
04932
04933 }
04934
04935
04936
04937
04938
04939
04940 ref_frame = cpl_frameset_get_first(frameset);
04941 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04942 0)) == NULL) {
04943 cpl_msg_error(cpl_func, "getting header from reference frame");
04944 cpl_ensure_code(0, cpl_error_get_code());
04945 }
04946
04947
04948 paflist = cpl_propertylist_new();
04949 cpl_propertylist_copy_property_regexp(paflist, plist,
04950 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
04951 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
04952 "ESO DET NCORRS|"
04953 "ESO DET MODE NAME)$", 0);
04954
04955 for(i = 0; i < detmon_dark_config.nb_extensions; i++) {
04956 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
04957 error = cpl_propertylist_append(c_paflist, qclist[i]);
04958 cpl_ensure_code(!error, error);
04959
04960
04961 if(detmon_dark_config.exts >= 0) {
04962 if(!flag_sets) {
04963 name_o = cpl_sprintf("%s.paf", recipe_name);
04964 assert(name_o != NULL);
04965 } else {
04966 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
04967 assert(name_o != NULL);
04968 }
04969 } else {
04970 if(!flag_sets) {
04971 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
04972 assert(name_o != NULL);
04973 } else {
04974 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
04975 assert(name_o != NULL);
04976 }
04977 }
04978
04979 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
04980 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04981 cpl_free(name_o);
04982 cpl_propertylist_delete(paflist);
04983 cpl_propertylist_delete(plist);
04984 cpl_free(name_o);
04985 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04986 }
04987 cpl_propertylist_delete(c_paflist);
04988 cpl_free(name_o);
04989 }
04990
04991 cpl_propertylist_delete(plist);
04992 cpl_propertylist_delete(paflist);
04993
04994 return cpl_error_get_code();
04995 }
04996
04997 cpl_error_code
04998 irplib_detmon_dark_qc(cpl_propertylist * qclist,
04999 cpl_image * collapsed)
05000 {
05001 double mean = cpl_image_get_mean(collapsed);
05002 double stdev = cpl_image_get_stdev(collapsed);
05003
05004 cpl_error_code error;
05005
05006 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK, mean);
05007 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK,
05008 DETMON_QC_DARK_C);
05009 cpl_ensure_code(!error, error);
05010
05011 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK_STDEV, stdev);
05012 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK_STDEV,
05013 DETMON_QC_DARK_STDEV_C);
05014 cpl_ensure_code(!error, error);
05015
05016 return cpl_error_get_code();
05017 }
05018
05019
05020
05037
05038 cpl_image *
05039 irplib_imagelist_collapse_stdev_create(const cpl_imagelist * imlist)
05040 {
05041 cpl_image * mean;
05042 cpl_image * delta;
05043 cpl_image * sq_delta;
05044 cpl_image * stdev;
05045
05046 int i;
05047
05048
05049 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05050 cpl_ensure(cpl_imagelist_is_uniform(imlist) == 0, CPL_ERROR_ILLEGAL_INPUT,
05051 NULL);
05052
05053
05054 mean = cpl_image_duplicate(cpl_imagelist_get_const(imlist, 0));
05055 cpl_image_fill_rejected(mean, 0.0);
05056 cpl_image_accept_all(mean);
05057
05058 stdev = cpl_image_new(cpl_image_get_size_x(mean),
05059 cpl_image_get_size_y(mean),
05060 CPL_TYPE_FLOAT);
05061
05062 for (i = 1; i < cpl_imagelist_get_size(imlist); i++) {
05063 delta = cpl_image_subtract_create(cpl_imagelist_get_const(imlist, i),
05064 mean);
05065 cpl_image_fill_rejected(delta, 0.0);
05066 cpl_image_accept_all(delta);
05067
05068 sq_delta = cpl_image_multiply_create(delta, delta);
05069
05070 cpl_image_multiply_scalar(sq_delta, ((double) i / (double)(i+1)));
05071 cpl_image_add(stdev, sq_delta);
05072
05073 cpl_image_divide_scalar(delta, i + 1);
05074 cpl_image_add(mean, delta);
05075
05076 cpl_image_delete(delta);
05077 cpl_image_delete(sq_delta);
05078 }
05079
05080 cpl_image_divide_scalar(stdev, cpl_imagelist_get_size(imlist) - 1);
05081 cpl_image_power(stdev, 0.5);
05082
05083 cpl_image_delete(mean);
05084
05085 return stdev;
05086 }