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