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 int preoverscan_degree;
00109 int random_nsamples;
00110 int random_sizex;
00111 int random_sizey;
00112 int criteria;
00113 int ref_llx;
00114 int ref_lly;
00115 int ref_urx;
00116 int ref_ury;
00117 const char *stacking_method;
00118 int stacking_ks_low;
00119 int stacking_ks_high;
00120 int stacking_ks_iter;
00121 int master_shift_x;
00122 int master_shift_y;
00123 int ron_llx;
00124 int ron_lly;
00125 int ron_urx;
00126 int ron_ury;
00127 int exts;
00128 int nb_extensions;
00129 } detmon_ronbias_config;
00130
00131 static struct
00132 {
00133 int mode;
00134 cpl_boolean direction;
00135 double speed;
00136 int llx;
00137 int lly;
00138 int urx;
00139 int ury;
00140 int kappa;
00141 int exts;
00142 int nb_extensions;
00143 } detmon_pernoise_config;
00144
00145 static struct
00146 {
00147 const char * ron_method;
00148 const char * dsnu_method;
00149 int exts;
00150 int nb_extensions;
00151 cpl_boolean opt_nir;
00152 } detmon_dark_config;
00153
00154 #define NIR TRUE
00155 #define OPT FALSE
00156
00157
00158
00159
00160
00161
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 unsigned long maxf;
01565
01566 double mean, stdev;
01567 cpl_image * dupi;
01568 unsigned long x1a = 1;
01569 unsigned long x2a = 1;
01570
01571 double x1 = 0;
01572 double x2 = 0;
01573
01574 double maxwhere_interp;
01575 double max_interp;
01576 double a, b, c;
01577 cpl_matrix * coeffs =cpl_matrix_new(3, 3);
01578 cpl_matrix * rhs =cpl_matrix_new(3, 1);
01579 int p, q;
01580 cpl_matrix * result = NULL;
01581 cpl_error_code error;
01582
01583 mean = cpl_image_get_mean(c_raw);
01584 stdev = cpl_image_get_stdev(c_raw);
01585 dupi = cpl_image_duplicate(c_raw);
01586
01587
01588
01589
01590 hist = irplib_hist_new();
01591 error = irplib_hist_fill(hist, dupi);
01592 cpl_ensure_code(!error, error);
01593
01594 cpl_image_delete(dupi);
01595
01596 maxf = irplib_hist_get_max(hist, &maxwhere);
01597
01598 for( p = 0; p< 3; p++){
01599 unsigned long bi = irplib_hist_get_value(hist, maxwhere-1+p);
01600 cpl_matrix_set(rhs, p, 0, bi);
01601 for( q= 0; q< 3; q++) {
01602 cpl_matrix_set(coeffs, p,q,pow((maxwhere-1+p),q));
01603 }
01604 }
01605
01606 result = cpl_matrix_solve(coeffs, rhs);
01607
01608 a = cpl_matrix_get(result, 2, 0);
01609 b = cpl_matrix_get(result, 1, 0);
01610 c = cpl_matrix_get(result, 0, 0);
01611
01612 maxwhere_interp = -0.5 * b / (2 * a);
01613 max_interp = -1 * b * b / (4 * a) + c;
01614
01615 cpl_matrix_delete(coeffs);
01616 cpl_matrix_delete(rhs);
01617 cpl_matrix_delete(result);
01618
01619
01620 for(uj = 0; uj < maxwhere; uj++) {
01621 if(irplib_hist_get_value(hist, uj) <= max_interp / 2 &&
01622 irplib_hist_get_value(hist, uj + 1) > max_interp / 2) {
01623 x1a = uj;
01624 }
01625 }
01626 for(uj = maxwhere; uj < irplib_hist_get_nbins(hist)-1; uj++) {
01627 if(irplib_hist_get_value(hist, uj) >= max_interp / 2 &&
01628 irplib_hist_get_value(hist, uj + 1) < max_interp / 2) {
01629 x2a = uj;
01630 }
01631 }
01632
01633 x1 = (max_interp / 2 - irplib_hist_get_value(hist, x1a)) /
01634 (irplib_hist_get_value(hist, x1a + 1) -
01635 irplib_hist_get_value(hist, x1a)) + x1a;
01636 x2 = (max_interp / 2 - irplib_hist_get_value(hist, x2a)) /
01637 (irplib_hist_get_value(hist, x2a + 1) -
01638 irplib_hist_get_value(hist, x2a)) + x2a;
01639
01640 *fwhm = (x2 - x1) * irplib_hist_get_bin_size(hist);
01641
01642 *max = max_interp;
01643
01644 *bias = maxwhere_interp * irplib_hist_get_bin_size(hist) +
01645 irplib_hist_get_start(hist);
01646
01647 irplib_hist_delete(hist);
01648
01649 return cpl_error_get_code();
01650 }
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662 static cpl_error_code
01663 detmon_ronbias_preoverscan(const cpl_imagelist * rawbiases,
01664 cpl_propertylist * qclist,
01665 cpl_image ** synthetic)
01666 {
01667 int i;
01668 int nx, ny;
01669 int nraws;
01670
01671 cpl_vector *meanspre;
01672 cpl_vector *medspre;
01673 cpl_vector *rmsspre;
01674 cpl_vector *meansover;
01675 cpl_vector *medsover;
01676 cpl_vector *rmssover;
01677
01678 cpl_error_code error;
01679
01680 nraws = cpl_imagelist_get_size(rawbiases);
01681 cpl_ensure_code(nraws != -1, CPL_ERROR_ILLEGAL_INPUT);
01682
01683 meanspre = cpl_vector_new(nraws);
01684 medspre = cpl_vector_new(nraws);
01685 rmsspre = cpl_vector_new(nraws);
01686 meansover = cpl_vector_new(nraws);
01687 medsover = cpl_vector_new(nraws);
01688 rmssover = cpl_vector_new(nraws);
01689
01690 nx = cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
01691 ny = cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
01692 cpl_ensure_code(nx != -1 && ny != -1, CPL_ERROR_ILLEGAL_INPUT);
01693
01694 if(nx < detmon_ronbias_config.prescan_urx ||
01695 nx < detmon_ronbias_config.overscan_urx ||
01696 ny < detmon_ronbias_config.prescan_ury ||
01697 ny < detmon_ronbias_config.overscan_ury) {
01698 cpl_msg_warning(cpl_func, "PREOVERSCAN method not applied. Given "
01699 "limits of prescan and overscan area "
01700 "exceed image size. Please check and rerun.");
01701 return CPL_ERROR_NONE;
01702 }
01703
01704 for(i = 0; i < nraws; i++) {
01705 double mean = 0;
01706 double stdev = 0;
01707
01708 cpl_image *prescan = NULL;
01709 cpl_image *overscan = NULL;
01710
01711 const cpl_image *c_raw = cpl_imagelist_get_const(rawbiases, i);
01712
01713 cpl_ensure_code(c_raw != NULL, CPL_ERROR_ILLEGAL_INPUT);
01714
01715 prescan =
01716 cpl_image_extract(c_raw,
01717 detmon_ronbias_config.prescan_llx,
01718 detmon_ronbias_config.prescan_lly,
01719 detmon_ronbias_config.prescan_urx,
01720 detmon_ronbias_config.prescan_ury);
01721 cpl_ensure_code(prescan != NULL, CPL_ERROR_ILLEGAL_INPUT);
01722 overscan =
01723 cpl_image_extract(c_raw,
01724 detmon_ronbias_config.overscan_llx,
01725 detmon_ronbias_config.overscan_lly,
01726 detmon_ronbias_config.overscan_urx,
01727 detmon_ronbias_config.overscan_ury);
01728 cpl_ensure_code(overscan != NULL, CPL_ERROR_ILLEGAL_INPUT);
01729
01730 if(i == 0) {
01731 *synthetic = detmon_build_synthetic(prescan, overscan);
01732 cpl_msg_info(cpl_func, "Creating SYNTHETIC frame");
01733 if(*synthetic == NULL) {
01734 cpl_msg_error(cpl_func, "Error creating SYNTHETIC frame");
01735 return CPL_ERROR_UNSPECIFIED;
01736 }
01737 }
01738
01739 error = irplib_ksigma_clip(c_raw,
01740 detmon_ronbias_config.
01741 prescan_llx,
01742 detmon_ronbias_config.
01743 prescan_lly,
01744 detmon_ronbias_config.
01745 prescan_urx,
01746 detmon_ronbias_config.
01747 prescan_ury,
01748 (double) detmon_ronbias_config.
01749 stacking_ks_low,
01750 detmon_ronbias_config.
01751 stacking_ks_iter, 1e-5,
01752 &mean, &stdev);
01753 cpl_ensure_code(!error, error);
01754
01755 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
01756
01757 error = cpl_vector_set(medspre, i, cpl_image_get_median(prescan));
01758 cpl_ensure_code(!error, error);
01759
01760 error = cpl_vector_set(meanspre, i, mean);
01761 cpl_ensure_code(!error, error);
01762 error = cpl_vector_set(rmsspre, i, stdev);
01763 cpl_ensure_code(!error, error);
01764 error = irplib_ksigma_clip(c_raw,
01765 detmon_ronbias_config.
01766 overscan_llx,
01767 detmon_ronbias_config.
01768 overscan_lly,
01769 detmon_ronbias_config.
01770 overscan_urx,
01771 detmon_ronbias_config.
01772 overscan_ury,
01773 (double) detmon_ronbias_config.
01774 stacking_ks_low,
01775 detmon_ronbias_config.
01776 stacking_ks_iter, 1e-5,
01777 &mean, &stdev);
01778 cpl_ensure_code(!error, error);
01779
01780 cpl_ensure_code(mean != 0 && stdev != 0, CPL_ERROR_UNSPECIFIED);
01781
01782 error = cpl_vector_set(medsover, i, cpl_image_get_median(overscan));
01783 cpl_ensure_code(!error, error);
01784
01785 error = cpl_vector_set(meansover, i, mean);
01786 cpl_ensure_code(!error, error);
01787 error = cpl_vector_set(rmssover, i, stdev);
01788 cpl_ensure_code(!error, error);
01789
01790 cpl_image_delete(prescan);
01791 cpl_image_delete(overscan);
01792 }
01793
01794 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
01795 cpl_vector_get_mean(meanspre));
01796
01797 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MEAN,
01798 DETMON_QC_BIAS_PRESCAN_MEAN_C);
01799
01800 cpl_ensure_code(!error, error);
01801 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_MED,
01802 cpl_vector_get_mean(medspre));
01803 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_MED,
01804 DETMON_QC_BIAS_PRESCAN_MED_C);
01805
01806 cpl_ensure_code(!error, error);
01807 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_PRESCAN_RON,
01808 cpl_vector_get_mean(rmsspre));
01809
01810 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_PRESCAN_RON,
01811 DETMON_QC_BIAS_PRESCAN_RON_C);
01812 cpl_ensure_code(!error, error);
01813
01814 error =
01815 cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
01816 cpl_vector_get_mean(meansover));
01817 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MEAN,
01818 DETMON_QC_BIAS_OVERSCAN_MEAN_C);
01819 cpl_ensure_code(!error, error);
01820 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
01821 cpl_vector_get_mean(medsover));
01822 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_MED,
01823 DETMON_QC_BIAS_OVERSCAN_MED_C);
01824 cpl_ensure_code(!error, error);
01825 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
01826 cpl_vector_get_mean(rmssover));
01827 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_OVERSCAN_RON,
01828 DETMON_QC_BIAS_OVERSCAN_RON_C);
01829 cpl_ensure_code(!error, error);
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
01864
01865
01866
01867 cpl_vector_delete(meanspre);
01868 cpl_vector_delete(medspre);
01869 cpl_vector_delete(rmsspre);
01870 cpl_vector_delete(meansover);
01871 cpl_vector_delete(medsover);
01872 cpl_vector_delete(rmssover);
01873
01874 return CPL_ERROR_NONE;
01875 }
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888 static cpl_error_code
01889 detmon_ronbias_region(const cpl_imagelist * rawbiases,
01890 const cpl_image * masterbias,
01891 cpl_propertylist * qclist)
01892 {
01893
01894 int nraws = cpl_imagelist_get_size(rawbiases);
01895 int i;
01896
01897 int nx =
01898 cpl_image_get_size_x(cpl_imagelist_get_const(rawbiases, 0));
01899 int ny =
01900 cpl_image_get_size_y(cpl_imagelist_get_const(rawbiases, 0));
01901
01902 cpl_vector *rmssreg;
01903 cpl_error_code error;
01904
01905 const cpl_image * c_raw;
01906 double median, mbias, mstdev;
01907
01908 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) nraws--;
01909
01910 rmssreg = cpl_vector_new(nraws);
01911
01912 if(nx < detmon_ronbias_config.ref_urx ||
01913 ny < detmon_ronbias_config.ref_ury) {
01914 cpl_msg_warning(cpl_func, "REGION method not applied. Given "
01915 "limits of prescan and overscan area "
01916 "exceed image size. Please check and rerun.");
01917 return CPL_ERROR_NONE;
01918 }
01919
01920 for(i = 0; i < nraws; i++) {
01921 double mean = 0;
01922 double stdev = 0;
01923 if(strcmp(detmon_ronbias_config.pmethod, "DIF")) {
01924 c_raw = cpl_imagelist_get_const(rawbiases, i);
01925 } else {
01926 const cpl_image *c1_raw = cpl_imagelist_get_const(rawbiases, i);
01927 const cpl_image * c2_raw = cpl_imagelist_get_const(rawbiases, i+1);
01928 c_raw = cpl_image_subtract_create(c1_raw, c2_raw);
01929 }
01930 error = irplib_ksigma_clip(c_raw,
01931 detmon_ronbias_config.ref_llx,
01932 detmon_ronbias_config.ref_lly,
01933 detmon_ronbias_config.ref_urx,
01934 detmon_ronbias_config.ref_ury,
01935 (double) detmon_ronbias_config.
01936 stacking_ks_low,
01937 detmon_ronbias_config.
01938 stacking_ks_iter, 1e-5,
01939 &mean, &stdev);
01940 cpl_ensure_code(!error, error);
01941
01942
01943
01944
01945
01946
01947 error = cpl_vector_set(rmssreg, i, stdev);
01948 cpl_ensure_code(!error, error);
01949 if(!strcmp(detmon_ronbias_config.pmethod, "DIF")) cpl_image_delete((cpl_image *)c_raw);
01950 }
01951
01952 median = cpl_image_get_median_window(masterbias,
01953 detmon_ronbias_config.ref_llx,
01954 detmon_ronbias_config.ref_lly,
01955 detmon_ronbias_config.ref_urx,
01956 detmon_ronbias_config.ref_ury);
01957 error = irplib_ksigma_clip(masterbias,
01958 detmon_ronbias_config.ref_llx,
01959 detmon_ronbias_config.ref_lly,
01960 detmon_ronbias_config.ref_urx,
01961 detmon_ronbias_config.ref_ury,
01962 (double) detmon_ronbias_config.
01963 stacking_ks_low,
01964 detmon_ronbias_config.
01965 stacking_ks_iter, 1e-5,
01966 &mbias, &mstdev);
01967
01968 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_MED,
01969 median);
01970 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_MED,
01971 DETMON_QC_BIAS_REGION_MED_C);
01972 cpl_ensure_code(!error, error);
01973
01974 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_VAL,
01975 mbias);
01976 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_VAL,
01977 DETMON_QC_BIAS_REGION_VAL_C);
01978 cpl_ensure_code(!error, error);
01979 error = cpl_propertylist_append_double(qclist,DETMON_QC_BIAS_REGION_RON,
01980 cpl_vector_get_mean(rmssreg));
01981 error = cpl_propertylist_set_comment(qclist,DETMON_QC_BIAS_REGION_RON,
01982 DETMON_QC_BIAS_REGION_RON_C);
01983 cpl_ensure_code(!error, error);
01984
01985
01986
01987
01988
01989
01990 cpl_vector_delete(rmssreg);
01991
01992 return cpl_error_get_code();
01993 }
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006 static cpl_image *
02007 detmon_ronbias_master(const cpl_imagelist * rawbiases,
02008 cpl_mask ** bpmhot, cpl_mask ** bpmcold,
02009 cpl_mask ** bpmdev, cpl_propertylist * qclist)
02010 {
02011 double mean = 0;
02012 double stdev = 0;
02013 cpl_image *masterbias = NULL;
02014 double dark_med, stdev_med,lower, upper;
02015 int hotpix_nb, coldpix_nb, devpix_nb;
02016 cpl_image * stdev_im = NULL;
02017
02018 if(!strcmp(detmon_ronbias_config.stacking_method, "MEAN"))
02019 masterbias = cpl_imagelist_collapse_create(rawbiases);
02020 if(!strcmp(detmon_ronbias_config.stacking_method, "MINMAX"))
02021 masterbias =
02022 cpl_imagelist_collapse_minmax_create(rawbiases, 0, 10000);
02023 if(!strcmp(detmon_ronbias_config.stacking_method, "KSIGMA"))
02024 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(5, 1, 0)
02025 masterbias =
02026 cpl_imagelist_collapse_sigclip_create(rawbiases, 3.0, 3.0, 0.9,
02027 CPL_COLLAPSE_MEAN, NULL);
02028 #else
02029 masterbias =
02030 cpl_imagelist_collapse_sigclip_create(rawbiases, 3.0, 0.0, 1.0,
02031 1, NULL);
02032 #endif
02033 if(!strcmp(detmon_ronbias_config.stacking_method, "MEDIAN"))
02034 masterbias = cpl_imagelist_collapse_median_create(rawbiases);
02035
02036 skip_if(masterbias == NULL);
02037
02038 skip_if(irplib_ksigma_clip(masterbias, 1, 1,
02039 cpl_image_get_size_x(masterbias),
02040 cpl_image_get_size_y(masterbias),
02041 (double) detmon_ronbias_config.
02042 stacking_ks_low,
02043 detmon_ronbias_config.
02044 stacking_ks_iter, 1e-5,
02045 &mean, &stdev));
02046
02047 if(irplib_isnan(mean))
02048 cpl_msg_error(cpl_func, "We have an error in mean");
02049 if(irplib_isnan(stdev))
02050 cpl_msg_error(cpl_func, "We have an error in stdev");
02051
02052 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_MEAN,
02053 mean));
02054 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_MEAN,
02055 DETMON_QC_MASTER_MEAN_C));
02056
02057 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_MASTER_RMS,
02058 stdev));
02059 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_MASTER_RMS,
02060 DETMON_QC_MASTER_RMS_C));
02061
02062
02063 dark_med = cpl_image_get_median(masterbias);
02064
02065 lower = dark_med - stdev * detmon_ronbias_config.stacking_ks_low;
02066 upper = dark_med + stdev * detmon_ronbias_config.stacking_ks_high;
02067
02068
02069 cpl_mask_delete(*bpmhot);
02070 irplib_check(*bpmhot = cpl_mask_threshold_image_create(masterbias,
02071 upper, DBL_MAX),
02072 "Cannot compute the hot pixel map");
02073 hotpix_nb = cpl_mask_count(*bpmhot);
02074 skip_if (0);
02075
02076
02077 cpl_mask_delete(*bpmcold);
02078 irplib_check(*bpmcold = cpl_mask_threshold_image_create(masterbias,
02079 -FLT_MAX, lower),
02080 "Cannot compute the cold pixel map");
02081 coldpix_nb = cpl_mask_count(*bpmcold);
02082 skip_if (0);
02083
02084
02085 stdev_im = irplib_imagelist_collapse_stdev_create(rawbiases);
02086 stdev_med = cpl_image_get_median(stdev_im);
02087
02088 skip_if(irplib_ksigma_clip(stdev_im, 1, 1,
02089 cpl_image_get_size_x(stdev_im),
02090 cpl_image_get_size_y(stdev_im),
02091 (double) detmon_ronbias_config.
02092 stacking_ks_low,
02093 detmon_ronbias_config.
02094 stacking_ks_iter, 1e-5,
02095 &mean, &stdev));
02096
02097 lower = stdev_med - stdev * detmon_ronbias_config.stacking_ks_low;
02098 upper = stdev_med + stdev * detmon_ronbias_config.stacking_ks_high;
02099
02100 cpl_mask_delete(*bpmdev);
02101 irplib_check(*bpmdev = cpl_mask_threshold_image_create(stdev_im,
02102 lower, upper),
02103 "Cannot compute the cold pixel map");
02104 cpl_mask_not(*bpmdev);
02105 devpix_nb = cpl_mask_count(*bpmdev);
02106 skip_if (0);
02107
02108
02109 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBCOLDPIX,coldpix_nb));
02110 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBCOLDPIX,
02111 DETMON_QC_NBCOLDPIX_C));
02112
02113 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBHOTPIX, hotpix_nb));
02114 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBHOTPIX,
02115 DETMON_QC_NBHOTPIX_C));
02116
02117 skip_if(cpl_propertylist_append_int(qclist,DETMON_QC_NBDEVPIX, devpix_nb));
02118 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_NBDEVPIX,
02119 DETMON_QC_NBDEVPIX_C));
02120
02121 end_skip;
02122
02123 cpl_image_delete(stdev_im);
02124
02125 if (cpl_error_get_code()) {
02126 cpl_image_delete(masterbias);
02127 masterbias = NULL;
02128 }
02129
02130 return masterbias;
02131 }
02132
02133
02134
02135
02136
02137
02138
02139
02140
02141
02142
02143
02144 static cpl_error_code
02145 detmon_ronbias_save(const cpl_parameterlist * parlist,
02146 cpl_frameset * frameset,
02147 const char *recipe_name,
02148 const char *pipeline_name,
02149 const char *pafregexp,
02150 const cpl_propertylist * pro_master,
02151 const cpl_propertylist * pro_xstr,
02152 const cpl_propertylist * pro_ystr,
02153 const cpl_propertylist * pro_synth,
02154 const cpl_propertylist * pro_bpmhot,
02155 const cpl_propertylist * pro_bpmcold,
02156 const cpl_propertylist * pro_bpmdev,
02157 const char *package,
02158 const cpl_image * masterbias,
02159 const cpl_image * synthetic,
02160 const cpl_mask * bpmhot,
02161 const cpl_mask * bpmcold,
02162 const cpl_mask * bpmdev,
02163 cpl_propertylist * qclist,
02164 const int flag_sets,
02165 const int which_set,
02166 cpl_frameset * usedframes,
02167 int whichext)
02168 {
02169
02170 cpl_frame *ref_frame;
02171 cpl_propertylist *plist = NULL;
02172 char *name_o = NULL;
02173
02174 cpl_propertylist * paflist = NULL;
02175 cpl_propertylist * mainplist = NULL;
02176 cpl_propertylist * xplist = NULL;
02177 cpl_image * image = NULL;
02178
02179 cpl_propertylist * mypro_master =
02180 cpl_propertylist_duplicate(pro_master);
02181
02182 cpl_propertylist * mypro_synth = NULL;
02183 cpl_propertylist * mypro_bpmhot =
02184 cpl_propertylist_duplicate(pro_bpmhot);
02185 cpl_propertylist * mypro_bpmcold =
02186 cpl_propertylist_duplicate(pro_bpmcold);
02187 cpl_propertylist * mypro_bpmdev =
02188 cpl_propertylist_duplicate(pro_bpmdev);
02189
02190 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
02191 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
02192 cpl_ensure_code(pafregexp != NULL, CPL_ERROR_NULL_INPUT);
02193 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
02194 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
02195 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
02196 cpl_ensure_code(usedframes != NULL, CPL_ERROR_NULL_INPUT);
02197
02198 if (pro_synth)
02199 mypro_synth = cpl_propertylist_duplicate(pro_synth);
02200
02201
02202 cpl_ensure_code(pro_xstr == NULL && pro_ystr == NULL,
02203 CPL_ERROR_UNSUPPORTED_MODE);
02204
02205
02206 if (detmon_ronbias_config.exts < 0) {
02207 const char * filename =
02208 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
02209
02210
02211 xplist = cpl_propertylist_load_regexp(filename, whichext,
02212 "ESO DET", 0);
02213 skip_if(cpl_propertylist_append(xplist, qclist));
02214 }
02215
02216 cpl_msg_info(cpl_func,"dealing with extention %d",whichext);
02217
02218
02219
02220 ref_frame = cpl_frameset_get_first(frameset);
02221 skip_if(ref_frame == NULL);
02222
02223 skip_if((mainplist =
02224 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02225 0)) == NULL);
02226
02227
02228
02229
02230
02231
02232 if(!flag_sets) {
02233 name_o = cpl_sprintf("%s_masterbias.fits", recipe_name);
02234 assert(name_o != NULL);
02235 } else {
02236 name_o =
02237 cpl_sprintf("%s_masterbias_set%02d.fits", recipe_name,
02238 which_set);
02239 assert(name_o != NULL);
02240 }
02241
02242 if (whichext == 0) {
02243 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02244 cpl_propertylist_append(mypro_master, qclist);
02245
02246 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02247 masterbias, CPL_BPP_IEEE_FLOAT, recipe_name,
02248 mypro_master, NULL, package, name_o));
02249 #else
02250 const char * procatg_master =
02251 cpl_propertylist_get_string(mypro_master, CPL_DFS_PRO_CATG);
02252
02253 cpl_propertylist_append(mypro_master, qclist);
02254
02255 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, masterbias,
02256 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_master,
02257 mypro_master, NULL, package, name_o));
02258 #endif
02259 } else
02260 skip_if(cpl_image_save(masterbias,
02261 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02262 CPL_IO_EXTEND));
02263
02264
02265 cpl_free(name_o);
02266 name_o = NULL;
02267
02268
02269
02270
02271
02272
02273 if(!flag_sets) {
02274 name_o = cpl_sprintf("%s_hotpixmap.fits", recipe_name);
02275 assert(name_o != NULL);
02276 } else {
02277 name_o =
02278 cpl_sprintf("%s_hotpixmap_set%02d.fits", recipe_name,
02279 which_set);
02280 assert(name_o != NULL);
02281 }
02282
02283 skip_if(0);
02284 image = cpl_image_new_from_mask(bpmhot);
02285 cpl_error_reset();
02286
02287 if (whichext == 0) {
02288 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02289 cpl_propertylist_append(mypro_bpmhot, qclist);
02290
02291 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02292 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02293 mypro_bpmhot, NULL, package, name_o));
02294 #else
02295 const char * procatg_bpmhot =
02296 cpl_propertylist_get_string(mypro_bpmhot, CPL_DFS_PRO_CATG);
02297
02298 cpl_propertylist_append(mypro_bpmhot, qclist);
02299
02300 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02301 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmhot,
02302 mypro_bpmhot, NULL, package, name_o));
02303 #endif
02304 } else
02305 skip_if(cpl_image_save(image,
02306 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02307 CPL_IO_EXTEND));
02308
02309
02310 cpl_free(name_o);
02311 cpl_image_delete(image);
02312 image = NULL;
02313 name_o = NULL;
02314
02315
02316
02317
02318
02319
02320 if(!flag_sets) {
02321 name_o = cpl_sprintf("%s_coldpixmap.fits", recipe_name);
02322 assert(name_o != NULL);
02323 } else {
02324 name_o =
02325 cpl_sprintf("%s_coldpixmap_set%02d.fits", recipe_name,
02326 which_set);
02327 assert(name_o != NULL);
02328 }
02329
02330 skip_if(0);
02331 image = cpl_image_new_from_mask(bpmcold);
02332 cpl_error_reset();
02333
02334 if (whichext == 0) {
02335 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02336 cpl_propertylist_append(mypro_bpmcold, qclist);
02337
02338 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
02339 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02340 mypro_bpmcold, NULL, package, name_o));
02341 #else
02342 const char * procatg_bpmcold =
02343 cpl_propertylist_get_string(mypro_bpmcold, CPL_DFS_PRO_CATG);
02344
02345 cpl_propertylist_append(mypro_bpmcold, qclist);
02346
02347 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02348 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmcold,
02349 mypro_bpmcold, NULL, package, name_o));
02350 #endif
02351 } else
02352 skip_if(cpl_image_save(image,
02353 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02354 CPL_IO_EXTEND));
02355
02356
02357 cpl_free(name_o);
02358 cpl_image_delete(image);
02359 image = NULL;
02360 name_o = NULL;
02361
02362
02363
02364
02365
02366
02367 if(!flag_sets) {
02368 name_o = cpl_sprintf("%s_devpixmap.fits", recipe_name);
02369 assert(name_o != NULL);
02370 } else {
02371 name_o =
02372 cpl_sprintf("%s_devpixmap_set%02d.fits", recipe_name,
02373 which_set);
02374 assert(name_o != NULL);
02375 }
02376
02377 skip_if(0);
02378 image = cpl_image_new_from_mask(bpmdev);
02379 cpl_error_reset();
02380
02381 if (whichext == 0) {
02382 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02383 cpl_propertylist_append(mypro_bpmdev, qclist);
02384
02385 skip_if(cpl_dfs_save_image(frameset, NULL,parlist, usedframes, NULL,
02386 image, CPL_BPP_IEEE_FLOAT, recipe_name,
02387 mypro_bpmdev, NULL, package, name_o));
02388 #else
02389 const char * procatg_bpmdev =
02390 cpl_propertylist_get_string(mypro_bpmdev, CPL_DFS_PRO_CATG);
02391
02392 cpl_propertylist_append(mypro_bpmdev, qclist);
02393
02394 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, image,
02395 CPL_BPP_IEEE_FLOAT, recipe_name, procatg_bpmdev,
02396 mypro_bpmdev, NULL, package, name_o));
02397 #endif
02398 } else
02399 skip_if(cpl_image_save(image,
02400 name_o, CPL_BPP_IEEE_FLOAT, xplist,
02401 CPL_IO_EXTEND));
02402
02403
02404 cpl_free(name_o);
02405 cpl_image_delete(image);
02406 image = NULL;
02407 name_o = NULL;
02408
02409
02410
02411
02412 if(detmon_ronbias_config.method_bitmask & PREOVERSCAN) {
02413
02414 if(!flag_sets) {
02415 name_o = cpl_sprintf("%s_synthetic.fits", recipe_name);
02416 assert(name_o != NULL);
02417 } else {
02418 name_o =
02419 cpl_sprintf("%s_synthetic_set%02d.fits", recipe_name,
02420 which_set);
02421 assert(name_o != NULL);
02422 }
02423
02424 if (whichext == 0) {
02425 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02426
02427 cpl_propertylist_append(mypro_synth, qclist);
02428
02429 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
02430 NULL,synthetic, CPL_BPP_IEEE_DOUBLE,
02431 recipe_name, mypro_synth, NULL,
02432 package, name_o));
02433 #else
02434
02435 const char * procatg_synth =
02436 cpl_propertylist_get_string(mypro_synth, CPL_DFS_PRO_CATG);
02437
02438 cpl_propertylist_append(mypro_synth, qclist);
02439
02440 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, synthetic,
02441 CPL_BPP_IEEE_DOUBLE, recipe_name,
02442 procatg_synth,
02443 mypro_synth, NULL, package, name_o));
02444 #endif
02445 } else
02446 skip_if(cpl_image_save(synthetic, name_o, CPL_BPP_IEEE_FLOAT,
02447 xplist, CPL_IO_EXTEND));
02448
02449
02450 cpl_free(name_o);
02451 name_o = NULL;
02452 }
02453
02454
02455
02456
02457 if (qclist) {
02458 paflist = cpl_propertylist_new();
02459
02460
02461 if(detmon_ronbias_config.exts >= 0) {
02462 skip_if((plist =
02463 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02464 detmon_ronbias_config.exts)) == NULL);
02465
02466 if(!flag_sets) {
02467 name_o = cpl_sprintf("%s.paf", recipe_name);
02468 assert(name_o != NULL);
02469 } else {
02470 name_o = cpl_sprintf("%s_set%02d.paf",
02471 recipe_name, which_set);
02472 assert(name_o != NULL);
02473 }
02474 } else {
02475 skip_if((plist =
02476 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02477 whichext)) == NULL);
02478
02479
02480 if(!flag_sets) {
02481 name_o = cpl_sprintf("%s_ext%02d.paf",
02482 recipe_name, whichext);
02483 assert(name_o != NULL);
02484 } else {
02485 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf",
02486 recipe_name,
02487 which_set, whichext);
02488 assert(name_o != NULL);
02489 }
02490 }
02491
02492
02493 skip_if(cpl_propertylist_copy_property_regexp(paflist, plist,
02494 pafregexp, 0));
02495 skip_if(cpl_propertylist_copy_property_regexp(paflist, mainplist,
02496 pafregexp, 0));
02497
02498 skip_if(cpl_propertylist_append(paflist, qclist));
02499
02500
02501 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, paflist, name_o));
02502
02503 }
02504
02505 end_skip;
02506
02507 cpl_propertylist_delete(plist);
02508 cpl_propertylist_delete(paflist);
02509 cpl_propertylist_delete(mainplist);
02510 cpl_propertylist_delete(xplist);
02511 cpl_free(name_o);
02512 cpl_image_delete(image);
02513
02514 cpl_propertylist_delete(mypro_master);
02515 cpl_propertylist_delete(mypro_synth);
02516 cpl_propertylist_delete(mypro_bpmhot);
02517 cpl_propertylist_delete(mypro_bpmcold);
02518 cpl_propertylist_delete(mypro_bpmdev);
02519
02520 return cpl_error_get_code();
02521 }
02522
02523 cpl_propertylist *
02524 detmon_fill_prolist(const char * procatg,
02525 const char * protype,
02526 const char * protech,
02527 cpl_boolean proscience)
02528 {
02529 cpl_propertylist * prolist = cpl_propertylist_new();
02530
02531 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_CATG, procatg);
02532 cpl_propertylist_append_bool(prolist, CPL_DFS_PRO_SCIENCE, proscience);
02533 if (protype)
02534 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TYPE, protype);
02535 if (protech)
02536 cpl_propertylist_append_string(prolist, CPL_DFS_PRO_TECH, protech);
02537
02538 return prolist;
02539 }
02540
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552 int
02553 detmon_ronbias_dfs_set_groups(cpl_frameset * set, const char *tag)
02554 {
02555 cpl_frame *cur_frame;
02556 const char *cur_tag;
02557 int nframes;
02558 int i;
02559
02560
02561 if(set == NULL)
02562 return -1;
02563
02564
02565 nframes = cpl_frameset_get_size(set);
02566
02567
02568 for(i = 0; i < nframes; i++) {
02569 cur_frame = cpl_frameset_get_frame(set, i);
02570 cur_tag = cpl_frame_get_tag(cur_frame);
02571
02572
02573 if(!strcmp(cur_tag, tag))
02574 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
02575
02576
02577
02578
02579
02580 }
02581 return 0;
02582 }
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
02593
02594
02595 cpl_image *
02596 detmon_build_synthetic(cpl_image * prescan, cpl_image * overscan)
02597 {
02598 cpl_size j;
02599
02600 int distance = detmon_ronbias_config.overscan_urx -
02601 detmon_ronbias_config.prescan_llx + 1;
02602
02603 double *mean_x =
02604 (double *) cpl_malloc(sizeof(double) * distance);
02605
02606 double *xvalues =
02607 (double *) cpl_malloc(sizeof(double) * distance);
02608
02609 cpl_vector *x = NULL;
02610 cpl_vector *y = NULL;
02611
02612 cpl_polynomial *poly = NULL;
02613 cpl_polynomial *poly2 = NULL;
02614
02615 cpl_matrix * samppos;
02616 cpl_vector * fitresidual;
02617
02618 double mse;
02619 cpl_size pows[2] = { 0, 0 };
02620
02621 cpl_image *synthetic = NULL;
02622
02623 double initial = 0;
02624
02625
02626 for(j = 0; j < distance; j++) {
02627 *(mean_x + j) = 0;
02628 *(xvalues + j) = j;
02629 }
02630
02631 for(j = 0; j < cpl_image_get_size_x(prescan); j++) {
02632 *(mean_x + j) =
02633 cpl_image_get_mean_window(prescan, j + 1, 1, j + 1,
02634 cpl_image_get_size_y(prescan));
02635 }
02636
02637 for(j = 0; j < cpl_image_get_size_x(overscan); j++) {
02638 *(mean_x + distance - cpl_image_get_size_x(overscan) + j) =
02639 cpl_image_get_mean_window(overscan, j + 1, 1, j + 1,
02640 cpl_image_get_size_y(overscan));
02641 }
02642
02643 x = cpl_vector_wrap(distance, xvalues);
02644 y = cpl_vector_wrap(distance, mean_x);
02645
02646 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
02647 poly = cpl_polynomial_new(1);
02648 samppos =
02649 cpl_matrix_wrap(1, cpl_vector_get_size(x), cpl_vector_get_data(x));
02650 fitresidual = cpl_vector_new(cpl_vector_get_size(x));
02651
02652 cpl_polynomial_fit(poly, samppos, NULL, y, NULL,
02653 CPL_FALSE, NULL,
02654 (cpl_size*)&(detmon_ronbias_config.preoverscan_degree));
02655
02656 cpl_vector_fill_polynomial_fit_residual(fitresidual, y, NULL, poly,
02657 samppos, NULL);
02658 cpl_matrix_unwrap(samppos);
02659 mse = cpl_vector_product(fitresidual, fitresidual)
02660 / cpl_vector_get_size(fitresidual);
02661
02662 cpl_vector_delete(fitresidual);
02663 #else
02664 poly =
02665 cpl_polynomial_fit_1d_create(x, y,
02666 detmon_ronbias_config.preoverscan_degree,
02667 &mse);
02668 #endif
02669
02670 cpl_vector_unwrap(x);
02671 cpl_vector_unwrap(y);
02672
02673 initial = *mean_x;
02674
02675 cpl_free(xvalues);
02676 cpl_free(mean_x);
02677
02678 poly2 = cpl_polynomial_new(2);
02679
02680 j = 0;
02681 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
02682
02683 pows[0] = 1;
02684 j = 1;
02685 cpl_polynomial_set_coeff(poly2, pows, cpl_polynomial_get_coeff(poly, &j));
02686
02687 cpl_polynomial_delete(poly);
02688
02689 synthetic =
02690 cpl_image_new(distance, cpl_image_get_size_y(prescan),
02691 CPL_TYPE_DOUBLE);
02692
02693 if(cpl_image_fill_polynomial(synthetic, poly2, initial, 1, 1, 1)) {
02694 cpl_msg_error(cpl_func, "Error creating the synthetic frame");
02695 cpl_polynomial_delete(poly2);
02696 return NULL;
02697 }
02698
02699 cpl_polynomial_delete(poly2);
02700
02701 return synthetic;
02702 }
02703
02704
02705
02706
02707
02708
02709
02710
02711
02712
02713
02714
02715 static cpl_error_code
02716 detmon_ronbias_dutycycl(const cpl_frameset * frameset,
02717 cpl_propertylist * qclist)
02718 {
02719 const cpl_frame *first = 0;
02720 cpl_propertylist *plistfirst = 0;
02721 double tfirst;
02722 int nraws;
02723 const cpl_frame *last = 0;
02724 cpl_propertylist *plistlast = 0;
02725 double tlast;
02726 double dutycycl;
02727 cpl_error_code error;
02728
02729 first = cpl_frameset_get_first_const(frameset);
02730 plistfirst = cpl_propertylist_load(cpl_frame_get_filename(first), 0);
02731 tfirst = cpl_propertylist_get_double(plistfirst, "MJD-OBS");
02732 nraws = cpl_frameset_get_size(frameset);
02733 last = cpl_frameset_get_frame_const(frameset, nraws - 1);
02734 plistlast = cpl_propertylist_load(cpl_frame_get_filename(last), 0);
02735 tlast = cpl_propertylist_get_double(plistlast, "MJD-OBS");
02736 dutycycl = (tlast - tfirst) / (nraws - 1);
02737
02738 error = cpl_error_get_code();
02739 if (error != CPL_ERROR_NONE)
02740 {
02741 goto cleanup;
02742 }
02743 cpl_propertylist_append_double(qclist,DETMON_QC_DUTYCYCL, dutycycl);
02744 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DUTYCYCL,
02745 DETMON_QC_DUTYCYCL_C);
02746
02747 cleanup:
02748
02749 cpl_propertylist_delete(plistfirst);
02750 cpl_propertylist_delete(plistlast);
02751
02752 return error;
02753 }
02754
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769 #define HORIZONTAL TRUE
02770
02771 cpl_table *
02772 detmon_pernoise_reduce(cpl_image * image)
02773 {
02774 int nsamples, nffts;
02775 int i, j;
02776
02777 int status;
02778 float * hanning = 0;
02779 float * data = 0;
02780 float * power = 0;
02781 cpl_image * power_im = 0;
02782 cpl_image * output = 0;
02783 cpl_image * pos_spec = 0;
02784 cpl_table * table = 0;
02785 cpl_image* fourier_im = 0;
02786 double freq;
02787 cpl_error_code error = CPL_ERROR_NONE;
02788 cpl_image * sub_image = 0;
02789 int nffts_old;
02790
02791
02792 if(detmon_pernoise_config.direction == HORIZONTAL) {
02793 error = cpl_image_flip(image, 1);
02794 cpl_ensure(!error, error, NULL);
02795 }
02796
02797 nsamples = cpl_image_get_size_x(image);
02798 nffts = cpl_image_get_size_y(image);
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809 error = detmon_pernoise_rm_bg(image, nsamples, nffts);
02810 cpl_ensure(!error, error, NULL);
02811
02812 sub_image = cpl_image_extract(image, nsamples/8 + 1, nffts/8+1,
02813 nsamples*7/8, nffts*7/8);
02814 nffts_old = nffts;
02815 nsamples = cpl_image_get_size_x(sub_image);
02816 nffts = cpl_image_get_size_y(sub_image);
02817
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829 hanning = cpl_malloc(sizeof(float) * nsamples);
02830
02831 for(i = 0; i < nsamples; i++) {
02832 *(hanning + i) = 0.5 - 0.5 * cos(2 * CPL_MATH_PI * (float) i / nsamples);
02833 for(j = 0; j < nffts; j++) {
02834 double value =
02835 cpl_image_get(sub_image, i + 1, j + 1, &status);
02836 error = cpl_image_set(sub_image, i + 1, j + 1, (*(hanning + i)) * value);
02837 }
02838 }
02839
02840 cpl_free(hanning);
02841 if (error != CPL_ERROR_NONE)
02842 {
02843 goto cleanup;
02844 }
02845 data = cpl_image_get_data_float(sub_image);
02846
02847 power = (float *) cpl_calloc(sizeof(float), nsamples * nffts);
02848
02849
02850 fourier_im = cpl_image_new(nsamples,nffts, CPL_TYPE_FLOAT_COMPLEX);
02851 error = cpl_fft_image(fourier_im, sub_image, CPL_FFT_FORWARD);
02852
02853
02854
02855
02856
02857
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870 for(i = 1; i <= nffts; i++) {
02871 for(j = 1; j <= nsamples; j++) {
02872 int rej = 0;
02873 double complex cvalue = cpl_image_get_complex(fourier_im,j, i, &rej );
02874 double value = cabs(cvalue);
02875
02876
02877
02878
02879 cpl_image_set(power_im, j, i, value);
02880 }
02881
02882 }
02883 cpl_image_delete(fourier_im);
02884
02885
02886
02887
02888
02889
02890 output = cpl_image_collapse_create(power_im, 0);
02891 pos_spec = cpl_image_extract(output, 1, 1, nsamples/2, 1);
02892
02893
02894 cpl_image_delete(power_im);
02895 cpl_free(power);
02896
02897 cpl_image_delete(output);
02898
02899 table = cpl_table_new(nsamples/2);
02900 cpl_table_new_column(table, "FREQ", CPL_TYPE_DOUBLE);
02901 cpl_table_new_column(table, "POW", CPL_TYPE_DOUBLE);
02902
02903 freq = detmon_pernoise_config.speed*1000/nffts_old;
02904
02905 for(i = 0; i < nsamples/2; i++) {
02906 error = cpl_table_set(table, "FREQ", i, freq/(nsamples/2)*i);
02907 error = cpl_table_set(table, "POW", i, cpl_image_get(pos_spec, i+1, 1, &status));
02908 }
02909
02910 for(i= 0; i < 5; i++) {
02911 error = cpl_table_set(table, "POW", i, 0.0);
02912 }
02913
02914
02915 cleanup:
02916 cpl_image_delete(pos_spec);
02917
02918 cpl_image_delete(sub_image);
02919 if (error != CPL_ERROR_NONE)
02920 {
02921 cpl_table_delete(table);
02922 table = 0;
02923 }
02924 return table;
02925 }
02926 #undef HORIZONTAL
02927
02928
02929
02930
02931
02932
02933
02934
02935
02936
02937
02938
02939
02940
02941
02942
02943 cpl_error_code
02944 detmon_rm_bpixs(cpl_image ** image,
02945 const double kappa, int nffts, int nsamples)
02946 {
02947 int i, j;
02948
02949 float *data = cpl_image_get_data_float(*image);
02950 int k = 0;
02951 for(i = 0; i < nffts; i++) {
02952 for(j = 0; j < nsamples; j++) {
02953 float neighbours = 0;
02954 int nneighs = 0;
02955 float average = 0;
02956
02957
02958
02959
02960
02961
02962 if(i > 0) {
02963 neighbours += *(data + (i - 1) * nsamples + j);
02964 nneighs++;
02965 }
02966 if(i < nffts - 1) {
02967 neighbours += *(data + (i + 1) * nsamples + j);
02968 nneighs++;
02969 }
02970 if(j > 0) {
02971 neighbours += *(data + i * nsamples + (j - 1));
02972 nneighs++;
02973 }
02974 if(j < nsamples - 1) {
02975 neighbours += *(data + i * nsamples + (j + 1));
02976 nneighs++;
02977 }
02978 average = neighbours / nneighs;
02979 if(average > 0) {
02980 if(*(data + i * nsamples + j) < average * (-1 * kappa) ||
02981 *(data + i * nsamples + j) > average * (kappa)) {
02982 k++;
02983 *(data + i * nsamples + j) = average;
02984 }
02985 }
02986 if(average < 0) {
02987 if(*(data + i * nsamples + j) > average * (-1 * kappa) ||
02988 *(data + i * nsamples + j) < average * (kappa)) {
02989 k++;
02990 *(data + i * nsamples + j) = average;
02991 }
02992 }
02993
02994 }
02995 }
02996
02997
02998 return cpl_error_get_code();
02999
03000 }
03001
03002
03003
03004 #define RECT_RON_HS 4
03005 #define RECT_RON_SAMPLES 100
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018 cpl_error_code
03019 irplib_flux_get_bias_window(const cpl_image * diff,
03020 const int *zone_def,
03021 int ron_hsize,
03022 int ron_nsamp, double *bias, double *error)
03023 {
03024 const int hsize = ron_hsize < 0 ? RECT_RON_HS : ron_hsize;
03025 const int nsamples =
03026 ron_nsamp < 0 ? RECT_RON_SAMPLES : ron_nsamp;
03027 cpl_bivector *sample_reg;
03028 cpl_vector *rms_list;
03029 int rect[4];
03030 int zone[4];
03031 double *px;
03032 double *py;
03033 double *pr;
03034 int i;
03035
03036
03037 cpl_ensure_code(diff && bias, CPL_ERROR_NULL_INPUT);
03038
03039
03040 if(zone_def != NULL) {
03041 rect[0] = zone_def[0] + hsize + 1;
03042 rect[1] = zone_def[1] - hsize - 1;
03043 rect[2] = zone_def[2] + hsize + 1;
03044 rect[3] = zone_def[3] - hsize - 1;
03045 } else {
03046 rect[0] = hsize + 1;
03047 rect[1] = cpl_image_get_size_x(diff) - hsize - 1;
03048 rect[2] = hsize + 1;
03049 rect[3] = cpl_image_get_size_y(diff) - hsize - 1;
03050 }
03051
03052 cpl_ensure_code(rect[0] < rect[1] && rect[2] < rect[3],
03053 CPL_ERROR_ILLEGAL_INPUT);
03054
03055
03056
03057 sample_reg =
03058 irplib_bivector_gen_rect_poisson(rect, nsamples + 1, nsamples + 1);
03059 cpl_ensure(sample_reg != NULL, CPL_ERROR_ILLEGAL_INPUT,
03060 CPL_ERROR_ILLEGAL_INPUT);
03061
03062 px = cpl_bivector_get_x_data(sample_reg);
03063 py = cpl_bivector_get_y_data(sample_reg);
03064
03065
03066
03067 rms_list = cpl_vector_new(nsamples);
03068 cpl_ensure(rms_list != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
03069 pr = cpl_vector_get_data(rms_list);
03070
03071 for(i = 0; i < nsamples; i++) {
03072 zone[0] = (int) px[i + 1] - hsize;
03073 zone[1] = (int) px[i + 1] + hsize;
03074 zone[2] = (int) py[i + 1] - hsize;
03075 zone[3] = (int) py[i + 1] + hsize;
03076 pr[i] = cpl_image_get_mean_window(diff,
03077 zone[0], zone[2], zone[1], zone[3]);
03078 }
03079 cpl_bivector_delete(sample_reg);
03080
03081
03082 if(error != NULL)
03083 *error = cpl_vector_get_stdev(rms_list);
03084
03085
03086
03087 *bias = cpl_vector_get_median(rms_list);
03088
03089 cpl_vector_delete(rms_list);
03090
03091 return CPL_ERROR_NONE;
03092 }
03093
03094 #undef RECT_RON_HS
03095 #undef RECT_RON_SAMPLES
03096
03097
03098
03099
03100
03101
03102
03103
03104
03105
03106
03107
03108 static cpl_bivector *
03109 irplib_bivector_gen_rect_poisson(const int *r, const int np, const int homog)
03110 {
03111 double min_dist;
03112 int i;
03113 int gnp;
03114 cpl_bivector *list;
03115 double cand_x, cand_y;
03116 int ok;
03117 int start_ndx;
03118 int xmin, xmax, ymin, ymax;
03119
03120
03121 const int homogc = 0 < homog && homog < np ? homog : np;
03122 double *px;
03123 double *py;
03124
03125
03126 cpl_ensure(r, CPL_ERROR_NULL_INPUT, NULL);
03127 cpl_ensure(np > 0, CPL_ERROR_ILLEGAL_INPUT, NULL);
03128
03129 list = cpl_bivector_new(np);
03130 cpl_ensure(list, CPL_ERROR_NULL_INPUT, NULL);
03131 px = cpl_bivector_get_x_data(list);
03132 py = cpl_bivector_get_y_data(list);
03133
03134 xmin = r[0];
03135 xmax = r[1];
03136 ymin = r[2];
03137 ymax = r[3];
03138
03139 min_dist =
03140 CPL_MATH_SQRT1_2 * ((xmax - xmin) * (ymax - ymin) / (double) (homogc + 1));
03141 gnp = 1;
03142 px[0] = 0;
03143 py[0] = 0;
03144
03145
03146 while(gnp < homogc) {
03147
03148 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03149 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03150
03151
03152 ok = 1;
03153 for(i = 0; i < gnp; i++) {
03154 if(pdist(cand_x, cand_y, px[i], py[i]) < min_dist) {
03155
03156 ok = 0;
03157 break;
03158 }
03159 }
03160 if(ok) {
03161
03162 px[gnp] = cand_x;
03163 py[gnp] = cand_y;
03164 gnp++;
03165 }
03166 }
03167
03168
03169
03170 start_ndx = 0;
03171 while(gnp < np) {
03172
03173 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03174 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03175
03176
03177 ok = 1;
03178 for(i = 0; i < homogc; i++) {
03179 if(pdist(cand_x,
03180 cand_y,
03181 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03182
03183 ok = 0;
03184 break;
03185 }
03186 }
03187 if(ok) {
03188
03189 px[gnp] = cand_x;
03190 py[gnp] = cand_y;
03191 gnp++;
03192 }
03193 }
03194
03195
03196
03197 start_ndx = 0;
03198 while(gnp < np) {
03199
03200 cand_x = cpl_drand() * (xmax - xmin) + xmin;
03201 cand_y = cpl_drand() * (ymax - ymin) + ymin;
03202
03203
03204 ok = 1;
03205 for(i = 0; i < homogc; i++) {
03206 if(pdist(cand_x,
03207 cand_y,
03208 px[start_ndx + i], py[start_ndx + i]) < min_dist) {
03209
03210 ok = 0;
03211 break;
03212 }
03213 }
03214 if(ok) {
03215
03216 px[gnp] = cand_x;
03217 py[gnp] = cand_y;
03218 gnp++;
03219 start_ndx++;
03220 }
03221 }
03222 return list;
03223 }
03224
03225
03226
03227
03228
03229
03230
03231
03232
03233
03234
03235
03236
03237
03238 cpl_error_code
03239 detmon_pernoise(cpl_frameset * frameset,
03240 const cpl_parameterlist * parlist,
03241 const char * tag,
03242 const char * recipe_name,
03243 const char * pipeline_name,
03244 const char * procatg_tbl,
03245 const char * package,
03246 int (*compare)(const cpl_frame *,
03247 const cpl_frame *))
03248 {
03249 cpl_size nsets;
03250 cpl_size *selection = NULL;
03251 int i;
03252 cpl_error_code error;
03253
03254 if(detmon_pernoise_dfs_set_groups(frameset, tag)) {
03255 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
03256 }
03257
03258
03259
03260
03261
03262
03263 error = detmon_pernoise_retrieve_parlist(pipeline_name,
03264 recipe_name, parlist);
03265 cpl_ensure_code(!error, error);
03266
03267
03268 if(compare == NULL)
03269 nsets = 1;
03270 else {
03271 cpl_msg_info(cpl_func, "Identify the different settings");
03272 selection = cpl_frameset_labelise(frameset, compare, &nsets);
03273 if(selection == NULL)
03274 cpl_msg_error(cpl_func, "Cannot labelise input frames");
03275 }
03276
03277 detmon_pernoise_config.nb_extensions = 1;
03278 if(detmon_pernoise_config.exts < 0) {
03279 const cpl_frame *cur_frame =
03280 cpl_frameset_get_first_const(frameset);
03281
03282 detmon_pernoise_config.nb_extensions =
03283 cpl_frame_get_nextensions(cur_frame);
03284 }
03285
03286
03287 for(i = 0; i < nsets; i++)
03288 {
03289 int j;
03290 cpl_table ** freq_table;
03291 cpl_propertylist ** qclist =
03292 (cpl_propertylist **)
03293 cpl_malloc(detmon_pernoise_config.nb_extensions *
03294 sizeof(cpl_propertylist *));
03295
03296 cpl_imagelist ** raws = (cpl_imagelist **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_imagelist *));
03297 cpl_image ** input = (cpl_image **) cpl_malloc(detmon_pernoise_config.nb_extensions * sizeof(cpl_image *));
03298
03299
03300 if(detmon_pernoise_config.mode == 1)
03301 {
03302 freq_table =
03303 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03304 4 * sizeof(cpl_table *));
03305 } else
03306 {
03307 freq_table =
03308 (cpl_table **) cpl_malloc(detmon_pernoise_config.nb_extensions *
03309 sizeof(cpl_table *));
03310 }
03311
03312 if(detmon_pernoise_config.exts >= 0)
03313 {
03314 *raws =
03315 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03316 detmon_pernoise_config.exts);
03317 *input = cpl_image_subtract_create(cpl_imagelist_get(*raws,0),
03318 cpl_imagelist_get(*raws,1));
03319 } else
03320 {
03321 cpl_imagelist *raws_all_exts =
03322 cpl_imagelist_load_frameset(frameset, CPL_TYPE_FLOAT, 1,
03323 -1);
03324 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
03325 {
03326 int nframes = cpl_frameset_get_size(frameset);
03327 int k;
03328 for(k = 0; k < nframes; k++)
03329 {
03330 cpl_image *image =
03331 cpl_imagelist_unset(raws_all_exts,
03332 (detmon_pernoise_config.
03333 nb_extensions - 1 - j) * k);
03334 cpl_imagelist_set(raws[j], image, k);
03335 }
03336 input[j] =
03337 cpl_image_subtract_create(cpl_imagelist_get(raws[j],0),
03338 cpl_imagelist_get(raws[j],1));
03339 }
03340 }
03341
03342 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++) {
03343 cpl_msg_info(cpl_func, "Starting reduction");
03344 qclist[j] = cpl_propertylist_new();
03345 if(detmon_pernoise_config.mode == 1)
03346 {
03347 int nx = cpl_image_get_size_x(input[j]);
03348 int ny = cpl_image_get_size_y(input[j]);
03349 int k = 0;
03350 cpl_image* quad[4];
03351
03352 quad[0] = cpl_image_extract(input[j], 1, 1, nx/2, ny/2);
03353 quad[1] = cpl_image_extract(input[j], 1, ny/2+1, nx/2, ny);
03354 quad[2] = cpl_image_extract(input[j], nx/2+1, 1, nx, ny/2);
03355 quad[3] = cpl_image_extract(input[j], nx/2+1, ny/2+1, nx, ny);
03356
03357 for (k = 0; k < 4; k++)
03358 {
03359 freq_table[j * 4 + k] = detmon_pernoise_reduce(quad[k]);
03360 }
03361 for(k = 0; k < 4; k++)
03362 {
03363 error = detmon_pernoise_qc(qclist[j], freq_table[j + k], k+1);
03364 if (error != CPL_ERROR_NONE)
03365 break;
03366 }
03367 for (k = 0; k < 4; k++)
03368 {
03369 cpl_image_delete(quad[k]);
03370 }
03371 } else
03372 {
03373 freq_table[j] = detmon_pernoise_reduce(input[j]);
03374 if(freq_table[j] != NULL)
03375 {
03376 error = detmon_pernoise_qc(qclist[j], freq_table[j], 0);
03377 }
03378 }
03379 if (error != CPL_ERROR_NONE)
03380 {
03381 break;
03382 }
03383 }
03384 if (error == CPL_ERROR_NONE)
03385 {
03386 error = detmon_pernoise_save(parlist, frameset, recipe_name,
03387 pipeline_name, procatg_tbl,
03388 package, freq_table, qclist, 0,
03389 0, frameset);
03390 }
03391
03392 for(j = 0; j < detmon_pernoise_config.nb_extensions; j++)
03393 {
03394 cpl_propertylist_delete(qclist[j]);
03395 cpl_imagelist_delete(raws[j]);
03396 cpl_image_delete(input[j]);
03397 }
03398 cpl_free(qclist);
03399 cpl_free(raws);
03400 cpl_free(input);
03401 if(detmon_pernoise_config.mode == 1)
03402 {
03403 for(j= 0; j < detmon_pernoise_config.nb_extensions * 4; j++) {
03404 cpl_table_delete(freq_table[j]);
03405 }
03406 } else {
03407 for(j= 0; j < detmon_pernoise_config.nb_extensions; j++) {
03408 cpl_table_delete(freq_table[j]);
03409 }
03410 }
03411 cpl_free(freq_table);
03412 if (error != CPL_ERROR_NONE)
03413 {
03414 break;
03415 }
03416 }
03417
03418 return cpl_error_get_code();
03419 }
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429
03430
03431
03432 int
03433 detmon_pernoise_dfs_set_groups(cpl_frameset * set, const char *tag)
03434 {
03435 cpl_frame *cur_frame;
03436 const char *cur_tag;
03437 int nframes;
03438 int i;
03439
03440
03441 if(set == NULL)
03442 return -1;
03443
03444
03445 nframes = cpl_frameset_get_size(set);
03446
03447
03448 for(i = 0; i < nframes; i++) {
03449 cur_frame = cpl_frameset_get_frame(set, i);
03450 cur_tag = cpl_frame_get_tag(cur_frame);
03451
03452
03453 if(!strcmp(cur_tag, tag))
03454 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
03455
03456
03457
03458
03459
03460 }
03461 return 0;
03462 }
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475 cpl_error_code
03476 detmon_fill_pernoise_params(cpl_parameterlist * parlist,
03477 const char *recipe_name,
03478 const char *pipeline_name,
03479 int mode,
03480 const char * direction,
03481 double speed,
03482 int llx,
03483 int lly,
03484 int urx,
03485 int ury,
03486 double kappa,
03487 int exts)
03488 {
03489 detmon_fill_parlist(parlist, recipe_name, pipeline_name, 9,
03490
03491 "mode",
03492 "Mode",
03493 "CPL_TYPE_INT", mode,
03494
03495 "direction",
03496 "Readout direction",
03497 "CPL_TYPE_BOOL", direction,
03498
03499 "speed",
03500 "Readout speed",
03501 "CPL_TYPE_DOUBLE", speed,
03502
03503 "llx",
03504 "(yet unsupported) x coordinate of the lower-left "
03505 "point of the region of interest. If not modified, default value will be 1.",
03506 "CPL_TYPE_INT", llx,
03507 "lly",
03508 "(yet unsupported) y coordinate of the lower-left "
03509 "point of the region of interest. If not modified, default value will be 1.",
03510 "CPL_TYPE_INT", lly,
03511 "urx",
03512 "(yet unsupported) x coordinate of the upper-right "
03513 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
03514 "CPL_TYPE_INT", urx,
03515 "ury",
03516 "(yet unsupported) y coordinate of the upper-right "
03517 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
03518 "CPL_TYPE_INT", ury,
03519
03520 "kappa",
03521 "Kappa used for determining threshold of bad (hot, cold) pixels",
03522 "CPL_TYPE_DOUBLE", kappa,
03523
03524 "exts",
03525 "Activate the multi-exts option",
03526 "CPL_TYPE_INT", exts);
03527
03528 return 0;
03529 }
03530
03531
03532
03533
03534
03535
03536
03537
03538
03539
03540
03541
03542 int
03543 detmon_fill_pernoise_params_default(cpl_parameterlist * parlist,
03544 const char *recipe_name,
03545 const char *pipeline_name)
03546 {
03547 detmon_fill_pernoise_params(parlist, recipe_name, pipeline_name,
03548 1,
03549 "CPL_TRUE",
03550 84.5,
03551 -1,
03552 -1,
03553 -1,
03554 -1,
03555 100,
03556 0);
03557
03558 return 0;
03559
03560 }
03561
03562
03563 static cpl_error_code
03564 detmon_pernoise_retrieve_parlist(const char *pipeline_name,
03565 const char *recipe_name,
03566 const cpl_parameterlist * parlist)
03567 {
03568 char *par_name;
03569 cpl_parameter *par;
03570
03571
03572 detmon_pernoise_config.mode =
03573 detmon_retrieve_par_int("mode", pipeline_name, recipe_name,
03574 parlist);
03575
03576
03577 par_name = cpl_sprintf("%s.%s.direction", pipeline_name, recipe_name);
03578 assert(par_name != NULL);
03579 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03580 detmon_pernoise_config.direction = cpl_parameter_get_bool(par);
03581 cpl_free(par_name);
03582
03583
03584 par_name = cpl_sprintf("%s.%s.speed", pipeline_name, recipe_name);
03585 assert(par_name != NULL);
03586 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
03587 detmon_pernoise_config.speed = cpl_parameter_get_double(par);
03588 cpl_free(par_name);
03589
03590
03591 detmon_pernoise_config.llx =
03592 detmon_retrieve_par_int("llx", pipeline_name, recipe_name,
03593 parlist);
03594
03595
03596 detmon_pernoise_config.lly =
03597 detmon_retrieve_par_int("lly", pipeline_name, recipe_name,
03598 parlist);
03599
03600 detmon_pernoise_config.urx =
03601 detmon_retrieve_par_int("urx", pipeline_name, recipe_name,
03602 parlist);
03603
03604 detmon_pernoise_config.ury =
03605 detmon_retrieve_par_int("ury", pipeline_name, recipe_name,
03606 parlist);
03607
03608 detmon_pernoise_config.kappa =
03609 detmon_retrieve_par_double("kappa", pipeline_name, recipe_name,
03610 parlist);
03611
03612
03613 detmon_pernoise_config.exts =
03614 detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
03615 parlist);
03616
03617 if(cpl_error_get_code()) {
03618 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
03619 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
03620 }
03621
03622 return cpl_error_get_code();
03623 }
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636 static cpl_error_code
03637 detmon_pernoise_save(const cpl_parameterlist * parlist,
03638 cpl_frameset * frameset,
03639 const char *recipe_name,
03640 const char *pipeline_name,
03641 const char *procatg_tbl,
03642 const char *package,
03643 cpl_table ** freq_table,
03644 cpl_propertylist ** qclist,
03645 const int flag_sets,
03646 const int which_set,
03647 const cpl_frameset * usedframes)
03648 {
03649
03650 cpl_frame *ref_frame;
03651 cpl_propertylist *plist;
03652 char *name_o = NULL;
03653 int i, j;
03654 cpl_propertylist *paflist;
03655 cpl_error_code error;
03656
03657 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03658 cpl_propertylist * pro_tbl = cpl_propertylist_new();
03659
03660 cpl_propertylist_append_string(pro_tbl,
03661 CPL_DFS_PRO_CATG, procatg_tbl);
03662
03663 cpl_propertylist_append(pro_tbl, qclist[0]);
03664
03665 #endif
03666
03667
03668
03669
03670
03671 if(detmon_pernoise_config.mode != 1) {
03672
03673 if(!flag_sets) {
03674 name_o = cpl_sprintf("%s_freq_table.fits", recipe_name);
03675 assert(name_o != NULL);
03676 } else {
03677 name_o =
03678 cpl_sprintf("%s_freq_table_set%02d.fits", recipe_name,
03679 which_set);
03680 assert(name_o != NULL);
03681 }
03682
03683 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03684
03685 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, freq_table[0],
03686 NULL, recipe_name, pro_tbl, NULL,
03687 package, name_o)) {
03688 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03689 cpl_free(name_o);
03690 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03691 }
03692 #else
03693
03694 if(cpl_dfs_save_table(frameset, parlist, usedframes, freq_table[0],
03695 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03696 package, name_o)) {
03697 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03698 cpl_free(name_o);
03699 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03700 }
03701 #endif
03702
03703 if(detmon_pernoise_config.exts < 0) {
03704
03705 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03706 error =
03707 cpl_table_save(freq_table[i], NULL, qclist[i], name_o,
03708 CPL_IO_EXTEND);
03709 cpl_ensure_code(!error, error);
03710 }
03711 }
03712
03713
03714 cpl_free(name_o);
03715
03716 } else {
03717 for (j = 1; j <= 4; j++) {
03718
03719 if(!flag_sets) {
03720 name_o = cpl_sprintf("%s_freq_table_quad%02d.fits",
03721 recipe_name, j);
03722 assert(name_o != NULL);
03723 } else {
03724 name_o =
03725 cpl_sprintf("%s_freq_table_quad%02d_set%02d.fits",
03726 recipe_name, j, which_set);
03727 assert(name_o != NULL);
03728 }
03729
03730 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03731
03732 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
03733 freq_table[j - 1],
03734 NULL, recipe_name, pro_tbl, NULL,
03735 package, name_o)) {
03736 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03737 cpl_free(name_o);
03738 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03739 }
03740 #else
03741
03742 if(cpl_dfs_save_table(frameset, parlist, usedframes,
03743 freq_table[j - 1],
03744 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
03745 package, name_o)) {
03746 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03747 cpl_free(name_o);
03748 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03749 }
03750 #endif
03751
03752 if(detmon_pernoise_config.exts < 0) {
03753 for(i = 1; i < detmon_pernoise_config.nb_extensions; i++) {
03754 error = cpl_table_save(freq_table[(j-1) + 4 * i],
03755 NULL, qclist[i], name_o,
03756 CPL_IO_EXTEND);
03757 cpl_ensure_code(!error, error);
03758 }
03759 }
03760
03761
03762 cpl_free(name_o);
03763 }
03764
03765 }
03766
03767
03768
03769
03770
03771 ref_frame = cpl_frameset_get_first(frameset);
03772 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03773 0)) == NULL) {
03774 cpl_msg_error(cpl_func, "getting header from reference frame");
03775 cpl_ensure_code(0, cpl_error_get_code());
03776 }
03777
03778
03779 paflist = cpl_propertylist_new();
03780 cpl_propertylist_copy_property_regexp(paflist, plist,
03781 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
03782 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
03783 "ESO DET NCORRS|"
03784 "ESO DET MODE NAME)$", 0);
03785
03786 for(i = 0; i < detmon_pernoise_config.nb_extensions; i++) {
03787 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
03788 error = cpl_propertylist_append(c_paflist, qclist[i]);
03789 cpl_ensure_code(!error, error);
03790
03791
03792 if(detmon_pernoise_config.exts >= 0) {
03793 if(!flag_sets) {
03794 name_o = cpl_sprintf("%s.paf", recipe_name);
03795 assert(name_o != NULL);
03796 } else {
03797 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
03798 assert(name_o != NULL);
03799 }
03800 } else {
03801 if(!flag_sets) {
03802 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
03803 assert(name_o != NULL);
03804 } else {
03805 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
03806 assert(name_o != NULL);
03807 }
03808 }
03809
03810 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
03811 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03812 cpl_free(name_o);
03813 cpl_propertylist_delete(paflist);
03814 cpl_propertylist_delete(plist);
03815 cpl_free(name_o);
03816 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03817 }
03818 cpl_propertylist_delete(c_paflist);
03819 cpl_free(name_o);
03820 }
03821
03822 cpl_propertylist_delete(plist);
03823 cpl_propertylist_delete(paflist);
03824 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03825 cpl_propertylist_delete(pro_tbl);
03826 #endif
03827 return cpl_error_get_code();
03828 }
03829
03830 static cpl_error_code
03831 detmon_pernoise_qc(cpl_propertylist * qclist,
03832 cpl_table * table,
03833 int iquad)
03834 {
03835 cpl_error_code error;
03836 char * propname;
03837
03838 double freqs[3] = {0, 0, 0};
03839 double pows[3] = {0, 0, 0};
03840
03841
03842
03843
03844
03845
03846
03847
03848 int nrows = cpl_table_get_nrow(table);
03849 int i;
03850
03851 double * all_freqs = cpl_table_get_data_double(table, "FREQ");
03852 double * all_pows = cpl_table_get_data_double(table, "POW");
03853
03854 for ( i= 1; i< nrows-1; i++){
03855 if (all_pows[i] > pows[0]) {
03856 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
03857 pows[2]=pows[1];
03858 pows[1]=pows[0];
03859 pows[0]=all_pows[i];
03860
03861 freqs[2]=freqs[1];
03862 freqs[1]=freqs[0];
03863 freqs[0]=all_freqs[i];
03864 }
03865 } else if (all_pows[i] > pows[1]) {
03866 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
03867 pows[2]=pows[1];
03868 pows[1]=all_pows[i];
03869
03870 freqs[2]=freqs[1];
03871 freqs[1]=all_freqs[i];
03872 }
03873
03874 } else if(all_pows[i] > pows[2]) {
03875 if(all_pows[i-1] < all_pows[i] && all_pows[i] > all_pows[i+1]){
03876 pows[2]=all_pows[i];
03877
03878 freqs[2]=all_freqs[i];
03879 }
03880
03881 }
03882 }
03883
03884 if (detmon_pernoise_config.mode == 1) {
03885 propname = cpl_sprintf("ESO QC FREQ1 %d", iquad);
03886 assert(propname != NULL);
03887 } else {
03888 propname = cpl_sprintf("ESO QC FREQ1");
03889 }
03890
03891 error = cpl_propertylist_append_double(qclist, propname, freqs[0]);
03892 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
03893 cpl_ensure_code(!error, error);
03894
03895 cpl_free(propname);
03896
03897 if (detmon_pernoise_config.mode == 1) {
03898 propname = cpl_sprintf("ESO QC FREQ2 %d", iquad);
03899 assert(propname != NULL);
03900 } else {
03901 propname = cpl_sprintf("ESO QC FREQ2");
03902 }
03903
03904 error = cpl_propertylist_append_double(qclist, propname, freqs[1]);
03905 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
03906 cpl_ensure_code(!error, error);
03907
03908 cpl_free(propname);
03909
03910 if (detmon_pernoise_config.mode == 1) {
03911 propname = cpl_sprintf("ESO QC FREQ3 %d", iquad);
03912 assert(propname != NULL);
03913 } else {
03914 propname = cpl_sprintf("ESO QC FREQ3");
03915 }
03916
03917 error = cpl_propertylist_append_double(qclist, propname, freqs[2]);
03918 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_FREQ_C);
03919 cpl_ensure_code(!error, error);
03920
03921 cpl_free(propname);
03922
03923 if (detmon_pernoise_config.mode == 1) {
03924 propname = cpl_sprintf("ESO QC POW1 %d", iquad);
03925 assert(propname != NULL);
03926 } else {
03927 propname = cpl_sprintf("ESO QC POW1");
03928 }
03929
03930 error = cpl_propertylist_append_double(qclist, propname, pows[0]);
03931 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
03932 cpl_ensure_code(!error, error);
03933
03934 cpl_free(propname);
03935
03936 if (detmon_pernoise_config.mode == 1) {
03937 propname = cpl_sprintf("ESO QC POW2 %d", iquad);
03938 assert(propname != NULL);
03939 } else {
03940 propname = cpl_sprintf("ESO QC POW2");
03941 }
03942
03943 error = cpl_propertylist_append_double(qclist, propname, pows[1]);
03944 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
03945 cpl_ensure_code(!error, error);
03946
03947 cpl_free(propname);
03948
03949 if (detmon_pernoise_config.mode == 1) {
03950 propname = cpl_sprintf("ESO QC POW3 %d", iquad);
03951 assert(propname != NULL);
03952 } else {
03953 propname = cpl_sprintf("ESO QC POW3");
03954 }
03955
03956 error = cpl_propertylist_append_double(qclist, propname, pows[2]);
03957 error = cpl_propertylist_set_comment(qclist,propname,DETMON_QC_POW_C);
03958 cpl_ensure_code(!error, error);
03959
03960
03961 cpl_free(propname);
03962
03963 return cpl_error_get_code();
03964 }
03965
03966
03967
03968
03969
03970
03971
03972
03973
03974
03975
03976
03977 cpl_error_code
03978 detmon_pernoise_rm_bg(cpl_image * image, int nsamples, int nffts)
03979 {
03980 cpl_vector *values = cpl_vector_new(nsamples * nffts);
03981
03982 int rejected;
03983 int i, j;
03984 cpl_vector *xy_pos = cpl_vector_new(nsamples * nffts * 2);
03985 double mse = 0;
03986 cpl_polynomial * poly_2d = 0;
03987 cpl_image * poly_ima = 0;
03988 cpl_size degree = 3;
03989 cpl_error_code error = CPL_ERROR_NONE;
03990 cpl_matrix * samppos = 0;
03991 cpl_vector * fitresidual = 0;
03992
03993 for(i = 1; i <= nffts; i++) {
03994 for(j = 1; j <= nsamples; j++) {
03995 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1), j);
03996 cpl_vector_set(xy_pos, (i - 1) * nsamples + (j - 1) + nsamples * nffts, i);
03997 cpl_vector_set(values, (i - 1) * nsamples + (j - 1),
03998 cpl_image_get(image, j, i, &rejected));
03999 error = cpl_error_get_code();
04000 if (error != CPL_ERROR_NONE)
04001 {
04002 break;
04003 }
04004 }
04005 if (error != CPL_ERROR_NONE)
04006 {
04007 break;
04008 }
04009 }
04010 if (error != CPL_ERROR_NONE)
04011 {
04012 goto cleanup;
04013 }
04014 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04015 poly_2d = cpl_polynomial_new(2);
04016 samppos =
04017 cpl_matrix_wrap(2, nsamples * nffts, cpl_vector_get_data(xy_pos));
04018 fitresidual = cpl_vector_new(nsamples * nffts);
04019 cpl_polynomial_fit(poly_2d, samppos, NULL, values, NULL,
04020 CPL_FALSE, NULL, °ree);
04021
04022 cpl_vector_fill_polynomial_fit_residual(fitresidual, values, NULL, poly_2d,
04023 samppos, NULL);
04024 cpl_matrix_unwrap(samppos);
04025 mse = cpl_vector_product(fitresidual, fitresidual)
04026 / cpl_vector_get_size(fitresidual);
04027 cpl_vector_delete(fitresidual);
04028
04029 #else
04030 poly_2d = cpl_polynomial_fit_2d_create(xy_pos, values, 3, &mse);
04031 #endif
04032
04033 poly_ima = cpl_image_new(nsamples, nffts, CPL_TYPE_FLOAT);
04034
04035 cpl_image_fill_polynomial(poly_ima, poly_2d, 1, 1, 1, 1);
04036
04037 cpl_image_subtract(image, poly_ima);
04038
04039 cleanup:
04040 cpl_polynomial_delete(poly_2d);
04041 cpl_image_delete(poly_ima);
04042 cpl_vector_delete(xy_pos);
04043 cpl_vector_delete(values);
04044
04045 return cpl_error_get_code();
04046 }
04047
04048
04049
04050
04051
04052
04053
04054
04055
04056
04057
04058
04059 cpl_error_code
04060 detmon_dark(cpl_frameset * frameset,
04061 const cpl_parameterlist * parlist,
04062 const char * tag,
04063 const char * recipe_name,
04064 const char * pipeline_name,
04065 const char * procatg_master,
04066 const char * procatg_dsnu,
04067 const char * procatg_tbl,
04068 const char * package,
04069 int (*compare)(const cpl_frame *,
04070 const cpl_frame *))
04071 {
04072 cpl_size nsets;
04073 cpl_size *selection = NULL;
04074 int i;
04075 cpl_error_code error;
04076
04077 if(detmon_dark_dfs_set_groups(frameset, tag)) {
04078 cpl_msg_error(cpl_func, "Cannot identify RAW and CALIB frames");
04079 }
04080
04081
04082
04083
04084
04085
04086 error = detmon_retrieve_dark_params(pipeline_name,
04087 recipe_name, parlist);
04088 cpl_ensure_code(!error, error);
04089
04090
04091 if(compare == NULL)
04092 nsets = 1;
04093 else {
04094 cpl_msg_info(cpl_func, "Identify the different settings");
04095 selection = cpl_frameset_labelise(frameset, compare, &nsets);
04096 if(selection == NULL)
04097 cpl_msg_error(cpl_func, "Cannot labelise input frames");
04098 }
04099
04100 detmon_dark_config.nb_extensions = 1;
04101 if(detmon_dark_config.exts < 0) {
04102 const cpl_frame *cur_frame =
04103 cpl_frameset_get_first_const(frameset);
04104
04105 detmon_dark_config.nb_extensions =
04106 cpl_frame_get_nextensions(cur_frame);
04107 }
04108
04109
04110 for(i = 0; i < nsets; i++) {
04111 cpl_size *select_dits = NULL;
04112 cpl_frameset *cur_fset =
04113 nsets == 1 ? cpl_frameset_duplicate(frameset) :
04114 cpl_frameset_extract(frameset, selection, i);
04115
04116 cpl_size ndits = 0;
04117 int j, k;
04118 cpl_table ** dsnu_table = NULL;
04119 cpl_imagelist ** dsnu = NULL;
04120
04121 cpl_propertylist ** qclist =
04122 (cpl_propertylist **)
04123 cpl_malloc(detmon_dark_config.nb_extensions *
04124 sizeof(cpl_propertylist *));
04125
04126
04127 cpl_imagelist ** masters =
04128 (cpl_imagelist **)
04129 cpl_malloc(detmon_dark_config.nb_extensions *
04130 sizeof(cpl_imagelist *));
04131
04132
04133 if(detmon_dark_config.opt_nir == OPT) {
04134 dsnu_table =
04135 (cpl_table **) cpl_malloc(detmon_dark_config.nb_extensions *
04136 sizeof(cpl_table *));
04137 dsnu =
04138 (cpl_imagelist **)
04139 cpl_malloc(detmon_dark_config.nb_extensions *
04140 sizeof(cpl_imagelist *));
04141 }
04142
04143 select_dits = cpl_frameset_labelise(cur_fset,
04144 detmon_compare_dits,
04145 &ndits);
04146
04147 if(detmon_dark_config.exts >= 0) {
04148 *masters = cpl_imagelist_new();
04149 if(detmon_dark_config.opt_nir == OPT) {
04150 *dsnu = cpl_imagelist_new();
04151 *dsnu_table = cpl_table_new(ndits);
04152 }
04153 *qclist = cpl_propertylist_new();
04154 cpl_table_new_column(*dsnu_table, "DIT", CPL_TYPE_DOUBLE);
04155 cpl_table_new_column(*dsnu_table, "STDEV", CPL_TYPE_DOUBLE);
04156 } else {
04157 for ( j = 0; j < detmon_dark_config.nb_extensions; j ++) {
04158 masters[j] = cpl_imagelist_new();
04159 if(detmon_dark_config.opt_nir == OPT) {
04160 dsnu[j] = cpl_imagelist_new();
04161 dsnu_table[j] = cpl_table_new(ndits);
04162 }
04163 qclist[j] = cpl_propertylist_new();
04164 cpl_table_new_column(dsnu_table[j], "DIT", CPL_TYPE_DOUBLE);
04165 cpl_table_new_column(dsnu_table[j], "STDEV", CPL_TYPE_DOUBLE);
04166 }
04167 }
04168
04169 for(j = 0; j < ndits; j++) {
04170 cpl_frameset * cur_fdit = cpl_frameset_extract(cur_fset,
04171 select_dits, j);
04172 cpl_imagelist ** raws =
04173 (cpl_imagelist **)
04174 cpl_malloc(detmon_dark_config.nb_extensions *
04175 sizeof(cpl_imagelist *));
04176
04177 if(detmon_dark_config.exts >= 0) {
04178 cpl_image * collapsed;
04179 *raws =
04180 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04181 detmon_dark_config.exts);
04182 collapsed = cpl_imagelist_collapse_create(*raws);
04183 cpl_imagelist_set(*masters, collapsed, j);
04184 if(detmon_dark_config.opt_nir == OPT) {
04185 detmon_dark_dsnu(cur_fdit, *dsnu, *dsnu_table,
04186 collapsed, j);
04187 }
04188 detmon_dark_qc(*qclist, collapsed);
04189 } else {
04190 cpl_imagelist *raws_all_exts =
04191 cpl_imagelist_load_frameset(cur_fdit, CPL_TYPE_FLOAT, 1,
04192 -1);
04193 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04194 int nframes = cpl_frameset_get_size(cur_fdit);
04195 int h;
04196 cpl_image * collapsed;
04197 for(h = 0; h < nframes; h++) {
04198 cpl_image *image =
04199 cpl_imagelist_unset(raws_all_exts,
04200 (detmon_dark_config.
04201 nb_extensions - 1 - k) * h);
04202 cpl_imagelist_set(raws[k], image, h);
04203 }
04204 collapsed = cpl_imagelist_collapse_create(raws[k]);
04205 cpl_imagelist_set(masters[k],collapsed, j);
04206 if(detmon_dark_config.opt_nir == OPT) {
04207 detmon_dark_dsnu(cur_fdit, dsnu[k],
04208 dsnu_table[j], collapsed, j);
04209 }
04210 detmon_dark_qc(qclist[k], collapsed);
04211 }
04212 }
04213
04214 cpl_frameset_delete(cur_fdit);
04215 for(k = 0; k < detmon_dark_config.nb_extensions; k++) {
04216 cpl_imagelist_delete(raws[k]);
04217 }
04218 cpl_free(raws);
04219 }
04220
04221 cpl_frameset_delete(cur_fset);
04222
04223 detmon_dark_save(parlist, frameset, recipe_name, pipeline_name,
04224 procatg_master, procatg_tbl, procatg_dsnu,
04225 package, masters, dsnu_table, dsnu, qclist,
04226 0, 0, frameset);
04227
04228 if(detmon_dark_config.opt_nir == OPT) {
04229 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04230 cpl_table_delete(dsnu_table[j]);
04231 cpl_imagelist_delete(dsnu[j]);
04232 }
04233 cpl_free(dsnu_table);
04234 cpl_free(dsnu);
04235 }
04236
04237 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04238 cpl_propertylist_delete(qclist[j]);
04239 cpl_imagelist_delete(masters[j]);
04240 }
04241 cpl_free(qclist);
04242 cpl_free(masters);
04243 cpl_free(select_dits);
04244
04245 }
04246
04247 cpl_free(selection);
04248
04249 return cpl_error_get_code();
04250 }
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264 int
04265 detmon_dark_dfs_set_groups(cpl_frameset * set, const char *tag)
04266 {
04267 cpl_frame *cur_frame;
04268 const char *cur_tag;
04269 int nframes;
04270 int i;
04271
04272
04273 if(set == NULL)
04274 return -1;
04275
04276
04277 nframes = cpl_frameset_get_size(set);
04278
04279
04280 for(i = 0; i < nframes; i++) {
04281 cur_frame = cpl_frameset_get_frame(set, i);
04282 cur_tag = cpl_frame_get_tag(cur_frame);
04283
04284
04285 if(!strcmp(cur_tag, tag))
04286 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
04287
04288
04289
04290
04291
04292 }
04293 return 0;
04294 }
04295
04296
04297
04298
04299
04300
04301
04302
04303
04304
04305
04306
04307 static cpl_error_code
04308 detmon_retrieve_dark_params(const char *pipeline_name,
04309 const char *recipe_name,
04310 const cpl_parameterlist * parlist)
04311 {
04312 char *par_name;
04313 cpl_parameter *par;
04314
04315
04316 par_name = cpl_sprintf("%s.%s.ron.method", pipeline_name, recipe_name);
04317 assert(par_name != NULL);
04318 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04319 detmon_dark_config.ron_method = cpl_parameter_get_string(par);
04320 cpl_free(par_name);
04321
04322
04323 par_name = cpl_sprintf("%s.%s.dsnu.method", pipeline_name, recipe_name);
04324 assert(par_name != NULL);
04325 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04326 detmon_dark_config.dsnu_method = cpl_parameter_get_string(par);
04327 cpl_free(par_name);
04328
04329
04330 par_name = cpl_sprintf("%s.%s.opt_nir", pipeline_name, recipe_name);
04331 assert(par_name != NULL);
04332 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
04333 detmon_dark_config.opt_nir = cpl_parameter_get_bool(par);
04334 cpl_free(par_name);
04335
04336
04337 detmon_dark_config.exts =
04338 detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
04339 parlist);
04340
04341 if(cpl_error_get_code()) {
04342 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
04343 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
04344 }
04345
04346
04347 return CPL_ERROR_NONE;
04348 }
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362 cpl_error_code
04363 detmon_fill_dark_params(cpl_parameterlist * parlist,
04364 const char *recipe_name,
04365 const char *pipeline_name,
04366 const char * ron_method,
04367 const char * dsnu_method,
04368 const char * opt_nir,
04369 int exts)
04370 {
04371 detmon_fill_parlist(parlist, recipe_name, pipeline_name, 4,
04372
04373 "ron.method",
04374 "Method used to compute RON. Currently no "
04375 "change is possible, RMS computed",
04376 "CPL_TYPE_STRING", ron_method,
04377
04378 "dsnu.method",
04379 "Method used to compute DSNU map. Currently no "
04380 "change is possible. Method used STDEV",
04381 "CPL_TYPE_STRING", dsnu_method,
04382
04383 "opt_nir",
04384 "Boolean, OPT (FALSE) or NIR(TRUE)",
04385 "CPL_TYPE_BOOL", opt_nir,
04386
04387 "exts",
04388 "Activate the multi-exts option. Default 0"
04389 "(primary unit), -1 (all exts)",
04390 "CPL_TYPE_INT", exts);
04391
04392 return cpl_error_get_code();
04393 }
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406 int
04407 detmon_fill_dark_params_default(cpl_parameterlist * parlist,
04408 const char *recipe_name,
04409 const char *pipeline_name)
04410 {
04411 detmon_fill_dark_params(parlist, recipe_name, pipeline_name,
04412 "SIMPLE",
04413 "STDEV",
04414 "CPL_FALSE",
04415 0);
04416 return cpl_error_get_code();
04417 }
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430 cpl_error_code
04431 detmon_dark_dsnu(cpl_frameset * cur_fdit,
04432 cpl_imagelist * dsnu,
04433 cpl_table * dsnu_table,
04434 cpl_image * collapsed,
04435 int pos)
04436 {
04437 cpl_frame * first = cpl_frameset_get_first(cur_fdit);
04438 cpl_propertylist * plist =
04439 cpl_propertylist_load(cpl_frame_get_filename(first), 0);
04440 double dit = irplib_pfits_get_exptime(plist);
04441 double mean = cpl_image_get_mean(collapsed);
04442
04443 cpl_image * dsnu_map =
04444 cpl_image_subtract_scalar_create(collapsed, mean);
04445 double stdev;
04446 cpl_image_divide_scalar(dsnu_map, mean);
04447 stdev = cpl_image_get_stdev(dsnu_map);
04448
04449 cpl_imagelist_set(dsnu, dsnu_map, pos);
04450
04451 cpl_table_set(dsnu_table, "DIT", pos, dit);
04452 cpl_table_set(dsnu_table, "STDEV", pos, stdev);
04453
04454 cpl_propertylist_delete(plist);
04455
04456 return cpl_error_get_code();
04457
04458 }
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468
04469
04470
04471 static cpl_error_code
04472 detmon_dark_save(const cpl_parameterlist * parlist,
04473 cpl_frameset * frameset,
04474 const char *recipe_name,
04475 const char *pipeline_name,
04476 const char *procatg_master,
04477 const char *procatg_tbl,
04478 const char *procatg_dsnu,
04479 const char *package,
04480 cpl_imagelist ** masters,
04481 cpl_table ** dsnu_table,
04482 cpl_imagelist ** dsnu,
04483 cpl_propertylist ** qclist,
04484 const int flag_sets,
04485 const int which_set,
04486 const cpl_frameset * usedframes)
04487 {
04488
04489 cpl_frame *ref_frame;
04490 cpl_propertylist *plist;
04491 char *name_o = NULL;
04492 int i, j;
04493 cpl_propertylist *paflist;
04494 cpl_error_code error;
04495 int nb_images;
04496
04497
04498
04499
04500
04501 nb_images = cpl_imagelist_get_size(masters[0]);
04502 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
04503
04504
04505 for(i = 0; i < nb_images; i++) {
04506
04507 if(!flag_sets) {
04508 name_o =
04509 cpl_sprintf("%s_master_dit_%d.fits", recipe_name, i+1);
04510 assert(name_o != NULL);
04511 } else {
04512 name_o =
04513 cpl_sprintf("%s_master_dit_%d_set%02d.fits",
04514 recipe_name, i, which_set);
04515 assert(name_o != NULL);
04516 }
04517
04518
04519
04520 if(detmon_dark_config.exts >= 0) {
04521 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04522 cpl_propertylist * pro_master = cpl_propertylist_new();
04523
04524 cpl_propertylist_append_string(pro_master,
04525 CPL_DFS_PRO_CATG, procatg_master);
04526
04527 cpl_propertylist_append(pro_master, qclist[0]);
04528
04529 if(cpl_dfs_save_image
04530 (frameset, NULL, parlist, usedframes, NULL,
04531 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04532 recipe_name, pro_master, NULL, package,
04533 name_o)) {
04534 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04535 name_o);
04536 cpl_free(name_o);
04537 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04538
04539 }
04540
04541 cpl_propertylist_delete(pro_master);
04542 #else
04543 if(cpl_dfs_save_image
04544 (frameset, parlist, usedframes,
04545 cpl_imagelist_get(*masters, i), CPL_BPP_IEEE_FLOAT,
04546 recipe_name, procatg_master, qclist[0], NULL, package,
04547 name_o)) {
04548 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04549 name_o);
04550 cpl_free(name_o);
04551 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04552
04553 }
04554 #endif
04555 } else {
04556 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04557 cpl_propertylist * pro_master = cpl_propertylist_new();
04558
04559 cpl_propertylist_append_string(pro_master,
04560 CPL_DFS_PRO_CATG, procatg_master);
04561
04562 cpl_propertylist_append(pro_master, qclist[0]);
04563
04564 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,
04565 NULL, CPL_BPP_IEEE_FLOAT, recipe_name,
04566 pro_master, NULL,
04567 package, name_o)) {
04568 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04569 name_o);
04570 cpl_free(name_o);
04571 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04572 }
04573
04574 cpl_propertylist_delete(pro_master);
04575 #else
04576 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04577 CPL_BPP_IEEE_FLOAT, recipe_name,
04578 procatg_master, qclist[0], NULL,
04579 package, name_o)) {
04580 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04581 name_o);
04582 cpl_free(name_o);
04583 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04584 }
04585 #endif
04586 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04587 error =
04588 cpl_image_save(cpl_imagelist_get(masters[j], i),
04589 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04590 CPL_IO_EXTEND);
04591 cpl_ensure_code(!error, error);
04592 }
04593 }
04594 cpl_free(name_o);
04595 }
04596
04597 if (detmon_dark_config.opt_nir == OPT) {
04598 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04599 cpl_propertylist * pro_tbl = cpl_propertylist_new();
04600
04601 cpl_propertylist_append_string(pro_tbl,
04602 CPL_DFS_PRO_CATG, procatg_tbl);
04603
04604 cpl_propertylist_append(pro_tbl, qclist[0]);
04605 #endif
04606
04607
04608
04609
04610
04611 if(!flag_sets) {
04612 name_o = cpl_sprintf("%s_dsnu_table.fits", recipe_name);
04613 assert(name_o != NULL);
04614 } else {
04615 name_o =
04616 cpl_sprintf("%s_dsnu_table_set%02d.fits", recipe_name,
04617 which_set);
04618 assert(name_o != NULL);
04619 }
04620 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04621
04622 if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,
04623 dsnu_table[0], NULL, recipe_name, pro_tbl, NULL,
04624 package, name_o)) {
04625 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04626 cpl_free(name_o);
04627 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04628 }
04629 #else
04630
04631 if(cpl_dfs_save_table(frameset, parlist, usedframes, dsnu_table[0],
04632 NULL, recipe_name, procatg_tbl, qclist[0], NULL,
04633 package, name_o)) {
04634 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04635 cpl_free(name_o);
04636 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04637 }
04638 #endif
04639
04640 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04641 cpl_propertylist_delete(pro_tbl);
04642 #endif
04643
04644 if(detmon_dark_config.exts < 0) {
04645
04646 for(i = 1; i < detmon_dark_config.nb_extensions; i++) {
04647 error =
04648 cpl_table_save(dsnu_table[i], NULL, qclist[i], name_o,
04649 CPL_IO_EXTEND);
04650 cpl_ensure_code(!error, error);
04651 }
04652 }
04653
04654
04655 cpl_free(name_o);
04656
04657
04658
04659
04660
04661 for(i = 0; i < nb_images; i++) {
04662
04663 if(!flag_sets) {
04664 name_o =
04665 cpl_sprintf("%s_dsnu_map_dit_%d.fits", recipe_name, i+1);
04666 assert(name_o != NULL);
04667 } else {
04668 name_o =
04669 cpl_sprintf("%s_dsnu_map_dit_%d_set%02d.fits",
04670 recipe_name, i, which_set);
04671 assert(name_o != NULL);
04672 }
04673
04674
04675
04676 if(detmon_dark_config.exts >= 0) {
04677 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04678 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04679
04680 cpl_propertylist_append_string(pro_dsnu,
04681 CPL_DFS_PRO_CATG, procatg_dsnu);
04682
04683 cpl_propertylist_append(pro_dsnu, qclist[0]);
04684
04685 if(cpl_dfs_save_image
04686 (frameset, NULL, parlist, usedframes, NULL,
04687 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04688 recipe_name, pro_dsnu, NULL, package,
04689 name_o)) {
04690 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04691 name_o);
04692 cpl_free(name_o);
04693 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04694
04695 }
04696
04697 cpl_propertylist_delete(pro_dsnu);
04698 #else
04699 if(cpl_dfs_save_image
04700 (frameset, parlist, usedframes,
04701 cpl_imagelist_get(*dsnu, i), CPL_BPP_IEEE_FLOAT,
04702 recipe_name, procatg_dsnu, qclist[0], NULL, package,
04703 name_o)) {
04704 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04705 name_o);
04706 cpl_free(name_o);
04707 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04708
04709 }
04710 #endif
04711 } else {
04712 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
04713 cpl_propertylist * pro_dsnu = cpl_propertylist_new();
04714
04715 cpl_propertylist_append_string(pro_dsnu,
04716 CPL_DFS_PRO_CATG, procatg_dsnu);
04717
04718 cpl_propertylist_append(pro_dsnu, qclist[0]);
04719
04720 if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
04721 NULL, NULL,
04722 CPL_BPP_IEEE_FLOAT, recipe_name,
04723 pro_dsnu, NULL,
04724 package, name_o)) {
04725 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04726 name_o);
04727 cpl_free(name_o);
04728 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04729 }
04730
04731 cpl_propertylist_delete(pro_dsnu);
04732 #else
04733 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
04734 CPL_BPP_IEEE_FLOAT, recipe_name,
04735 procatg_dsnu, qclist[0], NULL,
04736 package, name_o)) {
04737 cpl_msg_error(cpl_func, "Cannot save the product: %s",
04738 name_o);
04739 cpl_free(name_o);
04740 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04741 }
04742 #endif
04743 for(j = 0; j < detmon_dark_config.nb_extensions; j++) {
04744 error =
04745 cpl_image_save(cpl_imagelist_get(dsnu[j], i),
04746 name_o, CPL_BPP_IEEE_FLOAT, qclist[j],
04747 CPL_IO_EXTEND);
04748 cpl_ensure_code(!error, error);
04749 }
04750 }
04751 cpl_free(name_o);
04752 }
04753
04754
04755
04756 }
04757
04758
04759
04760
04761
04762
04763 ref_frame = cpl_frameset_get_first(frameset);
04764 if((plist = cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04765 0)) == NULL) {
04766 cpl_msg_error(cpl_func, "getting header from reference frame");
04767 cpl_ensure_code(0, cpl_error_get_code());
04768 }
04769
04770
04771 paflist = cpl_propertylist_new();
04772 cpl_propertylist_copy_property_regexp(paflist, plist,
04773 "^(ARCFILE|MJD-OBS|ESO TPL ID|"
04774 "DATE-OBS|ESO DET DIT|ESO DET NDIT|"
04775 "ESO DET NCORRS|"
04776 "ESO DET MODE NAME)$", 0);
04777
04778 for(i = 0; i < detmon_dark_config.nb_extensions; i++) {
04779 cpl_propertylist * c_paflist = cpl_propertylist_duplicate(paflist);
04780 error = cpl_propertylist_append(c_paflist, qclist[i]);
04781 cpl_ensure_code(!error, error);
04782
04783
04784 if(detmon_dark_config.exts >= 0) {
04785 if(!flag_sets) {
04786 name_o = cpl_sprintf("%s.paf", recipe_name);
04787 assert(name_o != NULL);
04788 } else {
04789 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
04790 assert(name_o != NULL);
04791 }
04792 } else {
04793 if(!flag_sets) {
04794 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
04795 assert(name_o != NULL);
04796 } else {
04797 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
04798 assert(name_o != NULL);
04799 }
04800 }
04801
04802 if(cpl_dfs_save_paf(pipeline_name, recipe_name, c_paflist, name_o)) {
04803 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
04804 cpl_free(name_o);
04805 cpl_propertylist_delete(paflist);
04806 cpl_propertylist_delete(plist);
04807 cpl_free(name_o);
04808 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
04809 }
04810 cpl_propertylist_delete(c_paflist);
04811 cpl_free(name_o);
04812 }
04813
04814 cpl_propertylist_delete(plist);
04815 cpl_propertylist_delete(paflist);
04816
04817 return cpl_error_get_code();
04818 }
04819
04820 cpl_error_code
04821 detmon_dark_qc(cpl_propertylist * qclist,
04822 cpl_image * collapsed)
04823 {
04824 double mean = cpl_image_get_mean(collapsed);
04825 double stdev = cpl_image_get_stdev(collapsed);
04826
04827 cpl_error_code error;
04828
04829 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK, mean);
04830 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK,
04831 DETMON_QC_DARK_C);
04832 cpl_ensure_code(!error, error);
04833
04834 error = cpl_propertylist_append_double(qclist,DETMON_QC_DARK_STDEV, stdev);
04835 error = cpl_propertylist_set_comment(qclist,DETMON_QC_DARK_STDEV,
04836 DETMON_QC_DARK_STDEV_C);
04837 cpl_ensure_code(!error, error);
04838
04839 return cpl_error_get_code();
04840 }
04841
04842
04843
04860
04861 cpl_image *
04862 irplib_imagelist_collapse_stdev_create(const cpl_imagelist * imlist)
04863 {
04864 cpl_image * mean;
04865 cpl_image * delta;
04866 cpl_image * sq_delta;
04867 cpl_image * stdev;
04868
04869 int i;
04870
04871
04872 cpl_ensure(imlist != NULL, CPL_ERROR_NULL_INPUT, NULL);
04873 cpl_ensure(cpl_imagelist_is_uniform(imlist) == 0, CPL_ERROR_ILLEGAL_INPUT,
04874 NULL);
04875
04876
04877 mean = cpl_image_duplicate(cpl_imagelist_get_const(imlist, 0));
04878 cpl_image_fill_rejected(mean, 0.0);
04879 cpl_image_accept_all(mean);
04880
04881 stdev = cpl_image_new(cpl_image_get_size_x(mean),
04882 cpl_image_get_size_y(mean),
04883 CPL_TYPE_FLOAT);
04884
04885 for (i = 1; i < cpl_imagelist_get_size(imlist); i++) {
04886 delta = cpl_image_subtract_create(cpl_imagelist_get_const(imlist, i),
04887 mean);
04888 cpl_image_fill_rejected(delta, 0.0);
04889 cpl_image_accept_all(delta);
04890
04891 sq_delta = cpl_image_multiply_create(delta, delta);
04892
04893 cpl_image_multiply_scalar(sq_delta, ((double) i / (double)(i+1)));
04894 cpl_image_add(stdev, sq_delta);
04895
04896 cpl_image_divide_scalar(delta, i + 1);
04897 cpl_image_add(mean, delta);
04898
04899 cpl_image_delete(delta);
04900 cpl_image_delete(sq_delta);
04901 }
04902
04903 cpl_image_divide_scalar(stdev, cpl_imagelist_get_size(imlist) - 1);
04904 cpl_image_power(stdev, 0.5);
04905
04906 cpl_image_delete(mean);
04907
04908 return stdev;
04909 }