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