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