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
03810
03811 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
03812
03813 skip_if(cpl_propertylist_append_string(qclist, DETMON_QC_METHOD,
03814 detmon_lg_config.method));
03815 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_METHOD,
03816 DETMON_QC_METHOD_C));
03817
03818 if (!strcmp(detmon_lg_config.method, "PTC")) {
03819
03820 if (detmon_lg_config.exts >= 0) {
03821 cpl_msg_info(cpl_func,
03822 "Polynomial fitting for the GAIN (constant term method)");
03823 } else {
03824 cpl_msg_info(cpl_func,
03825 "Polynomial fitting for the GAIN (constant term method)"
03826 " for extension nb %d", which_ext);
03827 }
03828 skip_if(irplib_detmon_lg_qc_ptc(gain_table, qclist, mode));
03829 } else {
03830 skip_if(irplib_detmon_lg_qc_med(gain_table, qclist));
03831 }
03832
03833
03834
03835 if(detmon_lg_config.lamp_ok) {
03836 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LAMP_FLUX,
03837 detmon_lg_config.cr));
03838 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LAMP_FLUX,
03839 DETMON_QC_LAMP_FLUX_C));
03840 }
03841
03842
03843 if(detmon_lg_config.autocorr == TRUE) {
03844 autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
03845 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_AUTOCORR,
03846 autocorr));
03847 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_AUTOCORR,
03848 DETMON_QC_AUTOCORR_C));
03849 }
03850 if (detmon_lg_config.exts >= 0) {
03851 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix");
03852 } else {
03853 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix"
03854 " for extension nb %d", which_ext);
03855 }
03856
03857 if(!detmon_lg_config.pix2pix) {
03858 double mse = 0;
03859
03860 y = cpl_vector_wrap(nsets,
03861 (double *)cpl_table_get_data_double_const(linear_table,
03862 "MED"));
03863
03864 if (opt_nir == NIR)
03865 x = cpl_vector_wrap(nsets,
03866 (double *)cpl_table_get_data_double_const(linear_table,
03867 "DIT"));
03868 else
03869 x = cpl_vector_wrap(nsets,
03870 (double *)cpl_table_get_data_double_const(linear_table,
03871 "EXPTIME"));
03872
03873
03874 if(x == NULL || y == NULL) {
03875 cpl_vector_unwrap((cpl_vector *)x);
03876 cpl_vector_unwrap((cpl_vector *)y);
03877
03878
03879
03880
03881
03882
03883 skip_if(1);
03884 }
03885
03886 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
03887 poly_linfit = cpl_polynomial_fit_1d_create(x, y,
03888 detmon_lg_config.order,
03889 &mse);
03890
03891 if(detmon_lg_config.order == cpl_vector_get_size(x) - 1) {
03892 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
03893 mse = 0;
03894 }
03895
03896 if(poly_linfit == NULL) {
03897 cpl_vector_unwrap((cpl_vector *)x);
03898 cpl_vector_unwrap((cpl_vector *)y);
03899
03900 skip_if(1);
03901 }
03902
03903
03904 min_val=cpl_vector_get_min(y);
03905 max_val=cpl_vector_get_max(y);
03906
03907 cpl_vector_unwrap((cpl_vector *)x);
03908 cpl_vector_unwrap((cpl_vector *)y);
03909
03910 for(i = 0; i <= detmon_lg_config.order; i++) {
03911 const double coeff =
03912 cpl_polynomial_get_coeff(poly_linfit, &i);
03913 char *name_o =
03914 cpl_sprintf("ESO QC LIN COEF%d", i);
03915 assert(name_o != NULL);
03916 skip_if(cpl_propertylist_append_double(qclist, name_o, coeff));
03917 skip_if(cpl_propertylist_set_comment(qclist,name_o,
03918 DETMON_QC_LIN_COEF_C));
03919
03920 cpl_free(name_o);
03921 pcoeffs[i] = coeff;
03922 }
03923 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT, mse));
03924 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
03925 DETMON_QC_ERRFIT_MSE_C));
03926
03927
03928 } else {
03929
03930
03931 y = cpl_vector_wrap(nsets,
03932 (double *)cpl_table_get_data_double_const(linear_table,
03933 "MED"));
03934
03935 if (opt_nir == NIR) {
03936 x=
03937 cpl_vector_wrap(nsets,
03938 (double *)cpl_table_get_data_double_const(linear_table,
03939 "DIT"));
03940
03941 } else {
03942
03943 x =
03944 cpl_vector_wrap(nsets,
03945 (double *)cpl_table_get_data_double_const(linear_table,
03946 "EXPTIME"));
03947
03948 }
03949
03950
03951 const cpl_image * first = cpl_imagelist_get_const(linearity_inputs, 0);
03952 int sizex = cpl_image_get_size_x(first);
03953 int sizey = cpl_image_get_size_y(first);
03954
03955 double vsize = cpl_vector_get_size(x);
03956
03957 fiterror = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
03958
03959 *coeffs_ptr =
03960 cpl_fit_imagelist_polynomial(x, linearity_inputs, 0,
03961 detmon_lg_config.order, FALSE,
03962 CPL_TYPE_FLOAT, fiterror);
03963
03964 min_val=cpl_vector_get_min(y);
03965 max_val=cpl_vector_get_max(y);
03966
03967
03968 cpl_vector_unwrap((cpl_vector*)x);
03969 cpl_vector_unwrap((cpl_vector*)y);
03970 irplib_ensure(*coeffs_ptr != NULL, CPL_ERROR_UNSPECIFIED,
03971 "Failed polynomial fit");
03972
03973 for(i = 0; i <= detmon_lg_config.order; i++) {
03974 cpl_image *image = cpl_imagelist_get(*coeffs_ptr, i);
03975 const double coeff = cpl_image_get_median(image);
03976 pcoeffs[i] = coeff;
03977 name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
03978 name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
03979 assert(name_o1 != NULL);
03980 assert(name_o2 != NULL);
03981 skip_if(cpl_propertylist_append_double(qclist, name_o1, coeff));
03982 skip_if(cpl_propertylist_set_comment(qclist,name_o1,
03983 DETMON_QC_LIN_COEF_C));
03984 cpl_free(name_o1);
03985 name_o1= NULL;
03986 skip_if(cpl_propertylist_append_double(qclist, name_o2,
03987 cpl_image_get_stdev(image)));
03988 skip_if(cpl_propertylist_set_comment(qclist,name_o2,
03989 DETMON_QC_LIN_COEF_ERR_C));
03990 cpl_free(name_o2);
03991 name_o2= NULL;
03992 }
03993
03994 if(detmon_lg_config.order == vsize - 1) {
03995 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
03996 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
03997 0.0));
03998 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
03999 DETMON_QC_ERRFIT_C));
04000
04001
04002
04003 } else {
04004 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
04005 cpl_image_get_median(fiterror)));
04006 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
04007 DETMON_QC_ERRFIT_C));
04008
04009 }
04010 }
04011
04012
04013 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_COUNTS_MIN,
04014 min_val));
04015
04016 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_COUNTS_MIN,
04017 DETMON_QC_COUNTS_MIN_C));
04018
04019 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_COUNTS_MAX,
04020 max_val));
04021
04022 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_COUNTS_MAX,
04023 DETMON_QC_COUNTS_MAX_C));
04024
04025 skip_if(irplib_detmon_lg_lineff(pcoeffs,qclist,detmon_lg_config.ref_level,
04026 detmon_lg_config.order));
04027
04028
04029 if (detmon_lg_config.exts >= 0) {
04030 cpl_msg_info(cpl_func, "Bad pixel detection");
04031 } else {
04032 cpl_msg_info(cpl_func, "Bad pixel detection"
04033 " for extension nb %d", which_ext);
04034 }
04035
04036 if(detmon_lg_config.pix2pix) {
04037 *bpms_ptr = irplib_detmon_bpixs(*coeffs_ptr, detmon_lg_config.bpmbin,
04038 detmon_lg_config.kappa, &nbpixs);
04039 skip_if(*bpms_ptr == NULL);
04040 }
04041
04042 skip_if(cpl_propertylist_append_int(qclist, DETMON_QC_NUM_BPM, nbpixs));
04043 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_NUM_BPM,
04044 DETMON_QC_NUM_BPM_C));
04045
04046 if(detmon_lg_config.lamp_stability != 0.0) {
04047 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LAMP_STAB,
04048 detmon_lg_config.lamp_stability));
04049 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LAMP_STAB,
04050 DETMON_QC_LAMP_STAB_C));
04051 }
04052 end_skip;
04053
04054 cpl_free(pcoeffs);
04055 cpl_free(name_o1);
04056 cpl_free(name_o2);
04057 cpl_image_delete(fiterror);
04058 cpl_polynomial_delete(poly_linfit);
04059
04060 return cpl_error_get_code();
04061 }
04062
04063
04071
04072 static cpl_error_code
04073 irplib_detmon_lg_lineff(double * pcoeffs,
04074 cpl_propertylist * qclist,
04075 int ref_level,
04076 int order)
04077 {
04078 double lineff = 0;
04079 double root = 0;
04080 cpl_polynomial * poly = cpl_polynomial_new(1);
04081 int i;
04082
04083 double residual, slope;
04084
04085
04086
04087
04088
04089 pcoeffs[0] -= ref_level;
04090
04091 for (i = 2; i <= order; i++) {
04092 int j;
04093 for(j = 0; j < i; j++) {
04094 pcoeffs[i] /= pcoeffs[1];
04095 }
04096 }
04097
04098 pcoeffs[1] = 1;
04099
04100 for (i = 0; i <= order; i++) {
04101 skip_if(cpl_polynomial_set_coeff(poly, &i, pcoeffs[i]));
04102 }
04103
04104
04105
04106
04107
04108
04109
04110 residual = cpl_polynomial_eval_1d(poly, 0.0, &slope);
04111
04112 if (slope <= 0.0 && residual >= 0.0) {
04113 cpl_msg_warning(cpl_func, "Reference level (--ref_level) outside"
04114 " linearity range of the detector. Cannot compute"
04115 " linearity efficiency (QC.LINEFF).");
04116 lineff = -1;
04117 } else {
04118 skip_if(cpl_polynomial_solve_1d(poly, 0.0, &root, 1));
04119
04120 lineff = (root - ref_level) / ref_level;
04121 }
04122
04123 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LIN_EFF,
04124 lineff));
04125 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LIN_EFF,
04126 DETMON_QC_LIN_EFF_C));
04127
04128 end_skip;
04129
04130 cpl_polynomial_delete(poly);
04131
04132 return cpl_error_get_code();
04133 }
04134
04135
04142
04143 static cpl_error_code
04144 irplib_detmon_lg_qc_ptc(const cpl_table * gain_table,
04145 cpl_propertylist * qclist, unsigned mode)
04146 {
04147 double mse = 0;
04148 cpl_polynomial *poly_fit = NULL;
04149 cpl_polynomial *poly_fit2 = NULL;
04150 int i;
04151 const int nsets = cpl_table_get_nrow(gain_table);
04152
04153
04154
04155
04156
04157 const cpl_vector *x;
04158 const cpl_vector *y;
04159
04160 cpl_errorstate prestate;
04161 double coef = 0;
04162
04163 cpl_ensure_code(gain_table != NULL, CPL_ERROR_NULL_INPUT);
04164 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
04165
04166 x = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT"));
04167
04168 y = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
04169
04170 skip_if(x == NULL || y == NULL);
04171
04172 poly_fit = cpl_polynomial_fit_1d_create(x, y, 1, &mse);
04173 skip_if(poly_fit == NULL);
04174
04175
04176 i = 1;
04177 prestate = cpl_errorstate_get();
04178 coef = cpl_polynomial_get_coeff(poly_fit, &i);
04179 skip_if (!cpl_errorstate_is_equal(prestate) || coef == 0);
04180
04181 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD, coef));
04182 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
04183 DETMON_QC_CONAD_C));
04184
04185 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,
04186 1 / coef));
04187 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
04188 DETMON_QC_GAIN_C));
04189
04190 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE, mse));
04191 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
04192 DETMON_QC_GAIN_MSE_C));
04193 i = 0;
04194 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_RON,
04195 cpl_polynomial_get_coeff(poly_fit, &i)));
04196 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_RON,
04197 DETMON_QC_RON_C));
04198
04199 if(mode & IRPLIB_GAIN_WITH_AUTOCORR){
04200 const cpl_vector *x2 =
04201 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT_CORR"));
04202 const cpl_vector *y2 =
04203 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
04204
04205 if(x2 == NULL || y2 == NULL) {
04206 cpl_vector_unwrap((cpl_vector *)x2);
04207 cpl_vector_unwrap((cpl_vector *)y2);
04208
04209
04210
04211
04212
04213
04214 skip_if(1);
04215 }
04216
04217
04218 poly_fit2 = cpl_polynomial_fit_1d_create(x2, y2, 1, &mse);
04219 if(poly_fit2 == NULL) {
04220 cpl_vector_unwrap((cpl_vector *)x2);
04221 cpl_vector_unwrap((cpl_vector *)y2);
04222
04223 skip_if(1);
04224 }
04225
04226 cpl_vector_unwrap((cpl_vector *)x2);
04227 cpl_vector_unwrap((cpl_vector *)y2);
04228
04229
04230 i = 1;
04231 prestate = cpl_errorstate_get();
04232 coef = cpl_polynomial_get_coeff(poly_fit2, &i);
04233 skip_if (!cpl_errorstate_is_equal(prestate) || coef == 0);
04234
04235 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
04236 1 / coef));
04237 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
04238 DETMON_QC_GAIN_CORR_C));
04239 }
04240
04241 end_skip;
04242
04243
04244 cpl_vector_unwrap((cpl_vector *)x);
04245 cpl_vector_unwrap((cpl_vector *)y);
04246 cpl_polynomial_delete(poly_fit);
04247 cpl_polynomial_delete(poly_fit2);
04248
04249 return cpl_error_get_code();
04250 }
04251
04252
04261
04262 static cpl_error_code
04263 irplib_detmon_lg_qc_med(const cpl_table * gain_table,
04264 cpl_propertylist * qclist)
04265 {
04266
04267 double gain=0;
04268 gain=cpl_table_get_column_median(gain_table, "GAIN");
04269
04270 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,gain));
04271
04272 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
04273 DETMON_QC_GAIN_C));
04274
04275 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE,
04276 cpl_table_get_column_stdev
04277 (gain_table, "GAIN")));
04278 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
04279 DETMON_QC_GAIN_MSE_C));
04280
04281 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD,1./gain));
04282 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
04283 DETMON_QC_CONAD_C));
04284
04285
04286 gain=cpl_table_get_column_median(gain_table, "GAIN_CORR");
04287
04288 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
04289 gain));
04290 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
04291 DETMON_QC_GAIN_CORR_C));
04292
04293
04294 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD_CORR,1./gain));
04295 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD_CORR,
04296 DETMON_QC_CONAD_CORR_C));
04297
04298
04299 end_skip;
04300
04301 return cpl_error_get_code();
04302 }
04303
04304
04305
04314
04315 static cpl_error_code
04316 irplib_detmon_lg_rescale(cpl_imagelist * to_rescale)
04317 {
04318 double med1 =
04319 cpl_image_get_median(cpl_imagelist_get(to_rescale, 0));
04320 double med2 =
04321 cpl_image_get_median(cpl_imagelist_get(to_rescale, 1));
04322
04323 skip_if(0);
04324
04325 if(fabs(med1 / med2 - 1) > 0.001) {
04326 if(med1 > med2)
04327 skip_if(cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 0),
04328 med1 / med2));
04329 else
04330 skip_if(cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 1),
04331 med2 / med1));
04332 }
04333
04334 end_skip;
04335
04336 return cpl_error_get_code();
04337 }
04338
04339
04357
04358 static cpl_error_code
04359 irplib_detmon_pair_extract(const cpl_frameset * set,
04360 int * selection, int selected,
04361 int nsets_extracted,
04362 int * with_equal_dit,
04363 int onoff,
04364 cpl_frameset ** pair)
04365 {
04366 int new_with_equal_dit = 0;
04367
04368 cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
04369 cpl_ensure_code(selection != NULL, CPL_ERROR_NULL_INPUT);
04370 cpl_ensure_code(with_equal_dit != NULL, CPL_ERROR_NULL_INPUT);
04371 cpl_ensure_code(pair != NULL, CPL_ERROR_NULL_INPUT);
04372
04373 *pair = cpl_frameset_extract(set, selection, selected);
04374 cpl_ensure_code(*pair != NULL, cpl_error_get_code());
04375
04376
04377
04378
04379 skip_if(cpl_frameset_get_size(*pair) % 2 != 0);
04380
04381
04382 if(cpl_frameset_get_size(*pair) != 2) {
04383 new_with_equal_dit = cpl_frameset_get_size(*pair) / 2;
04384 if(onoff == 1) {
04385 *with_equal_dit = new_with_equal_dit;
04386 } else {
04387 skip_if (*with_equal_dit != 0 &&
04388 new_with_equal_dit != *with_equal_dit);
04389 }
04390 }
04391
04392
04393 if (new_with_equal_dit != 0) {
04394 int found = 0;
04395 int j;
04396 for(j = 0; j < cpl_frameset_get_size(set); j++) {
04397
04398 if(selection[j] == selected) {
04399 found++;
04400
04401 if((found - 1) / 2 != 0) {
04402 selection[j] =
04403 nsets_extracted + (found - 1) / 2 - 1;
04404 }
04405 }
04406 }
04407 cpl_frameset_delete(*pair);
04408 *pair = cpl_frameset_extract(set, selection, selected);
04409
04410 }
04411
04412 end_skip;
04413
04414 return cpl_error_get_code();
04415 }
04416
04434
04435 static cpl_error_code
04436 irplib_detmon_single_extract(const cpl_frameset * set,
04437 int * selection, int selected,
04438 int nsets_extracted,
04439 int * with_equal_dit,
04440 int onoff,
04441 cpl_frameset ** single)
04442 {
04443 int new_with_equal_dit = 0;
04444
04445 cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
04446 cpl_ensure_code(selection != NULL, CPL_ERROR_NULL_INPUT);
04447 cpl_ensure_code(with_equal_dit != NULL, CPL_ERROR_NULL_INPUT);
04448 cpl_ensure_code(single != NULL, CPL_ERROR_NULL_INPUT);
04449
04450 *single = cpl_frameset_extract(set, selection, selected);
04451 cpl_ensure_code(*single != NULL, cpl_error_get_code());
04452
04453
04454
04455
04456 if(cpl_frameset_get_size(*single) != 1) {
04457 new_with_equal_dit = cpl_frameset_get_size(*single);
04458 if(onoff == 1) {
04459 *with_equal_dit = new_with_equal_dit;
04460 } else {
04461 skip_if (*with_equal_dit != 0 &&
04462 new_with_equal_dit != *with_equal_dit);
04463 }
04464 }
04465
04466
04467 if (new_with_equal_dit != 0) {
04468 int found = 0;
04469 int j;
04470 for(j = 0; j < cpl_frameset_get_size(set); j++) {
04471
04472 if(selection[j] == selected) {
04473 found++;
04474
04475 if(found > 1) {
04476 selection[j] =
04477 nsets_extracted + (found - 2);
04478 }
04479 }
04480 }
04481 cpl_frameset_delete(*single);
04482 *single = cpl_frameset_extract(set, selection, selected);
04483
04484 }
04485
04486 end_skip;
04487
04488 return cpl_error_get_code();
04489 }
04490
04491
04492
04493
04494
04495
04496
04497
04498
04499
04500
04501 static int
04502 irplib_detmon_lg_compare_pairs(const cpl_frame * frame1,
04503 const cpl_frame * frame2)
04504 {
04505 int comparison;
04506 cpl_propertylist *plist1;
04507 cpl_propertylist *plist2;
04508 double dval1, dval2;
04509
04510
04511 if(frame1 == NULL || frame2 == NULL)
04512 return -1;
04513
04514
04515 if((plist1 = cpl_propertylist_load(cpl_frame_get_filename(frame1),
04516 0)) == NULL) {
04517 cpl_msg_error(cpl_func, "getting header from reference frame");
04518 return -1;
04519 }
04520 if((plist2 = cpl_propertylist_load(cpl_frame_get_filename(frame2),
04521 0)) == NULL) {
04522 cpl_msg_error(cpl_func, "getting header from reference frame");
04523 cpl_propertylist_delete(plist1);
04524 return -1;
04525 }
04526
04527
04528 if(cpl_error_get_code()) {
04529 cpl_propertylist_delete(plist1);
04530 cpl_propertylist_delete(plist2);
04531 return -1;
04532 }
04533
04534
04535 comparison = 1;
04536 dval1 = irplib_pfits_get_exptime(plist1);
04537 dval2 = irplib_pfits_get_exptime(plist2);
04538 if(cpl_error_get_code()) {
04539 cpl_msg_error(cpl_func, "cannot get exposure time");
04540 cpl_propertylist_delete(plist1);
04541 cpl_propertylist_delete(plist2);
04542 return -1;
04543 }
04544 if(fabs(dval1 - dval2) > detmon_lg_config.tolerance)
04545 comparison = 0;
04546
04547
04548 cpl_propertylist_delete(plist1);
04549 cpl_propertylist_delete(plist2);
04550 return comparison;
04551 }
04552
04553
04642
04643
04644 cpl_table *
04645 irplib_detmon_gain(const cpl_imagelist * imlist_on,
04646 const cpl_imagelist * imlist_off,
04647 const cpl_vector * exptimes,
04648 double tolerance,
04649 int llx,
04650 int lly,
04651 int urx,
04652 int ury,
04653 double kappa,
04654 int nclip,
04655 int xshift,
04656 int yshift,
04657 cpl_propertylist * qclist,
04658 unsigned mode,
04659 cpl_imagelist ** diff_imlist,
04660 cpl_imagelist ** autocorr_imlist)
04661 {
04662 cpl_table * gain_table = NULL;
04663 cpl_imagelist * difflist = NULL;
04664 cpl_imagelist * autocorrlist = NULL;
04665 cpl_imagelist * c_onlist = NULL;
04666 cpl_imagelist * c_offlist = NULL;
04667 cpl_vector * diffdits = NULL;
04668 int ndiffdits, ndits;
04669 int i, j;
04670 cpl_boolean opt_nir = mode & IRPLIB_GAIN_OPT ? OPT : NIR;
04671
04672 cpl_ensure(imlist_on != NULL, CPL_ERROR_NULL_INPUT, NULL);
04673 cpl_ensure(imlist_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
04674 cpl_ensure(exptimes != NULL, CPL_ERROR_NULL_INPUT, NULL);
04675 cpl_ensure(qclist != NULL, CPL_ERROR_NULL_INPUT, NULL);
04676
04677
04678 gain_table = cpl_table_new(cpl_vector_get_size(exptimes) / 2);
04679 skip_if(irplib_detmon_gain_table_create(gain_table, opt_nir));
04680
04681
04682 diffdits = irplib_detmon_lg_find_dits(exptimes, tolerance);
04683 ndiffdits = cpl_vector_get_size(diffdits);
04684
04685 ndits = cpl_vector_get_size(exptimes);
04686
04687
04688 if (mode & IRPLIB_GAIN_WITH_AUTOCORR && (diff_imlist || autocorr_imlist)) {
04689 difflist = cpl_imagelist_new();
04690 autocorrlist = cpl_imagelist_new();
04691 }
04692
04693 if (mode & IRPLIB_GAIN_COLLAPSE) {
04694 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04695 c_offlist = cpl_imagelist_duplicate(imlist_off);
04696 skip_if(irplib_detmon_lg_rescale(c_offlist));
04697 } else {
04698 c_offlist = (cpl_imagelist *) imlist_off;
04699 }
04700 }
04701
04702
04703 for (i = 0; i < ndiffdits; i++) {
04704 int c_nons;
04705 int c_noffs = 0;
04706
04707 double c_dit = cpl_vector_get(diffdits, i);
04708
04709 c_onlist = cpl_imagelist_new();
04710 c_nons = 0;
04711
04712 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04713 c_offlist = cpl_imagelist_new();
04714 c_noffs = 0;
04715 }
04716
04717
04718 for(j = 0; j < ndits; j++) {
04719 if (fabs(c_dit - cpl_vector_get(exptimes, j)) <= tolerance) {
04720
04721
04722
04723
04724
04725
04726
04727
04728 cpl_image * im_on;
04729 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04730 const cpl_image * im =
04731 cpl_imagelist_get_const(imlist_on, j);
04732 im_on = cpl_image_duplicate(im);
04733 } else {
04734 im_on = (cpl_image *)cpl_imagelist_get_const(imlist_on, j);
04735 }
04736 skip_if(cpl_imagelist_set(c_onlist, im_on, c_nons));
04737 c_nons++;
04738
04739
04740
04741
04742
04743 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04744 cpl_image * im_off;
04745 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04746 const cpl_image * im =
04747 cpl_imagelist_get_const(imlist_off, j);
04748 im_off = cpl_image_duplicate(im);
04749 } else {
04750 im_off =
04751 (cpl_image *) cpl_imagelist_get_const(imlist_off, j);
04752 }
04753 skip_if(cpl_imagelist_set(c_offlist, im_off, c_noffs));
04754 c_noffs++;
04755 }
04756 }
04757 }
04758
04759
04760 if (mode & IRPLIB_GAIN_NO_COLLAPSE)
04761 skip_if (c_nons != c_noffs);
04762
04763
04764 skip_if (c_nons == 0 || c_nons % 2 != 0);
04765
04766
04767 if(mode & IRPLIB_GAIN_WITH_RESCALE) {
04768 skip_if(irplib_detmon_lg_rescale(c_onlist));
04769 if (mode & IRPLIB_GAIN_NO_COLLAPSE)
04770 skip_if(irplib_detmon_lg_rescale(c_offlist));
04771 }
04772
04773
04774
04775 while(c_nons > 0) {
04776 skip_if(irplib_detmon_gain_table_fill_row(gain_table, c_dit,
04777 autocorrlist,
04778 difflist, c_onlist,
04779 c_offlist, kappa, nclip,
04780 llx, lly, urx, ury,
04781 xshift, yshift, i,
04782 mode));
04783 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
04784 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
04785 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
04786 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04787 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
04788 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
04789 }
04790 } else {
04791 cpl_imagelist_unset(c_onlist, 0);
04792 skip_if(0);
04793 cpl_imagelist_unset(c_onlist, 0);
04794 skip_if(0);
04795 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04796 cpl_imagelist_unset(c_offlist, 0);
04797 skip_if(0);
04798 cpl_imagelist_unset(c_offlist, 0);
04799 skip_if(0);
04800 }
04801 }
04802 skip_if(0);
04803 c_nons -= 2;
04804 }
04805
04806 cpl_imagelist_delete(c_onlist);
04807 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
04808 cpl_imagelist_delete(c_offlist);
04809 }
04810 }
04811
04812
04813 if (mode & IRPLIB_GAIN_PTC) {
04814 skip_if(irplib_detmon_lg_qc_ptc(gain_table, qclist, mode));
04815 } else {
04816 skip_if(irplib_detmon_lg_qc_med(gain_table, qclist));
04817 }
04818
04819 if(mode & IRPLIB_GAIN_WITH_AUTOCORR) {
04820 double autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
04821 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_AUTOCORR,
04822 autocorr));
04823 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_AUTOCORR,
04824 DETMON_QC_AUTOCORR_C));
04825 }
04826
04827 if (diff_imlist != NULL) *diff_imlist = difflist;
04828 if (autocorr_imlist != NULL) *autocorr_imlist = autocorrlist;
04829
04830 end_skip;
04831
04832 cpl_vector_delete(diffdits);
04833
04834 return gain_table;
04835 }
04836
04837 static cpl_error_code
04838 irplib_detmon_gain_table_create(cpl_table * gain_table,
04839 const cpl_boolean opt_nir)
04840 {
04841 if (opt_nir == NIR) {
04842 skip_if(cpl_table_new_column(gain_table, "DIT", CPL_TYPE_DOUBLE));
04843 } else {
04844 skip_if(cpl_table_new_column(gain_table, "EXPTIME", CPL_TYPE_DOUBLE));
04845 }
04846 skip_if(cpl_table_new_column(gain_table, "MEAN_ON1", CPL_TYPE_DOUBLE));
04847 skip_if(cpl_table_new_column(gain_table, "MEAN_ON2", CPL_TYPE_DOUBLE));
04848 skip_if(cpl_table_new_column(gain_table, "MEAN_OFF1", CPL_TYPE_DOUBLE));
04849 skip_if(cpl_table_new_column(gain_table, "MEAN_OFF2", CPL_TYPE_DOUBLE));
04850 skip_if(cpl_table_new_column(gain_table, "SIG_ON_DIF", CPL_TYPE_DOUBLE));
04851 skip_if(cpl_table_new_column(gain_table, "SIG_OFF_DIF", CPL_TYPE_DOUBLE));
04852 skip_if(cpl_table_new_column(gain_table, "GAIN", CPL_TYPE_DOUBLE));
04853 skip_if(cpl_table_new_column(gain_table, "AUTOCORR", CPL_TYPE_DOUBLE));
04854 skip_if(cpl_table_new_column(gain_table, "GAIN_CORR", CPL_TYPE_DOUBLE));
04855 skip_if(cpl_table_new_column(gain_table, "ADU", CPL_TYPE_DOUBLE));
04856 skip_if(cpl_table_new_column(gain_table, "X_FIT", CPL_TYPE_DOUBLE));
04857 skip_if(cpl_table_new_column(gain_table, "X_FIT_CORR", CPL_TYPE_DOUBLE));
04858 skip_if(cpl_table_new_column(gain_table, "Y_FIT", CPL_TYPE_DOUBLE));
04859 skip_if(cpl_table_new_column(gain_table, "Y_FIT_CORR", CPL_TYPE_DOUBLE));
04860
04861 end_skip;
04862
04863 return cpl_error_get_code();
04864 }
04865
04866 static cpl_error_code
04867 irplib_detmon_lin_table_create(cpl_table * lin_table,
04868 const cpl_boolean opt_nir)
04869 {
04870 if (opt_nir == NIR) {
04871 skip_if(cpl_table_new_column(lin_table, "DIT", CPL_TYPE_DOUBLE));
04872 } else {
04873 skip_if(cpl_table_new_column(lin_table, "EXPTIME", CPL_TYPE_DOUBLE));
04874 }
04875 skip_if(cpl_table_new_column(lin_table, "MED", CPL_TYPE_DOUBLE));
04876 skip_if(cpl_table_new_column(lin_table, "MEAN", CPL_TYPE_DOUBLE));
04877 skip_if(cpl_table_new_column(lin_table, "MED_DIT", CPL_TYPE_DOUBLE));
04878 skip_if(cpl_table_new_column(lin_table, "MEAN_DIT", CPL_TYPE_DOUBLE));
04879 skip_if(cpl_table_new_column(lin_table, "ADL", CPL_TYPE_DOUBLE));
04880
04881 end_skip;
04882
04883 return cpl_error_get_code();
04884 }
04885
04886 static cpl_vector *
04887 irplib_detmon_lg_find_dits(const cpl_vector * exptimes,
04888 double tolerance)
04889 {
04890 cpl_vector * dits = cpl_vector_new(cpl_vector_get_size(exptimes) / 2);
04891 int ndits = 0;
04892
04893 int i, j;
04894
04895
04896 cpl_vector_set(dits, 0, cpl_vector_get(exptimes, 0));
04897 ndits = 1;
04898
04899
04900 for(i = 1; i < cpl_vector_get_size(exptimes); i++) {
04901 int ndiffs = 0;
04902 for (j = 0; j < ndits; j++) {
04903 if (fabs(cpl_vector_get(exptimes, i) -
04904 cpl_vector_get(dits, j)) > tolerance)
04905 ndiffs++;
04906 }
04907 if(ndiffs == ndits) {
04908 cpl_vector_set(dits, ndits, cpl_vector_get(exptimes, i));
04909 ndits++;
04910 }
04911 }
04912
04913 cpl_vector_set_size(dits, ndits);
04914
04915 return dits;
04916 }
04917
04918
04919
05000
05001
05002 cpl_table *
05003 irplib_detmon_lin(const cpl_imagelist * imlist_on,
05004 const cpl_imagelist * imlist_off,
05005 const cpl_vector * exptimes,
05006 double tolerance,
05007 int llx,
05008 int lly,
05009 int urx,
05010 int ury,
05011 int order,
05012 int ref_level,
05013 double kappa,
05014 cpl_boolean bpmbin,
05015 cpl_propertylist * qclist,
05016 unsigned mode,
05017 cpl_imagelist ** coeffs_cube,
05018 cpl_image ** bpm)
05019 {
05020 cpl_table * lin_table = NULL;
05021 cpl_imagelist * c_onlist = NULL;
05022 cpl_imagelist * c_offlist = NULL;
05023 cpl_vector * diffdits = NULL;
05024 cpl_imagelist * lin_inputs = NULL;
05025 cpl_polynomial * poly_linfit = NULL;
05026 cpl_image * fiterror = NULL;
05027 cpl_vector * vcoeffs = NULL;
05028 double * pcoeffs = NULL;
05029 int ndiffdits, ndits;
05030 int i, j;
05031 cpl_boolean opt_nir = mode & IRPLIB_LIN_OPT ? OPT : NIR;
05032 const cpl_vector *x = NULL;
05033 const cpl_vector *y = NULL;
05034
05035
05036 cpl_ensure(imlist_on != NULL, CPL_ERROR_NULL_INPUT, NULL);
05037 cpl_ensure(imlist_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
05038 cpl_ensure(exptimes != NULL, CPL_ERROR_NULL_INPUT, NULL);
05039 cpl_ensure(qclist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05040 cpl_ensure(order > 0 , CPL_ERROR_ILLEGAL_INPUT, NULL);
05041
05042 vcoeffs = cpl_vector_new(order + 1);
05043 pcoeffs = cpl_vector_get_data(vcoeffs);
05044
05045
05046 if (mode & IRPLIB_LIN_PIX2PIX) {
05047 lin_inputs = cpl_imagelist_new();
05048 cpl_ensure(coeffs_cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
05049 cpl_ensure(bpm != NULL, CPL_ERROR_NULL_INPUT, NULL);
05050 }
05051
05052
05053 lin_table = cpl_table_new(cpl_vector_get_size(exptimes) / 2);
05054 skip_if(irplib_detmon_lin_table_create(lin_table, opt_nir));
05055
05056
05057
05058 diffdits = irplib_detmon_lg_find_dits(exptimes, tolerance);
05059 ndiffdits = cpl_vector_get_size(diffdits);
05060
05061 ndits = cpl_vector_get_size(exptimes);
05062
05063
05064
05065
05066
05067
05068
05069
05070
05071
05072
05073
05074
05075
05076
05077
05078
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091 if (mode & IRPLIB_LIN_COLLAPSE) {
05092
05093
05094
05095
05096 cpl_image * collapse = cpl_imagelist_collapse_create(imlist_off);
05097 skip_if(collapse == NULL);
05098
05099 c_offlist = cpl_imagelist_new();
05100 skip_if(cpl_imagelist_set(c_offlist, collapse, 0));
05101 }
05102
05103
05104 for (i = 0; i < ndiffdits; i++) {
05105 int c_nons;
05106 int c_noffs = 0;
05107
05108 double c_dit = cpl_vector_get(diffdits, i);
05109
05110 c_onlist = cpl_imagelist_new();
05111 c_nons = 0;
05112
05113 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05114 c_offlist = cpl_imagelist_new();
05115 c_noffs = 0;
05116 }
05117
05118 for(j = 0; j < ndits; j++) {
05119 if (fabs(c_dit - cpl_vector_get(exptimes, j)) <= tolerance) {
05120
05121
05122
05123
05124
05125
05126
05127
05128 cpl_image * im_on;
05129 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05130 const cpl_image * im =
05131 cpl_imagelist_get_const(imlist_on, j);
05132 im_on = cpl_image_duplicate(im);
05133 } else {
05134 im_on = (cpl_image *)cpl_imagelist_get_const(imlist_on, j);
05135 }
05136 skip_if(cpl_imagelist_set(c_onlist, im_on, c_nons));
05137 c_nons++;
05138
05139
05140
05141
05142
05143 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05144 cpl_image * im_off;
05145 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05146 const cpl_image * im =
05147 cpl_imagelist_get_const(imlist_off, j);
05148 im_off = cpl_image_duplicate(im);
05149 } else {
05150 im_off =
05151 (cpl_image *) cpl_imagelist_get_const(imlist_off, j);
05152 }
05153 skip_if(cpl_imagelist_set(c_offlist, im_off, c_noffs));
05154 c_noffs++;
05155 }
05156 }
05157 }
05158
05159
05160 if (mode & IRPLIB_LIN_NO_COLLAPSE)
05161 skip_if (c_nons != c_noffs);
05162
05163
05164 skip_if (c_nons == 0 || c_nons % 2 != 0);
05165
05166
05167 if(mode & IRPLIB_LIN_WITH_RESCALE) {
05168 skip_if(irplib_detmon_lg_rescale(c_onlist));
05169 if (mode & IRPLIB_LIN_NO_COLLAPSE)
05170 skip_if(irplib_detmon_lg_rescale(c_offlist));
05171 }
05172
05173
05174
05175 while(c_nons > 0) {
05176
05177 skip_if(irplib_detmon_lin_table_fill_row(lin_table, c_dit,
05178 lin_inputs,
05179 c_onlist, c_offlist,
05180 llx, lly, urx, ury,
05181 i, 0, mode));
05182
05183 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05184 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05185 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05186 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05187 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05188 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05189 }
05190 } else {
05191 cpl_imagelist_unset(c_onlist, 0);
05192 skip_if(0);
05193 cpl_imagelist_unset(c_onlist, 0);
05194 skip_if(0);
05195 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05196 cpl_imagelist_unset(c_offlist, 0);
05197 skip_if(0);
05198 cpl_imagelist_unset(c_offlist, 0);
05199 skip_if(0);
05200 }
05201 }
05202 skip_if(0);
05203 c_nons -= 2;
05204 }
05205
05206 cpl_imagelist_delete(c_onlist);
05207 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05208 cpl_imagelist_delete(c_offlist);
05209 }
05210 }
05211
05212 skip_if(irplib_detmon_add_adl_column(lin_table, opt_nir));
05213
05214 if(!(mode & IRPLIB_LIN_PIX2PIX)) {
05215 double mse = 0;
05216
05217 y = cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05218 (double *)cpl_table_get_data_double_const(lin_table,
05219 "MED"));
05220 if (opt_nir == NIR) {
05221 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05222 (double *)cpl_table_get_data_double_const(lin_table, "DIT"));
05223 } else {
05224 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05225 (double *)cpl_table_get_data_double_const(lin_table, "EXPTIME"));
05226 }
05227 if(x == NULL || y == NULL) {
05228 cpl_vector_unwrap((cpl_vector *)x);
05229 cpl_vector_unwrap((cpl_vector *)y);
05230
05231
05232
05233
05234
05235
05236 skip_if(1);
05237 }
05238
05239 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
05240 poly_linfit = cpl_polynomial_fit_1d_create(x, y, order, &mse);
05241
05242 if(order == cpl_vector_get_size(x) - 1) {
05243 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
05244 mse = 0;
05245 }
05246
05247 if(poly_linfit == NULL) {
05248 cpl_vector_unwrap((cpl_vector *)x);
05249 cpl_vector_unwrap((cpl_vector *)y);
05250
05251 skip_if(1);
05252 }
05253
05254 cpl_vector_unwrap((cpl_vector *)x);
05255 cpl_vector_unwrap((cpl_vector *)y);
05256
05257 for(i = 0; i <= order; i++) {
05258 const double coeff =
05259 cpl_polynomial_get_coeff(poly_linfit, &i);
05260 char *name_o =
05261 cpl_sprintf("ESO QC LIN COEF%d", i);
05262 assert(name_o != NULL);
05263 skip_if(cpl_propertylist_append_double(qclist, name_o, coeff));
05264 skip_if(cpl_propertylist_set_comment(qclist,name_o,
05265 DETMON_QC_LIN_COEF_C));
05266 cpl_free(name_o);
05267 pcoeffs[i] = coeff;
05268 }
05269 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT, mse));
05270 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05271 DETMON_QC_ERRFIT_MSE_C));
05272
05273
05274 } else {
05275 if (opt_nir == NIR) {
05276 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05277 (double *)cpl_table_get_data_double_const(lin_table,
05278 "DIT"));
05279 } else {
05280 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05281 (double *)cpl_table_get_data_double_const(lin_table,
05282 "EXPTIME"));
05283 }
05284 const cpl_image * first = cpl_imagelist_get_const(lin_inputs, 0);
05285 int sizex = cpl_image_get_size_x(first);
05286 int sizey = cpl_image_get_size_y(first);
05287
05288 double vsize = cpl_vector_get_size(x);
05289
05290 fiterror = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
05291
05292 *coeffs_cube =
05293 cpl_fit_imagelist_polynomial(x, lin_inputs, 0,
05294 order, FALSE, CPL_TYPE_FLOAT,
05295 fiterror);
05296
05297 cpl_vector_unwrap((cpl_vector*)x);
05298 irplib_ensure(*coeffs_cube != NULL, CPL_ERROR_UNSPECIFIED,
05299 "Failed polynomial fit");
05300
05301 for(i = 0; i <= order; i++) {
05302 cpl_image *image = cpl_imagelist_get(*coeffs_cube, i);
05303 const double coeff = cpl_image_get_median(image);
05304 char * name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
05305 char * name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
05306 pcoeffs[i] = coeff;
05307 assert(name_o1 != NULL);
05308 assert(name_o2 != NULL);
05309 skip_if(cpl_propertylist_append_double(qclist, name_o1, coeff));
05310 skip_if(cpl_propertylist_set_comment(qclist,name_o1,
05311 DETMON_QC_LIN_COEF_C));
05312 cpl_free(name_o1);
05313 name_o1= NULL;
05314 skip_if(cpl_propertylist_append_double(qclist, name_o2,
05315 cpl_image_get_stdev(image)));
05316 skip_if(cpl_propertylist_set_comment(qclist,name_o2,
05317 DETMON_QC_LIN_COEF_ERR_C));
05318 cpl_free(name_o2);
05319 name_o2= NULL;
05320 }
05321
05322 if(order == vsize - 1) {
05323 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
05324 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
05325 0.0));
05326 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05327 DETMON_QC_ERRFIT_C));
05328
05329
05330 } else {
05331 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
05332 cpl_image_get_median(fiterror)));
05333 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05334 DETMON_QC_ERRFIT_C));
05335
05336 }
05337 }
05338
05339 skip_if(irplib_detmon_lg_lineff(pcoeffs, qclist, ref_level, order));
05340
05341 if(mode & IRPLIB_LIN_PIX2PIX) {
05342 int nbpixs;
05343 *bpm = irplib_detmon_bpixs(*coeffs_cube, bpmbin, kappa, &nbpixs);
05344 skip_if(*bpm == NULL);
05345 skip_if(cpl_propertylist_append_int(qclist, DETMON_QC_NUM_BPM,
05346 nbpixs));
05347 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_NUM_BPM,
05348 DETMON_QC_NUM_BPM_C));
05349 }
05350
05351 end_skip;
05352
05353 cpl_vector_delete(diffdits);
05354 cpl_polynomial_delete(poly_linfit);
05355 cpl_imagelist_delete(lin_inputs);
05356 cpl_vector_delete(vcoeffs);
05357 cpl_image_delete(fiterror);
05358
05359 return lin_table;
05360
05361 }
05362
05363
05387
05388 static cpl_error_code
05389 irplib_detmon_lin_table_fill_row(cpl_table * lin_table, double c_dit,
05390 cpl_imagelist * linearity_inputs,
05391 const cpl_imagelist * ons,
05392 const cpl_imagelist * offs,
05393 int llx,
05394 int lly,
05395 int urx,
05396 int ury,
05397 const int pos,
05398 const int nskip,
05399 unsigned mode)
05400 {
05401 cpl_image * dif1=NULL;
05402 cpl_image * dif2=NULL;
05403 cpl_image * dif_avg=NULL;
05404
05405 double med_dit=0;
05406 double mean_dit=0;
05407 cpl_error_code error;
05408 cpl_image * extracted=NULL;
05409 int offsize=0;
05410
05411 cpl_ensure_code(lin_table != NULL, CPL_ERROR_NULL_INPUT);
05412 cpl_ensure_code(ons != NULL, CPL_ERROR_NULL_INPUT);
05413 cpl_ensure_code(offs != NULL, CPL_ERROR_NULL_INPUT);
05414
05415 if (mode & IRPLIB_LIN_PIX2PIX) {
05416 cpl_msg_debug(cpl_func,"checking linearity inputs");
05417 cpl_ensure_code(linearity_inputs != NULL, CPL_ERROR_NULL_INPUT);
05418 }
05419
05420
05421 if (mode & IRPLIB_LIN_NIR) {
05422 cpl_table_set(lin_table, "DIT", pos, c_dit);
05423 } else if (mode & IRPLIB_LIN_OPT) {
05424 cpl_table_set(lin_table, "EXPTIME", pos, c_dit);
05425 } else {
05426 cpl_msg_error(cpl_func, "Mandatory mode not given");
05427 }
05428
05429
05430 offsize = cpl_imagelist_get_size(offs);
05431
05432
05433 dif1 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
05434 cpl_imagelist_get_const(offs, 0));
05435
05436 if (mode & IRPLIB_LIN_NO_COLLAPSE && offsize > 1)
05437 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
05438 cpl_imagelist_get_const(offs, 1));
05439 else
05440 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
05441 cpl_imagelist_get_const(offs, 0));
05442
05443 dif_avg = cpl_image_average_create(dif1, dif2);
05444
05445 cpl_image_abs(dif_avg);
05446 extracted = cpl_image_extract(dif_avg, llx, lly, urx, ury);
05447
05448 cpl_ensure_code(extracted != NULL, cpl_error_get_code());
05449
05450 cpl_table_set(lin_table, "MED", pos, cpl_image_get_median(extracted));
05451 cpl_table_set(lin_table, "MEAN", pos, cpl_image_get_mean(extracted));
05452 med_dit = cpl_image_get_median(extracted) / c_dit;
05453 mean_dit = cpl_image_get_mean(extracted) / c_dit;
05454
05455 cpl_table_set(lin_table, "MED_DIT", pos, med_dit);
05456 cpl_table_set(lin_table, "MEAN_DIT", pos, mean_dit);
05457
05458 cpl_image_delete(dif1);
05459 cpl_image_delete(dif2);
05460
05461
05462 if(mode & IRPLIB_LIN_PIX2PIX) {
05463 error = cpl_imagelist_set(linearity_inputs, extracted, pos-nskip);
05464 cpl_ensure_code(!error, error);
05465 } else {
05466 cpl_image_delete(extracted);
05467 }
05468
05469
05470 cpl_image_delete(dif_avg);
05471
05472 return cpl_error_get_code();
05473 }