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