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
03061 for(i = 1; i <= nffts; i++) {
03062 for(j = 1; j <= nsamples; j++) {
03063 int rej = 0;
03064 double complex cvalue = cpl_image_get_complex(fourier_im,j, i, &rej );
03065 double value = cabs(cvalue);
03066
03067
03068
03069
03070 cpl_image_set(power_im, j, i, value);
03071 }
03072
03073 }
03074 cpl_image_delete(fourier_im);
03075
03076
03077
03078
03079
03080
03081 output = cpl_image_collapse_create(power_im, 0);
03082 pos_spec = cpl_image_extract(output, 1, 1, nsamples/2, 1);
03083
03084
03085 cpl_image_delete(power_im);
03086 cpl_free(power);
03087
03088 cpl_image_delete(output);
03089
03090 table = cpl_table_new(nsamples/2);
03091 cpl_table_new_column(table, "FREQ", CPL_TYPE_DOUBLE);
03092 cpl_table_new_column(table, "POW", CPL_TYPE_DOUBLE);
03093
03094 freq = detmon_pernoise_config.speed*1000/nffts_old;
03095
03096 for(i = 0; i < nsamples/2; i++) {
03097 error = cpl_table_set(table, "FREQ", i, freq/(nsamples/2)*i);
03098 error = cpl_table_set(table, "POW", i, cpl_image_get(pos_spec, i+1, 1, &status));
03099 }
03100
03101 for(i= 0; i < 5; i++) {
03102 error = cpl_table_set(table, "POW", i, 0.0);
03103 }
03104
03105
03106 cleanup:
03107 cpl_image_delete(pos_spec);
03108
03109 cpl_image_delete(sub_image);
03110 if (error != CPL_ERROR_NONE)
03111 {
03112 cpl_table_delete(table);
03113 table = 0;
03114 }
03115 return table;
03116 }
03117 #undef HORIZONTAL
03118
03119
03120
03121
03122
03123
03124
03125
03126
03127
03128
03129
03130
03131
03132
03133
03134 cpl_error_code
03135 irplib_detmon_rm_bpixs(cpl_image ** image,
03136 const double kappa, int nffts, int nsamples)
03137 {
03138 int i, j;
03139
03140 float *data = cpl_image_get_data_float(*image);
03141 int k = 0;
03142 for(i = 0; i < nffts; i++) {
03143 for(j = 0; j < nsamples; j++) {
03144 float neighbours = 0;
03145 int nneighs = 0;
03146 float average = 0;
03147
03148
03149
03150
03151
03152
03153 if(i > 0) {
03154 neighbours += *(data + (i - 1) * nsamples + j);
03155 nneighs++;
03156 }
03157 if(i < nffts - 1) {
03158 neighbours += *(data + (i + 1) * nsamples + j);
03159 nneighs++;
03160 }
03161 if(j > 0) {
03162 neighbours += *(data + i * nsamples + (j - 1));
03163 nneighs++;
03164 }
03165 if(j < nsamples - 1) {
03166 neighbours += *(data + i * nsamples + (j + 1));
03167 nneighs++;
03168 }
03169 average = neighbours / nneighs;
03170 if(average > 0) {
03171 if(*(data + i * nsamples + j) < average * (-1 * kappa) ||
03172 *(data + i * nsamples + j) > average * (kappa)) {
03173 k++;
03174 *(data + i * nsamples + j) = average;
03175 }
03176 }
03177 if(average < 0) {
03178 if(*(data + i * nsamples + j) > average * (-1 * kappa) ||
03179 *(data + i * nsamples + j) < average * (kappa)) {
03180 k++;
03181 *(data + i * nsamples + j) = average;
03182 }
03183 }
03184
03185 }
03186 }
03187
03188
03189 return cpl_error_get_code();
03190
03191 }
03192
03193
03194
03195 #define RECT_RON_HS 4
03196 #define RECT_RON_SAMPLES 100
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206
03207
03208
03209 cpl_error_code
03210 irplib_flux_get_bias_window(const cpl_image * diff,
03211 const int *zone_def,
03212 int ron_hsize,
03213 int ron_nsamp, double *bias, double *error)
03214 {
03215 const int hsize = ron_hsize < 0 ? RECT_RON_HS : ron_hsize;
03216 const int nsamples =
03217 ron_nsamp < 0 ? RECT_RON_SAMPLES : ron_nsamp;
03218 cpl_bivector *sample_reg;
03219 cpl_vector *rms_list;
03220 int rect[4];
03221 int zone[4];
03222 double *px;
03223 double *py;
03224 double *pr;
03225 int i;
03226
03227
03228 cpl_ensure_code(diff && bias, CPL_ERROR_NULL_INPUT);
03229
03230
03231 if(zone_def != NULL) {
03232 rect[0] = zone_def[0] + hsize + 1;
03233 rect[1] = zone_def[1] - hsize - 1;
03234 rect[2] = zone_def[2] + hsize + 1;
03235 rect[3] = zone_def[3] - hsize - 1;
03236 } else {
03237 rect[0] = hsize + 1;
03238 rect[1] = cpl_image_get_size_x(diff) - hsize - 1;
03239 rect[2] = hsize + 1;
03240 rect[3] = cpl_image_get_size_y(diff) - hsize - 1;
03241 }
03242
03243 cpl_ensure_code(rect[0] < rect[1] && rect[2] < rect[3],
03244 CPL_ERROR_ILLEGAL_INPUT);
03245
03246
03247
03248 sample_reg =
03249 irplib_bivector_gen_rect_poisson(rect, nsamples + 1, nsamples + 1);
03250 cpl_ensure(sample_reg != NULL, CPL_ERROR_ILLEGAL_INPUT,
03251 CPL_ERROR_ILLEGAL_INPUT);
03252
03253 px = cpl_bivector_get_x_data(sample_reg);
03254 py = cpl_bivector_get_y_data(sample_reg);
03255
03256
03257
03258 rms_list = cpl_vector_new(nsamples);
03259 cpl_ensure(rms_list != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
03260 pr = cpl_vector_get_data(rms_list);
03261
03262 for(i = 0; i < nsamples; i++) {
03263 zone[0] = (int) px[i + 1] - hsize;
03264 zone[1] = (int) px[i + 1] + hsize;
03265 zone[2] = (int) py[i + 1] - hsize;
03266 zone[3] = (int) py[i + 1] + hsize;
03267 pr[i] = cpl_image_get_mean_window(diff,
03268 zone[0], zone[2], zone[1], zone[3]);
03269 }
03270 cpl_bivector_delete(sample_reg);
03271
03272
03273 if(error != NULL)
03274 *error = cpl_vector_get_stdev(rms_list);
03275
03276
03277
03278 *bias = cpl_vector_get_median(rms_list);
03279
03280 cpl_vector_delete(rms_list);
03281
03282 return CPL_ERROR_NONE;
03283 }
03284
03285 #undef RECT_RON_HS
03286 #undef RECT_RON_SAMPLES
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299 static cpl_bivector *
03300 irplib_bivector_gen_rect_poisson(const int *r, const int np, const int homog)
03301 {
03302 double min_dist;
03303 int i;
03304 int gnp;
03305 cpl_bivector *list;
03306 double cand_x, cand_y;
03307 int ok;
03308 int start_ndx;
03309 int xmin, xmax, ymin, ymax;
03310
03311
03312 const int homogc = 0 < homog && homog < np ? homog : np;
03313 double *px;
03314 double *py;
03315
03316
03317 cpl_ensure(r, CPL_ERROR_NULL_INPUT, NULL);
03318 cpl_ensure(np > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
03319
03320 list = cpl_bivector_new(np);
03321 cpl_ensure(list, CPL_ERROR_NULL_INPUT, NULL);
03322 px = cpl_bivector_get_x_data(list);
03323 py = cpl_bivector_get_y_data(list);
03324
03325 xmin = r[0];
03326 xmax = r[1];
03327 ymin = r[2];
03328 ymax = r[3];
03329
03330 min_dist =
03331 CPL_MATH_SQRT1_2 * ((xmax - xmin) * (ymax - ymin) / (double) (homogc + 1));
03332 gnp = 1;
03333 px[0] = 0;
03334 py[0] = 0;
03335
03336
03337 while(gnp < homogc) {
03338
03339 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03340 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03341
03342
03343 ok = 1;
03344 for(i = 0; i < gnp; i++) {
03345 if(pdist(cand_x, cand_y, px[i], py[i]) < min_dist) {
03346
03347 ok = 0;
03348 break;
03349 }
03350 }
03351 if(ok) {
03352
03353 px[gnp] = cand_x;
03354 py[gnp] = cand_y;
03355 gnp++;
03356 }
03357 }
03358
03359
03360
03361 start_ndx = 0;
03362 while(gnp < np) {
03363
03364 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03365 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03366
03367
03368 ok = 1;
03369 for(i = 0; i < homogc; i++) {
03370 if(pdist(cand_x,
03371 cand_y,
03372 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03373
03374 ok = 0;
03375 break;
03376 }
03377 }
03378 if(ok) {
03379
03380 px[gnp] = cand_x;
03381 py[gnp] = cand_y;
03382 gnp++;
03383 }
03384 }
03385
03386
03387
03388 start_ndx = 0;
03389 while(gnp < np) {
03390
03391 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03392 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03393
03394
03395 ok = 1;
03396 for(i = 0; i < homogc; i++) {
03397 if(pdist(cand_x,
03398 cand_y,
03399 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03400
03401 ok = 0;
03402 break;
03403 }
03404 }
03405 if(ok) {
03406
03407 px[gnp] = cand_x;
03408 py[gnp] = cand_y;
03409 gnp++;
03410 start_ndx++;
03411 }
03412 }
03413 return list;
03414 }
03415
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429 cpl_error_code
03430 irplib_detmon_pernoise(cpl_frameset * frameset,
03431 const cpl_parameterlist * parlist,
03432 const char * tag,
03433 const char * recipe_name,
03434 const char * pipeline_name,
03435 const char * procatg_tbl,
03436 const char * package,
03437 int (*compare)(const cpl_frame *,
03438 const cpl_frame *))
03439 {
03440 int nsets;
03441 int *selection = NULL;
03442 int i;
03443 cpl_error_code error;
03444
03445 if(irplib_detmon_pernoise_dfs_set_groups(frameset, tag)) {
03446 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
03447 }
03448
03449
03450
03451
03452
03453
03454 error = irplib_detmon_pernoise_retrieve_parlist(pipeline_name,
03455 recipe_name, parlist);
03456 cpl_ensure_code(!error, error);
03457
03458
03459 if(compare == NULL)
03460 nsets = 1;
03461 else {
03462 cpl_msg_info(cpl_func, "Identify the different settings");
03463 selection = cpl_frameset_labelise(frameset, compare, &nsets);
03464 if(selection == NULL)
03465 cpl_msg_error(cpl_func, "Cannot labelise input frames");
03466 }
03467
03468 detmon_pernoise_config.nb_extensions = 1;
03469 if(detmon_pernoise_config.exts < 0) {
03470 const cpl_frame *cur_frame =
03471 cpl_frameset_get_first_const(frameset);
03472
03473 detmon_pernoise_config.nb_extensions =
03474 cpl_frame_get_nextensions(cur_frame);
03475 }
03476
03477
03478 for(i = 0; i < nsets; i++)
03479 {
03480 int j;
03481 cpl_table ** freq_table;
03482 cpl_propertylist ** qclist =
03483 (cpl_propertylist **)
03484 cpl_malloc(detmon_pernoise_config.nb_extensions *
03485 sizeof(cpl_propertylist *));
03486
03487 cpl_imagelist ** raws = (cpl_imagelist **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_imagelist *));
03488 cpl_image ** input = (cpl_image **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_image *));
03489
03490
03491 if(detmon_pernoise_config.mode == 1)
03492 {
03493 freq_table =
03494 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03495 4 * sizeof(cpl_table *));
03496 } else
03497 {
03498 freq_table =
03499 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03500 sizeof(cpl_table *));
03501 }
03502
03503 if(detmon_pernoise_config.exts >= 0)
03504 {
03505 *raws =
03506 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03507 detmon_pernoise_config.exts);
03508 *input = cpl_image_subtract_create(cpl_imagelist_get(*raws,0),
03509 cpl_imagelist_get(*raws,1));
03510 } else
03511 {
03512 cpl_imagelist *raws_all_exts =
03513 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03514 -1);
03515 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
03516 {
03517 int nframes = cpl_frameset_get_size(frameset);
03518 int k;
03519 for(k = 0; k < nframes; k++)
03520 {
03521 cpl_image *image =
03522 cpl_imagelist_unset(raws_all_exts,
03523 (detmon_pernoise_config.
03524 nb_extensions - 1 - j) * k);
03525 cpl_imagelist_set(raws[j], image, k);
03526 }
03527 input[j] =
03528 cpl_image_subtract_create(cpl_imagelist_get(raws[j],0),
03529 cpl_imagelist_get(raws[j],1));
03530 }
03531 }
03532
03533 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
03534 cpl_msg_info(cpl_func, "Starting reduction");
03535 qclist[j] = cpl_propertylist_new();
03536 if(detmon_pernoise_config.mode == 1)
03537 {
03538 int nx = cpl_image_get_size_x(input[j]);
03539 int ny = cpl_image_get_size_y(input[j]);
03540 int k = 0;
03541 cpl_image* quad[4];
03542
03543 quad[0] = cpl_image_extract(input[j], 1, 1, nx/2, ny/2);
03544 quad[1] = cpl_image_extract(input[j], 1, ny/2+1, nx/2, ny);
03545 quad[2] = cpl_image_extract(input[j], nx/2+1, 1, nx, ny/2);
03546 quad[3] = cpl_image_extract(input[j], nx/2+1, ny/2+1, nx, ny);
03547
03548 for (k = 0; k < 4; k++)
03549 {
03550 freq_table[j * 4 + k] = irplib_detmon_pernoise_reduce(quad[k]);
03551 }
03552 for(k = 0; k < 4; k++)
03553 {
03554 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j + k], k+1);
03555 if (error != CPL_ERROR_NONE)
03556 break;
03557 }
03558 for (k = 0; k < 4; k++)
03559 {
03560 cpl_image_delete(quad[k]);
03561 }
03562 } else
03563 {
03564 freq_table[j] = irplib_detmon_pernoise_reduce(input[j]);
03565 if(freq_table[j] != NULL)
03566 {
03567 error = irplib_detmon_pernoise_qc(qclist[j], freq_table[j], 0);
03568 }
03569 }
03570 if (error != CPL_ERROR_NONE)
03571 {
03572 break;
03573 }
03574 }
03575 if (error == CPL_ERROR_NONE)
03576 {
03577 error = irplib_detmon_pernoise_save(parlist, frameset, recipe_name,
03578 pipeline_name, procatg_tbl,
03579 package, freq_table, qclist, 0,
03580 0, frameset);
03581 }
03582
03583 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
03584 {
03585 cpl_propertylist_delete(qclist[j]);
03586 cpl_imagelist_delete(raws[j]);
03587 cpl_image_delete(input[j]);
03588 }
03589 cpl_free(qclist);
03590 cpl_free(raws);
03591 cpl_free(input);
03592 if(detmon_pernoise_config.mode == 1)
03593 {
03594 for(j= 0; j < detmon_pernoise_config.nb_extensions * 4; j++) {
03595 cpl_table_delete(freq_table[j]);
03596 }
03597 } else {
03598 for(j= 0; j < detmon_pernoise_config.nb_extensions; j++) {
03599 cpl_table_delete(freq_table[j]);
03600 }
03601 }
03602 cpl_free(freq_table);
03603 if (error != CPL_ERROR_NONE)
03604 {
03605 break;
03606 }
03607 }
03608
03609 return cpl_error_get_code();
03610 }
03611
03612
03613
03614
03615
03616
03617
03618
03619
03620
03621
03622
03623 int
03624 irplib_detmon_pernoise_dfs_set_groups(cpl_frameset * set, const char *tag)
03625 {
03626 cpl_frame *cur_frame;
03627 const char *cur_tag;
03628 int nframes;
03629 int i;
03630
03631
03632 if(set == NULL)
03633 return -1;
03634
03635
03636 nframes = cpl_frameset_get_size(set);
03637
03638
03639 for(i = 0; i < nframes; i++) {
03640 cur_frame = cpl_frameset_get_frame(set, i);
03641 cur_tag = cpl_frame_get_tag(cur_frame);
03642
03643
03644 if(!strcmp(cur_tag, tag))
03645 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
03646
03647
03648
03649
03650
03651 }
03652 return 0;
03653 }
03654
03655
03656
03657
03658
03659
03660
03661
03662
03663
03664
03665
03666 cpl_error_code
03667 irplib_detmon_fill_pernoise_params(cpl_parameterlist * parlist,
03668 const char *recipe_name,
03669 const char *pipeline_name,
03670 int mode,
03671 const char * direction,
03672 double speed,
03673 int llx,
03674 int lly,
03675 int urx,
03676 int ury,
03677 double kappa,
03678 int exts)
03679 {
03680 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 9,
03681
03682 "mode",
03683 "Mode",
03684 "CPL_TYPE_INT", mode,
03685
03686 "direction",
03687 "Readout direction",
03688 "CPL_TYPE_BOOL", direction,
03689
03690 "speed",
03691 "Readout speed",
03692 "CPL_TYPE_DOUBLE", speed,
03693
03694 "llx",
03695 "(yet unsupported) x coordinate of the lower-left "
03696 "point of the region of interest. If not modified, default value will be 1.",
03697 "CPL_TYPE_INT", llx,
03698 "lly",
03699 "(yet unsupported) y coordinate of the lower-left "
03700 "point of the region of interest. If not modified, default value will be 1.",
03701 "CPL_TYPE_INT", lly,
03702 "urx",
03703 "(yet unsupported) x coordinate of the upper-right "
03704 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
03705 "CPL_TYPE_INT", urx,
03706 "ury",
03707 "(yet unsupported) y coordinate of the upper-right "
03708 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
03709 "CPL_TYPE_INT", ury,
03710
03711 "kappa",
03712 "Kappa used for determining threshold of bad (hot, cold) pixels",
03713 "CPL_TYPE_DOUBLE", kappa,
03714
03715 "exts",
03716 "Activate the multi-exts option",
03717 "CPL_TYPE_INT", exts);
03718
03719 return 0;
03720 }
03721
03722
03723
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733 int
03734 irplib_detmon_fill_pernoise_params_default(cpl_parameterlist * parlist,
03735 const char *recipe_name,
03736 const char *pipeline_name)
03737 {
03738 irplib_detmon_fill_pernoise_params(parlist, recipe_name, pipeline_name,
03739 1,
03740 "CPL_TRUE",
03741 84.5,
03742 -1,
03743 -1,
03744 -1,
03745 -1,
03746 100,
03747 0);
03748
03749 return 0;
03750
03751 }
03752
03753
03754 static cpl_error_code
03755 irplib_detmon_pernoise_retrieve_parlist(const char *pipeline_name,
03756 const char *recipe_name,
03757 const cpl_parameterlist * parlist)
03758 {
03759 char *par_name;
03760 cpl_parameter *par;
03761
03762
03763 detmon_pernoise_config.mode =
03764 irplib_detmon_retrieve_par_int("mode", pipeline_name, recipe_name,
03765 parlist);
03766
03767
03768 par_name = cpl_sprintf("%s.%s.direction", pipeline_name, recipe_name);
03769 assert(par_name != NULL);
03770 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03771 detmon_pernoise_config.direction = cpl_parameter_get_bool(par);
03772 cpl_free(par_name);
03773
03774
03775 par_name = cpl_sprintf("%s.%s.speed", pipeline_name, recipe_name);
03776 assert(par_name != NULL);
03777 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03778 detmon_pernoise_config.speed = cpl_parameter_get_double(par);
03779 cpl_free(par_name);
03780
03781
03782 detmon_pernoise_config.llx =
03783 irplib_detmon_retrieve_par_int("llx", pipeline_name, recipe_name,
03784 parlist);
03785
03786
03787 detmon_pernoise_config.lly =
03788 irplib_detmon_retrieve_par_int("lly", pipeline_name, recipe_name,
03789 parlist);
03790
03791 detmon_pernoise_config.urx =
03792 irplib_detmon_retrieve_par_int("urx", pipeline_name, recipe_name,
03793 parlist);
03794
03795 detmon_pernoise_config.ury =
03796 irplib_detmon_retrieve_par_int("ury", pipeline_name, recipe_name,
03797 parlist);
03798
03799 detmon_pernoise_config.kappa =
03800 irplib_detmon_retrieve_par_double("kappa", pipeline_name, recipe_name,
03801 parlist);
03802
03803
03804 detmon_pernoise_config.exts =
03805 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
03806 parlist);
03807
03808 if(cpl_error_get_code()) {
03809 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
03810 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
03811 }
03812
03813 return cpl_error_get_code();
03814 }
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824
03825
03826
03827 static cpl_error_code
03828 irplib_detmon_pernoise_save(const cpl_parameterlist * parlist,
03829 cpl_frameset * frameset,
03830 const char *recipe_name,
03831 const char *pipeline_name,
03832 const char *procatg_tbl,
03833 const char *package,
03834 cpl_table ** freq_table,
03835 cpl_propertylist ** qclist,
03836 const int flag_sets,
03837 const int which_set,
03838 const cpl_frameset * usedframes)
03839 {
03840
03841 cpl_frame *ref_frame;
03842 cpl_propertylist *plist;
03843 char *name_o = NULL;
03844 int i, j;
03845 cpl_propertylist *paflist;
03846 cpl_error_code error;
03847
03848 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03849 cpl_propertylist * pro_tbl = cpl_propertylist_new();
03850
03851 cpl_propertylist_append_string(pro_tbl,
03852 CPL_DFS_PRO_CATG, procatg_tbl);
03853
03854 cpl_propertylist_append(pro_tbl, qclist[0]);
03855
03856 #endif
03857
03858
03859
03860
03861
03862 if(detmon_pernoise_config.mode != 1) {
03863
03864 if(!flag_sets) {
03865 name_o = cpl_sprintf("%s_freq_table.fits", recipe_name);
03866 assert(name_o != NULL);
03867 } else {
03868 name_o =
03869 cpl_sprintf("%s_freq_table_set%02d.fits", recipe_name,
03870 which_set);
03871 assert(name_o != NULL);
03872 }
03873
03874 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03875
03876 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, freq_table[0],
03877 NULL, recipe_name, pro_tbl, NULL,
03878 package, name_o)) {
03879 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03880 cpl_free(name_o);
03881 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03882 }
03883 #else
03884
03885 if(cpl_dfs_save_table(frameset, parlist, usedframes, freq_table[0],
03886 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03887 package, name_o)) {
03888 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03889 cpl_free(name_o);
03890 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03891 }
03892 #endif
03893
03894 if(detmon_pernoise_config.exts < 0) {
03895
03896 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03897 error =
03898 cpl_table_save(freq_table[i], NULL, qclist[i], name_o,
03899 CPL_IO_EXTEND);
03900 cpl_ensure_code(!error, error);
03901 }
03902 }
03903
03904
03905 cpl_free(name_o);
03906
03907 } else {
03908 for (j = 1; j <= 4; j++) {
03909
03910 if(!flag_sets) {
03911 name_o = cpl_sprintf("%s_freq_table_quad%02d.fits",
03912 recipe_name, j);
03913 assert(name_o != NULL);
03914 } else {
03915 name_o =
03916 cpl_sprintf("%s_freq_table_quad%02d_set%02d.fits",
03917 recipe_name, j, which_set);
03918 assert(name_o != NULL);
03919 }
03920
03921 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03922
03923 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
03924 freq_table[j - 1],
03925 NULL, recipe_name, pro_tbl, NULL,
03926 package, name_o)) {
03927 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03928 cpl_free(name_o);
03929 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03930 }
03931 #else
03932
03933 if(cpl_dfs_save_table(frameset, parlist, usedframes,
03934 freq_table[j - 1],
03935 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03936 package, name_o)) {
03937 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03938 cpl_free(name_o);
03939 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03940 }
03941 #endif
03942
03943 if(detmon_pernoise_config.exts < 0) {
03944 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03945 error = cpl_table_save(freq_table[(j-1) + 4 * i],
03946 NULL, qclist[i], name_o,
03947 CPL_IO_EXTEND);
03948 cpl_ensure_code(!error, error);
03949 }
03950 }
03951
03952
03953 cpl_free(name_o);
03954 }
03955
03956 }
03957
03958
03959
03960
03961
03962 ref_frame = cpl_frameset_get_first(frameset);
03963 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03964 0)) == NULL) {
03965 cpl_msg_error(cpl_func, "getting header from reference frame");
03966 cpl_ensure_code(0, cpl_error_get_code());
03967 }
03968
03969
03970 paflist = cpl_propertylist_new();
03971 cpl_propertylist_copy_property_regexp(paflist, plist,
03972 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
03973 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
03974 "ESO DET NCORRS|"
03975 "ESO DET MODE NAME)$", 0);
03976
03977 for(i = 0; i < detmon_pernoise_config.nb_extensions; i++) {
03978 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
03979 error = cpl_propertylist_append(c_paflist, qclist[i]);
03980 cpl_ensure_code(!error, error);
03981
03982
03983 if(detmon_pernoise_config.exts >= 0) {
03984 if(!flag_sets) {
03985 name_o = cpl_sprintf("%s.paf", recipe_name);
03986 assert(name_o != NULL);
03987 } else {
03988 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
03989 assert(name_o != NULL);
03990 }
03991 } else {
03992 if(!flag_sets) {
03993 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
03994 assert(name_o != NULL);
03995 } else {
03996 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
03997 assert(name_o != NULL);
03998 }
03999 }
04000
04001 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
04002 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04003 cpl_free(name_o);
04004 cpl_propertylist_delete(paflist);
04005 cpl_propertylist_delete(plist);
04006 cpl_free(name_o);
04007 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04008 }
04009 cpl_propertylist_delete(c_paflist);
04010 cpl_free(name_o);
04011 }
04012
04013 cpl_propertylist_delete(plist);
04014 cpl_propertylist_delete(paflist);
04015 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04016 cpl_propertylist_delete(pro_tbl);
04017 #endif
04018 return cpl_error_get_code();
04019 }
04020
04021 static cpl_error_code
04022 irplib_detmon_pernoise_qc(cpl_propertylist * qclist,
04023 cpl_table * table,
04024 int iquad)
04025 {
04026 cpl_error_code error;
04027 char * propname;
04028
04029 double freqs[3] = {0, 0, 0};
04030 double pows[3] = {0, 0, 0};
04031
04032
04033
04034
04035
04036
04037
04038
04039 int nrows = cpl_table_get_nrow(table);
04040 int i;
04041
04042 double * all_freqs = cpl_table_get_data_double(table, "FREQ");
04043 double * all_pows = cpl_table_get_data_double(table, "POW");
04044
04045 for ( i= 1; i< nrows-1; i++){
04046 if (all_pows[i] > pows[0]) {
04047 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04048 pows[2]=pows[1];
04049 pows[1]=pows[0];
04050 pows[0]=all_pows[i];
04051
04052 freqs[2]=freqs[1];
04053 freqs[1]=freqs[0];
04054 freqs[0]=all_freqs[i];
04055 }
04056 } else if (all_pows[i] > pows[1]) {
04057 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04058 pows[2]=pows[1];
04059 pows[1]=all_pows[i];
04060
04061 freqs[2]=freqs[1];
04062 freqs[1]=all_freqs[i];
04063 }
04064
04065 } else if(all_pows[i] > pows[2]) {
04066 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
04067 pows[2]=all_pows[i];
04068
04069 freqs[2]=all_freqs[i];
04070 }
04071
04072 }
04073 }
04074
04075 if (detmon_pernoise_config.mode == 1) {
04076 propname = cpl_sprintf("ESO QC FREQ1 %d", iquad);
04077 assert(propname != NULL);
04078 } else {
04079 propname = cpl_sprintf("ESO QC FREQ1");
04080 }
04081
04082 error = cpl_propertylist_append_double(qclist, propname, freqs[0]);
04083 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04084 cpl_ensure_code(!error, error);
04085
04086 cpl_free(propname);
04087
04088 if (detmon_pernoise_config.mode == 1) {
04089 propname = cpl_sprintf("ESO QC FREQ2 %d", iquad);
04090 assert(propname != NULL);
04091 } else {
04092 propname = cpl_sprintf("ESO QC FREQ2");
04093 }
04094
04095 error = cpl_propertylist_append_double(qclist, propname, freqs[1]);
04096 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04097 cpl_ensure_code(!error, error);
04098
04099 cpl_free(propname);
04100
04101 if (detmon_pernoise_config.mode == 1) {
04102 propname = cpl_sprintf("ESO QC FREQ3 %d", iquad);
04103 assert(propname != NULL);
04104 } else {
04105 propname = cpl_sprintf("ESO QC FREQ3");
04106 }
04107
04108 error = cpl_propertylist_append_double(qclist, propname, freqs[2]);
04109 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
04110 cpl_ensure_code(!error, error);
04111
04112 cpl_free(propname);
04113
04114 if (detmon_pernoise_config.mode == 1) {
04115 propname = cpl_sprintf("ESO QC POW1 %d", iquad);
04116 assert(propname != NULL);
04117 } else {
04118 propname = cpl_sprintf("ESO QC POW1");
04119 }
04120
04121 error = cpl_propertylist_append_double(qclist, propname, pows[0]);
04122 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04123 cpl_ensure_code(!error, error);
04124
04125 cpl_free(propname);
04126
04127 if (detmon_pernoise_config.mode == 1) {
04128 propname = cpl_sprintf("ESO QC POW2 %d", iquad);
04129 assert(propname != NULL);
04130 } else {
04131 propname = cpl_sprintf("ESO QC POW2");
04132 }
04133
04134 error = cpl_propertylist_append_double(qclist, propname, pows[1]);
04135 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04136 cpl_ensure_code(!error, error);
04137
04138 cpl_free(propname);
04139
04140 if (detmon_pernoise_config.mode == 1) {
04141 propname = cpl_sprintf("ESO QC POW3 %d", iquad);
04142 assert(propname != NULL);
04143 } else {
04144 propname = cpl_sprintf("ESO QC POW3");
04145 }
04146
04147 error = cpl_propertylist_append_double(qclist, propname, pows[2]);
04148 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
04149 cpl_ensure_code(!error, error);
04150
04151
04152 cpl_free(propname);
04153
04154 return cpl_error_get_code();
04155 }
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167
04168 cpl_error_code
04169 irplib_detmon_pernoise_rm_bg(cpl_image * image, int nsamples, int nffts)
04170 {
04171 cpl_vector *values = cpl_vector_new(nsamples * nffts);
04172
04173 int rejected;
04174 int i, j;
04175 cpl_vector *xy_pos = cpl_vector_new(nsamples * nffts * 2);
04176 double mse = 0;
04177 cpl_polynomial * poly_2d = 0;
04178 cpl_image * poly_ima = 0;
04179 int degree = 3;
04180 cpl_error_code error = CPL_ERROR_NONE;
04181 cpl_matrix * samppos = 0;
04182 cpl_vector * fitresidual = 0;
04183
04184 for(i = 1; i <= nffts; i++) {
04185 for(j = 1; j <= nsamples; j++) {
04186 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1), j);
04187 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1) + nsamples * nffts, i);
04188 cpl_vector_set(values, (i - 1) * nsamples + (j - 1),
04189 cpl_image_get(image, j, i, &rejected));
04190 error = cpl_error_get_code();
04191 if (error != CPL_ERROR_NONE)
04192 {
04193 break;
04194 }
04195 }
04196 if (error != CPL_ERROR_NONE)
04197 {
04198 break;
04199 }
04200 }
04201 if (error != CPL_ERROR_NONE)
04202 {
04203 goto cleanup;
04204 }
04205 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04206 poly_2d = cpl_polynomial_new(2);
04207 samppos =
04208 cpl_matrix_wrap(2, nsamples * nffts, cpl_vector_get_data(xy_pos));
04209 fitresidual = cpl_vector_new(nsamples * nffts);
04210 cpl_polynomial_fit(poly_2d, samppos, NULL, values, NULL,
04211 CPL_FALSE, NULL, °ree);
04212
04213 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, poly_2d,
04214 samppos, NULL);
04215 cpl_matrix_unwrap(samppos);
04216 mse = cpl_vector_product(fitresidual, fitresidual)
04217 / cpl_vector_get_size(fitresidual);
04218 cpl_vector_delete(fitresidual);
04219
04220 #else
04221 poly_2d = cpl_polynomial_fit_2d_create(xy_pos, values, 3, &mse);
04222 #endif
04223
04224 poly_ima = cpl_image_new(nsamples, nffts, CPL_TYPE_FLOAT);
04225
04226 cpl_image_fill_polynomial(poly_ima, poly_2d, 1, 1, 1, 1);
04227
04228 cpl_image_subtract(image, poly_ima);
04229
04230 cleanup:
04231 cpl_polynomial_delete(poly_2d);
04232 cpl_image_delete(poly_ima);
04233 cpl_vector_delete(xy_pos);
04234 cpl_vector_delete(values);
04235
04236 return cpl_error_get_code();
04237 }
04238
04239
04240
04241
04242
04243
04244
04245
04246
04247
04248
04249
04250 cpl_error_code
04251 irplib_detmon_dark(cpl_frameset * frameset,
04252 const cpl_parameterlist * parlist,
04253 const char * tag,
04254 const char * recipe_name,
04255 const char * pipeline_name,
04256 const char * procatg_master,
04257 const char * procatg_dsnu,
04258 const char * procatg_tbl,
04259 const char * package,
04260 int (*compare)(const cpl_frame *,
04261 const cpl_frame *))
04262 {
04263 int nsets;
04264 int *selection = NULL;
04265 int i;
04266 cpl_error_code error;
04267
04268 if(irplib_detmon_dark_dfs_set_groups(frameset, tag)) {
04269 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
04270 }
04271
04272
04273
04274
04275
04276
04277 error = irplib_detmon_retrieve_dark_params(pipeline_name,
04278 recipe_name, parlist);
04279 cpl_ensure_code(!error, error);
04280
04281
04282 if(compare == NULL)
04283 nsets = 1;
04284 else {
04285 cpl_msg_info(cpl_func, "Identify the different settings");
04286 selection = cpl_frameset_labelise(frameset, compare, &nsets);
04287 if(selection == NULL)
04288 cpl_msg_error(cpl_func, "Cannot labelise input frames");
04289 }
04290
04291 detmon_dark_config.nb_extensions = 1;
04292 if(detmon_dark_config.exts < 0) {
04293 const cpl_frame *cur_frame =
04294 cpl_frameset_get_first_const(frameset);
04295
04296 detmon_dark_config.nb_extensions =
04297 cpl_frame_get_nextensions(cur_frame);
04298 }
04299
04300
04301 for(i = 0; i < nsets; i++) {
04302 int *select_dits = NULL;
04303 cpl_frameset *cur_fset =
04304 nsets == 1 ? cpl_frameset_duplicate(frameset) :
04305 cpl_frameset_extract(frameset, selection, i);
04306
04307 int ndits = 0;
04308 int j, k;
04309 cpl_table ** dsnu_table = NULL;
04310 cpl_imagelist ** dsnu = NULL;
04311
04312 cpl_propertylist ** qclist =
04313 (cpl_propertylist **)
04314 cpl_malloc(detmon_dark_config.nb_extensions *
04315 sizeof(cpl_propertylist *));
04316
04317
04318 cpl_imagelist ** masters =
04319 (cpl_imagelist **)
04320 cpl_malloc(detmon_dark_config.nb_extensions *
04321 sizeof(cpl_imagelist *));
04322
04323
04324 if(detmon_dark_config.opt_nir == OPT) {
04325 dsnu_table =
04326 (cpl_table **) cpl_malloc(detmon_dark_config.nb_extensions *
04327 sizeof(cpl_table *));
04328 dsnu =
04329 (cpl_imagelist **)
04330 cpl_malloc(detmon_dark_config.nb_extensions *
04331 sizeof(cpl_imagelist *));
04332 }
04333
04334 select_dits = cpl_frameset_labelise(cur_fset,
04335 irplib_detmon_compare_dits,
04336 &ndits);
04337
04338 if(detmon_dark_config.exts >= 0) {
04339 *masters = cpl_imagelist_new();
04340 if(detmon_dark_config.opt_nir == OPT) {
04341 *dsnu = cpl_imagelist_new();
04342 *dsnu_table = cpl_table_new(ndits);
04343 }
04344 *qclist = cpl_propertylist_new();
04345 cpl_table_new_column(*dsnu_table, "DIT", CPL_TYPE_DOUBLE);
04346 cpl_table_new_column(*dsnu_table, "STDEV", CPL_TYPE_DOUBLE);
04347 } else {
04348 for ( j = 0; j < detmon_dark_config.nb_extensions; j ++) {
04349 masters[j] = cpl_imagelist_new();
04350 if(detmon_dark_config.opt_nir == OPT) {
04351 dsnu[j] = cpl_imagelist_new();
04352 dsnu_table[j] = cpl_table_new(ndits);
04353 }
04354 qclist[j] = cpl_propertylist_new();
04355 cpl_table_new_column(dsnu_table[j], "DIT", CPL_TYPE_DOUBLE);
04356 cpl_table_new_column(dsnu_table[j], "STDEV", CPL_TYPE_DOUBLE);
04357 }
04358 }
04359
04360 for(j = 0; j < ndits; j++) {
04361 cpl_frameset * cur_fdit = cpl_frameset_extract(cur_fset,
04362 select_dits, j);
04363 cpl_imagelist ** raws =
04364 (cpl_imagelist **)
04365 cpl_malloc(detmon_dark_config.nb_extensions *
04366 sizeof(cpl_imagelist *));
04367
04368 if(detmon_dark_config.exts >= 0) {
04369 cpl_image * collapsed;
04370 *raws =
04371 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04372 detmon_dark_config.exts);
04373 collapsed = cpl_imagelist_collapse_create(*raws);
04374 cpl_imagelist_set(*masters, collapsed, j);
04375 if(detmon_dark_config.opt_nir == OPT) {
04376 irplib_detmon_dark_dsnu(cur_fdit, *dsnu, *dsnu_table,
04377 collapsed, j);
04378 }
04379 irplib_detmon_dark_qc(*qclist, collapsed);
04380 } else {
04381 cpl_imagelist *raws_all_exts =
04382 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04383 -1);
04384 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04385 int nframes = cpl_frameset_get_size(cur_fdit);
04386 int h;
04387 cpl_image * collapsed;
04388 for(h = 0; h < nframes; h++) {
04389 cpl_image *image =
04390 cpl_imagelist_unset(raws_all_exts,
04391 (detmon_dark_config.
04392 nb_extensions - 1 - k) * h);
04393 cpl_imagelist_set(raws[k], image, h);
04394 }
04395 collapsed = cpl_imagelist_collapse_create(raws[k]);
04396 cpl_imagelist_set(masters[k],collapsed, j);
04397 if(detmon_dark_config.opt_nir == OPT) {
04398 irplib_detmon_dark_dsnu(cur_fdit, dsnu[k],
04399 dsnu_table[j], collapsed, j);
04400 }
04401 irplib_detmon_dark_qc(qclist[k], collapsed);
04402 }
04403 }
04404
04405 cpl_frameset_delete(cur_fdit);
04406 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04407 cpl_imagelist_delete(raws[k]);
04408 }
04409 cpl_free(raws);
04410 }
04411
04412 cpl_frameset_delete(cur_fset);
04413
04414 irplib_detmon_dark_save(parlist, frameset, recipe_name, pipeline_name,
04415 procatg_master, procatg_tbl, procatg_dsnu,
04416 package, masters, dsnu_table, dsnu, qclist,
04417 0, 0, frameset);
04418
04419 if(detmon_dark_config.opt_nir == OPT) {
04420 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04421 cpl_table_delete(dsnu_table[j]);
04422 cpl_imagelist_delete(dsnu[j]);
04423 }
04424 cpl_free(dsnu_table);
04425 cpl_free(dsnu);
04426 }
04427
04428 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04429 cpl_propertylist_delete(qclist[j]);
04430 cpl_imagelist_delete(masters[j]);
04431 }
04432 cpl_free(qclist);
04433 cpl_free(masters);
04434 cpl_free(select_dits);
04435
04436 }
04437
04438 cpl_free(selection);
04439
04440 return cpl_error_get_code();
04441 }
04442
04443
04444
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454
04455 int
04456 irplib_detmon_dark_dfs_set_groups(cpl_frameset * set, const char *tag)
04457 {
04458 cpl_frame *cur_frame;
04459 const char *cur_tag;
04460 int nframes;
04461 int i;
04462
04463
04464 if(set == NULL)
04465 return -1;
04466
04467
04468 nframes = cpl_frameset_get_size(set);
04469
04470
04471 for(i = 0; i < nframes; i++) {
04472 cur_frame = cpl_frameset_get_frame(set, i);
04473 cur_tag = cpl_frame_get_tag(cur_frame);
04474
04475
04476 if(!strcmp(cur_tag, tag))
04477 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
04478
04479
04480
04481
04482
04483 }
04484 return 0;
04485 }
04486
04487
04488
04489
04490
04491
04492
04493
04494
04495
04496
04497
04498 static cpl_error_code
04499 irplib_detmon_retrieve_dark_params(const char *pipeline_name,
04500 const char *recipe_name,
04501 const cpl_parameterlist * parlist)
04502 {
04503 char *par_name;
04504 cpl_parameter *par;
04505
04506
04507 par_name = cpl_sprintf("%s.%s.ron.method", pipeline_name, recipe_name);
04508 assert(par_name != NULL);
04509 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04510 detmon_dark_config.ron_method = cpl_parameter_get_string(par);
04511 cpl_free(par_name);
04512
04513
04514 par_name = cpl_sprintf("%s.%s.dsnu.method", pipeline_name, recipe_name);
04515 assert(par_name != NULL);
04516 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04517 detmon_dark_config.dsnu_method = cpl_parameter_get_string(par);
04518 cpl_free(par_name);
04519
04520
04521 par_name = cpl_sprintf("%s.%s.opt_nir", pipeline_name, recipe_name);
04522 assert(par_name != NULL);
04523 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04524 detmon_dark_config.opt_nir = cpl_parameter_get_bool(par);
04525 cpl_free(par_name);
04526
04527
04528 detmon_dark_config.exts =
04529 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
04530 parlist);
04531
04532 if(cpl_error_get_code()) {
04533 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
04534 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
04535 }
04536
04537
04538 return CPL_ERROR_NONE;
04539 }
04540
04541
04542
04543
04544
04545
04546
04547
04548
04549
04550
04551
04552
04553 cpl_error_code
04554 irplib_detmon_fill_dark_params(cpl_parameterlist * parlist,
04555 const char *recipe_name,
04556 const char *pipeline_name,
04557 const char * ron_method,
04558 const char * dsnu_method,
04559 const char * opt_nir,
04560 int exts)
04561 {
04562 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 4,
04563
04564 "ron.method",
04565 "Method used to compute RON. Currently no "
04566 "change is possible, RMS computed",
04567 "CPL_TYPE_STRING", ron_method,
04568
04569 "dsnu.method",
04570 "Method used to compute DSNU map. Currently no "
04571 "change is possible. Method used STDEV",
04572 "CPL_TYPE_STRING", dsnu_method,
04573
04574 "opt_nir",
04575 "Boolean, OPT (FALSE) or NIR(TRUE)",
04576 "CPL_TYPE_BOOL", opt_nir,
04577
04578 "exts",
04579 "Activate the multi-exts option. Default 0"
04580 "(primary unit), -1 (all exts)",
04581 "CPL_TYPE_INT", exts);
04582
04583 return cpl_error_get_code();
04584 }
04585
04586
04587
04588
04589
04590
04591
04592
04593
04594
04595
04596
04597 int
04598 irplib_detmon_fill_dark_params_default(cpl_parameterlist * parlist,
04599 const char *recipe_name,
04600 const char *pipeline_name)
04601 {
04602 irplib_detmon_fill_dark_params(parlist, recipe_name, pipeline_name,
04603 "SIMPLE",
04604 "STDEV",
04605 "CPL_FALSE",
04606 0);
04607 return cpl_error_get_code();
04608 }
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621 cpl_error_code
04622 irplib_detmon_dark_dsnu(cpl_frameset * cur_fdit,
04623 cpl_imagelist * dsnu,
04624 cpl_table * dsnu_table,
04625 cpl_image * collapsed,
04626 int pos)
04627 {
04628 cpl_frame * first = cpl_frameset_get_first(cur_fdit);
04629 cpl_propertylist * plist =
04630 cpl_propertylist_load(cpl_frame_get_filename(first), 0);
04631 double dit = irplib_pfits_get_exptime(plist);
04632 double mean = cpl_image_get_mean(collapsed);
04633
04634 cpl_image * dsnu_map =
04635 cpl_image_subtract_scalar_create(collapsed, mean);
04636 double stdev;
04637 cpl_image_divide_scalar(dsnu_map, mean);
04638 stdev = cpl_image_get_stdev(dsnu_map);
04639
04640 cpl_imagelist_set(dsnu, dsnu_map, pos);
04641
04642 cpl_table_set(dsnu_table, "DIT", pos, dit);
04643 cpl_table_set(dsnu_table, "STDEV", pos, stdev);
04644
04645 cpl_propertylist_delete(plist);
04646
04647 return cpl_error_get_code();
04648
04649 }
04650
04651
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661
04662 static cpl_error_code
04663 irplib_detmon_dark_save(const cpl_parameterlist * parlist,
04664 cpl_frameset * frameset,
04665 const char *recipe_name,
04666 const char *pipeline_name,
04667 const char *procatg_master,
04668 const char *procatg_tbl,
04669 const char *procatg_dsnu,
04670 const char *package,
04671 cpl_imagelist ** masters,
04672 cpl_table ** dsnu_table,
04673 cpl_imagelist ** dsnu,
04674 cpl_propertylist ** qclist,
04675 const int flag_sets,
04676 const int which_set,
04677 const cpl_frameset * usedframes)
04678 {
04679
04680 cpl_frame *ref_frame;
04681 cpl_propertylist *plist;
04682 char *name_o = NULL;
04683 int i, j;
04684 cpl_propertylist *paflist;
04685 cpl_error_code error;
04686 int nb_images;
04687
04688
04689
04690
04691
04692 nb_images = cpl_imagelist_get_size(masters[0]);
04693 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
04694
04695
04696 for(i = 0; i < nb_images; i++) {
04697
04698 if(!flag_sets) {
04699 name_o =
04700 cpl_sprintf("%s_master_dit_%d.fits", recipe_name, i+1);
04701 assert(name_o != NULL);
04702 } else {
04703 name_o =
04704 cpl_sprintf("%s_master_dit_%d_set%02d.fits",
04705 recipe_name, i, which_set);
04706 assert(name_o != NULL);
04707 }
04708
04709
04710
04711 if(detmon_dark_config.exts >= 0) {
04712 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04713 cpl_propertylist * pro_master = cpl_propertylist_new();
04714
04715 cpl_propertylist_append_string(pro_master,
04716 CPL_DFS_PRO_CATG, procatg_master);
04717
04718 cpl_propertylist_append(pro_master, qclist[0]);
04719
04720 if(cpl_dfs_save_image
04721 (frameset, NULL, parlist, usedframes, NULL,
04722 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04723 recipe_name, pro_master, NULL, package,
04724 name_o)) {
04725 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04726 name_o);
04727 cpl_free(name_o);
04728 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04729
04730 }
04731
04732 cpl_propertylist_delete(pro_master);
04733 #else
04734 if(cpl_dfs_save_image
04735 (frameset, parlist, usedframes,
04736 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04737 recipe_name, procatg_master, qclist[0], NULL, package,
04738 name_o)) {
04739 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04740 name_o);
04741 cpl_free(name_o);
04742 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04743
04744 }
04745 #endif
04746 } else {
04747 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04748 cpl_propertylist * pro_master = cpl_propertylist_new();
04749
04750 cpl_propertylist_append_string(pro_master,
04751 CPL_DFS_PRO_CATG, procatg_master);
04752
04753 cpl_propertylist_append(pro_master, qclist[0]);
04754
04755 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
04756 NULL, CPL_BPP_IEEE_FLOAT, recipe_name,
04757 pro_master, NULL,
04758 package, name_o)) {
04759 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04760 name_o);
04761 cpl_free(name_o);
04762 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04763 }
04764
04765 cpl_propertylist_delete(pro_master);
04766 #else
04767 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04768 CPL_BPP_IEEE_FLOAT, recipe_name,
04769 procatg_master, qclist[0], NULL,
04770 package, name_o)) {
04771 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04772 name_o);
04773 cpl_free(name_o);
04774 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04775 }
04776 #endif
04777 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04778 error =
04779 cpl_image_save(cpl_imagelist_get(masters[j], i),
04780 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04781 CPL_IO_EXTEND);
04782 cpl_ensure_code(!error, error);
04783 }
04784 }
04785 cpl_free(name_o);
04786 }
04787
04788 if (detmon_dark_config.opt_nir == OPT) {
04789 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04790 cpl_propertylist * pro_tbl = cpl_propertylist_new();
04791
04792 cpl_propertylist_append_string(pro_tbl,
04793 CPL_DFS_PRO_CATG, procatg_tbl);
04794
04795 cpl_propertylist_append(pro_tbl, qclist[0]);
04796 #endif
04797
04798
04799
04800
04801
04802 if(!flag_sets) {
04803 name_o = cpl_sprintf("%s_dsnu_table.fits", recipe_name);
04804 assert(name_o != NULL);
04805 } else {
04806 name_o =
04807 cpl_sprintf("%s_dsnu_table_set%02d.fits", recipe_name,
04808 which_set);
04809 assert(name_o != NULL);
04810 }
04811 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04812
04813 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
04814 dsnu_table[0], NULL, recipe_name, pro_tbl, NULL,
04815 package, name_o)) {
04816 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04817 cpl_free(name_o);
04818 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04819 }
04820 #else
04821
04822 if(cpl_dfs_save_table(frameset, parlist, usedframes, dsnu_table[0],
04823 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
04824 package, name_o)) {
04825 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04826 cpl_free(name_o);
04827 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04828 }
04829 #endif
04830
04831 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04832 cpl_propertylist_delete(pro_tbl);
04833 #endif
04834
04835 if(detmon_dark_config.exts < 0) {
04836
04837 for(i = 1; i < detmon_dark_config.nb_extensions; i++) {
04838 error =
04839 cpl_table_save(dsnu_table[i], NULL, qclist[i], name_o,
04840 CPL_IO_EXTEND);
04841 cpl_ensure_code(!error, error);
04842 }
04843 }
04844
04845
04846 cpl_free(name_o);
04847
04848
04849
04850
04851
04852 for(i = 0; i < nb_images; i++) {
04853
04854 if(!flag_sets) {
04855 name_o =
04856 cpl_sprintf("%s_dsnu_map_dit_%d.fits", recipe_name, i+1);
04857 assert(name_o != NULL);
04858 } else {
04859 name_o =
04860 cpl_sprintf("%s_dsnu_map_dit_%d_set%02d.fits",
04861 recipe_name, i, which_set);
04862 assert(name_o != NULL);
04863 }
04864
04865
04866
04867 if(detmon_dark_config.exts >= 0) {
04868 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04869 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04870
04871 cpl_propertylist_append_string(pro_dsnu,
04872 CPL_DFS_PRO_CATG, procatg_dsnu);
04873
04874 cpl_propertylist_append(pro_dsnu, qclist[0]);
04875
04876 if(cpl_dfs_save_image
04877 (frameset, NULL, parlist, usedframes, NULL,
04878 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04879 recipe_name, pro_dsnu, NULL, package,
04880 name_o)) {
04881 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04882 name_o);
04883 cpl_free(name_o);
04884 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04885
04886 }
04887
04888 cpl_propertylist_delete(pro_dsnu);
04889 #else
04890 if(cpl_dfs_save_image
04891 (frameset, parlist, usedframes,
04892 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04893 recipe_name, procatg_dsnu, qclist[0], NULL, package,
04894 name_o)) {
04895 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04896 name_o);
04897 cpl_free(name_o);
04898 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04899
04900 }
04901 #endif
04902 } else {
04903 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04904 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04905
04906 cpl_propertylist_append_string(pro_dsnu,
04907 CPL_DFS_PRO_CATG, procatg_dsnu);
04908
04909 cpl_propertylist_append(pro_dsnu, qclist[0]);
04910
04911 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
04912 NULL, NULL,
04913 CPL_BPP_IEEE_FLOAT, recipe_name,
04914 pro_dsnu, NULL,
04915 package, name_o)) {
04916 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04917 name_o);
04918 cpl_free(name_o);
04919 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04920 }
04921
04922 cpl_propertylist_delete(pro_dsnu);
04923 #else
04924 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04925 CPL_BPP_IEEE_FLOAT, recipe_name,
04926 procatg_dsnu, qclist[0], NULL,
04927 package, name_o)) {
04928 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04929 name_o);
04930 cpl_free(name_o);
04931 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04932 }
04933 #endif
04934 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04935 error =
04936 cpl_image_save(cpl_imagelist_get(dsnu[j], i),
04937 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04938 CPL_IO_EXTEND);
04939 cpl_ensure_code(!error, error);
04940 }
04941 }
04942 cpl_free(name_o);
04943 }
04944
04945
04946
04947 }
04948
04949
04950
04951
04952
04953
04954 ref_frame = cpl_frameset_get_first(frameset);
04955 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04956 0)) == NULL) {
04957 cpl_msg_error(cpl_func, "getting header from reference frame");
04958 cpl_ensure_code(0, cpl_error_get_code());
04959 }
04960
04961
04962 paflist = cpl_propertylist_new();
04963 cpl_propertylist_copy_property_regexp(paflist, plist,
04964 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
04965 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
04966 "ESO DET NCORRS|"
04967 "ESO DET MODE NAME)$", 0);
04968
04969 for(i = 0; i < detmon_dark_config.nb_extensions; i++) {
04970 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
04971 error = cpl_propertylist_append(c_paflist, qclist[i]);
04972 cpl_ensure_code(!error, error);
04973
04974
04975 if(detmon_dark_config.exts >= 0) {
04976 if(!flag_sets) {
04977 name_o = cpl_sprintf("%s.paf", recipe_name);
04978 assert(name_o != NULL);
04979 } else {
04980 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
04981 assert(name_o != NULL);
04982 }
04983 } else {
04984 if(!flag_sets) {
04985 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
04986 assert(name_o != NULL);
04987 } else {
04988 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
04989 assert(name_o != NULL);
04990 }
04991 }
04992
04993 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
04994 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04995 cpl_free(name_o);
04996 cpl_propertylist_delete(paflist);
04997 cpl_propertylist_delete(plist);
04998 cpl_free(name_o);
04999 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
05000 }
05001 cpl_propertylist_delete(c_paflist);
05002 cpl_free(name_o);
05003 }
05004
05005 cpl_propertylist_delete(plist);
05006 cpl_propertylist_delete(paflist);
05007
05008 return cpl_error_get_code();
05009 }
05010
05011 cpl_error_code
05012 irplib_detmon_dark_qc(cpl_propertylist * qclist,
05013 cpl_image * collapsed)
05014 {
05015 double mean = cpl_image_get_mean(collapsed);
05016 double stdev = cpl_image_get_stdev(collapsed);
05017
05018 cpl_error_code error;
05019
05020 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK, mean);
05021 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK,
05022 DETMON_QC_DARK_C);
05023 cpl_ensure_code(!error, error);
05024
05025 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK_STDEV, stdev);
05026 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK_STDEV,
05027 DETMON_QC_DARK_STDEV_C);
05028 cpl_ensure_code(!error, error);
05029
05030 return cpl_error_get_code();
05031 }
05032
05033
05034
05051
05052 cpl_image *
05053 irplib_imagelist_collapse_stdev_create(const cpl_imagelist * imlist)
05054 {
05055 cpl_image * mean;
05056 cpl_image * delta;
05057 cpl_image * sq_delta;
05058 cpl_image * stdev;
05059
05060 int i;
05061
05062
05063 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05064 cpl_ensure(cpl_imagelist_is_uniform(imlist) == 0, CPL_ERROR_ILLEGAL_INPUT,
05065 NULL);
05066
05067
05068 mean = cpl_image_duplicate(cpl_imagelist_get_const(imlist, 0));
05069 cpl_image_fill_rejected(mean, 0.0);
05070 cpl_image_accept_all(mean);
05071
05072 stdev = cpl_image_new(cpl_image_get_size_x(mean),
05073 cpl_image_get_size_y(mean),
05074 CPL_TYPE_FLOAT);
05075
05076 for (i = 1; i < cpl_imagelist_get_size(imlist); i++) {
05077 delta = cpl_image_subtract_create(cpl_imagelist_get_const(imlist, i),
05078 mean);
05079 cpl_image_fill_rejected(delta, 0.0);
05080 cpl_image_accept_all(delta);
05081
05082 sq_delta = cpl_image_multiply_create(delta, delta);
05083
05084 cpl_image_multiply_scalar(sq_delta, ((double) i / (double)(i+1)));
05085 cpl_image_add(stdev, sq_delta);
05086
05087 cpl_image_divide_scalar(delta, i + 1);
05088 cpl_image_add(mean, delta);
05089
05090 cpl_image_delete(delta);
05091 cpl_image_delete(sq_delta);
05092 }
05093
05094 cpl_image_divide_scalar(stdev, cpl_imagelist_get_size(imlist) - 1);
05095 cpl_image_power(stdev, 0.5);
05096
05097 cpl_image_delete(mean);
05098
05099 return stdev;
05100 }