00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #ifdef HAVE_SFFTW
00037 #include <complex.h>
00038
00039 #include <sfftw.h>
00040
00041 #endif
00042
00043
00044
00045 #include <math.h>
00046 #include <string.h>
00047 #include <assert.h>
00048
00049 #include <cpl.h>
00050
00051 #include "irplib_detmon.h"
00052 #include "irplib_detmon_lg.h"
00053
00054 #include "irplib_utils.h"
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 static struct
00070 {
00071 const char * method;
00072
00073 int order;
00074 double kappa;
00075 int niter;
00076 int threshold_min;
00077 int threshold_max;
00078 int llx;
00079 int lly;
00080 int urx;
00081 int ury;
00082 int ref_level;
00083 int threshold;
00084 int m;
00085 int n;
00086 int llx1;
00087 int lly1;
00088 int urx1;
00089 int ury1;
00090 int llx2;
00091 int lly2;
00092 int urx2;
00093 int ury2;
00094 int llx3;
00095 int lly3;
00096 int urx3;
00097 int ury3;
00098 int llx4;
00099 int lly4;
00100 int urx4;
00101 int ury4;
00102 int llx5;
00103 int lly5;
00104 int urx5;
00105 int ury5;
00106 cpl_boolean autocorr;
00107 cpl_boolean intermediate;
00108 cpl_boolean collapse;
00109 cpl_boolean rescale;
00110 cpl_boolean pix2pix;
00111 cpl_boolean bpmbin;
00112 int filter;
00113 double tolerance;
00114 const char * pafname;
00115
00116 double cr;
00117 int exts;
00118 int nb_extensions;
00119 double lamp_stability;
00120 cpl_boolean lamp_ok;
00121 } detmon_lg_config;
00122
00123
00124
00125
00126
00127
00128
00129 static cpl_error_code
00130 irplib_detmon_lg_retrieve_parlist(const char *,
00131 const char *, const cpl_parameterlist *,
00132 cpl_boolean);
00133
00134
00135 static cpl_error_code
00136 irplib_detmon_lg_split_onoff(const cpl_frameset *,
00137 cpl_frameset *,
00138 cpl_frameset *,
00139 const char *, const char * );
00140
00141 static cpl_error_code
00142 irplib_detmon_lg_reduce(const cpl_frameset *,
00143 const cpl_frameset *,
00144 int *,
00145 int *,
00146 int,
00147 cpl_imagelist **,
00148 cpl_table *,
00149 cpl_table *,
00150 cpl_image **,
00151 cpl_imagelist *,
00152 cpl_imagelist *,
00153 cpl_propertylist *,
00154 int (* load_fset) (const cpl_frameset *,
00155 cpl_type,
00156 cpl_imagelist *),
00157 const cpl_boolean, int);
00158
00159 static cpl_error_code
00160 irplib_detmon_lin_table_fill_row(cpl_table *, double,
00161 cpl_imagelist *,
00162 const cpl_imagelist *,
00163 const cpl_imagelist *,
00164 int, int, int, int,
00165 const int,
00166 const int,
00167 unsigned);
00168
00169 static cpl_error_code
00170 irplib_detmon_gain_table_fill_row(cpl_table *, double,
00171 cpl_imagelist *,
00172 cpl_imagelist *,
00173 const cpl_imagelist *,
00174 const cpl_imagelist *,
00175 double, int,
00176 int, int, int, int,
00177 int, int, const int, unsigned);
00178
00179 static cpl_error_code
00180 irplib_detmon_lg_save(const cpl_parameterlist *,
00181 cpl_frameset *,
00182 const char *,
00183 const char *,
00184 const char *,
00185 const cpl_propertylist *,
00186 const cpl_propertylist *,
00187 const cpl_propertylist *,
00188 const cpl_propertylist *,
00189 const cpl_propertylist *,
00190 const cpl_propertylist *,
00191 const char *,
00192 cpl_imagelist *,
00193 cpl_table *,
00194 cpl_table *,
00195 cpl_image *,
00196 cpl_imagelist *,
00197 cpl_imagelist *,
00198 cpl_propertylist *,
00199 const int, const int, const cpl_frameset *,
00200 int);
00201
00202 static cpl_error_code
00203 irplib_detmon_lg_qc_ptc(const cpl_table *,
00204 cpl_propertylist *, unsigned);
00205
00206 static cpl_error_code
00207 irplib_detmon_lg_qc_med(const cpl_table *,
00208 cpl_propertylist *);
00209
00210 static cpl_error_code
00211 irplib_detmon_pair_extract(const cpl_frameset *,
00212 int *, int,
00213 int ,
00214 int *,
00215 int,
00216 cpl_frameset **);
00217
00218 static cpl_error_code
00219 irplib_detmon_single_extract(const cpl_frameset *,
00220 int *, int,
00221 int ,
00222 int *,
00223 int,
00224 cpl_frameset **);
00225
00226
00227 static double
00228 irplib_pfits_get_dit(const cpl_propertylist *);
00229
00230 static double
00231 irplib_pfits_get_dit_opt(const cpl_propertylist *);
00232
00233
00234 static cpl_image *irplib_detmon_bpixs(const cpl_imagelist *, cpl_boolean, const double, int *);
00235
00236 static double
00237 irplib_detmon_autocorr_factor(const cpl_image *,
00238 cpl_image **, int, int);
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static cpl_error_code
00251 irplib_detmon_opt_contamination(const cpl_imagelist *,
00252 const cpl_imagelist *,
00253 unsigned mode, cpl_propertylist *);
00254
00255 #if 0
00256 irplib_detmon_opt_lampcr(cpl_frameset *, int);
00257 #endif
00258
00259 int
00260 irplib_detmon_lg_dfs_set_groups(cpl_frameset *, const char *, const char *);
00261
00262 static cpl_error_code
00263 irplib_detmon_lg_reduce_all(const cpl_table *,
00264 cpl_propertylist *,
00265 cpl_imagelist **,
00266 cpl_image **,
00267 const cpl_imagelist *,
00268 const cpl_table *, int, cpl_boolean);
00269
00270 static cpl_error_code
00271 irplib_detmon_lg_check_defaults(const cpl_image *);
00272
00273 static cpl_error_code
00274 irplib_detmon_lg_rescale(cpl_imagelist *);
00275
00276 static cpl_error_code
00277 irplib_detmon_lg_reduce_init(cpl_table *,
00278 cpl_table *,
00279 cpl_imagelist **,
00280 const cpl_boolean);
00281
00282
00283
00284 static cpl_error_code
00285 irplib_detmon_add_adl_column(cpl_table *, cpl_boolean);
00286
00287 static cpl_error_code
00288 irplib_detmon_lg_lamp_stab(const cpl_frameset *,
00289 const cpl_frameset *,
00290 cpl_boolean, int);
00291
00292
00293 static cpl_error_code
00294 irplib_detmon_lg_reduce_dit(const cpl_frameset *,
00295 int *,
00296 const int ,
00297 int *,
00298 int ,
00299 const cpl_frameset *,
00300 int *,
00301 cpl_table *,
00302 cpl_table *,
00303 cpl_imagelist *,
00304 cpl_propertylist *,
00305 cpl_boolean ,
00306 cpl_imagelist *,
00307 cpl_imagelist *,
00308 cpl_imagelist *,
00309 int (*)(const cpl_frameset *,
00310 cpl_type,
00311 cpl_imagelist *), int);
00312
00313 static cpl_error_code
00314 irplib_detmon_lg_core(cpl_frameset *,
00315 cpl_frameset *,
00316 int *,
00317 int *,
00318 int ,
00319 int ,
00320 int ,
00321 const char *,
00322 const char *,
00323 const char *,
00324 const cpl_propertylist *,
00325 const cpl_propertylist *,
00326 const cpl_propertylist *,
00327 const cpl_propertylist *,
00328 const cpl_propertylist *,
00329 const cpl_propertylist *,
00330 const char *,
00331 int (*) (const cpl_frameset *,
00332 cpl_type,
00333 cpl_imagelist *),
00334 int, cpl_boolean,
00335 cpl_frameset *, const cpl_parameterlist *, cpl_frameset *);
00336
00337 static cpl_error_code
00338 irplib_detmon_lg_lineff(double *, cpl_propertylist *, int, int);
00339
00340
00341 static int
00342 irplib_detmon_lg_compare_pairs(const cpl_frame *,
00343 const cpl_frame *);
00344
00345 static cpl_error_code
00346 irplib_detmon_gain_table_create(cpl_table *,
00347 const cpl_boolean);
00348
00349
00350 static cpl_error_code
00351 irplib_detmon_lin_table_create(cpl_table *,
00352 const cpl_boolean);
00353
00354 static cpl_vector *
00355 irplib_detmon_lg_find_dits(const cpl_vector *,
00356 double );
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 cpl_error_code
00435 irplib_detmon_lg(cpl_frameset * frameset,
00436 const cpl_parameterlist * parlist,
00437 const char * tag_on,
00438 const char * tag_off,
00439 const char * recipe_name,
00440 const char * pipeline_name,
00441 const char * pafregexp,
00442 const cpl_propertylist * pro_lintbl,
00443 const cpl_propertylist * pro_gaintbl,
00444 const cpl_propertylist * pro_coeffscube,
00445 const cpl_propertylist * pro_bpm,
00446 const cpl_propertylist * pro_corr,
00447 const cpl_propertylist * pro_diff,
00448 const char * package,
00449 int (* compare) (const cpl_frame *,
00450 const cpl_frame *),
00451 int (* load_fset) (const cpl_frameset *,
00452 cpl_type,
00453 cpl_imagelist *),
00454 const cpl_boolean opt_nir)
00455 {
00456 int nsets;
00457 int * selection = NULL;
00458 int i;
00459 cpl_frame * first = NULL;
00460 cpl_image * reference = NULL;
00461 cpl_frameset * set = NULL;
00462
00463
00464
00465
00466
00467
00468 int * selection_on = NULL;
00469 int * selection_off = NULL;
00470 cpl_frameset * cur_fset = NULL;
00471 cpl_frameset * cur_fset_on = NULL;
00472 cpl_frameset * cur_fset_off = NULL;
00473
00474
00475 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
00476 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00477 cpl_ensure_code(tag_on != NULL, CPL_ERROR_NULL_INPUT);
00478 cpl_ensure_code(tag_off != NULL, CPL_ERROR_NULL_INPUT);
00479 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00480 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
00481 cpl_ensure_code(pro_lintbl != NULL, CPL_ERROR_NULL_INPUT);
00482 cpl_ensure_code(pro_gaintbl != NULL, CPL_ERROR_NULL_INPUT);
00483 cpl_ensure_code(pro_coeffscube != NULL, CPL_ERROR_NULL_INPUT);
00484 cpl_ensure_code(pro_bpm != NULL, CPL_ERROR_NULL_INPUT);
00485 cpl_ensure_code(pro_corr != NULL, CPL_ERROR_NULL_INPUT);
00486 cpl_ensure_code(pro_diff != NULL, CPL_ERROR_NULL_INPUT);
00487 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
00488
00489 skip_if (irplib_detmon_lg_dfs_set_groups(frameset, tag_on, tag_off));
00490
00491
00492
00493
00494
00495
00496 skip_if (irplib_detmon_lg_retrieve_parlist(pipeline_name, recipe_name,
00497 parlist, opt_nir));
00498
00499
00500
00501
00502
00503
00504 first = cpl_frameset_get_first(frameset);
00505 irplib_ensure (first != NULL, CPL_ERROR_ILLEGAL_INPUT, "Empty data set!");
00506
00507 if (detmon_lg_config.exts < 0) {
00508 reference = cpl_image_load(cpl_frame_get_filename(first),
00509 CPL_TYPE_FLOAT, 0, 1);
00510 } else {
00511 if (load_fset != NULL) {
00512 cpl_frameset * new = cpl_frameset_new();
00513 cpl_imagelist * p = cpl_imagelist_new();
00514 cpl_frameset_insert(new, cpl_frame_duplicate(first));
00515 (*load_fset)(new, CPL_TYPE_FLOAT, p);
00516 reference = cpl_image_duplicate(cpl_imagelist_get(p, 0));
00517 cpl_imagelist_delete(p);
00518 cpl_frameset_delete(new);
00519 } else {
00520 cpl_msg_info(cpl_func,"name=%s",cpl_frame_get_filename(first));
00521 reference = cpl_image_load(cpl_frame_get_filename(first),
00522 CPL_TYPE_FLOAT, 0, detmon_lg_config.exts);
00523 }
00524 }
00525 skip_if (reference == NULL);
00526
00527 skip_if (irplib_detmon_lg_check_defaults(reference));
00528
00529
00530 set = cpl_frameset_duplicate(frameset);
00531
00532
00533
00534
00535
00536 if (compare == NULL) {
00537 nsets = 1;
00538 } else {
00539 cpl_msg_info(cpl_func, "Identifying different settings");
00540 selection = cpl_frameset_labelise(set, compare, &nsets);
00541 skip_if (selection == NULL);
00542 }
00543
00544
00545 detmon_lg_config.nb_extensions = 1;
00546 if (detmon_lg_config.exts < 0) {
00547 detmon_lg_config.nb_extensions = cpl_frame_get_nextensions(first);
00548 }
00549
00550
00551 for(i = 0; i < nsets; i++) {
00552 int j;
00553 int nexts = detmon_lg_config.nb_extensions;
00554
00555 int nsets_on = 0;
00556 int nsets_off = 0;
00557
00558
00559 cpl_msg_info(cpl_func, "Reduce data set nb %d out of %d",
00560 i + 1, nsets);
00561
00562 cur_fset = nsets == 1 ?
00563 cpl_frameset_duplicate(set) :
00564 cpl_frameset_extract(set, selection, i);
00565 skip_if(cur_fset == NULL);
00566
00567
00568 cur_fset_on = cpl_frameset_new();
00569 cur_fset_off = cpl_frameset_new();
00570 cpl_msg_info(cpl_func, "Splitting into ON and OFF sub-framesets");
00571 skip_if (irplib_detmon_lg_split_onoff(cur_fset,
00572 cur_fset_on, cur_fset_off,
00573 tag_on, tag_off ));
00574
00575
00576 selection_on = cpl_frameset_labelise(cur_fset_on,
00577 irplib_detmon_lg_compare_pairs,
00578 &nsets_on);
00579 skip_if (selection_on == NULL);
00580
00581 if (!detmon_lg_config.collapse) {
00582 selection_off = cpl_frameset_labelise(cur_fset_off,
00583 irplib_detmon_lg_compare_pairs,
00584 &nsets_off);
00585 skip_if (selection_off == NULL);
00586 }
00587
00588
00589 if (!detmon_lg_config.collapse) {
00590 skip_if(nsets_on != nsets_off);
00591 }
00592
00593 if(nsets_on <= detmon_lg_config.order) {
00594 cpl_msg_error(cpl_func, "Not enough frames for the polynomial"
00595 " fitting. nsets <= order.");
00596 skip_if(1);
00597 }
00598
00599 if(detmon_lg_config.exts >= 0) {
00600
00601
00602
00603
00604
00605 #if 0
00606 if (detmon_lg_config.lamp_ok) {
00607 skip_if(irplib_detmon_opt_lampcr(cur_fset, 0));
00608 }
00609 #endif
00610 skip_if(irplib_detmon_lg_core(cur_fset_on, cur_fset_off, selection_on,
00611 selection_off, nsets_on, detmon_lg_config.exts, i, recipe_name, pipeline_name, pafregexp, pro_lintbl, pro_gaintbl, pro_coeffscube, pro_bpm, pro_corr, pro_diff, package, load_fset, nsets, opt_nir, frameset, parlist, cur_fset));
00612 } else {
00613 for(j = 1; j <= nexts; j++) {
00614
00615
00616
00617
00618
00619 #if 0
00620 if (detmon_lg_config.lamp_ok) {
00621 skip_if(irplib_detmon_opt_lampcr(cur_fset, j));
00622 }
00623 #endif
00624
00625 skip_if(irplib_detmon_lg_core(cur_fset_on, cur_fset_off, selection_on,
00626 selection_off, nsets_on, j, i, recipe_name, pipeline_name,pafregexp, pro_lintbl, pro_gaintbl, pro_coeffscube, pro_bpm, pro_corr, pro_diff, package, load_fset, nsets, opt_nir, frameset, parlist, cur_fset));
00627 }
00628 }
00629
00630
00631 cpl_free(selection_on);
00632 cpl_free(selection_off);
00633
00634 cpl_frameset_delete(cur_fset);
00635 cpl_frameset_delete(cur_fset_on);
00636 cpl_frameset_delete(cur_fset_off);
00637
00638 selection_on = NULL;
00639 selection_off = NULL;
00640 cur_fset = NULL;
00641 cur_fset_on = NULL;
00642 cur_fset_off = NULL;
00643 }
00644
00645 end_skip;
00646
00647 cpl_free(selection_on);
00648 cpl_free(selection_off);
00649
00650 cpl_frameset_delete(cur_fset);
00651 cpl_frameset_delete(cur_fset_on);
00652 cpl_frameset_delete(cur_fset_off);
00653
00654 cpl_frameset_delete(set);
00655 cpl_free(selection);
00656 cpl_image_delete(reference);
00657
00658 return cpl_error_get_code();
00659 }
00660
00661
00694
00695
00696 static cpl_error_code
00697 irplib_detmon_lg_core(cpl_frameset * cur_fset_on,
00698 cpl_frameset * cur_fset_off,
00699 int * selection_on,
00700 int * selection_off,
00701 int nsets_on,
00702 int whichext,
00703 int whichset,
00704 const char * recipe_name,
00705 const char * pipeline_name,
00706 const char * pafregexp,
00707 const cpl_propertylist * pro_lintbl,
00708 const cpl_propertylist * pro_gaintbl,
00709 const cpl_propertylist * pro_coeffscube,
00710 const cpl_propertylist * pro_bpm,
00711 const cpl_propertylist * pro_corr,
00712 const cpl_propertylist * pro_diff,
00713 const char * package,
00714 int (* load_fset) (const cpl_frameset *,
00715 cpl_type,
00716 cpl_imagelist *),
00717 int nsets, cpl_boolean opt_nir,
00718 cpl_frameset * frameset, const cpl_parameterlist * parlist,
00719 cpl_frameset * cur_fset)
00720 {
00721 cpl_table * gain_table = cpl_table_new(cpl_frameset_get_size(cur_fset_on)/2);
00722 cpl_table * linear_table = cpl_table_new(cpl_frameset_get_size(cur_fset_on)/2);
00723 cpl_imagelist * coeffs = NULL;
00724 cpl_image * bpm = NULL;
00725 cpl_imagelist * autocorr_images = NULL;
00726 cpl_imagelist * diff_flats = NULL;
00727 cpl_propertylist * qclist = NULL;
00728
00729
00730 cpl_msg_info(cpl_func, "Reduce extension nb %d ",
00731 whichext);
00732
00733
00734
00735 if (detmon_lg_config.intermediate) {
00736 autocorr_images = cpl_imagelist_new();
00737 diff_flats = cpl_imagelist_new();
00738 }
00739 qclist = cpl_propertylist_new();
00740
00741
00742 cpl_msg_info(cpl_func, "Starting data reduction");
00743 skip_if(irplib_detmon_lg_reduce(cur_fset_on, cur_fset_off,
00744 selection_on, selection_off,
00745 nsets_on, &coeffs, gain_table,
00746 linear_table, &bpm, autocorr_images,
00747 diff_flats, qclist, load_fset,
00748 opt_nir, whichext));
00749
00750
00751 cpl_msg_info(cpl_func, "Saving the products");
00752 if(nsets == 1) {
00753 skip_if(irplib_detmon_lg_save(parlist, frameset, recipe_name,
00754 pipeline_name, pafregexp,
00755 pro_lintbl, pro_gaintbl,
00756 pro_coeffscube, pro_bpm,
00757 pro_corr, pro_diff, package,
00758 coeffs, gain_table, linear_table,
00759 bpm, autocorr_images, diff_flats,
00760 qclist, 0, 0, cur_fset, whichext));
00761 } else {
00762 skip_if(irplib_detmon_lg_save(parlist, frameset, recipe_name,
00763 pipeline_name, pafregexp,
00764 pro_lintbl, pro_gaintbl,
00765 pro_coeffscube, pro_bpm,
00766 pro_corr, pro_diff, package,
00767 coeffs, gain_table, linear_table,
00768 bpm, autocorr_images, diff_flats,
00769 qclist, 1, whichset+ 1, cur_fset, whichext));
00770 }
00771
00772 end_skip;
00773
00774
00775 cpl_table_delete(gain_table);
00776 cpl_table_delete(linear_table);
00777 cpl_imagelist_delete(coeffs);
00778 cpl_propertylist_delete(qclist);
00779 cpl_image_delete(bpm);
00780 cpl_imagelist_delete(autocorr_images);
00781 cpl_imagelist_delete(diff_flats);
00782
00783 return cpl_error_get_code();
00784 }
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804 #ifdef HAVE_SFFTW
00805
00806 cpl_image *
00807 irplib_detmon_image_correlate(const cpl_image * image1,
00808 const cpl_image * image2,
00809 const int m, const int n)
00810 {
00811 cpl_image *image1_padded;
00812 cpl_image *image2_padded;
00813 float *data1;
00814 float *data2;
00815 int nx, ny;
00816 int nx2, ny2;
00817 int i;
00818
00819 fftwnd_plan p1;
00820 fftw_complex *in1;
00821 fftw_complex *ri1;
00822
00823 fftwnd_plan p2;
00824 fftw_complex *in2;
00825 fftw_complex *ri2;
00826
00827 fftwnd_plan p_inv;
00828 fftw_complex *in_inv;
00829 fftw_complex *ri_inv;
00830
00831 fftw_complex *corr;
00832 float *corr_r;
00833
00834 cpl_image *corr_image;
00835 cpl_image *corr_image_window;
00836 cpl_image *reorganised;
00837 cpl_image *image;
00838
00839
00840 cpl_ensure(image1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
00841 cpl_ensure(image2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
00842
00843 cpl_ensure(m > 0, CPL_ERROR_NULL_INPUT, NULL);
00844 cpl_ensure(n > 0, CPL_ERROR_NULL_INPUT, NULL);
00845
00846 nx = cpl_image_get_size_x(image1);
00847 ny = cpl_image_get_size_y(image1);
00848
00849 nx2 = cpl_image_get_size_x(image2);
00850 ny2 = cpl_image_get_size_y(image2);
00851
00852
00853 cpl_ensure(nx == nx2 && ny == ny2, CPL_ERROR_ILLEGAL_INPUT, NULL);
00854
00855
00856 image1_padded = cpl_image_new(nx + 2 * m, ny + 2 * n, CPL_TYPE_FLOAT);
00857 cpl_image_copy(image1_padded, image1, m + 1, n + 1);
00858
00859 image2_padded = cpl_image_new(nx + 2 * m, ny + 2 * n, CPL_TYPE_FLOAT);
00860 cpl_image_copy(image2_padded, image2, m + 1, n + 1);
00861
00862
00863 data1 = cpl_image_get_data_float(image1_padded);
00864 data2 = cpl_image_get_data_float(image2_padded);
00865
00866
00867 nx = nx + 2 * m;
00868 ny = ny + 2 * n;
00869
00870
00871 in1 = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00872 ri1 = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00873 p1 = fftw2d_create_plan_specific(ny, nx, FFTW_FORWARD, FFTW_ESTIMATE,
00874 in1, 1, ri1, 1);
00875
00876
00877 for(i = 0; i < nx * ny; i++) {
00878 *((float complex *)in1 + i) = (*(data1 + i) + 0.0 * I);
00879 }
00880
00881
00882 fftwnd_one(p1, in1, ri1);
00883
00884
00885 fftwnd_destroy_plan(p1);
00886 cpl_image_delete(image1_padded);
00887
00888
00889 in2 = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00890 ri2 = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00891
00892 p2 = fftw2d_create_plan_specific(ny, nx, FFTW_FORWARD, FFTW_ESTIMATE,
00893 in2, 1, ri2, 1);
00894
00895
00896
00897 for(i = 0; i < nx * ny; i++) {
00898 *((float complex *)in2 + i) = (*(data2 + i) + 0.0 * I);
00899 }
00900
00901
00902 fftwnd_one(p2, in2, ri2);
00903
00904
00905 fftwnd_destroy_plan(p2);
00906 cpl_image_delete(image2_padded);
00907
00908
00909 in_inv = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00910 ri_inv = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00911 p_inv = fftw2d_create_plan_specific(ny, nx, FFTW_FORWARD, FFTW_ESTIMATE,
00912 in_inv, 1, ri_inv, 1);
00913
00914
00915 for(i = 0; i < nx * ny; i++) {
00916 *((float complex *)in_inv + i) = conjf(*((float complex *)ri1 + i)) *
00917 (*((float complex *)ri2+i));
00918 }
00919
00920
00921 fftw_free(in1);
00922 fftw_free(ri1);
00923
00924 fftw_free(in2);
00925 fftw_free(ri2);
00926
00927
00928 fftwnd_one(p_inv, in_inv, ri_inv);
00929
00930
00931 fftwnd_destroy_plan(p_inv);
00932
00933
00934 corr = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nx * ny);
00935 corr_r = (float *) cpl_malloc(sizeof(float) * nx * ny);
00936
00937 for(i = 0; i < nx * ny; i++) {
00938 *((float complex *)corr + i) = conjf(*((float complex *)ri_inv + i));
00939 *((float complex *)corr + i) *= *((float complex *)ri_inv + i);
00940 *(corr_r + i) = crealf(*((float complex *)corr + i));
00941 }
00942 fftw_free(in_inv);
00943 fftw_free(ri_inv);
00944
00945
00946 corr_image = cpl_image_wrap_float(nx, ny, corr_r);
00947
00948
00949 fftw_free(corr);
00950
00951
00952 reorganised = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00953
00954 image = cpl_image_extract(corr_image, nx / 2 + 1, 1, nx, ny);
00955 cpl_image_copy(reorganised, image, 1, 1);
00956 cpl_image_delete(image);
00957
00958 image = cpl_image_extract(corr_image, 1, 1, nx / 2, ny);
00959 cpl_image_copy(reorganised, image, nx / 2 + 1, 1);
00960 cpl_image_delete(image);
00961
00962 cpl_image_unwrap(corr_image);
00963 cpl_free(corr_r);
00964
00965 corr_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00966
00967 image = cpl_image_extract(reorganised, 1, ny / 2 + 1, nx, ny);
00968 cpl_image_copy(corr_image, image, 1, 1);
00969 cpl_image_delete(image);
00970
00971 image = cpl_image_extract(reorganised, 1, 1, nx, ny / 2);
00972 cpl_image_copy(corr_image, image, 1, ny / 2 + 1);
00973 cpl_image_delete(image);
00974
00975
00976 corr_image_window = cpl_image_extract(corr_image,
00977 nx / 2 + 1 - m,
00978 ny / 2 + 1 - n,
00979 nx / 2 + 1 + m, ny / 2 + 1 + n);
00980
00981
00982 cpl_image_delete(reorganised);
00983 cpl_image_delete(corr_image);
00984
00985 if(cpl_image_divide_scalar(corr_image_window,
00986 cpl_image_get_max(corr_image_window))) {
00987 cpl_image_delete(corr_image_window);
00988 return NULL;
00989 }
00990
00991 return corr_image_window;
00992 }
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118 #endif
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137 cpl_image *
01138 irplib_detmon_autocorrelate(const cpl_image * input2, const int m,
01139 const int n)
01140 {
01141 cpl_image *im_re = NULL;
01142 cpl_image *im_im = NULL;
01143 int nx, ny;
01144 cpl_image *ifft_re = NULL;
01145 cpl_image *ifft_im = NULL;
01146 cpl_image *autocorr = NULL;
01147 cpl_image *autocorr_norm_double = NULL;
01148 cpl_image *autocorr_norm = NULL;
01149 cpl_image *reorganised = NULL;
01150 cpl_image *image = NULL;
01151 int p;
01152 cpl_error_code error;
01153 cpl_image *input;
01154
01155 cpl_ensure(input2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
01156
01157 cpl_ensure(m > 0, CPL_ERROR_NULL_INPUT, NULL);
01158 cpl_ensure(n > 0, CPL_ERROR_NULL_INPUT, NULL);
01159
01160 nx = cpl_image_get_size_x(input2) + 2 * m;
01161 ny = cpl_image_get_size_y(input2) + 2 * n;
01162
01163 p = 128;
01164 while(nx > p || ny > p) {
01165 p *= 2;
01166 }
01167
01168 input = cpl_image_cast(input2, CPL_TYPE_DOUBLE);
01169
01170 im_re = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01171 error = cpl_image_copy(im_re, input, 1, 1);
01172 cpl_ensure(!error, error, NULL);
01173
01174 im_im = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01175
01176 error = cpl_image_fft(im_re, im_im, CPL_FFT_DEFAULT);
01177 cpl_ensure(!error, error, NULL);
01178
01179 ifft_re = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01180 error = cpl_image_power(im_re, 2);
01181 cpl_ensure(!error, error, NULL);
01182
01183 error = cpl_image_add(ifft_re, im_re);
01184 cpl_ensure(!error, error, NULL);
01185
01186 cpl_image_delete(im_re);
01187
01188 error = cpl_image_power(im_im, 2);
01189 cpl_ensure(!error, error, NULL);
01190
01191 error = cpl_image_add(ifft_re, im_im);
01192 cpl_ensure(!error, error, NULL);
01193
01194 cpl_image_delete(im_im);
01195
01196 ifft_im = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01197
01198 error = cpl_image_fft(ifft_re, ifft_im, CPL_FFT_INVERSE);
01199 cpl_ensure(!error, error, NULL);
01200
01201 autocorr = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01202
01203 error = cpl_image_power(ifft_re, 2);
01204 cpl_ensure(!error, error, NULL);
01205
01206 error = cpl_image_add(autocorr, ifft_re);
01207 cpl_ensure(!error, error, NULL);
01208
01209 cpl_image_delete(ifft_re);
01210
01211 error = cpl_image_power(ifft_im, 2);
01212 cpl_ensure(!error, error, NULL);
01213
01214 error = cpl_image_add(autocorr, ifft_im);
01215 cpl_ensure(!error, error, NULL);
01216
01217 cpl_image_delete(ifft_im);
01218
01219
01220 reorganised = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01221
01222 image = cpl_image_extract(autocorr, p / 2 + 1, 1, p, p);
01223 cpl_image_copy(reorganised, image, 1, 1);
01224 cpl_image_delete(image);
01225
01226 image = cpl_image_extract(autocorr, 1, 1, p / 2, p);
01227 cpl_image_copy(reorganised, image, p / 2 + 1, 1);
01228 cpl_image_delete(image);
01229
01230 cpl_image_delete(autocorr);
01231
01232 autocorr = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01233
01234 image = cpl_image_extract(reorganised, 1, p / 2 + 1, p, p);
01235 cpl_image_copy(autocorr, image, 1, 1);
01236 cpl_image_delete(image);
01237
01238 image = cpl_image_extract(reorganised, 1, 1, p, p / 2);
01239 cpl_image_copy(autocorr, image, 1, p / 2 + 1);
01240 cpl_image_delete(image);
01241
01242 cpl_image_delete(reorganised);
01243
01244 autocorr_norm_double =
01245 cpl_image_extract(autocorr, p / 2 + 1 - m, p / 2 + 1 - n,
01246 p / 2 + 1 + m, p / 2 + 1 + n);
01247
01248 cpl_image_delete(autocorr);
01249
01250 if(cpl_image_divide_scalar(autocorr_norm_double,
01251 cpl_image_get_max(autocorr_norm_double))) {
01252 cpl_image_delete(autocorr_norm_double);
01253 cpl_ensure(0, cpl_error_get_code(), NULL);
01254 }
01255
01256
01257 autocorr_norm = cpl_image_cast(autocorr_norm_double, CPL_TYPE_FLOAT);
01258 cpl_image_delete(autocorr_norm_double);
01259
01260 cpl_image_delete(input);
01261
01262 return autocorr_norm;
01263 }
01264
01265
01276
01277 cpl_error_code
01278 irplib_detmon_lg_fill_parlist_nir_default(cpl_parameterlist * parlist,
01279 const char *recipe_name,
01280 const char *pipeline_name)
01281 {
01282 const cpl_error_code error =
01283 irplib_detmon_lg_fill_parlist(parlist, recipe_name, pipeline_name,
01284 "PTC",
01285 3,
01286 3.,
01287 5,
01288 -1,
01289 -1,
01290 -1,
01291 -1,
01292 10000,
01293 "CPL_FALSE",
01294 "CPL_FALSE",
01295 "CPL_FALSE",
01296 "CPL_TRUE",
01297 "CPL_TRUE",
01298 "CPL_FALSE",
01299 -1,
01300 26,
01301 26,
01302 1e-3,
01303 recipe_name,
01304 -1,
01305 -1,
01306 -1,
01307 -1,
01308 -1,
01309 -1,
01310 -1,
01311 -1,
01312 -1,
01313 -1,
01314 -1,
01315 -1,
01316 -1,
01317 -1,
01318 -1,
01319 -1,
01320 -1,
01321 -1,
01322 -1,
01323 -1,
01324 0,
01325 NIR);
01326
01327
01328 cpl_ensure_code(!error, error);
01329
01330 return cpl_error_get_code();
01331 }
01332
01333
01344
01345 cpl_error_code
01346 irplib_detmon_lg_fill_parlist_opt_default(cpl_parameterlist * parlist,
01347 const char *recipe_name,
01348 const char *pipeline_name)
01349 {
01350 const cpl_error_code error =
01351 irplib_detmon_lg_fill_parlist(parlist, recipe_name, pipeline_name,
01352 "PTC",
01353 3,
01354 3.,
01355 5,
01356 -1,
01357 -1,
01358 -1,
01359 -1,
01360 10000,
01361 "CPL_FALSE",
01362 "CPL_FALSE",
01363 "CPL_TRUE",
01364 "CPL_TRUE",
01365 "CPL_FALSE",
01366 "CPL_FALSE",
01367 -1,
01368 26,
01369 26,
01370 1e-3,
01371 recipe_name,
01372 -1,
01373 -1,
01374 -1,
01375 -1,
01376 -1,
01377 -1,
01378 -1,
01379 -1,
01380 -1,
01381 -1,
01382 -1,
01383 -1,
01384 -1,
01385 -1,
01386 -1,
01387 -1,
01388 -1,
01389 -1,
01390 -1,
01391 -1,
01392 0,
01393 OPT);
01394
01395 cpl_ensure_code(!error, error);
01396
01397 return cpl_error_get_code();
01398 }
01399
01400
01454
01455 cpl_error_code
01456 irplib_detmon_lg_fill_parlist(cpl_parameterlist * parlist,
01457 const char *recipe_name, const char *pipeline_name,
01458 const char *method,
01459 int order,
01460 double kappa,
01461 int niter,
01462 int llx,
01463 int lly,
01464 int urx,
01465 int ury,
01466 int ref_level,
01467 const char *intermediate,
01468 const char *autocorr,
01469 const char *collapse,
01470 const char *rescale,
01471 const char *pix2pix,
01472 const char *bpmbin,
01473 int filter,
01474 int m,
01475 int n,
01476 double tolerance,
01477 const char * pafname,
01478 int llx1,
01479 int lly1,
01480 int urx1,
01481 int ury1,
01482 int llx2,
01483 int lly2,
01484 int urx2,
01485 int ury2,
01486 int llx3,
01487 int lly3,
01488 int urx3,
01489 int ury3,
01490 int llx4,
01491 int lly4,
01492 int urx4,
01493 int ury4,
01494 int llx5, int lly5, int urx5, int ury5, int exts,
01495 cpl_boolean opt_nir)
01496 {
01497 const cpl_error_code error =
01498 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 21,
01499 "method",
01500 "Method to be used when computing GAIN. Methods appliable: <PTC | MED>. By default PTC method will be applied.",
01501 "CPL_TYPE_STRING", method,
01502
01503 "order",
01504 "Polynomial order for the fit (Linearity)",
01505 "CPL_TYPE_INT", order,
01506 "kappa",
01507 "Kappa value for the kappa-sigma clipping (Gain)",
01508 "CPL_TYPE_DOUBLE", kappa,
01509 "niter",
01510 "Number of iterations to compute rms (Gain)",
01511 "CPL_TYPE_INT", niter,
01512 "llx",
01513 "x coordinate of the lower-left "
01514 "point of the region of interest. If not modified, default value will be 1.",
01515 "CPL_TYPE_INT", llx,
01516 "lly",
01517 "y coordinate of the lower-left "
01518 "point of the region of interest. If not modified, default value will be 1.",
01519 "CPL_TYPE_INT", lly,
01520 "urx",
01521 "x coordinate of the upper-right "
01522 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
01523 "CPL_TYPE_INT", urx,
01524 "ury",
01525 "y coordinate of the upper-right "
01526 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
01527 "CPL_TYPE_INT", ury,
01528 "ref_level",
01529 "User reference level",
01530 "CPL_TYPE_INT", ref_level,
01531 "intermediate",
01532 "De-/Activate intermediate products",
01533 "CPL_TYPE_BOOL", intermediate,
01534 "autocorr",
01535 "De-/Activate the autocorr option",
01536 "CPL_TYPE_BOOL", autocorr,
01537 "collapse",
01538 "De-/Activate the collapse option",
01539 "CPL_TYPE_BOOL", collapse,
01540 "rescale",
01541 "De-/Activate the image rescale option",
01542 "CPL_TYPE_BOOL", rescale,
01543 "pix2pix",
01544 "De-/Activate the computation with pixel to pixel accuracy",
01545 "CPL_TYPE_BOOL", pix2pix,
01546 "bpmbin",
01547 "De-/Activate the binary bpm option",
01548 "CPL_TYPE_BOOL", bpmbin,
01549 "m",
01550 "Maximum x-shift for the autocorr",
01551 "CPL_TYPE_INT", m,
01552 "filter",
01553 "Upper limit of Median flux to be filtered",
01554 "CPL_TYPE_INT", filter,
01555 "n",
01556 "Maximum y-shift for the autocorr",
01557 "CPL_TYPE_INT", n,
01558 "tolerance",
01559 "Tolerance for pair discrimination",
01560 "CPL_TYPE_DOUBLE", tolerance,
01561 "pafname",
01562 "Specific name for PAF file",
01563 "CPL_TYPE_STRING", pafname,
01564
01565 "exts",
01566 "Activate the multi-exts option",
01567 "CPL_TYPE_INT", exts);
01568
01569
01570 if(opt_nir == FALSE) {
01571 const cpl_error_code erroropt =
01572 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 20,
01573 "llx1",
01574 "x coord of the lower-left point of the first "
01575 "field used for contamination measurement. If not modified, default value will be 1.",
01576 "CPL_TYPE_INT", llx1,
01577 "lly1",
01578 "y coord of the lower-left point of the first "
01579 "field used for contamination measurement. If not modified, default value will be 1.",
01580 "CPL_TYPE_INT", lly1,
01581 "urx1",
01582 "x coord of the upper-right point of the first "
01583 "field used for contamination measurement. If not modified, default value will be X dimension of the input image.",
01584 "CPL_TYPE_INT", urx1,
01585 "ury1",
01586 "y coord of the upper-right point of the first "
01587 "field used for contamination measurement. If not modified, default value will be Y dimension of the input image.",
01588 "CPL_TYPE_INT", ury1,
01589 "llx2",
01590 "x coord of the lower-left point of the second "
01591 "field used for contamination measurement. If not modified, default value will be 1.",
01592 "CPL_TYPE_INT", llx2,
01593 "lly2",
01594 "y coord of the lower-left point of the second "
01595 "field used for contamination measurement. If not modified, default value will be 1.",
01596 "CPL_TYPE_INT", lly2,
01597 "urx2",
01598 "x coord of the upper-right point of the second "
01599 "field used for contamination measurement. If not modified, default value will be half of the X dimension of the input image.",
01600 "CPL_TYPE_INT", urx2,
01601 "ury2",
01602 "y coord of the upper-right point of the second "
01603 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01604 "CPL_TYPE_INT", ury2,
01605 "llx3",
01606 "x coord of the lower-left point of the third "
01607 "field used for contamination measurement. If not modified, default value will be 1.",
01608 "CPL_TYPE_INT", llx3,
01609 "lly3",
01610 "y coord of the lower-left point of the third "
01611 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01612 "CPL_TYPE_INT", lly3,
01613 "urx3",
01614 "x coord of the upper-right point of the third "
01615 "field used for contamination measurement. If not modified, default value will be half of X dimension of the image.",
01616 "CPL_TYPE_INT", urx3,
01617 "ury3",
01618 "y coord of the upper-right point of the third "
01619 "field used for contamination measurement. If not modified, default value will be Y dimension of the image.",
01620 "CPL_TYPE_INT", ury3,
01621 "llx4",
01622 "x coord of the lower-left point of the fourth "
01623 "field used for contamination measurement. If not modified, default value will be half of X dimension of the image.",
01624 "CPL_TYPE_INT", llx4,
01625 "lly4",
01626 "y coord of the lower-left point of the fourth "
01627 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01628 "CPL_TYPE_INT", lly4,
01629 "urx4",
01630 "x coord of the upper-right point of the fourth "
01631 "field used for contamination measurement. If not modified, default value will be X dimension of the image.",
01632 "CPL_TYPE_INT", urx4,
01633 "ury4",
01634 "y coord of the upper-right point of the fourth "
01635 "field used for contamination measurement. If not modified, default value will be Y dimension of the input image.",
01636 "CPL_TYPE_INT", ury4,
01637 "llx5",
01638 "x coord of the lower-left point of the fifth "
01639 "field used for contamination measurement. If not modified, default value will be half of the X dimension of the input image.",
01640 "CPL_TYPE_INT", llx5,
01641 "lly5",
01642 "y coord of the lower-left point of the fifth "
01643 "field used for contamination measurement. If not modified, default value will be 1.",
01644 "CPL_TYPE_INT", lly5,
01645 "urx5",
01646 "x coord of the upper-right point of the fifth "
01647 "field used for contamination measurement. If not modified, default value will be X dimension of the image.",
01648 "CPL_TYPE_INT", urx5,
01649 "ury5",
01650 "y coord of the upper-right point of the fifth "
01651 "field used for contamination measurement. If not modified, default value will be half of Y dimension of the input image.",
01652 "CPL_TYPE_INT", ury5);
01653 cpl_ensure_code(!erroropt, erroropt);
01654 }
01655
01656 cpl_ensure_code(!error, error);
01657
01658 return cpl_error_get_code();
01659 }
01660
01661
01670
01671 static cpl_error_code
01672 irplib_detmon_lg_retrieve_parlist(const char * pipeline_name,
01673 const char * recipe_name,
01674 const cpl_parameterlist * parlist,
01675 cpl_boolean opt_nir)
01676 {
01677
01678 char * par_name;
01679 cpl_parameter * par;
01680
01681
01682 par_name = cpl_sprintf("%s.%s.method", pipeline_name, recipe_name);
01683 assert(par_name != NULL);
01684 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01685 detmon_lg_config.method = cpl_parameter_get_string(par);
01686 cpl_free(par_name);
01687
01688
01689 detmon_lg_config.order =
01690 irplib_detmon_retrieve_par_int("order", pipeline_name, recipe_name,
01691 parlist);
01692
01693
01694 detmon_lg_config.kappa =
01695 irplib_detmon_retrieve_par_double("kappa", pipeline_name, recipe_name,
01696 parlist);
01697
01698
01699 detmon_lg_config.niter =
01700 irplib_detmon_retrieve_par_int("niter", pipeline_name, recipe_name,
01701 parlist);
01702
01703
01704 detmon_lg_config.llx =
01705 irplib_detmon_retrieve_par_int("llx", pipeline_name, recipe_name,
01706 parlist);
01707
01708
01709 detmon_lg_config.lly =
01710 irplib_detmon_retrieve_par_int("lly", pipeline_name, recipe_name,
01711 parlist);
01712
01713
01714 detmon_lg_config.urx =
01715 irplib_detmon_retrieve_par_int("urx", pipeline_name, recipe_name,
01716 parlist);
01717
01718
01719 detmon_lg_config.ury =
01720 irplib_detmon_retrieve_par_int("ury", pipeline_name, recipe_name,
01721 parlist);
01722
01723
01724 detmon_lg_config.ref_level =
01725 irplib_detmon_retrieve_par_int("ref_level", pipeline_name, recipe_name,
01726 parlist);
01727
01728
01729 par_name =
01730 cpl_sprintf("%s.%s.intermediate", pipeline_name, recipe_name);
01731 assert(par_name != NULL);
01732 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01733 detmon_lg_config.intermediate = cpl_parameter_get_bool(par);
01734 cpl_free(par_name);
01735
01736
01737 par_name = cpl_sprintf("%s.%s.autocorr", pipeline_name, recipe_name);
01738 assert(par_name != NULL);
01739 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01740 detmon_lg_config.autocorr = cpl_parameter_get_bool(par);
01741 cpl_free(par_name);
01742
01743
01744 par_name = cpl_sprintf("%s.%s.collapse", pipeline_name, recipe_name);
01745 assert(par_name != NULL);
01746 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01747 detmon_lg_config.collapse = cpl_parameter_get_bool(par);
01748 cpl_free(par_name);
01749
01750
01751 par_name = cpl_sprintf("%s.%s.rescale", pipeline_name, recipe_name);
01752 assert(par_name != NULL);
01753 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01754 detmon_lg_config.rescale = cpl_parameter_get_bool(par);
01755 cpl_free(par_name);
01756
01757
01758 par_name = cpl_sprintf("%s.%s.pix2pix", pipeline_name, recipe_name);
01759 assert(par_name != NULL);
01760 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01761 detmon_lg_config.pix2pix = cpl_parameter_get_bool(par);
01762 cpl_free(par_name);
01763
01764
01765 par_name = cpl_sprintf("%s.%s.bpmbin", pipeline_name, recipe_name);
01766 assert(par_name != NULL);
01767 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01768 detmon_lg_config.bpmbin = cpl_parameter_get_bool(par);
01769 cpl_free(par_name);
01770
01771
01772 detmon_lg_config.filter =
01773 irplib_detmon_retrieve_par_int("filter", pipeline_name,
01774 recipe_name, parlist);
01775
01776
01777 detmon_lg_config.m =
01778 irplib_detmon_retrieve_par_int("m", pipeline_name, recipe_name, parlist);
01779
01780
01781 detmon_lg_config.n =
01782 irplib_detmon_retrieve_par_int("n", pipeline_name, recipe_name, parlist);
01783
01784
01785 par_name = cpl_sprintf("%s.%s.tolerance", pipeline_name, recipe_name);
01786 assert(par_name != NULL);
01787 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01788 detmon_lg_config.tolerance = cpl_parameter_get_double(par);
01789 cpl_free(par_name);
01790
01791
01792 par_name = cpl_sprintf("%s.%s.pafname", pipeline_name, recipe_name);
01793 assert(par_name != NULL);
01794 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01795 detmon_lg_config.pafname = cpl_parameter_get_string(par);
01796 cpl_free(par_name);
01797
01798 if(opt_nir == OPT) {
01799
01800 detmon_lg_config.llx1 =
01801 irplib_detmon_retrieve_par_int("llx1", pipeline_name, recipe_name,
01802 parlist);
01803
01804
01805 detmon_lg_config.lly1 =
01806 irplib_detmon_retrieve_par_int("lly1", pipeline_name, recipe_name,
01807 parlist);
01808
01809
01810 detmon_lg_config.urx1 =
01811 irplib_detmon_retrieve_par_int("urx1", pipeline_name, recipe_name,
01812 parlist);
01813
01814
01815 detmon_lg_config.ury1 =
01816 irplib_detmon_retrieve_par_int("ury1", pipeline_name, recipe_name,
01817 parlist);
01818
01819
01820 detmon_lg_config.llx2 =
01821 irplib_detmon_retrieve_par_int("llx2", pipeline_name, recipe_name,
01822 parlist);
01823
01824
01825 detmon_lg_config.lly2 =
01826 irplib_detmon_retrieve_par_int("lly2", pipeline_name, recipe_name,
01827 parlist);
01828
01829
01830 detmon_lg_config.urx2 =
01831 irplib_detmon_retrieve_par_int("urx2", pipeline_name, recipe_name,
01832 parlist);
01833
01834
01835 detmon_lg_config.ury2 =
01836 irplib_detmon_retrieve_par_int("ury2", pipeline_name, recipe_name,
01837 parlist);
01838
01839
01840 detmon_lg_config.llx3 =
01841 irplib_detmon_retrieve_par_int("llx3", pipeline_name, recipe_name,
01842 parlist);
01843
01844
01845 detmon_lg_config.lly3 =
01846 irplib_detmon_retrieve_par_int("lly3", pipeline_name, recipe_name,
01847 parlist);
01848
01849
01850 detmon_lg_config.urx3 =
01851 irplib_detmon_retrieve_par_int("urx3", pipeline_name, recipe_name,
01852 parlist);
01853
01854
01855 detmon_lg_config.ury3 =
01856 irplib_detmon_retrieve_par_int("ury3", pipeline_name, recipe_name,
01857 parlist);
01858
01859
01860 detmon_lg_config.llx4 =
01861 irplib_detmon_retrieve_par_int("llx4", pipeline_name, recipe_name,
01862 parlist);
01863
01864
01865 detmon_lg_config.lly4 =
01866 irplib_detmon_retrieve_par_int("lly4", pipeline_name, recipe_name,
01867 parlist);
01868
01869
01870 detmon_lg_config.urx4 =
01871 irplib_detmon_retrieve_par_int("urx4", pipeline_name, recipe_name,
01872 parlist);
01873
01874
01875 detmon_lg_config.ury4 =
01876 irplib_detmon_retrieve_par_int("ury4", pipeline_name, recipe_name,
01877 parlist);
01878
01879
01880 detmon_lg_config.llx5 =
01881 irplib_detmon_retrieve_par_int("llx5", pipeline_name, recipe_name,
01882 parlist);
01883
01884
01885 detmon_lg_config.lly5 =
01886 irplib_detmon_retrieve_par_int("lly5", pipeline_name, recipe_name,
01887 parlist);
01888
01889
01890 detmon_lg_config.urx5 =
01891 irplib_detmon_retrieve_par_int("urx5", pipeline_name, recipe_name,
01892 parlist);
01893
01894
01895 detmon_lg_config.ury5 =
01896 irplib_detmon_retrieve_par_int("ury5", pipeline_name, recipe_name,
01897 parlist);
01898 }
01899
01900
01901 detmon_lg_config.exts =
01902 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
01903 parlist);
01904
01905 if(cpl_error_get_code()) {
01906 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
01907 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
01908 }
01909
01910
01911 return cpl_error_get_code();
01912 }
01913
01914
01920
01921 static cpl_error_code
01922 irplib_detmon_lg_check_defaults(const cpl_image * reference)
01923 {
01924 const int nx = cpl_image_get_size_x(reference);
01925 const int ny = cpl_image_get_size_y(reference);
01926
01927 if(detmon_lg_config.llx == -1)
01928 detmon_lg_config.llx = 1;
01929 if(detmon_lg_config.lly == -1)
01930 detmon_lg_config.lly = 1;
01931 if(detmon_lg_config.urx == -1)
01932 detmon_lg_config.urx = nx;
01933 if(detmon_lg_config.ury == -1)
01934 detmon_lg_config.ury = ny;
01935
01936 if(detmon_lg_config.llx1 == -1)
01937 detmon_lg_config.llx1 = 1;
01938 if(detmon_lg_config.lly1 == -1)
01939 detmon_lg_config.lly1 = 1;
01940 if(detmon_lg_config.urx1 == -1)
01941 detmon_lg_config.urx1 = nx;
01942 if(detmon_lg_config.ury1 == -1)
01943 detmon_lg_config.ury1 = ny;
01944
01945 if(detmon_lg_config.llx2 == -1)
01946 detmon_lg_config.llx2 = 1;
01947 if(detmon_lg_config.lly2 == -1)
01948 detmon_lg_config.lly2 = 1;
01949 if(detmon_lg_config.urx2 == -1)
01950 detmon_lg_config.urx2 = nx / 2;
01951 if(detmon_lg_config.ury2 == -1)
01952 detmon_lg_config.ury2 = ny / 2;
01953
01954 if(detmon_lg_config.llx3 == -1)
01955 detmon_lg_config.llx3 = 1;
01956 if(detmon_lg_config.lly3 == -1)
01957 detmon_lg_config.lly3 = ny / 2;
01958 if(detmon_lg_config.urx3 == -1)
01959 detmon_lg_config.urx3 = nx / 2;
01960 if(detmon_lg_config.ury3 == -1)
01961 detmon_lg_config.ury3 = ny;
01962
01963 if(detmon_lg_config.llx4 == -1)
01964 detmon_lg_config.llx4 = nx / 2;
01965 if(detmon_lg_config.lly4 == -1)
01966 detmon_lg_config.lly4 = ny / 2;
01967 if(detmon_lg_config.urx4 == -1)
01968 detmon_lg_config.urx4 = nx;
01969 if(detmon_lg_config.ury4 == -1)
01970 detmon_lg_config.ury4 = ny;
01971
01972 if(detmon_lg_config.llx5 == -1)
01973 detmon_lg_config.llx5 = nx / 2;
01974 if(detmon_lg_config.lly5 == -1)
01975 detmon_lg_config.lly5 = 1;
01976 if(detmon_lg_config.urx5 == -1)
01977 detmon_lg_config.urx5 = nx;
01978 if(detmon_lg_config.ury5 == -1)
01979 detmon_lg_config.ury5 = ny / 2;
01980
01981 if(detmon_lg_config.intermediate == TRUE) {
01982 cpl_msg_warning(cpl_func, "PLEASE NOTE: The --intermediate option saves the difference and correlation images produced during autocorrelation computation. Therefore, --autocorr option has been automatically activated. If you didn't want to run this, please abort and rerun.");
01983 detmon_lg_config.autocorr = TRUE;
01984 }
01985
01986 #ifndef HAVE_SFFTW
01987 if(detmon_lg_config.autocorr == TRUE)
01988 cpl_msg_warning(cpl_func,
01989 "You don't have FFTW installed in your system."
01990 " Please note that use of --autocorr option without it "
01991 "will result in an execution time close to 10 minutes.");
01992
01993 #endif
01994
01995 detmon_lg_config.lamp_stability = 0.0;
01996
01997 detmon_lg_config.lamp_ok = FALSE;
01998
01999 detmon_lg_config.cr = 0.0;
02000
02001 return cpl_error_get_code();
02002 }
02003
02004
02015
02016 static cpl_error_code
02017 irplib_detmon_lg_split_onoff(const cpl_frameset * cur_fset,
02018 cpl_frameset * cur_fset_on,
02019 cpl_frameset * cur_fset_off,
02020 const char *tag_on,
02021 const char *tag_off)
02022 {
02023 int nframes;
02024 int i;
02025
02026 const cpl_frame * first;
02027 const cpl_frame * second;
02028
02029 const char * first_tag;
02030 const char * second_tag;
02031
02032 cpl_frame * cur_frame_dup = NULL;
02033
02034 skip_if((first = cpl_frameset_get_first_const(cur_fset)) == NULL);
02035 skip_if((second = cpl_frameset_get_next_const (cur_fset)) == NULL);
02036
02037 skip_if((first_tag = cpl_frame_get_tag(first)) == NULL);
02038 skip_if((second_tag = cpl_frame_get_tag(second)) == NULL);
02039
02040 #if 0
02041 if (opt_nir == OPT &&
02042 ((!strcmp(first_tag, tag_on ) && !strcmp(second_tag, tag_off)) ||
02043 (!strcmp(first_tag, tag_off) && !strcmp(second_tag, tag_on )))) {
02044 detmon_lg_config.lamp_ok = TRUE;
02045 }
02046 #endif
02047
02048 nframes = cpl_frameset_get_size(cur_fset);
02049 for(i = detmon_lg_config.lamp_ok ? 2 : 0; i < nframes; i++) {
02050 const cpl_frame * cur_frame =
02051 cpl_frameset_get_frame_const(cur_fset, i);
02052 char * tag;
02053
02054
02055 cur_frame_dup = cpl_frame_duplicate(cur_frame);
02056 tag = (char *) cpl_frame_get_tag(cur_frame_dup);
02057
02058
02059 if(!strcmp(tag, tag_on)) {
02060 skip_if(cpl_frameset_insert(cur_fset_on, cur_frame_dup));
02061 } else if(!strcmp(tag, tag_off)) {
02062 skip_if(cpl_frameset_insert(cur_fset_off, cur_frame_dup));
02063 } else {
02064 cpl_frame_delete(cur_frame_dup);
02065 cur_frame_dup = NULL;
02066 }
02067 }
02068 cur_frame_dup = NULL;
02069
02070 end_skip;
02071
02072 cpl_frame_delete(cur_frame_dup);
02073
02074 return cpl_error_get_code();
02075 }
02076
02077
02101
02102
02103 static cpl_error_code
02104 irplib_detmon_lg_reduce(const cpl_frameset * set_on,
02105 const cpl_frameset * set_off,
02106 int *selection_on,
02107 int *selection_off,
02108 int nsets_extracted,
02109 cpl_imagelist ** coeffs_ptr,
02110 cpl_table * gain_table,
02111 cpl_table * linear_table,
02112 cpl_image ** bpm_ptr,
02113 cpl_imagelist * autocorr_images,
02114 cpl_imagelist * diff_flats,
02115 cpl_propertylist * qclist,
02116 int (* load_fset) (const cpl_frameset *,
02117 cpl_type,
02118 cpl_imagelist *),
02119 const cpl_boolean opt_nir,
02120 int whichext)
02121 {
02122 int i;
02123 cpl_imagelist * linearity_inputs = NULL;
02124 cpl_imagelist * opt_offs = NULL;
02125 int nsets;
02126 cpl_propertylist * reflist = NULL;
02127 int dit_nskip=0;
02128
02129 cpl_ensure(set_on != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
02130 cpl_ensure(set_off != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
02131
02132 nsets = cpl_frameset_get_size(set_on) / 2;
02133
02134 if(detmon_lg_config.collapse) {
02135
02136
02137
02138
02139
02140
02141 const cpl_frame *first = cpl_frameset_get_first_const(set_off);
02142 cpl_frame *dup_first = cpl_frame_duplicate(first);
02143
02144 const cpl_frame *second = cpl_frameset_get_next_const(set_off);
02145 cpl_frame *dup_second = cpl_frame_duplicate(second);
02146
02147 cpl_frameset *raw_offs = cpl_frameset_new();
02148
02149 cpl_frameset_insert(raw_offs, dup_first);
02150 cpl_frameset_insert(raw_offs, dup_second);
02151
02152 opt_offs = cpl_imagelist_load_frameset(raw_offs, CPL_TYPE_FLOAT,
02153 0, whichext);
02154
02155 cpl_frameset_delete(raw_offs);
02156
02157 }
02158
02159 skip_if(irplib_detmon_lg_reduce_init(gain_table,
02160 linear_table,
02161 &linearity_inputs,
02162 opt_nir));
02163
02164 if (!strcmp(detmon_lg_config.method, "PTC"))
02165 cpl_msg_warning(cpl_func, "PTC method incompatible with lamp stability computation");
02166 else if(!detmon_lg_config.collapse)
02167 skip_if(irplib_detmon_lg_lamp_stab(set_on, set_off,
02168 opt_nir, whichext));
02169
02170
02171 skip_if(cpl_table_unselect_all(linear_table));
02172 skip_if(cpl_table_unselect_all(gain_table));
02173
02174
02175
02176 for(i = 0; i < nsets ; i++) {
02177 skip_if(irplib_detmon_lg_reduce_dit(set_on, selection_on, i,&dit_nskip,
02178 nsets_extracted, set_off,
02179 selection_off, linear_table,
02180 gain_table, linearity_inputs,
02181 qclist, opt_nir,
02182 autocorr_images, diff_flats,
02183 opt_offs, load_fset, whichext));
02184 }
02185
02186 skip_if(irplib_detmon_add_adl_column(linear_table, opt_nir));
02187
02188
02189
02190
02191
02192 skip_if(cpl_table_erase_selected(gain_table));
02193 skip_if(cpl_table_erase_selected(linear_table));
02194
02195 reflist = cpl_propertylist_new();
02196 skip_if(cpl_propertylist_append_bool(reflist, "ADU", FALSE));
02197 skip_if(cpl_table_sort(gain_table, reflist));
02198
02199
02200
02201
02202
02203
02204
02205 skip_if(irplib_detmon_lg_reduce_all(linear_table,
02206 qclist, coeffs_ptr, bpm_ptr,
02207 linearity_inputs,
02208 gain_table, whichext, opt_nir));
02209
02210 end_skip;
02211
02212 cpl_imagelist_delete(linearity_inputs);
02213 cpl_imagelist_delete(opt_offs);
02214 cpl_propertylist_delete(reflist);
02215
02216 return cpl_error_get_code();
02217 }
02218
02219
02227
02228 static cpl_error_code
02229 irplib_detmon_lg_lamp_stab(const cpl_frameset * lamps,
02230 const cpl_frameset * darks,
02231 cpl_boolean opt_nir,
02232 int whichext)
02233 {
02234
02235
02236
02237
02238
02239
02240 int nb_lamps;
02241 cpl_vector * selection = NULL;
02242 cpl_propertylist * plist;
02243 double dit_lamp, dit_dark;
02244 int dit_stab;
02245 cpl_imagelist * lamps_data = NULL;
02246 cpl_imagelist * darks_data = NULL;
02247 double * stab_levels = NULL;
02248 int i, j;
02249 double * ditvals = NULL;
02250 int last_stab = 0;
02251
02252
02253 cpl_ensure_code((nb_lamps = cpl_frameset_get_size(lamps)) >= 3,
02254 CPL_ERROR_ILLEGAL_INPUT);
02255 cpl_ensure_code(cpl_frameset_get_size(darks) == nb_lamps,
02256 CPL_ERROR_ILLEGAL_INPUT);
02257
02258
02259 cpl_msg_info(__func__, "Checking DIT consistency");
02260 selection = cpl_vector_new(nb_lamps);
02261 ditvals = cpl_malloc(nb_lamps * sizeof(double));
02262 dit_stab = 0;
02263 for (i = 0; i < nb_lamps; i++) {
02264 const cpl_frame * c_lamp;
02265 const cpl_frame * c_dark;
02266
02267 skip_if (cpl_error_get_code());
02268
02269
02270 c_lamp = cpl_frameset_get_frame_const(lamps, i);
02271 plist = cpl_propertylist_load(cpl_frame_get_filename(c_lamp), 0);
02272 if(opt_nir)
02273 dit_lamp = (double)irplib_pfits_get_dit(plist);
02274 else
02275 dit_lamp = (double)irplib_pfits_get_dit_opt(plist);
02276 cpl_propertylist_delete(plist);
02277 skip_if (cpl_error_get_code());
02278
02279
02280 c_dark = cpl_frameset_get_frame_const(darks, i);
02281 plist = cpl_propertylist_load(cpl_frame_get_filename(c_dark), 0);
02282 if(opt_nir)
02283 dit_dark = (double)irplib_pfits_get_dit(plist);
02284 else
02285 dit_dark = (double)irplib_pfits_get_dit_opt(plist);
02286 cpl_propertylist_delete(plist);
02287 skip_if (cpl_error_get_code());
02288
02289
02290 if (fabs(dit_dark-dit_lamp) > 1e-3) {
02291 cpl_msg_error(__func__, "DIT not consistent between LAMP and DARK");
02292
02293 skip_if(1);
02294 }
02295 ditvals[i] = dit_lamp;
02296
02297 if (i==0) {
02298 cpl_vector_set(selection, i, -1.0);
02299 dit_stab ++;
02300 last_stab = 0;
02301 } else {
02302
02303
02304
02305
02306 if (fabs(dit_lamp - ditvals[0]) < 1e-5 && i - last_stab > 3) {
02307 cpl_vector_set(selection, i, -1.0);
02308 dit_stab ++;
02309 last_stab = i;
02310 } else {
02311 cpl_vector_set(selection, i, 1.0);
02312 }
02313 }
02314 }
02315
02316
02317 if (dit_stab < 2) {
02318 cpl_msg_info(__func__, "Not enough frames for stability check");
02319 } else {
02320
02321
02322 cpl_msg_info(__func__, "Compute the differences lamp - dark");
02323 lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1,
02324 whichext);
02325 darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1,
02326 whichext);
02327 skip_if(cpl_imagelist_subtract(lamps_data,darks_data));
02328
02329
02330 cpl_msg_info(__func__, "Check the lamp stability");
02331 stab_levels = cpl_malloc(dit_stab * sizeof(double));
02332 j = 0;
02333 for (i=0; i<nb_lamps; i++) {
02334 if (cpl_vector_get(selection, i) < 0) {
02335 stab_levels[j] =
02336 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i));
02337 j++;
02338 }
02339 }
02340
02341
02342 for (i=1; i<dit_stab; i++) {
02343 if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
02344 detmon_lg_config.lamp_stability)
02345 detmon_lg_config.lamp_stability =
02346 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0];
02347 }
02348
02349
02350
02351 if (detmon_lg_config.lamp_stability > 0.01) {
02352 cpl_msg_warning(__func__,
02353 "level difference too high - proceed anyway");
02354 }
02355 }
02356 end_skip;
02357
02358 cpl_free(ditvals);
02359 cpl_vector_delete(selection);
02360 cpl_imagelist_delete(lamps_data);
02361 cpl_imagelist_delete(darks_data);
02362 cpl_free(stab_levels);
02363
02364 return cpl_error_get_code();
02365 }
02366
02367
02395
02396 static cpl_error_code
02397 irplib_detmon_lg_reduce_dit(const cpl_frameset * set_on,
02398 int * selection_on,
02399 const int dit_nb,
02400 int * dit_nskip,
02401 int nsets_extracted,
02402 const cpl_frameset * set_off,
02403 int * selection_off,
02404 cpl_table * linear_table,
02405 cpl_table * gain_table,
02406 cpl_imagelist * linearity_inputs,
02407 cpl_propertylist * qclist,
02408 cpl_boolean opt_nir,
02409 cpl_imagelist * autocorr_images,
02410 cpl_imagelist * diff_flats,
02411 cpl_imagelist * opt_offs,
02412 int (* load_fset) (const cpl_frameset *,
02413 cpl_type,
02414 cpl_imagelist *),
02415 int whichext)
02416 {
02417 cpl_frameset * pair_on = NULL;
02418 cpl_frameset * pair_off = NULL;
02419 cpl_imagelist * ons = NULL;
02420 cpl_imagelist * offs = NULL;
02421 int with_equal_dit = 0;
02422 cpl_boolean follow = CPL_TRUE;
02423 cpl_imagelist * masterl = NULL;
02424 unsigned mode = detmon_lg_config.autocorr ? IRPLIB_GAIN_WITH_AUTOCORR : 0;
02425 double c_dit;
02426 const char * filename;
02427 cpl_propertylist * plist = NULL;
02428
02429 mode = detmon_lg_config.collapse ?
02430 mode | IRPLIB_GAIN_COLLAPSE | IRPLIB_LIN_COLLAPSE:
02431 mode | IRPLIB_GAIN_NO_COLLAPSE | IRPLIB_LIN_NO_COLLAPSE;
02432 mode = detmon_lg_config.pix2pix ?
02433 mode | IRPLIB_LIN_PIX2PIX : mode;
02434 mode = opt_nir ?
02435 mode | IRPLIB_GAIN_NIR | IRPLIB_LIN_NIR :
02436 mode | IRPLIB_GAIN_OPT | IRPLIB_LIN_OPT ;
02437
02438
02439
02440 skip_if(irplib_detmon_pair_extract(set_on, selection_on, dit_nb, nsets_extracted, &with_equal_dit, 1, &pair_on));
02441
02442
02443
02444 if (load_fset != NULL) {
02445 ons = cpl_imagelist_new();
02446 (*load_fset)(pair_on, CPL_TYPE_FLOAT, ons);
02447 } else {
02448 ons = cpl_imagelist_load_frameset(pair_on, CPL_TYPE_FLOAT, 1,whichext);
02449 }
02450 skip_if(ons == NULL);
02451
02452 if(detmon_lg_config.filter > 0) {
02453 double med1 =
02454 cpl_image_get_median_window(cpl_imagelist_get(ons, 0),
02455 detmon_lg_config.llx,
02456 detmon_lg_config.lly,
02457 detmon_lg_config.urx,
02458 detmon_lg_config.ury);
02459 double med2 =
02460 cpl_image_get_median_window(cpl_imagelist_get(ons, 1),
02461 detmon_lg_config.llx,
02462 detmon_lg_config.lly,
02463 detmon_lg_config.urx,
02464 detmon_lg_config.ury);
02465 if ( med1 > (double)detmon_lg_config.filter ||
02466 med2 > (double)detmon_lg_config.filter) {
02467 follow = CPL_FALSE;
02468 cpl_table_select_row(gain_table, dit_nb);
02469 cpl_table_select_row(linear_table, dit_nb);
02470 (*dit_nskip)++;
02471 cpl_msg_warning(cpl_func, "Frames of EXPTIME nb %d "
02472 "will not be taken into account for computation "
02473 "as they are above --filter threshold", dit_nb);
02474 }
02475 }
02476
02477 if (follow || detmon_lg_config.filter < 0) {
02478
02479
02480
02481
02482
02483
02484 if(!detmon_lg_config.collapse) {
02485
02486 if (!strcmp(detmon_lg_config.method, "MED") ||
02487 cpl_frameset_get_size(set_on) == cpl_frameset_get_size(set_off))
02488
02489 skip_if(irplib_detmon_pair_extract(set_off, selection_off,
02490 dit_nb, nsets_extracted,
02491 &with_equal_dit, 0,
02492 &pair_off));
02493 else
02494 skip_if(irplib_detmon_single_extract(set_off, selection_off,
02495 dit_nb, nsets_extracted,
02496 &with_equal_dit, 0,
02497 &pair_off));
02498
02499
02500
02501 if (load_fset != NULL) {
02502 offs = cpl_imagelist_new();
02503 (*load_fset)(pair_off, CPL_TYPE_FLOAT, offs);
02504 } else {
02505 offs = cpl_imagelist_load_frameset(pair_off, CPL_TYPE_FLOAT,
02506 1, whichext);
02507 }
02508 skip_if(offs == NULL);
02509 skip_if(cpl_error_get_code());
02510 } else {
02511
02512
02513
02514
02515 cpl_image * collapse;
02516 masterl = cpl_imagelist_load_frameset(set_off, CPL_TYPE_FLOAT,
02517 1, whichext);
02518 skip_if(masterl == NULL);
02519 skip_if(cpl_error_get_code());
02520
02521 collapse = cpl_imagelist_collapse_create(masterl);
02522 skip_if(collapse == NULL);
02523 skip_if(cpl_imagelist_set(masterl, collapse, 0));
02524
02525
02526 offs = (cpl_imagelist *)masterl;
02527 }
02528
02529
02530 if(detmon_lg_config.rescale) {
02531 skip_if(irplib_detmon_lg_rescale(ons));
02532 if (!detmon_lg_config.collapse &&
02533 !strcmp(detmon_lg_config.method, "MED"))
02534 skip_if(irplib_detmon_lg_rescale(offs));
02535 }
02536
02537
02538
02539 filename =
02540 cpl_frame_get_filename(cpl_frameset_get_first_const(pair_on));
02541 skip_if ((plist = cpl_propertylist_load(filename, 0)) == NULL);
02542
02543 if(opt_nir == NIR) {
02544 c_dit = irplib_pfits_get_dit(plist);
02545 } else {
02546 c_dit = irplib_pfits_get_exptime(plist);
02547 }
02548
02549
02550
02551 skip_if(irplib_detmon_lin_table_fill_row(linear_table, c_dit,
02552 linearity_inputs, ons, offs,
02553 detmon_lg_config.llx,
02554 detmon_lg_config.lly,
02555 detmon_lg_config.urx,
02556 detmon_lg_config.ury,
02557 dit_nb, *dit_nskip, mode));
02558
02559 if(opt_nir == OPT && dit_nb == nsets_extracted / 2) {
02560 irplib_detmon_opt_contamination(ons, offs, mode, qclist);
02561 }
02562
02563
02564
02565
02566
02567
02568
02569
02570 if(detmon_lg_config.collapse) {
02571 offs = (cpl_imagelist *) opt_offs;
02572 }
02573
02574 cpl_msg_info(cpl_func, "Computing GAIN for EXPTIME value nb %d",
02575 dit_nb + 1);
02576
02577
02578 if(cpl_imagelist_get_size(offs) == 1 && mode & IRPLIB_GAIN_NO_COLLAPSE && dit_nb == 0) {
02579 cpl_table_erase_column(gain_table, "MEAN_OFF1");
02580 cpl_table_erase_column(gain_table, "MEAN_OFF2");
02581 cpl_table_erase_column(gain_table, "SIG_OFF_DIF");
02582 cpl_table_erase_column(gain_table, "GAIN");
02583 cpl_table_erase_column(gain_table, "GAIN_CORR");
02584 cpl_table_new_column(gain_table, "MEAN_OFF", CPL_TYPE_DOUBLE);
02585 }
02586
02587 skip_if(irplib_detmon_gain_table_fill_row(gain_table, c_dit,
02588 autocorr_images,
02589 diff_flats, ons, offs,
02590 detmon_lg_config.kappa,
02591 detmon_lg_config.niter,
02592 detmon_lg_config.llx,
02593 detmon_lg_config.lly,
02594 detmon_lg_config.urx,
02595 detmon_lg_config.ury,
02596 detmon_lg_config.m,
02597 detmon_lg_config.n,
02598 dit_nb, mode));
02599 }
02600
02601 end_skip;
02602
02603 cpl_frameset_delete(pair_on);
02604 cpl_imagelist_delete(ons);
02605
02606 if(!detmon_lg_config.collapse ) {
02607 cpl_imagelist_delete(offs);
02608 }
02609
02610 if(!detmon_lg_config.collapse) {
02611 cpl_frameset_delete(pair_off);
02612 }
02613
02614 if(detmon_lg_config.collapse) {
02615 cpl_imagelist_delete(masterl);
02616 }
02617
02618 cpl_propertylist_delete(plist);
02619
02620 return cpl_error_get_code();
02621 }
02622
02623
02629
02630 static cpl_error_code
02631 irplib_detmon_add_adl_column(cpl_table * table,
02632 cpl_boolean opt_nir)
02633 {
02634 cpl_error_code error;
02635 double mean_med_dit;
02636 double *dits;
02637
02638 cpl_ensure_code(table != NULL, CPL_ERROR_NULL_INPUT);
02639
02640 mean_med_dit = cpl_table_get_column_mean(table, "MED_DIT");
02641 if (opt_nir == OPT)
02642 dits = cpl_table_get_data_double(table, "EXPTIME");
02643 else
02644 dits = cpl_table_get_data_double(table, "DIT");
02645
02646 error = cpl_table_copy_data_double(table, "ADL", dits);
02647 cpl_ensure_code(!error, error);
02648 error = cpl_table_multiply_scalar(table, "ADL", mean_med_dit);
02649 cpl_ensure_code(!error, error);
02650
02651 return cpl_error_get_code();
02652 }
02653
02654
02662
02663 static cpl_error_code
02664 irplib_detmon_lg_reduce_init(cpl_table * gain_table,
02665 cpl_table * linear_table,
02666 cpl_imagelist ** linearity_inputs,
02667 const cpl_boolean opt_nir)
02668 {
02669 skip_if(irplib_detmon_gain_table_create(gain_table, opt_nir));
02670 skip_if(irplib_detmon_lin_table_create(linear_table, opt_nir));
02671
02672 if(detmon_lg_config.pix2pix) {
02673 *linearity_inputs = cpl_imagelist_new();
02674 skip_if(*linearity_inputs == NULL);
02675 }
02676
02677 end_skip;
02678
02679 return cpl_error_get_code();
02680 }
02681
02682
02688
02689 static double
02690 irplib_pfits_get_dit(const cpl_propertylist * plist)
02691 {
02692 double dit;
02693
02694 dit = cpl_propertylist_get_double(plist, "ESO DET DIT");
02695
02696 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02697 cpl_msg_error(cpl_func, cpl_error_get_where());
02698 }
02699 return dit;
02700 }
02701
02702
02708
02709 static double
02710 irplib_pfits_get_dit_opt(const cpl_propertylist * plist)
02711 {
02712 double dit;
02713
02714 dit = cpl_propertylist_get_double(plist, "ESO DET WIN1 UIT1");
02715
02716 if(cpl_error_get_code() != CPL_ERROR_NONE) {
02717 cpl_msg_error(cpl_func, cpl_error_get_where());
02718 }
02719 return dit;
02720 }
02721
02722
02754
02755 static cpl_error_code
02756 irplib_detmon_gain_table_fill_row(cpl_table * gain_table, double c_dit,
02757 cpl_imagelist * autocorr_images,
02758 cpl_imagelist * diff_flats,
02759 const cpl_imagelist * ons,
02760 const cpl_imagelist * offs,
02761 double kappa, int nclip,
02762 int llx, int lly, int urx, int ury,
02763 int m, int n,
02764 const int pos, unsigned mode)
02765 {
02766 const cpl_image *image;
02767 double std = 0;
02768 cpl_image *on_dif = NULL;
02769 cpl_image *off_dif = NULL;
02770 double avg_on1, avg_on2;
02771 double avg_off1, avg_off2;
02772 double avg_on_dif, sig_on_dif;
02773 double avg_off_dif, sig_off_dif;
02774 double double_adu, autocorr, gain, gain_corr;
02775 double sigma, sigma_corr;
02776
02777 if (mode & IRPLIB_GAIN_NIR) {
02778 cpl_table_set(gain_table, "DIT", pos, c_dit);
02779 } else if (mode & IRPLIB_GAIN_OPT) {
02780 cpl_table_set(gain_table, "EXPTIME", pos, c_dit);
02781 } else {
02782 cpl_msg_error(cpl_func, "Mandatory mode (OPT or NIR) not provided");
02783 skip_if(1);
02784 }
02785
02786 skip_if((image = cpl_imagelist_get_const(ons, 0)) == NULL);
02787 skip_if(irplib_ksigma_clip(image, llx, lly, urx, ury, kappa,
02788 nclip, 1e-5, &avg_on1, &std));
02789 skip_if(cpl_table_set_double(gain_table, "MEAN_ON1", pos, avg_on1));
02790
02791 skip_if((image = cpl_imagelist_get_const(ons, 1)) == NULL);
02792 skip_if(irplib_ksigma_clip(image, llx, lly, urx, ury, kappa,
02793 nclip, 1e-5, &avg_on2, &std));
02794 skip_if(cpl_table_set_double(gain_table, "MEAN_ON2", pos, avg_on2));
02795
02796 on_dif =
02797 cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
02798 cpl_imagelist_get_const(ons, 1));
02799 skip_if(on_dif == NULL);
02800
02801 skip_if(irplib_ksigma_clip(on_dif, llx, lly, urx, ury, kappa,
02802 nclip, 1e-5,
02803 &avg_on_dif, &sig_on_dif));
02804 skip_if(cpl_table_set_double(gain_table, "SIG_ON_DIF", pos, sig_on_dif));
02805
02806
02807
02808 if(mode & IRPLIB_GAIN_WITH_AUTOCORR) {
02809 if (diff_flats) {
02810 cpl_image * diff = cpl_image_duplicate(on_dif);
02811 skip_if(cpl_imagelist_set(diff_flats, diff, pos));
02812 }
02813 if (autocorr_images) {
02814 cpl_image * corr;
02815 autocorr = irplib_detmon_autocorr_factor(on_dif, &corr, m, n);
02816 skip_if(cpl_imagelist_set(autocorr_images, corr, pos));
02817 } else {
02818 autocorr = irplib_detmon_autocorr_factor(on_dif, NULL, m, n);
02819 }
02820 } else {
02821 autocorr = 1.0;
02822 }
02823
02824 if (cpl_imagelist_get_size(offs) == 1 && mode & IRPLIB_GAIN_NO_COLLAPSE) {
02825
02826 skip_if(irplib_ksigma_clip(cpl_imagelist_get_const(offs, 0),
02827 llx, lly, urx, ury, kappa, nclip,
02828 1e-5, &avg_off1, &std));
02829 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF", pos, avg_off1));
02830
02831 } else if (mode & IRPLIB_GAIN_NO_COLLAPSE ||
02832 ( pos == 0 && mode & IRPLIB_GAIN_COLLAPSE )) {
02833 skip_if(irplib_ksigma_clip(cpl_imagelist_get_const(offs, 0),
02834 llx, lly, urx, ury, kappa, nclip,
02835 1e-5, &avg_off1, &std));
02836 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF1", pos, avg_off1));
02837 skip_if(irplib_ksigma_clip(cpl_imagelist_get_const(offs, 1),
02838 llx, lly, urx, ury, kappa, nclip,
02839 1e-5, &avg_off2, &std));
02840 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF2", pos, avg_off2));
02841 off_dif =
02842 cpl_image_subtract_create(cpl_imagelist_get_const(offs, 0),
02843 cpl_imagelist_get_const(offs, 1));
02844 skip_if(off_dif == NULL);
02845 skip_if(irplib_ksigma_clip(off_dif, llx, lly, urx, ury,
02846 kappa, nclip, 1e-5,
02847 &avg_off_dif, &sig_off_dif));
02848 skip_if(cpl_table_set_double(gain_table, "SIG_OFF_DIF",
02849 pos, sig_off_dif));
02850 } else if (pos > 0 && mode & IRPLIB_GAIN_COLLAPSE){
02851 int status;
02852 avg_off1 = cpl_table_get_double(gain_table, "MEAN_OFF1", 0, &status);
02853 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF1", pos, avg_off1));
02854 avg_off2 = cpl_table_get_double(gain_table, "MEAN_OFF2", 0, &status);
02855 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF2", pos, avg_off2));
02856 sig_off_dif = cpl_table_get_double(gain_table, "SIG_OFF_DIF",
02857 0, &status);
02858 skip_if(cpl_table_set_double(gain_table, "SIG_OFF_DIF",
02859 pos, sig_off_dif));
02860 }
02861
02862 if (cpl_imagelist_get_size(offs) == 1 && mode & IRPLIB_GAIN_NO_COLLAPSE)
02863 double_adu = (avg_on1 + avg_on2) - 2 * avg_off1;
02864 else {
02865 double_adu = (avg_on1 + avg_on2) - (avg_off1 + avg_off2);
02866
02867 sigma = (sig_on_dif * sig_on_dif) - (sig_off_dif * sig_off_dif);
02868
02869 sigma_corr = autocorr * sigma;
02870
02871 gain = double_adu / sigma;
02872
02873 gain_corr = double_adu / sigma_corr;
02874
02875 skip_if(cpl_table_set_double(gain_table, "GAIN", pos, gain));
02876 skip_if(cpl_table_set_double(gain_table, "GAIN_CORR", pos, gain_corr));
02877 }
02878
02879 skip_if(cpl_table_set_double(gain_table, "AUTOCORR", pos, autocorr));
02880 skip_if(cpl_table_set_double(gain_table, "ADU", pos, double_adu / 2));
02881
02882
02883 skip_if(cpl_table_set_double(gain_table, "Y_FIT",
02884 pos, sig_on_dif * sig_on_dif));
02885 skip_if(cpl_table_set_double(gain_table, "Y_FIT_CORR",
02886 pos, sig_on_dif * sig_on_dif));
02887 skip_if(cpl_table_set_double(gain_table, "X_FIT", pos, double_adu));
02888 skip_if(cpl_table_set_double(gain_table, "X_FIT_CORR",
02889 pos, double_adu / autocorr));
02890
02891 end_skip;
02892
02893 cpl_image_delete(on_dif);
02894 cpl_image_delete(off_dif);
02895
02896 return cpl_error_get_code();
02897 }
02898
02899
02906
02907
02908 static cpl_image *
02909 irplib_detmon_bpixs(const cpl_imagelist * coeffs,
02910 cpl_boolean bpmbin,
02911 const double kappa,
02912 int *nbpixs)
02913 {
02914 int size;
02915 int i;
02916 const cpl_image *first= cpl_imagelist_get_const(coeffs, 0);
02917 cpl_stats *stats;
02918 double cur_mean;
02919 double cur_stdev;
02920 double lo_cut;
02921 double hi_cut;
02922 cpl_mask *cur_mask;
02923 cpl_mask *mask = cpl_mask_new(cpl_image_get_size_x(first),
02924 cpl_image_get_size_y(first));
02925 cpl_image *cur_image = NULL;
02926 cpl_image *bpm = NULL;
02927 double p;
02928
02929 size = cpl_imagelist_get_size(coeffs);
02930
02931 if(!bpmbin) {
02932 bpm = cpl_image_new(cpl_image_get_size_x(first),
02933 cpl_image_get_size_y(first),
02934 CPL_TYPE_INT);
02935 }
02936
02937
02938 for(i = 0; i < size; i++) {
02939 const cpl_image * cur_coeff = cpl_imagelist_get_const(coeffs, i);
02940
02941 stats = cpl_stats_new_from_image(cur_coeff,
02942 CPL_STATS_MEAN | CPL_STATS_STDEV);
02943 cur_mean = cpl_stats_get_mean(stats);
02944 cur_stdev = cpl_stats_get_stdev(stats);
02945
02946 lo_cut = cur_mean - kappa * cur_stdev;
02947 hi_cut = cur_mean + kappa * cur_stdev;
02948
02949 cur_mask = cpl_mask_threshold_image_create(cur_coeff, lo_cut, hi_cut);
02950 cpl_mask_not(cur_mask);
02951
02952 if(!bpmbin) {
02953 cur_image = cpl_image_new_from_mask(cur_mask);
02954 p = pow(2, i);
02955 cpl_image_power(cur_image, p);
02956 cpl_image_add(bpm, cur_image);
02957 cpl_image_delete(cur_image);
02958 }
02959
02960 cpl_mask_or(mask, cur_mask);
02961
02962 cpl_mask_delete(cur_mask);
02963 cpl_stats_delete(stats);
02964 }
02965
02966 if(bpmbin) {
02967 bpm = cpl_image_new_from_mask(mask);
02968 }
02969
02970 *nbpixs += cpl_mask_count(mask);
02971
02972 cpl_mask_delete(mask);
02973
02974 return bpm;
02975 }
02976
02977
02989
02990
02991 static double
02992 irplib_detmon_autocorr_factor(const cpl_image * image,
02993 cpl_image ** autocorr_image, int m, int n)
02994 {
02995 cpl_image * mycorr_image;
02996 double autocorr;
02997
02998 #ifdef HAVE_SFFTW
02999 mycorr_image = irplib_detmon_image_correlate(image, image, m, n);
03000 #else
03001 mycorr_image = irplib_detmon_autocorrelate(image, m, n);
03002 #endif
03003 if(mycorr_image == NULL) {
03004 return -1;
03005 }
03006
03007 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), -1);
03008
03009 autocorr = cpl_image_get_flux(mycorr_image);
03010
03011 if (autocorr_image) *autocorr_image = mycorr_image;
03012 else cpl_image_delete(mycorr_image);
03013
03014 return autocorr;
03015 }
03016
03017
03048
03049 static cpl_error_code
03050 irplib_detmon_lg_save(const cpl_parameterlist * parlist,
03051 cpl_frameset * frameset,
03052 const char *recipe_name,
03053 const char *pipeline_name,
03054 const char *pafregexp,
03055 const cpl_propertylist * pro_lintbl,
03056 const cpl_propertylist * pro_gaintbl,
03057 const cpl_propertylist * pro_coeffscube,
03058 const cpl_propertylist * pro_bpm,
03059 const cpl_propertylist * pro_corr,
03060 const cpl_propertylist * pro_diff,
03061 const char *package,
03062 cpl_imagelist * coeffs,
03063 cpl_table * gain_table,
03064 cpl_table * linear_table,
03065 cpl_image * bpms,
03066 cpl_imagelist * autocorr_images,
03067 cpl_imagelist * diff_flats,
03068 cpl_propertylist * qclist,
03069 const int flag_sets,
03070 const int which_set,
03071 const cpl_frameset * usedframes,
03072 int whichext)
03073 {
03074
03075 cpl_frame *ref_frame;
03076 cpl_propertylist *plist = NULL;
03077 cpl_propertylist *mainplist = NULL;
03078 char *name_o = NULL;
03079 int nb_images;
03080 int i;
03081 cpl_error_code error;
03082 cpl_propertylist * xplist = NULL;
03083 cpl_propertylist * paflist = NULL;
03084
03085 cpl_propertylist * mypro_lintbl =
03086 cpl_propertylist_duplicate(pro_lintbl);
03087 cpl_propertylist * mypro_gaintbl =
03088 cpl_propertylist_duplicate(pro_gaintbl);
03089 cpl_propertylist * mypro_coeffscube =
03090 cpl_propertylist_duplicate(pro_coeffscube);
03091 cpl_propertylist * mypro_bpm =
03092 cpl_propertylist_duplicate(pro_bpm);
03093 cpl_propertylist * mypro_corr =
03094 cpl_propertylist_duplicate(pro_corr);
03095 cpl_propertylist * mypro_diff =
03096 cpl_propertylist_duplicate(pro_diff);
03097
03098
03099 if (detmon_lg_config.exts < 0) {
03100 const char * filename =
03101 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
03102
03103
03104 xplist = cpl_propertylist_load_regexp(filename, whichext,
03105 "ESO DET|EXTNAME", 0);
03106
03107
03108 cpl_propertylist_erase_regexp(xplist, "DET CHIP LIVE", 0) ;
03109
03110
03111 skip_if(cpl_propertylist_append(xplist, qclist));
03112 }
03113
03114
03115
03116
03117 ref_frame = cpl_frameset_get_first(frameset);
03118
03119 skip_if((mainplist =
03120 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03121 0)) == NULL);
03122
03123
03124
03125
03126
03127
03128 if(!flag_sets) {
03129 name_o = cpl_sprintf("%s_linearity_table.fits", recipe_name);
03130 assert(name_o != NULL);
03131 } else {
03132 name_o =
03133 cpl_sprintf("%s_linearity_table_set%02d.fits", recipe_name,
03134 which_set);
03135 assert(name_o != NULL);
03136 }
03137
03138 if (detmon_lg_config.exts >= 0) {
03139
03140 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03141 cpl_propertylist_append(mypro_lintbl, qclist);
03142
03143 skip_if(cpl_dfs_save_table(frameset, NULL,parlist, usedframes, NULL,linear_table,
03144 NULL, recipe_name,
03145 mypro_lintbl, NULL, package, name_o));
03146 #else
03147 const char * procatg_lintbl =
03148 cpl_propertylist_get_string(mypro_lintbl, CPL_DFS_PRO_CATG);
03149
03150 cpl_propertylist_append(mypro_lintbl, qclist);
03151
03152 skip_if(cpl_dfs_save_table(frameset, parlist, usedframes, linear_table,
03153 NULL, recipe_name, procatg_lintbl,
03154 mypro_lintbl, NULL, package, name_o));
03155 #endif
03156 } else {
03157 if(whichext == 1) {
03158
03159 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03160 skip_if(cpl_dfs_save_table(frameset,NULL, parlist, usedframes, NULL, linear_table,
03161 xplist, recipe_name, mypro_lintbl,
03162 NULL, package, name_o));
03163 #else
03164 const char * procatg_lintbl =
03165 cpl_propertylist_get_string(mypro_lintbl, CPL_DFS_PRO_CATG);
03166
03167 skip_if(cpl_dfs_save_table(frameset, parlist, usedframes, linear_table,
03168 xplist, recipe_name, procatg_lintbl, mypro_lintbl,
03169 NULL, package, name_o));
03170 #endif
03171
03172 } else {
03173 skip_if(cpl_table_save(linear_table, NULL, xplist, name_o,
03174 CPL_IO_EXTEND));
03175 }
03176 }
03177
03178
03179 cpl_free(name_o);
03180 name_o = NULL;
03181
03182
03183
03184
03185
03186
03187 if(!flag_sets) {
03188 name_o = cpl_sprintf("%s_gain_table.fits", recipe_name);
03189 assert(name_o != NULL);
03190 } else {
03191 name_o =
03192 cpl_sprintf("%s_gain_table_set%02d.fits", recipe_name,
03193 which_set);
03194 assert(name_o != NULL);
03195 }
03196
03197 if (detmon_lg_config.exts >= 0) {
03198
03199 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03200 cpl_propertylist_append(mypro_gaintbl, qclist);
03201
03202 skip_if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,gain_table,
03203 NULL, recipe_name, mypro_gaintbl,
03204 NULL, package, name_o));
03205 #else
03206 const char * procatg_gaintbl =
03207 cpl_propertylist_get_string(mypro_gaintbl, CPL_DFS_PRO_CATG);
03208
03209 cpl_propertylist_append(mypro_gaintbl, qclist);
03210
03211 skip_if(cpl_dfs_save_table(frameset, parlist, usedframes, gain_table,
03212 NULL, recipe_name, procatg_gaintbl, mypro_gaintbl,
03213 NULL, package, name_o));
03214 #endif
03215 } else {
03216 if(whichext == 1) {
03217 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03218
03219 skip_if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, gain_table,
03220 xplist, recipe_name, mypro_gaintbl,
03221 NULL, package, name_o));
03222 #else
03223 const char * procatg_gaintbl =
03224 cpl_propertylist_get_string(mypro_gaintbl, CPL_DFS_PRO_CATG);
03225
03226 skip_if(cpl_dfs_save_table(frameset, parlist, usedframes, gain_table,
03227 xplist, recipe_name, procatg_gaintbl, mypro_gaintbl,
03228 NULL, package, name_o));
03229 #endif
03230 } else {
03231 skip_if(cpl_table_save(gain_table, NULL, xplist, name_o,
03232 CPL_IO_EXTEND));
03233 }
03234 }
03235
03236
03237 cpl_free(name_o);
03238 name_o = NULL;
03239
03240 if(detmon_lg_config.pix2pix) {
03241
03242
03243
03244
03245
03246
03247 if(!flag_sets) {
03248 name_o =
03249 cpl_sprintf("%s_coeffs_cube.fits", recipe_name);
03250 assert(name_o != NULL);
03251 } else {
03252 name_o =
03253 cpl_sprintf("%s_coeffs_cube_set%02d.fits",
03254 recipe_name, which_set);
03255 assert(name_o != NULL);
03256 }
03257
03258
03259 if(detmon_lg_config.exts >= 0) {
03260 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03261 cpl_propertylist_append(mypro_coeffscube, qclist);
03262
03263 skip_if(cpl_dfs_save_imagelist
03264 (frameset, NULL, parlist, usedframes, NULL,coeffs, CPL_BPP_IEEE_FLOAT,
03265 recipe_name, mypro_coeffscube, NULL, package,
03266 name_o));
03267 #else
03268 const char * procatg_coeffscube =
03269 cpl_propertylist_get_string(mypro_coeffscube, CPL_DFS_PRO_CATG);
03270 cpl_propertylist_append(mypro_coeffscube, qclist);
03271
03272 skip_if(cpl_dfs_save_imagelist
03273 (frameset, parlist, usedframes, coeffs, CPL_BPP_IEEE_FLOAT,
03274 recipe_name, procatg_coeffscube, mypro_coeffscube, NULL, package,
03275 name_o));
03276 #endif
03277 } else {
03278 if(whichext == 1) {
03279 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03280 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
03281 NULL, NULL,
03282 CPL_BPP_IEEE_FLOAT, recipe_name,
03283 mypro_coeffscube, NULL,
03284 package, name_o));
03285 #else
03286 const char * procatg_coeffscube =
03287 cpl_propertylist_get_string(mypro_coeffscube, CPL_DFS_PRO_CATG);
03288
03289 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
03290 CPL_BPP_IEEE_FLOAT, recipe_name,
03291 procatg_coeffscube, mypro_coeffscube, NULL,
03292 package, name_o));
03293 #endif
03294 skip_if(cpl_imagelist_save(coeffs,
03295 name_o, CPL_BPP_IEEE_FLOAT, xplist,
03296 CPL_IO_EXTEND));
03297 } else {
03298 skip_if(cpl_imagelist_save(coeffs,
03299 name_o, CPL_BPP_IEEE_FLOAT, xplist,
03300 CPL_IO_EXTEND));
03301 }
03302 }
03303 cpl_free(name_o);
03304 name_o = NULL;
03305
03306
03307
03308
03309
03310
03311 if(!flag_sets) {
03312 name_o = cpl_sprintf("%s_bpm.fits", recipe_name);
03313 assert(name_o != NULL);
03314 } else {
03315 name_o =
03316 cpl_sprintf("%s_bpm_set%02d.fits", recipe_name, which_set);
03317 assert(name_o != NULL);
03318 }
03319
03320
03321 if(detmon_lg_config.exts >= 0) {
03322 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03323 cpl_propertylist_append(mypro_bpm, qclist);
03324
03325 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL, bpms,
03326 CPL_BPP_IEEE_FLOAT, recipe_name,
03327 mypro_bpm, NULL, package,
03328 name_o));
03329 #else
03330 const char * procatg_bpm =
03331 cpl_propertylist_get_string(mypro_bpm, CPL_DFS_PRO_CATG);
03332
03333 cpl_propertylist_append(mypro_bpm, qclist);
03334
03335 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, bpms,
03336 CPL_BPP_IEEE_FLOAT, recipe_name,
03337 procatg_bpm, mypro_bpm, NULL, package,
03338 name_o));
03339 #endif
03340 } else {
03341 if (whichext == 1) {
03342 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03343 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,NULL, NULL,
03344 CPL_BPP_IEEE_FLOAT, recipe_name,
03345 mypro_bpm, NULL, package,
03346 name_o));
03347 #else
03348 const char * procatg_bpm =
03349 cpl_propertylist_get_string(mypro_bpm, CPL_DFS_PRO_CATG);
03350
03351 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
03352 CPL_BPP_IEEE_FLOAT, recipe_name,
03353 procatg_bpm, mypro_bpm, NULL, package,
03354 name_o));
03355 #endif
03356 skip_if(cpl_image_save(bpms, name_o, CPL_BPP_IEEE_FLOAT,
03357 xplist, CPL_IO_EXTEND));
03358 } else {
03359 skip_if(cpl_image_save(bpms, name_o, CPL_BPP_IEEE_FLOAT,
03360 xplist, CPL_IO_EXTEND));
03361 }
03362 }
03363
03364 cpl_free(name_o);
03365 name_o = NULL;
03366
03367 }
03368
03369 if(detmon_lg_config.intermediate) {
03370
03371
03372
03373 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE < CPL_VERSION(4, 8, 0)
03374 const char * procatg_corr =
03375 cpl_propertylist_get_string(mypro_corr, CPL_DFS_PRO_CATG);
03376
03377 const char * procatg_diff =
03378 cpl_propertylist_get_string(mypro_diff, CPL_DFS_PRO_CATG);
03379 #endif
03380
03381 int j;
03382
03383 nb_images = cpl_imagelist_get_size(autocorr_images);
03384 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
03385
03386 if(detmon_lg_config.exts >= 0)
03387 cpl_propertylist_append(mypro_corr, qclist);
03388
03389 for(i = 0; i < nb_images; i++) {
03390
03391 if(!flag_sets) {
03392 name_o =
03393 cpl_sprintf("%s_autocorr_%d.fits", recipe_name, i);
03394 assert(name_o != NULL);
03395 } else {
03396 name_o =
03397 cpl_sprintf("%s_autocorr_%d_set%02d.fits",
03398 recipe_name, i, which_set);
03399 assert(name_o != NULL);
03400 }
03401
03402
03403
03404 if(detmon_lg_config.exts >= 0) {
03405 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03406 skip_if(cpl_dfs_save_image
03407 (frameset, NULL, parlist, usedframes, NULL,
03408 cpl_imagelist_get(autocorr_images, i), CPL_BPP_IEEE_FLOAT,
03409 recipe_name, mypro_corr, NULL, package,
03410 name_o));
03411 #else
03412 skip_if(cpl_dfs_save_image
03413 (frameset, parlist, usedframes,
03414 cpl_imagelist_get(autocorr_images, i), CPL_BPP_IEEE_FLOAT,
03415 recipe_name, procatg_corr, mypro_corr, NULL, package,
03416 name_o));
03417 #endif
03418 } else {
03419 if(whichext == 1) {
03420 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03421 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,NULL,
03422 CPL_BPP_IEEE_FLOAT, recipe_name,
03423 mypro_corr, NULL,
03424 package, name_o));
03425 #else
03426 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
03427 CPL_BPP_IEEE_FLOAT, recipe_name,
03428 procatg_corr, mypro_corr, NULL,
03429 package, name_o));
03430 #endif
03431 skip_if(cpl_image_save(cpl_imagelist_get(autocorr_images, i),
03432 name_o, CPL_BPP_IEEE_FLOAT, xplist,
03433 CPL_IO_EXTEND));
03434 } else {
03435 skip_if(cpl_image_save(cpl_imagelist_get(autocorr_images, i),
03436 name_o, CPL_BPP_IEEE_FLOAT, xplist,
03437 CPL_IO_EXTEND));
03438 }
03439 }
03440 cpl_free(name_o);
03441 name_o = NULL;
03442 }
03443
03444
03445
03446
03447
03448 if(detmon_lg_config.exts >= 0)
03449 cpl_propertylist_append(mypro_diff, qclist);
03450
03451 for(i = 0; i < nb_images; i++) {
03452
03453 if(!flag_sets) {
03454 name_o =
03455 cpl_sprintf("%s_diff_flat_%d.fits", recipe_name, i);
03456 assert(name_o != NULL);
03457 } else {
03458 name_o =
03459 cpl_sprintf("%s_diff_flat_%d_set%02d.fits",
03460 recipe_name, i, which_set);
03461 assert(name_o != NULL);
03462 }
03463
03464
03465
03466 if(detmon_lg_config.exts >= 0) {
03467 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03468 skip_if(cpl_dfs_save_image
03469 (frameset, NULL, parlist, usedframes, NULL,
03470 cpl_imagelist_get(diff_flats, i), CPL_BPP_IEEE_FLOAT,
03471 recipe_name, mypro_diff, NULL, package,
03472 name_o));
03473 #else
03474 skip_if(cpl_dfs_save_image
03475 (frameset, parlist, usedframes,
03476 cpl_imagelist_get(diff_flats, i), CPL_BPP_IEEE_FLOAT,
03477 recipe_name, procatg_diff, mypro_diff, NULL, package,
03478 name_o));
03479 #endif
03480 } else {
03481 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE >= CPL_VERSION(4, 8, 0)
03482 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL, NULL,
03483 CPL_BPP_IEEE_FLOAT, recipe_name,
03484 mypro_diff, NULL,
03485 package, name_o));
03486 #else
03487 skip_if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
03488 CPL_BPP_IEEE_FLOAT, recipe_name,
03489 procatg_diff, mypro_diff, NULL,
03490 package, name_o));
03491 #endif
03492 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
03493 skip_if(cpl_image_save(cpl_imagelist_get(diff_flats, i),
03494 name_o, CPL_BPP_IEEE_FLOAT, xplist,
03495 CPL_IO_EXTEND));
03496 }
03497 }
03498 cpl_free(name_o);
03499 name_o = NULL;
03500 }
03501
03502 }
03503
03504
03505
03506
03507
03508 paflist = cpl_propertylist_new();
03509
03510
03511
03512 if(detmon_lg_config.exts >= 0) {
03513 skip_if((plist =
03514 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03515 detmon_lg_config.exts)) == NULL);
03516
03517 if(!flag_sets) {
03518 name_o = cpl_sprintf("%s.paf", detmon_lg_config.pafname);
03519 assert(name_o != NULL);
03520 } else {
03521 name_o = cpl_sprintf("%s_set%02d.paf",
03522 detmon_lg_config.pafname, which_set);
03523 assert(name_o != NULL);
03524 }
03525 } else {
03526 skip_if((plist =
03527 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03528 whichext)) == NULL);
03529
03530
03531 if(!flag_sets) {
03532 name_o = cpl_sprintf("%s_ext%02d.paf",
03533 detmon_lg_config.pafname, whichext);
03534 assert(name_o != NULL);
03535 } else {
03536 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf",
03537 detmon_lg_config.pafname,
03538 which_set, whichext);
03539 assert(name_o != NULL);
03540 }
03541 }
03542
03543
03544 skip_if(cpl_propertylist_copy_property_regexp(paflist, plist,
03545 pafregexp, 0));
03546 skip_if(cpl_propertylist_copy_property_regexp(paflist, mainplist,
03547 pafregexp, 0));
03548
03549 if(detmon_lg_config.exts >= 0)
03550 skip_if(error = cpl_propertylist_append(paflist, qclist));
03551 else
03552 skip_if(error = cpl_propertylist_append(paflist, xplist));
03553
03554
03555 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, paflist, name_o));
03556
03557 end_skip;
03558
03559 cpl_propertylist_delete(xplist);
03560 cpl_propertylist_delete(paflist);
03561 cpl_propertylist_delete(plist);
03562 cpl_free(name_o);
03563 cpl_propertylist_delete(mainplist);
03564
03565 cpl_propertylist_delete(mypro_lintbl);
03566 cpl_propertylist_delete(mypro_gaintbl);
03567 cpl_propertylist_delete(mypro_coeffscube);
03568 cpl_propertylist_delete(mypro_bpm);
03569 cpl_propertylist_delete(mypro_corr);
03570 cpl_propertylist_delete(mypro_diff);
03571
03572 return cpl_error_get_code();
03573 }
03574
03575
03576
03584
03585 static cpl_error_code
03586 irplib_detmon_opt_contamination(const cpl_imagelist * ons,
03587 const cpl_imagelist * offs,
03588 unsigned mode,
03589 cpl_propertylist * qclist)
03590 {
03591
03592 double median[5] = {0, 0, 0, 0, 0};
03593
03594 cpl_image * dif1=NULL;
03595 cpl_image * dif2=NULL;
03596 cpl_image * dif_avg=NULL;
03597 const char* kname=NULL;
03598 int offsize = cpl_imagelist_get_size(offs);
03599
03600
03601 dif1 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
03602 cpl_imagelist_get_const(offs, 0));
03603
03604 if (offsize == 1 || mode & IRPLIB_LIN_COLLAPSE)
03605 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
03606 cpl_imagelist_get_const(offs, 0));
03607 else if (mode & IRPLIB_LIN_NO_COLLAPSE)
03608 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
03609 cpl_imagelist_get_const(offs, 1));
03610
03611 dif_avg = cpl_image_average_create(dif1, dif2);
03612
03613 cpl_image_abs(dif_avg);
03614
03615 median[0] = cpl_image_get_median_window(dif_avg,
03616 detmon_lg_config.llx1,
03617 detmon_lg_config.lly1,
03618 detmon_lg_config.urx1,
03619 detmon_lg_config.ury1);
03620
03621 skip_if(0);
03622 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,1);
03623 skip_if(cpl_propertylist_append_double(qclist,kname,median[0]));
03624 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
03625
03626 median[1] = cpl_image_get_median_window(dif_avg,
03627 detmon_lg_config.llx2,
03628 detmon_lg_config.lly2,
03629 detmon_lg_config.urx2,
03630 detmon_lg_config.ury2);
03631
03632 skip_if(0);
03633 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,2);
03634 skip_if(cpl_propertylist_append_double(qclist,kname,median[1]));
03635 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
03636
03637 median[2] = cpl_image_get_median_window(dif_avg,
03638 detmon_lg_config.llx3,
03639 detmon_lg_config.lly3,
03640 detmon_lg_config.urx3,
03641 detmon_lg_config.ury3);
03642 skip_if(0);
03643
03644 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,3);
03645 skip_if(cpl_propertylist_append_double(qclist,kname,median[2]));
03646 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
03647
03648
03649 median[3] = cpl_image_get_median_window(dif_avg,
03650 detmon_lg_config.llx4,
03651 detmon_lg_config.lly4,
03652 detmon_lg_config.urx4,
03653 detmon_lg_config.ury4);
03654 skip_if(0);
03655
03656 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,4);
03657 skip_if(cpl_propertylist_append_double(qclist,kname,median[3]));
03658 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
03659
03660 median[4] = cpl_image_get_median_window(dif_avg,
03661 detmon_lg_config.llx5,
03662 detmon_lg_config.lly5,
03663 detmon_lg_config.urx5,
03664 detmon_lg_config.ury5);
03665 skip_if(0);
03666
03667 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,5);
03668 skip_if(cpl_propertylist_append_double(qclist,kname,median[4]));
03669 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
03670
03671 end_skip;
03672
03673 cpl_image_delete(dif1);
03674 cpl_image_delete(dif2);
03675 cpl_image_delete(dif_avg);
03676
03677 return cpl_error_get_code();
03678 }
03679
03680
03687
03688
03689
03690
03691
03692
03693
03694
03695
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722
03723
03724
03725
03726
03734
03735 int
03736 irplib_detmon_lg_dfs_set_groups(cpl_frameset * set,
03737 const char *tag_on, const char *tag_off)
03738 {
03739 cpl_frame *cur_frame;
03740 const char *tag;
03741 int nframes;
03742 int i;
03743
03744
03745 if(set == NULL)
03746 return -1;
03747
03748
03749 nframes = cpl_frameset_get_size(set);
03750
03751
03752 for(i = 0; i < nframes; i++) {
03753 cur_frame = cpl_frameset_get_frame(set, i);
03754 tag = cpl_frame_get_tag(cur_frame);
03755
03756
03757 if(!strcmp(tag, tag_on) || !strcmp(tag, tag_off))
03758 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
03759
03760
03761
03762
03763
03764 }
03765 return 0;
03766 }
03767
03768
03782
03783 static cpl_error_code
03784 irplib_detmon_lg_reduce_all(const cpl_table * linear_table,
03785 cpl_propertylist * qclist,
03786 cpl_imagelist ** coeffs_ptr,
03787 cpl_image ** bpms_ptr,
03788 const cpl_imagelist * linearity_inputs,
03789 const cpl_table * gain_table,
03790 int which_ext, cpl_boolean opt_nir)
03791 {
03792
03793 int nbpixs = 0;
03794 const int nsets = cpl_table_get_nrow(linear_table);
03795 int i;
03796 double autocorr;
03797 cpl_polynomial *poly_linfit = NULL;
03798 cpl_image *fiterror = NULL;
03799 char * name_o1 = NULL;
03800 char * name_o2 = NULL;
03801 double * pcoeffs = cpl_malloc(sizeof(double)*(detmon_lg_config.order + 1));
03802 unsigned mode = detmon_lg_config.autocorr ? IRPLIB_GAIN_WITH_AUTOCORR : 0;
03803 double min_val=0;
03804 double max_val=0;
03805 cpl_vector *x =NULL;
03806 const cpl_vector *y =NULL;
03807
03808
03809 const cpl_image * first = NULL;
03810 int sizex = 0;
03811 int sizey = 0;
03812
03813 double vsize = 0;
03814
03815
03816
03817
03818 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
03819
03820 skip_if(cpl_propertylist_append_string(qclist, DETMON_QC_METHOD,
03821 detmon_lg_config.method));
03822 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_METHOD,
03823 DETMON_QC_METHOD_C));
03824
03825 if (!strcmp(detmon_lg_config.method, "PTC")) {
03826
03827 if (detmon_lg_config.exts >= 0) {
03828 cpl_msg_info(cpl_func,
03829 "Polynomial fitting for the GAIN (constant term method)");
03830 } else {
03831 cpl_msg_info(cpl_func,
03832 "Polynomial fitting for the GAIN (constant term method)"
03833 " for extension nb %d", which_ext);
03834 }
03835 skip_if(irplib_detmon_lg_qc_ptc(gain_table, qclist, mode));
03836 } else {
03837 skip_if(irplib_detmon_lg_qc_med(gain_table, qclist));
03838 }
03839
03840
03841
03842 if(detmon_lg_config.lamp_ok) {
03843 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LAMP_FLUX,
03844 detmon_lg_config.cr));
03845 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LAMP_FLUX,
03846 DETMON_QC_LAMP_FLUX_C));
03847 }
03848
03849
03850 if(detmon_lg_config.autocorr == TRUE) {
03851 autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
03852 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_AUTOCORR,
03853 autocorr));
03854 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_AUTOCORR,
03855 DETMON_QC_AUTOCORR_C));
03856 }
03857 if (detmon_lg_config.exts >= 0) {
03858 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix");
03859 } else {
03860 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix"
03861 " for extension nb %d", which_ext);
03862 }
03863
03864 if(!detmon_lg_config.pix2pix) {
03865 double mse = 0;
03866
03867 y = cpl_vector_wrap(nsets,
03868 (double *)cpl_table_get_data_double_const(linear_table,
03869 "MED"));
03870
03871 if (opt_nir == NIR)
03872 x = cpl_vector_wrap(nsets,
03873 (double *)cpl_table_get_data_double_const(linear_table,
03874 "DIT"));
03875 else
03876 x = cpl_vector_wrap(nsets,
03877 (double *)cpl_table_get_data_double_const(linear_table,
03878 "EXPTIME"));
03879
03880
03881 if(x == NULL || y == NULL) {
03882 cpl_vector_unwrap((cpl_vector *)x);
03883 cpl_vector_unwrap((cpl_vector *)y);
03884
03885
03886
03887
03888
03889
03890 skip_if(1);
03891 }
03892
03893 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
03894 poly_linfit = cpl_polynomial_fit_1d_create(x, y,
03895 detmon_lg_config.order,
03896 &mse);
03897
03898 if(detmon_lg_config.order == cpl_vector_get_size(x) - 1) {
03899 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
03900 mse = 0;
03901 }
03902
03903 if(poly_linfit == NULL) {
03904 cpl_vector_unwrap((cpl_vector *)x);
03905 cpl_vector_unwrap((cpl_vector *)y);
03906
03907 skip_if(1);
03908 }
03909
03910
03911 min_val=cpl_vector_get_min(y);
03912 max_val=cpl_vector_get_max(y);
03913
03914 cpl_vector_unwrap((cpl_vector *)x);
03915 cpl_vector_unwrap((cpl_vector *)y);
03916
03917 for(i = 0; i <= detmon_lg_config.order; i++) {
03918 const double coeff =
03919 cpl_polynomial_get_coeff(poly_linfit, &i);
03920 char *name_o =
03921 cpl_sprintf("ESO QC LIN COEF%d", i);
03922 assert(name_o != NULL);
03923 skip_if(cpl_propertylist_append_double(qclist, name_o, coeff));
03924 skip_if(cpl_propertylist_set_comment(qclist,name_o,
03925 DETMON_QC_LIN_COEF_C));
03926
03927 cpl_free(name_o);
03928 pcoeffs[i] = coeff;
03929 }
03930 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT, mse));
03931 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
03932 DETMON_QC_ERRFIT_MSE_C));
03933
03934
03935 } else {
03936
03937
03938 y = cpl_vector_wrap(nsets,
03939 (double *)cpl_table_get_data_double_const(linear_table,
03940 "MED"));
03941
03942 if (opt_nir == NIR) {
03943 x=
03944 cpl_vector_wrap(nsets,
03945 (double *)cpl_table_get_data_double_const(linear_table,
03946 "DIT"));
03947
03948 } else {
03949
03950 x =
03951 cpl_vector_wrap(nsets,
03952 (double *)cpl_table_get_data_double_const(linear_table,
03953 "EXPTIME"));
03954
03955 }
03956
03957
03958 first = cpl_imagelist_get_const(linearity_inputs, 0);
03959 sizex = cpl_image_get_size_x(first);
03960 sizey = cpl_image_get_size_y(first);
03961
03962 vsize = cpl_vector_get_size(x);
03963
03964 fiterror = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
03965
03966 *coeffs_ptr =
03967 cpl_fit_imagelist_polynomial(x, linearity_inputs, 0,
03968 detmon_lg_config.order, FALSE,
03969 CPL_TYPE_FLOAT, fiterror);
03970
03971 min_val=cpl_vector_get_min(y);
03972 max_val=cpl_vector_get_max(y);
03973
03974
03975 cpl_vector_unwrap((cpl_vector*)x);
03976 cpl_vector_unwrap((cpl_vector*)y);
03977 irplib_ensure(*coeffs_ptr != NULL, CPL_ERROR_UNSPECIFIED,
03978 "Failed polynomial fit");
03979
03980 for(i = 0; i <= detmon_lg_config.order; i++) {
03981 cpl_image *image = cpl_imagelist_get(*coeffs_ptr, i);
03982 const double coeff = cpl_image_get_median(image);
03983 pcoeffs[i] = coeff;
03984 name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
03985 name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
03986 assert(name_o1 != NULL);
03987 assert(name_o2 != NULL);
03988 skip_if(cpl_propertylist_append_double(qclist, name_o1, coeff));
03989 skip_if(cpl_propertylist_set_comment(qclist,name_o1,
03990 DETMON_QC_LIN_COEF_C));
03991 cpl_free(name_o1);
03992 name_o1= NULL;
03993 skip_if(cpl_propertylist_append_double(qclist, name_o2,
03994 cpl_image_get_stdev(image)));
03995 skip_if(cpl_propertylist_set_comment(qclist,name_o2,
03996 DETMON_QC_LIN_COEF_ERR_C));
03997 cpl_free(name_o2);
03998 name_o2= NULL;
03999 }
04000
04001 if(detmon_lg_config.order == vsize - 1) {
04002 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
04003 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
04004 0.0));
04005 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
04006 DETMON_QC_ERRFIT_C));
04007
04008
04009
04010 } else {
04011 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
04012 cpl_image_get_median(fiterror)));
04013 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
04014 DETMON_QC_ERRFIT_C));
04015
04016 }
04017 }
04018
04019
04020 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_COUNTS_MIN,
04021 min_val));
04022
04023 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_COUNTS_MIN,
04024 DETMON_QC_COUNTS_MIN_C));
04025
04026 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_COUNTS_MAX,
04027 max_val));
04028
04029 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_COUNTS_MAX,
04030 DETMON_QC_COUNTS_MAX_C));
04031
04032 skip_if(irplib_detmon_lg_lineff(pcoeffs,qclist,detmon_lg_config.ref_level,
04033 detmon_lg_config.order));
04034
04035
04036 if (detmon_lg_config.exts >= 0) {
04037 cpl_msg_info(cpl_func, "Bad pixel detection");
04038 } else {
04039 cpl_msg_info(cpl_func, "Bad pixel detection"
04040 " for extension nb %d", which_ext);
04041 }
04042
04043 if(detmon_lg_config.pix2pix) {
04044 *bpms_ptr = irplib_detmon_bpixs(*coeffs_ptr, detmon_lg_config.bpmbin,
04045 detmon_lg_config.kappa, &nbpixs);
04046 skip_if(*bpms_ptr == NULL);
04047 }
04048
04049 skip_if(cpl_propertylist_append_int(qclist, DETMON_QC_NUM_BPM, nbpixs));
04050 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_NUM_BPM,
04051 DETMON_QC_NUM_BPM_C));
04052
04053 if(detmon_lg_config.lamp_stability != 0.0) {
04054 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LAMP_STAB,
04055 detmon_lg_config.lamp_stability));
04056 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LAMP_STAB,
04057 DETMON_QC_LAMP_STAB_C));
04058 }
04059 end_skip;
04060
04061 cpl_free(pcoeffs);
04062 cpl_free(name_o1);
04063 cpl_free(name_o2);
04064 cpl_image_delete(fiterror);
04065 cpl_polynomial_delete(poly_linfit);
04066
04067 return cpl_error_get_code();
04068 }
04069
04070
04078
04079 static cpl_error_code
04080 irplib_detmon_lg_lineff(double * pcoeffs,
04081 cpl_propertylist * qclist,
04082 int ref_level,
04083 int order)
04084 {
04085 double lineff = 0;
04086 double root = 0;
04087 cpl_polynomial * poly = cpl_polynomial_new(1);
04088 int i;
04089
04090 double residual, slope;
04091
04092
04093
04094
04095
04096 pcoeffs[0] -= ref_level;
04097
04098 for (i = 2; i <= order; i++) {
04099 int j;
04100 for(j = 0; j < i; j++) {
04101 pcoeffs[i] /= pcoeffs[1];
04102 }
04103 }
04104
04105 pcoeffs[1] = 1;
04106
04107 for (i = 0; i <= order; i++) {
04108 skip_if(cpl_polynomial_set_coeff(poly, &i, pcoeffs[i]));
04109 }
04110
04111
04112
04113
04114
04115
04116
04117 residual = cpl_polynomial_eval_1d(poly, 0.0, &slope);
04118
04119 if (slope <= 0.0 && residual >= 0.0) {
04120 cpl_msg_warning(cpl_func, "Reference level (--ref_level) outside"
04121 " linearity range of the detector. Cannot compute"
04122 " linearity efficiency (QC.LINEFF).");
04123 lineff = -1;
04124 } else {
04125 skip_if(cpl_polynomial_solve_1d(poly, 0.0, &root, 1));
04126
04127 lineff = (root - ref_level) / ref_level;
04128 }
04129
04130 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LIN_EFF,
04131 lineff));
04132 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LIN_EFF,
04133 DETMON_QC_LIN_EFF_C));
04134
04135 end_skip;
04136
04137 cpl_polynomial_delete(poly);
04138
04139 return cpl_error_get_code();
04140 }
04141
04142
04149
04150 static cpl_error_code
04151 irplib_detmon_lg_qc_ptc(const cpl_table * gain_table,
04152 cpl_propertylist * qclist, unsigned mode)
04153 {
04154 double mse = 0;
04155 cpl_polynomial *poly_fit = NULL;
04156 cpl_polynomial *poly_fit2 = NULL;
04157 int i;
04158 const int nsets = cpl_table_get_nrow(gain_table);
04159
04160
04161
04162
04163
04164 const cpl_vector *x;
04165 const cpl_vector *y;
04166
04167 cpl_errorstate prestate;
04168 double coef = 0;
04169
04170 cpl_ensure_code(gain_table != NULL, CPL_ERROR_NULL_INPUT);
04171 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
04172
04173 x = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT"));
04174
04175 y = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
04176
04177 skip_if(x == NULL || y == NULL);
04178
04179 poly_fit = cpl_polynomial_fit_1d_create(x, y, 1, &mse);
04180 skip_if(poly_fit == NULL);
04181
04182
04183 i = 1;
04184 prestate = cpl_errorstate_get();
04185 coef = cpl_polynomial_get_coeff(poly_fit, &i);
04186 skip_if (!cpl_errorstate_is_equal(prestate) || coef == 0);
04187
04188 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD, coef));
04189 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
04190 DETMON_QC_CONAD_C));
04191
04192 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,
04193 1 / coef));
04194 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
04195 DETMON_QC_GAIN_C));
04196
04197 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE, mse));
04198 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
04199 DETMON_QC_GAIN_MSE_C));
04200 i = 0;
04201 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_RON,
04202 cpl_polynomial_get_coeff(poly_fit, &i)));
04203 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_RON,
04204 DETMON_QC_RON_C));
04205
04206 if(mode & IRPLIB_GAIN_WITH_AUTOCORR){
04207 const cpl_vector *x2 =
04208 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT_CORR"));
04209 const cpl_vector *y2 =
04210 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
04211
04212 if(x2 == NULL || y2 == NULL) {
04213 cpl_vector_unwrap((cpl_vector *)x2);
04214 cpl_vector_unwrap((cpl_vector *)y2);
04215
04216
04217
04218
04219
04220
04221 skip_if(1);
04222 }
04223
04224
04225 poly_fit2 = cpl_polynomial_fit_1d_create(x2, y2, 1, &mse);
04226 if(poly_fit2 == NULL) {
04227 cpl_vector_unwrap((cpl_vector *)x2);
04228 cpl_vector_unwrap((cpl_vector *)y2);
04229
04230 skip_if(1);
04231 }
04232
04233 cpl_vector_unwrap((cpl_vector *)x2);
04234 cpl_vector_unwrap((cpl_vector *)y2);
04235
04236
04237 i = 1;
04238 prestate = cpl_errorstate_get();
04239 coef = cpl_polynomial_get_coeff(poly_fit2, &i);
04240 skip_if (!cpl_errorstate_is_equal(prestate) || coef == 0);
04241
04242 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
04243 1 / coef));
04244 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
04245 DETMON_QC_GAIN_CORR_C));
04246 }
04247
04248 end_skip;
04249
04250
04251 cpl_vector_unwrap((cpl_vector *)x);
04252 cpl_vector_unwrap((cpl_vector *)y);
04253 cpl_polynomial_delete(poly_fit);
04254 cpl_polynomial_delete(poly_fit2);
04255
04256 return cpl_error_get_code();
04257 }
04258
04259
04268
04269 static cpl_error_code
04270 irplib_detmon_lg_qc_med(const cpl_table * gain_table,
04271 cpl_propertylist * qclist)
04272 {
04273
04274 double gain=0;
04275 gain=cpl_table_get_column_median(gain_table, "GAIN");
04276
04277 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,gain));
04278
04279 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
04280 DETMON_QC_GAIN_C));
04281
04282 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE,
04283 cpl_table_get_column_stdev
04284 (gain_table, "GAIN")));
04285 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
04286 DETMON_QC_GAIN_MSE_C));
04287
04288 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD,1./gain));
04289 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
04290 DETMON_QC_CONAD_C));
04291
04292
04293 gain=cpl_table_get_column_median(gain_table, "GAIN_CORR");
04294
04295 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
04296 gain));
04297 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
04298 DETMON_QC_GAIN_CORR_C));
04299
04300
04301 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD_CORR,1./gain));
04302 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD_CORR,
04303 DETMON_QC_CONAD_CORR_C));
04304
04305
04306 end_skip;
04307
04308 return cpl_error_get_code();
04309 }
04310
04311
04312
04321
04322 static cpl_error_code
04323 irplib_detmon_lg_rescale(cpl_imagelist * to_rescale)
04324 {
04325 double med1 =
04326 cpl_image_get_median(cpl_imagelist_get(to_rescale, 0));
04327 double med2 =
04328 cpl_image_get_median(cpl_imagelist_get(to_rescale, 1));
04329
04330 skip_if(0);
04331
04332 if(fabs(med1 / med2 - 1) > 0.001) {
04333 if(med1 > med2)
04334 skip_if(cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 0),
04335 med1 / med2));
04336 else
04337 skip_if(cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 1),
04338 med2 / med1));
04339 }
04340
04341 end_skip;
04342
04343 return cpl_error_get_code();
04344 }
04345
04346
04364
04365 static cpl_error_code
04366 irplib_detmon_pair_extract(const cpl_frameset * set,
04367 int * selection, int selected,
04368 int nsets_extracted,
04369 int * with_equal_dit,
04370 int onoff,
04371 cpl_frameset ** pair)
04372 {
04373 int new_with_equal_dit = 0;
04374
04375 cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
04376 cpl_ensure_code(selection != NULL, CPL_ERROR_NULL_INPUT);
04377 cpl_ensure_code(with_equal_dit != NULL, CPL_ERROR_NULL_INPUT);
04378 cpl_ensure_code(pair != NULL, CPL_ERROR_NULL_INPUT);
04379
04380 *pair = cpl_frameset_extract(set, selection, selected);
04381 cpl_ensure_code(*pair != NULL, cpl_error_get_code());
04382
04383
04384
04385
04386 skip_if(cpl_frameset_get_size(*pair) % 2 != 0);
04387
04388
04389 if(cpl_frameset_get_size(*pair) != 2) {
04390 new_with_equal_dit = cpl_frameset_get_size(*pair) / 2;
04391 if(onoff == 1) {
04392 *with_equal_dit = new_with_equal_dit;
04393 } else {
04394 skip_if (*with_equal_dit != 0 &&
04395 new_with_equal_dit != *with_equal_dit);
04396 }
04397 }
04398
04399
04400 if (new_with_equal_dit != 0) {
04401 int found = 0;
04402 int j;
04403 for(j = 0; j < cpl_frameset_get_size(set); j++) {
04404
04405 if(selection[j] == selected) {
04406 found++;
04407
04408 if((found - 1) / 2 != 0) {
04409 selection[j] =
04410 nsets_extracted + (found - 1) / 2 - 1;
04411 }
04412 }
04413 }
04414 cpl_frameset_delete(*pair);
04415 *pair = cpl_frameset_extract(set, selection, selected);
04416
04417 }
04418
04419 end_skip;
04420
04421 return cpl_error_get_code();
04422 }
04423
04441
04442 static cpl_error_code
04443 irplib_detmon_single_extract(const cpl_frameset * set,
04444 int * selection, int selected,
04445 int nsets_extracted,
04446 int * with_equal_dit,
04447 int onoff,
04448 cpl_frameset ** single)
04449 {
04450 int new_with_equal_dit = 0;
04451
04452 cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
04453 cpl_ensure_code(selection != NULL, CPL_ERROR_NULL_INPUT);
04454 cpl_ensure_code(with_equal_dit != NULL, CPL_ERROR_NULL_INPUT);
04455 cpl_ensure_code(single != NULL, CPL_ERROR_NULL_INPUT);
04456
04457 *single = cpl_frameset_extract(set, selection, selected);
04458 cpl_ensure_code(*single != NULL, cpl_error_get_code());
04459
04460
04461
04462
04463 if(cpl_frameset_get_size(*single) != 1) {
04464 new_with_equal_dit = cpl_frameset_get_size(*single);
04465 if(onoff == 1) {
04466 *with_equal_dit = new_with_equal_dit;
04467 } else {
04468 skip_if (*with_equal_dit != 0 &&
04469 new_with_equal_dit != *with_equal_dit);
04470 }
04471 }
04472
04473
04474 if (new_with_equal_dit != 0) {
04475 int found = 0;
04476 int j;
04477 for(j = 0; j < cpl_frameset_get_size(set); j++) {
04478
04479 if(selection[j] == selected) {
04480 found++;
04481
04482 if(found > 1) {
04483 selection[j] =
04484 nsets_extracted + (found - 2);
04485 }
04486 }
04487 }
04488 cpl_frameset_delete(*single);
04489 *single = cpl_frameset_extract(set, selection, selected);
04490
04491 }
04492
04493 end_skip;
04494
04495 return cpl_error_get_code();
04496 }
04497
04498
04499
04500
04501
04502
04503
04504
04505
04506
04507
04508 static int
04509 irplib_detmon_lg_compare_pairs(const cpl_frame * frame1,
04510 const cpl_frame * frame2)
04511 {
04512 int comparison;
04513 cpl_propertylist *plist1;
04514 cpl_propertylist *plist2;
04515 double dval1, dval2;
04516
04517
04518 if(frame1 == NULL || frame2 == NULL)
04519 return -1;
04520
04521
04522 if((plist1 = cpl_propertylist_load(cpl_frame_get_filename(frame1),
04523 0)) == NULL) {
04524 cpl_msg_error(cpl_func, "getting header from reference frame");
04525 return -1;
04526 }
04527 if((plist2 = cpl_propertylist_load(cpl_frame_get_filename(frame2),
04528 0)) == NULL) {
04529 cpl_msg_error(cpl_func, "getting header from reference frame");
04530 cpl_propertylist_delete(plist1);
04531 return -1;
04532 }
04533
04534
04535 if(cpl_error_get_code()) {
04536 cpl_propertylist_delete(plist1);
04537 cpl_propertylist_delete(plist2);
04538 return -1;
04539 }
04540
04541
04542 comparison = 1;
04543 dval1 = irplib_pfits_get_exptime(plist1);
04544 dval2 = irplib_pfits_get_exptime(plist2);
04545 if(cpl_error_get_code()) {
04546 cpl_msg_error(cpl_func, "cannot get exposure time");
04547 cpl_propertylist_delete(plist1);
04548 cpl_propertylist_delete(plist2);
04549 return -1;
04550 }
04551 if(fabs(dval1 - dval2) > detmon_lg_config.tolerance)
04552 comparison = 0;
04553
04554
04555 cpl_propertylist_delete(plist1);
04556 cpl_propertylist_delete(plist2);
04557 return comparison;
04558 }
04559
04560
04649
04650
04651 cpl_table *
04652 irplib_detmon_gain(const cpl_imagelist * imlist_on,
04653 const cpl_imagelist * imlist_off,
04654 const cpl_vector * exptimes,
04655 double tolerance,
04656 int llx,
04657 int lly,
04658 int urx,
04659 int ury,
04660 double kappa,
04661 int nclip,
04662 int xshift,
04663 int yshift,
04664 cpl_propertylist * qclist,
04665 unsigned mode,
04666 cpl_imagelist ** diff_imlist,
04667 cpl_imagelist ** autocorr_imlist)
04668 {
04669 cpl_table * gain_table = NULL;
04670 cpl_imagelist * difflist = NULL;
04671 cpl_imagelist * autocorrlist = NULL;
04672 cpl_imagelist * c_onlist = NULL;
04673 cpl_imagelist * c_offlist = NULL;
04674 cpl_vector * diffdits = NULL;
04675 int ndiffdits, ndits;
04676 int i, j;
04677 cpl_boolean opt_nir = mode & IRPLIB_GAIN_OPT ? OPT : NIR;
04678
04679 cpl_ensure(imlist_on != NULL, CPL_ERROR_NULL_INPUT, NULL);
04680 cpl_ensure(imlist_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
04681 cpl_ensure(exptimes != NULL, CPL_ERROR_NULL_INPUT, NULL);
04682 cpl_ensure(qclist != NULL, CPL_ERROR_NULL_INPUT, NULL);
04683
04684
04685 gain_table = cpl_table_new(cpl_vector_get_size(exptimes) / 2);
04686 skip_if(irplib_detmon_gain_table_create(gain_table, opt_nir));
04687
04688
04689 diffdits = irplib_detmon_lg_find_dits(exptimes, tolerance);
04690 ndiffdits = cpl_vector_get_size(diffdits);
04691
04692 ndits = cpl_vector_get_size(exptimes);
04693
04694
04695 if (mode & IRPLIB_GAIN_WITH_AUTOCORR && (diff_imlist || autocorr_imlist)) {
04696 difflist = cpl_imagelist_new();
04697 autocorrlist = cpl_imagelist_new();
04698 }
04699
04700 if (mode & IRPLIB_GAIN_COLLAPSE) {
04701 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04702 c_offlist = cpl_imagelist_duplicate(imlist_off);
04703 skip_if(irplib_detmon_lg_rescale(c_offlist));
04704 } else {
04705 c_offlist = (cpl_imagelist *) imlist_off;
04706 }
04707 }
04708
04709
04710 for (i = 0; i < ndiffdits; i++) {
04711 int c_nons;
04712 int c_noffs = 0;
04713
04714 double c_dit = cpl_vector_get(diffdits, i);
04715
04716 c_onlist = cpl_imagelist_new();
04717 c_nons = 0;
04718
04719 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04720 c_offlist = cpl_imagelist_new();
04721 c_noffs = 0;
04722 }
04723
04724
04725 for(j = 0; j < ndits; j++) {
04726 if (fabs(c_dit - cpl_vector_get(exptimes, j)) <= tolerance) {
04727
04728
04729
04730
04731
04732
04733
04734
04735 cpl_image * im_on;
04736 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04737 const cpl_image * im =
04738 cpl_imagelist_get_const(imlist_on, j);
04739 im_on = cpl_image_duplicate(im);
04740 } else {
04741 im_on = (cpl_image *)cpl_imagelist_get_const(imlist_on, j);
04742 }
04743 skip_if(cpl_imagelist_set(c_onlist, im_on, c_nons));
04744 c_nons++;
04745
04746
04747
04748
04749
04750 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04751 cpl_image * im_off;
04752 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04753 const cpl_image * im =
04754 cpl_imagelist_get_const(imlist_off, j);
04755 im_off = cpl_image_duplicate(im);
04756 } else {
04757 im_off =
04758 (cpl_image *) cpl_imagelist_get_const(imlist_off, j);
04759 }
04760 skip_if(cpl_imagelist_set(c_offlist, im_off, c_noffs));
04761 c_noffs++;
04762 }
04763 }
04764 }
04765
04766
04767 if (mode & IRPLIB_GAIN_NO_COLLAPSE)
04768 skip_if (c_nons != c_noffs);
04769
04770
04771 skip_if (c_nons == 0 || c_nons % 2 != 0);
04772
04773
04774 if(mode & IRPLIB_GAIN_WITH_RESCALE) {
04775 skip_if(irplib_detmon_lg_rescale(c_onlist));
04776 if (mode & IRPLIB_GAIN_NO_COLLAPSE)
04777 skip_if(irplib_detmon_lg_rescale(c_offlist));
04778 }
04779
04780
04781
04782 while(c_nons > 0) {
04783 skip_if(irplib_detmon_gain_table_fill_row(gain_table, c_dit,
04784 autocorrlist,
04785 difflist, c_onlist,
04786 c_offlist, kappa, nclip,
04787 llx, lly, urx, ury,
04788 xshift, yshift, i,
04789 mode));
04790 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04791 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
04792 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
04793 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04794 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
04795 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
04796 }
04797 } else {
04798 cpl_imagelist_unset(c_onlist, 0);
04799 skip_if(0);
04800 cpl_imagelist_unset(c_onlist, 0);
04801 skip_if(0);
04802 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04803 cpl_imagelist_unset(c_offlist, 0);
04804 skip_if(0);
04805 cpl_imagelist_unset(c_offlist, 0);
04806 skip_if(0);
04807 }
04808 }
04809 skip_if(0);
04810 c_nons -= 2;
04811 }
04812
04813 cpl_imagelist_delete(c_onlist);
04814 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04815 cpl_imagelist_delete(c_offlist);
04816 }
04817 }
04818
04819
04820 if (mode & IRPLIB_GAIN_PTC) {
04821 skip_if(irplib_detmon_lg_qc_ptc(gain_table, qclist, mode));
04822 } else {
04823 skip_if(irplib_detmon_lg_qc_med(gain_table, qclist));
04824 }
04825
04826 if(mode & IRPLIB_GAIN_WITH_AUTOCORR) {
04827 double autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
04828 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_AUTOCORR,
04829 autocorr));
04830 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_AUTOCORR,
04831 DETMON_QC_AUTOCORR_C));
04832 }
04833
04834 if (diff_imlist != NULL) *diff_imlist = difflist;
04835 if (autocorr_imlist != NULL) *autocorr_imlist = autocorrlist;
04836
04837 end_skip;
04838
04839 cpl_vector_delete(diffdits);
04840
04841 return gain_table;
04842 }
04843
04844 static cpl_error_code
04845 irplib_detmon_gain_table_create(cpl_table * gain_table,
04846 const cpl_boolean opt_nir)
04847 {
04848 if (opt_nir == NIR) {
04849 skip_if(cpl_table_new_column(gain_table, "DIT", CPL_TYPE_DOUBLE));
04850 } else {
04851 skip_if(cpl_table_new_column(gain_table, "EXPTIME", CPL_TYPE_DOUBLE));
04852 }
04853 skip_if(cpl_table_new_column(gain_table, "MEAN_ON1", CPL_TYPE_DOUBLE));
04854 skip_if(cpl_table_new_column(gain_table, "MEAN_ON2", CPL_TYPE_DOUBLE));
04855 skip_if(cpl_table_new_column(gain_table, "MEAN_OFF1", CPL_TYPE_DOUBLE));
04856 skip_if(cpl_table_new_column(gain_table, "MEAN_OFF2", CPL_TYPE_DOUBLE));
04857 skip_if(cpl_table_new_column(gain_table, "SIG_ON_DIF", CPL_TYPE_DOUBLE));
04858 skip_if(cpl_table_new_column(gain_table, "SIG_OFF_DIF", CPL_TYPE_DOUBLE));
04859 skip_if(cpl_table_new_column(gain_table, "GAIN", CPL_TYPE_DOUBLE));
04860 skip_if(cpl_table_new_column(gain_table, "AUTOCORR", CPL_TYPE_DOUBLE));
04861 skip_if(cpl_table_new_column(gain_table, "GAIN_CORR", CPL_TYPE_DOUBLE));
04862 skip_if(cpl_table_new_column(gain_table, "ADU", CPL_TYPE_DOUBLE));
04863 skip_if(cpl_table_new_column(gain_table, "X_FIT", CPL_TYPE_DOUBLE));
04864 skip_if(cpl_table_new_column(gain_table, "X_FIT_CORR", CPL_TYPE_DOUBLE));
04865 skip_if(cpl_table_new_column(gain_table, "Y_FIT", CPL_TYPE_DOUBLE));
04866 skip_if(cpl_table_new_column(gain_table, "Y_FIT_CORR", CPL_TYPE_DOUBLE));
04867
04868 end_skip;
04869
04870 return cpl_error_get_code();
04871 }
04872
04873 static cpl_error_code
04874 irplib_detmon_lin_table_create(cpl_table * lin_table,
04875 const cpl_boolean opt_nir)
04876 {
04877 if (opt_nir == NIR) {
04878 skip_if(cpl_table_new_column(lin_table, "DIT", CPL_TYPE_DOUBLE));
04879 } else {
04880 skip_if(cpl_table_new_column(lin_table, "EXPTIME", CPL_TYPE_DOUBLE));
04881 }
04882 skip_if(cpl_table_new_column(lin_table, "MED", CPL_TYPE_DOUBLE));
04883 skip_if(cpl_table_new_column(lin_table, "MEAN", CPL_TYPE_DOUBLE));
04884 skip_if(cpl_table_new_column(lin_table, "MED_DIT", CPL_TYPE_DOUBLE));
04885 skip_if(cpl_table_new_column(lin_table, "MEAN_DIT", CPL_TYPE_DOUBLE));
04886 skip_if(cpl_table_new_column(lin_table, "ADL", CPL_TYPE_DOUBLE));
04887
04888 end_skip;
04889
04890 return cpl_error_get_code();
04891 }
04892
04893 static cpl_vector *
04894 irplib_detmon_lg_find_dits(const cpl_vector * exptimes,
04895 double tolerance)
04896 {
04897 cpl_vector * dits = cpl_vector_new(cpl_vector_get_size(exptimes) / 2);
04898 int ndits = 0;
04899
04900 int i, j;
04901
04902
04903 cpl_vector_set(dits, 0, cpl_vector_get(exptimes, 0));
04904 ndits = 1;
04905
04906
04907 for(i = 1; i < cpl_vector_get_size(exptimes); i++) {
04908 int ndiffs = 0;
04909 for (j = 0; j < ndits; j++) {
04910 if (fabs(cpl_vector_get(exptimes, i) -
04911 cpl_vector_get(dits, j)) > tolerance)
04912 ndiffs++;
04913 }
04914 if(ndiffs == ndits) {
04915 cpl_vector_set(dits, ndits, cpl_vector_get(exptimes, i));
04916 ndits++;
04917 }
04918 }
04919
04920 cpl_vector_set_size(dits, ndits);
04921
04922 return dits;
04923 }
04924
04925
04926
05007
05008
05009 cpl_table *
05010 irplib_detmon_lin(const cpl_imagelist * imlist_on,
05011 const cpl_imagelist * imlist_off,
05012 const cpl_vector * exptimes,
05013 double tolerance,
05014 int llx,
05015 int lly,
05016 int urx,
05017 int ury,
05018 int order,
05019 int ref_level,
05020 double kappa,
05021 cpl_boolean bpmbin,
05022 cpl_propertylist * qclist,
05023 unsigned mode,
05024 cpl_imagelist ** coeffs_cube,
05025 cpl_image ** bpm)
05026 {
05027 cpl_table * lin_table = NULL;
05028 cpl_imagelist * c_onlist = NULL;
05029 cpl_imagelist * c_offlist = NULL;
05030 cpl_vector * diffdits = NULL;
05031 cpl_imagelist * lin_inputs = NULL;
05032 cpl_polynomial * poly_linfit = NULL;
05033 cpl_image * fiterror = NULL;
05034 cpl_vector * vcoeffs = NULL;
05035 double * pcoeffs = NULL;
05036 int ndiffdits, ndits;
05037 int i, j;
05038 cpl_boolean opt_nir = mode & IRPLIB_LIN_OPT ? OPT : NIR;
05039 const cpl_vector *x = NULL;
05040 const cpl_vector *y = NULL;
05041
05042 const cpl_image * first = NULL;
05043 int sizex = 0;
05044 int sizey = 0;
05045
05046 double vsize = 0;
05047
05048
05049 cpl_ensure(imlist_on != NULL, CPL_ERROR_NULL_INPUT, NULL);
05050 cpl_ensure(imlist_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
05051 cpl_ensure(exptimes != NULL, CPL_ERROR_NULL_INPUT, NULL);
05052 cpl_ensure(qclist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05053 cpl_ensure(order > 0 , CPL_ERROR_ILLEGAL_INPUT, NULL);
05054
05055 vcoeffs = cpl_vector_new(order + 1);
05056 pcoeffs = cpl_vector_get_data(vcoeffs);
05057
05058
05059 if (mode & IRPLIB_LIN_PIX2PIX) {
05060 lin_inputs = cpl_imagelist_new();
05061 cpl_ensure(coeffs_cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
05062 cpl_ensure(bpm != NULL, CPL_ERROR_NULL_INPUT, NULL);
05063 }
05064
05065
05066 lin_table = cpl_table_new(cpl_vector_get_size(exptimes) / 2);
05067 skip_if(irplib_detmon_lin_table_create(lin_table, opt_nir));
05068
05069
05070
05071 diffdits = irplib_detmon_lg_find_dits(exptimes, tolerance);
05072 ndiffdits = cpl_vector_get_size(diffdits);
05073
05074 ndits = cpl_vector_get_size(exptimes);
05075
05076
05077
05078
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097
05098
05099
05100
05101
05102
05103
05104 if (mode & IRPLIB_LIN_COLLAPSE) {
05105
05106
05107
05108
05109 cpl_image * collapse = cpl_imagelist_collapse_create(imlist_off);
05110 skip_if(collapse == NULL);
05111
05112 c_offlist = cpl_imagelist_new();
05113 skip_if(cpl_imagelist_set(c_offlist, collapse, 0));
05114 }
05115
05116
05117 for (i = 0; i < ndiffdits; i++) {
05118 int c_nons;
05119 int c_noffs = 0;
05120
05121 double c_dit = cpl_vector_get(diffdits, i);
05122
05123 c_onlist = cpl_imagelist_new();
05124 c_nons = 0;
05125
05126 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05127 c_offlist = cpl_imagelist_new();
05128 c_noffs = 0;
05129 }
05130
05131 for(j = 0; j < ndits; j++) {
05132 if (fabs(c_dit - cpl_vector_get(exptimes, j)) <= tolerance) {
05133
05134
05135
05136
05137
05138
05139
05140
05141 cpl_image * im_on;
05142 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05143 const cpl_image * im =
05144 cpl_imagelist_get_const(imlist_on, j);
05145 im_on = cpl_image_duplicate(im);
05146 } else {
05147 im_on = (cpl_image *)cpl_imagelist_get_const(imlist_on, j);
05148 }
05149 skip_if(cpl_imagelist_set(c_onlist, im_on, c_nons));
05150 c_nons++;
05151
05152
05153
05154
05155
05156 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05157 cpl_image * im_off;
05158 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05159 const cpl_image * im =
05160 cpl_imagelist_get_const(imlist_off, j);
05161 im_off = cpl_image_duplicate(im);
05162 } else {
05163 im_off =
05164 (cpl_image *) cpl_imagelist_get_const(imlist_off, j);
05165 }
05166 skip_if(cpl_imagelist_set(c_offlist, im_off, c_noffs));
05167 c_noffs++;
05168 }
05169 }
05170 }
05171
05172
05173 if (mode & IRPLIB_LIN_NO_COLLAPSE)
05174 skip_if (c_nons != c_noffs);
05175
05176
05177 skip_if (c_nons == 0 || c_nons % 2 != 0);
05178
05179
05180 if(mode & IRPLIB_LIN_WITH_RESCALE) {
05181 skip_if(irplib_detmon_lg_rescale(c_onlist));
05182 if (mode & IRPLIB_LIN_NO_COLLAPSE)
05183 skip_if(irplib_detmon_lg_rescale(c_offlist));
05184 }
05185
05186
05187
05188 while(c_nons > 0) {
05189
05190 skip_if(irplib_detmon_lin_table_fill_row(lin_table, c_dit,
05191 lin_inputs,
05192 c_onlist, c_offlist,
05193 llx, lly, urx, ury,
05194 i, 0, mode));
05195
05196 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05197 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05198 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05199 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05200 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05201 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05202 }
05203 } else {
05204 cpl_imagelist_unset(c_onlist, 0);
05205 skip_if(0);
05206 cpl_imagelist_unset(c_onlist, 0);
05207 skip_if(0);
05208 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05209 cpl_imagelist_unset(c_offlist, 0);
05210 skip_if(0);
05211 cpl_imagelist_unset(c_offlist, 0);
05212 skip_if(0);
05213 }
05214 }
05215 skip_if(0);
05216 c_nons -= 2;
05217 }
05218
05219 cpl_imagelist_delete(c_onlist);
05220 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05221 cpl_imagelist_delete(c_offlist);
05222 }
05223 }
05224
05225 skip_if(irplib_detmon_add_adl_column(lin_table, opt_nir));
05226
05227 if(!(mode & IRPLIB_LIN_PIX2PIX)) {
05228 double mse = 0;
05229
05230 y = cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05231 (double *)cpl_table_get_data_double_const(lin_table,
05232 "MED"));
05233 if (opt_nir == NIR) {
05234 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05235 (double *)cpl_table_get_data_double_const(lin_table, "DIT"));
05236 } else {
05237 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05238 (double *)cpl_table_get_data_double_const(lin_table, "EXPTIME"));
05239 }
05240 if(x == NULL || y == NULL) {
05241 cpl_vector_unwrap((cpl_vector *)x);
05242 cpl_vector_unwrap((cpl_vector *)y);
05243
05244
05245
05246
05247
05248
05249 skip_if(1);
05250 }
05251
05252 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
05253 poly_linfit = cpl_polynomial_fit_1d_create(x, y, order, &mse);
05254
05255 if(order == cpl_vector_get_size(x) - 1) {
05256 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
05257 mse = 0;
05258 }
05259
05260 if(poly_linfit == NULL) {
05261 cpl_vector_unwrap((cpl_vector *)x);
05262 cpl_vector_unwrap((cpl_vector *)y);
05263
05264 skip_if(1);
05265 }
05266
05267 cpl_vector_unwrap((cpl_vector *)x);
05268 cpl_vector_unwrap((cpl_vector *)y);
05269
05270 for(i = 0; i <= order; i++) {
05271 const double coeff =
05272 cpl_polynomial_get_coeff(poly_linfit, &i);
05273 char *name_o =
05274 cpl_sprintf("ESO QC LIN COEF%d", i);
05275 assert(name_o != NULL);
05276 skip_if(cpl_propertylist_append_double(qclist, name_o, coeff));
05277 skip_if(cpl_propertylist_set_comment(qclist,name_o,
05278 DETMON_QC_LIN_COEF_C));
05279 cpl_free(name_o);
05280 pcoeffs[i] = coeff;
05281 }
05282 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT, mse));
05283 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05284 DETMON_QC_ERRFIT_MSE_C));
05285
05286
05287 } else {
05288 if (opt_nir == NIR) {
05289 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05290 (double *)cpl_table_get_data_double_const(lin_table,
05291 "DIT"));
05292 } else {
05293 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05294 (double *)cpl_table_get_data_double_const(lin_table,
05295 "EXPTIME"));
05296 }
05297
05298
05299 first = cpl_imagelist_get_const(lin_inputs, 0);
05300 sizex = cpl_image_get_size_x(first);
05301 sizey = cpl_image_get_size_y(first);
05302
05303 vsize = cpl_vector_get_size(x);
05304
05305 fiterror = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
05306
05307 *coeffs_cube =
05308 cpl_fit_imagelist_polynomial(x, lin_inputs, 0,
05309 order, FALSE, CPL_TYPE_FLOAT,
05310 fiterror);
05311
05312 cpl_vector_unwrap((cpl_vector*)x);
05313 irplib_ensure(*coeffs_cube != NULL, CPL_ERROR_UNSPECIFIED,
05314 "Failed polynomial fit");
05315
05316 for(i = 0; i <= order; i++) {
05317 cpl_image *image = cpl_imagelist_get(*coeffs_cube, i);
05318 const double coeff = cpl_image_get_median(image);
05319 char * name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
05320 char * name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
05321 pcoeffs[i] = coeff;
05322 assert(name_o1 != NULL);
05323 assert(name_o2 != NULL);
05324 skip_if(cpl_propertylist_append_double(qclist, name_o1, coeff));
05325 skip_if(cpl_propertylist_set_comment(qclist,name_o1,
05326 DETMON_QC_LIN_COEF_C));
05327 cpl_free(name_o1);
05328 name_o1= NULL;
05329 skip_if(cpl_propertylist_append_double(qclist, name_o2,
05330 cpl_image_get_stdev(image)));
05331 skip_if(cpl_propertylist_set_comment(qclist,name_o2,
05332 DETMON_QC_LIN_COEF_ERR_C));
05333 cpl_free(name_o2);
05334 name_o2= NULL;
05335 }
05336
05337 if(order == vsize - 1) {
05338 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
05339 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
05340 0.0));
05341 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05342 DETMON_QC_ERRFIT_C));
05343
05344
05345 } else {
05346 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
05347 cpl_image_get_median(fiterror)));
05348 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05349 DETMON_QC_ERRFIT_C));
05350
05351 }
05352 }
05353
05354 skip_if(irplib_detmon_lg_lineff(pcoeffs, qclist, ref_level, order));
05355
05356 if(mode & IRPLIB_LIN_PIX2PIX) {
05357 int nbpixs;
05358 *bpm = irplib_detmon_bpixs(*coeffs_cube, bpmbin, kappa, &nbpixs);
05359 skip_if(*bpm == NULL);
05360 skip_if(cpl_propertylist_append_int(qclist, DETMON_QC_NUM_BPM,
05361 nbpixs));
05362 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_NUM_BPM,
05363 DETMON_QC_NUM_BPM_C));
05364 }
05365
05366 end_skip;
05367
05368 cpl_vector_delete(diffdits);
05369 cpl_polynomial_delete(poly_linfit);
05370 cpl_imagelist_delete(lin_inputs);
05371 cpl_vector_delete(vcoeffs);
05372 cpl_image_delete(fiterror);
05373
05374 return lin_table;
05375
05376 }
05377
05378
05402
05403 static cpl_error_code
05404 irplib_detmon_lin_table_fill_row(cpl_table * lin_table, double c_dit,
05405 cpl_imagelist * linearity_inputs,
05406 const cpl_imagelist * ons,
05407 const cpl_imagelist * offs,
05408 int llx,
05409 int lly,
05410 int urx,
05411 int ury,
05412 const int pos,
05413 const int nskip,
05414 unsigned mode)
05415 {
05416 cpl_image * dif1=NULL;
05417 cpl_image * dif2=NULL;
05418 cpl_image * dif_avg=NULL;
05419
05420 double med_dit=0;
05421 double mean_dit=0;
05422 cpl_error_code error;
05423 cpl_image * extracted=NULL;
05424 int offsize=0;
05425
05426 cpl_ensure_code(lin_table != NULL, CPL_ERROR_NULL_INPUT);
05427 cpl_ensure_code(ons != NULL, CPL_ERROR_NULL_INPUT);
05428 cpl_ensure_code(offs != NULL, CPL_ERROR_NULL_INPUT);
05429
05430 if (mode & IRPLIB_LIN_PIX2PIX) {
05431 cpl_msg_debug(cpl_func,"checking linearity inputs");
05432 cpl_ensure_code(linearity_inputs != NULL, CPL_ERROR_NULL_INPUT);
05433 }
05434
05435
05436 if (mode & IRPLIB_LIN_NIR) {
05437 cpl_table_set(lin_table, "DIT", pos, c_dit);
05438 } else if (mode & IRPLIB_LIN_OPT) {
05439 cpl_table_set(lin_table, "EXPTIME", pos, c_dit);
05440 } else {
05441 cpl_msg_error(cpl_func, "Mandatory mode not given");
05442 }
05443
05444
05445 offsize = cpl_imagelist_get_size(offs);
05446
05447
05448 dif1 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
05449 cpl_imagelist_get_const(offs, 0));
05450
05451 if (mode & IRPLIB_LIN_NO_COLLAPSE && offsize > 1)
05452 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
05453 cpl_imagelist_get_const(offs, 1));
05454 else
05455 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
05456 cpl_imagelist_get_const(offs, 0));
05457
05458 dif_avg = cpl_image_average_create(dif1, dif2);
05459
05460 cpl_image_abs(dif_avg);
05461 extracted = cpl_image_extract(dif_avg, llx, lly, urx, ury);
05462
05463 cpl_ensure_code(extracted != NULL, cpl_error_get_code());
05464
05465 cpl_table_set(lin_table, "MED", pos, cpl_image_get_median(extracted));
05466 cpl_table_set(lin_table, "MEAN", pos, cpl_image_get_mean(extracted));
05467 med_dit = cpl_image_get_median(extracted) / c_dit;
05468 mean_dit = cpl_image_get_mean(extracted) / c_dit;
05469
05470 cpl_table_set(lin_table, "MED_DIT", pos, med_dit);
05471 cpl_table_set(lin_table, "MEAN_DIT", pos, mean_dit);
05472
05473 cpl_image_delete(dif1);
05474 cpl_image_delete(dif2);
05475
05476
05477 if(mode & IRPLIB_LIN_PIX2PIX) {
05478 error = cpl_imagelist_set(linearity_inputs, extracted, pos-nskip);
05479 cpl_ensure_code(!error, error);
05480 } else {
05481 cpl_image_delete(extracted);
05482 }
05483
05484
05485 cpl_image_delete(dif_avg);
05486
05487 return cpl_error_get_code();
05488 }