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