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