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