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
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #ifdef HAVE_CONFIG_H
00147 #include <config.h>
00148 #endif
00149
00150
00151
00152
00153
00154 #include <complex.h>
00155
00156
00157 #include <math.h>
00158 #include <string.h>
00159 #include <assert.h>
00160
00161 #include <cpl.h>
00162 #include <cpl_fft.h>
00163 #include "irplib_detmon.h"
00164 #include "irplib_detmon_lg.h"
00165 #include "irplib_detmon_lg_impl.h"
00166
00167 #include "irplib_utils.h"
00168 #include "irplib_hist.h"
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 enum _FPN_METHOD
00182 {
00183 FPN_UNKNOWN,
00184 FPN_HISTOGRAM,
00185 FPN_SMOOTH,
00186 };
00187 typedef enum _FPN_METHOD FPN_METHOD;
00188 static struct
00189 {
00190 const char * method;
00191
00192 int order;
00193 double kappa;
00194 int niter;
00195 int threshold_min;
00196 int threshold_max;
00197 int llx;
00198 int lly;
00199 int urx;
00200 int ury;
00201 int ref_level;
00202 int threshold;
00203 int m;
00204 int n;
00205 int llx1;
00206 int lly1;
00207 int urx1;
00208 int ury1;
00209 int llx2;
00210 int lly2;
00211 int urx2;
00212 int ury2;
00213 int llx3;
00214 int lly3;
00215 int urx3;
00216 int ury3;
00217 int llx4;
00218 int lly4;
00219 int urx4;
00220 int ury4;
00221 int llx5;
00222 int lly5;
00223 int urx5;
00224 int ury5;
00225 int nx;
00226 int ny;
00227 cpl_boolean wholechip;
00228 cpl_boolean autocorr;
00229 cpl_boolean intermediate;
00230 cpl_boolean collapse;
00231 cpl_boolean rescale;
00232 cpl_boolean pix2pix;
00233 cpl_boolean bpmbin;
00234 int filter;
00235 double tolerance;
00236 const char * pafname;
00237
00238 double cr;
00239 int exts;
00240 int nb_extensions;
00241 double lamp_stability;
00242 cpl_boolean lamp_ok;
00243
00244 int (* load_fset) (
00245 const cpl_frameset *, cpl_type, cpl_imagelist *
00246 );
00247 cpl_imagelist * (* load_fset_wrp) (
00248 const cpl_frameset *, cpl_type, int
00249 );
00250 FPN_METHOD fpn_method;
00251 int fpn_smooth;
00252 double saturation_limit;
00253 } detmon_lg_config;
00254
00255
00256
00257
00258
00259
00260
00261
00262 static cpl_error_code
00263 irplib_detmon_lg_retrieve_parlist(const char *,
00264 const char *, const cpl_parameterlist *,
00265 cpl_boolean);
00266
00267
00268 static cpl_error_code
00269 irplib_detmon_lg_split_onoff(const cpl_frameset *,
00270 cpl_frameset *,
00271 cpl_frameset *,
00272 const char *, const char * );
00273
00274 static cpl_error_code
00275 irplib_detmon_lg_reduce(const cpl_frameset *,
00276 const cpl_frameset *,
00277
00278
00279 int* index_on, int* index_off, double* exptime_on, double* exptime_off,
00280 int *next_index_on, int* next_index_off,
00281 cpl_imagelist **,
00282 cpl_table *,
00283 cpl_table *,
00284 cpl_image **,
00285 cpl_imagelist *,
00286 cpl_imagelist *,
00287 cpl_propertylist *,
00288 cpl_propertylist *,
00289 cpl_propertylist *,
00290 cpl_propertylist *,
00291 int (* load_fset) (const cpl_frameset *,
00292 cpl_type,
00293 cpl_imagelist *),
00294 const cpl_boolean, int);
00295
00296 static cpl_error_code
00297 irplib_detmon_lin_table_fill_row(cpl_table *, double,
00298 cpl_imagelist *,
00299 const cpl_imagelist *,
00300 const cpl_imagelist *,
00301 int, int, int, int,
00302 const int,
00303 const int,
00304 unsigned);
00305
00306 static cpl_error_code
00307 irplib_detmon_gain_table_fill_row(cpl_table * gain_table,
00308 double c_dit,int c_ndit,
00309 cpl_imagelist * autocorr_images,
00310 cpl_imagelist * diff_flats,
00311 const cpl_imagelist * ons,
00312 const cpl_imagelist * offs,
00313 double kappa, int nclip,
00314 int llx, int lly, int urx, int ury,
00315 int m, int n,
00316 double saturation_limit,
00317 const int pos, unsigned mode, int* rows_affected);
00318
00319 static cpl_error_code
00320 irplib_detmon_lg_save(const cpl_parameterlist *,
00321 cpl_frameset *,
00322 const char *,
00323 const char *,
00324 const char *,
00325 const cpl_propertylist *,
00326 const cpl_propertylist *,
00327 const cpl_propertylist *,
00328 const cpl_propertylist *,
00329 const cpl_propertylist *,
00330 const cpl_propertylist *,
00331 const char *,
00332 cpl_imagelist *,
00333 cpl_table *,
00334 cpl_table *,
00335 cpl_image *,
00336 cpl_imagelist *,
00337 cpl_imagelist *,
00338 cpl_propertylist *,
00339 cpl_propertylist *,
00340 cpl_propertylist *,
00341 cpl_propertylist *,
00342 const int, const int, const cpl_frameset *,
00343 int);
00344
00345 static cpl_error_code
00346 irplib_detmon_lg_qc_ptc(const cpl_table *,
00347 cpl_propertylist *, unsigned, int);
00348
00349 static cpl_error_code
00350 irplib_detmon_lg_qc_med(const cpl_table *,
00351 cpl_propertylist *, int);
00352
00353
00354 static double
00355 irplib_pfits_get_dit(const cpl_propertylist *);
00356
00357 static double
00358 irplib_pfits_get_dit_opt(const cpl_propertylist *);
00359 static double
00360 irplib_pfits_get_prop_double(const cpl_propertylist * plist, const char* prop_name);
00361
00362 static cpl_image *irplib_detmon_bpixs(const cpl_imagelist *, cpl_boolean, const double, int *);
00363
00364 static double
00365 irplib_detmon_autocorr_factor(const cpl_image *,
00366 cpl_image **, int, int);
00367
00368
00369
00370 static cpl_error_code
00371 irplib_detmon_opt_contamination(const cpl_imagelist *,
00372 const cpl_imagelist *,
00373 unsigned mode, cpl_propertylist *);
00374
00375 #if 0
00376 irplib_detmon_opt_lampcr(cpl_frameset *, int);
00377 #endif
00378
00379 int
00380 irplib_detmon_lg_dfs_set_groups(cpl_frameset *, const char *, const char *);
00381
00382 static cpl_error_code
00383 irplib_detmon_lg_reduce_all(const cpl_table *,
00384 cpl_propertylist *,
00385 cpl_propertylist *
00386 , cpl_propertylist *,
00387 cpl_propertylist *,
00388 cpl_imagelist **,
00389 cpl_image **,
00390 const cpl_imagelist *,
00391 const cpl_table *, int, cpl_boolean);
00392
00393 static cpl_error_code
00394 irplib_detmon_lg_check_defaults(const cpl_image *);
00395
00396 static cpl_error_code
00397 irplib_detmon_lg_rescale(cpl_imagelist *);
00398
00399 static cpl_error_code
00400 irplib_detmon_lg_reduce_init(cpl_table *,
00401 cpl_table *,
00402 cpl_imagelist **,
00403 const cpl_boolean);
00404
00405
00406
00407 static cpl_error_code
00408 irplib_detmon_add_adl_column(cpl_table *, cpl_boolean);
00409
00410 static cpl_error_code
00411 irplib_detmon_lg_lamp_stab(const cpl_frameset *,
00412 const cpl_frameset *,
00413 cpl_boolean, int);
00414
00415
00416 static cpl_error_code
00417 irplib_detmon_lg_reduce_dit(const cpl_frameset * set_on,
00418 int* index_on, double* exptime_on,
00419 const int dit_nb,
00420 int * dit_nskip,
00421 const cpl_frameset * set_off,
00422 int * index_off, double* exptime_off,
00423 int* next_on, int* next_off,
00424 cpl_table * linear_table,
00425 cpl_table * gain_table,
00426 cpl_imagelist * linearity_inputs,
00427 cpl_propertylist * qclist,
00428 cpl_boolean opt_nir,
00429 cpl_imagelist * autocorr_images,
00430 cpl_imagelist * diff_flats,
00431 cpl_imagelist * opt_offs,
00432 int whichext,
00433 int * rows_affected);
00434
00435 static cpl_error_code
00436 irplib_detmon_lg_core(cpl_frameset * cur_fset_on,
00437 cpl_frameset * cur_fset_off,
00438 int * index_on,
00439 int * index_off,
00440 double * exptime_on,
00441 double * exptime_off,
00442 int whichext,
00443 int whichset,
00444 const char * recipe_name,
00445 const char * pipeline_name,
00446 const char * pafregexp,
00447 const cpl_propertylist * pro_lintbl,
00448 const cpl_propertylist * pro_gaintbl,
00449 const cpl_propertylist * pro_coeffscube,
00450 const cpl_propertylist * pro_bpm,
00451 const cpl_propertylist * pro_corr,
00452 const cpl_propertylist * pro_diff,
00453 const char * package,
00454 int (* load_fset) (const cpl_frameset *,
00455 cpl_type,
00456 cpl_imagelist *),
00457 int nsets, cpl_boolean opt_nir,
00458 cpl_frameset * frameset, const cpl_parameterlist * parlist,
00459 cpl_frameset * cur_fset);
00460
00461 static cpl_error_code
00462 irplib_detmon_lg_lineff(double *, cpl_propertylist *, int, int);
00463
00464
00465
00466
00467
00468
00469 static cpl_error_code
00470 irplib_detmon_gain_table_create(cpl_table *,
00471 const cpl_boolean);
00472
00473
00474 static cpl_error_code
00475 irplib_detmon_lin_table_create(cpl_table *,
00476 const cpl_boolean);
00477
00478 static cpl_vector *
00479 irplib_detmon_lg_find_dits(const cpl_vector *,
00480 double );
00481
00482 static cpl_error_code
00483 irplib_detmon_lg_find_dits_ndits(const cpl_vector * exptimes,
00484 const cpl_vector * vec_ndits,
00485 double tolerance,
00486 cpl_vector** diff_dits,
00487 cpl_vector** diff_ndits);
00488
00489 static cpl_error_code
00490 irplib_detmon_fpn_compute(const cpl_frameset *set_on,
00491 int * index_on,
00492 int last_best,
00493 cpl_propertylist *lint_qclist,
00494 int llx,
00495 int lly,
00496 int urx,
00497 int ury,
00498 double gain,
00499 int whichext,
00500 FPN_METHOD fpn_method,
00501 int smooth_size);
00502 static double irplib_fpn_lg(const cpl_image* f1, int* range, double gain,
00503 FPN_METHOD fpn_method, int, double* mse);
00504 static double irplib_calculate_total_noise(const cpl_image* pimage);
00505
00506 static cpl_imagelist* irplib_load_fset_wrp(const cpl_frameset *, cpl_type, int whichext);
00507 static cpl_imagelist * irplib_load_fset_wrp_ext(const cpl_frameset *, cpl_type, int);
00508
00509 static cpl_error_code irplib_table_create_column(cpl_table* ptable, cpl_propertylist* plist);
00510 static cpl_error_code irplib_fill_table_DETWINUIT(cpl_table* ptable, cpl_propertylist* plist, int row);
00511
00512 static cpl_error_code
00513 irplib_detmon_pair_extract_next(const cpl_frameset * set,
00514 int* index,
00515 int* next_element,
00516 double* dit_array,
00517
00518
00519 cpl_frameset ** pair,
00520 double tolerance);
00521 static cpl_error_code
00522 irplib_detmon_single_extract_next(const cpl_frameset * set,
00523 int* index,
00524 int* next_element,
00525 double* dit_array,
00526 cpl_frameset ** pair);
00527
00528
00529
00530
00531
00532
00533 static cpl_error_code irplib_detmon_table_fill_invalid(cpl_table* ptable, double code);
00534 static void irplib_detmon_lg_add_empty_image(cpl_imagelist* imlist, int pos);
00535
00542
00543 static int irplib_pfits_get_ndit(const cpl_propertylist * plist)
00544 {
00545 return cpl_propertylist_get_int(plist,"ESO DET NDIT");
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 static cpl_error_code irplib_detmon_lg_reduce_set(int i, cpl_frameset * frameset, int nsets,
00589 const char * tag_on,
00590 const char * tag_off,
00591 const char * recipe_name,
00592 const char * pipeline_name,
00593 const char * pafregexp,
00594 const cpl_propertylist * pro_lintbl,
00595 const cpl_propertylist * pro_gaintbl,
00596 const cpl_propertylist * pro_coeffscube,
00597 const cpl_propertylist * pro_bpm,
00598 const cpl_propertylist * pro_corr,
00599 const cpl_propertylist * pro_diff,
00600 const char * package,
00601 int (* load_fset)
00602 (const cpl_frameset *, cpl_type, cpl_imagelist *),
00603 const cpl_boolean opt_nir,
00604 const cpl_parameterlist * parlist,
00605 int* selection
00606 );
00607 static double irplib_compute_err(double gain, double ron, double photon_noise);
00608
00609 static cpl_error_code irplib_detmon_lg_dfs_save_imagelist(
00610 cpl_frameset * frameset,
00611 const cpl_parameterlist * parlist,
00612 const cpl_frameset *usedframes,
00613 const cpl_imagelist *coeffs,
00614 const char *recipe_name,
00615 const cpl_propertylist *mypro_coeffscube,
00616 const char * package,
00617 const char * name_o);
00618
00619
00620 static cpl_error_code irplib_detmon_lg_reduce_set(int i, cpl_frameset * frameset, int nsets,
00621 const char * tag_on,
00622 const char * tag_off,
00623 const char * recipe_name,
00624 const char * pipeline_name,
00625 const char * pafregexp,
00626 const cpl_propertylist * pro_lintbl,
00627 const cpl_propertylist * pro_gaintbl,
00628 const cpl_propertylist * pro_coeffscube,
00629 const cpl_propertylist * pro_bpm,
00630 const cpl_propertylist * pro_corr,
00631 const cpl_propertylist * pro_diff,
00632 const char * package,
00633 int (* load_fset)
00634 (const cpl_frameset *, cpl_type, cpl_imagelist *),
00635 const cpl_boolean opt_nir,
00636 const cpl_parameterlist * parlist,
00637 int* selection
00638 )
00639 {
00640 int j;
00641 int nexts = detmon_lg_config.nb_extensions;
00642
00643 double* exptime_on = 0;
00644 double* exptime_off = 0;
00645 int* index_on = 0;
00646 int* index_off = 0;
00647 cpl_frameset * cur_fset = NULL;
00648 cpl_frameset* cur_fset_on = 0;
00649 cpl_frameset* cur_fset_off = 0;
00650
00651
00652
00653
00654 cur_fset =
00655 (nsets == 1) ?
00656 cpl_frameset_duplicate(frameset) : cpl_frameset_extract(frameset, selection, i);
00657
00658
00659 skip_if(cur_fset == NULL);
00660
00661
00662 cur_fset_on = cpl_frameset_new();
00663 cur_fset_off = cpl_frameset_new();
00664 cpl_msg_info(cpl_func, "Splitting into ON and OFF sub-framesets");
00665 skip_if (irplib_detmon_lg_split_onoff(cur_fset,
00666 cur_fset_on, cur_fset_off,
00667 tag_on, tag_off ));
00668 if (cpl_frameset_get_size(cur_fset_on) == 0)
00669 {
00670 cpl_msg_error(cpl_func, "No lamp frames in input");
00671 skip_if(1);
00672 }
00673
00674 if (cpl_frameset_get_size(cur_fset_off) == 0)
00675 {
00676 cpl_msg_error(cpl_func, "No dark / bias frames in input");
00677 skip_if(1);
00678 }
00679 cpl_msg_info(cpl_func, "found on-frames[%d] off-frames[%d]",cpl_frameset_get_size(cur_fset_on), cpl_frameset_get_size(cur_fset_off));
00680
00681
00682
00683
00684
00685
00686
00687 exptime_on = cpl_malloc(sizeof(double)*cpl_frameset_get_size(cur_fset_on));
00688 exptime_off = cpl_malloc(sizeof(double)*cpl_frameset_get_size(cur_fset_off));
00689
00690 index_on = cpl_malloc(sizeof(int)*cpl_frameset_get_size(cur_fset_on));
00691 index_off = cpl_malloc(sizeof(int)*cpl_frameset_get_size(cur_fset_off));
00692 irplib_frameset_sort(cur_fset_on, index_on, exptime_on);
00693 irplib_frameset_sort(cur_fset_off, index_off, exptime_off);
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 skip_if(irplib_detmon_check_order(exptime_on, cpl_frameset_get_size(cur_fset_on), detmon_lg_config.tolerance, detmon_lg_config.order));
00707
00708 if(detmon_lg_config.exts >= 0)
00709 {
00710
00711
00712
00713
00714
00715 #if 0
00716 if (detmon_lg_config.lamp_ok) {
00717 skip_if(irplib_detmon_opt_lampcr(cur_fset, 0));
00718 }
00719 #endif
00720 skip_if(irplib_detmon_lg_core(cur_fset_on, cur_fset_off,
00721 index_on,
00722 index_off,
00723 exptime_on,
00724 exptime_off,
00725 detmon_lg_config.exts,
00726 i,
00727 recipe_name, pipeline_name, pafregexp,
00728 pro_lintbl, pro_gaintbl, pro_coeffscube, pro_bpm, pro_corr, pro_diff,
00729 package, load_fset, nsets, opt_nir, frameset, parlist, cur_fset));
00730 } else {
00731 for(j = 1; j <= nexts; j++) {
00732
00733
00734
00735
00736
00737 #if 0
00738 if (detmon_lg_config.lamp_ok) {
00739 skip_if(irplib_detmon_opt_lampcr(cur_fset, j));
00740 }
00741 #endif
00742
00743 skip_if(irplib_detmon_lg_core(cur_fset_on, cur_fset_off,
00744 index_on,
00745 index_off,
00746 exptime_on,
00747 exptime_off,
00748 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));
00749 }
00750 }
00751 end_skip;
00752
00753 cpl_frameset_delete(cur_fset);
00754 cpl_frameset_delete(cur_fset_on);
00755 cpl_frameset_delete(cur_fset_off);
00756 cpl_free(index_on);
00757 cpl_free(index_off);
00758 cpl_free(exptime_on);
00759 cpl_free(exptime_off);
00760 return cpl_error_get_code();
00761 }
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836 cpl_error_code
00837 irplib_detmon_lg(cpl_frameset * frameset,
00838 const cpl_parameterlist * parlist,
00839 const char * tag_on,
00840 const char * tag_off,
00841 const char * recipe_name,
00842 const char * pipeline_name,
00843 const char * pafregexp,
00844 const cpl_propertylist * pro_lintbl,
00845 const cpl_propertylist * pro_gaintbl,
00846 const cpl_propertylist * pro_coeffscube,
00847 const cpl_propertylist * pro_bpm,
00848 const cpl_propertylist * pro_corr,
00849 const cpl_propertylist * pro_diff,
00850 const char * package,
00851 int (* compare) (const cpl_frame *,
00852 const cpl_frame *),
00853 int (* load_fset) (const cpl_frameset *,
00854 cpl_type,
00855 cpl_imagelist *),
00856 const cpl_boolean opt_nir)
00857 {
00858 int nsets;
00859 int * selection = NULL;
00860 int i;
00861 cpl_frame * first = NULL;
00862 cpl_image * reference = NULL;
00863
00864
00865
00866
00867
00868
00869
00870
00871 cpl_frameset * cur_fset = NULL;
00872 cpl_frameset * cur_fset_on = NULL;
00873 cpl_frameset * cur_fset_off = NULL;
00874
00875
00876 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
00877 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00878 cpl_ensure_code(tag_on != NULL, CPL_ERROR_NULL_INPUT);
00879 cpl_ensure_code(tag_off != NULL, CPL_ERROR_NULL_INPUT);
00880 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00881 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
00882 cpl_ensure_code(pro_lintbl != NULL, CPL_ERROR_NULL_INPUT);
00883 cpl_ensure_code(pro_gaintbl != NULL, CPL_ERROR_NULL_INPUT);
00884 cpl_ensure_code(pro_coeffscube != NULL, CPL_ERROR_NULL_INPUT);
00885 cpl_ensure_code(pro_bpm != NULL, CPL_ERROR_NULL_INPUT);
00886 cpl_ensure_code(pro_corr != NULL, CPL_ERROR_NULL_INPUT);
00887 cpl_ensure_code(pro_diff != NULL, CPL_ERROR_NULL_INPUT);
00888 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
00889
00890 cpl_msg_info(cpl_func,"frameset size [%d]", cpl_frameset_get_size(frameset));
00891
00892
00893 skip_if (irplib_detmon_lg_dfs_set_groups(frameset, tag_on, tag_off));
00894
00895
00896
00897
00898
00899
00900 skip_if (irplib_detmon_lg_retrieve_parlist(pipeline_name, recipe_name,
00901 parlist, opt_nir));
00902
00903
00904
00905
00906
00907
00908 first = cpl_frameset_get_first(frameset);
00909 irplib_ensure (first != NULL, CPL_ERROR_ILLEGAL_INPUT, "Empty data set!");
00910
00911 detmon_lg_config.load_fset = load_fset;
00912 detmon_lg_config.load_fset_wrp = load_fset ? irplib_load_fset_wrp_ext : irplib_load_fset_wrp;
00913
00914
00915 if (detmon_lg_config.exts < 0) {
00916 reference = cpl_image_load(cpl_frame_get_filename(first),
00917 CPL_TYPE_FLOAT, 0, 1);
00918 } else {
00919 if (load_fset != NULL) {
00920 cpl_frameset * new = cpl_frameset_new();
00921 cpl_imagelist * p = cpl_imagelist_new();
00922 cpl_frameset_insert(new, cpl_frame_duplicate(first));
00923 (*load_fset)(new, CPL_TYPE_FLOAT, p);
00924 reference = cpl_image_duplicate(cpl_imagelist_get(p, 0));
00925 cpl_imagelist_delete(p);
00926 cpl_frameset_delete(new);
00927 } else {
00928 cpl_msg_info(cpl_func,"name=%s",cpl_frame_get_filename(first));
00929 reference = cpl_image_load(cpl_frame_get_filename(first),
00930 CPL_TYPE_FLOAT, 0, detmon_lg_config.exts);
00931 }
00932 }
00933 skip_if (reference == NULL);
00934
00935 skip_if (irplib_detmon_lg_check_defaults(reference));
00936
00937
00938
00939
00940
00941
00942
00943
00944 if (compare == NULL) {
00945 nsets = 1;
00946 } else {
00947 cpl_msg_info(cpl_func, "Identifying different settings");
00948 selection = cpl_frameset_labelise(frameset, compare, &nsets);
00949 skip_if (selection == NULL);
00950 }
00951
00952
00953 detmon_lg_config.nb_extensions = 1;
00954 if (detmon_lg_config.exts < 0)
00955 {
00956 detmon_lg_config.nb_extensions = cpl_frame_get_nextensions(first);
00957 }
00958
00959 for(i = 0; i < nsets; i++)
00960 {
00961
00962 int fr_size = cpl_frameset_get_size(frameset);
00963 int fr_size_new = 0;
00964 cpl_msg_info(cpl_func, "Reduce data set nb %d out of %d",
00965 i + 1, nsets);
00966 skip_if(irplib_detmon_lg_reduce_set(i, frameset, nsets, tag_on, tag_off,
00967 recipe_name,
00968 pipeline_name,
00969 pafregexp,
00970 pro_lintbl,
00971 pro_gaintbl,
00972 pro_coeffscube,
00973 pro_bpm,
00974 pro_corr,
00975 pro_diff,
00976 package,
00977 load_fset,
00978 opt_nir,
00979 parlist,
00980 selection));
00981 fr_size_new = cpl_frameset_get_size(frameset);
00982
00983
00984
00985
00986
00987 if (fr_size_new > fr_size)
00988 {
00989 selection = cpl_realloc(selection, fr_size_new * sizeof(selection[0]));
00990 memset(selection + fr_size, -1, (fr_size_new - fr_size) * sizeof(selection[0]));
00991 }
00992 }
00993
00994 end_skip;
00995
00996 cpl_frameset_delete(cur_fset);
00997 cpl_frameset_delete(cur_fset_on);
00998 cpl_frameset_delete(cur_fset_off);
00999 cpl_free(selection);
01000 cpl_image_delete(reference);
01001
01002 return cpl_error_get_code();
01003 }
01004
01005
01036
01037
01038 static cpl_error_code
01039 irplib_detmon_lg_core(cpl_frameset * cur_fset_on,
01040 cpl_frameset * cur_fset_off,
01041 int * index_on,
01042 int * index_off,
01043 double * exptime_on,
01044 double * exptime_off,
01045 int whichext,
01046 int whichset,
01047 const char * recipe_name,
01048 const char * pipeline_name,
01049 const char * pafregexp,
01050 const cpl_propertylist * pro_lintbl,
01051 const cpl_propertylist * pro_gaintbl,
01052 const cpl_propertylist * pro_coeffscube,
01053 const cpl_propertylist * pro_bpm,
01054 const cpl_propertylist * pro_corr,
01055 const cpl_propertylist * pro_diff,
01056 const char * package,
01057 int (* load_fset) (const cpl_frameset *,
01058 cpl_type,
01059 cpl_imagelist *),
01060 int nsets, cpl_boolean opt_nir,
01061 cpl_frameset * frameset, const cpl_parameterlist * parlist,
01062 cpl_frameset * cur_fset)
01063 {
01064 cpl_table * gain_table = cpl_table_new(cpl_frameset_get_size(cur_fset_on)/2);
01065 cpl_table * linear_table = cpl_table_new(cpl_frameset_get_size(cur_fset_on)/2);
01066 cpl_imagelist * coeffs = NULL;
01067 cpl_image * bpm = NULL;
01068 cpl_imagelist * autocorr_images = NULL;
01069 cpl_imagelist * diff_flats = NULL;
01070 cpl_propertylist * gaint_qclist = NULL;
01071 cpl_propertylist * lint_qclist = NULL;
01072 cpl_propertylist * linc_qclist = NULL;
01073 cpl_propertylist * bpm_qclist = NULL;
01074
01075 int next_index_on = 0;
01076 int next_index_off = 0;
01077
01078
01079
01080 cpl_msg_info(cpl_func, "Reduce extension nb %d ",
01081 whichext);
01082
01083
01084
01085 if (detmon_lg_config.intermediate) {
01086 autocorr_images = cpl_imagelist_new();
01087 diff_flats = cpl_imagelist_new();
01088 }
01089
01090 gaint_qclist = cpl_propertylist_new();
01091 lint_qclist = cpl_propertylist_new();
01092 linc_qclist = cpl_propertylist_new();
01093 bpm_qclist = cpl_propertylist_new();
01094
01095
01096 cpl_msg_info(cpl_func, "Starting data reduction");
01097 skip_if(irplib_detmon_lg_reduce(cur_fset_on, cur_fset_off,
01098 index_on, index_off, exptime_on, exptime_off,
01099 &next_index_on, &next_index_off,
01100 &coeffs, gain_table,
01101 linear_table, &bpm, autocorr_images,
01102 diff_flats, gaint_qclist, lint_qclist,
01103 linc_qclist, bpm_qclist, load_fset,
01104 opt_nir, whichext));
01105
01106
01107 cpl_msg_info(cpl_func, "Saving the products");
01108 if(nsets == 1) {
01109 skip_if(irplib_detmon_lg_save(parlist, frameset, recipe_name,
01110 pipeline_name, pafregexp,
01111 pro_lintbl, pro_gaintbl,
01112 pro_coeffscube, pro_bpm,
01113 pro_corr, pro_diff, package,
01114 coeffs, gain_table, linear_table,
01115 bpm, autocorr_images, diff_flats,
01116 gaint_qclist, lint_qclist, linc_qclist,
01117 bpm_qclist, 0, 0, cur_fset, whichext));
01118 } else {
01119 skip_if(irplib_detmon_lg_save(parlist, frameset, recipe_name,
01120 pipeline_name, pafregexp,
01121 pro_lintbl, pro_gaintbl,
01122 pro_coeffscube, pro_bpm,
01123 pro_corr, pro_diff, package,
01124 coeffs, gain_table, linear_table,
01125 bpm, autocorr_images, diff_flats,
01126 gaint_qclist, lint_qclist, linc_qclist,
01127 bpm_qclist, 1, whichset+ 1, cur_fset,
01128 whichext));
01129 }
01130
01131 end_skip;
01132
01133
01134 cpl_table_delete(gain_table);
01135 cpl_table_delete(linear_table);
01136 cpl_imagelist_delete(coeffs);
01137 cpl_propertylist_delete(gaint_qclist);
01138 cpl_propertylist_delete(lint_qclist);
01139 cpl_propertylist_delete(linc_qclist);
01140 cpl_propertylist_delete(bpm_qclist);
01141 cpl_image_delete(bpm);
01142 cpl_imagelist_delete(autocorr_images);
01143 cpl_imagelist_delete(diff_flats);
01144
01145 return cpl_error_get_code();
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167 cpl_image *
01168 irplib_detmon_image_correlate(const cpl_image * image1,
01169 const cpl_image * image2,
01170 const int m, const int n)
01171 {
01172 cpl_image *image1_padded = NULL;
01173 cpl_image *image2_padded = NULL;
01174 int nx, ny;
01175 int nx2, ny2;
01176 int i,j;
01177
01178 cpl_image *corr_image = NULL;
01179 cpl_image *corr_image_window = NULL;
01180 cpl_image *reorganised= NULL;
01181 cpl_image *image= NULL;
01182
01183 cpl_image* image_ri_inv = NULL;
01184 cpl_image* image_in_inv = NULL;
01185 cpl_image* image_ri1 = NULL;
01186 cpl_image* image_ri2 = NULL;
01187 cpl_error_code err = CPL_ERROR_NONE;
01188
01189
01190 cpl_ensure(image1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
01191 cpl_ensure(image2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
01192
01193 cpl_ensure(m > 0, CPL_ERROR_NULL_INPUT, NULL);
01194 cpl_ensure(n > 0, CPL_ERROR_NULL_INPUT, NULL);
01195
01196 nx = cpl_image_get_size_x(image1);
01197 ny = cpl_image_get_size_y(image1);
01198
01199 nx2 = cpl_image_get_size_x(image2);
01200 ny2 = cpl_image_get_size_y(image2);
01201
01202
01203 cpl_ensure(nx == nx2 && ny == ny2, CPL_ERROR_ILLEGAL_INPUT, NULL);
01204
01205
01206 image1_padded = cpl_image_new(nx + 2 * m, ny + 2 * n, CPL_TYPE_FLOAT);
01207 cpl_image_copy(image1_padded, image1, m + 1, n + 1);
01208
01209 image2_padded = cpl_image_new(nx + 2 * m, ny + 2 * n, CPL_TYPE_FLOAT);
01210 cpl_image_copy(image2_padded, image2, m + 1, n + 1);
01211
01212
01213 nx = nx + 2 * m;
01214 ny = ny + 2 * n;
01215
01216 image_ri1 = cpl_image_new(nx, ny, CPL_TYPE_FLOAT_COMPLEX);
01217 image_ri2 = cpl_image_new(nx, ny , CPL_TYPE_FLOAT_COMPLEX);
01218
01219 cpl_fft_image(image_ri1, image1_padded, CPL_FFT_FORWARD);
01220 cpl_fft_image(image_ri2, image2_padded, CPL_FFT_FORWARD);
01221 err = cpl_error_get_code();
01222 cpl_image_delete(image1_padded);
01223 image1_padded = NULL;
01224 cpl_image_delete(image2_padded);
01225 image2_padded = NULL;
01226 if (err == CPL_ERROR_NONE)
01227 {
01228
01229 image_ri_inv = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
01230 image_in_inv = cpl_image_new(nx, ny, CPL_TYPE_FLOAT_COMPLEX);
01231
01232 for (i = 1; i <= nx; i++)
01233 {
01234 for (j = 1; j <= ny; j++)
01235 {
01236 int rej = 0;
01237 complex value1, value2, value;
01238 value1 = cpl_image_get_complex(image_ri1, i, j, &rej);
01239 value2 = cpl_image_get_complex(image_ri2, i, j, &rej);;
01240 value = conjf(value1) * value2;
01241 cpl_image_set_complex(image_in_inv, i, j, value);
01242 }
01243 }
01244 cpl_image_delete(image_ri1);
01245 image_ri1 = NULL;
01246 cpl_image_delete(image_ri2);
01247 image_ri2 = NULL;
01248
01249 err = cpl_error_get_code();
01250 if (err == CPL_ERROR_NONE)
01251 {
01252
01253
01254 cpl_fft_image(image_ri_inv, image_in_inv,CPL_FFT_BACKWARD);
01255 cpl_image_delete(image_in_inv);
01256
01257
01258 corr_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
01259 for (i = 1; i <= nx; i++)
01260 {
01261 for (j = 1; j <= ny; j++)
01262 {
01263 int rej = 0;
01264 double value =0;
01265 value = cpl_image_get(image_ri_inv, i, j, &rej);
01266 cpl_image_set(corr_image, i, j, value);
01267 }
01268 }
01269 cpl_image_delete(image_ri_inv);
01270 err = cpl_error_get_code();
01271 if (err == CPL_ERROR_NONE)
01272 {
01273
01274 reorganised = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
01275
01276 image = cpl_image_extract(corr_image, nx / 2 + 1, 1, nx, ny);
01277 cpl_image_copy(reorganised, image, 1, 1);
01278 cpl_image_delete(image);
01279 image = cpl_image_extract(corr_image, 1, 1, nx / 2, ny);
01280 cpl_image_copy(reorganised, image, nx / 2 + 1, 1);
01281 cpl_image_delete(image);
01282
01283 cpl_image_delete(corr_image);
01284
01285 corr_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
01286 image = cpl_image_extract(reorganised, 1, ny / 2 + 1, nx, ny);
01287 cpl_image_copy(corr_image, image, 1, 1);
01288 cpl_image_delete(image);
01289
01290 image = cpl_image_extract(reorganised, 1, 1, nx, ny / 2);
01291 cpl_image_copy(corr_image, image, 1, ny / 2 + 1);
01292 cpl_image_delete(image);
01293
01294 corr_image_window = cpl_image_extract(corr_image,
01295 nx / 2 + 1 - m,
01296 ny / 2 + 1 - n,
01297 nx / 2 + 1 + m, ny / 2 + 1 + n);
01298 }
01299
01300
01301 }
01302 cpl_image_delete(reorganised);
01303 cpl_image_delete(corr_image);
01304
01305 if(cpl_image_divide_scalar(corr_image_window,
01306 cpl_image_get_max(corr_image_window))) {
01307 cpl_image_delete(corr_image_window);
01308 return NULL;
01309 }
01310 }
01311 cpl_image_delete (image_ri1);
01312 cpl_image_delete (image_ri2);
01313 cpl_image_delete (image1_padded);
01314 cpl_image_delete (image2_padded);
01315 return corr_image_window;
01316 }
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337 cpl_image *
01338 irplib_detmon_autocorrelate(const cpl_image * input2, const int m,
01339 const int n)
01340 {
01341 cpl_image *im_re = NULL;
01342 cpl_image *im_im = NULL;
01343 int nx, ny;
01344 cpl_image *ifft_re = NULL;
01345 cpl_image *ifft_im = NULL;
01346 cpl_image *autocorr = NULL;
01347 cpl_image *autocorr_norm_double = NULL;
01348 cpl_image *autocorr_norm = NULL;
01349 cpl_image *reorganised = NULL;
01350 cpl_image *image = NULL;
01351 int p;
01352 cpl_error_code error;
01353 cpl_image *input;
01354
01355 cpl_ensure(input2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
01356
01357 cpl_ensure(m > 0, CPL_ERROR_NULL_INPUT, NULL);
01358 cpl_ensure(n > 0, CPL_ERROR_NULL_INPUT, NULL);
01359
01360 nx = cpl_image_get_size_x(input2) + 2 * m;
01361 ny = cpl_image_get_size_y(input2) + 2 * n;
01362
01363 p = 128;
01364 while(nx > p || ny > p) {
01365 p *= 2;
01366 }
01367
01368 input = cpl_image_cast(input2, CPL_TYPE_DOUBLE);
01369
01370 im_re = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01371 error = cpl_image_copy(im_re, input, 1, 1);
01372 cpl_ensure(!error, error, NULL);
01373
01374 im_im = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01375
01376 error = cpl_image_fft(im_re, im_im, CPL_FFT_DEFAULT);
01377 cpl_ensure(!error, error, NULL);
01378
01379 ifft_re = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01380 error = cpl_image_power(im_re, 2);
01381 cpl_ensure(!error, error, NULL);
01382
01383 error = cpl_image_add(ifft_re, im_re);
01384 cpl_ensure(!error, error, NULL);
01385
01386 cpl_image_delete(im_re);
01387
01388 error = cpl_image_power(im_im, 2);
01389 cpl_ensure(!error, error, NULL);
01390
01391 error = cpl_image_add(ifft_re, im_im);
01392 cpl_ensure(!error, error, NULL);
01393
01394 cpl_image_delete(im_im);
01395
01396 ifft_im = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01397
01398 error = cpl_image_fft(ifft_re, ifft_im, CPL_FFT_INVERSE);
01399 cpl_ensure(!error, error, NULL);
01400
01401 autocorr = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01402
01403 error = cpl_image_power(ifft_re, 2);
01404 cpl_ensure(!error, error, NULL);
01405
01406 error = cpl_image_add(autocorr, ifft_re);
01407 cpl_ensure(!error, error, NULL);
01408
01409 cpl_image_delete(ifft_re);
01410
01411 error = cpl_image_power(ifft_im, 2);
01412 cpl_ensure(!error, error, NULL);
01413
01414 error = cpl_image_add(autocorr, ifft_im);
01415 cpl_ensure(!error, error, NULL);
01416
01417 cpl_image_delete(ifft_im);
01418
01419
01420 reorganised = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01421
01422 image = cpl_image_extract(autocorr, p / 2 + 1, 1, p, p);
01423 cpl_image_copy(reorganised, image, 1, 1);
01424 cpl_image_delete(image);
01425
01426 image = cpl_image_extract(autocorr, 1, 1, p / 2, p);
01427 cpl_image_copy(reorganised, image, p / 2 + 1, 1);
01428 cpl_image_delete(image);
01429
01430 cpl_image_delete(autocorr);
01431
01432 autocorr = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01433
01434 image = cpl_image_extract(reorganised, 1, p / 2 + 1, p, p);
01435 cpl_image_copy(autocorr, image, 1, 1);
01436 cpl_image_delete(image);
01437
01438 image = cpl_image_extract(reorganised, 1, 1, p, p / 2);
01439 cpl_image_copy(autocorr, image, 1, p / 2 + 1);
01440 cpl_image_delete(image);
01441
01442 cpl_image_delete(reorganised);
01443
01444 autocorr_norm_double =
01445 cpl_image_extract(autocorr, p / 2 + 1 - m, p / 2 + 1 - n,
01446 p / 2 + 1 + m, p / 2 + 1 + n);
01447
01448 cpl_image_delete(autocorr);
01449
01450 if(cpl_image_divide_scalar(autocorr_norm_double,
01451 cpl_image_get_max(autocorr_norm_double))) {
01452 cpl_image_delete(autocorr_norm_double);
01453 cpl_ensure(0, cpl_error_get_code(), NULL);
01454 }
01455
01456
01457 autocorr_norm = cpl_image_cast(autocorr_norm_double, CPL_TYPE_FLOAT);
01458 cpl_image_delete(autocorr_norm_double);
01459
01460 cpl_image_delete(input);
01461
01462 return autocorr_norm;
01463 }
01464
01465
01476
01477 cpl_error_code
01478 irplib_detmon_lg_fill_parlist_nir_default(cpl_parameterlist * parlist,
01479 const char *recipe_name,
01480 const char *pipeline_name)
01481 {
01482 const cpl_error_code error =
01483 irplib_detmon_lg_fill_parlist(parlist, recipe_name, pipeline_name,
01484 "PTC",
01485 3,
01486 3.,
01487 5,
01488 -1,
01489 -1,
01490 -1,
01491 -1,
01492 10000,
01493 "CPL_FALSE",
01494 "CPL_FALSE",
01495 "CPL_FALSE",
01496 "CPL_TRUE",
01497 "CPL_TRUE",
01498 "CPL_FALSE",
01499 -1,
01500 26,
01501 26,
01502 1e-3,
01503 recipe_name,
01504 -1,
01505 -1,
01506 -1,
01507 -1,
01508 -1,
01509 -1,
01510 -1,
01511 -1,
01512 -1,
01513 -1,
01514 -1,
01515 -1,
01516 -1,
01517 -1,
01518 -1,
01519 -1,
01520 -1,
01521 -1,
01522 -1,
01523 -1,
01524 0,
01525 NIR);
01526
01527
01528 cpl_ensure_code(!error, error);
01529
01530 return cpl_error_get_code();
01531 }
01532
01533
01544
01545 cpl_error_code
01546 irplib_detmon_lg_fill_parlist_opt_default(cpl_parameterlist * parlist,
01547 const char *recipe_name,
01548 const char *pipeline_name)
01549 {
01550 const cpl_error_code error =
01551 irplib_detmon_lg_fill_parlist(parlist, recipe_name, pipeline_name,
01552 "PTC",
01553 3,
01554 3.,
01555 5,
01556 -1,
01557 -1,
01558 -1,
01559 -1,
01560 10000,
01561 "CPL_FALSE",
01562 "CPL_FALSE",
01563 "CPL_TRUE",
01564 "CPL_TRUE",
01565 "CPL_FALSE",
01566 "CPL_FALSE",
01567 -1,
01568 26,
01569 26,
01570 1e-3,
01571 recipe_name,
01572 -1,
01573 -1,
01574 -1,
01575 -1,
01576 -1,
01577 -1,
01578 -1,
01579 -1,
01580 -1,
01581 -1,
01582 -1,
01583 -1,
01584 -1,
01585 -1,
01586 -1,
01587 -1,
01588 -1,
01589 -1,
01590 -1,
01591 -1,
01592 0,
01593 OPT);
01594
01595 cpl_ensure_code(!error, error);
01596
01597 return cpl_error_get_code();
01598 }
01599
01600
01654
01655 cpl_error_code
01656 irplib_detmon_lg_fill_parlist(cpl_parameterlist * parlist,
01657 const char *recipe_name, const char *pipeline_name,
01658 const char *method,
01659 int order,
01660 double kappa,
01661 int niter,
01662 int llx,
01663 int lly,
01664 int urx,
01665 int ury,
01666 int ref_level,
01667 const char *intermediate,
01668 const char *autocorr,
01669 const char *collapse,
01670 const char *rescale,
01671 const char *pix2pix,
01672 const char *bpmbin,
01673 int filter,
01674 int m,
01675 int n,
01676 double tolerance,
01677 const char * pafname,
01678 int llx1,
01679 int lly1,
01680 int urx1,
01681 int ury1,
01682 int llx2,
01683 int lly2,
01684 int urx2,
01685 int ury2,
01686 int llx3,
01687 int lly3,
01688 int urx3,
01689 int ury3,
01690 int llx4,
01691 int lly4,
01692 int urx4,
01693 int ury4,
01694 int llx5, int lly5, int urx5, int ury5, int exts,
01695 cpl_boolean opt_nir)
01696 {
01697 const cpl_error_code error =
01698 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 24,
01699 "method",
01700 "Method to be used when computing GAIN. Methods appliable: <PTC | MED>. By default PTC method will be applied.",
01701 "CPL_TYPE_STRING", method,
01702
01703 "order",
01704 "Polynomial order for the fit (Linearity)",
01705 "CPL_TYPE_INT", order,
01706 "kappa",
01707 "Kappa value for the kappa-sigma clipping (Gain)",
01708 "CPL_TYPE_DOUBLE", kappa,
01709 "niter",
01710 "Number of iterations to compute rms (Gain)",
01711 "CPL_TYPE_INT", niter,
01712 "llx",
01713 "x coordinate of the lower-left "
01714 "point of the region of interest. If not modified, default value will be 1.",
01715 "CPL_TYPE_INT", llx,
01716 "lly",
01717 "y coordinate of the lower-left "
01718 "point of the region of interest. If not modified, default value will be 1.",
01719 "CPL_TYPE_INT", lly,
01720 "urx",
01721 "x coordinate of the upper-right "
01722 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
01723 "CPL_TYPE_INT", urx,
01724 "ury",
01725 "y coordinate of the upper-right "
01726 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
01727 "CPL_TYPE_INT", ury,
01728 "ref_level",
01729 "User reference level",
01730 "CPL_TYPE_INT", ref_level,
01731 "intermediate",
01732 "De-/Activate intermediate products",
01733 "CPL_TYPE_BOOL", intermediate,
01734 "autocorr",
01735 "De-/Activate the autocorr option",
01736 "CPL_TYPE_BOOL", autocorr,
01737 "collapse",
01738 "De-/Activate the collapse option",
01739 "CPL_TYPE_BOOL", collapse,
01740 "rescale",
01741 "De-/Activate the image rescale option",
01742 "CPL_TYPE_BOOL", rescale,
01743 "pix2pix",
01744 "De-/Activate the computation with pixel to pixel accuracy",
01745 "CPL_TYPE_BOOL", pix2pix,
01746 "bpmbin",
01747 "De-/Activate the binary bpm option",
01748 "CPL_TYPE_BOOL", bpmbin,
01749 "m",
01750 "Maximum x-shift for the autocorr",
01751 "CPL_TYPE_INT", m,
01752 "filter",
01753 "Upper limit of Median flux to be filtered",
01754 "CPL_TYPE_INT", filter,
01755 "n",
01756 "Maximum y-shift for the autocorr",
01757 "CPL_TYPE_INT", n,
01758 "tolerance",
01759 "Tolerance for pair discrimination",
01760 "CPL_TYPE_DOUBLE", tolerance,
01761 "pafname",
01762 "Specific name for PAF file",
01763 "CPL_TYPE_STRING", pafname,
01764
01765 "exts",
01766 "Activate the multi-exts option",
01767 "CPL_TYPE_INT", exts,
01768
01769 "fpn_method",
01770 "Method for computing Fixed Pattern Noise (SMOOTH or HISTOGRAM)",
01771 "CPL_TYPE_STRING", "HISTOGRAM",
01772
01773 "fpn_smooth",
01774 "template size in pixels for smoothing during FPN computation (only for SMOOTH method)",
01775 "CPL_TYPE_INT", 13,
01776
01777 "saturation_limit",
01778 "all frames with mean saturation above the limit would not be used in calculation",
01779 "CPL_TYPE_DOUBLE", 65535.0
01780 );
01781
01782
01783 if(opt_nir == FALSE) {
01784 const cpl_error_code erroropt =
01785 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 20,
01786 "llx1",
01787 "x coord of the lower-left point of the first "
01788 "field used for contamination measurement. If not modified, default value will be 1.",
01789 "CPL_TYPE_INT", llx1,
01790 "lly1",
01791 "y coord of the lower-left point of the first "
01792 "field used for contamination measurement. If not modified, default value will be 1.",
01793 "CPL_TYPE_INT", lly1,
01794 "urx1",
01795 "x coord of the upper-right point of the first "
01796 "field used for contamination measurement. If not modified, default value will be X dimension of the input image.",
01797 "CPL_TYPE_INT", urx1,
01798 "ury1",
01799 "y coord of the upper-right point of the first "
01800 "field used for contamination measurement. If not modified, default value will be Y dimension of the input image.",
01801 "CPL_TYPE_INT", ury1,
01802 "llx2",
01803 "x coord of the lower-left point of the second "
01804 "field used for contamination measurement. If not modified, default value will be 1.",
01805 "CPL_TYPE_INT", llx2,
01806 "lly2",
01807 "y coord of the lower-left point of the second "
01808 "field used for contamination measurement. If not modified, default value will be 1.",
01809 "CPL_TYPE_INT", lly2,
01810 "urx2",
01811 "x coord of the upper-right point of the second "
01812 "field used for contamination measurement. If not modified, default value will be half of the X dimension of the input image.",
01813 "CPL_TYPE_INT", urx2,
01814 "ury2",
01815 "y coord of the upper-right point of the second "
01816 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01817 "CPL_TYPE_INT", ury2,
01818 "llx3",
01819 "x coord of the lower-left point of the third "
01820 "field used for contamination measurement. If not modified, default value will be 1.",
01821 "CPL_TYPE_INT", llx3,
01822 "lly3",
01823 "y coord of the lower-left point of the third "
01824 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01825 "CPL_TYPE_INT", lly3,
01826 "urx3",
01827 "x coord of the upper-right point of the third "
01828 "field used for contamination measurement. If not modified, default value will be half of X dimension of the image.",
01829 "CPL_TYPE_INT", urx3,
01830 "ury3",
01831 "y coord of the upper-right point of the third "
01832 "field used for contamination measurement. If not modified, default value will be Y dimension of the image.",
01833 "CPL_TYPE_INT", ury3,
01834 "llx4",
01835 "x coord of the lower-left point of the fourth "
01836 "field used for contamination measurement. If not modified, default value will be half of X dimension of the image.",
01837 "CPL_TYPE_INT", llx4,
01838 "lly4",
01839 "y coord of the lower-left point of the fourth "
01840 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01841 "CPL_TYPE_INT", lly4,
01842 "urx4",
01843 "x coord of the upper-right point of the fourth "
01844 "field used for contamination measurement. If not modified, default value will be X dimension of the image.",
01845 "CPL_TYPE_INT", urx4,
01846 "ury4",
01847 "y coord of the upper-right point of the fourth "
01848 "field used for contamination measurement. If not modified, default value will be Y dimension of the input image.",
01849 "CPL_TYPE_INT", ury4,
01850 "llx5",
01851 "x coord of the lower-left point of the fifth "
01852 "field used for contamination measurement. If not modified, default value will be half of the X dimension of the input image.",
01853 "CPL_TYPE_INT", llx5,
01854 "lly5",
01855 "y coord of the lower-left point of the fifth "
01856 "field used for contamination measurement. If not modified, default value will be 1.",
01857 "CPL_TYPE_INT", lly5,
01858 "urx5",
01859 "x coord of the upper-right point of the fifth "
01860 "field used for contamination measurement. If not modified, default value will be X dimension of the image.",
01861 "CPL_TYPE_INT", urx5,
01862
01863 "ury5",
01864 "y coord of the upper-right point of the fifth "
01865 "field used for contamination measurement. If not modified, default value will be half of Y dimension of the input image.",
01866 "CPL_TYPE_INT", ury5);
01867 cpl_ensure_code(!erroropt, erroropt);
01868 }
01869
01870 cpl_ensure_code(!error, error);
01871
01872 return cpl_error_get_code();
01873 }
01874
01875
01884
01885 static cpl_error_code
01886 irplib_detmon_lg_retrieve_parlist(const char * pipeline_name,
01887 const char * recipe_name,
01888 const cpl_parameterlist * parlist,
01889 cpl_boolean opt_nir)
01890 {
01891
01892 char * par_name;
01893 cpl_parameter * par;
01894
01895
01896 par_name = cpl_sprintf("%s.%s.method", pipeline_name, recipe_name);
01897 assert(par_name != NULL);
01898 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01899 detmon_lg_config.method = cpl_parameter_get_string(par);
01900 cpl_free(par_name);
01901
01902
01903 detmon_lg_config.order =
01904 irplib_detmon_retrieve_par_int("order", pipeline_name, recipe_name,
01905 parlist);
01906
01907
01908 detmon_lg_config.kappa =
01909 irplib_detmon_retrieve_par_double("kappa", pipeline_name, recipe_name,
01910 parlist);
01911
01912
01913 detmon_lg_config.niter =
01914 irplib_detmon_retrieve_par_int("niter", pipeline_name, recipe_name,
01915 parlist);
01916
01917
01918 detmon_lg_config.llx =
01919 irplib_detmon_retrieve_par_int("llx", pipeline_name, recipe_name,
01920 parlist);
01921
01922
01923 detmon_lg_config.lly =
01924 irplib_detmon_retrieve_par_int("lly", pipeline_name, recipe_name,
01925 parlist);
01926
01927
01928 detmon_lg_config.urx =
01929 irplib_detmon_retrieve_par_int("urx", pipeline_name, recipe_name,
01930 parlist);
01931
01932
01933 detmon_lg_config.ury =
01934 irplib_detmon_retrieve_par_int("ury", pipeline_name, recipe_name,
01935 parlist);
01936
01937
01938 detmon_lg_config.ref_level =
01939 irplib_detmon_retrieve_par_int("ref_level", pipeline_name, recipe_name,
01940 parlist);
01941
01942
01943 par_name =
01944 cpl_sprintf("%s.%s.intermediate", pipeline_name, recipe_name);
01945 assert(par_name != NULL);
01946 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01947 detmon_lg_config.intermediate = cpl_parameter_get_bool(par);
01948 cpl_free(par_name);
01949
01950
01951 par_name = cpl_sprintf("%s.%s.autocorr", pipeline_name, recipe_name);
01952 assert(par_name != NULL);
01953 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01954 detmon_lg_config.autocorr = cpl_parameter_get_bool(par);
01955 cpl_free(par_name);
01956
01957
01958 par_name = cpl_sprintf("%s.%s.collapse", pipeline_name, recipe_name);
01959 assert(par_name != NULL);
01960 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01961 detmon_lg_config.collapse = cpl_parameter_get_bool(par);
01962 cpl_free(par_name);
01963
01964
01965 par_name = cpl_sprintf("%s.%s.rescale", pipeline_name, recipe_name);
01966 assert(par_name != NULL);
01967 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01968 detmon_lg_config.rescale = cpl_parameter_get_bool(par);
01969 cpl_free(par_name);
01970
01971
01972 par_name = cpl_sprintf("%s.%s.pix2pix", pipeline_name, recipe_name);
01973 assert(par_name != NULL);
01974 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01975 detmon_lg_config.pix2pix = cpl_parameter_get_bool(par);
01976 cpl_free(par_name);
01977
01978
01979 par_name = cpl_sprintf("%s.%s.bpmbin", pipeline_name, recipe_name);
01980 assert(par_name != NULL);
01981 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01982 detmon_lg_config.bpmbin = cpl_parameter_get_bool(par);
01983 cpl_free(par_name);
01984
01985
01986 detmon_lg_config.filter =
01987 irplib_detmon_retrieve_par_int("filter", pipeline_name,
01988 recipe_name, parlist);
01989
01990
01991 detmon_lg_config.m =
01992 irplib_detmon_retrieve_par_int("m", pipeline_name, recipe_name, parlist);
01993
01994
01995 detmon_lg_config.n =
01996 irplib_detmon_retrieve_par_int("n", pipeline_name, recipe_name, parlist);
01997
01998
01999 par_name = cpl_sprintf("%s.%s.tolerance", pipeline_name, recipe_name);
02000 assert(par_name != NULL);
02001 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
02002 detmon_lg_config.tolerance = cpl_parameter_get_double(par);
02003 cpl_free(par_name);
02004
02005
02006 par_name = cpl_sprintf("%s.%s.pafname", pipeline_name, recipe_name);
02007 assert(par_name != NULL);
02008 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
02009 detmon_lg_config.pafname = cpl_parameter_get_string(par);
02010 cpl_free(par_name);
02011
02012 if(opt_nir == OPT) {
02013
02014 detmon_lg_config.llx1 =
02015 irplib_detmon_retrieve_par_int("llx1", pipeline_name, recipe_name,
02016 parlist);
02017
02018
02019 detmon_lg_config.lly1 =
02020 irplib_detmon_retrieve_par_int("lly1", pipeline_name, recipe_name,
02021 parlist);
02022
02023
02024 detmon_lg_config.urx1 =
02025 irplib_detmon_retrieve_par_int("urx1", pipeline_name, recipe_name,
02026 parlist);
02027
02028
02029 detmon_lg_config.ury1 =
02030 irplib_detmon_retrieve_par_int("ury1", pipeline_name, recipe_name,
02031 parlist);
02032
02033
02034 detmon_lg_config.llx2 =
02035 irplib_detmon_retrieve_par_int("llx2", pipeline_name, recipe_name,
02036 parlist);
02037
02038
02039 detmon_lg_config.lly2 =
02040 irplib_detmon_retrieve_par_int("lly2", pipeline_name, recipe_name,
02041 parlist);
02042
02043
02044 detmon_lg_config.urx2 =
02045 irplib_detmon_retrieve_par_int("urx2", pipeline_name, recipe_name,
02046 parlist);
02047
02048
02049 detmon_lg_config.ury2 =
02050 irplib_detmon_retrieve_par_int("ury2", pipeline_name, recipe_name,
02051 parlist);
02052
02053
02054 detmon_lg_config.llx3 =
02055 irplib_detmon_retrieve_par_int("llx3", pipeline_name, recipe_name,
02056 parlist);
02057
02058
02059 detmon_lg_config.lly3 =
02060 irplib_detmon_retrieve_par_int("lly3", pipeline_name, recipe_name,
02061 parlist);
02062
02063
02064 detmon_lg_config.urx3 =
02065 irplib_detmon_retrieve_par_int("urx3", pipeline_name, recipe_name,
02066 parlist);
02067
02068
02069 detmon_lg_config.ury3 =
02070 irplib_detmon_retrieve_par_int("ury3", pipeline_name, recipe_name,
02071 parlist);
02072
02073
02074 detmon_lg_config.llx4 =
02075 irplib_detmon_retrieve_par_int("llx4", pipeline_name, recipe_name,
02076 parlist);
02077
02078
02079 detmon_lg_config.lly4 =
02080 irplib_detmon_retrieve_par_int("lly4", pipeline_name, recipe_name,
02081 parlist);
02082
02083
02084 detmon_lg_config.urx4 =
02085 irplib_detmon_retrieve_par_int("urx4", pipeline_name, recipe_name,
02086 parlist);
02087
02088
02089 detmon_lg_config.ury4 =
02090 irplib_detmon_retrieve_par_int("ury4", pipeline_name, recipe_name,
02091 parlist);
02092
02093
02094 detmon_lg_config.llx5 =
02095 irplib_detmon_retrieve_par_int("llx5", pipeline_name, recipe_name,
02096 parlist);
02097
02098
02099 detmon_lg_config.lly5 =
02100 irplib_detmon_retrieve_par_int("lly5", pipeline_name, recipe_name,
02101 parlist);
02102
02103
02104 detmon_lg_config.urx5 =
02105 irplib_detmon_retrieve_par_int("urx5", pipeline_name, recipe_name,
02106 parlist);
02107
02108
02109 detmon_lg_config.ury5 =
02110 irplib_detmon_retrieve_par_int("ury5", pipeline_name, recipe_name,
02111 parlist);
02112 }
02113
02114
02115 detmon_lg_config.exts =
02116 irplib_detmon_retrieve_par_int("exts", pipeline_name, recipe_name,
02117 parlist);
02118
02119 {
02120 const char* str_method = 0;
02121 detmon_lg_config.fpn_method = FPN_HISTOGRAM;
02122 par_name =
02123 cpl_sprintf("%s.%s.fpn_method", pipeline_name, recipe_name);
02124 assert(par_name != NULL);
02125 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
02126 if (par)
02127 {
02128 str_method = cpl_parameter_get_string(par);
02129 if (strcmp(str_method, "SMOOTH") == 0)
02130 {
02131 detmon_lg_config.fpn_method = FPN_SMOOTH;
02132 }
02133 else if (strcmp(str_method, "HISTOGRAM") == 0)
02134 {
02135 detmon_lg_config.fpn_method = FPN_HISTOGRAM;
02136 }
02137 }
02138 cpl_free(par_name);
02139 }
02140
02141 detmon_lg_config.fpn_smooth =
02142 irplib_detmon_retrieve_par_int("fpn_smooth", pipeline_name, recipe_name,
02143 parlist);
02144
02145 {
02146 detmon_lg_config.saturation_limit = 65535;
02147 par_name =
02148 cpl_sprintf("%s.%s.saturation_limit", pipeline_name, recipe_name);
02149 assert(par_name != NULL);
02150 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
02151 if (par)
02152 {
02153 detmon_lg_config.saturation_limit = cpl_parameter_get_double(par);
02154 }
02155 cpl_free(par_name);
02156 }
02157 if(cpl_error_get_code())
02158 {
02159 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
02160 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
02161 }
02162
02163
02164 return cpl_error_get_code();
02165 }
02166
02167
02173
02174 static cpl_error_code
02175 irplib_detmon_lg_check_defaults(const cpl_image * reference)
02176 {
02177 const int nx = cpl_image_get_size_x(reference);
02178 const int ny = cpl_image_get_size_y(reference);
02179
02180 detmon_lg_config.nx = nx;
02181 detmon_lg_config.ny = ny;
02182
02183 detmon_lg_config.wholechip = CPL_FALSE;
02184
02185 if(detmon_lg_config.llx == -1)
02186 detmon_lg_config.llx = 1;
02187 if(detmon_lg_config.lly == -1)
02188 detmon_lg_config.lly = 1;
02189 if(detmon_lg_config.urx == -1)
02190 detmon_lg_config.urx = nx;
02191 if(detmon_lg_config.ury == -1)
02192 detmon_lg_config.ury = ny;
02193
02194 if (detmon_lg_config.llx == 1 &&
02195 detmon_lg_config.lly == 1 &&
02196 detmon_lg_config.urx == nx &&
02197 detmon_lg_config.ury == ny)
02198 detmon_lg_config.wholechip = CPL_TRUE;
02199
02200 if(detmon_lg_config.llx1 == -1)
02201 detmon_lg_config.llx1 = 1;
02202 if(detmon_lg_config.lly1 == -1)
02203 detmon_lg_config.lly1 = 1;
02204 if(detmon_lg_config.urx1 == -1)
02205 detmon_lg_config.urx1 = nx;
02206 if(detmon_lg_config.ury1 == -1)
02207 detmon_lg_config.ury1 = ny;
02208
02209 if(detmon_lg_config.llx2 == -1)
02210 detmon_lg_config.llx2 = 1;
02211 if(detmon_lg_config.lly2 == -1)
02212 detmon_lg_config.lly2 = 1;
02213 if(detmon_lg_config.urx2 == -1)
02214 detmon_lg_config.urx2 = nx / 2;
02215 if(detmon_lg_config.ury2 == -1)
02216 detmon_lg_config.ury2 = ny / 2;
02217
02218 if(detmon_lg_config.llx3 == -1)
02219 detmon_lg_config.llx3 = 1;
02220 if(detmon_lg_config.lly3 == -1)
02221 detmon_lg_config.lly3 = ny / 2;
02222 if(detmon_lg_config.urx3 == -1)
02223 detmon_lg_config.urx3 = nx / 2;
02224 if(detmon_lg_config.ury3 == -1)
02225 detmon_lg_config.ury3 = ny;
02226
02227 if(detmon_lg_config.llx4 == -1)
02228 detmon_lg_config.llx4 = nx / 2;
02229 if(detmon_lg_config.lly4 == -1)
02230 detmon_lg_config.lly4 = ny / 2;
02231 if(detmon_lg_config.urx4 == -1)
02232 detmon_lg_config.urx4 = nx;
02233 if(detmon_lg_config.ury4 == -1)
02234 detmon_lg_config.ury4 = ny;
02235
02236 if(detmon_lg_config.llx5 == -1)
02237 detmon_lg_config.llx5 = nx / 2;
02238 if(detmon_lg_config.lly5 == -1)
02239 detmon_lg_config.lly5 = 1;
02240 if(detmon_lg_config.urx5 == -1)
02241 detmon_lg_config.urx5 = nx;
02242 if(detmon_lg_config.ury5 == -1)
02243 detmon_lg_config.ury5 = ny / 2;
02244
02245 if(detmon_lg_config.intermediate == TRUE) {
02246 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.");
02247 detmon_lg_config.autocorr = TRUE;
02248 }
02249
02250
02251 detmon_lg_config.lamp_stability = 0.0;
02252
02253 detmon_lg_config.lamp_ok = FALSE;
02254
02255 detmon_lg_config.cr = 0.0;
02256
02257 return cpl_error_get_code();
02258 }
02259
02260
02271
02272 static cpl_error_code
02273 irplib_detmon_lg_split_onoff(const cpl_frameset * cur_fset,
02274 cpl_frameset * cur_fset_on,
02275 cpl_frameset * cur_fset_off,
02276 const char *tag_on,
02277 const char *tag_off)
02278 {
02279 int nframes;
02280 int i;
02281
02282 const cpl_frame * first;
02283 const cpl_frame * second;
02284
02285 const char * first_tag;
02286 const char * second_tag;
02287
02288 cpl_frame * cur_frame_dup = NULL;
02289
02290 skip_if((first = cpl_frameset_get_first_const(cur_fset)) == NULL);
02291 skip_if((second = cpl_frameset_get_next_const (cur_fset)) == NULL);
02292
02293 skip_if((first_tag = cpl_frame_get_tag(first)) == NULL);
02294 skip_if((second_tag = cpl_frame_get_tag(second)) == NULL);
02295
02296 #if 0
02297 if (opt_nir == OPT &&
02298 ((!strcmp(first_tag, tag_on ) && !strcmp(second_tag, tag_off)) ||
02299 (!strcmp(first_tag, tag_off) && !strcmp(second_tag, tag_on )))) {
02300 detmon_lg_config.lamp_ok = TRUE;
02301 }
02302 #endif
02303
02304 nframes = cpl_frameset_get_size(cur_fset);
02305 for(i = detmon_lg_config.lamp_ok ? 2 : 0; i < nframes; i++) {
02306 const cpl_frame * cur_frame =
02307 cpl_frameset_get_frame_const(cur_fset, i);
02308 char * tag;
02309
02310
02311 cur_frame_dup = cpl_frame_duplicate(cur_frame);
02312 tag = (char *) cpl_frame_get_tag(cur_frame_dup);
02313
02314
02315 if(!strcmp(tag, tag_on)) {
02316 skip_if(cpl_frameset_insert(cur_fset_on, cur_frame_dup));
02317 } else if(!strcmp(tag, tag_off)) {
02318 skip_if(cpl_frameset_insert(cur_fset_off, cur_frame_dup));
02319 } else {
02320 cpl_frame_delete(cur_frame_dup);
02321 cur_frame_dup = NULL;
02322 }
02323 }
02324 cur_frame_dup = NULL;
02325
02326 end_skip;
02327
02328 cpl_frame_delete(cur_frame_dup);
02329
02330 return cpl_error_get_code();
02331 }
02332
02333
02355
02356
02357 static cpl_error_code
02358 irplib_detmon_lg_reduce(const cpl_frameset * set_on,
02359 const cpl_frameset * set_off,
02360 int* index_on, int* index_off, double* exptime_on, double* exptime_off,
02361 int *next_index_on, int* next_index_off,
02362 cpl_imagelist ** coeffs_ptr,
02363 cpl_table * gain_table,
02364 cpl_table * linear_table,
02365 cpl_image ** bpm_ptr,
02366 cpl_imagelist * autocorr_images,
02367 cpl_imagelist * diff_flats,
02368 cpl_propertylist * gaint_qclist,
02369 cpl_propertylist * lint_qclist,
02370 cpl_propertylist * linc_qclist,
02371 cpl_propertylist * bpm_qclist,
02372 int (* load_fset) (const cpl_frameset *,
02373 cpl_type,
02374 cpl_imagelist *),
02375 const cpl_boolean opt_nir,
02376 int whichext)
02377 {
02378 const double D_INVALID_VALUE = -999;
02379 int i;
02380 cpl_imagelist * linearity_inputs = NULL;
02381 cpl_imagelist * opt_offs = NULL;
02382 int nsets;
02383 cpl_propertylist * reflist = NULL;
02384 int dit_nskip=0;
02385 int rows_affected = 1;
02386 int last_best = 0;
02387
02388 cpl_ensure(set_on != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
02389 cpl_ensure(set_off != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
02390
02391 nsets = cpl_frameset_get_size(set_on) / 2;
02392
02393 detmon_lg_config.load_fset = load_fset;
02394
02395 if(detmon_lg_config.collapse) {
02396
02397
02398
02399
02400
02401
02402 const cpl_frame *first = cpl_frameset_get_first_const(set_off);
02403 cpl_frame *dup_first = cpl_frame_duplicate(first);
02404
02405 const cpl_frame *second = cpl_frameset_get_next_const(set_off);
02406 cpl_frame *dup_second = cpl_frame_duplicate(second);
02407
02408 cpl_frameset *raw_offs = cpl_frameset_new();
02409
02410 cpl_frameset_insert(raw_offs, dup_first);
02411 cpl_frameset_insert(raw_offs, dup_second);
02412
02413 opt_offs = cpl_imagelist_load_frameset(raw_offs, CPL_TYPE_FLOAT,
02414 0, whichext);
02415
02416 cpl_frameset_delete(raw_offs);
02417
02418 }
02419
02420 skip_if(irplib_detmon_lg_reduce_init(gain_table,
02421 linear_table,
02422 &linearity_inputs,
02423 opt_nir));
02424
02425 if (!strcmp(detmon_lg_config.method, "PTC"))
02426 {
02427 cpl_msg_warning(cpl_func, "PTC method incompatible with lamp stability computation");
02428 }
02429 else if(!detmon_lg_config.collapse)
02430 {
02431 skip_if(irplib_detmon_lg_lamp_stab(set_on, set_off,
02432 opt_nir, whichext));
02433 }
02434
02435 skip_if(cpl_table_unselect_all(linear_table));
02436 skip_if(cpl_table_unselect_all(gain_table));
02437
02438
02439
02440
02441
02442
02443
02444 for(i = 0; i < nsets ; i++)
02445 {
02446 skip_if(irplib_detmon_lg_reduce_dit(set_on,
02447 index_on, exptime_on,
02448 i,
02449 &dit_nskip,
02450 set_off,
02451 index_off, exptime_off,
02452 next_index_on, next_index_off,
02453 linear_table,
02454 gain_table, linearity_inputs,
02455 lint_qclist, opt_nir,
02456 autocorr_images, diff_flats,
02457 opt_offs, whichext,
02458 &rows_affected));
02459 if (rows_affected == 0)
02460 {
02461 cpl_msg_warning(cpl_func, "The rest frames would not be taken into calculation, check the messages above");
02462 cpl_table_select_row(linear_table, i);
02463 }
02464 else
02465 {
02466 last_best = i;
02467 }
02468 }
02469
02470 skip_if(irplib_detmon_add_adl_column(linear_table, opt_nir));
02471
02472
02473
02474
02475
02476 skip_if(cpl_table_erase_selected(gain_table));
02477 skip_if(cpl_table_erase_selected(linear_table));
02478
02479 reflist = cpl_propertylist_new();
02480 skip_if(cpl_propertylist_append_bool(reflist, "ADU", FALSE));
02481 skip_if(cpl_table_sort(gain_table, reflist));
02482
02483
02484
02485
02486
02487
02488 skip_if(irplib_detmon_lg_reduce_all(linear_table,
02489 gaint_qclist, lint_qclist, linc_qclist,
02490 bpm_qclist, coeffs_ptr, bpm_ptr,
02491 linearity_inputs,
02492 gain_table, whichext, opt_nir));
02493
02494 {
02495
02496 double gain = cpl_propertylist_get_double(gaint_qclist, DETMON_QC_GAIN);
02497 cpl_error_code cplerr = cpl_error_get_code();
02498 if (cplerr != CPL_ERROR_NONE)
02499 {
02500 cpl_msg_warning(cpl_func, "Cannot read gain from QC parameters - FPN would not be computed");
02501 cpl_error_reset();
02502 }
02503 else
02504 {
02505 irplib_detmon_fpn_compute(set_on, index_on, last_best, lint_qclist,
02506 detmon_lg_config.llx,
02507 detmon_lg_config.lly,
02508 detmon_lg_config.urx,
02509 detmon_lg_config.ury,
02510 gain,
02511 whichext,
02512 detmon_lg_config.fpn_method,
02513 detmon_lg_config.fpn_smooth);
02514 }
02515 }
02516
02517 irplib_detmon_table_fill_invalid(gain_table, D_INVALID_VALUE);
02518 end_skip;
02519
02520 cpl_imagelist_delete(linearity_inputs);
02521 cpl_imagelist_delete(opt_offs);
02522 cpl_propertylist_delete(reflist);
02523
02524 return cpl_error_get_code();
02525 }
02526
02527 static cpl_error_code irplib_detmon_table_fill_invalid(cpl_table* ptable, double code)
02528 {
02529 int ncols = cpl_table_get_ncol(ptable);
02530 cpl_array* pnames = cpl_table_get_column_names(ptable);
02531 int nrows = cpl_table_get_nrow(ptable);
02532 int i = 0;
02533 for (i=0; i < ncols; i++)
02534 {
02535 int j = 0;
02536 for (j = 0; j< nrows; j++)
02537 {
02538 const char* colname = cpl_array_get_data_string_const(pnames)[i];
02539 int isnull;
02540 cpl_type type = cpl_table_get_column_type(ptable, colname);
02541 cpl_table_get(ptable, colname, j, &isnull);
02542 if(isnull == 1)
02543 {
02544 if (type == CPL_TYPE_DOUBLE)
02545 {
02546 cpl_table_set(ptable,colname,j, code);
02547 }
02548 else if (type == CPL_TYPE_FLOAT)
02549 {
02550 cpl_table_set_float(ptable,colname,j, (float)code);
02551 }
02552 }
02553 }
02554 }
02555 cpl_array_delete(pnames);
02556 return cpl_error_get_code();
02557 }
02558
02559 static cpl_error_code
02560 irplib_detmon_fpn_compute(const cpl_frameset *set_on,
02561 int * index_on,
02562 int last_best,
02563 cpl_propertylist *lint_qclist,
02564 int llx,
02565 int lly,
02566 int urx,
02567 int ury,
02568 double gain,
02569 int whichext,
02570 FPN_METHOD fpn_method,
02571 int smooth_size)
02572 {
02573 double fpn = 0;
02574 const cpl_image* im1 = 0;
02575 int range[4];
02576 cpl_imagelist* ons = 0;
02577 cpl_frameset * pair_on = 0;
02578 int nsets_extracted = cpl_frameset_get_size(set_on);
02579 int * selection = 0;
02580 double mse = 0;
02581 range[0] = llx;
02582 range[1] = lly;
02583 range[2] = urx;
02584 range[3] = ury;
02585
02586
02587
02588 selection = cpl_malloc(sizeof(int) * nsets_extracted);
02589 memset(&selection[0], 0, sizeof(int) * nsets_extracted);
02590
02591 selection[index_on[last_best*2 + 0] ] = 1;
02592 selection[index_on[last_best*2 + 1] ] = 1;
02593 pair_on = cpl_frameset_extract(set_on, selection, 1);
02594 ons = detmon_lg_config.load_fset_wrp(pair_on, CPL_TYPE_FLOAT, whichext);
02595
02596 skip_if(ons == NULL);
02597 skip_if((im1 = cpl_imagelist_get_const(ons, 0)) == NULL);
02598
02599 fpn = irplib_fpn_lg(im1, range, gain, fpn_method, smooth_size, &mse);
02600 skip_if(cpl_propertylist_append_double(lint_qclist, DETMON_QC_FPN,
02601 fpn));
02602 skip_if(cpl_propertylist_append_double(lint_qclist, "ESO QC GAIN ERR",
02603 mse));
02604
02605 cleanup:
02606 cpl_frameset_delete(pair_on);
02607 cpl_imagelist_delete(ons);
02608 cpl_free(selection);
02609 return cpl_error_get_code();
02610 }
02611
02612
02620
02621 static cpl_error_code
02622 irplib_detmon_lg_lamp_stab(const cpl_frameset * lamps,
02623 const cpl_frameset * darks,
02624 cpl_boolean opt_nir,
02625 int whichext)
02626 {
02627
02628
02629
02630
02631
02632
02633 int nb_lamps;
02634
02635 cpl_vector * selection = NULL;
02636 cpl_propertylist * plist;
02637 double dit_lamp, dit_dark;
02638 int dit_stab;
02639 cpl_imagelist * lamps_data = NULL;
02640 cpl_imagelist * darks_data = NULL;
02641 double * stab_levels = NULL;
02642 int i, j;
02643 double * ditvals = NULL;
02644 int last_stab = 0;
02645
02646
02647 cpl_ensure_code((nb_lamps = cpl_frameset_get_size(lamps)) >= 3,
02648 CPL_ERROR_ILLEGAL_INPUT);
02649 cpl_ensure_code(cpl_frameset_get_size(darks) == nb_lamps,
02650 CPL_ERROR_ILLEGAL_INPUT);
02651
02652
02653 cpl_msg_info(__func__, "Checking DIT consistency");
02654 selection = cpl_vector_new(nb_lamps);
02655 ditvals = cpl_malloc(nb_lamps * sizeof(double));
02656 dit_stab = 0;
02657 for (i = 0; i < nb_lamps; i++) {
02658 const cpl_frame * c_lamp;
02659 const cpl_frame * c_dark;
02660
02661 skip_if (cpl_error_get_code());
02662
02663
02664 c_lamp = cpl_frameset_get_frame_const(lamps, i);
02665 plist = cpl_propertylist_load(cpl_frame_get_filename(c_lamp), 0);
02666 if(opt_nir)
02667 dit_lamp = (double)irplib_pfits_get_dit(plist);
02668 else
02669 dit_lamp = (double)irplib_pfits_get_dit_opt(plist);
02670 cpl_propertylist_delete(plist);
02671 skip_if (cpl_error_get_code());
02672
02673
02674 c_dark = cpl_frameset_get_frame_const(darks, i);
02675 plist = cpl_propertylist_load(cpl_frame_get_filename(c_dark), 0);
02676 if(opt_nir)
02677 dit_dark = (double)irplib_pfits_get_dit(plist);
02678 else
02679 dit_dark = (double)irplib_pfits_get_dit_opt(plist);
02680 cpl_propertylist_delete(plist);
02681 skip_if (cpl_error_get_code());
02682
02683
02684 if (fabs(dit_dark-dit_lamp) > 1e-3) {
02685 cpl_msg_error(__func__, "DIT not consistent between LAMP and DARK");
02686
02687 skip_if(1);
02688 }
02689 ditvals[i] = dit_lamp;
02690
02691 if (i==0) {
02692 cpl_vector_set(selection, i, -1.0);
02693 dit_stab ++;
02694 last_stab = 0;
02695 } else {
02696
02697
02698
02699
02700 if (fabs(dit_lamp - ditvals[0]) < 1e-5 && i - last_stab > 3) {
02701 cpl_vector_set(selection, i, -1.0);
02702 dit_stab ++;
02703 last_stab = i;
02704 } else {
02705 cpl_vector_set(selection, i, 1.0);
02706 }
02707 }
02708 }
02709
02710
02711 if (dit_stab < 2) {
02712 cpl_msg_info(__func__, "Not enough frames for stability check");
02713 } else {
02714
02715
02716 cpl_msg_info(__func__, "Compute the differences lamp - dark");
02717 lamps_data = cpl_imagelist_load_frameset(lamps, CPL_TYPE_FLOAT, 1,
02718 whichext);
02719 darks_data = cpl_imagelist_load_frameset(darks, CPL_TYPE_FLOAT, 1,
02720 whichext);
02721 skip_if(cpl_imagelist_subtract(lamps_data,darks_data));
02722
02723
02724 cpl_msg_info(__func__, "Check the lamp stability");
02725 stab_levels = cpl_malloc(dit_stab * sizeof(double));
02726 j = 0;
02727 for (i=0; i<nb_lamps; i++) {
02728 if (cpl_vector_get(selection, i) < 0) {
02729 stab_levels[j] =
02730 cpl_image_get_mean(cpl_imagelist_get(lamps_data, i));
02731 j++;
02732 }
02733 }
02734
02735
02736 for (i=1; i<dit_stab; i++) {
02737 if ((fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0]) >
02738 detmon_lg_config.lamp_stability)
02739 detmon_lg_config.lamp_stability =
02740 fabs(stab_levels[i]-stab_levels[0]) / stab_levels[0];
02741 }
02742
02743
02744
02745 if (detmon_lg_config.lamp_stability > 0.01) {
02746 cpl_msg_warning(__func__,
02747 "level difference too high - proceed anyway");
02748 }
02749 }
02750 end_skip;
02751
02752 cpl_free(ditvals);
02753 cpl_vector_delete(selection);
02754 cpl_imagelist_delete(lamps_data);
02755 cpl_imagelist_delete(darks_data);
02756 cpl_free(stab_levels);
02757
02758 return cpl_error_get_code();
02759 }
02760
02761
02784
02785 static cpl_error_code
02786 irplib_detmon_lg_reduce_dit(const cpl_frameset * set_on,
02787 int* index_on, double* exptime_on,
02788 const int dit_nb,
02789 int * dit_nskip,
02790 const cpl_frameset * set_off,
02791 int * index_off, double* exptime_off,
02792 int* next_on, int* next_off,
02793 cpl_table * linear_table,
02794 cpl_table * gain_table,
02795 cpl_imagelist * linearity_inputs,
02796 cpl_propertylist * qclist,
02797 cpl_boolean opt_nir,
02798 cpl_imagelist * autocorr_images,
02799 cpl_imagelist * diff_flats,
02800 cpl_imagelist * opt_offs,
02801 int whichext,
02802 int* rows_affected)
02803 {
02804 cpl_frameset * pair_on = NULL;
02805 cpl_frameset * pair_off = NULL;
02806 cpl_imagelist * ons = NULL;
02807 cpl_imagelist * offs = NULL;
02808 cpl_boolean follow = CPL_TRUE;
02809 cpl_imagelist * masterl = NULL;
02810 unsigned mode = detmon_lg_config.autocorr ? IRPLIB_GAIN_WITH_AUTOCORR : 0;
02811 double c_dit;
02812 int c_ndit;
02813
02814 double current_dit = 0;
02815
02816 const char * filename;
02817
02818 cpl_propertylist * plist = NULL;
02819 cpl_propertylist* pDETlist = NULL;
02820
02821 mode = detmon_lg_config.collapse ?
02822 mode | IRPLIB_GAIN_COLLAPSE | IRPLIB_LIN_COLLAPSE:
02823 mode | IRPLIB_GAIN_NO_COLLAPSE | IRPLIB_LIN_NO_COLLAPSE;
02824 mode = detmon_lg_config.pix2pix ?
02825 mode | IRPLIB_LIN_PIX2PIX : mode;
02826 mode = opt_nir ?
02827 mode | IRPLIB_GAIN_NIR | IRPLIB_LIN_NIR :
02828 mode | IRPLIB_GAIN_OPT | IRPLIB_LIN_OPT ;
02829
02830
02831
02832 skip_if(irplib_detmon_pair_extract_next(set_on, index_on, next_on, exptime_on, &pair_on, detmon_lg_config.tolerance));
02833 current_dit = exptime_on[*next_on - 1];
02834
02835
02836 ons = detmon_lg_config.load_fset_wrp(pair_on, CPL_TYPE_FLOAT, whichext);
02837 skip_if(ons == NULL);
02838 cpl_msg_debug(cpl_func, "Loaded ON images: %d, exptime[%f]",cpl_imagelist_get_size(ons), current_dit );
02839 if(cpl_imagelist_get_size(ons) != 2)
02840 {
02841 cpl_msg_error(cpl_func, "cannot take ON pair, number of images[%d]", cpl_imagelist_get_size(ons));
02842 skip_if(TRUE);
02843 }
02844 if(detmon_lg_config.filter > 0)
02845 {
02846 double med1 =
02847 cpl_image_get_median_window(cpl_imagelist_get(ons, 0),
02848 detmon_lg_config.llx,
02849 detmon_lg_config.lly,
02850 detmon_lg_config.urx,
02851 detmon_lg_config.ury);
02852 double med2 =
02853 cpl_image_get_median_window(cpl_imagelist_get(ons, 1),
02854 detmon_lg_config.llx,
02855 detmon_lg_config.lly,
02856 detmon_lg_config.urx,
02857 detmon_lg_config.ury);
02858 if ( med1 > (double)detmon_lg_config.filter ||
02859 med2 > (double)detmon_lg_config.filter)
02860 {
02861 follow = CPL_FALSE;
02862 cpl_table_select_row(gain_table, dit_nb);
02863 cpl_table_select_row(linear_table, dit_nb);
02864 (*dit_nskip)++;
02865 cpl_msg_warning(cpl_func, "Frames of EXPTIME nb %d "
02866 "will not be taken into account for computation "
02867 "as they are above --filter threshold", dit_nb);
02868 }
02869 }
02870
02871 if (follow || detmon_lg_config.filter < 0)
02872 {
02873
02874
02875
02876
02877
02878
02879 if(!detmon_lg_config.collapse)
02880 {
02881 if (!strcmp(detmon_lg_config.method, "MED") ||
02882 cpl_frameset_get_size(set_on) == cpl_frameset_get_size(set_off))
02883 {
02884 skip_if(irplib_detmon_pair_extract_next(set_off, index_off, next_off, exptime_off, &pair_off, detmon_lg_config.tolerance));
02885 }
02886 else
02887 {
02888 skip_if(irplib_detmon_single_extract_next(set_off, index_off, next_off, exptime_off, &pair_off));
02889 }
02890
02891 cpl_msg_debug(cpl_func, "Load the OFF images, ext[%d], exptime[%f]", whichext, exptime_off[*next_off - 1]);
02892 offs = detmon_lg_config.load_fset_wrp(pair_off, CPL_TYPE_FLOAT, whichext);
02893
02894 skip_if(offs == NULL);
02895 skip_if(cpl_error_get_code());
02896 } else
02897 {
02898
02899
02900
02901
02902 cpl_image * collapse;
02903 masterl = cpl_imagelist_load_frameset(set_off, CPL_TYPE_FLOAT,
02904 1, whichext);
02905 skip_if(masterl == NULL);
02906 skip_if(cpl_error_get_code());
02907
02908 collapse = cpl_imagelist_collapse_create(masterl);
02909 skip_if(collapse == NULL);
02910 skip_if(cpl_imagelist_set(masterl, collapse, 0));
02911
02912
02913 offs = (cpl_imagelist *)masterl;
02914 }
02915
02916
02917 if(detmon_lg_config.rescale)
02918 {
02919 skip_if(irplib_detmon_lg_rescale(ons));
02920 if (!detmon_lg_config.collapse &&
02921 !strcmp(detmon_lg_config.method, "MED"))
02922 skip_if(irplib_detmon_lg_rescale(offs));
02923 }
02924
02925
02926 filename =
02927 cpl_frame_get_filename(cpl_frameset_get_first_const(pair_on));
02928 skip_if ((plist = cpl_propertylist_load(filename, 0)) == NULL);
02929
02930 if (plist)
02931 {
02932 pDETlist = cpl_propertylist_new();
02933 cpl_propertylist_copy_property_regexp(pDETlist, plist, "DET[0-9]* WIN[0-9]* UIT[0-9]*",0);
02934 if (dit_nb == 0)
02935 {
02936 irplib_table_create_column(gain_table, pDETlist);
02937 irplib_table_create_column(linear_table, pDETlist);
02938 }
02939 }
02940 if(opt_nir == NIR) {
02941 c_dit = irplib_pfits_get_dit(plist);
02942 c_ndit = irplib_pfits_get_ndit(plist);
02943 } else {
02944 c_dit = irplib_pfits_get_exptime(plist);
02945 c_ndit=1;
02946 }
02947
02948
02949
02950
02951
02952
02953
02954
02955 if(detmon_lg_config.collapse) {
02956 offs = (cpl_imagelist *) opt_offs;
02957 }
02958
02959 cpl_msg_info(cpl_func, "Computing GAIN for EXPTIME value nb %d",
02960 dit_nb + 1);
02961
02962
02963 if(cpl_imagelist_get_size(offs) == 1 && mode & IRPLIB_GAIN_NO_COLLAPSE && dit_nb == 0)
02964 {
02965 cpl_table_erase_column(gain_table, "MEAN_OFF1");
02966 cpl_table_erase_column(gain_table, "MEAN_OFF2");
02967 cpl_table_erase_column(gain_table, "SIG_OFF_DIF");
02968 cpl_table_erase_column(gain_table, "GAIN");
02969 cpl_table_erase_column(gain_table, "GAIN_CORR");
02970 cpl_table_new_column(gain_table, "MEAN_OFF", CPL_TYPE_DOUBLE);
02971 }
02972
02973 skip_if(irplib_detmon_gain_table_fill_row(gain_table,
02974 c_dit,c_ndit,
02975 autocorr_images,
02976 diff_flats, ons, offs,
02977 detmon_lg_config.kappa,
02978 detmon_lg_config.niter,
02979 detmon_lg_config.llx,
02980 detmon_lg_config.lly,
02981 detmon_lg_config.urx,
02982 detmon_lg_config.ury,
02983 detmon_lg_config.m,
02984 detmon_lg_config.n,
02985 detmon_lg_config.saturation_limit,
02986 dit_nb, mode, rows_affected));
02987
02988
02989 if (*rows_affected)
02990 {
02991
02992 skip_if(irplib_fill_table_DETWINUIT(gain_table, pDETlist, dit_nb));
02993
02994 cpl_msg_info(cpl_func, "Linearity reduction for nb %d",
02995 dit_nb + 1);
02996 skip_if(irplib_detmon_lin_table_fill_row(linear_table, c_dit,
02997 linearity_inputs, ons, offs,
02998 detmon_lg_config.llx,
02999 detmon_lg_config.lly,
03000 detmon_lg_config.urx,
03001 detmon_lg_config.ury,
03002 dit_nb, *dit_nskip, mode));
03003
03004 skip_if(irplib_fill_table_DETWINUIT(linear_table, pDETlist, dit_nb));
03005 }
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016 if(opt_nir == OPT &&
03017 *rows_affected != 0 ) {
03018 irplib_detmon_opt_contamination(ons, offs, mode, qclist);
03019 }
03020
03021 }
03022
03023 end_skip;
03024
03025 cpl_frameset_delete(pair_on);
03026 cpl_imagelist_delete(ons);
03027
03028 if(!detmon_lg_config.collapse ) {
03029 cpl_imagelist_delete(offs);
03030 }
03031
03032 if(!detmon_lg_config.collapse) {
03033 cpl_frameset_delete(pair_off);
03034 }
03035
03036 if(detmon_lg_config.collapse) {
03037 cpl_imagelist_delete(masterl);
03038 }
03039
03040 cpl_propertylist_delete(plist);
03041 cpl_propertylist_delete(pDETlist);
03042 return cpl_error_get_code();
03043 }
03044
03045
03051
03052 static cpl_error_code
03053 irplib_detmon_add_adl_column(cpl_table * table,
03054 cpl_boolean opt_nir)
03055 {
03056 cpl_error_code error;
03057 double mean_med_dit;
03058 double *dits;
03059
03060 cpl_ensure_code(table != NULL, CPL_ERROR_NULL_INPUT);
03061
03062 mean_med_dit = cpl_table_get_column_mean(table, "MED_DIT");
03063 if (opt_nir == OPT)
03064 dits = cpl_table_get_data_double(table, "EXPTIME");
03065 else
03066 dits = cpl_table_get_data_double(table, "DIT");
03067
03068 error = cpl_table_copy_data_double(table, "ADL", dits);
03069 cpl_ensure_code(!error, error);
03070 error = cpl_table_multiply_scalar(table, "ADL", mean_med_dit);
03071 cpl_ensure_code(!error, error);
03072
03073 return cpl_error_get_code();
03074 }
03075
03076
03084
03085 static cpl_error_code
03086 irplib_detmon_lg_reduce_init(cpl_table * gain_table,
03087 cpl_table * linear_table,
03088 cpl_imagelist ** linearity_inputs,
03089 const cpl_boolean opt_nir)
03090 {
03091 skip_if(irplib_detmon_gain_table_create(gain_table, opt_nir));
03092 skip_if(irplib_detmon_lin_table_create(linear_table, opt_nir));
03093
03094 if(detmon_lg_config.pix2pix) {
03095 *linearity_inputs = cpl_imagelist_new();
03096 skip_if(*linearity_inputs == NULL);
03097 }
03098
03099 end_skip;
03100
03101 return cpl_error_get_code();
03102 }
03103
03104
03110
03111 static double
03112 irplib_pfits_get_dit(const cpl_propertylist * plist)
03113 {
03114 return irplib_pfits_get_prop_double(plist, "ESO DET DIT");
03115 }
03116
03117
03123
03124 static double
03125 irplib_pfits_get_dit_opt(const cpl_propertylist * plist)
03126 {
03127 return irplib_pfits_get_prop_double(plist, "ESO DET WIN1 UIT1");
03128 }
03129
03130 static double irplib_pfits_get_prop_double(const cpl_propertylist * plist, const char* prop_name)
03131 {
03132 double dit;
03133 dit = cpl_propertylist_get_double(plist, prop_name);
03134 if(cpl_error_get_code() != CPL_ERROR_NONE)
03135 {
03136 cpl_msg_error(cpl_func, "Cannot read property '%s', err[%s]",prop_name, cpl_error_get_where());
03137 }
03138 return dit;
03139 }
03140
03172
03173 static cpl_error_code
03174 irplib_detmon_gain_table_fill_row(cpl_table * gain_table,
03175 double c_dit,int c_ndit,
03176 cpl_imagelist * autocorr_images,
03177 cpl_imagelist * diff_flats,
03178 const cpl_imagelist * ons,
03179 const cpl_imagelist * offs,
03180 double kappa, int nclip,
03181 int llx, int lly, int urx, int ury,
03182 int m, int n,
03183 double saturation_limit,
03184 const int pos, unsigned mode, int* rows_affected)
03185 {
03186 const cpl_image *image;
03187 double std = 0;
03188 cpl_image *on_dif = NULL;
03189 cpl_image *off_dif = NULL;
03190 double avg_on1, avg_on2;
03191 double avg_off1, avg_off2;
03192 double avg_on_dif, sig_on_dif;
03193 double avg_off_dif, sig_off_dif;
03194 double double_adu, autocorr, gain, gain_corr;
03195 double sigma, sigma_corr;
03196
03197 cpl_table_set(gain_table, "FLAG", pos, 1);
03198 if (mode & IRPLIB_GAIN_NIR)
03199 {
03200 cpl_table_set(gain_table, "DIT", pos, c_dit);
03201 cpl_table_set(gain_table, "NDIT", pos, c_ndit);
03202 } else if (mode & IRPLIB_GAIN_OPT)
03203 {
03204 cpl_table_set(gain_table, "EXPTIME", pos, c_dit);
03205 } else
03206 {
03207 cpl_msg_error(cpl_func, "Mandatory mode (OPT or NIR) not provided");
03208 skip_if(1);
03209 }
03210 if(*rows_affected == 0)
03211 {
03212 cpl_msg_info(cpl_func, "skip the frame #%d", pos + 1);
03213 cpl_table_set(gain_table, "FLAG", pos, 0);
03214 if(mode & IRPLIB_GAIN_WITH_AUTOCORR)
03215 {
03216 autocorr = -1;
03217 if (diff_flats)
03218 {
03219 irplib_detmon_lg_add_empty_image(diff_flats, pos);
03220 }
03221 if (autocorr_images)
03222 {
03223 irplib_detmon_lg_add_empty_image(autocorr_images, pos);
03224 }
03225 }
03226 return cpl_error_get_code();
03227 }
03228 skip_if((image = cpl_imagelist_get_const(ons, 0)) == NULL);
03229 skip_if(irplib_ksigma_clip(image, llx, lly, urx, ury, kappa,
03230 nclip, 1e-5, &avg_on1, &std));
03231 skip_if((image = cpl_imagelist_get_const(ons, 1)) == NULL);
03232 skip_if(irplib_ksigma_clip(image, llx, lly, urx, ury, kappa,
03233 nclip, 1e-5, &avg_on2, &std));
03234
03235 if ((avg_on1 > saturation_limit) || (avg_on2 > saturation_limit))
03236 {
03237 cpl_msg_warning(cpl_func, "Average saturation is above the limit, the frames would not be taken into calculation");
03238 cpl_msg_warning(cpl_func, "saturation levels [%f ; %f], limit [%f]", avg_on1, avg_on2, saturation_limit);
03239 cpl_msg_info(cpl_func, "skip the frame #%d", pos + 1);
03240 cpl_table_set(gain_table, "FLAG", pos, 0);
03241 if(mode & IRPLIB_GAIN_WITH_AUTOCORR)
03242 {
03243 autocorr = -1;
03244 if (diff_flats)
03245 {
03246 irplib_detmon_lg_add_empty_image(diff_flats, pos);
03247 }
03248 if (autocorr_images)
03249 {
03250 irplib_detmon_lg_add_empty_image(autocorr_images, pos);
03251 }
03252 }
03253 *rows_affected = 0;
03254 }
03255 else
03256 {
03257 *rows_affected = 1;
03258 skip_if(cpl_table_set_double(gain_table, "MEAN_ON1", pos, avg_on1));
03259 skip_if(cpl_table_set_double(gain_table, "MEAN_ON2", pos, avg_on2));
03260 on_dif =
03261 cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
03262 cpl_imagelist_get_const(ons, 1));
03263 skip_if(on_dif == NULL);
03264 skip_if(irplib_ksigma_clip(on_dif, llx, lly, urx, ury, kappa,
03265 nclip, 1e-5,
03266 &avg_on_dif, &sig_on_dif));
03267 skip_if(cpl_table_set_double(gain_table, "SIG_ON_DIF", pos, sig_on_dif));
03268
03269 if(mode & IRPLIB_GAIN_WITH_AUTOCORR)
03270 {
03271 if (diff_flats)
03272 {
03273 cpl_image * diff = cpl_image_duplicate(on_dif);
03274 skip_if(cpl_imagelist_set(diff_flats, diff, pos));
03275 }
03276 if (autocorr_images)
03277 {
03278 cpl_image * corr = NULL;
03279 autocorr = irplib_detmon_autocorr_factor(on_dif, &corr, m, n);
03280 if(corr)
03281 {
03282 skip_if(cpl_imagelist_set(autocorr_images, corr, pos));
03283 }
03284 else
03285 {
03286 irplib_detmon_lg_add_empty_image(autocorr_images, pos);
03287 }
03288 } else
03289 {
03290 autocorr = irplib_detmon_autocorr_factor(on_dif, NULL, m, n);
03291 }
03292 autocorr = isnan(autocorr) ? 1.0 : autocorr;
03293 } else
03294 {
03295 autocorr = 1.0;
03296 }
03297
03298 if (cpl_imagelist_get_size(offs) == 1 && mode & IRPLIB_GAIN_NO_COLLAPSE)
03299 {
03300
03301 skip_if(irplib_ksigma_clip(cpl_imagelist_get_const(offs, 0),
03302 llx, lly, urx, ury, kappa, nclip,
03303 1e-5, &avg_off1, &std));
03304 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF", pos, avg_off1));
03305
03306 } else if (mode & IRPLIB_GAIN_NO_COLLAPSE ||
03307 ( pos == 0 && mode & IRPLIB_GAIN_COLLAPSE )) {
03308 skip_if(irplib_ksigma_clip(cpl_imagelist_get_const(offs, 0),
03309 llx, lly, urx, ury, kappa, nclip,
03310 1e-5, &avg_off1, &std));
03311 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF1", pos, avg_off1));
03312 skip_if(irplib_ksigma_clip(cpl_imagelist_get_const(offs, 1),
03313 llx, lly, urx, ury, kappa, nclip,
03314 1e-5, &avg_off2, &std));
03315 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF2", pos, avg_off2));
03316 off_dif =
03317 cpl_image_subtract_create(cpl_imagelist_get_const(offs, 0),
03318 cpl_imagelist_get_const(offs, 1));
03319 skip_if(off_dif == NULL);
03320 skip_if(irplib_ksigma_clip(off_dif, llx, lly, urx, ury,
03321 kappa, nclip, 1e-5,
03322 &avg_off_dif, &sig_off_dif));
03323 skip_if(cpl_table_set_double(gain_table, "SIG_OFF_DIF",
03324 pos, sig_off_dif));
03325 } else if (pos > 0 && mode & IRPLIB_GAIN_COLLAPSE)
03326 {
03327 int status;
03328 avg_off1 = cpl_table_get_double(gain_table, "MEAN_OFF1", 0, &status);
03329 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF1", pos, avg_off1));
03330 avg_off2 = cpl_table_get_double(gain_table, "MEAN_OFF2", 0, &status);
03331 skip_if(cpl_table_set_double(gain_table, "MEAN_OFF2", pos, avg_off2));
03332 sig_off_dif = cpl_table_get_double(gain_table, "SIG_OFF_DIF",
03333 0, &status);
03334 skip_if(cpl_table_set_double(gain_table, "SIG_OFF_DIF",
03335 pos, sig_off_dif));
03336 }
03337
03338 if (cpl_imagelist_get_size(offs) == 1 && mode & IRPLIB_GAIN_NO_COLLAPSE)
03339 {
03340 double_adu = (avg_on1 + avg_on2) - 2 * avg_off1;
03341 }
03342 else
03343 {
03344 double_adu = (avg_on1 + avg_on2) - (avg_off1 + avg_off2);
03345
03346 sigma = (sig_on_dif * sig_on_dif) - (sig_off_dif * sig_off_dif);
03347
03348 sigma_corr = autocorr * sigma;
03349
03350 gain = double_adu / (c_ndit * sigma);
03351
03352 gain_corr = double_adu / (c_dit*sigma_corr);
03353
03354 skip_if(cpl_table_set_double(gain_table, "GAIN", pos, gain));
03355 skip_if(cpl_table_set_double(gain_table, "GAIN_CORR", pos, gain_corr));
03356 }
03357
03358 skip_if(cpl_table_set_double(gain_table, "AUTOCORR", pos, autocorr));
03359 skip_if(cpl_table_set_double(gain_table, "ADU", pos, double_adu / 2));
03360
03361
03362 skip_if(cpl_table_set_double(gain_table, "Y_FIT",
03363 pos,
03364 c_ndit* sig_on_dif * sig_on_dif));
03365 skip_if(cpl_table_set_double(gain_table, "Y_FIT_CORR",
03366 pos,
03367 c_ndit * sig_on_dif * sig_on_dif));
03368 skip_if(cpl_table_set_double(gain_table, "X_FIT", pos, double_adu));
03369 skip_if(cpl_table_set_double(gain_table, "X_FIT_CORR",
03370 pos, double_adu / autocorr));
03371 }
03372 end_skip;
03373
03374 cpl_image_delete(on_dif);
03375 cpl_image_delete(off_dif);
03376
03377 return cpl_error_get_code();
03378 }
03379
03380
03387
03388
03389 static cpl_image *
03390 irplib_detmon_bpixs(const cpl_imagelist * coeffs,
03391 cpl_boolean bpmbin,
03392 const double kappa,
03393 int *nbpixs)
03394 {
03395 int size;
03396 int i;
03397 const cpl_image *first= cpl_imagelist_get_const(coeffs, 0);
03398 cpl_stats *stats;
03399 double cur_mean;
03400 double cur_stdev;
03401 double lo_cut;
03402 double hi_cut;
03403 cpl_mask *cur_mask;
03404 cpl_mask *mask = cpl_mask_new(cpl_image_get_size_x(first),
03405 cpl_image_get_size_y(first));
03406 cpl_image *cur_image = NULL;
03407 cpl_image *bpm = NULL;
03408 double p;
03409
03410 size = cpl_imagelist_get_size(coeffs);
03411
03412 if(!bpmbin) {
03413 bpm = cpl_image_new(cpl_image_get_size_x(first),
03414 cpl_image_get_size_y(first),
03415 CPL_TYPE_INT);
03416 }
03417
03418
03419 for(i = 0; i < size; i++) {
03420 const cpl_image * cur_coeff = cpl_imagelist_get_const(coeffs, i);
03421
03422 stats = cpl_stats_new_from_image(cur_coeff,
03423 CPL_STATS_MEAN | CPL_STATS_STDEV);
03424 cur_mean = cpl_stats_get_mean(stats);
03425 cur_stdev = cpl_stats_get_stdev(stats);
03426
03427 lo_cut = cur_mean - kappa * cur_stdev;
03428 hi_cut = cur_mean + kappa * cur_stdev;
03429
03430 cur_mask = cpl_mask_threshold_image_create(cur_coeff, lo_cut, hi_cut);
03431 cpl_mask_not(cur_mask);
03432
03433 if(!bpmbin) {
03434 cur_image = cpl_image_new_from_mask(cur_mask);
03435 p = pow(2, i);
03436 cpl_image_power(cur_image, p);
03437 cpl_image_add(bpm, cur_image);
03438 cpl_image_delete(cur_image);
03439 }
03440
03441 cpl_mask_or(mask, cur_mask);
03442
03443 cpl_mask_delete(cur_mask);
03444 cpl_stats_delete(stats);
03445 }
03446
03447 if(bpmbin) {
03448 bpm = cpl_image_new_from_mask(mask);
03449 }
03450
03451 *nbpixs += cpl_mask_count(mask);
03452
03453 cpl_mask_delete(mask);
03454
03455 return bpm;
03456 }
03457
03458
03470
03471
03472 static double
03473 irplib_detmon_autocorr_factor(const cpl_image * image,
03474 cpl_image ** autocorr_image, int m, int n)
03475 {
03476 cpl_image * mycorr_image = NULL;
03477 double autocorr = 0;
03478 cpl_error_code err = CPL_ERROR_NONE;
03479
03480 mycorr_image = irplib_detmon_image_correlate(image, image, m, n);
03481 err=cpl_error_get_code();
03482 if (err == CPL_ERROR_UNSUPPORTED_MODE)
03483 {
03484 cpl_msg_warning(cpl_func, "FFTW is not supported by CPL, autocorrelation "
03485 "would be computed using internal implementation");
03486 cpl_error_reset();
03487 if (mycorr_image)
03488 cpl_image_delete(mycorr_image);
03489 mycorr_image = irplib_detmon_autocorrelate(image, m, n);
03490 }
03491 if(mycorr_image == NULL) {
03492 return -1;
03493 }
03494
03495 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), -1);
03496
03497 autocorr = cpl_image_get_flux(mycorr_image);
03498
03499 if (autocorr_image) *autocorr_image = mycorr_image;
03500 else cpl_image_delete(mycorr_image);
03501
03502 return autocorr;
03503 }
03504
03505
03536
03537 static cpl_error_code
03538 irplib_detmon_lg_save(const cpl_parameterlist * parlist,
03539 cpl_frameset * frameset,
03540 const char *recipe_name,
03541 const char *pipeline_name,
03542 const char *pafregexp,
03543 const cpl_propertylist * pro_lintbl,
03544 const cpl_propertylist * pro_gaintbl,
03545 const cpl_propertylist * pro_coeffscube,
03546 const cpl_propertylist * pro_bpm,
03547 const cpl_propertylist * pro_corr,
03548 const cpl_propertylist * pro_diff,
03549 const char *package,
03550 cpl_imagelist * coeffs,
03551 cpl_table * gain_table,
03552 cpl_table * linear_table,
03553 cpl_image * bpms,
03554 cpl_imagelist * autocorr_images,
03555 cpl_imagelist * diff_flats,
03556 cpl_propertylist * gaint_qclist,
03557 cpl_propertylist * lint_qclist,
03558 cpl_propertylist * linc_qclist,
03559 cpl_propertylist * bpm_qclist,
03560 const int flag_sets,
03561 const int which_set,
03562 const cpl_frameset * usedframes,
03563 int whichext)
03564 {
03565
03566 cpl_frame *ref_frame;
03567 cpl_propertylist *plist = NULL;
03568 cpl_propertylist *mainplist = NULL;
03569 char *name_o = NULL;
03570 int nb_images;
03571 int i;
03572 cpl_error_code error;
03573 cpl_propertylist * xplist = NULL;
03574 cpl_propertylist * gaint_paflist = NULL;
03575 cpl_propertylist * lint_paflist = NULL;
03576 cpl_propertylist * linc_paflist = NULL;
03577 cpl_propertylist * bpm_paflist = NULL;
03578
03579 cpl_propertylist * mypro_lintbl =
03580 cpl_propertylist_duplicate(pro_lintbl);
03581 cpl_propertylist * mypro_gaintbl =
03582 cpl_propertylist_duplicate(pro_gaintbl);
03583 cpl_propertylist * mypro_coeffscube =
03584 cpl_propertylist_duplicate(pro_coeffscube);
03585 cpl_propertylist * mypro_bpm =
03586 cpl_propertylist_duplicate(pro_bpm);
03587 cpl_propertylist * mypro_corr =
03588 cpl_propertylist_duplicate(pro_corr);
03589 cpl_propertylist * mypro_diff =
03590 cpl_propertylist_duplicate(pro_diff);
03591
03592 const char * procatg_lintbl =
03593 cpl_propertylist_get_string(mypro_lintbl, CPL_DFS_PRO_CATG);
03594
03595 const char * procatg_gaintbl =
03596 cpl_propertylist_get_string(mypro_gaintbl, CPL_DFS_PRO_CATG);
03597
03598 const char * procatg_coeffscube =
03599 cpl_propertylist_get_string(mypro_coeffscube, CPL_DFS_PRO_CATG);
03600 const char * procatg_bpm =
03601 cpl_propertylist_get_string(mypro_bpm, CPL_DFS_PRO_CATG);
03602
03603
03604 if (detmon_lg_config.exts < 0) {
03605 const char * filename =
03606 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
03607
03608
03609 xplist = cpl_propertylist_load_regexp(filename, whichext,
03610 "ESO DET|EXTNAME", 0);
03611
03612
03613 cpl_propertylist_erase_regexp(xplist, "DET CHIP LIVE", 0) ;
03614
03615
03616 skip_if(cpl_propertylist_append(gaint_qclist, xplist));
03617 skip_if(cpl_propertylist_append(lint_qclist, xplist));
03618 skip_if(cpl_propertylist_append(linc_qclist, xplist));
03619 skip_if(cpl_propertylist_append(bpm_qclist, xplist));
03620 }
03621
03622
03623
03624
03625 ref_frame = cpl_frameset_get_first(frameset);
03626
03627 skip_if((mainplist =
03628 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03629 0)) == NULL);
03630
03631
03632
03633
03634
03635
03636 if(!flag_sets) {
03637 name_o = cpl_sprintf("%s_linearity_table.fits", recipe_name);
03638 assert(name_o != NULL);
03639 } else {
03640 name_o =
03641 cpl_sprintf("%s_linearity_table_set%02d.fits", recipe_name,
03642 which_set);
03643 assert(name_o != NULL);
03644 }
03645
03646 if (detmon_lg_config.exts >= 0) {
03647
03648 cpl_propertylist_append(mypro_lintbl, lint_qclist);
03649
03650 skip_if(cpl_dfs_save_table(frameset, NULL,parlist, usedframes, NULL,linear_table,
03651 NULL, recipe_name,
03652 mypro_lintbl, NULL, package, name_o));
03653
03654 } else {
03655 if(whichext == 1) {
03656
03657 skip_if(cpl_dfs_save_table(frameset,NULL, parlist, usedframes, NULL, linear_table,
03658 lint_qclist, recipe_name, mypro_lintbl,
03659 NULL, package, name_o));
03660 } else {
03661 skip_if(cpl_table_save(linear_table, NULL, lint_qclist, name_o,
03662 CPL_IO_EXTEND));
03663 }
03664 }
03665
03666
03667 if(name_o!=NULL) {
03668 cpl_free(name_o);
03669 name_o=NULL;
03670 }
03671
03672
03673
03674
03675
03676
03677 if(!flag_sets) {
03678 name_o = cpl_sprintf("%s_gain_table.fits", recipe_name);
03679 assert(name_o != NULL);
03680 } else {
03681 name_o =
03682 cpl_sprintf("%s_gain_table_set%02d.fits", recipe_name,
03683 which_set);
03684 assert(name_o != NULL);
03685 }
03686
03687 if (detmon_lg_config.exts >= 0) {
03688
03689 cpl_propertylist_append(mypro_gaintbl, gaint_qclist);
03690
03691 skip_if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL,gain_table,
03692 NULL, recipe_name, mypro_gaintbl,
03693 NULL, package, name_o));
03694 } else {
03695 if(whichext == 1) {
03696
03697 skip_if(cpl_dfs_save_table(frameset, NULL, parlist, usedframes, NULL, gain_table,
03698 gaint_qclist, recipe_name, mypro_gaintbl,
03699 NULL, package, name_o));
03700 } else {
03701 skip_if(cpl_table_save(gain_table, NULL, gaint_qclist, name_o,
03702 CPL_IO_EXTEND));
03703 }
03704 }
03705
03706
03707 if(name_o!=NULL) {
03708 cpl_free(name_o);
03709 name_o=NULL;
03710 }
03711
03712 if(detmon_lg_config.pix2pix) {
03713
03714
03715
03716
03717
03718
03719 if(!flag_sets) {
03720 name_o =
03721 cpl_sprintf("%s_coeffs_cube.fits", recipe_name);
03722 assert(name_o != NULL);
03723 } else {
03724 name_o =
03725 cpl_sprintf("%s_coeffs_cube_set%02d.fits",
03726 recipe_name, which_set);
03727 assert(name_o != NULL);
03728 }
03729
03730
03731 if(detmon_lg_config.exts >= 0) {
03732 cpl_propertylist_append(mypro_coeffscube, linc_qclist);
03733 skip_if(irplib_detmon_lg_dfs_save_imagelist
03734 (frameset, parlist, usedframes, coeffs,
03735 recipe_name, mypro_coeffscube, package,
03736 name_o));
03737 } else {
03738 if(whichext == 1) {
03739 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,
03740 NULL, NULL,
03741 CPL_BPP_IEEE_FLOAT, recipe_name,
03742 mypro_coeffscube, NULL,
03743 package, name_o));
03744 skip_if(cpl_imagelist_save(coeffs,
03745 name_o, CPL_BPP_IEEE_FLOAT, linc_qclist,
03746 CPL_IO_EXTEND));
03747 } else {
03748 skip_if(cpl_imagelist_save(coeffs,
03749 name_o, CPL_BPP_IEEE_FLOAT, linc_qclist,
03750 CPL_IO_EXTEND));
03751 }
03752 }
03753 if(name_o!=NULL) {
03754 cpl_free(name_o);
03755 name_o=NULL;
03756 }
03757
03758
03759
03760
03761
03762
03763 if(!flag_sets) {
03764 name_o = cpl_sprintf("%s_bpm.fits", recipe_name);
03765 assert(name_o != NULL);
03766 } else {
03767 name_o =
03768 cpl_sprintf("%s_bpm_set%02d.fits", recipe_name, which_set);
03769 assert(name_o != NULL);
03770 }
03771
03772
03773 if(detmon_lg_config.exts >= 0) {
03774 cpl_propertylist_append(mypro_bpm, bpm_qclist);
03775
03776 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL, bpms,
03777 CPL_BPP_IEEE_FLOAT, recipe_name,
03778 mypro_bpm, NULL, package,
03779 name_o));
03780 } else {
03781 if (whichext == 1) {
03782 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes,NULL, NULL,
03783 CPL_BPP_IEEE_FLOAT, recipe_name,
03784 mypro_bpm, NULL, package,
03785 name_o));
03786 skip_if(cpl_image_save(bpms, name_o, CPL_BPP_IEEE_FLOAT,
03787 bpm_qclist, CPL_IO_EXTEND));
03788 } else {
03789 skip_if(cpl_image_save(bpms, name_o, CPL_BPP_IEEE_FLOAT,
03790 bpm_qclist, CPL_IO_EXTEND));
03791 }
03792 }
03793
03794 if(name_o!=NULL) {
03795 cpl_free(name_o);
03796 name_o=NULL;
03797 }
03798
03799 }
03800
03801 if(detmon_lg_config.intermediate) {
03802
03803
03804
03805 nb_images = cpl_imagelist_get_size(autocorr_images);
03806 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
03807 for(i = 0; i < nb_images; i++)
03808 {
03809 cpl_propertylist* pplist = cpl_propertylist_duplicate(mypro_corr);
03810 int inull = 0;
03811 cpl_array* pnames = cpl_table_get_column_names(linear_table);
03812 double ddit = 0;
03813 if(i < cpl_table_get_nrow(linear_table))
03814 {
03815 ddit = cpl_table_get_double(linear_table,
03816 cpl_array_get_data_string_const(pnames)[0], i, &inull);
03817 }
03818 cpl_array_delete(pnames);
03819 cpl_propertylist_append_double(pplist, "ESO DET DIT", ddit);
03820
03821 if(!flag_sets)
03822 {
03823 name_o =
03824 cpl_sprintf("%s_autocorr_%d.fits", recipe_name, i);
03825 assert(name_o != NULL);
03826 } else
03827 {
03828 name_o =
03829 cpl_sprintf("%s_autocorr_%02d_set%02d.fits",
03830 recipe_name, i, which_set);
03831 assert(name_o != NULL);
03832 }
03833
03834 if(detmon_lg_config.exts >= 0)
03835 {
03836 skip_if(cpl_dfs_save_image
03837 (frameset, NULL, parlist, usedframes, NULL,
03838 cpl_imagelist_get(autocorr_images, i), CPL_BPP_IEEE_FLOAT,
03839 recipe_name, pplist, NULL, package,
03840 name_o));
03841 }
03842 else
03843 {
03844 if(whichext == 1)
03845 {
03846 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,NULL,
03847 CPL_BPP_IEEE_FLOAT, recipe_name,
03848 pplist, NULL,
03849 package, name_o));
03850 skip_if(cpl_image_save(cpl_imagelist_get(autocorr_images, i),
03851 name_o, CPL_BPP_IEEE_FLOAT, NULL,
03852 CPL_IO_EXTEND));
03853 } else
03854 {
03855 skip_if(cpl_image_save(cpl_imagelist_get(autocorr_images, i),
03856 name_o, CPL_BPP_IEEE_FLOAT, NULL,
03857 CPL_IO_EXTEND));
03858 }
03859 }
03860 if(name_o!=NULL)
03861 {
03862 cpl_free(name_o);
03863 name_o=NULL;
03864 }
03865 cpl_propertylist_delete (pplist);
03866 }
03867
03868
03869
03870
03871 for(i = 0; i < nb_images; i++)
03872 {
03873 cpl_propertylist* pplist = cpl_propertylist_duplicate(mypro_diff);
03874 int inull = 0;
03875 cpl_array* pnames = cpl_table_get_column_names(linear_table);
03876 double ddit = 0;
03877 if(i < cpl_table_get_nrow(linear_table))
03878 {
03879 ddit = cpl_table_get_double(linear_table,
03880 cpl_array_get_data_string_const(pnames)[0], i, &inull);
03881 }
03882 cpl_array_delete(pnames);
03883 cpl_propertylist_append_double(pplist, "ESO DET DIT", ddit);
03884
03885 if(!flag_sets)
03886 {
03887 name_o =
03888 cpl_sprintf("%s_diff_flat_%d.fits", recipe_name, i);
03889 assert(name_o != NULL);
03890 } else
03891 {
03892 name_o =
03893 cpl_sprintf("%s_diff_flat_%d_set%02d.fits",
03894 recipe_name, i, which_set);
03895 assert(name_o != NULL);
03896 }
03897
03898 if(detmon_lg_config.exts >= 0)
03899 {
03900 skip_if(cpl_dfs_save_image
03901 (frameset, NULL, parlist, usedframes, NULL,
03902 cpl_imagelist_get(diff_flats, i), CPL_BPP_IEEE_FLOAT,
03903 recipe_name, pplist, NULL, package,
03904 name_o));
03905 } else
03906 {
03907 if(whichext == 1)
03908 {
03909 skip_if(cpl_dfs_save_image(frameset, NULL, parlist, usedframes, NULL,NULL,
03910 CPL_BPP_IEEE_FLOAT, recipe_name,
03911 mypro_diff, NULL,
03912 package, name_o));
03913 skip_if(cpl_image_save(cpl_imagelist_get(diff_flats, i),
03914 name_o, CPL_BPP_IEEE_FLOAT, NULL,
03915 CPL_IO_EXTEND));
03916 } else
03917 {
03918 skip_if(cpl_image_save(cpl_imagelist_get(diff_flats, i),
03919 name_o, CPL_BPP_IEEE_FLOAT, NULL,
03920 CPL_IO_EXTEND));
03921 }
03922 }
03923 if(name_o!=NULL)
03924 {
03925 cpl_free(name_o);
03926 name_o=NULL;
03927 }
03928 cpl_propertylist_delete(pplist);
03929 }
03930 if(name_o!=NULL)
03931 {
03932 cpl_free(name_o);
03933 name_o=NULL;
03934 }
03935 }
03936
03937
03938
03939
03940
03941 gaint_paflist = cpl_propertylist_new();
03942 lint_paflist = cpl_propertylist_new();
03943
03944 skip_if(cpl_propertylist_append_string(gaint_paflist, CPL_DFS_PRO_CATG,
03945 procatg_gaintbl));
03946 skip_if(cpl_propertylist_append_string(lint_paflist, CPL_DFS_PRO_CATG,
03947 procatg_lintbl));
03948
03949 if(detmon_lg_config.pix2pix) {
03950 linc_paflist = cpl_propertylist_new();
03951 bpm_paflist = cpl_propertylist_new();
03952
03953 skip_if(cpl_propertylist_append_string(linc_paflist, CPL_DFS_PRO_CATG,
03954 procatg_coeffscube));
03955 skip_if(cpl_propertylist_append_string(bpm_paflist, CPL_DFS_PRO_CATG,
03956 procatg_bpm));
03957
03958 }
03959
03960
03961 if(detmon_lg_config.exts >= 0) {
03962 skip_if((plist =
03963 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03964 detmon_lg_config.exts)) == NULL);
03965
03966 if(!flag_sets) {
03967 name_o = cpl_sprintf("%s_qc01.paf", detmon_lg_config.pafname);
03968 assert(name_o != NULL);
03969 } else {
03970 name_o = cpl_sprintf("%s_qc01_set%02d.paf",
03971 detmon_lg_config.pafname, which_set);
03972 assert(name_o != NULL);
03973 }
03974 } else {
03975 skip_if((plist =
03976 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03977 whichext)) == NULL);
03978
03979
03980 if(!flag_sets) {
03981 name_o = cpl_sprintf("%s_qc01_ext%02d.paf",
03982 detmon_lg_config.pafname, whichext);
03983 assert(name_o != NULL);
03984 } else {
03985 name_o = cpl_sprintf("%s_qc01_set%02d_ext%02d.paf",
03986 detmon_lg_config.pafname,
03987 which_set, whichext);
03988 assert(name_o != NULL);
03989 }
03990 }
03991
03992
03993 skip_if(cpl_propertylist_copy_property_regexp(gaint_paflist, plist,
03994 pafregexp, 0));
03995 skip_if(cpl_propertylist_copy_property_regexp(gaint_paflist, mainplist,
03996 pafregexp, 0));
03997
03998 if(plist!=NULL) {
03999 cpl_propertylist_delete(plist);
04000 plist=NULL;
04001 }
04002 skip_if(error = cpl_propertylist_append(gaint_paflist, gaint_qclist));
04003
04004
04005 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, gaint_paflist, name_o));
04006
04007 if(name_o!=NULL) {
04008 cpl_free(name_o);
04009 name_o=NULL;
04010 }
04011
04012
04013 if(detmon_lg_config.exts >= 0) {
04014 skip_if((plist =
04015 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04016 detmon_lg_config.exts)) == NULL);
04017
04018 if(!flag_sets) {
04019 name_o = cpl_sprintf("%s_qc02.paf", detmon_lg_config.pafname);
04020 assert(name_o != NULL);
04021 } else {
04022 name_o = cpl_sprintf("%s_qc02_set%02d.paf",
04023 detmon_lg_config.pafname, which_set);
04024 assert(name_o != NULL);
04025 }
04026 } else {
04027 skip_if((plist =
04028 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04029 whichext)) == NULL);
04030
04031
04032 if(!flag_sets) {
04033 name_o = cpl_sprintf("%s_qc02_ext%02d.paf",
04034 detmon_lg_config.pafname, whichext);
04035 assert(name_o != NULL);
04036 } else {
04037 name_o = cpl_sprintf("%s_qc02_set%02d_ext%02d.paf",
04038 detmon_lg_config.pafname,
04039 which_set, whichext);
04040 assert(name_o != NULL);
04041 }
04042 }
04043
04044
04045 skip_if(cpl_propertylist_copy_property_regexp(lint_paflist, plist,
04046 pafregexp, 0));
04047 skip_if(cpl_propertylist_copy_property_regexp(lint_paflist, mainplist,
04048 pafregexp, 0));
04049
04050 if(plist!=NULL) {
04051 cpl_propertylist_delete(plist);
04052 plist=NULL;
04053 }
04054
04055 skip_if(error = cpl_propertylist_append(lint_paflist, lint_qclist));
04056
04057
04058 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, lint_paflist, name_o));
04059
04060 if(name_o!=NULL) {
04061 cpl_free(name_o);
04062 name_o=NULL;
04063 }
04064
04065 if(detmon_lg_config.pix2pix) {
04066
04067
04068 if(detmon_lg_config.exts >= 0) {
04069 skip_if((plist =
04070 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04071 detmon_lg_config.exts)) == NULL);
04072
04073 if(!flag_sets) {
04074 name_o = cpl_sprintf("%s_qc03.paf", detmon_lg_config.pafname);
04075 assert(name_o != NULL);
04076 } else {
04077 name_o = cpl_sprintf("%s_qc03_set%02d.paf",
04078 detmon_lg_config.pafname, which_set);
04079 assert(name_o != NULL);
04080 }
04081 } else {
04082 skip_if((plist =
04083 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04084 whichext)) == NULL);
04085
04086
04087 if(!flag_sets) {
04088 name_o = cpl_sprintf("%s_qc03_ext%02d.paf",
04089 detmon_lg_config.pafname, whichext);
04090 assert(name_o != NULL);
04091 } else {
04092 name_o = cpl_sprintf("%s_qc03_set%02d_ext%02d.paf",
04093 detmon_lg_config.pafname,
04094 which_set, whichext);
04095 assert(name_o != NULL);
04096 }
04097 }
04098
04099
04100 skip_if(cpl_propertylist_copy_property_regexp(linc_paflist, plist,
04101 pafregexp, 0));
04102 skip_if(cpl_propertylist_copy_property_regexp(linc_paflist, mainplist,
04103 pafregexp, 0));
04104
04105 skip_if(error = cpl_propertylist_append(linc_paflist, linc_qclist));
04106
04107 if(plist!=NULL) {
04108 cpl_propertylist_delete(plist);
04109 plist=NULL;
04110 }
04111
04112
04113 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, linc_paflist, name_o));
04114
04115 if(name_o!=NULL) {
04116 cpl_free(name_o);
04117 name_o=NULL;
04118 }
04119
04120
04121 if(detmon_lg_config.exts >= 0) {
04122 skip_if((plist =
04123 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04124 detmon_lg_config.exts)) == NULL);
04125
04126 if(!flag_sets) {
04127 name_o = cpl_sprintf("%s_qc04.paf", detmon_lg_config.pafname);
04128 assert(name_o != NULL);
04129 } else {
04130 name_o = cpl_sprintf("%s_qc04_set%02d.paf",
04131 detmon_lg_config.pafname, which_set);
04132 assert(name_o != NULL);
04133 }
04134 } else {
04135 skip_if((plist =
04136 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
04137 whichext)) == NULL);
04138
04139
04140 if(!flag_sets) {
04141 name_o = cpl_sprintf("%s_qc04_ext%02d.paf",
04142 detmon_lg_config.pafname, whichext);
04143 assert(name_o != NULL);
04144 } else {
04145 name_o = cpl_sprintf("%s_qc04_set%02d_ext%02d.paf",
04146 detmon_lg_config.pafname,
04147 which_set, whichext);
04148 assert(name_o != NULL);
04149 }
04150 }
04151
04152
04153 skip_if(cpl_propertylist_copy_property_regexp(bpm_paflist, plist,
04154 pafregexp, 0));
04155 skip_if(cpl_propertylist_copy_property_regexp(bpm_paflist, mainplist,
04156 pafregexp, 0));
04157
04158 if(plist!=NULL) {
04159 cpl_propertylist_delete(plist);
04160 plist=NULL;
04161 }
04162
04163 skip_if(error = cpl_propertylist_append(bpm_paflist, bpm_qclist));
04164
04165
04166 skip_if(cpl_dfs_save_paf(pipeline_name, recipe_name, bpm_paflist, name_o));
04167 if(name_o!=NULL) {
04168 cpl_free(name_o);
04169 name_o=NULL;
04170 }
04171 }
04172
04173 end_skip;
04174
04175 cpl_propertylist_delete(xplist);
04176
04177 cpl_propertylist_delete(gaint_paflist);
04178 cpl_propertylist_delete(lint_paflist);
04179 cpl_propertylist_delete(linc_paflist);
04180 cpl_propertylist_delete(bpm_paflist);
04181
04182
04183 if(plist!=NULL) {
04184 cpl_propertylist_delete(plist);
04185 plist=NULL;
04186 }
04187
04188 if(name_o!=NULL) {
04189 cpl_free(name_o);
04190 name_o=NULL;
04191 }
04192
04193 cpl_propertylist_delete(mainplist);
04194
04195 cpl_propertylist_delete(mypro_lintbl);
04196 cpl_propertylist_delete(mypro_gaintbl);
04197 cpl_propertylist_delete(mypro_coeffscube);
04198 cpl_propertylist_delete(mypro_bpm);
04199 cpl_propertylist_delete(mypro_corr);
04200 cpl_propertylist_delete(mypro_diff);
04201
04202 return cpl_error_get_code();
04203 }
04204
04205
04206
04214
04215 static cpl_error_code
04216 irplib_detmon_opt_contamination(const cpl_imagelist * ons,
04217 const cpl_imagelist * offs,
04218 unsigned mode,
04219 cpl_propertylist * qclist)
04220 {
04221
04222 double median[5] = {0, 0, 0, 0, 0};
04223
04224 cpl_image * dif1=NULL;
04225 cpl_image * dif2=NULL;
04226 cpl_image * dif_avg=NULL;
04227 char* kname=NULL;
04228 int offsize = cpl_imagelist_get_size(offs);
04229
04230
04231 dif1 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
04232 cpl_imagelist_get_const(offs, 0));
04233
04234 if (offsize == 1 || mode & IRPLIB_LIN_COLLAPSE)
04235 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
04236 cpl_imagelist_get_const(offs, 0));
04237 else if (mode & IRPLIB_LIN_NO_COLLAPSE)
04238 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
04239 cpl_imagelist_get_const(offs, 1));
04240
04241 dif_avg = cpl_image_average_create(dif1, dif2);
04242
04243 cpl_image_abs(dif_avg);
04244
04245 median[0] = cpl_image_get_median_window(dif_avg,
04246 detmon_lg_config.llx1,
04247 detmon_lg_config.lly1,
04248 detmon_lg_config.urx1,
04249 detmon_lg_config.ury1);
04250
04251 skip_if(0);
04252 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,1);
04253
04254 if(cpl_propertylist_has(qclist,kname)){
04255 skip_if(cpl_propertylist_update_double(qclist,kname,median[0]));
04256 } else {
04257 skip_if(cpl_propertylist_append_double(qclist,kname,median[0]));
04258 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
04259 }
04260 median[1] = cpl_image_get_median_window(dif_avg,
04261 detmon_lg_config.llx2,
04262 detmon_lg_config.lly2,
04263 detmon_lg_config.urx2,
04264 detmon_lg_config.ury2);
04265
04266 skip_if(0);
04267 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,2);
04268 if(cpl_propertylist_has(qclist,kname)){
04269 skip_if(cpl_propertylist_update_double(qclist,kname,median[1]));
04270 } else {
04271 skip_if(cpl_propertylist_append_double(qclist,kname,median[1]));
04272 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
04273 }
04274 median[2] = cpl_image_get_median_window(dif_avg,
04275 detmon_lg_config.llx3,
04276 detmon_lg_config.lly3,
04277 detmon_lg_config.urx3,
04278 detmon_lg_config.ury3);
04279 skip_if(0);
04280
04281 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,3);
04282 if(cpl_propertylist_has(qclist,kname)){
04283 skip_if(cpl_propertylist_update_double(qclist,kname,median[2]));
04284 } else {
04285 skip_if(cpl_propertylist_append_double(qclist,kname,median[2]));
04286 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
04287 }
04288
04289 median[3] = cpl_image_get_median_window(dif_avg,
04290 detmon_lg_config.llx4,
04291 detmon_lg_config.lly4,
04292 detmon_lg_config.urx4,
04293 detmon_lg_config.ury4);
04294 skip_if(0);
04295
04296 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,4);
04297 if(cpl_propertylist_has(qclist,kname)){
04298 skip_if(cpl_propertylist_update_double(qclist,kname,median[3]));
04299 } else {
04300 skip_if(cpl_propertylist_append_double(qclist,kname,median[3]));
04301 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
04302 }
04303
04304 median[4] = cpl_image_get_median_window(dif_avg,
04305 detmon_lg_config.llx5,
04306 detmon_lg_config.lly5,
04307 detmon_lg_config.urx5,
04308 detmon_lg_config.ury5);
04309 skip_if(0);
04310
04311 kname = cpl_sprintf("%s%d", DETMON_QC_CONTAM,5);
04312 if(cpl_propertylist_has(qclist,kname)){
04313 skip_if(cpl_propertylist_update_double(qclist,kname,median[4]));
04314 } else {
04315 skip_if(cpl_propertylist_append_double(qclist,kname,median[4]));
04316 skip_if(cpl_propertylist_set_comment(qclist,kname,DETMON_QC_CONTAM_C));
04317 }
04318 end_skip;
04319
04320 cpl_image_delete(dif1);
04321 cpl_image_delete(dif2);
04322 cpl_image_delete(dif_avg);
04323
04324 return cpl_error_get_code();
04325 }
04326
04327
04334
04335
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345
04346
04347
04348
04349
04350
04351
04352
04353
04354
04355
04356
04357
04358
04359
04360
04361
04362
04363
04364
04365
04366
04367
04368
04369
04370
04371
04372
04373
04381
04382 int
04383 irplib_detmon_lg_dfs_set_groups(cpl_frameset * set,
04384 const char *tag_on, const char *tag_off)
04385 {
04386 cpl_frame *cur_frame;
04387 const char *tag;
04388 int nframes;
04389 int i;
04390
04391
04392 if(set == NULL)
04393 return -1;
04394
04395
04396 nframes = cpl_frameset_get_size(set);
04397
04398
04399 for(i = 0; i < nframes; i++) {
04400 cur_frame = cpl_frameset_get_frame(set, i);
04401 tag = cpl_frame_get_tag(cur_frame);
04402
04403
04404 if(!strcmp(tag, tag_on) || !strcmp(tag, tag_off))
04405 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
04406
04407
04408
04409
04410
04411 }
04412 return 0;
04413 }
04414
04415
04429
04430 static cpl_error_code
04431 irplib_detmon_lg_reduce_all(const cpl_table * linear_table,
04432 cpl_propertylist * gaint_qclist,
04433 cpl_propertylist * lint_qclist,
04434 cpl_propertylist * linc_qclist,
04435 cpl_propertylist * bpm_qclist,
04436 cpl_imagelist ** coeffs_ptr,
04437 cpl_image ** bpms_ptr,
04438 const cpl_imagelist * linearity_inputs,
04439 const cpl_table * gain_table,
04440 int which_ext, cpl_boolean opt_nir)
04441 {
04442
04443 int nbpixs = 0;
04444 const int nsets = cpl_table_get_nrow(linear_table);
04445 int i, j, k;
04446 double autocorr;
04447 cpl_polynomial *poly_linfit = NULL;
04448 cpl_image *fiterror = NULL;
04449 char * name_o1 = NULL;
04450 char * name_o2 = NULL;
04451 double * pcoeffs = cpl_malloc(sizeof(double)*(detmon_lg_config.order + 1));
04452 unsigned mode = detmon_lg_config.autocorr ? IRPLIB_GAIN_WITH_AUTOCORR : 0;
04453 double min_val=0;
04454 double max_val=0;
04455 cpl_vector *x =NULL;
04456 const cpl_vector *y =NULL;
04457
04458
04459 const cpl_image * first = NULL;
04460 int sizex = 0;
04461 int sizey = 0;
04462
04463 int vsize = 0;
04464
04465
04466
04467
04468 cpl_ensure_code(gaint_qclist != NULL, CPL_ERROR_NULL_INPUT);
04469 cpl_ensure_code(lint_qclist != NULL, CPL_ERROR_NULL_INPUT);
04470 cpl_ensure_code(linc_qclist != NULL, CPL_ERROR_NULL_INPUT);
04471 cpl_ensure_code(bpm_qclist != NULL, CPL_ERROR_NULL_INPUT);
04472
04473 skip_if(cpl_propertylist_append_string(gaint_qclist, DETMON_QC_METHOD,
04474 detmon_lg_config.method));
04475 skip_if(cpl_propertylist_set_comment(gaint_qclist, DETMON_QC_METHOD,
04476 DETMON_QC_METHOD_C));
04477
04478 if (!strcmp(detmon_lg_config.method, "PTC")) {
04479
04480 if (detmon_lg_config.exts >= 0) {
04481 cpl_msg_info(cpl_func,
04482 "Polynomial fitting for the GAIN (constant term method)");
04483 } else {
04484 cpl_msg_info(cpl_func,
04485 "Polynomial fitting for the GAIN (constant term method)"
04486 " for extension nb %d", which_ext);
04487 }
04488 skip_if(irplib_detmon_lg_qc_ptc(gain_table, gaint_qclist, mode, nsets));
04489 } else {
04490 skip_if(irplib_detmon_lg_qc_med(gain_table, gaint_qclist, nsets));
04491 }
04492
04493
04494
04495 if(detmon_lg_config.lamp_ok) {
04496 skip_if(cpl_propertylist_append_double(lint_qclist, DETMON_QC_LAMP_FLUX,
04497 detmon_lg_config.cr));
04498 skip_if(cpl_propertylist_set_comment(lint_qclist, DETMON_QC_LAMP_FLUX,
04499 DETMON_QC_LAMP_FLUX_C));
04500 }
04501
04502
04503 if(detmon_lg_config.autocorr == TRUE) {
04504 autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
04505 skip_if(cpl_propertylist_append_double(gaint_qclist, DETMON_QC_AUTOCORR,
04506 autocorr));
04507 skip_if(cpl_propertylist_set_comment(gaint_qclist, DETMON_QC_AUTOCORR,
04508 DETMON_QC_AUTOCORR_C));
04509 }
04510 if (detmon_lg_config.exts >= 0) {
04511 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix");
04512 } else {
04513 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix"
04514 " for extension nb %d", which_ext);
04515 }
04516
04517 if(!detmon_lg_config.pix2pix) {
04518 double mse = 0;
04519
04520 y = cpl_vector_wrap(nsets,
04521 (double *)cpl_table_get_data_double_const(linear_table,
04522 "MED"));
04523
04524 if (opt_nir == NIR)
04525 x = cpl_vector_wrap(nsets,
04526 (double *)cpl_table_get_data_double_const(linear_table,
04527 "DIT"));
04528 else
04529 x = cpl_vector_wrap(nsets,
04530 (double *)cpl_table_get_data_double_const(linear_table,
04531 "EXPTIME"));
04532
04533
04534 if(x == NULL || y == NULL) {
04535 cpl_vector_unwrap((cpl_vector *)x);
04536 cpl_vector_unwrap((cpl_vector *)y);
04537
04538
04539
04540
04541
04542
04543 skip_if(1);
04544 }
04545
04546 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
04547 poly_linfit = irplib_polynomial_fit_1d_create(x, y,
04548 detmon_lg_config.order,
04549 &mse);
04550
04551 if(detmon_lg_config.order == cpl_vector_get_size(x) - 1) {
04552 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
04553 mse = 0;
04554 }
04555
04556 if(poly_linfit == NULL) {
04557 cpl_vector_unwrap((cpl_vector *)x);
04558 cpl_vector_unwrap((cpl_vector *)y);
04559
04560 skip_if(1);
04561 }
04562
04563
04564 min_val=cpl_vector_get_min(y);
04565 max_val=cpl_vector_get_max(y);
04566
04567 cpl_vector_unwrap((cpl_vector *)x);
04568 cpl_vector_unwrap((cpl_vector *)y);
04569
04570 for(i = 0; i <= detmon_lg_config.order; i++) {
04571 const double coeff =
04572 cpl_polynomial_get_coeff(poly_linfit, &i);
04573 char *name_o =
04574 cpl_sprintf("ESO QC LIN COEF%d", i);
04575 assert(name_o != NULL);
04576 skip_if(cpl_propertylist_append_double(lint_qclist, name_o, coeff));
04577 skip_if(cpl_propertylist_set_comment(lint_qclist,name_o,
04578 DETMON_QC_LIN_COEF_C));
04579
04580 cpl_free(name_o);
04581 pcoeffs[i] = coeff;
04582 }
04583 skip_if(cpl_propertylist_append_double(lint_qclist,DETMON_QC_ERRFIT, mse));
04584 skip_if(cpl_propertylist_set_comment(lint_qclist,DETMON_QC_ERRFIT,
04585 DETMON_QC_ERRFIT_MSE_C));
04586
04587
04588 } else {
04589
04590
04591 y = cpl_vector_wrap(nsets,
04592 (double *)cpl_table_get_data_double_const(linear_table,
04593 "MED"));
04594
04595 if (opt_nir == NIR) {
04596 x=
04597 cpl_vector_wrap(nsets,
04598 (double *)cpl_table_get_data_double_const(linear_table,
04599 "DIT"));
04600
04601 } else {
04602
04603 x =
04604 cpl_vector_wrap(nsets,
04605 (double *)cpl_table_get_data_double_const(linear_table,
04606 "EXPTIME"));
04607
04608 }
04609
04610
04611 first = cpl_imagelist_get_const(linearity_inputs, 0);
04612 sizex = cpl_image_get_size_x(first);
04613 sizey = cpl_image_get_size_y(first);
04614
04615 vsize = cpl_vector_get_size(x);
04616 fiterror = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
04617
04618 *coeffs_ptr =
04619 cpl_fit_imagelist_polynomial(x, linearity_inputs, 0,
04620 detmon_lg_config.order, FALSE,
04621 CPL_TYPE_FLOAT, fiterror);
04622
04623 min_val=cpl_vector_get_min(y);
04624 max_val=cpl_vector_get_max(y);
04625
04626
04627 cpl_vector_unwrap((cpl_vector*)x);
04628 cpl_vector_unwrap((cpl_vector*)y);
04629 irplib_ensure(*coeffs_ptr != NULL, CPL_ERROR_UNSPECIFIED,
04630 "Failed polynomial fit");
04631
04632 for(i = 0; i <= detmon_lg_config.order; i++) {
04633 cpl_image *image = cpl_imagelist_get(*coeffs_ptr, i);
04634 const double coeff = cpl_image_get_median(image);
04635 pcoeffs[i] = coeff;
04636 name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
04637 name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
04638 assert(name_o1 != NULL);
04639 assert(name_o2 != NULL);
04640 skip_if(cpl_propertylist_append_double(linc_qclist, name_o1, coeff));
04641 skip_if(cpl_propertylist_set_comment(linc_qclist,name_o1,
04642 DETMON_QC_LIN_COEF_C));
04643 cpl_free(name_o1);
04644 name_o1= NULL;
04645 skip_if(cpl_propertylist_append_double(linc_qclist, name_o2,
04646 cpl_image_get_stdev(image)));
04647 skip_if(cpl_propertylist_set_comment(linc_qclist,name_o2,
04648 DETMON_QC_LIN_COEF_ERR_C));
04649 cpl_free(name_o2);
04650 name_o2= NULL;
04651 }
04652
04653 if(detmon_lg_config.order == vsize - 1) {
04654 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
04655 skip_if(cpl_propertylist_append_double(linc_qclist,DETMON_QC_ERRFIT,
04656 0.0));
04657 skip_if(cpl_propertylist_set_comment(linc_qclist,DETMON_QC_ERRFIT,
04658 DETMON_QC_ERRFIT_C));
04659
04660
04661
04662 } else {
04663 skip_if(cpl_propertylist_append_double(linc_qclist,DETMON_QC_ERRFIT,
04664 cpl_image_get_median(fiterror)));
04665 skip_if(cpl_propertylist_set_comment(linc_qclist,DETMON_QC_ERRFIT,
04666 DETMON_QC_ERRFIT_C));
04667
04668 }
04669 }
04670
04671
04672 skip_if(cpl_propertylist_append_double(lint_qclist,DETMON_QC_COUNTS_MIN,
04673 min_val));
04674
04675 skip_if(cpl_propertylist_set_comment(lint_qclist,DETMON_QC_COUNTS_MIN,
04676 DETMON_QC_COUNTS_MIN_C));
04677
04678 skip_if(cpl_propertylist_append_double(lint_qclist,DETMON_QC_COUNTS_MAX,
04679 max_val));
04680
04681 skip_if(cpl_propertylist_set_comment(lint_qclist,DETMON_QC_COUNTS_MAX,
04682 DETMON_QC_COUNTS_MAX_C));
04683
04684 skip_if(irplib_detmon_lg_lineff(pcoeffs,lint_qclist,detmon_lg_config.ref_level,
04685 detmon_lg_config.order));
04686
04687
04688 if (detmon_lg_config.exts >= 0) {
04689 cpl_msg_info(cpl_func, "Bad pixel detection");
04690 } else {
04691 cpl_msg_info(cpl_func, "Bad pixel detection"
04692 " for extension nb %d", which_ext);
04693 }
04694
04695 if(detmon_lg_config.pix2pix) {
04696 *bpms_ptr = irplib_detmon_bpixs(*coeffs_ptr, detmon_lg_config.bpmbin,
04697 detmon_lg_config.kappa, &nbpixs);
04698 skip_if(*bpms_ptr == NULL);
04699 }
04700
04701 skip_if(cpl_propertylist_append_int(bpm_qclist, DETMON_QC_NUM_BPM, nbpixs));
04702 skip_if(cpl_propertylist_set_comment(bpm_qclist, DETMON_QC_NUM_BPM,
04703 DETMON_QC_NUM_BPM_C));
04704
04705 if(detmon_lg_config.lamp_stability != 0.0) {
04706 skip_if(cpl_propertylist_append_double(lint_qclist, DETMON_QC_LAMP_STAB,
04707 detmon_lg_config.lamp_stability));
04708 skip_if(cpl_propertylist_set_comment(lint_qclist, DETMON_QC_LAMP_STAB,
04709 DETMON_QC_LAMP_STAB_C));
04710 }
04711
04712
04713 if (!detmon_lg_config.wholechip) {
04714 cpl_image * dummy_bpm = cpl_image_new(detmon_lg_config.nx,
04715 detmon_lg_config.ny,
04716 CPL_TYPE_INT);
04717 cpl_imagelist * dummy_coeffs = cpl_imagelist_new();
04718
04719 int * db_p = cpl_image_get_data_int(dummy_bpm);
04720 int * rb_p = cpl_image_get_data_int(*bpms_ptr);
04721
04722 float ** dcs_p =
04723 cpl_malloc(sizeof(float *) * (detmon_lg_config.order + 1));
04724
04725 float ** rcs_p =
04726 cpl_malloc(sizeof(float *) * (detmon_lg_config.order + 1));
04727
04728 int dlength = detmon_lg_config.nx;
04729 int rlength = detmon_lg_config.urx - detmon_lg_config.llx + 1;
04730
04731 for (i = 0; i <= detmon_lg_config.order; i++) {
04732 cpl_image * dummy_coeff = cpl_image_new(detmon_lg_config.nx,
04733 detmon_lg_config.ny,
04734 CPL_TYPE_FLOAT);
04735
04736 cpl_imagelist_set(dummy_coeffs, dummy_coeff, i);
04737
04738 dcs_p[i] = cpl_image_get_data_float(dummy_coeff);
04739 rcs_p[i] =
04740 cpl_image_get_data_float(cpl_imagelist_get(*coeffs_ptr, i));
04741 }
04742
04743 for (i = detmon_lg_config.lly - 1; i < detmon_lg_config.ury; i++) {
04744 for (j = detmon_lg_config.llx - 1; j < detmon_lg_config.urx; j++) {
04745
04746 *(db_p + i * dlength + j) =
04747 *(rb_p + (i - detmon_lg_config.lly + 1) * rlength +
04748 j - detmon_lg_config.llx + 1);
04749
04750 for (k = 0; k <= detmon_lg_config.order; k++) {
04751 *(dcs_p[k] + i * dlength + j) =
04752 *(rcs_p[k] + (i - detmon_lg_config.lly + 1) * rlength +
04753 j - detmon_lg_config.llx + 1);
04754 }
04755 }
04756 }
04757
04758 cpl_imagelist_delete(*coeffs_ptr);
04759 cpl_image_delete(*bpms_ptr);
04760 *coeffs_ptr = dummy_coeffs;
04761 *bpms_ptr = dummy_bpm;
04762
04763 cpl_free(dcs_p);
04764 cpl_free(rcs_p);
04765 }
04766
04767 end_skip;
04768
04769 cpl_free(pcoeffs);
04770 cpl_free(name_o1);
04771 cpl_free(name_o2);
04772 cpl_image_delete(fiterror);
04773 cpl_polynomial_delete(poly_linfit);
04774
04775 return cpl_error_get_code();
04776 }
04777
04778
04786
04787 static cpl_error_code
04788 irplib_detmon_lg_lineff(double * pcoeffs,
04789 cpl_propertylist * qclist,
04790 int ref_level,
04791 int order)
04792 {
04793 double lineff = 0;
04794 double root = 0;
04795 cpl_polynomial * poly = cpl_polynomial_new(1);
04796 int i;
04797
04798 double residual, slope;
04799
04800
04801
04802
04803
04804 pcoeffs[0] -= ref_level;
04805
04806 for (i = 2; i <= order; i++) {
04807 int j;
04808 for(j = 0; j < i; j++) {
04809 pcoeffs[i] /= pcoeffs[1];
04810 }
04811 }
04812
04813 pcoeffs[1] = 1;
04814
04815 for (i = 0; i <= order; i++) {
04816 skip_if(cpl_polynomial_set_coeff(poly, &i, pcoeffs[i]));
04817 }
04818
04819
04820
04821
04822
04823
04824
04825 residual = cpl_polynomial_eval_1d(poly, 0.0, &slope);
04826
04827 if (slope <= 0.0 && residual >= 0.0) {
04828 cpl_msg_warning(cpl_func, "Reference level (--ref_level) outside"
04829 " linearity range of the detector. Cannot compute"
04830 " linearity efficiency (QC.LINEFF).");
04831 lineff = -1;
04832 } else {
04833 skip_if(cpl_polynomial_solve_1d(poly, 0.0, &root, 1));
04834
04835 lineff = (root - ref_level) / ref_level;
04836 }
04837
04838 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LIN_EFF,
04839 lineff));
04840 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LIN_EFF,
04841 DETMON_QC_LIN_EFF_C));
04842
04843 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LIN_EFF_FLUX,
04844 ref_level));
04845 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LIN_EFF_FLUX,
04846 DETMON_QC_LIN_EFF_FLUX_C));
04847
04848 end_skip;
04849
04850 cpl_polynomial_delete(poly);
04851
04852 return cpl_error_get_code();
04853 }
04854
04855
04862
04863 static cpl_error_code
04864 irplib_detmon_lg_qc_ptc(const cpl_table * gain_table,
04865 cpl_propertylist * qclist, unsigned mode, int rows_in_gain)
04866 {
04867 double mse = 0;
04868 cpl_polynomial *poly_fit = NULL;
04869 cpl_polynomial *poly_fit2 = NULL;
04870 int i;
04871 const int nsets = rows_in_gain;
04872
04873
04874
04875
04876
04877 const cpl_vector *x;
04878 const cpl_vector *y;
04879
04880 cpl_errorstate prestate;
04881 double coef = 0;
04882
04883 cpl_ensure_code(gain_table != NULL, CPL_ERROR_NULL_INPUT);
04884 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
04885
04886 x = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT"));
04887
04888 y = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
04889
04890 skip_if(x == NULL || y == NULL);
04891
04892
04893 poly_fit = irplib_polynomial_fit_1d_create_chiq(x, y, 1, &mse);
04894 skip_if(poly_fit == NULL);
04895
04896
04897 i = 1;
04898 prestate = cpl_errorstate_get();
04899 coef = cpl_polynomial_get_coeff(poly_fit, &i);
04900 skip_if (!cpl_errorstate_is_equal(prestate) || coef == 0);
04901
04902 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD, coef));
04903 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
04904 DETMON_QC_CONAD_C));
04905
04906 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,
04907 1 / coef));
04908 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
04909 DETMON_QC_GAIN_C));
04910
04911
04912
04913
04914
04915 i = 0;
04916
04917
04918
04919
04920
04921
04922
04923
04924 if(mode & IRPLIB_GAIN_WITH_AUTOCORR){
04925 const cpl_vector *x2 =
04926 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT_CORR"));
04927 const cpl_vector *y2 =
04928 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
04929
04930 if(x2 == NULL || y2 == NULL) {
04931 cpl_vector_unwrap((cpl_vector *)x2);
04932 cpl_vector_unwrap((cpl_vector *)y2);
04933
04934
04935
04936
04937
04938
04939 skip_if(1);
04940 }
04941
04942
04943 poly_fit2 = irplib_polynomial_fit_1d_create(x2, y2, 1, &mse);
04944 if(poly_fit2 == NULL) {
04945 cpl_vector_unwrap((cpl_vector *)x2);
04946 cpl_vector_unwrap((cpl_vector *)y2);
04947
04948 cpl_msg_error(cpl_func, "Error during polynomial fit, err[%s]", cpl_error_get_where());
04949
04950 skip_if(1);
04951 }
04952 skip_if(cpl_error_get_code() != CPL_ERROR_NONE);
04953 cpl_vector_unwrap((cpl_vector *)x2);
04954 cpl_vector_unwrap((cpl_vector *)y2);
04955 skip_if(cpl_error_get_code() != CPL_ERROR_NONE);
04956
04957 i = 1;
04958 prestate = cpl_errorstate_get();
04959 coef = cpl_polynomial_get_coeff(poly_fit2, &i);
04960 skip_if(cpl_error_get_code() != CPL_ERROR_NONE);
04961 skip_if (!cpl_errorstate_is_equal(prestate) || coef == 0);
04962
04963 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD_CORR,
04964 coef));
04965 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD_CORR,
04966 DETMON_QC_CONAD_CORR_C));
04967
04968 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
04969 1 / coef));
04970 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
04971 DETMON_QC_GAIN_CORR_C));
04972 }
04973
04974 end_skip;
04975
04976
04977 cpl_vector_unwrap((cpl_vector *)x);
04978 cpl_vector_unwrap((cpl_vector *)y);
04979 cpl_polynomial_delete(poly_fit);
04980 cpl_polynomial_delete(poly_fit2);
04981
04982 return cpl_error_get_code();
04983 }
04984
04985
04994
04995 static cpl_error_code
04996 irplib_detmon_lg_qc_med(const cpl_table * gain_table,
04997 cpl_propertylist * qclist, int rows_in_gain)
04998 {
04999
05000 double gain=0;
05001 int q_STUB;
05002 q_STUB = rows_in_gain;
05003 gain=cpl_table_get_column_median(gain_table, "GAIN");
05004
05005 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,gain));
05006
05007 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
05008 DETMON_QC_GAIN_C));
05009
05010 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE,
05011 cpl_table_get_column_stdev
05012 (gain_table, "GAIN")));
05013 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
05014 DETMON_QC_GAIN_MSE_C));
05015
05016 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD,1./gain));
05017 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
05018 DETMON_QC_CONAD_C));
05019
05020
05021 gain=cpl_table_get_column_median(gain_table, "GAIN_CORR");
05022
05023 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
05024 gain));
05025 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
05026 DETMON_QC_GAIN_CORR_C));
05027
05028
05029 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD_CORR,1./gain));
05030 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD_CORR,
05031 DETMON_QC_CONAD_CORR_C));
05032
05033
05034 end_skip;
05035
05036 return cpl_error_get_code();
05037 }
05038
05039
05040
05049
05050 static cpl_error_code
05051 irplib_detmon_lg_rescale(cpl_imagelist * to_rescale)
05052 {
05053 double med1 =
05054 cpl_image_get_median(cpl_imagelist_get(to_rescale, 0));
05055 double med2 =
05056 cpl_image_get_median(cpl_imagelist_get(to_rescale, 1));
05057
05058 skip_if(0);
05059
05060 if(fabs(med1 / med2 - 1) > 0.001) {
05061 if(med1 > med2)
05062 skip_if(cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 0),
05063 med1 / med2));
05064 else
05065 skip_if(cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 1),
05066 med2 / med1));
05067 }
05068
05069 end_skip;
05070
05071 return cpl_error_get_code();
05072 }
05073
05074 static cpl_error_code
05075 irplib_detmon_pair_extract_next(const cpl_frameset * set,
05076 int* iindex,
05077 int* next_element,
05078 double* dit_array,
05079
05080
05081 cpl_frameset ** pair,
05082 double tolerance)
05083 {
05084 double dit = -100;
05085 double dit_next = -100;
05086 int* selection;
05087 int nsets_extracted = 0;
05088 cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
05089 cpl_ensure_code(dit_array != NULL, CPL_ERROR_NULL_INPUT);
05090 cpl_ensure_code(iindex != NULL, CPL_ERROR_NULL_INPUT);
05091 cpl_ensure_code(pair != NULL, CPL_ERROR_NULL_INPUT);
05092
05093 nsets_extracted = cpl_frameset_get_size(set);
05094 selection = cpl_malloc(sizeof(int) * nsets_extracted);
05095 memset(&selection[0], 0, sizeof(int) * nsets_extracted);
05096
05097
05098 dit = dit_array[*next_element ];
05099
05100 if (*next_element < nsets_extracted - 1)
05101 {
05102 dit_next = dit_array[*next_element + 1 ];
05103
05104 }
05105
05106 selection[iindex[*next_element] ] = 1;
05107 if (fabs(dit - dit_next) < tolerance)
05108 {
05109
05110 selection[iindex[*next_element + 1] ] = 1;
05111 (*next_element)++;
05112 }
05113 else
05114 {
05115 cpl_msg_warning(cpl_func, "DIT for the second frame in the pair is above tolerance level - could not be taken, dit1[%f] dit2[%f] next_element: %d ", dit, dit_next, *next_element);
05116 }
05117 (*next_element)++;
05118
05119 cpl_frameset_delete(*pair);
05120 *pair = cpl_frameset_extract(set, selection, 1);
05121
05122
05123 cpl_free(selection);
05124 return cpl_error_get_code();
05125 }
05126 static cpl_error_code
05127 irplib_detmon_single_extract_next(const cpl_frameset * set,
05128 int* iindex,
05129 int* next_element,
05130 double* dit_array,
05131 cpl_frameset ** pair)
05132 {
05133 double dit = -100;
05134 int* selection;
05135 int nsets_extracted = 0;
05136 cpl_ensure_code(set != NULL, CPL_ERROR_NULL_INPUT);
05137 cpl_ensure_code(dit_array != NULL, CPL_ERROR_NULL_INPUT);
05138 cpl_ensure_code(iindex != NULL, CPL_ERROR_NULL_INPUT);
05139 cpl_ensure_code(pair != NULL, CPL_ERROR_NULL_INPUT);
05140
05141 nsets_extracted = cpl_frameset_get_size(set);
05142 selection = cpl_malloc(sizeof(int) * nsets_extracted);
05143 memset(&selection[0], 0, sizeof(int) * nsets_extracted);
05144
05145 nsets_extracted = cpl_frameset_get_size(set);
05146 dit = dit_array[iindex[*next_element] ];
05147
05148 selection[iindex[*next_element] ] = 1;
05149 (*next_element)++;
05150
05151 cpl_frameset_delete(*pair);
05152 *pair = cpl_frameset_extract(set, selection, 1);
05153
05154 cpl_free(selection);
05155 return cpl_error_get_code();
05156 }
05157
05158
05159
05248
05249
05250 cpl_table *
05251 irplib_detmon_gain(const cpl_imagelist * imlist_on,
05252 const cpl_imagelist * imlist_off,
05253 const cpl_vector * exptimes,
05254 const cpl_vector * ndit,
05255 double tolerance,
05256 int llx,
05257 int lly,
05258 int urx,
05259 int ury,
05260 double kappa,
05261 int nclip,
05262 int xshift,
05263 int yshift,
05264 cpl_propertylist * qclist,
05265 unsigned mode,
05266 cpl_imagelist ** diff_imlist,
05267 cpl_imagelist ** autocorr_imlist)
05268 {
05269 cpl_table * gain_table = NULL;
05270 cpl_imagelist * difflist = NULL;
05271 cpl_imagelist * autocorrlist = NULL;
05272 cpl_imagelist * c_onlist = NULL;
05273 cpl_imagelist * c_offlist = NULL;
05274 cpl_vector * diffdits = NULL;
05275 cpl_vector * diffndits = NULL;
05276 int rows_in_gain = 0;
05277 int ndiffdits, ndits;
05278 int i, j;
05279 cpl_boolean opt_nir = mode & IRPLIB_GAIN_OPT ? OPT : NIR;
05280 const char * method = mode & IRPLIB_GAIN_PTC ? "PTC" : "MED";
05281
05282 cpl_ensure(imlist_on != NULL, CPL_ERROR_NULL_INPUT, NULL);
05283 cpl_ensure(imlist_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
05284 cpl_ensure(exptimes != NULL, CPL_ERROR_NULL_INPUT, NULL);
05285 cpl_ensure(qclist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05286
05287
05288 gain_table = cpl_table_new(cpl_vector_get_size(exptimes) / 2);
05289 skip_if(irplib_detmon_gain_table_create(gain_table, opt_nir));
05290
05291
05292
05293 skip_if(irplib_detmon_lg_find_dits_ndits(exptimes, ndit,tolerance,&diffdits,&diffndits));
05294 ndiffdits = cpl_vector_get_size(diffdits);
05295
05296 ndits = cpl_vector_get_size(exptimes);
05297
05298
05299 if (mode & IRPLIB_GAIN_WITH_AUTOCORR && (diff_imlist || autocorr_imlist)) {
05300 difflist = cpl_imagelist_new();
05301 autocorrlist = cpl_imagelist_new();
05302 }
05303
05304 if (mode & IRPLIB_GAIN_COLLAPSE) {
05305 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
05306 c_offlist = cpl_imagelist_duplicate(imlist_off);
05307 skip_if(irplib_detmon_lg_rescale(c_offlist));
05308 } else {
05309 c_offlist = (cpl_imagelist *) imlist_off;
05310 }
05311 }
05312
05313
05314 for (i = 0; i < ndiffdits; i++) {
05315 int c_nons;
05316 int c_noffs = 0;
05317
05318 double c_dit = 0;
05319 int c_ndit = 1;
05320
05321 c_dit=cpl_vector_get(diffdits, i);
05322
05323 if(opt_nir) {
05324 c_ndit=(int)cpl_vector_get(diffndits, i);
05325 }
05326
05327 c_onlist = cpl_imagelist_new();
05328 c_nons = 0;
05329
05330 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
05331 c_offlist = cpl_imagelist_new();
05332 c_noffs = 0;
05333 }
05334
05335
05336 for(j = 0; j < ndits; j++) {
05337 if (fabs(c_dit - cpl_vector_get(exptimes, j)) <= tolerance) {
05338
05339
05340
05341
05342
05343
05344
05345
05346 cpl_image * im_on;
05347 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
05348 const cpl_image * im =
05349 cpl_imagelist_get_const(imlist_on, j);
05350 im_on = cpl_image_duplicate(im);
05351 } else {
05352 im_on = (cpl_image *)cpl_imagelist_get_const(imlist_on, j);
05353 }
05354 skip_if(cpl_imagelist_set(c_onlist, im_on, c_nons));
05355 c_nons++;
05356
05357
05358
05359
05360
05361 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
05362 cpl_image * im_off;
05363 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
05364 const cpl_image * im =
05365 cpl_imagelist_get_const(imlist_off, j);
05366 im_off = cpl_image_duplicate(im);
05367 } else {
05368 im_off =
05369 (cpl_image *) cpl_imagelist_get_const(imlist_off, j);
05370 }
05371 skip_if(cpl_imagelist_set(c_offlist, im_off, c_noffs));
05372 c_noffs++;
05373 }
05374 }
05375 }
05376
05377
05378 if (mode & IRPLIB_GAIN_NO_COLLAPSE)
05379 skip_if (c_nons != c_noffs);
05380
05381
05382 skip_if (c_nons == 0 || c_nons % 2 != 0);
05383
05384
05385 if(mode & IRPLIB_GAIN_WITH_RESCALE) {
05386 skip_if(irplib_detmon_lg_rescale(c_onlist));
05387 if (mode & IRPLIB_GAIN_NO_COLLAPSE)
05388 skip_if(irplib_detmon_lg_rescale(c_offlist));
05389 }
05390
05391
05392
05393 while(c_nons > 0) {
05394 int rows_affected = 1;
05395 skip_if(irplib_detmon_gain_table_fill_row(gain_table,
05396 c_dit,c_ndit,
05397 autocorrlist,
05398 difflist, c_onlist,
05399 c_offlist, kappa, nclip,
05400 llx, lly, urx, ury,
05401 xshift, yshift,1E10, i,
05402 mode, &rows_affected));
05403 if (rows_affected)
05404 {
05405 rows_in_gain++;
05406 }
05407 if (mode & IRPLIB_GAIN_WITH_RESCALE) {
05408 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05409 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05410 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
05411 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05412 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05413 }
05414 } else {
05415 cpl_imagelist_unset(c_onlist, 0);
05416 skip_if(0);
05417 cpl_imagelist_unset(c_onlist, 0);
05418 skip_if(0);
05419 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
05420 cpl_imagelist_unset(c_offlist, 0);
05421 skip_if(0);
05422 cpl_imagelist_unset(c_offlist, 0);
05423 skip_if(0);
05424 }
05425 }
05426 skip_if(0);
05427 c_nons -= 2;
05428 }
05429
05430 cpl_imagelist_delete(c_onlist);
05431 if (mode & IRPLIB_GAIN_NO_COLLAPSE) {
05432 cpl_imagelist_delete(c_offlist);
05433 }
05434 }
05435
05436 skip_if(cpl_propertylist_append_string(qclist, DETMON_QC_METHOD, method));
05437 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_METHOD,
05438 DETMON_QC_METHOD_C));
05439
05440
05441 if (mode & IRPLIB_GAIN_PTC) {
05442 skip_if(irplib_detmon_lg_qc_ptc(gain_table, qclist, mode, rows_in_gain));
05443 } else {
05444 skip_if(irplib_detmon_lg_qc_med(gain_table, qclist, rows_in_gain));
05445 }
05446
05447 if(mode & IRPLIB_GAIN_WITH_AUTOCORR) {
05448 double autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
05449 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_AUTOCORR,
05450 autocorr));
05451 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_AUTOCORR,
05452 DETMON_QC_AUTOCORR_C));
05453 }
05454
05455 if (diff_imlist != NULL) *diff_imlist = difflist;
05456 if (autocorr_imlist != NULL) *autocorr_imlist = autocorrlist;
05457
05458 end_skip;
05459
05460 cpl_vector_delete(diffdits);
05461 cpl_vector_delete(diffndits);
05462
05463 return gain_table;
05464 }
05465
05466 static cpl_error_code
05467 irplib_detmon_gain_table_create(cpl_table * gain_table,
05468 const cpl_boolean opt_nir)
05469 {
05470 if (opt_nir == NIR) {
05471 skip_if(cpl_table_new_column(gain_table, "DIT", CPL_TYPE_DOUBLE));
05472 skip_if(cpl_table_new_column(gain_table, "NDIT", CPL_TYPE_INT));
05473 } else {
05474 skip_if(cpl_table_new_column(gain_table, "EXPTIME", CPL_TYPE_DOUBLE));
05475 }
05476 skip_if(cpl_table_new_column(gain_table, "MEAN_ON1", CPL_TYPE_DOUBLE));
05477 skip_if(cpl_table_new_column(gain_table, "MEAN_ON2", CPL_TYPE_DOUBLE));
05478 skip_if(cpl_table_new_column(gain_table, "MEAN_OFF1", CPL_TYPE_DOUBLE));
05479 skip_if(cpl_table_new_column(gain_table, "MEAN_OFF2", CPL_TYPE_DOUBLE));
05480 skip_if(cpl_table_new_column(gain_table, "SIG_ON_DIF", CPL_TYPE_DOUBLE));
05481 skip_if(cpl_table_new_column(gain_table, "SIG_OFF_DIF", CPL_TYPE_DOUBLE));
05482 skip_if(cpl_table_new_column(gain_table, "GAIN", CPL_TYPE_DOUBLE));
05483 skip_if(cpl_table_new_column(gain_table, "AUTOCORR", CPL_TYPE_DOUBLE));
05484 skip_if(cpl_table_new_column(gain_table, "GAIN_CORR", CPL_TYPE_DOUBLE));
05485 skip_if(cpl_table_new_column(gain_table, "ADU", CPL_TYPE_DOUBLE));
05486 skip_if(cpl_table_new_column(gain_table, "X_FIT", CPL_TYPE_DOUBLE));
05487 skip_if(cpl_table_new_column(gain_table, "X_FIT_CORR", CPL_TYPE_DOUBLE));
05488 skip_if(cpl_table_new_column(gain_table, "Y_FIT", CPL_TYPE_DOUBLE));
05489 skip_if(cpl_table_new_column(gain_table, "Y_FIT_CORR", CPL_TYPE_DOUBLE));
05490 skip_if(cpl_table_new_column(gain_table, "FLAG", CPL_TYPE_INT));
05491
05492 end_skip;
05493
05494 return cpl_error_get_code();
05495 }
05496
05497 static cpl_error_code
05498 irplib_detmon_lin_table_create(cpl_table * lin_table,
05499 const cpl_boolean opt_nir)
05500 {
05501 if (opt_nir == NIR) {
05502 skip_if(cpl_table_new_column(lin_table, "DIT", CPL_TYPE_DOUBLE));
05503 } else {
05504 skip_if(cpl_table_new_column(lin_table, "EXPTIME", CPL_TYPE_DOUBLE));
05505 }
05506 skip_if(cpl_table_new_column(lin_table, "MED", CPL_TYPE_DOUBLE));
05507 skip_if(cpl_table_new_column(lin_table, "MEAN", CPL_TYPE_DOUBLE));
05508 skip_if(cpl_table_new_column(lin_table, "MED_DIT", CPL_TYPE_DOUBLE));
05509 skip_if(cpl_table_new_column(lin_table, "MEAN_DIT", CPL_TYPE_DOUBLE));
05510 skip_if(cpl_table_new_column(lin_table, "ADL", CPL_TYPE_DOUBLE));
05511 end_skip;
05512
05513 return cpl_error_get_code();
05514 }
05515
05516 static cpl_vector *
05517 irplib_detmon_lg_find_dits(const cpl_vector * exptimes,
05518 double tolerance)
05519 {
05520 cpl_vector * dits = cpl_vector_new(cpl_vector_get_size(exptimes) / 2);
05521 int ndits = 0;
05522
05523 int i, j;
05524
05525
05526 cpl_vector_set(dits, 0, cpl_vector_get(exptimes, 0));
05527 ndits = 1;
05528
05529
05530 for(i = 1; i < cpl_vector_get_size(exptimes); i++) {
05531 int ndiffs = 0;
05532 for (j = 0; j < ndits; j++) {
05533 if (fabs(cpl_vector_get(exptimes, i) -
05534 cpl_vector_get(dits, j)) > tolerance)
05535 ndiffs++;
05536 }
05537 if(ndiffs == ndits) {
05538 cpl_vector_set(dits, ndits, cpl_vector_get(exptimes, i));
05539 ndits++;
05540 }
05541 }
05542
05543 cpl_vector_set_size(dits, ndits);
05544
05545 return dits;
05546 }
05547
05548
05549
05550
05551 static cpl_error_code
05552 irplib_detmon_lg_find_dits_ndits(const cpl_vector * exptimes,
05553 const cpl_vector * vec_ndits,
05554 double tolerance,
05555 cpl_vector** diff_dits,
05556 cpl_vector** diff_ndits)
05557 {
05558 int ndits = 0;
05559
05560 int i, j;
05561 int size=0;
05562
05563
05564 * diff_dits = cpl_vector_new(cpl_vector_get_size(exptimes) / 2);
05565 * diff_ndits = cpl_vector_new(cpl_vector_get_size(*diff_dits));
05566
05567
05568 cpl_vector_set(*diff_dits, 0, cpl_vector_get(exptimes, 0));
05569 cpl_vector_set(*diff_ndits, 0, cpl_vector_get(vec_ndits, 0));
05570
05571 ndits = 1;
05572 size=cpl_vector_get_size(exptimes);
05573
05574 for(i = 1; i < size; i++) {
05575 int ndiffs = 0;
05576 for (j = 0; j < ndits; j++) {
05577 if (fabs(cpl_vector_get(exptimes, i) -
05578 cpl_vector_get(*diff_dits,j)) > tolerance)
05579 ndiffs++;
05580 }
05581 if(ndiffs == ndits) {
05582 cpl_vector_set(*diff_dits, ndits, cpl_vector_get(exptimes, i));
05583 cpl_vector_set(*diff_ndits, ndits, cpl_vector_get(vec_ndits, i));
05584 ndits++;
05585 }
05586 }
05587
05588 cpl_vector_set_size(*diff_dits, ndits);
05589 cpl_vector_set_size(*diff_ndits, ndits);
05590
05591
05592 return cpl_error_get_code();
05593 }
05594
05595
05596
05677
05678
05679 cpl_table *
05680 irplib_detmon_lin(const cpl_imagelist * imlist_on,
05681 const cpl_imagelist * imlist_off,
05682 const cpl_vector * exptimes,
05683 double tolerance,
05684 int llx,
05685 int lly,
05686 int urx,
05687 int ury,
05688 int order,
05689 int ref_level,
05690 double kappa,
05691 cpl_boolean bpmbin,
05692 cpl_propertylist * qclist,
05693 unsigned mode,
05694 cpl_imagelist ** coeffs_cube,
05695 cpl_image ** bpm)
05696 {
05697 cpl_table * lin_table = NULL;
05698 cpl_imagelist * c_onlist = NULL;
05699 cpl_imagelist * c_offlist = NULL;
05700 cpl_vector * diffdits = NULL;
05701 cpl_imagelist * lin_inputs = NULL;
05702 cpl_polynomial * poly_linfit = NULL;
05703 cpl_image * fiterror = NULL;
05704 cpl_vector * vcoeffs = NULL;
05705 double * pcoeffs = NULL;
05706 int ndiffdits, ndits;
05707 int i, j;
05708 cpl_boolean opt_nir = mode & IRPLIB_LIN_OPT ? OPT : NIR;
05709 const cpl_vector *x = NULL;
05710 const cpl_vector *y = NULL;
05711
05712 const cpl_image * first = NULL;
05713 int sizex = 0;
05714 int sizey = 0;
05715
05716 double vsize = 0;
05717
05718
05719 cpl_ensure(imlist_on != NULL, CPL_ERROR_NULL_INPUT, NULL);
05720 cpl_ensure(imlist_off != NULL, CPL_ERROR_NULL_INPUT, NULL);
05721 cpl_ensure(exptimes != NULL, CPL_ERROR_NULL_INPUT, NULL);
05722 cpl_ensure(qclist != NULL, CPL_ERROR_NULL_INPUT, NULL);
05723 cpl_ensure(order > 0 , CPL_ERROR_ILLEGAL_INPUT, NULL);
05724
05725 vcoeffs = cpl_vector_new(order + 1);
05726 pcoeffs = cpl_vector_get_data(vcoeffs);
05727
05728
05729 if (mode & IRPLIB_LIN_PIX2PIX) {
05730 lin_inputs = cpl_imagelist_new();
05731 cpl_ensure(coeffs_cube != NULL, CPL_ERROR_NULL_INPUT, NULL);
05732 cpl_ensure(bpm != NULL, CPL_ERROR_NULL_INPUT, NULL);
05733 }
05734
05735
05736 lin_table = cpl_table_new(cpl_vector_get_size(exptimes) / 2);
05737 skip_if(irplib_detmon_lin_table_create(lin_table, opt_nir));
05738
05739
05740
05741 diffdits = irplib_detmon_lg_find_dits(exptimes, tolerance);
05742 ndiffdits = cpl_vector_get_size(diffdits);
05743
05744 ndits = cpl_vector_get_size(exptimes);
05745
05746
05747
05748
05749
05750
05751
05752
05753
05754
05755
05756
05757
05758
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768
05769
05770
05771
05772
05773
05774 if (mode & IRPLIB_LIN_COLLAPSE) {
05775
05776
05777
05778
05779 cpl_image * collapse = cpl_imagelist_collapse_create(imlist_off);
05780 skip_if(collapse == NULL);
05781
05782 c_offlist = cpl_imagelist_new();
05783 skip_if(cpl_imagelist_set(c_offlist, collapse, 0));
05784 }
05785
05786
05787 for (i = 0; i < ndiffdits; i++) {
05788 int c_nons;
05789 int c_noffs = 0;
05790
05791 double c_dit = cpl_vector_get(diffdits, i);
05792
05793 c_onlist = cpl_imagelist_new();
05794 c_nons = 0;
05795
05796 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05797 c_offlist = cpl_imagelist_new();
05798 c_noffs = 0;
05799 }
05800
05801 for(j = 0; j < ndits; j++) {
05802 if (fabs(c_dit - cpl_vector_get(exptimes, j)) <= tolerance) {
05803
05804
05805
05806
05807
05808
05809
05810
05811 cpl_image * im_on;
05812 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05813 const cpl_image * im =
05814 cpl_imagelist_get_const(imlist_on, j);
05815 im_on = cpl_image_duplicate(im);
05816 } else {
05817 im_on = (cpl_image *)cpl_imagelist_get_const(imlist_on, j);
05818 }
05819 skip_if(cpl_imagelist_set(c_onlist, im_on, c_nons));
05820 c_nons++;
05821
05822
05823
05824
05825
05826 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05827 cpl_image * im_off;
05828 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05829 const cpl_image * im =
05830 cpl_imagelist_get_const(imlist_off, j);
05831 im_off = cpl_image_duplicate(im);
05832 } else {
05833 im_off =
05834 (cpl_image *) cpl_imagelist_get_const(imlist_off, j);
05835 }
05836 skip_if(cpl_imagelist_set(c_offlist, im_off, c_noffs));
05837 c_noffs++;
05838 }
05839 }
05840 }
05841
05842
05843 if (mode & IRPLIB_LIN_NO_COLLAPSE)
05844 skip_if (c_nons != c_noffs);
05845
05846
05847 skip_if (c_nons == 0 || c_nons % 2 != 0);
05848
05849
05850 if(mode & IRPLIB_LIN_WITH_RESCALE) {
05851 skip_if(irplib_detmon_lg_rescale(c_onlist));
05852 if (mode & IRPLIB_LIN_NO_COLLAPSE)
05853 skip_if(irplib_detmon_lg_rescale(c_offlist));
05854 }
05855
05856
05857
05858 while(c_nons > 0) {
05859
05860 skip_if(irplib_detmon_lin_table_fill_row(lin_table, c_dit,
05861 lin_inputs,
05862 c_onlist, c_offlist,
05863 llx, lly, urx, ury,
05864 i, 0, mode));
05865
05866 if (mode & IRPLIB_LIN_WITH_RESCALE) {
05867 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05868 cpl_image_delete(cpl_imagelist_unset(c_onlist, 0));
05869 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05870 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05871 cpl_image_delete(cpl_imagelist_unset(c_offlist, 0));
05872 }
05873 } else {
05874 cpl_imagelist_unset(c_onlist, 0);
05875 skip_if(0);
05876 cpl_imagelist_unset(c_onlist, 0);
05877 skip_if(0);
05878 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05879 cpl_imagelist_unset(c_offlist, 0);
05880 skip_if(0);
05881 cpl_imagelist_unset(c_offlist, 0);
05882 skip_if(0);
05883 }
05884 }
05885 skip_if(0);
05886 c_nons -= 2;
05887 }
05888
05889 cpl_imagelist_delete(c_onlist);
05890 if (mode & IRPLIB_LIN_NO_COLLAPSE) {
05891 cpl_imagelist_delete(c_offlist);
05892 }
05893 }
05894
05895 skip_if(irplib_detmon_add_adl_column(lin_table, opt_nir));
05896
05897 if(!(mode & IRPLIB_LIN_PIX2PIX)) {
05898 double mse = 0;
05899
05900 y = cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05901 (double *)cpl_table_get_data_double_const(lin_table,
05902 "MED"));
05903 if (opt_nir == NIR) {
05904 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05905 (double *)cpl_table_get_data_double_const(lin_table, "DIT"));
05906 } else {
05907 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05908 (double *)cpl_table_get_data_double_const(lin_table, "EXPTIME"));
05909 }
05910 if(x == NULL || y == NULL) {
05911 cpl_vector_unwrap((cpl_vector *)x);
05912 cpl_vector_unwrap((cpl_vector *)y);
05913
05914
05915
05916
05917
05918
05919 skip_if(1);
05920 }
05921
05922 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
05923 poly_linfit = irplib_polynomial_fit_1d_create_chiq(x, y, order, &mse);
05924
05925 if(order == cpl_vector_get_size(x) - 1) {
05926 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
05927 mse = 0;
05928 }
05929
05930 if(poly_linfit == NULL) {
05931 cpl_vector_unwrap((cpl_vector *)x);
05932 cpl_vector_unwrap((cpl_vector *)y);
05933
05934 skip_if(1);
05935 }
05936
05937 cpl_vector_unwrap((cpl_vector *)x);
05938 cpl_vector_unwrap((cpl_vector *)y);
05939
05940 for(i = 0; i <= order; i++) {
05941 const double coeff =
05942 cpl_polynomial_get_coeff(poly_linfit, &i);
05943 char *name_o =
05944 cpl_sprintf("ESO QC LIN COEF%d", i);
05945 assert(name_o != NULL);
05946 skip_if(cpl_propertylist_append_double(qclist, name_o, coeff));
05947 skip_if(cpl_propertylist_set_comment(qclist,name_o,
05948 DETMON_QC_LIN_COEF_C));
05949 cpl_free(name_o);
05950 pcoeffs[i] = coeff;
05951 }
05952 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT, mse));
05953 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
05954 DETMON_QC_ERRFIT_MSE_C));
05955
05956
05957 } else {
05958 if (opt_nir == NIR) {
05959 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05960 (double *)cpl_table_get_data_double_const(lin_table,
05961 "DIT"));
05962 } else {
05963 x=cpl_vector_wrap(cpl_table_get_nrow(lin_table),
05964 (double *)cpl_table_get_data_double_const(lin_table,
05965 "EXPTIME"));
05966 }
05967
05968
05969 first = cpl_imagelist_get_const(lin_inputs, 0);
05970 sizex = cpl_image_get_size_x(first);
05971 sizey = cpl_image_get_size_y(first);
05972
05973 vsize = cpl_vector_get_size(x);
05974
05975 fiterror = cpl_image_new(sizex, sizey, CPL_TYPE_FLOAT);
05976
05977 *coeffs_cube =
05978 cpl_fit_imagelist_polynomial(x, lin_inputs, 0,
05979 order, FALSE, CPL_TYPE_FLOAT,
05980 fiterror);
05981
05982 cpl_vector_unwrap((cpl_vector*)x);
05983 irplib_ensure(*coeffs_cube != NULL, CPL_ERROR_UNSPECIFIED,
05984 "Failed polynomial fit");
05985
05986 for(i = 0; i <= order; i++) {
05987 cpl_image *image = cpl_imagelist_get(*coeffs_cube, i);
05988 const double coeff = cpl_image_get_median(image);
05989 char * name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
05990 char * name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
05991 pcoeffs[i] = coeff;
05992 assert(name_o1 != NULL);
05993 assert(name_o2 != NULL);
05994 skip_if(cpl_propertylist_append_double(qclist, name_o1, coeff));
05995 skip_if(cpl_propertylist_set_comment(qclist,name_o1,
05996 DETMON_QC_LIN_COEF_C));
05997 cpl_free(name_o1);
05998 name_o1= NULL;
05999 skip_if(cpl_propertylist_append_double(qclist, name_o2,
06000 cpl_image_get_stdev(image)));
06001 skip_if(cpl_propertylist_set_comment(qclist,name_o2,
06002 DETMON_QC_LIN_COEF_ERR_C));
06003 cpl_free(name_o2);
06004 name_o2= NULL;
06005 }
06006
06007 if(order == vsize - 1) {
06008 cpl_msg_warning(cpl_func, "The fitting is not over-determined.");
06009 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
06010 0.0));
06011 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
06012 DETMON_QC_ERRFIT_C));
06013
06014
06015 } else {
06016 skip_if(cpl_propertylist_append_double(qclist,DETMON_QC_ERRFIT,
06017 cpl_image_get_median(fiterror)));
06018 skip_if(cpl_propertylist_set_comment(qclist,DETMON_QC_ERRFIT,
06019 DETMON_QC_ERRFIT_C));
06020
06021 }
06022 }
06023
06024 skip_if(irplib_detmon_lg_lineff(pcoeffs, qclist, ref_level, order));
06025
06026 if(mode & IRPLIB_LIN_PIX2PIX) {
06027 int nbpixs;
06028 *bpm = irplib_detmon_bpixs(*coeffs_cube, bpmbin, kappa, &nbpixs);
06029 skip_if(*bpm == NULL);
06030 skip_if(cpl_propertylist_append_int(qclist, DETMON_QC_NUM_BPM,
06031 nbpixs));
06032 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_NUM_BPM,
06033 DETMON_QC_NUM_BPM_C));
06034 }
06035
06036 end_skip;
06037
06038 cpl_vector_delete(diffdits);
06039 cpl_polynomial_delete(poly_linfit);
06040 cpl_imagelist_delete(lin_inputs);
06041 cpl_vector_delete(vcoeffs);
06042 cpl_image_delete(fiterror);
06043
06044 return lin_table;
06045
06046 }
06047
06048
06072
06073 static cpl_error_code
06074 irplib_detmon_lin_table_fill_row(cpl_table * lin_table, double c_dit,
06075 cpl_imagelist * linearity_inputs,
06076 const cpl_imagelist * ons,
06077 const cpl_imagelist * offs,
06078 int llx,
06079 int lly,
06080 int urx,
06081 int ury,
06082 const int pos,
06083 const int nskip,
06084 unsigned mode)
06085 {
06086 cpl_image * dif1=NULL;
06087 cpl_image * dif2=NULL;
06088 cpl_image * dif_avg=NULL;
06089
06090 double med_dit=0;
06091 double mean_dit=0;
06092 cpl_error_code error;
06093 cpl_image * extracted=NULL;
06094 int offsize=0;
06095
06096 cpl_ensure_code(lin_table != NULL, CPL_ERROR_NULL_INPUT);
06097 cpl_ensure_code(ons != NULL, CPL_ERROR_NULL_INPUT);
06098 cpl_ensure_code(offs != NULL, CPL_ERROR_NULL_INPUT);
06099
06100 if (mode & IRPLIB_LIN_PIX2PIX) {
06101 cpl_msg_debug(cpl_func,"checking linearity inputs");
06102 cpl_ensure_code(linearity_inputs != NULL, CPL_ERROR_NULL_INPUT);
06103 }
06104
06105
06106 if (mode & IRPLIB_LIN_NIR) {
06107 cpl_table_set(lin_table, "DIT", pos, c_dit);
06108 } else if (mode & IRPLIB_LIN_OPT) {
06109 cpl_table_set(lin_table, "EXPTIME", pos, c_dit);
06110 } else {
06111 cpl_msg_error(cpl_func, "Mandatory mode not given");
06112 }
06113
06114 offsize = cpl_imagelist_get_size(offs);
06115
06116
06117 dif1 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
06118 cpl_imagelist_get_const(offs, 0));
06119
06120 if (mode & IRPLIB_LIN_NO_COLLAPSE && offsize > 1)
06121 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
06122 cpl_imagelist_get_const(offs, 1));
06123 else
06124 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons, 1),
06125 cpl_imagelist_get_const(offs, 0));
06126
06127 dif_avg = cpl_image_average_create(dif1, dif2);
06128
06129 cpl_image_abs(dif_avg);
06130 extracted = cpl_image_extract(dif_avg, llx, lly, urx, ury);
06131
06132 cpl_ensure_code(extracted != NULL, cpl_error_get_code());
06133
06134 cpl_table_set(lin_table, "MED", pos, cpl_image_get_median(extracted));
06135 cpl_table_set(lin_table, "MEAN", pos, cpl_image_get_mean(extracted));
06136 med_dit = cpl_image_get_median(extracted) / c_dit;
06137 mean_dit = cpl_image_get_mean(extracted) / c_dit;
06138
06139 cpl_table_set(lin_table, "MED_DIT", pos, med_dit);
06140 cpl_table_set(lin_table, "MEAN_DIT", pos, mean_dit);
06141
06142 cpl_image_delete(dif1);
06143 cpl_image_delete(dif2);
06144
06145
06146 if(mode & IRPLIB_LIN_PIX2PIX) {
06147 error = cpl_imagelist_set(linearity_inputs, extracted, pos-nskip);
06148 cpl_ensure_code(!error, error);
06149 } else {
06150 cpl_image_delete(extracted);
06151 }
06152
06153
06154 cpl_image_delete(dif_avg);
06155
06156 return cpl_error_get_code();
06157 }
06158
06159 static double irplib_calculate_total_noise_smooth(const cpl_image* pimage, int pattern_x, int pattern_y)
06160 {
06161 cpl_image * p_tmp_image = 0;
06162 cpl_image * psmooth_image = 0;
06163 double ret_noise = -1;
06164 cpl_mask * mask = cpl_mask_new(pattern_x, pattern_y);
06165 cpl_mask_not(mask);
06166 p_tmp_image = cpl_image_duplicate(pimage);
06167 cpl_image_filter_mask(p_tmp_image,pimage, mask,CPL_FILTER_MEDIAN ,CPL_BORDER_FILTER);
06168 cpl_image_divide_scalar(p_tmp_image, cpl_image_get_median(pimage));
06169 psmooth_image = cpl_image_divide_create(pimage,p_tmp_image);
06170 ret_noise = irplib_calculate_total_noise(psmooth_image);
06171 cpl_mask_delete(mask);
06172 cpl_image_delete(psmooth_image);
06173 cpl_image_delete(p_tmp_image);
06174 return ret_noise;
06175 }
06176 static double irplib_calculate_total_noise(const cpl_image* pimage)
06177 {
06178 double total_noise = -1;
06179 unsigned long max_bin_size = 1E5;
06180 const double hstart = cpl_image_get_min(pimage);
06181 const double hrange = cpl_image_get_max(pimage) - hstart;
06182 const unsigned long nbins = max_bin_size;
06183 cpl_error_code err = CPL_ERROR_NONE;
06184
06185 irplib_hist * phist = 0;
06186 phist = irplib_hist_new();
06187
06188
06189 irplib_hist_init(phist, nbins, hstart, hrange);
06190 err = irplib_hist_fill(phist, pimage);
06191 if (err == CPL_ERROR_NONE)
06192 {
06193 unsigned int i = 0;
06194 double x0 = 0;
06195 double area = 0;
06196 double offset = 0;
06197
06198
06199 unsigned long n_bins = irplib_hist_get_nbins(phist);
06200 double start = irplib_hist_get_start(phist);
06201 double bin_size = irplib_hist_get_bin_size(phist);
06202 cpl_vector* pdata_vector = cpl_vector_new(n_bins);
06203 cpl_vector* ppos_vector = cpl_vector_new(n_bins);
06204 cpl_table* ptable = cpl_table_new(n_bins);
06205 cpl_table_new_column(ptable, "bin", CPL_TYPE_DOUBLE);
06206 cpl_table_new_column(ptable, "value", CPL_TYPE_DOUBLE);
06207 for(i = 0; i < n_bins; i++)
06208 {
06209 unsigned int value = irplib_hist_get_value(phist, i);
06210 double dvalue = (double)(value);
06211 cpl_vector_set(pdata_vector, i, dvalue);
06212 cpl_vector_set(ppos_vector, i, start + i * bin_size);
06213
06214 cpl_table_set(ptable, "bin", i, start + i * bin_size);
06215 cpl_table_set(ptable, "value", i, dvalue);
06216 }
06217 err = cpl_vector_fit_gaussian(ppos_vector, NULL, pdata_vector, NULL, CPL_FIT_ALL, &x0, &total_noise, &area, &offset, NULL, NULL, NULL );
06218 if (err == CPL_ERROR_NONE)
06219 {
06220 cpl_msg_info(cpl_func, "FPN Calculation: histogram x0[%f] total_noise[%f] area[%f] offset[%f]", x0, total_noise, area, offset);
06221 }
06222 else
06223 {
06224 cpl_msg_warning(cpl_func, "FPN could not be computed due failed Gaussian Fit, err msg [%s]", cpl_error_get_message());
06225 cpl_error_reset();
06226 }
06227 cpl_table_delete(ptable);
06228 cpl_vector_delete(ppos_vector);
06229 cpl_vector_delete(pdata_vector);
06230 }
06231 else
06232 {
06233 cpl_msg_warning(cpl_func, "FPN could not be computed due failed histogram computation, err msg [%s]", cpl_error_get_message());
06234 cpl_error_reset();
06235 }
06236 irplib_hist_delete(phist);
06237
06238 return total_noise;
06239 }
06240
06241 static double irplib_compute_err(double gain, double ron, double FA)
06242 {
06243 double int_gain = (gain * gain - 1) / 12;
06244 if (int_gain < 0)
06245 {
06246 int_gain = 0;
06247 }
06248 return sqrt(ron * ron + FA / gain + int_gain);
06249 }
06250 static double irplib_fpn_lg(const cpl_image* f1, int* range, double gain ,
06251 FPN_METHOD fpn_method, int smooth_size, double* mse)
06252 {
06253 cpl_image* im_diff = 0;
06254 const cpl_image* im_f1 = f1;
06255 cpl_image* im_inrange1 = 0;
06256 double FA = 0;
06257 double s_tot = 0;
06258 double s_fpn = 0;
06259 double sr_fpn = 0;
06260
06261 if (gain<=0) {
06262
06263
06264 cpl_msg_warning(cpl_func,"gain[%f]<0", gain);
06265 cpl_msg_warning(cpl_func,"We set dummy values for FPN");
06266 s_fpn=-999.;
06267 sr_fpn=-999;
06268 return sr_fpn;
06269 }
06270 if (range)
06271 {
06272 im_inrange1 = cpl_image_extract(f1, range[0], range[1], range[2], range[3]);
06273 im_f1 = im_inrange1;
06274 }
06275 FA = cpl_image_get_median(im_f1);
06276
06277
06278
06279 switch (fpn_method)
06280 {
06281 case FPN_SMOOTH:
06282 cpl_msg_info(cpl_func,"SMOOTH method is used for FPN, pattern size[%d x %d] pixels",smooth_size,smooth_size );
06283 s_tot = irplib_calculate_total_noise_smooth(im_f1,smooth_size,smooth_size);
06284 break;
06285 case FPN_HISTOGRAM:
06286 cpl_msg_info(cpl_func,"HISTOGRAM method is used for FPN");
06287 s_tot = irplib_calculate_total_noise(im_f1);
06288 break;
06289 default:
06290 s_tot = -1;
06291 sr_fpn = -1;
06292 cpl_msg_warning(cpl_func,"fpn_method is not defined");
06293 break;
06294 }
06295 if (s_tot > 0)
06296 {
06297 if (FA<0)
06298 {
06299
06300
06301 cpl_msg_warning(cpl_func,"Median flux on sum of flats<0");
06302 cpl_msg_warning(cpl_func,"We set dummy values for FPN");
06303 s_fpn=-999.;
06304 sr_fpn=-999;
06305 }
06306
06307 if ((s_tot * s_tot - FA / gain) > 0)
06308 {
06309 s_fpn = sqrt(s_tot * s_tot - FA / gain);
06310 sr_fpn = s_fpn / FA;
06311 *mse = (irplib_compute_err(gain, 0, FA)) * gain / FA;
06312 } else {
06313
06314
06315 cpl_msg_warning(cpl_func,"s_tot * s_tot < FA / gain");
06316 cpl_msg_warning(cpl_func,"We set dummy values for FPN");
06317 s_fpn=-999.;
06318 sr_fpn=-999;
06319 *mse = -1;
06320 }
06321
06322
06323 }
06324 cpl_image_delete(im_diff);
06325 if (range)
06326 {
06327 cpl_image_delete(im_inrange1);
06328 }
06329 return sr_fpn;
06330 }
06331
06332 static cpl_imagelist * irplib_load_fset_wrp(const cpl_frameset * pframeset, cpl_type type , int whichext)
06333 {
06334 cpl_imagelist * ret = 0;
06335 ret = cpl_imagelist_load_frameset(pframeset, type,
06336 1, whichext);
06337 if (ret)
06338 {
06339
06340 int sz = cpl_imagelist_get_size(ret);
06341 int i = 0;
06342 for(i = 0; i < sz; i ++)
06343 {
06344 cpl_image* pimage = 0;
06345 pimage = cpl_imagelist_get(ret, i);
06346 if (pimage)
06347 {
06348 int size_x = 0;
06349 int size_y = 0;
06350 size_x = cpl_image_get_size_x(pimage);
06351 size_y = cpl_image_get_size_y(pimage);
06352 if (detmon_lg_config.nx != size_x || detmon_lg_config.ny != size_y)
06353 {
06354 cpl_msg_error(cpl_func, "All images in the input should have the same size,\n" \
06355 " image #%d has size x[%d] y[%d], expected size x[%d] y[%d]", i, size_x, size_y,
06356 detmon_lg_config.nx, detmon_lg_config.ny);
06357 cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_INPUT);
06358 cpl_imagelist_delete(ret);
06359 ret = 0;
06360 }
06361 }
06362 }
06363 }
06364 return ret;
06365 }
06366
06367 static cpl_imagelist * irplib_load_fset_wrp_ext(const cpl_frameset * pframeset, cpl_type type , int whichext)
06368 {
06369 int i = whichext;
06370 cpl_imagelist* offs = cpl_imagelist_new();
06371 detmon_lg_config.load_fset(pframeset, type, offs);
06372 i++;
06373 return offs;
06374 }
06375
06376 static cpl_error_code irplib_table_create_column(cpl_table* ptable, cpl_propertylist* plist)
06377 {
06378 if (ptable && plist)
06379 {
06380 int size = cpl_propertylist_get_size(plist);
06381 int i = 0;
06382 for (i = 0; i < size; i++)
06383 {
06384 cpl_property* pprop = cpl_propertylist_get(plist,i);
06385 if (pprop)
06386 {
06387 const char* pname = cpl_property_get_name(pprop);
06388 if (pname)
06389 {
06390 cpl_table_new_column(ptable, pname, cpl_property_get_type(pprop));
06391 if (cpl_error_get_code() != CPL_ERROR_NONE)
06392 {
06393 cpl_msg_warning(cpl_func, "cannot create new column[%s], err[%s]", pname, cpl_error_get_message());
06394 break;
06395 }
06396 }
06397 }
06398 }
06399 }
06400 return cpl_error_get_code();
06401 }
06402
06403 static cpl_error_code irplib_fill_table_DETWINUIT(cpl_table* ptable, cpl_propertylist* plist, int row)
06404 {
06405 cpl_error_code err = CPL_ERROR_NONE;
06406 if (ptable && plist)
06407 {
06408 int size = cpl_propertylist_get_size(plist);
06409 int i = 0;
06410 for (i = 0; i < size; i++)
06411 {
06412 cpl_property* pprop = cpl_propertylist_get(plist,i);
06413 if (pprop)
06414 {
06415 const char* pname = cpl_property_get_name(pprop);
06416 double value = cpl_property_get_double(pprop);
06417 if (pname)
06418 {
06419 cpl_table_set_double(ptable, pname, row, value);
06420 if (cpl_error_get_code() != CPL_ERROR_NONE)
06421 {
06422 cpl_msg_warning(cpl_func, "cannot write value to the table, column[%s] value[%f], err[%s]", pname, value, cpl_error_get_message());
06423 cpl_error_reset();
06424 break;
06425 }
06426 }
06427 }
06428 }
06429 }
06430 return err;
06431 }
06432 cpl_error_code irplib_detmon_check_order(const double *exptime, int sz, double tolerance, int order)
06433 {
06434 int nsets = 0;
06435 int i = 0;
06436
06437 do
06438 {
06439 nsets++;
06440 do
06441 {
06442 i++;
06443 if(i == sz - 1)
06444 {
06445 break;
06446 }
06447 } while(fabs(exptime[i-1] - exptime[i]) < tolerance);
06448 } while(i < sz - 1);
06449
06450 if (!fabs(exptime[i-1] - exptime[i]) < tolerance) nsets++;
06451 if(nsets <= order)
06452 {
06453 char err_msg[80];
06454 sprintf(err_msg,"%s%s","Not enough frames for the polynomial",
06455 " fitting. nsets <= order");
06456 cpl_msg_error(cpl_func, err_msg);
06457 cpl_error_set(cpl_func, CPL_ERROR_INCOMPATIBLE_INPUT);
06458 }
06459 return cpl_error_get_code();
06460 }
06461
06462 static cpl_error_code irplib_detmon_lg_dfs_save_imagelist(
06463 cpl_frameset * frameset,
06464 const cpl_parameterlist * parlist,
06465 const cpl_frameset *usedframes,
06466 const cpl_imagelist *coeffs,
06467 const char *recipe_name,
06468 const cpl_propertylist *mypro_coeffscube,
06469 const char * package,
06470 const char * name_o)
06471 {
06472 return(cpl_dfs_save_imagelist
06473 (frameset, NULL, parlist, usedframes, NULL,coeffs, CPL_BPP_IEEE_FLOAT,
06474 recipe_name, mypro_coeffscube, NULL, package,
06475 name_o));
06476 }
06477 static void irplib_detmon_lg_add_empty_image(cpl_imagelist* imlist, int pos)
06478 {
06479 const cpl_image* first = cpl_imagelist_get(imlist, 0);
06480 if (first)
06481 {
06482 int x = cpl_image_get_size_x(first);
06483 int y = cpl_image_get_size_y(first);
06484 cpl_type type = cpl_image_get_type(first);
06485 cpl_image * blank = cpl_image_new(x, y, type);
06486 cpl_imagelist_set(imlist, blank, pos);
06487 }
06488 }