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 }
01284
01285 *kmean = mean;
01286 if (kstdev != NULL) *kstdev = stdev;
01287
01288 end_skip;
01289
01290 return cpl_error_get_code();
01291 }
01292
01293 #define CONCAT(a,b) a ## _ ## b
01294 #define CONCAT2X(a,b) CONCAT(a,b)
01295
01296 #define CPL_TYPE double
01297 #include "irplib_detmon_body.h"
01298 #undef CPL_TYPE
01299
01300 #define CPL_TYPE float
01301 #include "irplib_detmon_body.h"
01302 #undef CPL_TYPE
01303
01304 #define CPL_TYPE int
01305 #include "irplib_detmon_body.h"
01306 #undef CPL_TYPE
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319 cpl_error_code
01320 irplib_detmon_ronbias(cpl_frameset * frameset,
01321 const cpl_parameterlist * parlist,
01322 const char *tag,
01323 const char *recipe_name,
01324 const char *pipeline_name,
01325 const char *pafregexp,
01326 const cpl_propertylist * pro_master,
01327 const cpl_propertylist * pro_xstr,
01328 const cpl_propertylist * pro_ystr,
01329 const cpl_propertylist * pro_synth,
01330 const cpl_propertylist * pro_bpmhot,
01331 const cpl_propertylist * pro_bpmcold,
01332 const cpl_propertylist * pro_bpmdev,
01333 const char *package,
01334 int (*compare) (const cpl_frame *, const cpl_frame *),
01335 cpl_boolean opt_nir)
01336 {
01337
01338 int nsets;
01339 int i;
01340
01341 int * selection = NULL;
01342 cpl_frameset * cur_fset = NULL;
01343 cpl_propertylist * qclist = NULL;
01344 cpl_image * synthetic = NULL;
01345 cpl_image * masterbias = NULL;
01346 cpl_imagelist * rawbiases = NULL;
01347 cpl_mask * bpmhot = NULL;
01348 cpl_mask * bpmcold = NULL;
01349 cpl_mask * bpmdev = NULL;
01350
01351
01352 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
01353 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
01354 cpl_ensure_code(tag != NULL, CPL_ERROR_NULL_INPUT);
01355 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
01356 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
01357 cpl_ensure_code(pro_master != NULL, CPL_ERROR_NULL_INPUT);
01358 cpl_ensure_code(pro_bpmhot != NULL, CPL_ERROR_NULL_INPUT);
01359 cpl_ensure_code(pro_bpmcold != NULL, CPL_ERROR_NULL_INPUT);
01360 cpl_ensure_code(pro_bpmdev != NULL, CPL_ERROR_NULL_INPUT);
01361 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
01362
01363 if(irplib_detmon_ronbias_dfs_set_groups(frameset, tag)) {
01364 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
01365 }
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380 irplib_detmon_ronbias_retrieve_parlist(pipeline_name,
01381 recipe_name, parlist, opt_nir);
01382
01383
01384 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN)
01385 cpl_ensure_code(pro_synth != NULL, CPL_ERROR_NULL_INPUT);
01386
01387
01388
01389 if(compare == NULL)
01390 nsets = 1;
01391 else {
01392 cpl_msg_info(cpl_func, "Identify the different settings");
01393 selection = cpl_frameset_labelise(frameset, compare, &nsets);
01394 if(selection == NULL)
01395 cpl_msg_error(cpl_func, "Cannot labelise input frames");
01396 }
01397
01398
01399 for(i = 0; i < nsets; i++) {
01400 int j;
01401 int first_ext = 0;
01402 int last_ext = 1;
01403
01404 detmon_ronbias_config.nb_extensions = 1;
01405
01406
01407 cpl_msg_info(cpl_func, "Reduce data set nb %d out of %d",
01408 i + 1, nsets);
01409
01410 cur_fset = nsets == 1 ?
01411 cpl_frameset_duplicate(frameset) :
01412 cpl_frameset_extract(frameset, selection, i);
01413 skip_if(cur_fset == NULL);
01414
01415 if(detmon_ronbias_config.exts > 0) {
01416 first_ext = detmon_ronbias_config.exts;
01417 last_ext = first_ext + 1;
01418 } else if(detmon_ronbias_config.exts < 0) {
01419 const cpl_frame *cur_frame =
01420 cpl_frameset_get_first_const(cur_fset);
01421
01422 detmon_ronbias_config.nb_extensions =
01423 cpl_frame_get_nextensions(cur_frame);
01424 first_ext = 1;
01425 last_ext = detmon_ronbias_config.nb_extensions + 1;
01426 }
01427
01428 if (last_ext - first_ext > 1) {
01429 skip_if(irplib_detmon_ronbias_save(parlist, frameset,
01430 recipe_name,
01431 pipeline_name, pafregexp,
01432 pro_master, pro_xstr,
01433 pro_ystr, pro_synth,
01434 pro_bpmhot,
01435 pro_bpmcold, pro_bpmdev,
01436 package, NULL, NULL, NULL,
01437 NULL, NULL, NULL,
01438 0, 0, cur_fset, 0));
01439 }
01440
01441 for(j = first_ext; j < last_ext; j++) {
01442 int whichext;
01443
01444 qclist = cpl_propertylist_new();
01445
01446 rawbiases
01447 = cpl_imagelist_load_frameset(cur_fset,
01448 CPL_TYPE_FLOAT, 1, j);
01449 skip_if(rawbiases == NULL);
01450
01451 skip_if(irplib_detmon_ronbias_check_defaults(cur_fset, j));
01452
01453 skip_if(irplib_detmon_ronbias_dutycycl(cur_fset, qclist));
01454
01455 masterbias = irplib_detmon_ronbias_master(rawbiases,
01456 &bpmhot, &bpmcold,
01457 &bpmdev, qclist);
01458 skip_if(masterbias == NULL);
01459
01460
01461
01462
01463
01464
01465 if(detmon_ronbias_config.method_bitmask & RANDOM) {
01466 skip_if(irplib_detmon_ronbias_random(rawbiases, masterbias,
01467 qclist));
01468 }
01469
01470 if(detmon_ronbias_config.method_bitmask & HISTO) {
01471 skip_if(irplib_detmon_ronbias_histo(rawbiases, masterbias,
01472 qclist));
01473 }
01474
01475 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
01476 skip_if(irplib_detmon_ronbias_preoverscan(rawbiases,
01477
01478 qclist, &synthetic));
01479 }
01480
01481 if(detmon_ronbias_config.method_bitmask & REGION) {
01482 skip_if(irplib_detmon_ronbias_region(rawbiases, masterbias,
01483 qclist));
01484 }
01485
01486
01487
01488
01489
01490
01491 #if 0
01492 irplib_detmon_ronbias_check(qclist);
01493 #endif
01494
01495
01496
01497
01498 whichext = first_ext > 1 ? 0 : j;
01499
01500 skip_if(irplib_detmon_ronbias_save(parlist, frameset,
01501 recipe_name,
01502 pipeline_name, pafregexp,
01503 pro_master, pro_xstr,
01504 pro_ystr, pro_synth,
01505 pro_bpmhot,
01506 pro_bpmcold, pro_bpmdev,
01507 package, masterbias, synthetic,
01508 bpmhot, bpmcold, bpmdev,
01509 qclist, 0, 0, cur_fset,
01510 whichext));
01511
01512 cpl_image_delete(synthetic);
01513 cpl_image_delete(masterbias);
01514 cpl_mask_delete(bpmhot);
01515 cpl_mask_delete(bpmcold);
01516 cpl_mask_delete(bpmdev);
01517 cpl_imagelist_delete(rawbiases);
01518 cpl_propertylist_delete(qclist);
01519
01520 qclist = NULL;
01521 rawbiases = NULL;
01522 masterbias = NULL;
01523 bpmhot = NULL;
01524 bpmcold = NULL;
01525 bpmdev = NULL;
01526 synthetic = NULL;
01527 }
01528
01529 cpl_frameset_delete(cur_fset);
01530 cur_fset = NULL;
01531
01532 }
01533
01534 end_skip;
01535
01536 cpl_free(selection);
01537
01538 cpl_frameset_delete(cur_fset);
01539
01540 cpl_image_delete(synthetic);
01541 cpl_image_delete(masterbias);
01542 cpl_mask_delete(bpmhot);
01543 cpl_mask_delete(bpmcold);
01544 cpl_mask_delete(bpmdev);
01545 cpl_imagelist_delete(rawbiases);
01546 cpl_propertylist_delete(qclist);
01547
01548 return cpl_error_get_code();
01549 }
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562 static cpl_error_code
01563 irplib_detmon_ronbias_random(const cpl_imagelist * rawbiases,
01564 const cpl_image * masterbias,
01565 cpl_propertylist * qclist)
01566 {
01567 int nraws = cpl_imagelist_get_size(rawbiases);
01568 int i;
01569 double bias = DBL_MAX;
01570 double bias_error;
01571
01572 double ron_error;
01573 double *ron =
01574 (double *) cpl_malloc(sizeof(double) * nraws);
01575
01576 cpl_vector *v;
01577 double stdev = 0;
01578 cpl_error_code error = CPL_ERROR_NONE;
01579
01580
01581
01582 if(!strcmp(detmon_ronbias_config.pmethod, "DIF"))
01583 {
01584 nraws--;
01585
01586
01587 for(i = 0; i < nraws; i++)
01588 {
01589 const cpl_image *c1_raw =
01590 cpl_imagelist_get_const(rawbiases, i);
01591 const cpl_image *c2_raw =
01592 cpl_imagelist_get_const(rawbiases, i + 1);
01593
01594 const cpl_image *c_raw = cpl_image_subtract_create(c1_raw,
01595 c2_raw);
01596 error = cpl_flux_get_noise_window(c_raw, NULL,
01597 detmon_ronbias_config.random_sizex / 2,
01598 detmon_ronbias_config.random_nsamples,
01599 ron + i, &ron_error);
01600 cpl_image_delete((cpl_image*)c_raw);
01601 if (error != CPL_ERROR_NONE)
01602 {
01603 break;
01604 }
01605 }
01606 } else
01607 {
01608 for(i = 0; i < nraws; i++)
01609 {
01610 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
01611 skip_if(cpl_flux_get_noise_window(c_raw, NULL,
01612 detmon_ronbias_config.random_sizex / 2,
01613 detmon_ronbias_config.random_nsamples,
01614 ron + i, &ron_error));
01615 }
01616 }
01617
01618
01619
01620 if (error == CPL_ERROR_NONE)
01621 {
01622 irplib_flux_get_bias_window(masterbias, NULL,
01623 detmon_ronbias_config.random_sizex / 2,
01624 detmon_ronbias_config.random_nsamples,
01625 &bias, &bias_error);
01626
01627 v = cpl_vector_wrap(nraws, ron);
01628 stdev = cpl_vector_get_median_const(v);
01629 cpl_vector_unwrap(v);
01630
01631
01632 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_VAL, bias));
01633 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_VAL,
01634 DETMON_QC_BIAS_RANDOM_VAL_C));
01635
01636 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_RON, stdev));
01637 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_RON,
01638 DETMON_QC_BIAS_RANDOM_RON_C));
01639 }
01640
01641 irplib_flux_get_bias_window(masterbias, NULL,
01642 detmon_ronbias_config.random_sizex / 2,
01643 detmon_ronbias_config.random_nsamples,
01644 &bias, &bias_error);
01645
01646 v = cpl_vector_wrap(nraws, ron);
01647 if (v)
01648 {
01649 stdev = cpl_vector_get_median_const(v);
01650 cpl_vector_unwrap(v);
01651 }
01652
01653 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_VAL, bias);
01654 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_VAL,
01655 DETMON_QC_BIAS_RANDOM_VAL_C);
01656
01657
01658 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_RANDOM_RON, stdev);
01659 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_RANDOM_RON,
01660 DETMON_QC_BIAS_RANDOM_RON_C);
01661
01662 end_skip;
01663 if (ron)
01664 cpl_free(ron);
01665 return cpl_error_get_code();
01666 }
01667
01668 static cpl_error_code
01669 irplib_detmon_ronbias_histo(const cpl_imagelist * rawbiases,
01670 const cpl_image * masterbias,
01671 cpl_propertylist * qclist)
01672 {
01673 int nraws = cpl_imagelist_get_size(rawbiases);
01674 int i;
01675
01676 double mbias = DBL_MAX;
01677 double mfwhm = DBL_MAX;
01678 double mmax = DBL_MAX;
01679
01680 cpl_vector * fwhms;
01681 cpl_vector * maxs;
01682
01683 double mean_fwhm = DBL_MAX;
01684
01685 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) nraws--;
01686
01687 fwhms = cpl_vector_new(nraws);
01688 maxs = cpl_vector_new(nraws);
01689
01690 for(i = 0; i < nraws; i++) {
01691
01692 const cpl_image * c_raw;
01693 double bias = DBL_MAX;
01694 double fwhm = DBL_MAX;
01695 double max = DBL_MAX;
01696
01697 if(strcmp(detmon_ronbias_config.pmethod, "DIF")) {
01698 c_raw = cpl_imagelist_get_const(rawbiases, i);
01699 } else {
01700 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
01701 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
01702 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
01703 }
01704
01705 skip_if(irplib_detmon_ronbias_histo_reduce(c_raw, &bias, &fwhm, &max));
01706
01707 skip_if(bias == DBL_MAX || fwhm == DBL_MAX || max == DBL_MAX);
01708
01709 if(!strcmp(detmon_ronbias_config.pmethod, "DIF"))
01710 cpl_image_delete((cpl_image *)c_raw);
01711
01712 skip_if(cpl_vector_set(maxs, i, max));
01713 skip_if(cpl_vector_set(fwhms, i, fwhm));
01714
01715
01716 }
01717
01718 skip_if(cpl_vector_divide_scalar(fwhms, HIST_FACT));
01719
01720 irplib_detmon_ronbias_histo_reduce(masterbias, &mbias, &mfwhm, &mmax);
01721
01722 skip_if(mbias == DBL_MAX || mfwhm == DBL_MAX || mmax == DBL_MAX);
01723
01724 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_HISTO_VAL,
01725 mbias));
01726 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_HISTO_VAL,
01727 DETMON_QC_BIAS_HISTO_VAL_C));
01728 mean_fwhm = cpl_vector_get_mean(fwhms);
01729
01730 skip_if(mean_fwhm == DBL_MAX);
01731 skip_if(cpl_error_get_code());
01732
01733 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_HISTO_RON,
01734 mean_fwhm));
01735 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_HISTO_RON,
01736 DETMON_QC_BIAS_HISTO_RON_C));
01737
01738 end_skip;
01739
01740 cpl_vector_delete(fwhms);
01741 cpl_vector_delete(maxs);
01742
01743 return cpl_error_get_code();
01744 }
01745
01746 cpl_error_code
01747 irplib_detmon_ronbias_histo_reduce(const cpl_image * c_raw,
01748 double * bias,
01749 double * fwhm,
01750 double * max)
01751 {
01752 unsigned long uj;
01753 irplib_hist *hist;
01754 unsigned long maxwhere = 0;
01755 unsigned long maxf;
01756
01757 double mean, stdev;
01758 cpl_image * dupi;
01759 unsigned long x1a = 1;
01760 unsigned long x2a = 1;
01761
01762 double x1 = 0;
01763 double x2 = 0;
01764
01765 double maxwhere_interp;
01766 double max_interp;
01767 double a, b, c;
01768 cpl_matrix * coeffs =cpl_matrix_new(3, 3);
01769 cpl_matrix * rhs =cpl_matrix_new(3, 1);
01770 int p, q;
01771 cpl_matrix * result = NULL;
01772 cpl_error_code error;
01773
01774 mean = cpl_image_get_mean(c_raw);
01775 stdev = cpl_image_get_stdev(c_raw);
01776 dupi = cpl_image_duplicate(c_raw);
01777
01778
01779
01780
01781 hist = irplib_hist_new();
01782 error = irplib_hist_fill(hist, dupi);
01783 cpl_ensure_code(!error, error);
01784
01785 cpl_image_delete(dupi);
01786
01787 maxf = irplib_hist_get_max(hist, &maxwhere);
01788
01789 for( p = 0; p< 3; p++){
01790 unsigned long bi = irplib_hist_get_value(hist, maxwhere-1+p);
01791 cpl_matrix_set(rhs, p, 0, bi);
01792 for( q= 0; q< 3; q++) {
01793 cpl_matrix_set(coeffs, p,q,pow((maxwhere-1+p),q));
01794 }
01795 }
01796
01797 result = cpl_matrix_solve(coeffs, rhs);
01798
01799 a = cpl_matrix_get(result, 2, 0);
01800 b = cpl_matrix_get(result, 1, 0);
01801 c = cpl_matrix_get(result, 0, 0);
01802
01803 maxwhere_interp = -0.5 * b / (2 * a);
01804 max_interp = -1 * b * b / (4 * a) + c;
01805
01806 cpl_matrix_delete(coeffs);
01807 cpl_matrix_delete(rhs);
01808 cpl_matrix_delete(result);
01809
01810
01811 for(uj = 0; uj < maxwhere; uj++) {
01812 if(irplib_hist_get_value(hist, uj) <= max_interp / 2 &&
01813 irplib_hist_get_value(hist, uj + 1) > max_interp / 2) {
01814 x1a = uj;
01815 }
01816 }
01817 for(uj = maxwhere; uj < irplib_hist_get_nbins(hist)-1; uj++) {
01818 if(irplib_hist_get_value(hist, uj) >= max_interp / 2 &&
01819 irplib_hist_get_value(hist, uj + 1) < max_interp / 2) {
01820 x2a = uj;
01821 }
01822 }
01823
01824 x1 = (max_interp / 2 - irplib_hist_get_value(hist, x1a)) /
01825 (irplib_hist_get_value(hist, x1a + 1) -
01826 irplib_hist_get_value(hist, x1a)) + x1a;
01827 x2 = (max_interp / 2 - irplib_hist_get_value(hist, x2a)) /
01828 (irplib_hist_get_value(hist, x2a + 1) -
01829 irplib_hist_get_value(hist, x2a)) + x2a;
01830
01831 *fwhm = (x2 - x1) * irplib_hist_get_bin_size(hist);
01832
01833 *max = max_interp;
01834
01835 *bias = maxwhere_interp * irplib_hist_get_bin_size(hist) +
01836 irplib_hist_get_start(hist);
01837
01838 irplib_hist_delete(hist);
01839
01840 return cpl_error_get_code();
01841 }
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853 static cpl_error_code
01854 irplib_detmon_ronbias_preoverscan(const cpl_imagelist * rawbiases,
01855 cpl_propertylist * qclist,
01856 cpl_image ** synthetic)
01857 {
01858 int i;
01859 int nx, ny;
01860 int nraws;
01861
01862 cpl_vector *meanspre;
01863 cpl_vector *medspre;
01864 cpl_vector *rmsspre;
01865 cpl_vector *meansover;
01866 cpl_vector *medsover;
01867 cpl_vector *rmssover;
01868
01869 cpl_error_code error;
01870
01871 nraws = cpl_imagelist_get_size(rawbiases);
01872 cpl_ensure_code(nraws != -1, CPL_ERROR_ILLEGAL_INPUT);
01873
01874 meanspre = cpl_vector_new(nraws);
01875 medspre = cpl_vector_new(nraws);
01876 rmsspre = cpl_vector_new(nraws);
01877 meansover = cpl_vector_new(nraws);
01878 medsover = cpl_vector_new(nraws);
01879 rmssover = cpl_vector_new(nraws);
01880
01881 nx = cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
01882 ny = cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
01883 cpl_ensure_code(nx != -1 && ny != -1, CPL_ERROR_ILLEGAL_INPUT);
01884
01885 if(nx < detmon_ronbias_config.prescan_urx ||
01886 nx < detmon_ronbias_config.overscan_urx ||
01887 ny < detmon_ronbias_config.prescan_ury ||
01888 ny < detmon_ronbias_config.overscan_ury) {
01889 cpl_msg_warning(cpl_func, "PREOVERSCAN method not applied. Given "
01890 "limits of prescan and overscan area "
01891 "exceed image size. Please check and rerun.");
01892 return CPL_ERROR_NONE;
01893 }
01894
01895 for(i = 0; i < nraws; i++) {
01896 double mean = 0;
01897 double stdev = 0;
01898
01899 cpl_image *prescan = NULL;
01900 cpl_image *overscan = NULL;
01901
01902 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
01903
01904 cpl_ensure_code(c_raw != NULL, CPL_ERROR_ILLEGAL_INPUT);
01905
01906 prescan =
01907 cpl_image_extract(c_raw,
01908 detmon_ronbias_config.prescan_llx,
01909 detmon_ronbias_config.prescan_lly,
01910 detmon_ronbias_config.prescan_urx,
01911 detmon_ronbias_config.prescan_ury);
01912 cpl_ensure_code(prescan != NULL, CPL_ERROR_ILLEGAL_INPUT);
01913 overscan =
01914 cpl_image_extract(c_raw,
01915 detmon_ronbias_config.overscan_llx,
01916 detmon_ronbias_config.overscan_lly,
01917 detmon_ronbias_config.overscan_urx,
01918 detmon_ronbias_config.overscan_ury);
01919 cpl_ensure_code(overscan != NULL, CPL_ERROR_ILLEGAL_INPUT);
01920
01921 if(i == 0) {
01922 *synthetic = irplib_detmon_build_synthetic(prescan, overscan);
01923 cpl_msg_info(cpl_func, "Creating SYNTHETIC frame");
01924 if(*synthetic == NULL) {
01925 cpl_msg_error(cpl_func, "Error creating SYNTHETIC frame");
01926 return CPL_ERROR_UNSPECIFIED;
01927 }
01928 }
01929
01930 error = irplib_ksigma_clip(c_raw,
01931 detmon_ronbias_config.
01932 prescan_llx,
01933 detmon_ronbias_config.
01934 prescan_lly,
01935 detmon_ronbias_config.
01936 prescan_urx,
01937 detmon_ronbias_config.
01938 prescan_ury,
01939 (double) detmon_ronbias_config.
01940 stacking_ks_low,
01941 detmon_ronbias_config.
01942 stacking_ks_iter, 1e-5,
01943 &mean, &stdev);
01944 cpl_ensure_code(!error, error);
01945
01946 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
01947
01948 error = cpl_vector_set(medspre, i, cpl_image_get_median(prescan));
01949 cpl_ensure_code(!error, error);
01950
01951 error = cpl_vector_set(meanspre, i, mean);
01952 cpl_ensure_code(!error, error);
01953 error = cpl_vector_set(rmsspre, i, stdev);
01954 cpl_ensure_code(!error, error);
01955 error = irplib_ksigma_clip(c_raw,
01956 detmon_ronbias_config.
01957 overscan_llx,
01958 detmon_ronbias_config.
01959 overscan_lly,
01960 detmon_ronbias_config.
01961 overscan_urx,
01962 detmon_ronbias_config.
01963 overscan_ury,
01964 (double) detmon_ronbias_config.
01965 stacking_ks_low,
01966 detmon_ronbias_config.
01967 stacking_ks_iter, 1e-5,
01968 &mean, &stdev);
01969 cpl_ensure_code(!error, error);
01970
01971 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
01972
01973 error = cpl_vector_set(medsover, i, cpl_image_get_median(overscan));
01974 cpl_ensure_code(!error, error);
01975
01976 error = cpl_vector_set(meansover, i, mean);
01977 cpl_ensure_code(!error, error);
01978 error = cpl_vector_set(rmssover, i, stdev);
01979 cpl_ensure_code(!error, error);
01980
01981 cpl_image_delete(prescan);
01982 cpl_image_delete(overscan);
01983 }
01984
01985 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
01986 cpl_vector_get_mean(meanspre));
01987
01988 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
01989 DETMON_QC_BIAS_PRESCAN_MEAN_C);
01990
01991 cpl_ensure_code(!error, error);
01992 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MED,
01993 cpl_vector_get_mean(medspre));
01994 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MED,
01995 DETMON_QC_BIAS_PRESCAN_MED_C);
01996
01997 cpl_ensure_code(!error, error);
01998 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_RON,
01999 cpl_vector_get_mean(rmsspre));
02000
02001 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_RON,
02002 DETMON_QC_BIAS_PRESCAN_RON_C);
02003 cpl_ensure_code(!error, error);
02004
02005 error =
02006 cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
02007 cpl_vector_get_mean(meansover));
02008 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
02009 DETMON_QC_BIAS_OVERSCAN_MEAN_C);
02010 cpl_ensure_code(!error, error);
02011 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
02012 cpl_vector_get_mean(medsover));
02013 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
02014 DETMON_QC_BIAS_OVERSCAN_MED_C);
02015 cpl_ensure_code(!error, error);
02016 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
02017 cpl_vector_get_mean(rmssover));
02018 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
02019 DETMON_QC_BIAS_OVERSCAN_RON_C);
02020 cpl_ensure_code(!error, error);
02021
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036
02037
02038
02039
02040
02041
02042
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058 cpl_vector_delete(meanspre);
02059 cpl_vector_delete(medspre);
02060 cpl_vector_delete(rmsspre);
02061 cpl_vector_delete(meansover);
02062 cpl_vector_delete(medsover);
02063 cpl_vector_delete(rmssover);
02064
02065 return CPL_ERROR_NONE;
02066 }
02067
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079 static cpl_error_code
02080 irplib_detmon_ronbias_region(const cpl_imagelist * rawbiases,
02081 const cpl_image * masterbias,
02082 cpl_propertylist * qclist)
02083 {
02084
02085 int nraws = cpl_imagelist_get_size(rawbiases);
02086 int i;
02087
02088 int nx =
02089 cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
02090 int ny =
02091 cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
02092
02093 cpl_vector *rmssreg;
02094 cpl_error_code error;
02095
02096 const cpl_image * c_raw;
02097 double median, mbias, mstdev;
02098
02099 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) nraws--;
02100
02101 rmssreg = cpl_vector_new(nraws);
02102
02103 if(nx < detmon_ronbias_config.ref_urx ||
02104 ny < detmon_ronbias_config.ref_ury) {
02105 cpl_msg_warning(cpl_func, "REGION method not applied. Given "
02106 "limits of prescan and overscan area "
02107 "exceed image size. Please check and rerun.");
02108 return CPL_ERROR_NONE;
02109 }
02110
02111 for(i = 0; i < nraws; i++) {
02112 double mean = 0;
02113 double stdev = 0;
02114 if(strcmp(detmon_ronbias_config.pmethod, "DIF")) {
02115 c_raw = cpl_imagelist_get_const(rawbiases, i);
02116 } else {
02117 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
02118 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
02119 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
02120 }
02121 error = irplib_ksigma_clip(c_raw,
02122 detmon_ronbias_config.ref_llx,
02123 detmon_ronbias_config.ref_lly,
02124 detmon_ronbias_config.ref_urx,
02125 detmon_ronbias_config.ref_ury,
02126 (double) detmon_ronbias_config.
02127 stacking_ks_low,
02128 detmon_ronbias_config.
02129 stacking_ks_iter, 1e-5,
02130 &mean, &stdev);
02131 cpl_ensure_code(!error, error);
02132
02133
02134
02135
02136
02137
02138 error = cpl_vector_set(rmssreg, i, stdev);
02139 cpl_ensure_code(!error, error);
02140 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) cpl_image_delete((cpl_image *)c_raw);
02141 }
02142
02143 median = cpl_image_get_median_window(masterbias,
02144 detmon_ronbias_config.ref_llx,
02145 detmon_ronbias_config.ref_lly,
02146 detmon_ronbias_config.ref_urx,
02147 detmon_ronbias_config.ref_ury);
02148 error = irplib_ksigma_clip(masterbias,
02149 detmon_ronbias_config.ref_llx,
02150 detmon_ronbias_config.ref_lly,
02151 detmon_ronbias_config.ref_urx,
02152 detmon_ronbias_config.ref_ury,
02153 (double) detmon_ronbias_config.
02154 stacking_ks_low,
02155 detmon_ronbias_config.
02156 stacking_ks_iter, 1e-5,
02157 &mbias, &mstdev);
02158
02159 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_MED,
02160 median);
02161 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_MED,
02162 DETMON_QC_BIAS_REGION_MED_C);
02163 cpl_ensure_code(!error, error);
02164
02165 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_VAL,
02166 mbias);
02167 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_VAL,
02168 DETMON_QC_BIAS_REGION_VAL_C);
02169 cpl_ensure_code(!error, error);
02170 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_RON,
02171 cpl_vector_get_mean(rmssreg));
02172 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_RON,
02173 DETMON_QC_BIAS_REGION_RON_C);
02174 cpl_ensure_code(!error, error);
02175
02176
02177
02178
02179
02180
02181 cpl_vector_delete(rmssreg);
02182
02183 return cpl_error_get_code();
02184 }
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197 static cpl_image *
02198 irplib_detmon_ronbias_master(const cpl_imagelist * rawbiases,
02199 cpl_mask ** bpmhot, cpl_mask ** bpmcold,
02200 cpl_mask ** bpmdev, cpl_propertylist * qclist)
02201 {
02202 double mean = 0;
02203 double stdev = 0;
02204 cpl_image *masterbias = NULL;
02205 double dark_med, stdev_med,lower, upper;
02206 int hotpix_nb, coldpix_nb, devpix_nb;
02207 cpl_image * stdev_im = NULL;
02208
02209 if(!strcmp(detmon_ronbias_config.stacking_method, "MEAN"))
02210 masterbias = cpl_imagelist_collapse_create(rawbiases);
02211 if(!strcmp(detmon_ronbias_config.stacking_method, "MINMAX"))
02212 masterbias =
02213 cpl_imagelist_collapse_minmax_create(rawbiases, 0, 10000);
02214 if(!strcmp(detmon_ronbias_config.stacking_method, "KSIGMA"))
02215 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(5, 1, 0)
02216 masterbias =
02217 cpl_imagelist_collapse_sigclip_create(rawbiases, 3.0, 3.0, 0.9,
02218 CPL_COLLAPSE_MEAN, NULL);
02219 #else
02220 masterbias =
02221 cpl_imagelist_collapse_sigclip_create(rawbiases, 3.0, 0.0, 1.0,
02222 1, NULL);
02223 #endif
02224 if(!strcmp(detmon_ronbias_config.stacking_method, "MEDIAN"))
02225 masterbias = cpl_imagelist_collapse_median_create(rawbiases);
02226
02227 skip_if(masterbias == NULL);
02228
02229 skip_if(irplib_ksigma_clip(masterbias, 1, 1,
02230 cpl_image_get_size_x(masterbias),
02231 cpl_image_get_size_y(masterbias),
02232 (double) detmon_ronbias_config.
02233 stacking_ks_low,
02234 detmon_ronbias_config.
02235 stacking_ks_iter, 1e-5,
02236 &mean, &stdev));
02237
02238 if(irplib_isnan(mean))
02239 cpl_msg_error(cpl_func, "We have an error in mean");
02240 if(irplib_isnan(stdev))
02241 cpl_msg_error(cpl_func, "We have an error in stdev");
02242
02243 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_MEAN,
02244 mean));
02245 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_MEAN,
02246 DETMON_QC_MASTER_MEAN_C));
02247
02248 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_RMS,
02249 stdev));
02250 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_RMS,
02251 DETMON_QC_MASTER_RMS_C));
02252
02253
02254 dark_med = cpl_image_get_median(masterbias);
02255
02256 lower = dark_med - stdev * detmon_ronbias_config.stacking_ks_low;
02257 upper = dark_med + stdev * detmon_ronbias_config.stacking_ks_high;
02258
02259
02260 cpl_mask_delete(*bpmhot);
02261 irplib_check(*bpmhot = cpl_mask_threshold_image_create(masterbias,
02262 upper, DBL_MAX),
02263 "Cannot compute the hot pixel map");
02264 hotpix_nb = cpl_mask_count(*bpmhot);
02265 skip_if (0);
02266
02267
02268 cpl_mask_delete(*bpmcold);
02269 irplib_check(*bpmcold = cpl_mask_threshold_image_create(masterbias,
02270 -FLT_MAX, lower),
02271 "Cannot compute the cold pixel map");
02272 coldpix_nb = cpl_mask_count(*bpmcold);
02273 skip_if (0);
02274
02275
02276 stdev_im = irplib_imagelist_collapse_stdev_create(rawbiases);
02277 stdev_med = cpl_image_get_median(stdev_im);
02278
02279 skip_if(irplib_ksigma_clip(stdev_im, 1, 1,
02280 cpl_image_get_size_x(stdev_im),
02281 cpl_image_get_size_y(stdev_im),
02282 (double) detmon_ronbias_config.
02283 stacking_ks_low,
02284 detmon_ronbias_config.
02285 stacking_ks_iter, 1e-5,
02286 &mean, &stdev));
02287
02288 lower = stdev_med - stdev * detmon_ronbias_config.stacking_ks_low;
02289 upper = stdev_med + stdev * detmon_ronbias_config.stacking_ks_high;
02290
02291 cpl_mask_delete(*bpmdev);
02292 irplib_check(*bpmdev = cpl_mask_threshold_image_create(stdev_im,
02293 lower, upper),
02294 "Cannot compute the cold pixel map");
02295 cpl_mask_not(*bpmdev);
02296 devpix_nb = cpl_mask_count(*bpmdev);
02297 skip_if (0);
02298
02299
02300 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBCOLDPIX,coldpix_nb));
02301 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBCOLDPIX,
02302 DETMON_QC_NBCOLDPIX_C));
02303
02304 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBHOTPIX, hotpix_nb));
02305 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBHOTPIX,
02306 DETMON_QC_NBHOTPIX_C));
02307
02308 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBDEVPIX, devpix_nb));
02309 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBDEVPIX,
02310 DETMON_QC_NBDEVPIX_C));
02311
02312 end_skip;
02313
02314 cpl_image_delete(stdev_im);
02315
02316 if (cpl_error_get_code()) {
02317 cpl_image_delete(masterbias);
02318 masterbias = NULL;
02319 }
02320
02321 return masterbias;
02322 }
02323
02324
02325
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335 static cpl_error_code
02336 irplib_detmon_ronbias_save(const cpl_parameterlist * parlist,
02337 cpl_frameset * frameset,
02338 const char *recipe_name,
02339 const char *pipeline_name,
02340 const char *pafregexp,
02341 const cpl_propertylist * pro_master,
02342 const cpl_propertylist * pro_xstr,
02343 const cpl_propertylist * pro_ystr,
02344 const cpl_propertylist * pro_synth,
02345 const cpl_propertylist * pro_bpmhot,
02346 const cpl_propertylist * pro_bpmcold,
02347 const cpl_propertylist * pro_bpmdev,
02348 const char *package,
02349 const cpl_image * masterbias,
02350 const cpl_image * synthetic,
02351 const cpl_mask * bpmhot,
02352 const cpl_mask * bpmcold,
02353 const cpl_mask * bpmdev,
02354 cpl_propertylist * qclist,
02355 const int flag_sets,
02356 const int which_set,
02357 cpl_frameset * usedframes,
02358 int whichext)
02359 {
02360
02361 cpl_frame *ref_frame;
02362 cpl_propertylist *plist = NULL;
02363 char *name_o = NULL;
02364
02365 cpl_propertylist * paflist = NULL;
02366 cpl_propertylist * mainplist = NULL;
02367 cpl_propertylist * xplist = NULL;
02368 cpl_image * image = NULL;
02369
02370 cpl_propertylist * mypro_master =
02371 cpl_propertylist_duplicate(pro_master);
02372
02373 cpl_propertylist * mypro_synth = NULL;
02374 cpl_propertylist * mypro_bpmhot =
02375 cpl_propertylist_duplicate(pro_bpmhot);
02376 cpl_propertylist * mypro_bpmcold =
02377 cpl_propertylist_duplicate(pro_bpmcold);
02378 cpl_propertylist * mypro_bpmdev =
02379 cpl_propertylist_duplicate(pro_bpmdev);
02380
02381 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
02382 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
02383 cpl_ensure_code(pafregexp != NULL, CPL_ERROR_NULL_INPUT);
02384 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
02385 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
02386 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
02387 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
02388
02389 if (pro_synth)
02390 mypro_synth = cpl_propertylist_duplicate(pro_synth);
02391
02392
02393 cpl_ensure_code(pro_xstr == NULL && pro_ystr == NULL,
02394 CPL_ERROR_UNSUPPORTED_MODE);
02395
02396
02397 if (detmon_ronbias_config.exts < 0) {
02398 const char * filename =
02399 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
02400
02401
02402 xplist = cpl_propertylist_load_regexp(filename, whichext,
02403 "ESO DET", 0);
02404 skip_if(cpl_propertylist_append(xplist, qclist));
02405 }
02406
02407 cpl_msg_info(cpl_func,"dealing with extention %d",whichext);
02408
02409
02410
02411 ref_frame = cpl_frameset_get_first(frameset);
02412 skip_if(ref_frame == NULL);
02413
02414 skip_if((mainplist =
02415 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02416 0)) == NULL);
02417
02418
02419
02420
02421
02422
02423 if(!flag_sets) {
02424 name_o = cpl_sprintf("%s_masterbias.fits", recipe_name);
02425 assert(name_o != NULL);
02426 } else {
02427 name_o =
02428 cpl_sprintf("%s_masterbias_set%02d.fits", recipe_name,
02429 which_set);
02430 assert(name_o != NULL);
02431 }
02432
02433 if (whichext == 0) {
02434 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02435 cpl_propertylist_append(mypro_master, qclist);
02436
02437 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02438 masterbias, CPL_BPP_IEEE_FLOAT, recipe_name,
02439 mypro_master, NULL, package, name_o));
02440 #else
02441 const char * procatg_master =
02442 cpl_propertylist_get_string(mypro_master, CPL_DFS_PRO_CATG);
02443
02444 cpl_propertylist_append(mypro_master, qclist);
02445
02446 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, masterbias,
02447 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_master,
02448 mypro_master, NULL, package, name_o));
02449 #endif
02450 } else
02451 skip_if(cpl_image_save(masterbias,
02452 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02453 CPL_IO_EXTEND));
02454
02455
02456 cpl_free(name_o);
02457 name_o = NULL;
02458
02459
02460
02461
02462
02463
02464 if(!flag_sets) {
02465 name_o = cpl_sprintf("%s_hotpixmap.fits", recipe_name);
02466 assert(name_o != NULL);
02467 } else {
02468 name_o =
02469 cpl_sprintf("%s_hotpixmap_set%02d.fits", recipe_name,
02470 which_set);
02471 assert(name_o != NULL);
02472 }
02473
02474 skip_if(0);
02475 image = cpl_image_new_from_mask(bpmhot);
02476 cpl_error_reset();
02477
02478 if (whichext == 0) {
02479 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02480 cpl_propertylist_append(mypro_bpmhot, qclist);
02481
02482 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02483 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02484 mypro_bpmhot, NULL, package, name_o));
02485 #else
02486 const char * procatg_bpmhot =
02487 cpl_propertylist_get_string(mypro_bpmhot, CPL_DFS_PRO_CATG);
02488
02489 cpl_propertylist_append(mypro_bpmhot, qclist);
02490
02491 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02492 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmhot,
02493 mypro_bpmhot, NULL, package, name_o));
02494 #endif
02495 } else
02496 skip_if(cpl_image_save(image,
02497 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02498 CPL_IO_EXTEND));
02499
02500
02501 cpl_free(name_o);
02502 cpl_image_delete(image);
02503 image = NULL;
02504 name_o = NULL;
02505
02506
02507
02508
02509
02510
02511 if(!flag_sets) {
02512 name_o = cpl_sprintf("%s_coldpixmap.fits", recipe_name);
02513 assert(name_o != NULL);
02514 } else {
02515 name_o =
02516 cpl_sprintf("%s_coldpixmap_set%02d.fits", recipe_name,
02517 which_set);
02518 assert(name_o != NULL);
02519 }
02520
02521 skip_if(0);
02522 image = cpl_image_new_from_mask(bpmcold);
02523 cpl_error_reset();
02524
02525 if (whichext == 0) {
02526 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02527 cpl_propertylist_append(mypro_bpmcold, qclist);
02528
02529 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02530 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02531 mypro_bpmcold, NULL, package, name_o));
02532 #else
02533 const char * procatg_bpmcold =
02534 cpl_propertylist_get_string(mypro_bpmcold, CPL_DFS_PRO_CATG);
02535
02536 cpl_propertylist_append(mypro_bpmcold, qclist);
02537
02538 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02539 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmcold,
02540 mypro_bpmcold, NULL, package, name_o));
02541 #endif
02542 } else
02543 skip_if(cpl_image_save(image,
02544 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02545 CPL_IO_EXTEND));
02546
02547
02548 cpl_free(name_o);
02549 cpl_image_delete(image);
02550 image = NULL;
02551 name_o = NULL;
02552
02553
02554
02555
02556
02557
02558 if(!flag_sets) {
02559 name_o = cpl_sprintf("%s_devpixmap.fits", recipe_name);
02560 assert(name_o != NULL);
02561 } else {
02562 name_o =
02563 cpl_sprintf("%s_devpixmap_set%02d.fits", recipe_name,
02564 which_set);
02565 assert(name_o != NULL);
02566 }
02567
02568 skip_if(0);
02569 image = cpl_image_new_from_mask(bpmdev);
02570 cpl_error_reset();
02571
02572 if (whichext == 0) {
02573 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02574 cpl_propertylist_append(mypro_bpmdev, qclist);
02575
02576 skip_if(cpl_dfs_save_image(frameset, NULL,parlist, usedframes, NULL,
02577 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02578 mypro_bpmdev, NULL, package, name_o));
02579 #else
02580 const char * procatg_bpmdev =
02581 cpl_propertylist_get_string(mypro_bpmdev, CPL_DFS_PRO_CATG);
02582
02583 cpl_propertylist_append(mypro_bpmdev, qclist);
02584
02585 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02586 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmdev,
02587 mypro_bpmdev, NULL, package, name_o));
02588 #endif
02589 } else
02590 skip_if(cpl_image_save(image,
02591 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02592 CPL_IO_EXTEND));
02593
02594
02595 cpl_free(name_o);
02596 cpl_image_delete(image);
02597 image = NULL;
02598 name_o = NULL;
02599
02600
02601
02602
02603 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
02604
02605 if(!flag_sets) {
02606 name_o = cpl_sprintf("%s_synthetic.fits", recipe_name);
02607 assert(name_o != NULL);
02608 } else {
02609 name_o =
02610 cpl_sprintf("%s_synthetic_set%02d.fits", recipe_name,
02611 which_set);
02612 assert(name_o != NULL);
02613 }
02614
02615 if (whichext == 0) {
02616 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02617
02618 cpl_propertylist_append(mypro_synth, qclist);
02619
02620 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
02621 NULL,synthetic, CPL_BPP_IEEE_DOUBLE,
02622 recipe_name, mypro_synth, NULL,
02623 package, name_o));
02624 #else
02625
02626 const char * procatg_synth =
02627 cpl_propertylist_get_string(mypro_synth, CPL_DFS_PRO_CATG);
02628
02629 cpl_propertylist_append(mypro_synth, qclist);
02630
02631 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, synthetic,
02632 CPL_BPP_IEEE_DOUBLE, recipe_name,
02633 procatg_synth,
02634 mypro_synth, NULL, package, name_o));
02635 #endif
02636 } else
02637 skip_if(cpl_image_save(synthetic, name_o, CPL_BPP_IEEE_FLOAT,
02638 xplist, CPL_IO_EXTEND));
02639
02640
02641 cpl_free(name_o);
02642 name_o = NULL;
02643 }
02644
02645
02646
02647
02648 if (qclist) {
02649 paflist = cpl_propertylist_new();
02650
02651
02652 if(detmon_ronbias_config.exts >= 0) {
02653 skip_if((plist =
02654 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02655 detmon_ronbias_config.exts)) == NULL);
02656
02657 if(!flag_sets) {
02658 name_o = cpl_sprintf("%s.paf", recipe_name);
02659 assert(name_o != NULL);
02660 } else {
02661 name_o = cpl_sprintf("%s_set%02d.paf",
02662 recipe_name, which_set);
02663 assert(name_o != NULL);
02664 }
02665 } else {
02666 skip_if((plist =
02667 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02668 whichext)) == NULL);
02669
02670
02671 if(!flag_sets) {
02672 name_o = cpl_sprintf("%s_ext%02d.paf",
02673 recipe_name, whichext);
02674 assert(name_o != NULL);
02675 } else {
02676 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf",
02677 recipe_name,
02678 which_set, whichext);
02679 assert(name_o != NULL);
02680 }
02681 }
02682
02683
02684 skip_if(cpl_propertylist_copy_property_regexp(paflist, plist,
02685 pafregexp, 0));
02686 skip_if(cpl_propertylist_copy_property_regexp(paflist, mainplist,
02687 pafregexp, 0));
02688
02689 skip_if(cpl_propertylist_append(paflist, qclist));
02690
02691
02692 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, paflist, name_o));
02693
02694 }
02695
02696 end_skip;
02697
02698 cpl_propertylist_delete(plist);
02699 cpl_propertylist_delete(paflist);
02700 cpl_propertylist_delete(mainplist);
02701 cpl_propertylist_delete(xplist);
02702 cpl_free(name_o);
02703 cpl_image_delete(image);
02704
02705 cpl_propertylist_delete(mypro_master);
02706 cpl_propertylist_delete(mypro_synth);
02707 cpl_propertylist_delete(mypro_bpmhot);
02708 cpl_propertylist_delete(mypro_bpmcold);
02709 cpl_propertylist_delete(mypro_bpmdev);
02710
02711 return cpl_error_get_code();
02712 }
02713
02714 cpl_propertylist *
02715 irplib_detmon_fill_prolist(const char * procatg,
02716 const char * protype,
02717 const char * protech,
02718 cpl_boolean proscience)
02719 {
02720 cpl_propertylist * prolist = cpl_propertylist_new();
02721
02722 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procatg);
02723 cpl_propertylist_append_bool(prolist, CPL_DFS_PRO_SCIENCE, proscience);
02724 if (protype)
02725 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TYPE, protype);
02726 if (protech)
02727 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TECH, protech);
02728
02729 return prolist;
02730 }
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
02742
02743 int
02744 irplib_detmon_ronbias_dfs_set_groups(cpl_frameset * set, const char *tag)
02745 {
02746 cpl_frame *cur_frame;
02747 const char *cur_tag;
02748 int nframes;
02749 int i;
02750
02751
02752 if(set == NULL)
02753 return -1;
02754
02755
02756 nframes = cpl_frameset_get_size(set);
02757
02758
02759 for(i = 0; i < nframes; i++) {
02760 cur_frame = cpl_frameset_get_frame(set, i);
02761 cur_tag = cpl_frame_get_tag(cur_frame);
02762
02763
02764 if(!strcmp(cur_tag, tag))
02765 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
02766
02767
02768
02769
02770
02771 }
02772 return 0;
02773 }
02774
02775
02776
02777
02778
02779
02780
02781
02782
02783
02784
02785
02786 cpl_image *
02787 irplib_detmon_build_synthetic(cpl_image * prescan, cpl_image * overscan)
02788 {
02789 int j;
02790
02791 int distance = detmon_ronbias_config.overscan_urx -
02792 detmon_ronbias_config.prescan_llx + 1;
02793
02794 double *mean_x =
02795 (double *) cpl_malloc(sizeof(double) * distance);
02796
02797 double *xvalues =
02798 (double *) cpl_malloc(sizeof(double) * distance);
02799
02800 cpl_vector *x = NULL;
02801 cpl_vector *y = NULL;
02802
02803 cpl_polynomial *poly = NULL;
02804 cpl_polynomial *poly2 = NULL;
02805
02806 cpl_matrix * samppos;
02807 cpl_vector * fitresidual;
02808
02809 double mse;
02810 int pows[2] = { 0, 0 };
02811
02812 cpl_image *synthetic = NULL;
02813
02814 double initial = 0;
02815
02816
02817 for(j = 0; j < distance; j++) {
02818 *(mean_x + j) = 0;
02819 *(xvalues + j) = j;
02820 }
02821
02822 for(j = 0; j < cpl_image_get_size_x(prescan); j++) {
02823 *(mean_x + j) =
02824 cpl_image_get_mean_window(prescan, j + 1, 1, j + 1,
02825 cpl_image_get_size_y(prescan));
02826 }
02827
02828 for(j = 0; j < cpl_image_get_size_x(overscan); j++) {
02829 *(mean_x + distance - cpl_image_get_size_x(overscan) + j) =
02830 cpl_image_get_mean_window(overscan, j + 1, 1, j + 1,
02831 cpl_image_get_size_y(overscan));
02832 }
02833
02834 x = cpl_vector_wrap(distance, xvalues);
02835 y = cpl_vector_wrap(distance, mean_x);
02836
02837 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02838 poly = cpl_polynomial_new(1);
02839 samppos =
02840 cpl_matrix_wrap(1, cpl_vector_get_size(x), cpl_vector_get_data(x));
02841 fitresidual = cpl_vector_new(cpl_vector_get_size(x));
02842
02843 cpl_polynomial_fit(poly, samppos, NULL, y, NULL,
02844 CPL_FALSE, NULL,
02845 &(detmon_ronbias_config.preoverscan_degree));
02846
02847 cpl_vector_fill_polynomial_fit_residual(fitresidual, y, NULL, poly,
02848 samppos, NULL);
02849 cpl_matrix_unwrap(samppos);
02850 mse = cpl_vector_product(fitresidual, fitresidual)
02851 / cpl_vector_get_size(fitresidual);
02852
02853 cpl_vector_delete(fitresidual);
02854 #else
02855 poly =
02856 cpl_polynomial_fit_1d_create(x, y,
02857 detmon_ronbias_config.preoverscan_degree,
02858 &mse);
02859 #endif
02860
02861 cpl_vector_unwrap(x);
02862 cpl_vector_unwrap(y);
02863
02864 initial = *mean_x;
02865
02866 cpl_free(xvalues);
02867 cpl_free(mean_x);
02868
02869 poly2 = cpl_polynomial_new(2);
02870
02871 j = 0;
02872 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
02873
02874 pows[0] = 1;
02875 j = 1;
02876 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
02877
02878 cpl_polynomial_delete(poly);
02879
02880 synthetic =
02881 cpl_image_new(distance, cpl_image_get_size_y(prescan),
02882 CPL_TYPE_DOUBLE);
02883
02884 if(cpl_image_fill_polynomial(synthetic, poly2, initial, 1, 1, 1)) {
02885 cpl_msg_error(cpl_func, "Error creating the synthetic frame");
02886 cpl_polynomial_delete(poly2);
02887 return NULL;
02888 }
02889
02890 cpl_polynomial_delete(poly2);
02891
02892 return synthetic;
02893 }
02894
02895
02896
02897
02898
02899
02900
02901
02902
02903
02904
02905
02906 static cpl_error_code
02907 irplib_detmon_ronbias_dutycycl(const cpl_frameset * frameset,
02908 cpl_propertylist * qclist)
02909 {
02910 const cpl_frame *first = 0;
02911 cpl_propertylist *plistfirst = 0;
02912 double tfirst;
02913 int nraws;
02914 const cpl_frame *last = 0;
02915 cpl_propertylist *plistlast = 0;
02916 double tlast;
02917 double dutycycl;
02918 cpl_error_code error;
02919
02920 first = cpl_frameset_get_first_const(frameset);
02921 plistfirst = cpl_propertylist_load(cpl_frame_get_filename(first), 0);
02922 tfirst = cpl_propertylist_get_double(plistfirst, "MJD-OBS");
02923 nraws = cpl_frameset_get_size(frameset);
02924 last = cpl_frameset_get_frame_const(frameset, nraws - 1);
02925 plistlast = cpl_propertylist_load(cpl_frame_get_filename(last), 0);
02926 tlast = cpl_propertylist_get_double(plistlast, "MJD-OBS");
02927 dutycycl = (tlast - tfirst) / (nraws - 1);
02928
02929 error = cpl_error_get_code();
02930 if (error != CPL_ERROR_NONE)
02931 {
02932 goto cleanup;
02933 }
02934 cpl_propertylist_append_double(qclist,DETMON_QC_DUTYCYCL, dutycycl);
02935 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DUTYCYCL,
02936 DETMON_QC_DUTYCYCL_C);
02937
02938 cleanup:
02939
02940 cpl_propertylist_delete(plistfirst);
02941 cpl_propertylist_delete(plistlast);
02942
02943 return error;
02944 }
02945
02946
02947
02948
02949
02950
02951
02952
02953
02954
02955
02956
02957
02958
02959
02960 #define HORIZONTAL TRUE
02961
02962 cpl_table *
02963 irplib_detmon_pernoise_reduce(cpl_image * image)
02964 {
02965 int nsamples, nffts;
02966 int i, j;
02967
02968 int status;
02969 float * hanning = 0;
02970 float * data = 0;
02971 float * power = 0;
02972 cpl_image * power_im = 0;
02973 cpl_image * output = 0;
02974 cpl_image * pos_spec = 0;
02975 cpl_table * table = 0;
02976 cpl_image* fourier_im = 0;
02977 double freq;
02978 cpl_error_code error = CPL_ERROR_NONE;
02979 cpl_image * sub_image = 0;
02980 int nffts_old;
02981
02982
02983 if(detmon_pernoise_config.direction == HORIZONTAL) {
02984 error = cpl_image_flip(image, 1);
02985 cpl_ensure(!error, error, NULL);
02986 }
02987
02988 nsamples = cpl_image_get_size_x(image);
02989 nffts = cpl_image_get_size_y(image);
02990
02991
02992
02993
02994
02995
02996
02997
02998
02999
03000 error = irplib_detmon_pernoise_rm_bg(image, nsamples, nffts);
03001 cpl_ensure(!error, error, NULL);
03002
03003 sub_image = cpl_image_extract(image, nsamples/8 + 1, nffts/8+1,
03004 nsamples*7/8, nffts*7/8);
03005 nffts_old = nffts;
03006 nsamples = cpl_image_get_size_x(sub_image);
03007 nffts = cpl_image_get_size_y(sub_image);
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020 hanning = cpl_malloc(sizeof(float) * nsamples);
03021
03022 for(i = 0; i < nsamples; i++) {
03023 *(hanning + i) = 0.5 - 0.5 * cos(2 * CPL_MATH_PI * (float) i / nsamples);
03024 for(j = 0; j < nffts; j++) {
03025 double value =
03026 cpl_image_get(sub_image, i + 1, j + 1, &status);
03027 error = cpl_image_set(sub_image, i + 1, j + 1, (*(hanning + i)) * value);
03028 }
03029 }
03030
03031 cpl_free(hanning);
03032 if (error != CPL_ERROR_NONE)
03033 {
03034 goto cleanup;
03035 }
03036 data = cpl_image_get_data_float(sub_image);
03037
03038 power = (float *) cpl_calloc(sizeof(float), nsamples * nffts);
03039
03040
03041 fourier_im = cpl_image_new(nsamples,nffts, CPL_TYPE_FLOAT_COMPLEX);
03042 error = cpl_fft_image(fourier_im, sub_image, CPL_FFT_FORWARD);
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053
03054
03055
03056
03057
03058
03059
03060 for(i = 1; i <= nffts; i++) {
03061 for(j = 1; j <= nsamples; j++) {
03062 int rej = 0;
03063 double complex cvalue = cpl_image_get_complex(fourier_im,j, i, &rej );
03064 double value = cabs(cvalue);
03065
03066
03067 cpl_image_set(power_im, j, i, value);
03068 }
03069
03070 }
03071 cpl_image_delete(fourier_im);
03072
03073
03074
03075
03076
03077
03078 output = cpl_image_collapse_create(power_im, 0);
03079 pos_spec = cpl_image_extract(output, 1, 1, nsamples/2, 1);
03080
03081
03082 cpl_image_delete(power_im);
03083 cpl_free(power);
03084
03085 cpl_image_delete(output);
03086
03087 table = cpl_table_new(nsamples/2);
03088 cpl_table_new_column(table, "FREQ", CPL_TYPE_DOUBLE);
03089 cpl_table_new_column(table, "POW", CPL_TYPE_DOUBLE);
03090
03091 freq = detmon_pernoise_config.speed*1000/nffts_old;
03092
03093 for(i = 0; i < nsamples/2; i++) {
03094 error = cpl_table_set(table, "FREQ", i, freq/(nsamples/2)*i);
03095 error = cpl_table_set(table, "POW", i, cpl_image_get(pos_spec, i+1, 1, &status));
03096 }
03097
03098 for(i= 0; i < 5; i++) {
03099 error = cpl_table_set(table, "POW", i, 0.0);
03100 }
03101
03102
03103 cleanup:
03104 cpl_image_delete(pos_spec);
03105
03106 cpl_image_delete(sub_image);
03107 if (error != CPL_ERROR_NONE)
03108 {
03109 cpl_table_delete(table);
03110 table = 0;
03111 }
03112 return table;
03113 }
03114 #undef HORIZONTAL
03115
03116
03117
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131 cpl_error_code
03132 irplib_detmon_rm_bpixs(cpl_image ** image,
03133 const double kappa, int nffts, int nsamples)
03134 {
03135 int i, j;
03136
03137 float *data = cpl_image_get_data_float(*image);
03138 int k = 0;
03139 for(i = 0; i < nffts; i++) {
03140 for(j = 0; j < nsamples; j++) {
03141 float neighbours = 0;
03142 int nneighs = 0;
03143 float average = 0;
03144
03145
03146
03147
03148
03149
03150 if(i > 0) {
03151 neighbours += *(data + (i - 1) * nsamples + j);
03152 nneighs++;
03153 }
03154 if(i < nffts - 1) {
03155 neighbours += *(data + (i + 1) * nsamples + j);
03156 nneighs++;
03157 }
03158 if(j > 0) {
03159 neighbours += *(data + i * nsamples + (j - 1));
03160 nneighs++;
03161 }
03162 if(j < nsamples - 1) {
03163 neighbours += *(data + i * nsamples + (j + 1));
03164 nneighs++;
03165 }
03166 average = neighbours / nneighs;
03167 if(average > 0) {
03168 if(*(data + i * nsamples + j) < average * (-1 * kappa) ||
03169 *(data + i * nsamples + j) > average * (kappa)) {
03170 k++;
03171 *(data + i * nsamples + j) = average;
03172 }
03173 }
03174 if(average < 0) {
03175 if(*(data + i * nsamples + j) > average * (-1 * kappa) ||
03176 *(data + i * nsamples + j) < average * (kappa)) {
03177 k++;
03178 *(data + i * nsamples + j) = average;
03179 }
03180 }
03181
03182 }
03183 }
03184
03185
03186 return cpl_error_get_code();
03187
03188 }
03189
03190
03191
03192 #define RECT_RON_HS 4
03193 #define RECT_RON_SAMPLES 100
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206 cpl_error_code
03207 irplib_flux_get_bias_window(const cpl_image * diff,
03208 const int *zone_def,
03209 int ron_hsize,
03210 int ron_nsamp, double *bias, double *error)
03211 {
03212 const int hsize = ron_hsize < 0 ? RECT_RON_HS : ron_hsize;
03213 const int nsamples =
03214 ron_nsamp < 0 ? RECT_RON_SAMPLES : ron_nsamp;
03215 cpl_bivector *sample_reg;
03216 cpl_vector *rms_list;
03217 int rect[4];
03218 int zone[4];
03219 double *px;
03220 double *py;
03221 double *pr;
03222 int i;
03223
03224
03225 cpl_ensure_code(diff && bias, CPL_ERROR_NULL_INPUT);
03226
03227
03228 if(zone_def != NULL) {
03229 rect[0] = zone_def[0] + hsize + 1;
03230 rect[1] = zone_def[1] - hsize - 1;
03231 rect[2] = zone_def[2] + hsize + 1;
03232 rect[3] = zone_def[3] - hsize - 1;
03233 } else {
03234 rect[0] = hsize + 1;
03235 rect[1] = cpl_image_get_size_x(diff) - hsize - 1;
03236 rect[2] = hsize + 1;
03237 rect[3] = cpl_image_get_size_y(diff) - hsize - 1;
03238 }
03239
03240 cpl_ensure_code(rect[0] < rect[1] && rect[2] < rect[3],
03241 CPL_ERROR_ILLEGAL_INPUT);
03242
03243
03244
03245 sample_reg =
03246 irplib_bivector_gen_rect_poisson(rect, nsamples + 1, nsamples + 1);
03247 cpl_ensure(sample_reg != NULL, CPL_ERROR_ILLEGAL_INPUT,
03248 CPL_ERROR_ILLEGAL_INPUT);
03249
03250 px = cpl_bivector_get_x_data(sample_reg);
03251 py = cpl_bivector_get_y_data(sample_reg);
03252
03253
03254
03255 rms_list = cpl_vector_new(nsamples);
03256 cpl_ensure(rms_list != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
03257 pr = cpl_vector_get_data(rms_list);
03258
03259 for(i = 0; i < nsamples; i++) {
03260 zone[0] = (int) px[i + 1] - hsize;
03261 zone[1] = (int) px[i + 1] + hsize;
03262 zone[2] = (int) py[i + 1] - hsize;
03263 zone[3] = (int) py[i + 1] + hsize;
03264 pr[i] = cpl_image_get_mean_window(diff,
03265 zone[0], zone[2], zone[1], zone[3]);
03266 }
03267 cpl_bivector_delete(sample_reg);
03268
03269
03270 if(error != NULL)
03271 *error = cpl_vector_get_stdev(rms_list);
03272
03273
03274
03275 *bias = cpl_vector_get_median(rms_list);
03276
03277 cpl_vector_delete(rms_list);
03278
03279 return CPL_ERROR_NONE;
03280 }
03281
03282 #undef RECT_RON_HS
03283 #undef RECT_RON_SAMPLES
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296 static cpl_bivector *
03297 irplib_bivector_gen_rect_poisson(const int *r, const int np, const int homog)
03298 {
03299 double min_dist;
03300 int i;
03301 int gnp;
03302 cpl_bivector *list;
03303 double cand_x, cand_y;
03304 int ok;
03305 int start_ndx;
03306 int xmin, xmax, ymin, ymax;
03307
03308
03309 const int homogc = 0 < homog && homog < np ? homog : np;
03310 double *px;
03311 double *py;
03312
03313
03314 cpl_ensure(r, CPL_ERROR_NULL_INPUT, NULL);
03315 cpl_ensure(np > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
03316
03317 list = cpl_bivector_new(np);
03318 cpl_ensure(list, CPL_ERROR_NULL_INPUT, NULL);
03319 px = cpl_bivector_get_x_data(list);
03320 py = cpl_bivector_get_y_data(list);
03321
03322 xmin = r[0];
03323 xmax = r[1];
03324 ymin = r[2];
03325 ymax = r[3];
03326
03327 min_dist =
03328 CPL_MATH_SQRT1_2 * ((xmax - xmin) * (ymax - ymin) / (double) (homogc + 1));
03329 gnp = 1;
03330 px[0] = 0;
03331 py[0] = 0;
03332
03333
03334 while(gnp < homogc) {
03335
03336 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03337 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03338
03339
03340 ok = 1;
03341 for(i = 0; i < gnp; i++) {
03342 if(pdist(cand_x, cand_y, px[i], py[i]) < min_dist) {
03343
03344 ok = 0;
03345 break;
03346 }
03347 }
03348 if(ok) {
03349
03350 px[gnp] = cand_x;
03351 py[gnp] = cand_y;
03352 gnp++;
03353 }
03354 }
03355
03356
03357
03358 start_ndx = 0;
03359 while(gnp < np) {
03360
03361 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03362 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03363
03364
03365 ok = 1;
03366 for(i = 0; i < homogc; i++) {
03367 if(pdist(cand_x,
03368 cand_y,
03369 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03370
03371 ok = 0;
03372 break;
03373 }
03374 }
03375 if(ok) {
03376
03377 px[gnp] = cand_x;
03378 py[gnp] = cand_y;
03379 gnp++;
03380 }
03381 }
03382
03383
03384
03385 start_ndx = 0;
03386 while(gnp < np) {
03387
03388 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03389 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03390
03391
03392 ok = 1;
03393 for(i = 0; i < homogc; i++) {
03394 if(pdist(cand_x,
03395 cand_y,
03396 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03397
03398 ok = 0;
03399 break;
03400 }
03401 }
03402 if(ok) {
03403
03404 px[gnp] = cand_x;
03405 py[gnp] = cand_y;
03406 gnp++;
03407 start_ndx++;
03408 }
03409 }
03410 return list;
03411 }
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426 cpl_error_code
03427 irplib_detmon_pernoise(cpl_frameset * frameset,
03428 const cpl_parameterlist * parlist,
03429 const char * tag,
03430 const char * recipe_name,
03431 const char * pipeline_name,
03432 const char * procatg_tbl,
03433 const char * package,
03434 int (*compare)(const cpl_frame *,
03435 const cpl_frame *))
03436 {
03437 int nsets;
03438 int *selection = NULL;
03439 int i;
03440 cpl_error_code error;
03441
03442 if(irplib_detmon_pernoise_dfs_set_groups(frameset, tag)) {
03443 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
03444 }
03445
03446
03447
03448
03449
03450
03451 error = irplib_detmon_pernoise_retrieve_parlist(pipeline_name,
03452 recipe_name, parlist);
03453 cpl_ensure_code(!error, error);
03454
03455
03456 if(compare == NULL)
03457 nsets = 1;
03458 else {
03459 cpl_msg_info(cpl_func, "Identify the different settings");
03460 selection = cpl_frameset_labelise(frameset, compare, &nsets);
03461 if(selection == NULL)
03462 cpl_msg_error(cpl_func, "Cannot labelise input frames");
03463 }
03464
03465 detmon_pernoise_config.nb_extensions = 1;
03466 if(detmon_pernoise_config.exts < 0) {
03467 const cpl_frame *cur_frame =
03468 cpl_frameset_get_first_const(frameset);
03469
03470 detmon_pernoise_config.nb_extensions =
03471 cpl_frame_get_nextensions(cur_frame);
03472 }
03473
03474
03475 for(i = 0; i < nsets; i++)
03476 {
03477 int j;
03478 cpl_table ** freq_table;
03479 cpl_propertylist ** qclist =
03480 (cpl_propertylist **)
03481 cpl_malloc(detmon_pernoise_config.nb_extensions *
03482 sizeof(cpl_propertylist *));
03483
03484 cpl_imagelist ** raws = (cpl_imagelist **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_imagelist *));
03485 cpl_image ** input = (cpl_image **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_image *));
03486
03487
03488 if(detmon_pernoise_config.mode == 1)
03489 {
03490 freq_table =
03491 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03492 4 * sizeof(cpl_table *));
03493 } else
03494 {
03495 freq_table =
03496 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03497 sizeof(cpl_table *));
03498 }
03499
03500 if(detmon_pernoise_config.exts >= 0)
03501 {
03502 *raws =
03503 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03504 detmon_pernoise_config.exts);
03505 *input = cpl_image_subtract_create(cpl_imagelist_get(*raws,0),
03506 cpl_imagelist_get(*raws,1));
03507 } else
03508 {
03509 cpl_imagelist *raws_all_exts =
03510 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03511 -1);
03512 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
03513 {
03514 int nframes = cpl_frameset_get_size(frameset);
03515 int k;
03516 for(k = 0; k < nframes; k++)
03517 {
03518 cpl_image *image =
03519 cpl_imagelist_unset(raws_all_exts,
03520 (detmon_pernoise_config.
03521 nb_extensions - 1 - j) * k);
03522 cpl_imagelist_set(raws[j], image, k);
03523 }
03524 input[j] =
03525 cpl_image_subtract_create(cpl_imagelist_get(raws[j],0),
03526 cpl_imagelist_get(raws[j],1));
03527 }
03528 }
03529
03530 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
03531 cpl_msg_info(cpl_func, "Starting reduction");
03532 qclist[j] = cpl_propertylist_new();
03533 if(detmon_pernoise_config.mode == 1)
03534 {
03535 int nx = cpl_image_get_size_x(input[j]);
03536 int ny = cpl_image_get_size_y(input[j]);
03537 int k = 0;
03538 cpl_image* quad[4];
03539
03540 quad[0] = cpl_image_extract(input[j], 1, 1, nx/2, ny/2);
03541 quad[1] = cpl_image_extract(input[j], 1, ny/2+1, nx/2, ny);
03542 quad[2] = cpl_image_extract(input[j], nx/2+1, 1, nx, ny/2);
03543 quad[3] = cpl_image_extract(input[j], nx/2+1, ny/2+1, nx, ny);
03544
03545 for (k = 0; k < 4; k++)
03546 {
03547 freq_table[j * 4 + k] = irplib_detmon_pernoise_reduce(quad[k]);
03548 }
03549 for(k = 0; k < 4; k++)
03550 {
03551 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j + k], k+1);
03552 if (error != CPL_ERROR_NONE)
03553 break;
03554 }
03555 for (k = 0; k < 4; k++)
03556 {
03557 cpl_image_delete(quad[k]);
03558 }
03559 } else
03560 {
03561 freq_table[j] = irplib_detmon_pernoise_reduce(input[j]);
03562 if(freq_table[j] != NULL)
03563 {
03564 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j], 0);
03565 }
03566 }
03567 if (error != CPL_ERROR_NONE)
03568 {
03569 break;
03570 }
03571 }
03572 if (error == CPL_ERROR_NONE)
03573 {
03574 error = irplib_detmon_pernoise_save(parlist, frameset, recipe_name,
03575 pipeline_name, procatg_tbl,
03576 package, freq_table, qclist, 0,
03577 0, frameset);
03578 }
03579
03580 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
03581 {
03582 cpl_propertylist_delete(qclist[j]);
03583 cpl_imagelist_delete(raws[j]);
03584 cpl_image_delete(input[j]);
03585 }
03586 cpl_free(qclist);
03587 cpl_free(raws);
03588 cpl_free(input);
03589 if(detmon_pernoise_config.mode == 1)
03590 {
03591 for(j= 0; j < detmon_pernoise_config.nb_extensions * 4; j++) {
03592 cpl_table_delete(freq_table[j]);
03593 }
03594 } else {
03595 for(j= 0; j < detmon_pernoise_config.nb_extensions; j++) {
03596 cpl_table_delete(freq_table[j]);
03597 }
03598 }
03599 cpl_free(freq_table);
03600 if (error != CPL_ERROR_NONE)
03601 {
03602 break;
03603 }
03604 }
03605
03606 return cpl_error_get_code();
03607 }
03608
03609
03610
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620 int
03621 irplib_detmon_pernoise_dfs_set_groups(cpl_frameset * set, const char *tag)
03622 {
03623 cpl_frame *cur_frame;
03624 const char *cur_tag;
03625 int nframes;
03626 int i;
03627
03628
03629 if(set == NULL)
03630 return -1;
03631
03632
03633 nframes = cpl_frameset_get_size(set);
03634
03635
03636 for(i = 0; i < nframes; i++) {
03637 cur_frame = cpl_frameset_get_frame(set, i);
03638 cur_tag = cpl_frame_get_tag(cur_frame);
03639
03640
03641 if(!strcmp(cur_tag, tag))
03642 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
03643
03644
03645
03646
03647
03648 }
03649 return 0;
03650 }
03651
03652
03653
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663 cpl_error_code
03664 irplib_detmon_fill_pernoise_params(cpl_parameterlist * parlist,
03665 const char *recipe_name,
03666 const char *pipeline_name,
03667 int mode,
03668 const char * direction,
03669 double speed,
03670 int llx,
03671 int lly,
03672 int urx,
03673 int ury,
03674 double kappa,
03675 int exts)
03676 {
03677 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 9,
03678
03679 "mode",
03680 "Mode",
03681 "CPL_TYPE_INT", mode,
03682
03683 "direction",
03684 "Readout direction",
03685 "CPL_TYPE_BOOL", direction,
03686
03687 "speed",
03688 "Readout speed",
03689 "CPL_TYPE_DOUBLE", speed,
03690
03691 "llx",
03692 "(yet unsupported) x coordinate of the lower-left "
03693 "point of the region of interest. If not modified, default value will be 1.",
03694 "CPL_TYPE_INT", llx,
03695 "lly",
03696 "(yet unsupported) y coordinate of the lower-left "
03697 "point of the region of interest. If not modified, default value will be 1.",
03698 "CPL_TYPE_INT", lly,
03699 "urx",
03700 "(yet unsupported) x coordinate of the upper-right "
03701 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
03702 "CPL_TYPE_INT", urx,
03703 "ury",
03704 "(yet unsupported) y coordinate of the upper-right "
03705 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
03706 "CPL_TYPE_INT", ury,
03707
03708 "kappa",
03709 "Kappa used for determining threshold of bad (hot, cold) pixels",
03710 "CPL_TYPE_DOUBLE", kappa,
03711
03712 "exts",
03713 "Activate the multi-exts option",
03714 "CPL_TYPE_INT", exts);
03715
03716 return 0;
03717 }
03718
03719
03720
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730 int
03731 irplib_detmon_fill_pernoise_params_default(cpl_parameterlist * parlist,
03732 const char *recipe_name,
03733 const char *pipeline_name)
03734 {
03735 irplib_detmon_fill_pernoise_params(parlist, recipe_name, pipeline_name,
03736 1,
03737 "CPL_TRUE",
03738 84.5,
03739 -1,
03740 -1,
03741 -1,
03742 -1,
03743 100,
03744 0);
03745
03746 return 0;
03747
03748 }
03749
03750
03751 static cpl_error_code
03752 irplib_detmon_pernoise_retrieve_parlist(const char *pipeline_name,
03753 const char *recipe_name,
03754 const cpl_parameterlist * parlist)
03755 {
03756 char *par_name;
03757 cpl_parameter *par;
03758
03759
03760 detmon_pernoise_config.mode =
03761 irplib_detmon_retrieve_par_int("mode", pipeline_name, recipe_name,
03762 parlist);
03763
03764
03765 par_name = cpl_sprintf("%s.%s.direction", pipeline_name, recipe_name);
03766 assert(par_name != NULL);
03767 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03768 detmon_pernoise_config.direction = cpl_parameter_get_bool(par);
03769 cpl_free(par_name);
03770
03771
03772 par_name = cpl_sprintf("%s.%s.speed", pipeline_name, recipe_name);
03773 assert(par_name != NULL);
03774 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03775 detmon_pernoise_config.speed = cpl_parameter_get_double(par);
03776 cpl_free(par_name);
03777
03778
03779 detmon_pernoise_config.llx =
03780 irplib_detmon_retrieve_par_int("llx", pipeline_name, recipe_name,
03781 parlist);
03782
03783
03784 detmon_pernoise_config.lly =
03785 irplib_detmon_retrieve_par_int("lly", pipeline_name, recipe_name,
03786 parlist);
03787
03788 detmon_pernoise_config.urx =
03789 irplib_detmon_retrieve_par_int("urx", pipeline_name, recipe_name,
03790 parlist);
03791
03792 detmon_pernoise_config.ury =
03793 irplib_detmon_retrieve_par_int("ury", pipeline_name, recipe_name,
03794 parlist);
03795
03796 detmon_pernoise_config.kappa =
03797 irplib_detmon_retrieve_par_double("kappa", pipeline_name, recipe_name,
03798 parlist);
03799
03800
03801 detmon_pernoise_config.exts =
03802 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
03803 parlist);
03804
03805 if(cpl_error_get_code()) {
03806 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
03807 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
03808 }
03809
03810 return cpl_error_get_code();
03811 }
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824 static cpl_error_code
03825 irplib_detmon_pernoise_save(const cpl_parameterlist * parlist,
03826 cpl_frameset * frameset,
03827 const char *recipe_name,
03828 const char *pipeline_name,
03829 const char *procatg_tbl,
03830 const char *package,
03831 cpl_table ** freq_table,
03832 cpl_propertylist ** qclist,
03833 const int flag_sets,
03834 const int which_set,
03835 const cpl_frameset * usedframes)
03836 {
03837
03838 cpl_frame *ref_frame;
03839 cpl_propertylist *plist;
03840 char *name_o = NULL;
03841 int i, j;
03842 cpl_propertylist *paflist;
03843 cpl_error_code error;
03844
03845 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03846 cpl_propertylist * pro_tbl = cpl_propertylist_new();
03847
03848 cpl_propertylist_append_string(pro_tbl,
03849 CPL_DFS_PRO_CATG, procatg_tbl);
03850
03851 cpl_propertylist_append(pro_tbl, qclist[0]);
03852
03853 #endif
03854
03855
03856
03857
03858
03859 if(detmon_pernoise_config.mode != 1) {
03860
03861 if(!flag_sets) {
03862 name_o = cpl_sprintf("%s_freq_table.fits", recipe_name);
03863 assert(name_o != NULL);
03864 } else {
03865 name_o =
03866 cpl_sprintf("%s_freq_table_set%02d.fits", recipe_name,
03867 which_set);
03868 assert(name_o != NULL);
03869 }
03870
03871 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03872
03873 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, freq_table[0],
03874 NULL, recipe_name, pro_tbl, NULL,
03875 package, name_o)) {
03876 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03877 cpl_free(name_o);
03878 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03879 }
03880 #else
03881
03882 if(cpl_dfs_save_table(frameset, parlist, usedframes, freq_table[0],
03883 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03884 package, name_o)) {
03885 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03886 cpl_free(name_o);
03887 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03888 }
03889 #endif
03890
03891 if(detmon_pernoise_config.exts < 0) {
03892
03893 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03894 error =
03895 cpl_table_save(freq_table[i], NULL, qclist[i], name_o,
03896 CPL_IO_EXTEND);
03897 cpl_ensure_code(!error, error);
03898 }
03899 }
03900
03901
03902 cpl_free(name_o);
03903
03904 } else {
03905 for (j = 1; j <= 4; j++) {
03906
03907 if(!flag_sets) {
03908 name_o = cpl_sprintf("%s_freq_table_quad%02d.fits",
03909 recipe_name, j);
03910 assert(name_o != NULL);
03911 } else {
03912 name_o =
03913 cpl_sprintf("%s_freq_table_quad%02d_set%02d.fits",
03914 recipe_name, j, which_set);
03915 assert(name_o != NULL);
03916 }
03917
03918 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03919
03920 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
03921 freq_table[j - 1],
03922 NULL, recipe_name, pro_tbl, NULL,
03923 package, name_o)) {
03924 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03925 cpl_free(name_o);
03926 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03927 }
03928 #else
03929
03930 if(cpl_dfs_save_table(frameset, parlist, usedframes,
03931 freq_table[j - 1],
03932 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03933 package, name_o)) {
03934 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03935 cpl_free(name_o);
03936 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03937 }
03938 #endif
03939
03940 if(detmon_pernoise_config.exts < 0) {
03941 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03942 error = cpl_table_save(freq_table[(j-1) + 4 * i],
03943 NULL, qclist[i], name_o,
03944 CPL_IO_EXTEND);
03945 cpl_ensure_code(!error, error);
03946 }
03947 }
03948
03949
03950 cpl_free(name_o);
03951 }
03952
03953 }
03954
03955
03956
03957
03958
03959 ref_frame = cpl_frameset_get_first(frameset);
03960 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03961 0)) == NULL) {
03962 cpl_msg_error(cpl_func, "getting header from reference frame");
03963 cpl_ensure_code(0, cpl_error_get_code());
03964 }
03965
03966
03967 paflist = cpl_propertylist_new();
03968 cpl_propertylist_copy_property_regexp(paflist, plist,
03969 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
03970 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
03971 "ESO DET NCORRS|"
03972 "ESO DET MODE NAME)$", 0);
03973
03974 for(i = 0; i < detmon_pernoise_config.nb_extensions; i++) {
03975 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
03976 error = cpl_propertylist_append(c_paflist, qclist[i]);
03977 cpl_ensure_code(!error, error);
03978
03979
03980 if(detmon_pernoise_config.exts >= 0) {
03981 if(!flag_sets) {
03982 name_o = cpl_sprintf("%s.paf", recipe_name);
03983 assert(name_o != NULL);
03984 } else {
03985 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
03986 assert(name_o != NULL);
03987 }
03988 } else {
03989 if(!flag_sets) {
03990 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
03991 assert(name_o != NULL);
03992 } else {
03993 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
03994 assert(name_o != NULL);
03995 }
03996 }
03997
03998 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
03999 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04000 cpl_free(name_o);
04001 cpl_propertylist_delete(paflist);
04002 cpl_propertylist_delete(plist);
04003 cpl_free(name_o);
04004 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04005 }
04006 cpl_propertylist_delete(c_paflist);
04007 cpl_free(name_o);
04008 }
04009
04010 cpl_propertylist_delete(plist);
04011 cpl_propertylist_delete(paflist);
04012 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04013 cpl_propertylist_delete(pro_tbl);
04014 #endif
04015 return cpl_error_get_code();
04016 }
04017
04018 static cpl_error_code
04019 irplib_detmon_pernoise_qc(cpl_propertylist * qclist,
04020 cpl_table * table,
04021 int iquad)
04022 {
04023 cpl_error_code error;
04024 char * propname;
04025
04026 double freqs[3] = {0, 0, 0};
04027 double pows[3] = {0, 0, 0};
04028
04029
04030
04031
04032
04033
04034
04035
04036 int nrows = cpl_table_get_nrow(table);
04037 int i;
04038
04039 double * all_freqs = cpl_table_get_data_double(table, "FREQ");
04040 double * all_pows = cpl_table_get_data_double(table, "POW");
04041
04042 for ( i= 1; i< nrows-1; i++){
04043 if (all_pows[i] > pows[0]) {
04044 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04045 pows[2]=pows[1];
04046 pows[1]=pows[0];
04047 pows[0]=all_pows[i];
04048
04049 freqs[2]=freqs[1];
04050 freqs[1]=freqs[0];
04051 freqs[0]=all_freqs[i];
04052 }
04053 } else if (all_pows[i] > pows[1]) {
04054 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04055 pows[2]=pows[1];
04056 pows[1]=all_pows[i];
04057
04058 freqs[2]=freqs[1];
04059 freqs[1]=all_freqs[i];
04060 }
04061
04062 } else if(all_pows[i] > pows[2]) {
04063 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04064 pows[2]=all_pows[i];
04065
04066 freqs[2]=all_freqs[i];
04067 }
04068
04069 }
04070 }
04071
04072 if (detmon_pernoise_config.mode == 1) {
04073 propname = cpl_sprintf("ESO QC FREQ1 %d", iquad);
04074 assert(propname != NULL);
04075 } else {
04076 propname = cpl_sprintf("ESO QC FREQ1");
04077 }
04078
04079 error = cpl_propertylist_append_double(qclist, propname, freqs[0]);
04080 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04081 cpl_ensure_code(!error, error);
04082
04083 cpl_free(propname);
04084
04085 if (detmon_pernoise_config.mode == 1) {
04086 propname = cpl_sprintf("ESO QC FREQ2 %d", iquad);
04087 assert(propname != NULL);
04088 } else {
04089 propname = cpl_sprintf("ESO QC FREQ2");
04090 }
04091
04092 error = cpl_propertylist_append_double(qclist, propname, freqs[1]);
04093 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04094 cpl_ensure_code(!error, error);
04095
04096 cpl_free(propname);
04097
04098 if (detmon_pernoise_config.mode == 1) {
04099 propname = cpl_sprintf("ESO QC FREQ3 %d", iquad);
04100 assert(propname != NULL);
04101 } else {
04102 propname = cpl_sprintf("ESO QC FREQ3");
04103 }
04104
04105 error = cpl_propertylist_append_double(qclist, propname, freqs[2]);
04106 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04107 cpl_ensure_code(!error, error);
04108
04109 cpl_free(propname);
04110
04111 if (detmon_pernoise_config.mode == 1) {
04112 propname = cpl_sprintf("ESO QC POW1 %d", iquad);
04113 assert(propname != NULL);
04114 } else {
04115 propname = cpl_sprintf("ESO QC POW1");
04116 }
04117
04118 error = cpl_propertylist_append_double(qclist, propname, pows[0]);
04119 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04120 cpl_ensure_code(!error, error);
04121
04122 cpl_free(propname);
04123
04124 if (detmon_pernoise_config.mode == 1) {
04125 propname = cpl_sprintf("ESO QC POW2 %d", iquad);
04126 assert(propname != NULL);
04127 } else {
04128 propname = cpl_sprintf("ESO QC POW2");
04129 }
04130
04131 error = cpl_propertylist_append_double(qclist, propname, pows[1]);
04132 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04133 cpl_ensure_code(!error, error);
04134
04135 cpl_free(propname);
04136
04137 if (detmon_pernoise_config.mode == 1) {
04138 propname = cpl_sprintf("ESO QC POW3 %d", iquad);
04139 assert(propname != NULL);
04140 } else {
04141 propname = cpl_sprintf("ESO QC POW3");
04142 }
04143
04144 error = cpl_propertylist_append_double(qclist, propname, pows[2]);
04145 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04146 cpl_ensure_code(!error, error);
04147
04148
04149 cpl_free(propname);
04150
04151 return cpl_error_get_code();
04152 }
04153
04154
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165 cpl_error_code
04166 irplib_detmon_pernoise_rm_bg(cpl_image * image, int nsamples, int nffts)
04167 {
04168 cpl_vector *values = cpl_vector_new(nsamples * nffts);
04169
04170 int rejected;
04171 int i, j;
04172 cpl_vector *xy_pos = cpl_vector_new(nsamples * nffts * 2);
04173 double mse = 0;
04174 cpl_polynomial * poly_2d = 0;
04175 cpl_image * poly_ima = 0;
04176 int degree = 3;
04177 cpl_error_code error = CPL_ERROR_NONE;
04178 cpl_matrix * samppos = 0;
04179 cpl_vector * fitresidual = 0;
04180
04181 for(i = 1; i <= nffts; i++) {
04182 for(j = 1; j <= nsamples; j++) {
04183 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1), j);
04184 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1) + nsamples * nffts, i);
04185 cpl_vector_set(values, (i - 1) * nsamples + (j - 1),
04186 cpl_image_get(image, j, i, &rejected));
04187 error = cpl_error_get_code();
04188 if (error != CPL_ERROR_NONE)
04189 {
04190 break;
04191 }
04192 }
04193 if (error != CPL_ERROR_NONE)
04194 {
04195 break;
04196 }
04197 }
04198 if (error != CPL_ERROR_NONE)
04199 {
04200 goto cleanup;
04201 }
04202 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04203 poly_2d = cpl_polynomial_new(2);
04204 samppos =
04205 cpl_matrix_wrap(2, nsamples * nffts, cpl_vector_get_data(xy_pos));
04206 fitresidual = cpl_vector_new(nsamples * nffts);
04207 cpl_polynomial_fit(poly_2d, samppos, NULL, values, NULL,
04208 CPL_FALSE, NULL, °ree);
04209
04210 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, poly_2d,
04211 samppos, NULL);
04212 cpl_matrix_unwrap(samppos);
04213 mse = cpl_vector_product(fitresidual, fitresidual)
04214 / cpl_vector_get_size(fitresidual);
04215 cpl_vector_delete(fitresidual);
04216
04217 #else
04218 poly_2d = cpl_polynomial_fit_2d_create(xy_pos, values, 3, &mse);
04219 #endif
04220
04221 poly_ima = cpl_image_new(nsamples, nffts, CPL_TYPE_FLOAT);
04222
04223 cpl_image_fill_polynomial(poly_ima, poly_2d, 1, 1, 1, 1);
04224
04225 cpl_image_subtract(image, poly_ima);
04226
04227 cleanup:
04228 cpl_polynomial_delete(poly_2d);
04229 cpl_image_delete(poly_ima);
04230 cpl_vector_delete(xy_pos);
04231 cpl_vector_delete(values);
04232
04233 return cpl_error_get_code();
04234 }
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247 cpl_error_code
04248 irplib_detmon_dark(cpl_frameset * frameset,
04249 const cpl_parameterlist * parlist,
04250 const char * tag,
04251 const char * recipe_name,
04252 const char * pipeline_name,
04253 const char * procatg_master,
04254 const char * procatg_dsnu,
04255 const char * procatg_tbl,
04256 const char * package,
04257 int (*compare)(const cpl_frame *,
04258 const cpl_frame *))
04259 {
04260 int nsets;
04261 int *selection = NULL;
04262 int i;
04263 cpl_error_code error;
04264
04265 if(irplib_detmon_dark_dfs_set_groups(frameset, tag)) {
04266 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
04267 }
04268
04269
04270
04271
04272
04273
04274 error = irplib_detmon_retrieve_dark_params(pipeline_name,
04275 recipe_name, parlist);
04276 cpl_ensure_code(!error, error);
04277
04278
04279 if(compare == NULL)
04280 nsets = 1;
04281 else {
04282 cpl_msg_info(cpl_func, "Identify the different settings");
04283 selection = cpl_frameset_labelise(frameset, compare, &nsets);
04284 if(selection == NULL)
04285 cpl_msg_error(cpl_func, "Cannot labelise input frames");
04286 }
04287
04288 detmon_dark_config.nb_extensions = 1;
04289 if(detmon_dark_config.exts < 0) {
04290 const cpl_frame *cur_frame =
04291 cpl_frameset_get_first_const(frameset);
04292
04293 detmon_dark_config.nb_extensions =
04294 cpl_frame_get_nextensions(cur_frame);
04295 }
04296
04297
04298 for(i = 0; i < nsets; i++) {
04299 int *select_dits = NULL;
04300 cpl_frameset *cur_fset =
04301 nsets == 1 ? cpl_frameset_duplicate(frameset) :
04302 cpl_frameset_extract(frameset, selection, i);
04303
04304 int ndits = 0;
04305 int j, k;
04306 cpl_table ** dsnu_table = NULL;
04307 cpl_imagelist ** dsnu = NULL;
04308
04309 cpl_propertylist ** qclist =
04310 (cpl_propertylist **)
04311 cpl_malloc(detmon_dark_config.nb_extensions *
04312 sizeof(cpl_propertylist *));
04313
04314
04315 cpl_imagelist ** masters =
04316 (cpl_imagelist **)
04317 cpl_malloc(detmon_dark_config.nb_extensions *
04318 sizeof(cpl_imagelist *));
04319
04320
04321 if(detmon_dark_config.opt_nir == OPT) {
04322 dsnu_table =
04323 (cpl_table **) cpl_malloc(detmon_dark_config.nb_extensions *
04324 sizeof(cpl_table *));
04325 dsnu =
04326 (cpl_imagelist **)
04327 cpl_malloc(detmon_dark_config.nb_extensions *
04328 sizeof(cpl_imagelist *));
04329 }
04330
04331 select_dits = cpl_frameset_labelise(cur_fset,
04332 irplib_detmon_compare_dits,
04333 &ndits);
04334
04335 if(detmon_dark_config.exts >= 0) {
04336 *masters = cpl_imagelist_new();
04337 if(detmon_dark_config.opt_nir == OPT) {
04338 *dsnu = cpl_imagelist_new();
04339 *dsnu_table = cpl_table_new(ndits);
04340 }
04341 *qclist = cpl_propertylist_new();
04342 cpl_table_new_column(*dsnu_table, "DIT", CPL_TYPE_DOUBLE);
04343 cpl_table_new_column(*dsnu_table, "STDEV", CPL_TYPE_DOUBLE);
04344 } else {
04345 for ( j = 0; j < detmon_dark_config.nb_extensions; j ++) {
04346 masters[j] = cpl_imagelist_new();
04347 if(detmon_dark_config.opt_nir == OPT) {
04348 dsnu[j] = cpl_imagelist_new();
04349 dsnu_table[j] = cpl_table_new(ndits);
04350 }
04351 qclist[j] = cpl_propertylist_new();
04352 cpl_table_new_column(dsnu_table[j], "DIT", CPL_TYPE_DOUBLE);
04353 cpl_table_new_column(dsnu_table[j], "STDEV", CPL_TYPE_DOUBLE);
04354 }
04355 }
04356
04357 for(j = 0; j < ndits; j++) {
04358 cpl_frameset * cur_fdit = cpl_frameset_extract(cur_fset,
04359 select_dits, j);
04360 cpl_imagelist ** raws =
04361 (cpl_imagelist **)
04362 cpl_malloc(detmon_dark_config.nb_extensions *
04363 sizeof(cpl_imagelist *));
04364
04365 if(detmon_dark_config.exts >= 0) {
04366 cpl_image * collapsed;
04367 *raws =
04368 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04369 detmon_dark_config.exts);
04370 collapsed = cpl_imagelist_collapse_create(*raws);
04371 cpl_imagelist_set(*masters, collapsed, j);
04372 if(detmon_dark_config.opt_nir == OPT) {
04373 irplib_detmon_dark_dsnu(cur_fdit, *dsnu, *dsnu_table,
04374 collapsed, j);
04375 }
04376 irplib_detmon_dark_qc(*qclist, collapsed);
04377 } else {
04378 cpl_imagelist *raws_all_exts =
04379 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04380 -1);
04381 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04382 int nframes = cpl_frameset_get_size(cur_fdit);
04383 int h;
04384 cpl_image * collapsed;
04385 for(h = 0; h < nframes; h++) {
04386 cpl_image *image =
04387 cpl_imagelist_unset(raws_all_exts,
04388 (detmon_dark_config.
04389 nb_extensions - 1 - k) * h);
04390 cpl_imagelist_set(raws[k], image, h);
04391 }
04392 collapsed = cpl_imagelist_collapse_create(raws[k]);
04393 cpl_imagelist_set(masters[k],collapsed, j);
04394 if(detmon_dark_config.opt_nir == OPT) {
04395 irplib_detmon_dark_dsnu(cur_fdit, dsnu[k],
04396 dsnu_table[j], collapsed, j);
04397 }
04398 irplib_detmon_dark_qc(qclist[k], collapsed);
04399 }
04400 }
04401
04402 cpl_frameset_delete(cur_fdit);
04403 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04404 cpl_imagelist_delete(raws[k]);
04405 }
04406 cpl_free(raws);
04407 }
04408
04409 cpl_frameset_delete(cur_fset);
04410
04411 irplib_detmon_dark_save(parlist, frameset, recipe_name, pipeline_name,
04412 procatg_master, procatg_tbl, procatg_dsnu,
04413 package, masters, dsnu_table, dsnu, qclist,
04414 0, 0, frameset);
04415
04416 if(detmon_dark_config.opt_nir == OPT) {
04417 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04418 cpl_table_delete(dsnu_table[j]);
04419 cpl_imagelist_delete(dsnu[j]);
04420 }
04421 cpl_free(dsnu_table);
04422 cpl_free(dsnu);
04423 }
04424
04425 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04426 cpl_propertylist_delete(qclist[j]);
04427 cpl_imagelist_delete(masters[j]);
04428 }
04429 cpl_free(qclist);
04430 cpl_free(masters);
04431 cpl_free(select_dits);
04432
04433 }
04434
04435 cpl_free(selection);
04436
04437 return cpl_error_get_code();
04438 }
04439
04440
04441
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452 int
04453 irplib_detmon_dark_dfs_set_groups(cpl_frameset * set, const char *tag)
04454 {
04455 cpl_frame *cur_frame;
04456 const char *cur_tag;
04457 int nframes;
04458 int i;
04459
04460
04461 if(set == NULL)
04462 return -1;
04463
04464
04465 nframes = cpl_frameset_get_size(set);
04466
04467
04468 for(i = 0; i < nframes; i++) {
04469 cur_frame = cpl_frameset_get_frame(set, i);
04470 cur_tag = cpl_frame_get_tag(cur_frame);
04471
04472
04473 if(!strcmp(cur_tag, tag))
04474 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
04475
04476
04477
04478
04479
04480 }
04481 return 0;
04482 }
04483
04484
04485
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495 static cpl_error_code
04496 irplib_detmon_retrieve_dark_params(const char *pipeline_name,
04497 const char *recipe_name,
04498 const cpl_parameterlist * parlist)
04499 {
04500 char *par_name;
04501 cpl_parameter *par;
04502
04503
04504 par_name = cpl_sprintf("%s.%s.ron.method", pipeline_name, recipe_name);
04505 assert(par_name != NULL);
04506 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04507 detmon_dark_config.ron_method = cpl_parameter_get_string(par);
04508 cpl_free(par_name);
04509
04510
04511 par_name = cpl_sprintf("%s.%s.dsnu.method", pipeline_name, recipe_name);
04512 assert(par_name != NULL);
04513 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04514 detmon_dark_config.dsnu_method = cpl_parameter_get_string(par);
04515 cpl_free(par_name);
04516
04517
04518 par_name = cpl_sprintf("%s.%s.opt_nir", pipeline_name, recipe_name);
04519 assert(par_name != NULL);
04520 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04521 detmon_dark_config.opt_nir = cpl_parameter_get_bool(par);
04522 cpl_free(par_name);
04523
04524
04525 detmon_dark_config.exts =
04526 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
04527 parlist);
04528
04529 if(cpl_error_get_code()) {
04530 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
04531 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
04532 }
04533
04534
04535 return CPL_ERROR_NONE;
04536 }
04537
04538
04539
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550 cpl_error_code
04551 irplib_detmon_fill_dark_params(cpl_parameterlist * parlist,
04552 const char *recipe_name,
04553 const char *pipeline_name,
04554 const char * ron_method,
04555 const char * dsnu_method,
04556 const char * opt_nir,
04557 int exts)
04558 {
04559 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 4,
04560
04561 "ron.method",
04562 "Method used to compute RON. Currently no "
04563 "change is possible, RMS computed",
04564 "CPL_TYPE_STRING", ron_method,
04565
04566 "dsnu.method",
04567 "Method used to compute DSNU map. Currently no "
04568 "change is possible. Method used STDEV",
04569 "CPL_TYPE_STRING", dsnu_method,
04570
04571 "opt_nir",
04572 "Boolean, OPT (FALSE) or NIR(TRUE)",
04573 "CPL_TYPE_BOOL", opt_nir,
04574
04575 "exts",
04576 "Activate the multi-exts option. Default 0"
04577 "(primary unit), -1 (all exts)",
04578 "CPL_TYPE_INT", exts);
04579
04580 return cpl_error_get_code();
04581 }
04582
04583
04584
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594 int
04595 irplib_detmon_fill_dark_params_default(cpl_parameterlist * parlist,
04596 const char *recipe_name,
04597 const char *pipeline_name)
04598 {
04599 irplib_detmon_fill_dark_params(parlist, recipe_name, pipeline_name,
04600 "SIMPLE",
04601 "STDEV",
04602 "CPL_FALSE",
04603 0);
04604 return cpl_error_get_code();
04605 }
04606
04607
04608
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618 cpl_error_code
04619 irplib_detmon_dark_dsnu(cpl_frameset * cur_fdit,
04620 cpl_imagelist * dsnu,
04621 cpl_table * dsnu_table,
04622 cpl_image * collapsed,
04623 int pos)
04624 {
04625 cpl_frame * first = cpl_frameset_get_first(cur_fdit);
04626 cpl_propertylist * plist =
04627 cpl_propertylist_load(cpl_frame_get_filename(first), 0);
04628 double dit = irplib_pfits_get_exptime(plist);
04629 double mean = cpl_image_get_mean(collapsed);
04630
04631 cpl_image * dsnu_map =
04632 cpl_image_subtract_scalar_create(collapsed, mean);
04633 double stdev;
04634 cpl_image_divide_scalar(dsnu_map, mean);
04635 stdev = cpl_image_get_stdev(dsnu_map);
04636
04637 cpl_imagelist_set(dsnu, dsnu_map, pos);
04638
04639 cpl_table_set(dsnu_table, "DIT", pos, dit);
04640 cpl_table_set(dsnu_table, "STDEV", pos, stdev);
04641
04642 cpl_propertylist_delete(plist);
04643
04644 return cpl_error_get_code();
04645
04646 }
04647
04648
04649
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659 static cpl_error_code
04660 irplib_detmon_dark_save(const cpl_parameterlist * parlist,
04661 cpl_frameset * frameset,
04662 const char *recipe_name,
04663 const char *pipeline_name,
04664 const char *procatg_master,
04665 const char *procatg_tbl,
04666 const char *procatg_dsnu,
04667 const char *package,
04668 cpl_imagelist ** masters,
04669 cpl_table ** dsnu_table,
04670 cpl_imagelist ** dsnu,
04671 cpl_propertylist ** qclist,
04672 const int flag_sets,
04673 const int which_set,
04674 const cpl_frameset * usedframes)
04675 {
04676
04677 cpl_frame *ref_frame;
04678 cpl_propertylist *plist;
04679 char *name_o = NULL;
04680 int i, j;
04681 cpl_propertylist *paflist;
04682 cpl_error_code error;
04683 int nb_images;
04684
04685
04686
04687
04688
04689 nb_images = cpl_imagelist_get_size(masters[0]);
04690 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
04691
04692
04693 for(i = 0; i < nb_images; i++) {
04694
04695 if(!flag_sets) {
04696 name_o =
04697 cpl_sprintf("%s_master_dit_%d.fits", recipe_name, i+1);
04698 assert(name_o != NULL);
04699 } else {
04700 name_o =
04701 cpl_sprintf("%s_master_dit_%d_set%02d.fits",
04702 recipe_name, i, which_set);
04703 assert(name_o != NULL);
04704 }
04705
04706
04707
04708 if(detmon_dark_config.exts >= 0) {
04709 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04710 cpl_propertylist * pro_master = cpl_propertylist_new();
04711
04712 cpl_propertylist_append_string(pro_master,
04713 CPL_DFS_PRO_CATG, procatg_master);
04714
04715 cpl_propertylist_append(pro_master, qclist[0]);
04716
04717 if(cpl_dfs_save_image
04718 (frameset, NULL, parlist, usedframes, NULL,
04719 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04720 recipe_name, pro_master, NULL, package,
04721 name_o)) {
04722 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04723 name_o);
04724 cpl_free(name_o);
04725 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04726
04727 }
04728
04729 cpl_propertylist_delete(pro_master);
04730 #else
04731 if(cpl_dfs_save_image
04732 (frameset, parlist, usedframes,
04733 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04734 recipe_name, procatg_master, qclist[0], NULL, package,
04735 name_o)) {
04736 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04737 name_o);
04738 cpl_free(name_o);
04739 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04740
04741 }
04742 #endif
04743 } else {
04744 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04745 cpl_propertylist * pro_master = cpl_propertylist_new();
04746
04747 cpl_propertylist_append_string(pro_master,
04748 CPL_DFS_PRO_CATG, procatg_master);
04749
04750 cpl_propertylist_append(pro_master, qclist[0]);
04751
04752 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
04753 NULL, CPL_BPP_IEEE_FLOAT, recipe_name,
04754 pro_master, NULL,
04755 package, name_o)) {
04756 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04757 name_o);
04758 cpl_free(name_o);
04759 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04760 }
04761
04762 cpl_propertylist_delete(pro_master);
04763 #else
04764 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04765 CPL_BPP_IEEE_FLOAT, recipe_name,
04766 procatg_master, qclist[0], NULL,
04767 package, name_o)) {
04768 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04769 name_o);
04770 cpl_free(name_o);
04771 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04772 }
04773 #endif
04774 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04775 error =
04776 cpl_image_save(cpl_imagelist_get(masters[j], i),
04777 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04778 CPL_IO_EXTEND);
04779 cpl_ensure_code(!error, error);
04780 }
04781 }
04782 cpl_free(name_o);
04783 }
04784
04785 if (detmon_dark_config.opt_nir == OPT) {
04786 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04787 cpl_propertylist * pro_tbl = cpl_propertylist_new();
04788
04789 cpl_propertylist_append_string(pro_tbl,
04790 CPL_DFS_PRO_CATG, procatg_tbl);
04791
04792 cpl_propertylist_append(pro_tbl, qclist[0]);
04793 #endif
04794
04795
04796
04797
04798
04799 if(!flag_sets) {
04800 name_o = cpl_sprintf("%s_dsnu_table.fits", recipe_name);
04801 assert(name_o != NULL);
04802 } else {
04803 name_o =
04804 cpl_sprintf("%s_dsnu_table_set%02d.fits", recipe_name,
04805 which_set);
04806 assert(name_o != NULL);
04807 }
04808 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04809
04810 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
04811 dsnu_table[0], NULL, recipe_name, pro_tbl, NULL,
04812 package, name_o)) {
04813 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04814 cpl_free(name_o);
04815 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04816 }
04817 #else
04818
04819 if(cpl_dfs_save_table(frameset, parlist, usedframes, dsnu_table[0],
04820 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
04821 package, name_o)) {
04822 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04823 cpl_free(name_o);
04824 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04825 }
04826 #endif
04827
04828 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04829 cpl_propertylist_delete(pro_tbl);
04830 #endif
04831
04832 if(detmon_dark_config.exts < 0) {
04833
04834 for(i = 1; i < detmon_dark_config.nb_extensions; i++) {
04835 error =
04836 cpl_table_save(dsnu_table[i], NULL, qclist[i], name_o,
04837 CPL_IO_EXTEND);
04838 cpl_ensure_code(!error, error);
04839 }
04840 }
04841
04842
04843 cpl_free(name_o);
04844
04845
04846
04847
04848
04849 for(i = 0; i < nb_images; i++) {
04850
04851 if(!flag_sets) {
04852 name_o =
04853 cpl_sprintf("%s_dsnu_map_dit_%d.fits", recipe_name, i+1);
04854 assert(name_o != NULL);
04855 } else {
04856 name_o =
04857 cpl_sprintf("%s_dsnu_map_dit_%d_set%02d.fits",
04858 recipe_name, i, which_set);
04859 assert(name_o != NULL);
04860 }
04861
04862
04863
04864 if(detmon_dark_config.exts >= 0) {
04865 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04866 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04867
04868 cpl_propertylist_append_string(pro_dsnu,
04869 CPL_DFS_PRO_CATG, procatg_dsnu);
04870
04871 cpl_propertylist_append(pro_dsnu, qclist[0]);
04872
04873 if(cpl_dfs_save_image
04874 (frameset, NULL, parlist, usedframes, NULL,
04875 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04876 recipe_name, pro_dsnu, NULL, package,
04877 name_o)) {
04878 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04879 name_o);
04880 cpl_free(name_o);
04881 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04882
04883 }
04884
04885 cpl_propertylist_delete(pro_dsnu);
04886 #else
04887 if(cpl_dfs_save_image
04888 (frameset, parlist, usedframes,
04889 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04890 recipe_name, procatg_dsnu, qclist[0], NULL, package,
04891 name_o)) {
04892 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04893 name_o);
04894 cpl_free(name_o);
04895 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04896
04897 }
04898 #endif
04899 } else {
04900 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04901 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04902
04903 cpl_propertylist_append_string(pro_dsnu,
04904 CPL_DFS_PRO_CATG, procatg_dsnu);
04905
04906 cpl_propertylist_append(pro_dsnu, qclist[0]);
04907
04908 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
04909 NULL, NULL,
04910 CPL_BPP_IEEE_FLOAT, recipe_name,
04911 pro_dsnu, NULL,
04912 package, name_o)) {
04913 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04914 name_o);
04915 cpl_free(name_o);
04916 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04917 }
04918
04919 cpl_propertylist_delete(pro_dsnu);
04920 #else
04921 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04922 CPL_BPP_IEEE_FLOAT, recipe_name,
04923 procatg_dsnu, qclist[0], NULL,
04924 package, name_o)) {
04925 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04926 name_o);
04927 cpl_free(name_o);
04928 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04929 }
04930 #endif
04931 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04932 error =
04933 cpl_image_save(cpl_imagelist_get(dsnu[j], i),
04934 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04935 CPL_IO_EXTEND);
04936 cpl_ensure_code(!error, error);
04937 }
04938 }
04939 cpl_free(name_o);
04940 }
04941
04942
04943
04944 }
04945
04946
04947
04948
04949
04950
04951 ref_frame = cpl_frameset_get_first(frameset);
04952 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04953 0)) == NULL) {
04954 cpl_msg_error(cpl_func, "getting header from reference frame");
04955 cpl_ensure_code(0, cpl_error_get_code());
04956 }
04957
04958
04959 paflist = cpl_propertylist_new();
04960 cpl_propertylist_copy_property_regexp(paflist, plist,
04961 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
04962 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
04963 "ESO DET NCORRS|"
04964 "ESO DET MODE NAME)$", 0);
04965
04966 for(i = 0; i < detmon_dark_config.nb_extensions; i++) {
04967 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
04968 error = cpl_propertylist_append(c_paflist, qclist[i]);
04969 cpl_ensure_code(!error, error);
04970
04971
04972 if(detmon_dark_config.exts >= 0) {
04973 if(!flag_sets) {
04974 name_o = cpl_sprintf("%s.paf", recipe_name);
04975 assert(name_o != NULL);
04976 } else {
04977 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
04978 assert(name_o != NULL);
04979 }
04980 } else {
04981 if(!flag_sets) {
04982 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
04983 assert(name_o != NULL);
04984 } else {
04985 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
04986 assert(name_o != NULL);
04987 }
04988 }
04989
04990 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
04991 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04992 cpl_free(name_o);
04993 cpl_propertylist_delete(paflist);
04994 cpl_propertylist_delete(plist);
04995 cpl_free(name_o);
04996 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04997 }
04998 cpl_propertylist_delete(c_paflist);
04999 cpl_free(name_o);
05000 }
05001
05002 cpl_propertylist_delete(plist);
05003 cpl_propertylist_delete(paflist);
05004
05005 return cpl_error_get_code();
05006 }
05007
05008 cpl_error_code
05009 irplib_detmon_dark_qc(cpl_propertylist * qclist,
05010 cpl_image * collapsed)
05011 {
05012 double mean = cpl_image_get_mean(collapsed);
05013 double stdev = cpl_image_get_stdev(collapsed);
05014
05015 cpl_error_code error;
05016
05017 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK, mean);
05018 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK,
05019 DETMON_QC_DARK_C);
05020 cpl_ensure_code(!error, error);
05021
05022 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK_STDEV, stdev);
05023 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK_STDEV,
05024 DETMON_QC_DARK_STDEV_C);
05025 cpl_ensure_code(!error, error);
05026
05027 return cpl_error_get_code();
05028 }
05029
05030
05031
05048
05049 cpl_image *
05050 irplib_imagelist_collapse_stdev_create(const cpl_imagelist * imlist)
05051 {
05052 cpl_image * mean;
05053 cpl_image * delta;
05054 cpl_image * sq_delta;
05055 cpl_image * stdev;
05056
05057 int i;
05058
05059
05060 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05061 cpl_ensure(cpl_imagelist_is_uniform(imlist) == 0, CPL_ERROR_ILLEGAL_INPUT,
05062 NULL);
05063
05064
05065 mean = cpl_image_duplicate(cpl_imagelist_get_const(imlist, 0));
05066 cpl_image_fill_rejected(mean, 0.0);
05067 cpl_image_accept_all(mean);
05068
05069 stdev = cpl_image_new(cpl_image_get_size_x(mean),
05070 cpl_image_get_size_y(mean),
05071 CPL_TYPE_FLOAT);
05072
05073 for (i = 1; i < cpl_imagelist_get_size(imlist); i++) {
05074 delta = cpl_image_subtract_create(cpl_imagelist_get_const(imlist, i),
05075 mean);
05076 cpl_image_fill_rejected(delta, 0.0);
05077 cpl_image_accept_all(delta);
05078
05079 sq_delta = cpl_image_multiply_create(delta, delta);
05080
05081 cpl_image_multiply_scalar(sq_delta, ((double) i / (double)(i+1)));
05082 cpl_image_add(stdev, sq_delta);
05083
05084 cpl_image_divide_scalar(delta, i + 1);
05085 cpl_image_add(mean, delta);
05086
05087 cpl_image_delete(delta);
05088 cpl_image_delete(sq_delta);
05089 }
05090
05091 cpl_image_divide_scalar(stdev, cpl_imagelist_get_size(imlist) - 1);
05092 cpl_image_power(stdev, 0.5);
05093
05094 cpl_image_delete(mean);
05095
05096 return stdev;
05097 }