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