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