00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031
00032
00033
00034
00035
00036 #ifdef HAVE_FFTW
00037 #include <complex.h>
00038 #include <fftw3.h>
00039 #endif
00040
00041 #include <math.h>
00042 #include <string.h>
00043 #include <assert.h>
00044
00045 #include <cpl.h>
00046
00047 #include "irplib_detmon.h"
00048 #include "irplib_detmon_lg.h"
00049
00050 #include "irplib_utils.h"
00051
00052 #include "irplib_math_const.h"
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 static struct
00067 {
00068 const char * method;
00069
00070 int order;
00071 int kappa;
00072 int niter;
00073 int threshold_min;
00074 int threshold_max;
00075 int llx;
00076 int lly;
00077 int urx;
00078 int ury;
00079 int ref_level;
00080 int threshold;
00081 int m;
00082 int n;
00083 int llx1;
00084 int lly1;
00085 int urx1;
00086 int ury1;
00087 int llx2;
00088 int lly2;
00089 int urx2;
00090 int ury2;
00091 int llx3;
00092 int lly3;
00093 int urx3;
00094 int ury3;
00095 int llx4;
00096 int lly4;
00097 int urx4;
00098 int ury4;
00099 int llx5;
00100 int lly5;
00101 int urx5;
00102 int ury5;
00103 cpl_boolean autocorr;
00104 cpl_boolean intermediate;
00105 cpl_boolean collapse;
00106 int filter;
00107
00108 double cr;
00109 int exts;
00110 int nb_extensions;
00111 double avg_off1;
00112 double avg_off2;
00113 double sig_off_dif;
00114 } detmon_lg_config;
00115
00116 #define NIR TRUE
00117 #define OPT FALSE
00118
00119 #define DETMON_QC_CONAD "ESO QC CONAD"
00120 #define DETMON_QC_CONAD_C "CONAD value (inverse of GAIN)"
00121
00122 #define DETMON_QC_GAIN "ESO QC GAIN"
00123 #define DETMON_QC_GAIN_C "GAIN (see QC.METHOD)"
00124
00125 #define DETMON_QC_GAIN_MSE "ESO QC GAIN MSE"
00126 #define DETMON_QC_GAIN_MSE_C "Error of the GAIN computation"
00127
00128 #define DETMON_QC_RON "ESO QC RON"
00129 #define DETMON_QC_RON_C "RON obtained as independent term (PTC method)"
00130
00131 #define DETMON_QC_AUTOCORR "ESO QC AUTOCORR"
00132 #define DETMON_QC_AUTOCORR_C "Autocorrelation factor computed as sum of " \
00133 "all pixels in autocorrelation image"
00134 #define DETMON_QC_GAIN_CORR "ESO QC GAIN CORR"
00135 #define DETMON_QC_GAIN_CORR_C "GAIN taken QC.AUTOCORR into account"
00136
00137 #define DETMON_QC_LAMP_FLUX "ESO QC LAMP FLUX"
00138 #define DETMON_QC_LAMP_FLUX_C "Lamp flux"
00139
00140 #define DETMON_QC_NUM_BPM "ESO QC NUM BPM"
00141 #define DETMON_QC_NUM_BPM_C "Number of bad pixels detected according to "\
00142 "polynomial information"
00143
00144
00145
00146
00147
00148
00149
00150 static cpl_error_code
00151 irplib_detmon_lg_retrieve_parlist(const char *,
00152 const char *, const cpl_parameterlist *);
00153
00154
00155 static cpl_error_code
00156 irplib_detmon_lg_split_onoff(const cpl_frameset *,
00157 cpl_frameset *,
00158 cpl_frameset *,
00159 const char *, const char *, const cpl_boolean);
00160
00161 static cpl_error_code
00162 irplib_detmon_lg_reduce(const cpl_frameset *,
00163 const cpl_frameset *,
00164 int *,
00165 int *,
00166 int,
00167 cpl_imagelist **,
00168 cpl_table **,
00169 cpl_table **,
00170 cpl_image **,
00171 cpl_imagelist **,
00172 cpl_imagelist **,
00173 cpl_propertylist **,
00174 int (* load_fset) (const cpl_frameset *,
00175 cpl_type,
00176 cpl_imagelist *),
00177 const cpl_boolean);
00178
00179 static cpl_error_code
00180 irplib_detmon_linearity(const cpl_frameset *,
00181 cpl_table **,
00182 cpl_table **,
00183 cpl_imagelist **,
00184 cpl_vector **,
00185 cpl_imagelist **,
00186 cpl_imagelist **,
00187 const int,
00188 const int, cpl_propertylist **,
00189 const int, const cpl_boolean);
00190
00191 static cpl_error_code
00192 irplib_detmon_gain(cpl_table *,
00193 cpl_table *,
00194 cpl_imagelist *,
00195 cpl_imagelist *,
00196 cpl_imagelist *,
00197 cpl_imagelist *,
00198 const int);
00199
00200 static cpl_error_code
00201 irplib_detmon_lg_save(const cpl_parameterlist *,
00202 cpl_frameset *,
00203 const char *,
00204 const char *,
00205 const char *,
00206 const char *,
00207 const char *,
00208 const char *,
00209 const char *,
00210 const char *,
00211 const char *,
00212 const char *,
00213 cpl_imagelist **,
00214 cpl_table **,
00215 cpl_table **,
00216 cpl_image **,
00217 cpl_imagelist **,
00218 cpl_imagelist **,
00219 cpl_propertylist **,
00220 const int, const int, const cpl_frameset *,
00221 cpl_boolean);
00222
00223 static cpl_error_code
00224 irplib_detmon_lg_qc_ptc(const cpl_table *,
00225 const cpl_table *,
00226 cpl_propertylist *);
00227
00228 static cpl_error_code
00229 irplib_detmon_lg_qc_med(const cpl_table *,
00230 cpl_propertylist *);
00231
00232
00233
00234 cpl_imagelist **
00235 irplib_detmon_ilist_load_fset(const cpl_frameset *,
00236 cpl_type);
00237
00238 cpl_frameset *
00239 irplib_detmon_pair_extract(const cpl_frameset *,
00240 int *, int,
00241 int * ,
00242 int *,
00243 int);
00244
00245
00246
00247
00248
00249
00250
00251 static cpl_image *irplib_detmon_bpixs(const cpl_imagelist *, int *);
00252
00253 static double
00254 irplib_detmon_autocorr_factor(const cpl_image *,
00255 const int,
00256 cpl_imagelist *);
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 static cpl_error_code
00269 irplib_detmon_opt_contamination(const cpl_image *, cpl_propertylist *);
00270
00271 static int
00272 irplib_detmon_opt_lampcr(cpl_frameset *);
00273
00274 int
00275 irplib_detmon_lg_dfs_set_groups(cpl_frameset *, const char *, const char *);
00276
00277 cpl_error_code
00278 irplib_detmon_lg_reduce_all(const cpl_table *,
00279 cpl_table *,
00280 cpl_propertylist *,
00281 cpl_imagelist **,
00282 cpl_image **,
00283 cpl_vector *,
00284 cpl_imagelist *, cpl_table *, cpl_boolean, int);
00285
00286 static cpl_error_code
00287 irplib_detmon_lg_check_defaults(const cpl_image *);
00288
00289 static cpl_error_code
00290 irplib_detmon_lg_rescale(cpl_imagelist *);
00291
00292 static cpl_error_code
00293 irplib_detmon_lg_reduce_init(cpl_boolean,
00294 cpl_table **,
00295 cpl_table **,
00296 cpl_table **,
00297 cpl_imagelist **,
00298 cpl_vector **,
00299 cpl_propertylist **,
00300 int);
00301
00302
00303
00304 cpl_error_code
00305 irplib_detmon_add_adl_column(cpl_table *);
00306
00307
00308
00309 static cpl_error_code
00310 irplib_detmon_lg_reduce_dit(const cpl_frameset * set_on,
00311 int * selection_on,
00312 int dit_nb,
00313 int * nsets_extracted,
00314 const cpl_frameset * set_off,
00315 int * selection_off,
00316 cpl_table ** linear_table_ptr,
00317 cpl_table ** gain_table_ptr,
00318 cpl_imagelist ** linearity_inputs,
00319 cpl_vector ** x_pos,
00320 cpl_propertylist ** qclist,
00321 cpl_boolean opt_nir,
00322 cpl_table ** fit_table,
00323 cpl_imagelist ** autocorr_images,
00324 cpl_imagelist ** diff_flats,
00325 int nsets,
00326 cpl_imagelist ** opt_offs,
00327 int (* load_fset) (const cpl_frameset *,
00328 cpl_type,
00329 cpl_imagelist *));
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404 cpl_error_code
00405 irplib_detmon_lg(cpl_frameset * frameset,
00406 const cpl_parameterlist * parlist,
00407 const char * tag_on,
00408 const char * tag_off,
00409 const char * recipe_name,
00410 const char * pipeline_name,
00411 const char * pafregexp,
00412 const char * procatg_lintbl,
00413 const char * procatg_gaintbl,
00414 const char * procatg_lincoeff,
00415 const char * procatg_bpm,
00416 const char * procatg_corr,
00417 const char * procatg_diff,
00418 const char * package,
00419 int (* compare) (const cpl_frame *,
00420 const cpl_frame *),
00421 int (* load_fset) (const cpl_frameset *,
00422 cpl_type,
00423 cpl_imagelist *),
00424 const cpl_boolean opt_nir)
00425 {
00426 int nsets;
00427 int * selection = NULL;
00428 int i;
00429 cpl_frame * first = NULL;
00430 cpl_image * reference = NULL;
00431
00432
00433
00434
00435
00436
00437 int * selection_on = NULL;
00438 int * selection_off = NULL;
00439 cpl_frameset * cur_fset = NULL;
00440 cpl_frameset * cur_fset_on = NULL;
00441 cpl_frameset * cur_fset_off = NULL;
00442 cpl_table ** gain_table = NULL;
00443 cpl_table ** linear_table = NULL;
00444 cpl_imagelist ** coeffs = NULL;
00445 cpl_image ** bpm = NULL;
00446 cpl_imagelist ** autocorr_images = NULL;
00447 cpl_imagelist ** diff_flats = NULL;
00448 cpl_propertylist ** qclist = NULL;
00449
00450
00451 cpl_ensure_code(frameset != NULL, CPL_ERROR_NULL_INPUT);
00452 cpl_ensure_code(parlist != NULL, CPL_ERROR_NULL_INPUT);
00453 cpl_ensure_code(tag_on != NULL, CPL_ERROR_NULL_INPUT);
00454 cpl_ensure_code(tag_off != NULL, CPL_ERROR_NULL_INPUT);
00455 cpl_ensure_code(recipe_name != NULL, CPL_ERROR_NULL_INPUT);
00456 cpl_ensure_code(pipeline_name != NULL, CPL_ERROR_NULL_INPUT);
00457 cpl_ensure_code(procatg_lintbl != NULL, CPL_ERROR_NULL_INPUT);
00458 cpl_ensure_code(procatg_gaintbl != NULL, CPL_ERROR_NULL_INPUT);
00459 cpl_ensure_code(procatg_lincoeff != NULL, CPL_ERROR_NULL_INPUT);
00460 cpl_ensure_code(procatg_bpm != NULL, CPL_ERROR_NULL_INPUT);
00461 cpl_ensure_code(procatg_corr != NULL, CPL_ERROR_NULL_INPUT);
00462 cpl_ensure_code(procatg_diff != NULL, CPL_ERROR_NULL_INPUT);
00463 cpl_ensure_code(package != NULL, CPL_ERROR_NULL_INPUT);
00464
00465 skip_if (irplib_detmon_lg_dfs_set_groups(frameset, tag_on, tag_off));
00466
00467
00468
00469
00470
00471 skip_if (opt_nir == NIR && cpl_frameset_get_size(frameset) % 4 != 0);
00472
00473 skip_if (irplib_detmon_lg_retrieve_parlist(pipeline_name, recipe_name,
00474 parlist));
00475
00476
00477
00478
00479
00480
00481 first = cpl_frameset_get_first(frameset);
00482 skip_if (first == NULL);
00483
00484 if (detmon_lg_config.exts < 0) {
00485 reference = cpl_image_load(cpl_frame_get_filename(first),
00486 CPL_TYPE_FLOAT, 0, 1);
00487 } else {
00488 if (load_fset != NULL) {
00489 cpl_frameset * new = cpl_frameset_new();
00490 cpl_imagelist * p = cpl_imagelist_new();
00491 cpl_frameset_insert(new, cpl_frame_duplicate(first));
00492 (*load_fset)(new, CPL_TYPE_FLOAT, p);
00493 reference = cpl_image_duplicate(cpl_imagelist_get(p, 0));
00494 cpl_imagelist_delete(p);
00495 cpl_frameset_delete(new);
00496 } else {
00497 reference = cpl_image_load(cpl_frame_get_filename(first),
00498 CPL_TYPE_FLOAT, 0, detmon_lg_config.exts);
00499 }
00500 }
00501 skip_if (reference == NULL);
00502
00503 skip_if (irplib_detmon_lg_check_defaults(reference));
00504
00505
00506 if (compare == NULL) {
00507 nsets = 1;
00508 } else {
00509 cpl_msg_info(cpl_func, "Identifying different settings");
00510 selection = cpl_frameset_labelise(frameset, compare, &nsets);
00511 skip_if (selection == NULL);
00512 }
00513
00514
00515 for(i = 0; i < nsets; i++) {
00516 int nsets_on = 0;
00517 int nsets_off = 0;
00518 int j;
00519
00520 cur_fset = nsets == 1 ?
00521 cpl_frameset_duplicate(frameset) :
00522 cpl_frameset_extract(frameset, selection, i);
00523
00524
00525 cpl_msg_info(cpl_func, "Reduce data set nb %d out of %d",
00526 i + 1, nsets);
00527
00528
00529 detmon_lg_config.nb_extensions = 1;
00530 if (detmon_lg_config.exts < 0) {
00531 const cpl_frame * cur_frame =
00532 cpl_frameset_get_first_const(cur_fset);
00533 detmon_lg_config.nb_extensions =
00534 cpl_frame_get_nextensions(cur_frame);
00535 }
00536
00537
00538
00539
00540
00541 if (opt_nir == OPT) {
00542 irplib_detmon_opt_lampcr(cur_fset);
00543 detmon_lg_config.collapse = TRUE;
00544 }
00545
00546
00547 cur_fset_on = cpl_frameset_new();
00548 cur_fset_off = cpl_frameset_new();
00549 cpl_msg_info(cpl_func, "Splitting into ON and OFF sub-framesets");
00550 skip_if (irplib_detmon_lg_split_onoff(cur_fset,
00551 cur_fset_on, cur_fset_off,
00552 tag_on, tag_off, opt_nir));
00553
00554
00555 selection_on = cpl_frameset_labelise(cur_fset_on,
00556 irplib_detmon_compare_dits,
00557 &nsets_on);
00558 skip_if (selection_on == NULL);
00559
00560 if (!detmon_lg_config.collapse) {
00561 selection_off = cpl_frameset_labelise(cur_fset_off,
00562 irplib_detmon_compare_dits,
00563 &nsets_off);
00564 skip_if (selection_off == NULL);
00565 }
00566
00567
00568 if (!detmon_lg_config.collapse) {
00569 skip_if(nsets_on != nsets_off);
00570 }
00571
00572
00573
00574 gain_table = irplib_detmon_table_new(detmon_lg_config.nb_extensions);
00575 linear_table = irplib_detmon_table_new(detmon_lg_config.nb_extensions);
00576 qclist = irplib_detmon_propertylist_new(detmon_lg_config.nb_extensions);
00577
00578
00579 if (opt_nir == NIR) {
00580 coeffs = irplib_detmon_imagelist_new(detmon_lg_config.nb_extensions);
00581 bpm = irplib_detmon_image_new(detmon_lg_config.nb_extensions);
00582 }
00583
00584 autocorr_images = irplib_detmon_imagelist_new(detmon_lg_config.nb_extensions);
00585 diff_flats = irplib_detmon_imagelist_new(detmon_lg_config.nb_extensions);
00586 if (detmon_lg_config.intermediate) {
00587 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
00588 autocorr_images[j] = cpl_imagelist_new();
00589 diff_flats[j] = cpl_imagelist_new();
00590 }
00591 }
00592
00593
00594 cpl_msg_info(cpl_func, "Starting data reduction");
00595 skip_if(irplib_detmon_lg_reduce(cur_fset_on, cur_fset_off,
00596 selection_on, selection_off,
00597 nsets_on, coeffs, gain_table,
00598 linear_table, bpm, autocorr_images,
00599 diff_flats, qclist, load_fset,
00600 opt_nir));
00601
00602
00603 cpl_msg_info(cpl_func, "Saving the products");
00604 if(nsets == 1) {
00605 skip_if(irplib_detmon_lg_save(parlist, frameset, recipe_name,
00606 pipeline_name, pafregexp,
00607 procatg_lintbl, procatg_gaintbl,
00608 procatg_lincoeff, procatg_bpm,
00609 procatg_corr, procatg_diff, package,
00610 coeffs, gain_table, linear_table,
00611 bpm, autocorr_images, diff_flats,
00612 qclist, 0, 0, cur_fset,
00613 opt_nir));
00614 } else {
00615 skip_if(irplib_detmon_lg_save(parlist, frameset, recipe_name,
00616 pipeline_name, pafregexp,
00617 procatg_lintbl, procatg_gaintbl,
00618 procatg_lincoeff, procatg_bpm,
00619 procatg_corr, procatg_diff, package,
00620 coeffs, gain_table, linear_table,
00621 bpm, autocorr_images, diff_flats,
00622 qclist, 1, i + 1, cur_fset,
00623 opt_nir));
00624 }
00625
00626
00627 cpl_free(selection_on);
00628 cpl_free(selection_off);
00629
00630 cpl_frameset_delete(cur_fset);
00631 cpl_frameset_delete(cur_fset_on);
00632 cpl_frameset_delete(cur_fset_off);
00633
00634 irplib_detmon_table_delete(gain_table,
00635 detmon_lg_config.nb_extensions);
00636 irplib_detmon_table_delete(linear_table,
00637 detmon_lg_config.nb_extensions);
00638 irplib_detmon_imagelist_delete(coeffs,
00639 detmon_lg_config.nb_extensions);
00640 irplib_detmon_propertylist_delete(qclist,
00641 detmon_lg_config.nb_extensions);
00642 irplib_detmon_image_delete(bpm,
00643 detmon_lg_config.nb_extensions);
00644 irplib_detmon_imagelist_delete(autocorr_images,
00645 detmon_lg_config.nb_extensions);
00646 irplib_detmon_imagelist_delete(diff_flats,
00647 detmon_lg_config.nb_extensions);
00648
00649 selection_on = NULL;
00650 selection_off = NULL;
00651 cur_fset = NULL;
00652 cur_fset_on = NULL;
00653 cur_fset_off = NULL;
00654 gain_table = NULL;
00655 linear_table = NULL;
00656 coeffs = NULL;
00657 qclist = NULL;
00658 bpm = NULL;
00659 autocorr_images = NULL;
00660 diff_flats = NULL;
00661 }
00662
00663 end_skip;
00664
00665 cpl_free(selection_on);
00666 cpl_free(selection_off);
00667
00668 cpl_frameset_delete(cur_fset);
00669 cpl_frameset_delete(cur_fset_on);
00670 cpl_frameset_delete(cur_fset_off);
00671
00672 irplib_detmon_table_delete(gain_table,
00673 detmon_lg_config.nb_extensions);
00674 irplib_detmon_table_delete(linear_table,
00675 detmon_lg_config.nb_extensions);
00676 irplib_detmon_imagelist_delete(coeffs,
00677 detmon_lg_config.nb_extensions);
00678 irplib_detmon_propertylist_delete(qclist,
00679 detmon_lg_config.nb_extensions);
00680 irplib_detmon_image_delete(bpm,
00681 detmon_lg_config.nb_extensions);
00682 irplib_detmon_imagelist_delete(autocorr_images,
00683 detmon_lg_config.nb_extensions);
00684 irplib_detmon_imagelist_delete(diff_flats,
00685 detmon_lg_config.nb_extensions);
00686
00687 cpl_free(selection);
00688 cpl_image_delete(reference);
00689
00690 return cpl_error_get_code();
00691 }
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713 #ifdef HAVE_FFTW
00714
00715 cpl_image *
00716 irplib_detmon_image_correlate(const cpl_image * image1,
00717 const cpl_image * image2,
00718 const int m, const int n)
00719 {
00720 cpl_image *image1_padded;
00721 cpl_image *image2_padded;
00722 float *data1;
00723 float *data2;
00724 int nx, ny;
00725 int nx2, ny2;
00726 int i;
00727
00728 fftwf_plan p1;
00729 fftwf_complex *in1;
00730 fftwf_complex *ri1;
00731
00732 fftwf_plan p2;
00733 fftwf_complex *in2;
00734 fftwf_complex *ri2;
00735
00736 fftwf_plan p_inv;
00737 fftwf_complex *in_inv;
00738 fftwf_complex *ri_inv;
00739
00740 fftwf_complex *corr;
00741 float *corr_r;
00742
00743 cpl_image *corr_image;
00744 cpl_image *corr_image_window;
00745 cpl_image *reorganised;
00746 cpl_image *image;
00747
00748
00749 cpl_ensure(image1 != NULL, CPL_ERROR_NULL_INPUT, NULL);
00750 cpl_ensure(image2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
00751
00752 cpl_ensure(m > 0, CPL_ERROR_NULL_INPUT, NULL);
00753 cpl_ensure(n > 0, CPL_ERROR_NULL_INPUT, NULL);
00754
00755 nx = cpl_image_get_size_x(image1);
00756 ny = cpl_image_get_size_y(image1);
00757
00758 nx2 = cpl_image_get_size_x(image2);
00759 ny2 = cpl_image_get_size_y(image2);
00760
00761
00762 cpl_ensure(nx == nx2 && ny == ny2, CPL_ERROR_ILLEGAL_INPUT, NULL);
00763
00764
00765 image1_padded = cpl_image_new(nx + 2 * m, ny + 2 * n, CPL_TYPE_FLOAT);
00766 cpl_image_copy(image1_padded, image1, m + 1, n + 1);
00767
00768 image2_padded = cpl_image_new(nx + 2 * m, ny + 2 * n, CPL_TYPE_FLOAT);
00769 cpl_image_copy(image2_padded, image2, m + 1, n + 1);
00770
00771
00772 data1 = cpl_image_get_data_float(image1_padded);
00773 data2 = cpl_image_get_data_float(image2_padded);
00774
00775
00776 nx = nx + 2 * m;
00777 ny = ny + 2 * n;
00778
00779
00780 in1 = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00781 ri1 = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00782 p1 = fftwf_plan_dft_2d(ny, nx, in1, ri1, FFTW_FORWARD, FFTW_ESTIMATE);
00783
00784
00785 for(i = 0; i < nx * ny; i++) {
00786 *(in1 + i) = (*(data1 + i) + 0.0 * I);
00787 }
00788
00789
00790 fftwf_execute(p1);
00791
00792
00793 fftwf_destroy_plan(p1);
00794 cpl_image_delete(image1_padded);
00795
00796
00797 in2 = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00798 ri2 = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00799 p2 = fftwf_plan_dft_2d(ny, nx, in2, ri2, FFTW_FORWARD, FFTW_ESTIMATE);
00800
00801
00802 for(i = 0; i < nx * ny; i++) {
00803 *(in2 + i) = (*(data2 + i) + 0.0 * I);
00804 }
00805
00806
00807 fftwf_execute(p2);
00808
00809
00810 fftwf_destroy_plan(p2);
00811 cpl_image_delete(image2_padded);
00812
00813
00814 in_inv = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00815 ri_inv = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00816 p_inv = fftwf_plan_dft_2d(ny, nx, in_inv, ri_inv,
00817 FFTW_BACKWARD, FFTW_ESTIMATE);
00818
00819
00820 for(i = 0; i < nx * ny; i++) {
00821 in_inv[i] = conjf(ri1[i]) * ri2[i];
00822 }
00823
00824
00825 fftwf_free(in1);
00826 fftwf_free(ri1);
00827
00828 fftwf_free(in2);
00829 fftwf_free(ri2);
00830
00831
00832 fftwf_execute(p_inv);
00833
00834
00835 fftwf_destroy_plan(p_inv);
00836
00837
00838 corr = (fftwf_complex *) fftwf_malloc(sizeof(fftwf_complex) * nx * ny);
00839 corr_r = (float *) cpl_malloc(sizeof(float) * nx * ny);
00840
00841 for(i = 0; i < nx * ny; i++) {
00842 *(corr + i) = conjf(*(ri_inv + i));
00843 *(corr + i) *= *(ri_inv + i);
00844 corr_r[i] = crealf(*(corr + i));
00845 }
00846 fftwf_free(in_inv);
00847 fftwf_free(ri_inv);
00848
00849
00850 corr_image = cpl_image_wrap_float(nx, ny, corr_r);
00851
00852
00853 fftwf_free(corr);
00854
00855
00856 reorganised = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00857
00858 image = cpl_image_extract(corr_image, nx / 2 + 1, 1, nx, ny);
00859 cpl_image_copy(reorganised, image, 1, 1);
00860 cpl_image_delete(image);
00861
00862 image = cpl_image_extract(corr_image, 1, 1, nx / 2, ny);
00863 cpl_image_copy(reorganised, image, nx / 2 + 1, 1);
00864 cpl_image_delete(image);
00865
00866 cpl_image_unwrap(corr_image);
00867 cpl_free(corr_r);
00868
00869 corr_image = cpl_image_new(nx, ny, CPL_TYPE_FLOAT);
00870
00871 image = cpl_image_extract(reorganised, 1, ny / 2 + 1, nx, ny);
00872 cpl_image_copy(corr_image, image, 1, 1);
00873 cpl_image_delete(image);
00874
00875 image = cpl_image_extract(reorganised, 1, 1, nx, ny / 2);
00876 cpl_image_copy(corr_image, image, 1, ny / 2 + 1);
00877 cpl_image_delete(image);
00878
00879
00880 corr_image_window = cpl_image_extract(corr_image,
00881 nx / 2 + 1 - m,
00882 ny / 2 + 1 - n,
00883 nx / 2 + 1 + m, ny / 2 + 1 + n);
00884
00885
00886 cpl_image_delete(reorganised);
00887 cpl_image_delete(corr_image);
00888
00889 if(cpl_image_divide_scalar(corr_image_window,
00890 cpl_image_get_max(corr_image_window))) {
00891 cpl_image_delete(corr_image_window);
00892 return NULL;
00893 }
00894
00895 return corr_image_window;
00896 }
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022 #endif
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041 cpl_image *
01042 irplib_detmon_autocorrelate(const cpl_image * input2, const int m,
01043 const int n)
01044 {
01045 cpl_image *im_re = NULL;
01046 cpl_image *im_im = NULL;
01047 int nx, ny;
01048 cpl_image *ifft_re = NULL;
01049 cpl_image *ifft_im = NULL;
01050 cpl_image *autocorr = NULL;
01051 cpl_image *autocorr_norm_double = NULL;
01052 cpl_image *autocorr_norm = NULL;
01053
01054
01055 cpl_image *reorganised = NULL;
01056 cpl_image *image = NULL;
01057 int p;
01058 cpl_error_code error;
01059 cpl_image *input;
01060
01061 cpl_ensure(input2 != NULL, CPL_ERROR_NULL_INPUT, NULL);
01062
01063 cpl_ensure(m > 0, CPL_ERROR_NULL_INPUT, NULL);
01064 cpl_ensure(n > 0, CPL_ERROR_NULL_INPUT, NULL);
01065
01066 nx = cpl_image_get_size_x(input2) + 2 * m;
01067 ny = cpl_image_get_size_y(input2) + 2 * n;
01068
01069 p = 128;
01070 while(nx > p || ny > p) {
01071 p *= 2;
01072 }
01073
01074 input = cpl_image_cast(input2, CPL_TYPE_DOUBLE);
01075
01076 im_re = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01077 error = cpl_image_copy(im_re, input, 1, 1);
01078 cpl_ensure(!error, error, NULL);
01079
01080 im_im = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01081
01082 error = cpl_image_fft(im_re, im_im, CPL_FFT_DEFAULT);
01083 cpl_ensure(!error, error, NULL);
01084
01085 ifft_re = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01086
01087
01088 error = cpl_image_power(im_re, 2);
01089 cpl_ensure(!error, error, NULL);
01090
01091 error = cpl_image_add(ifft_re, im_re);
01092 cpl_ensure(!error, error, NULL);
01093
01094 cpl_image_delete(im_re);
01095
01096 error = cpl_image_power(im_im, 2);
01097 cpl_ensure(!error, error, NULL);
01098
01099 error = cpl_image_add(ifft_re, im_im);
01100 cpl_ensure(!error, error, NULL);
01101
01102 cpl_image_delete(im_im);
01103
01104 ifft_im = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01105
01106 error = cpl_image_fft(ifft_re, ifft_im, CPL_FFT_INVERSE);
01107 cpl_ensure(!error, error, NULL);
01108
01109 autocorr = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01110
01111 error = cpl_image_power(ifft_re, 2);
01112 cpl_ensure(!error, error, NULL);
01113
01114 error = cpl_image_add(autocorr, ifft_re);
01115 cpl_ensure(!error, error, NULL);
01116
01117 cpl_image_delete(ifft_re);
01118
01119 error = cpl_image_power(ifft_im, 2);
01120 cpl_ensure(!error, error, NULL);
01121
01122 error = cpl_image_add(autocorr, ifft_im);
01123 cpl_ensure(!error, error, NULL);
01124
01125 cpl_image_delete(ifft_im);
01126
01127
01128
01129
01130
01131
01132 reorganised = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01133
01134 image = cpl_image_extract(autocorr, p / 2 + 1, 1, p, p);
01135 cpl_image_copy(reorganised, image, 1, 1);
01136 cpl_image_delete(image);
01137
01138 image = cpl_image_extract(autocorr, 1, 1, p / 2, p);
01139 cpl_image_copy(reorganised, image, p / 2 + 1, 1);
01140 cpl_image_delete(image);
01141
01142 cpl_image_delete(autocorr);
01143
01144 autocorr = cpl_image_new(p, p, CPL_TYPE_DOUBLE);
01145
01146 image = cpl_image_extract(reorganised, 1, p / 2 + 1, p, p);
01147 cpl_image_copy(autocorr, image, 1, 1);
01148 cpl_image_delete(image);
01149
01150 image = cpl_image_extract(reorganised, 1, 1, p, p / 2);
01151 cpl_image_copy(autocorr, image, 1, p / 2 + 1);
01152 cpl_image_delete(image);
01153
01154 cpl_image_delete(reorganised);
01155
01156 autocorr_norm_double =
01157 cpl_image_extract(autocorr, p / 2 + 1 - m, p / 2 + 1 - n,
01158 p / 2 + 1 + m, p / 2 + 1 + n);
01159
01160 cpl_image_delete(autocorr);
01161
01162 if(cpl_image_divide_scalar(autocorr_norm_double,
01163 cpl_image_get_max(autocorr_norm_double))) {
01164 cpl_image_delete(autocorr_norm_double);
01165 cpl_ensure(0, cpl_error_get_code(), NULL);
01166 }
01167
01168
01169 autocorr_norm = cpl_image_cast(autocorr_norm_double, CPL_TYPE_FLOAT);
01170 cpl_image_delete(autocorr_norm_double);
01171
01172 cpl_image_delete(input);
01173
01174 return autocorr_norm;
01175 }
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 int
01189 irplib_detmon_fill_params_default(cpl_parameterlist * parlist,
01190 const char *recipe_name,
01191 const char *pipeline_name)
01192 {
01193 irplib_detmon_fill_params(parlist, recipe_name, pipeline_name,
01194 "PTC",
01195 3,
01196 3,
01197 25,
01198 0,
01199 10000,
01200 -1,
01201 -1,
01202 -1,
01203 -1,
01204 10000,
01205 10000,
01206 "CPL_FALSE",
01207 "CPL_FALSE",
01208 "CPL_FALSE",
01209 "CPL_TRUE",
01210 -1,
01211 26,
01212 26,
01213 -1,
01214 -1,
01215 -1,
01216 -1,
01217 -1,
01218 -1,
01219 -1,
01220 -1,
01221 -1,
01222 -1,
01223 -1,
01224 -1,
01225 -1,
01226 -1,
01227 -1,
01228 -1,
01229 -1,
01230 -1,
01231 -1,
01232 -1,
01233 0);
01234
01235 return 0;
01236
01237 }
01238
01239 int
01240 irplib_detmon_fill_params(cpl_parameterlist * parlist,
01241 const char *recipe_name, const char *pipeline_name,
01242 const char *method,
01243 int order,
01244 int kappa,
01245 int niter,
01246 int threshold_min,
01247 int threshold_max,
01248 int llx,
01249 int lly,
01250 int urx,
01251 int ury,
01252 int ref_level,
01253 int threshold,
01254 const char *intermediate,
01255 const char *autocorr,
01256 const char *collapse,
01257 const char *rescale,
01258 int filter,
01259 int m,
01260 int n,
01261 int llx1,
01262 int lly1,
01263 int urx1,
01264 int ury1,
01265 int llx2,
01266 int lly2,
01267 int urx2,
01268 int ury2,
01269 int llx3,
01270 int lly3,
01271 int urx3,
01272 int ury3,
01273 int llx4,
01274 int lly4,
01275 int urx4,
01276 int ury4,
01277 int llx5, int lly5, int urx5, int ury5, int exts)
01278 {
01279 irplib_detmon_fill_parlist(parlist, recipe_name, pipeline_name, 40,
01280 "method",
01281 "Method to be used when computing GAIN. Methods appliable: <PTC | MED>. By default PTC method will be applied.",
01282 "CPL_TYPE_STRING", method,
01283
01284 "order",
01285 "Polynomial order for the fit (Linearity)",
01286 "CPL_TYPE_INT", order,
01287 "kappa",
01288 "Kappa value for the kappa-sigma clipping (Gain)",
01289 "CPL_TYPE_INT", kappa,
01290 "niter",
01291 "Number of iterations to compute rms (Gain)",
01292 "CPL_TYPE_INT", niter,
01293 "threshold_min",
01294 "Minimum optional threshold for clean mean method",
01295 "CPL_TYPE_INT", threshold_min,
01296 "threshold_max",
01297 "Maximum optional threshold for clean mean method",
01298 "CPL_TYPE_INT", threshold_max,
01299 "llx",
01300 "x coordinate of the lower-left "
01301 "point of the region of interest. If not modified, default value will be 1.",
01302 "CPL_TYPE_INT", llx,
01303 "lly",
01304 "y coordinate of the lower-left "
01305 "point of the region of interest. If not modified, default value will be 1.",
01306 "CPL_TYPE_INT", lly,
01307 "urx",
01308 "x coordinate of the upper-right "
01309 "point of the region of interest. If not modified, default value will be X dimension of the input image.",
01310 "CPL_TYPE_INT", urx,
01311 "ury",
01312 "y coordinate of the upper-right "
01313 "point of the region of interest. If not modified, default value will be Y dimension of the input image.",
01314 "CPL_TYPE_INT", ury,
01315 "ref_level",
01316 "User reference level",
01317 "CPL_TYPE_INT", ref_level,
01318 "threshold",
01319 "Intensity of threshold pixels",
01320 "CPL_TYPE_INT", threshold,
01321 "intermediate",
01322 "De-/Activate intermediate products",
01323 "CPL_TYPE_BOOL", intermediate,
01324 "autocorr",
01325 "De-/Activate the autocorr option",
01326 "CPL_TYPE_BOOL", autocorr,
01327 "collapse",
01328 "De-/Activate the collapse option",
01329 "CPL_TYPE_BOOL", collapse,
01330 "rescale",
01331 "De-/Activate the collapse option",
01332 "CPL_TYPE_BOOL", rescale,
01333 "m",
01334 "Maximum x-shift for the autocorr",
01335 "CPL_TYPE_INT", m,
01336 "filter",
01337 "Upper limit of Median flux to be filtered",
01338 "CPL_TYPE_INT", filter,
01339 "n",
01340 "Maximum y-shift for the autocorr",
01341 "CPL_TYPE_INT", n,
01342 "llx1",
01343 "x coord of the lower-left point of the first "
01344 "field used for contamination measurement. If not modified, default value will be 1.",
01345 "CPL_TYPE_INT", llx1,
01346 "lly1",
01347 "y coord of the lower-left point of the first "
01348 "field used for contamination measurement. If not modified, default value will be 1.",
01349 "CPL_TYPE_INT", lly1,
01350 "urx1",
01351 "x coord of the upper-right point of the first "
01352 "field used for contamination measurement. If not modified, default value will be X dimension of the input image.",
01353 "CPL_TYPE_INT", urx1,
01354 "ury1",
01355 "y coord of the upper-right point of the first "
01356 "field used for contamination measurement. If not modified, default value will be Y dimension of the input image.",
01357 "CPL_TYPE_INT", ury1,
01358 "llx2",
01359 "x coord of the lower-left point of the second "
01360 "field used for contamination measurement. If not modified, default value will be 1.",
01361 "CPL_TYPE_INT", llx2,
01362 "lly2",
01363 "y coord of the lower-left point of the second "
01364 "field used for contamination measurement. If not modified, default value will be 1.",
01365 "CPL_TYPE_INT", lly2,
01366 "urx2",
01367 "x coord of the upper-right point of the second "
01368 "field used for contamination measurement. If not modified, default value will be half of the X dimension of the input image.",
01369 "CPL_TYPE_INT", urx2,
01370 "ury2",
01371 "y coord of the upper-right point of the second "
01372 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01373 "CPL_TYPE_INT", ury2,
01374 "llx3",
01375 "x coord of the lower-left point of the third "
01376 "field used for contamination measurement. If not modified, default value will be 1.",
01377 "CPL_TYPE_INT", llx3,
01378 "lly3",
01379 "y coord of the lower-left point of the third "
01380 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01381 "CPL_TYPE_INT", lly3,
01382 "urx3",
01383 "x coord of the upper-right point of the third "
01384 "field used for contamination measurement. If not modified, default value will be half of X dimension of the image.",
01385 "CPL_TYPE_INT", urx3,
01386 "ury3",
01387 "y coord of the upper-right point of the third "
01388 "field used for contamination measurement. If not modified, default value will be Y dimension of the image.",
01389 "CPL_TYPE_INT", ury3,
01390 "llx4",
01391 "x coord of the lower-left point of the fourth "
01392 "field used for contamination measurement. If not modified, default value will be half of X dimension of the image.",
01393 "CPL_TYPE_INT", llx4,
01394 "lly4",
01395 "y coord of the lower-left point of the fourth "
01396 "field used for contamination measurement. If not modified, default value will be half of the Y dimension of the input image.",
01397 "CPL_TYPE_INT", lly4,
01398 "urx4",
01399 "x coord of the upper-right point of the fourth "
01400 "field used for contamination measurement. If not modified, default value will be X dimension of the image.",
01401 "CPL_TYPE_INT", urx4,
01402 "ury4",
01403 "y coord of the upper-right point of the fourth "
01404 "field used for contamination measurement. If not modified, default value will be Y dimension of the input image.",
01405 "CPL_TYPE_INT", ury4,
01406 "llx5",
01407 "x coord of the lower-left point of the fifth "
01408 "field used for contamination measurement. If not modified, default value will be half of the X dimension of the input image.",
01409 "CPL_TYPE_INT", llx5,
01410 "lly5",
01411 "y coord of the lower-left point of the fifth "
01412 "field used for contamination measurement. If not modified, default value will be 1.",
01413 "CPL_TYPE_INT", lly5,
01414 "urx5",
01415 "x coord of the upper-right point of the fifth "
01416 "field used for contamination measurement. If not modified, default value will be X dimension of the image.",
01417 "CPL_TYPE_INT", urx5,
01418 "ury5",
01419 "y coord of the upper-right point of the fifth "
01420 "field used for contamination measurement. If not modified, default value will be half of Y dimension of the input image.",
01421 "CPL_TYPE_INT", ury5,
01422 "exts",
01423 "Activate the multi-exts option",
01424 "CPL_TYPE_INT", exts);
01425
01426 return 0;
01427 }
01428
01429 static cpl_error_code
01430 irplib_detmon_lg_retrieve_parlist(const char *pipeline_name,
01431 const char *recipe_name,
01432 const cpl_parameterlist * parlist)
01433 {
01434
01435 char *par_name;
01436 cpl_parameter *par;
01437
01438
01439 par_name = cpl_sprintf("%s.%s.method", pipeline_name, recipe_name);
01440 assert(par_name != NULL);
01441 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01442 detmon_lg_config.method = cpl_parameter_get_string(par);
01443 cpl_free(par_name);
01444
01445
01446 detmon_lg_config.order =
01447 irplib_detmon_retrieve_par("order", pipeline_name, recipe_name,
01448 parlist);
01449
01450
01451 detmon_lg_config.kappa =
01452 irplib_detmon_retrieve_par("kappa", pipeline_name, recipe_name,
01453 parlist);
01454
01455
01456 detmon_lg_config.niter =
01457 irplib_detmon_retrieve_par("niter", pipeline_name, recipe_name,
01458 parlist);
01459
01460
01461 detmon_lg_config.threshold_min =
01462 irplib_detmon_retrieve_par("threshold_min", pipeline_name,
01463 recipe_name, parlist);
01464
01465
01466 detmon_lg_config.threshold_max =
01467 irplib_detmon_retrieve_par("threshold_max", pipeline_name,
01468 recipe_name, parlist);
01469
01470
01471 detmon_lg_config.llx =
01472 irplib_detmon_retrieve_par("llx", pipeline_name, recipe_name,
01473 parlist);
01474
01475
01476 detmon_lg_config.lly =
01477 irplib_detmon_retrieve_par("lly", pipeline_name, recipe_name,
01478 parlist);
01479
01480
01481 detmon_lg_config.urx =
01482 irplib_detmon_retrieve_par("urx", pipeline_name, recipe_name,
01483 parlist);
01484
01485
01486 detmon_lg_config.ury =
01487 irplib_detmon_retrieve_par("ury", pipeline_name, recipe_name,
01488 parlist);
01489
01490
01491 detmon_lg_config.ref_level =
01492 irplib_detmon_retrieve_par("ref_level", pipeline_name, recipe_name,
01493 parlist);
01494
01495
01496 detmon_lg_config.threshold =
01497 irplib_detmon_retrieve_par("threshold", pipeline_name, recipe_name,
01498 parlist);
01499
01500
01501 par_name =
01502 cpl_sprintf("%s.%s.intermediate", pipeline_name, recipe_name);
01503 assert(par_name != NULL);
01504 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01505 detmon_lg_config.intermediate = cpl_parameter_get_bool(par);
01506 cpl_free(par_name);
01507
01508
01509 par_name = cpl_sprintf("%s.%s.autocorr", pipeline_name, recipe_name);
01510 assert(par_name != NULL);
01511 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01512 detmon_lg_config.autocorr = cpl_parameter_get_bool(par);
01513 cpl_free(par_name);
01514
01515
01516 par_name = cpl_sprintf("%s.%s.collapse", pipeline_name, recipe_name);
01517 assert(par_name != NULL);
01518 par = cpl_parameterlist_find((cpl_parameterlist *) parlist, par_name);
01519 detmon_lg_config.collapse = cpl_parameter_get_bool(par);
01520 cpl_free(par_name);
01521
01522
01523 detmon_lg_config.filter =
01524 irplib_detmon_retrieve_par("filter", pipeline_name,
01525 recipe_name, parlist);
01526
01527
01528 detmon_lg_config.m =
01529 irplib_detmon_retrieve_par("m", pipeline_name, recipe_name, parlist);
01530
01531
01532 detmon_lg_config.n =
01533 irplib_detmon_retrieve_par("n", pipeline_name, recipe_name, parlist);
01534
01535
01536 detmon_lg_config.llx1 =
01537 irplib_detmon_retrieve_par("llx1", pipeline_name, recipe_name,
01538 parlist);
01539
01540
01541 detmon_lg_config.lly1 =
01542 irplib_detmon_retrieve_par("lly1", pipeline_name, recipe_name,
01543 parlist);
01544
01545
01546 detmon_lg_config.urx1 =
01547 irplib_detmon_retrieve_par("urx1", pipeline_name, recipe_name,
01548 parlist);
01549
01550
01551 detmon_lg_config.ury1 =
01552 irplib_detmon_retrieve_par("ury1", pipeline_name, recipe_name,
01553 parlist);
01554
01555
01556 detmon_lg_config.llx2 =
01557 irplib_detmon_retrieve_par("llx2", pipeline_name, recipe_name,
01558 parlist);
01559
01560
01561 detmon_lg_config.lly2 =
01562 irplib_detmon_retrieve_par("lly2", pipeline_name, recipe_name,
01563 parlist);
01564
01565
01566 detmon_lg_config.urx2 =
01567 irplib_detmon_retrieve_par("urx2", pipeline_name, recipe_name,
01568 parlist);
01569
01570
01571 detmon_lg_config.ury2 =
01572 irplib_detmon_retrieve_par("ury2", pipeline_name, recipe_name,
01573 parlist);
01574
01575
01576 detmon_lg_config.llx3 =
01577 irplib_detmon_retrieve_par("llx3", pipeline_name, recipe_name,
01578 parlist);
01579
01580
01581 detmon_lg_config.lly3 =
01582 irplib_detmon_retrieve_par("lly3", pipeline_name, recipe_name,
01583 parlist);
01584
01585
01586 detmon_lg_config.urx3 =
01587 irplib_detmon_retrieve_par("urx3", pipeline_name, recipe_name,
01588 parlist);
01589
01590
01591 detmon_lg_config.ury3 =
01592 irplib_detmon_retrieve_par("ury3", pipeline_name, recipe_name,
01593 parlist);
01594
01595
01596 detmon_lg_config.llx4 =
01597 irplib_detmon_retrieve_par("llx4", pipeline_name, recipe_name,
01598 parlist);
01599
01600
01601 detmon_lg_config.lly4 =
01602 irplib_detmon_retrieve_par("lly4", pipeline_name, recipe_name,
01603 parlist);
01604
01605
01606 detmon_lg_config.urx4 =
01607 irplib_detmon_retrieve_par("urx4", pipeline_name, recipe_name,
01608 parlist);
01609
01610
01611 detmon_lg_config.ury4 =
01612 irplib_detmon_retrieve_par("ury4", pipeline_name, recipe_name,
01613 parlist);
01614
01615
01616 detmon_lg_config.llx5 =
01617 irplib_detmon_retrieve_par("llx5", pipeline_name, recipe_name,
01618 parlist);
01619
01620
01621 detmon_lg_config.lly5 =
01622 irplib_detmon_retrieve_par("lly5", pipeline_name, recipe_name,
01623 parlist);
01624
01625
01626 detmon_lg_config.urx5 =
01627 irplib_detmon_retrieve_par("urx5", pipeline_name, recipe_name,
01628 parlist);
01629
01630
01631 detmon_lg_config.ury5 =
01632 irplib_detmon_retrieve_par("ury5", pipeline_name, recipe_name,
01633 parlist);
01634
01635
01636 detmon_lg_config.exts =
01637 irplib_detmon_retrieve_par("exts", pipeline_name, recipe_name,
01638 parlist);
01639
01640 if(cpl_error_get_code()) {
01641 cpl_msg_error(cpl_func, "Failed to retrieve the input parameters");
01642 cpl_ensure_code(0, CPL_ERROR_DATA_NOT_FOUND);
01643 }
01644
01645
01646 return CPL_ERROR_NONE;
01647 }
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660 static cpl_error_code
01661 irplib_detmon_lg_check_defaults(const cpl_image * reference)
01662 {
01663 const int nx = cpl_image_get_size_x(reference);
01664 const int ny = cpl_image_get_size_y(reference);
01665
01666 if(detmon_lg_config.llx == -1)
01667 detmon_lg_config.llx = 1;
01668 if(detmon_lg_config.lly == -1)
01669 detmon_lg_config.lly = 1;
01670 if(detmon_lg_config.urx == -1)
01671 detmon_lg_config.urx = nx;
01672 if(detmon_lg_config.ury == -1)
01673 detmon_lg_config.ury = ny;
01674
01675 if(detmon_lg_config.llx1 == -1)
01676 detmon_lg_config.llx1 = 1;
01677 if(detmon_lg_config.lly1 == -1)
01678 detmon_lg_config.lly1 = 1;
01679 if(detmon_lg_config.urx1 == -1)
01680 detmon_lg_config.urx1 = nx;
01681 if(detmon_lg_config.ury1 == -1)
01682 detmon_lg_config.ury1 = ny;
01683
01684 if(detmon_lg_config.llx2 == -1)
01685 detmon_lg_config.llx2 = 1;
01686 if(detmon_lg_config.lly2 == -1)
01687 detmon_lg_config.lly2 = 1;
01688 if(detmon_lg_config.urx2 == -1)
01689 detmon_lg_config.urx2 = nx / 2;
01690 if(detmon_lg_config.ury2 == -1)
01691 detmon_lg_config.ury2 = ny / 2;
01692
01693 if(detmon_lg_config.llx3 == -1)
01694 detmon_lg_config.llx3 = 1;
01695 if(detmon_lg_config.lly3 == -1)
01696 detmon_lg_config.lly3 = ny / 2;
01697 if(detmon_lg_config.urx3 == -1)
01698 detmon_lg_config.urx3 = nx / 2;
01699 if(detmon_lg_config.ury3 == -1)
01700 detmon_lg_config.ury3 = ny;
01701
01702 if(detmon_lg_config.llx4 == -1)
01703 detmon_lg_config.llx4 = nx / 2;
01704 if(detmon_lg_config.lly4 == -1)
01705 detmon_lg_config.lly4 = ny / 2;
01706 if(detmon_lg_config.urx4 == -1)
01707 detmon_lg_config.urx4 = nx;
01708 if(detmon_lg_config.ury4 == -1)
01709 detmon_lg_config.ury4 = ny;
01710
01711 if(detmon_lg_config.llx5 == -1)
01712 detmon_lg_config.llx5 = nx / 2;
01713 if(detmon_lg_config.lly5 == -1)
01714 detmon_lg_config.lly5 = 1;
01715 if(detmon_lg_config.urx5 == -1)
01716 detmon_lg_config.urx5 = nx;
01717 if(detmon_lg_config.ury5 == -1)
01718 detmon_lg_config.ury5 = ny / 2;
01719
01720 if(detmon_lg_config.intermediate == TRUE) {
01721 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.");
01722 detmon_lg_config.autocorr = TRUE;
01723 }
01724
01725 #ifndef HAVE_FFTW
01726 if(detmon_lg_config.autocorr == TRUE)
01727 cpl_msg_warning(cpl_func,
01728 "You don't have FFTW installed in your system."
01729 " Please note that use of --autocorr option without it "
01730 "will result in an execution time close to 10 minutes.");
01731
01732 #endif
01733
01734 return CPL_ERROR_NONE;
01735 }
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751
01752 static cpl_error_code
01753 irplib_detmon_lg_split_onoff(const cpl_frameset * cur_fset,
01754 cpl_frameset * cur_fset_on,
01755 cpl_frameset * cur_fset_off,
01756 const char *tag_on,
01757 const char *tag_off, const cpl_boolean opt_nir)
01758 {
01759 int nframes;
01760 int i;
01761
01762 nframes = cpl_frameset_get_size(cur_fset);
01763 for(i = opt_nir == NIR ? 0 : 2; i < nframes; i++) {
01764 const cpl_frame *cur_frame =
01765 cpl_frameset_get_frame_const(cur_fset, i);
01766
01767 cpl_frame *cur_frame_dup =
01768 cpl_frame_duplicate(cur_frame);
01769 char *tag =
01770 (char *) cpl_frame_get_tag(cur_frame_dup);
01771
01772
01773 if(!strcmp(tag, tag_on)) {
01774 cpl_error_reset();
01775 cpl_frameset_insert(cur_fset_on, cur_frame_dup);
01776 if(cpl_error_get_code() != CPL_ERROR_NONE) {
01777 cpl_msg_error(cpl_func,
01778 "Cannot insert ON frame nb %d into "
01779 "corresponding sub-frameset", i + 1);
01780 cpl_frame_delete(cur_frame_dup);
01781 cpl_ensure_code(0, cpl_error_get_code());
01782 }
01783 } else if(!strcmp(tag, tag_off)) {
01784 cpl_error_reset();
01785 cpl_frameset_insert(cur_fset_off, cur_frame_dup);
01786 if(cpl_error_get_code() != CPL_ERROR_NONE) {
01787 cpl_msg_error(cpl_func, "Cannot insert OFF frame nb %d into "
01788 "corresponding sub-frameset", i + 1);
01789 cpl_frame_delete(cur_frame_dup);
01790 cpl_ensure_code(0, cpl_error_get_code());
01791 }
01792 } else {
01793 cpl_frame_delete(cur_frame_dup);
01794 }
01795 }
01796
01797 return CPL_ERROR_NONE;
01798 }
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822 static cpl_error_code
01823 irplib_detmon_lg_reduce(const cpl_frameset * set_on,
01824 const cpl_frameset * set_off,
01825 int *selection_on,
01826 int *selection_off,
01827 int nsets_extracted,
01828 cpl_imagelist ** coeffs_ptr,
01829 cpl_table ** gain_table_ptr,
01830 cpl_table ** linear_table_ptr,
01831 cpl_image ** bpm_ptr,
01832 cpl_imagelist ** autocorr_images,
01833 cpl_imagelist ** diff_flats,
01834 cpl_propertylist ** qclist,
01835 int (* load_fset) (const cpl_frameset *,
01836 cpl_type,
01837 cpl_imagelist *),
01838 const cpl_boolean opt_nir)
01839 {
01840 int i, j;
01841 cpl_imagelist **linearity_inputs = NULL;
01842 cpl_table **fit_table = NULL;
01843 cpl_vector **x_pos = NULL;
01844 cpl_imagelist **opt_offs = NULL;
01845 cpl_error_code error;
01846 int nsets;
01847 cpl_propertylist *reflist = NULL;
01848
01849
01850 cpl_ensure(set_on != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
01851 cpl_ensure(set_off != NULL, CPL_ERROR_NULL_INPUT, CPL_ERROR_NULL_INPUT);
01852
01853 nsets = cpl_frameset_get_size(set_on) / 2;
01854
01855
01856 fit_table = (cpl_table **) cpl_malloc(detmon_lg_config.nb_extensions *
01857 sizeof(cpl_table *));
01858 if(opt_nir == NIR) {
01859 linearity_inputs =
01860 (cpl_imagelist **) cpl_malloc(detmon_lg_config.nb_extensions *
01861 sizeof(cpl_imagelist *));
01862 x_pos =
01863 (cpl_vector **) cpl_malloc(detmon_lg_config.nb_extensions *
01864 sizeof(cpl_vector *));
01865 } else {
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875 const cpl_frame *first = cpl_frameset_get_first_const(set_off);
01876 cpl_frame *dup_first = cpl_frame_duplicate(first);
01877
01878 const cpl_frame *second = cpl_frameset_get_next_const(set_off);
01879 cpl_frame *dup_second = cpl_frame_duplicate(second);
01880
01881 cpl_frameset *raw_offs = cpl_frameset_new();
01882
01883 cpl_frameset_insert(raw_offs, dup_first);
01884 cpl_frameset_insert(raw_offs, dup_second);
01885
01886 opt_offs = irplib_detmon_ilist_load_fset(raw_offs, CPL_TYPE_FLOAT);
01887
01888 cpl_frameset_delete(raw_offs);
01889
01891
01892 }
01893
01894 irplib_detmon_lg_reduce_init(opt_nir, gain_table_ptr,
01895 linear_table_ptr, fit_table,
01896 linearity_inputs, x_pos, qclist, nsets);
01897
01898
01899
01900
01901 for(i = 0; i < nsets_extracted; i++) {
01902 skip_if(irplib_detmon_lg_reduce_dit(set_on, selection_on, i,
01903 &nsets_extracted, set_off,
01904 selection_off, linear_table_ptr,
01905 gain_table_ptr, linearity_inputs,
01906 x_pos, qclist, opt_nir, fit_table,
01907 autocorr_images, diff_flats,nsets,
01908 opt_offs, load_fset));
01909 }
01910
01911 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
01912 reflist = cpl_propertylist_new();
01913 skip_if(cpl_propertylist_append_bool(reflist, "ADU", FALSE));
01914 skip_if(cpl_table_sort(gain_table_ptr[i], reflist));
01915 }
01916
01917
01918
01919
01920
01921
01922
01923
01924
01925
01926 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
01927 if(opt_nir == NIR) {
01928 error = irplib_detmon_lg_reduce_all(linear_table_ptr[i], fit_table[i],
01929 qclist[i], &coeffs_ptr[i], &bpm_ptr[i],
01930 x_pos[i], linearity_inputs[i],
01931 gain_table_ptr[i], opt_nir, i+1);
01932 } else {
01933 error = irplib_detmon_lg_reduce_all(linear_table_ptr[i], fit_table[i],
01934 qclist[i], NULL, NULL, NULL, NULL,
01935 gain_table_ptr[i], opt_nir, i+1);
01936 }
01937 cpl_ensure_code(!error, error);
01938 }
01939
01940 end_skip;
01941
01942 if(linearity_inputs) {
01943 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
01944 cpl_imagelist_delete(linearity_inputs[i]);
01945 }
01946 cpl_free(linearity_inputs);
01947 linearity_inputs = NULL;
01948 }
01949 if(x_pos) {
01950 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
01951 cpl_vector_delete(x_pos[i]);
01952 }
01953 cpl_free(x_pos);
01954 x_pos = NULL;
01955 }
01956 if(fit_table) {
01957 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
01958 cpl_table_delete(fit_table[i]);
01959 }
01960 cpl_free(fit_table);
01961 fit_table = NULL;
01962 }
01963
01964 if(detmon_lg_config.collapse) {
01965 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
01966 cpl_imagelist_delete(opt_offs[j]);
01967 }
01968 cpl_free(opt_offs);
01969 opt_offs = NULL;
01970 }
01971
01972 cpl_propertylist_delete(reflist);
01973
01974 return CPL_ERROR_NONE;
01975 }
01976
01977 static cpl_error_code
01978 irplib_detmon_lg_reduce_dit(const cpl_frameset * set_on,
01979 int * selection_on,
01980 int dit_nb,
01981 int * nsets_extracted,
01982 const cpl_frameset * set_off,
01983 int * selection_off,
01984 cpl_table ** linear_table_ptr,
01985 cpl_table ** gain_table_ptr,
01986 cpl_imagelist ** linearity_inputs,
01987 cpl_vector ** x_pos,
01988 cpl_propertylist ** qclist,
01989 cpl_boolean opt_nir,
01990 cpl_table ** fit_table,
01991 cpl_imagelist ** autocorr_images,
01992 cpl_imagelist ** diff_flats,
01993 int nsets,
01994 cpl_imagelist ** opt_offs,
01995 int (* load_fset) (const cpl_frameset *,
01996 cpl_type,
01997 cpl_imagelist *))
01998 {
01999 cpl_frameset *pair_on = NULL;
02000 cpl_frameset *pair_off = NULL;
02001 cpl_imagelist **ons = NULL;
02002 cpl_imagelist **offs = NULL;
02003 int with_equal_dit = 0;
02004 cpl_boolean follow = CPL_TRUE;
02005 int j;
02006 cpl_imagelist ** masterl = NULL;
02007
02008
02009 pair_on = irplib_detmon_pair_extract(set_on, selection_on, dit_nb, nsets_extracted, &with_equal_dit, 1);
02010
02011 skip_if(pair_on == NULL);
02012
02013
02014 if (load_fset != NULL) {
02015 cpl_imagelist * p = cpl_imagelist_new();
02016 (*load_fset)(pair_on, CPL_TYPE_FLOAT, p);
02017 ons = &p;
02018 } else {
02019 ons = irplib_detmon_ilist_load_fset(pair_on, CPL_TYPE_FLOAT);
02020 }
02021 skip_if(*ons == NULL);
02022
02023 if(detmon_lg_config.filter > 0) {
02024 for (j = 0; j < detmon_lg_config.nb_extensions; j++) {
02025 double med1 =
02026 cpl_image_get_median_window(cpl_imagelist_get(ons[j], 0),
02027 detmon_lg_config.llx,
02028 detmon_lg_config.lly,
02029 detmon_lg_config.urx,
02030 detmon_lg_config.ury);
02031 double med2 =
02032 cpl_image_get_median_window(cpl_imagelist_get(ons[j], 1),
02033 detmon_lg_config.llx,
02034 detmon_lg_config.lly,
02035 detmon_lg_config.urx,
02036 detmon_lg_config.ury);
02037 if ( med1 > (double)detmon_lg_config.filter ||
02038 med2 > (double)detmon_lg_config.filter) {
02039 follow = CPL_FALSE;
02040 break;
02041 }
02042 }
02043 }
02044
02045 if (follow || detmon_lg_config.filter < 0) {
02046
02047
02048
02049
02050
02051 if(!detmon_lg_config.collapse) {
02052 pair_off =
02053 irplib_detmon_pair_extract(set_off, selection_off, dit_nb, nsets_extracted, &with_equal_dit, 0);
02054
02055 skip_if(pair_off == NULL || cpl_error_get_code());
02056
02057 if (load_fset != NULL) {
02058 cpl_imagelist * p = cpl_imagelist_new();
02059 (*load_fset)(pair_off, CPL_TYPE_FLOAT, p);
02060 offs = &p;
02061 } else {
02062 offs = irplib_detmon_ilist_load_fset(pair_off, CPL_TYPE_FLOAT);
02063 }
02064 skip_if(*offs == NULL);
02065 skip_if(cpl_error_get_code());
02066
02067 } else {
02068
02069
02070
02071
02072 masterl = irplib_detmon_ilist_load_fset(set_off, CPL_TYPE_FLOAT);
02073 skip_if(cpl_error_get_code());
02074
02075 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
02076 cpl_image * collapse =
02077 cpl_imagelist_collapse_create(masterl[j]);
02078
02079 skip_if(cpl_imagelist_set(masterl[j], collapse, 0));
02080 }
02081
02082 offs = (cpl_imagelist **)masterl;
02083 }
02084
02085
02086 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
02087 skip_if(irplib_detmon_linearity(pair_on, linear_table_ptr,
02088 gain_table_ptr,
02089 linearity_inputs, x_pos,
02090 ons, offs, dit_nb,
02091 nsets, qclist,j, opt_nir));
02092 skip_if(irplib_detmon_add_adl_column(linear_table_ptr[j]));
02093 }
02094
02095
02096
02097
02098
02099
02100
02101
02102 if(detmon_lg_config.collapse) {
02103 offs = (cpl_imagelist **) opt_offs;
02104 }
02105
02106 cpl_msg_info(cpl_func, "Computing GAIN for EXPTIME value nb %d",
02107 dit_nb + 1);
02108 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
02109 skip_if(irplib_detmon_gain(gain_table_ptr[j], fit_table[j],
02110 autocorr_images[j], diff_flats[j],
02111 ons[j], offs[j], dit_nb));
02112 }
02113 }
02114
02115 end_skip;
02116
02117 cpl_frameset_delete(pair_on);
02118 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
02119 cpl_imagelist_delete(ons[j]);
02120 }
02121 if(load_fset == NULL) cpl_free(ons);
02122 ons = NULL;
02123
02124 if(!detmon_lg_config.collapse ) {
02125 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
02126 cpl_imagelist_delete(offs[j]);
02127 }
02128 if(load_fset == NULL)cpl_free(offs);
02129 offs = NULL;
02130 }
02131
02132 if(!detmon_lg_config.collapse) {
02133 cpl_frameset_delete(pair_off);
02134 }
02135
02136 if(detmon_lg_config.collapse) {
02137 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
02138 cpl_imagelist_delete(masterl[j]);
02139 }
02140 cpl_free(masterl);
02141 }
02142
02143
02144 return cpl_error_get_code();
02145 }
02146
02147
02148
02149
02150
02151
02152
02153
02154
02155
02156
02157 cpl_error_code
02158 irplib_detmon_add_adl_column(cpl_table * table)
02159 {
02160 cpl_error_code error;
02161 double mean_med_dit =
02162 cpl_table_get_column_mean(table, "MED_DIT");
02163 double *dits = cpl_table_get_data_double(table, "DIT");
02164
02165 error = cpl_table_copy_data_double(table, "ADL", dits);
02166 cpl_ensure_code(!error, error);
02167 error = cpl_table_multiply_scalar(table, "ADL", mean_med_dit);
02168 cpl_ensure_code(!error, error);
02169
02170 return CPL_ERROR_NONE;
02171 }
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184 static cpl_error_code
02185 irplib_detmon_lg_reduce_init(cpl_boolean opt_nir,
02186 cpl_table ** gain_table_ptr,
02187 cpl_table ** linear_table_ptr,
02188 cpl_table ** fit_table,
02189 cpl_imagelist ** linearity_inputs,
02190 cpl_vector ** x_pos,
02191 cpl_propertylist ** qclist,
02192 int nsets)
02193 {
02194 int i;
02195
02196 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
02197
02198 gain_table_ptr[i] = cpl_table_new(nsets);
02199 cpl_table_new_column(gain_table_ptr[i], "DIT", CPL_TYPE_DOUBLE);
02200 cpl_table_new_column(gain_table_ptr[i], "EXPTIME", CPL_TYPE_DOUBLE);
02201 cpl_table_new_column(gain_table_ptr[i], "MEAN_ON1", CPL_TYPE_DOUBLE);
02202 cpl_table_new_column(gain_table_ptr[i], "MEAN_ON2", CPL_TYPE_DOUBLE);
02203 cpl_table_new_column(gain_table_ptr[i], "MEAN_OFF1", CPL_TYPE_DOUBLE);
02204 cpl_table_new_column(gain_table_ptr[i], "MEAN_OFF2", CPL_TYPE_DOUBLE);
02205 cpl_table_new_column(gain_table_ptr[i], "SIG_ON_DIF",
02206 CPL_TYPE_DOUBLE);
02207 cpl_table_new_column(gain_table_ptr[i], "SIG_OFF_DIF",
02208 CPL_TYPE_DOUBLE);
02209 cpl_table_new_column(gain_table_ptr[i], "GAIN", CPL_TYPE_DOUBLE);
02210 cpl_table_new_column(gain_table_ptr[i], "AUTOCORR", CPL_TYPE_DOUBLE);
02211 cpl_table_new_column(gain_table_ptr[i], "GAIN_CORR", CPL_TYPE_DOUBLE);
02212 cpl_table_new_column(gain_table_ptr[i], "ADU", CPL_TYPE_DOUBLE);
02213 cpl_table_new_column(gain_table_ptr[i], "X_FIT", CPL_TYPE_DOUBLE);
02214 cpl_table_new_column(gain_table_ptr[i], "Y_FIT", CPL_TYPE_DOUBLE);
02215
02216
02217 linear_table_ptr[i] = cpl_table_new(nsets);
02218 cpl_table_new_column(linear_table_ptr[i], "DIT", CPL_TYPE_DOUBLE);
02219 cpl_table_new_column(linear_table_ptr[i], "EXPTIME", CPL_TYPE_DOUBLE);
02220 cpl_table_new_column(linear_table_ptr[i], "MED", CPL_TYPE_DOUBLE);
02221 cpl_table_new_column(linear_table_ptr[i], "MEAN", CPL_TYPE_DOUBLE);
02222 cpl_table_new_column(linear_table_ptr[i], "MED_DIT", CPL_TYPE_DOUBLE);
02223 cpl_table_new_column(linear_table_ptr[i], "MEAN_DIT",
02224 CPL_TYPE_DOUBLE);
02225 cpl_table_new_column(linear_table_ptr[i], "ADL", CPL_TYPE_DOUBLE);
02226
02227 fit_table[i] = cpl_table_new(nsets);
02228 cpl_table_new_column(fit_table[i], "Y", CPL_TYPE_DOUBLE);
02229 cpl_table_new_column(fit_table[i], "X", CPL_TYPE_DOUBLE);
02230
02231 qclist[i] = cpl_propertylist_new();
02232
02233 if(opt_nir == NIR) {
02234 linearity_inputs[i] = cpl_imagelist_new();
02235 x_pos[i] = cpl_vector_new(nsets);
02236 }
02237 }
02238
02239 return cpl_error_get_code();
02240 }
02241
02242
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296 static cpl_error_code
02297 irplib_detmon_linearity(const cpl_frameset * pair,
02298 cpl_table ** linear_table,
02299 cpl_table ** gain_table,
02300 cpl_imagelist ** linearity_inputs,
02301 cpl_vector ** x_pos,
02302 cpl_imagelist ** ons,
02303 cpl_imagelist ** offs,
02304 const int pos,
02305 const int nsets,
02306 cpl_propertylist ** qclist,
02307 const int whichext, const cpl_boolean opt_nir)
02308 {
02309 const char *filename;
02310 cpl_propertylist *plist;
02311 cpl_image *dif1;
02312 cpl_image *dif2;
02313 cpl_image *dif_avg;
02314 double med_dit;
02315 double mean_dit;
02316 double exptime, dit;
02317 cpl_error_code error;
02318
02319 cpl_ensure_code(ons[whichext] != NULL, CPL_ERROR_NULL_INPUT);
02320 cpl_ensure_code(offs[whichext] != NULL, CPL_ERROR_NULL_INPUT);
02321
02322 filename = cpl_frame_get_filename(cpl_frameset_get_first_const(pair));
02323 if((plist = cpl_propertylist_load(filename, 0)) == NULL) {
02324 cpl_msg_error(cpl_func, "getting header from reference frame");
02325 cpl_ensure_code(0, cpl_error_get_code());
02326 }
02327
02328 dit = irplib_pfits_get_exptime(plist);
02329
02330 exptime = irplib_pfits_get_exptime(plist);
02331
02332 cpl_table_set(linear_table[whichext], "DIT", pos, dit);
02333 cpl_table_set(gain_table[whichext], "DIT", pos, dit);
02334
02335 cpl_table_set(linear_table[whichext], "EXPTIME", pos, exptime);
02336 cpl_table_set(gain_table[whichext], "EXPTIME", pos, exptime);
02337
02338
02339 dif1 = cpl_image_subtract_create(cpl_imagelist_get_const(ons[whichext], 0),
02340 cpl_imagelist_get_const(offs[whichext], 0));
02341 if(!detmon_lg_config.collapse)
02342 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons[whichext], 1),
02343 cpl_imagelist_get_const(offs[whichext], 1));
02344 else
02345 dif2 = cpl_image_subtract_create(cpl_imagelist_get_const(ons[whichext], 1),
02346 cpl_imagelist_get_const(offs[whichext], 0));
02347
02348 dif_avg = cpl_image_average_create(dif1, dif2);
02349 cpl_ensure_code(dif_avg != NULL, cpl_error_get_code());
02350
02351 if(opt_nir == OPT && pos == nsets / 2) {
02352 irplib_detmon_opt_contamination(dif_avg, qclist[whichext]);
02353 }
02354
02355 cpl_table_set(linear_table[whichext], "MED", pos, cpl_image_get_median(dif_avg));
02356 cpl_table_set(linear_table[whichext], "MEAN", pos, cpl_image_get_mean(dif_avg));
02357 med_dit = cpl_image_get_median(dif_avg) / irplib_pfits_get_exptime(plist);
02358 mean_dit = cpl_image_get_mean(dif_avg) / irplib_pfits_get_exptime(plist);
02359
02360 cpl_table_set(linear_table[whichext], "MED_DIT", pos, med_dit);
02361 cpl_table_set(linear_table[whichext], "MEAN_DIT", pos, mean_dit);
02362
02363
02364 if(pos == 0)
02365 detmon_lg_config.cr = cpl_image_get_mean(dif_avg) / dit;
02366
02367 cpl_image_delete(dif1);
02368 cpl_image_delete(dif2);
02369 cpl_propertylist_delete(plist);
02370
02371
02372 if(opt_nir == NIR) {
02373 error = cpl_imagelist_set(linearity_inputs[whichext], dif_avg, pos);
02374 cpl_ensure_code(!error, error);
02375 cpl_vector_set(x_pos[whichext], pos, dit);
02376 } else {
02377 cpl_image_delete(dif_avg);
02378 }
02379
02380 return CPL_ERROR_NONE;
02381 }
02382
02383
02384
02385
02386
02387
02388
02389
02390
02391
02392
02393
02394
02395
02396
02397 static cpl_error_code
02398 irplib_detmon_gain(cpl_table * gain_table,
02399 cpl_table * fit_table,
02400 cpl_imagelist * autocorr_images,
02401 cpl_imagelist * diff_flats,
02402 cpl_imagelist * ons, cpl_imagelist * offs, const int pos)
02403 {
02404 const cpl_image *image;
02405 double std;
02406 cpl_image *on_dif;
02407 cpl_image *off_dif;
02408 double avg_on1, avg_on2;
02409 double avg_off1, avg_off2;
02410 double avg_on_dif, sig_on_dif;
02411 double avg_off_dif, sig_off_dif;
02412 double double_adu, autocorr, gain, gain_corr;
02413 double sigma, sigma_corr;
02414 cpl_error_code error;
02415
02416 std = 0;
02417
02418 error = irplib_detmon_lg_rescale(ons);
02419 cpl_ensure_code(!error, error);
02420
02421 error = irplib_detmon_lg_rescale(offs);
02422 cpl_ensure_code(!error, error);
02423
02424
02425 if((image = cpl_imagelist_get_const(ons, 0)) == NULL) {
02426 cpl_ensure_code(0, cpl_error_get_code());
02427 }
02428
02429 irplib_get_clean_mean_window(image,
02430 detmon_lg_config.llx,
02431 detmon_lg_config.lly,
02432 detmon_lg_config.urx,
02433 detmon_lg_config.ury,
02434 detmon_lg_config.kappa,
02435 detmon_lg_config.niter, &avg_on1, &std);
02436 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02437 cpl_error_get_code());
02438 cpl_table_set_double(gain_table, "MEAN_ON1", pos, avg_on1);
02439
02440 if((image = cpl_imagelist_get_const(ons, 1)) == NULL) {
02441 cpl_ensure_code(0, cpl_error_get_code());
02442 }
02443
02444 irplib_get_clean_mean_window(image,
02445 detmon_lg_config.llx,
02446 detmon_lg_config.lly,
02447 detmon_lg_config.urx,
02448 detmon_lg_config.ury,
02449 detmon_lg_config.kappa,
02450 detmon_lg_config.niter, &avg_on2, &std);
02451 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02452 cpl_error_get_code());
02453 cpl_table_set_double(gain_table, "MEAN_ON2", pos, avg_on2);
02454
02455 on_dif =
02456 cpl_image_subtract_create(cpl_imagelist_get_const(ons, 0),
02457 cpl_imagelist_get_const(ons, 1));
02458
02459 irplib_get_clean_mean_window(on_dif, detmon_lg_config.llx,
02460 detmon_lg_config.lly,
02461 detmon_lg_config.urx,
02462 detmon_lg_config.ury,
02463 detmon_lg_config.kappa,
02464 detmon_lg_config.niter, &avg_on_dif,
02465 &sig_on_dif);
02466 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02467 cpl_error_get_code());
02468
02469 error = cpl_table_set_double(gain_table, "SIG_ON_DIF", pos, sig_on_dif);
02470 cpl_ensure_code(!error, error);
02471
02472 autocorr = irplib_detmon_autocorr_factor(on_dif, pos, autocorr_images);
02473
02474 if(detmon_lg_config.intermediate) {
02475 error = cpl_imagelist_set(diff_flats, on_dif, pos);
02476 cpl_ensure_code(!error, error);
02477 }
02478
02479
02480 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02481 cpl_error_get_code());
02482
02483 if (!detmon_lg_config.collapse || pos == 0) {
02484 irplib_get_clean_mean_window(cpl_imagelist_get_const(offs, 0),
02485 detmon_lg_config.llx,
02486 detmon_lg_config.lly,
02487 detmon_lg_config.urx,
02488 detmon_lg_config.ury,
02489 detmon_lg_config.kappa,
02490 detmon_lg_config.niter, &avg_off1, &std);
02491 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02492 cpl_error_get_code());
02493 cpl_table_set_double(gain_table, "MEAN_OFF1", pos, avg_off1);
02494 detmon_lg_config.avg_off1 = avg_off1;
02495 irplib_get_clean_mean_window(cpl_imagelist_get_const(offs, 1),
02496 detmon_lg_config.llx,
02497 detmon_lg_config.lly,
02498 detmon_lg_config.urx,
02499 detmon_lg_config.ury,
02500 detmon_lg_config.kappa,
02501 detmon_lg_config.niter, &avg_off2, &std);
02502 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02503 cpl_error_get_code());
02504 cpl_table_set_double(gain_table, "MEAN_OFF2", pos, avg_off2);
02505 detmon_lg_config.avg_off2 = avg_off2;
02506 off_dif =
02507 cpl_image_subtract_create(cpl_imagelist_get_const(offs, 0),
02508 cpl_imagelist_get_const(offs, 1));
02509 irplib_get_clean_mean_window(off_dif, detmon_lg_config.llx,
02510 detmon_lg_config.lly,
02511 detmon_lg_config.urx,
02512 detmon_lg_config.ury,
02513 detmon_lg_config.kappa,
02514 detmon_lg_config.niter, &avg_off_dif,
02515 &sig_off_dif);
02516 cpl_ensure_code(cpl_error_get_code() == CPL_ERROR_NONE,
02517 cpl_error_get_code());
02518 cpl_table_set_double(gain_table, "SIG_OFF_DIF", pos, sig_off_dif);
02519 detmon_lg_config.sig_off_dif = sig_off_dif;
02520 cpl_image_delete(off_dif);
02521 } else {
02522 cpl_table_set_double(gain_table, "MEAN_OFF1", pos,
02523 detmon_lg_config.avg_off1);
02524 cpl_table_set_double(gain_table, "MEAN_OFF2", pos,
02525 detmon_lg_config.avg_off2);
02526 cpl_table_set_double(gain_table, "SIG_OFF_DIF", pos,
02527 detmon_lg_config.sig_off_dif);
02528 }
02529
02530 double_adu = (avg_on1 + avg_on2) - (avg_off1 + avg_off2);
02531
02532 sigma = (sig_on_dif * sig_on_dif) - (sig_off_dif * sig_off_dif);
02533
02534 sigma_corr = autocorr * sigma;
02535
02536 gain = double_adu / sigma;
02537
02538 gain_corr = double_adu / sigma_corr;
02539
02540 if(cpl_table_set_double(gain_table, "GAIN", pos, gain)) {
02541 cpl_ensure_code(0, cpl_error_get_code());
02542 }
02543 if(cpl_table_set_double(gain_table, "AUTOCORR", pos, autocorr)) {
02544 cpl_ensure_code(0, cpl_error_get_code());
02545 }
02546 if(cpl_table_set_double(gain_table, "GAIN_CORR", pos, gain_corr)) {
02547 cpl_ensure_code(0, cpl_error_get_code());
02548 }
02549 if(cpl_table_set_double(gain_table, "ADU", pos, double_adu / 2)) {
02550 cpl_ensure_code(0, cpl_error_get_code());
02551 }
02552
02553
02554 if(cpl_table_set_double
02555 (gain_table, "Y_FIT", pos, sig_on_dif * sig_on_dif)) {
02556 cpl_ensure_code(0, cpl_error_get_code());
02557 }
02558 if(cpl_table_set_double(gain_table, "X_FIT", pos, double_adu)) {
02559 cpl_ensure_code(0, cpl_error_get_code());
02560 }
02561
02562
02563 if(cpl_table_set_double(fit_table, "Y", pos, sig_on_dif * sig_on_dif)) {
02564 cpl_ensure_code(0, cpl_error_get_code());
02565 }
02566 if(cpl_table_set_double(fit_table, "X", pos, double_adu / autocorr)) {
02567 cpl_ensure_code(0, cpl_error_get_code());
02568 }
02569 return CPL_ERROR_NONE;
02570 }
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583 static cpl_image *
02584 irplib_detmon_bpixs(const cpl_imagelist * coeffs, int *nbpixs)
02585 {
02586 int size;
02587 int i;
02588 const cpl_image *cur_coeff;
02589 cpl_stats *stats;
02590 double cur_mean;
02591 double cur_stdev;
02592 double lo_cut;
02593 double hi_cut;
02594 cpl_mask *cur_mask;
02595 cpl_image *cur_image;
02596 cpl_image *bpm = NULL;
02597 double p;
02598
02599 size = cpl_imagelist_get_size(coeffs);
02600
02601 for(i = 0; i < size; i++) {
02602 cur_coeff = cpl_imagelist_get_const(coeffs, i);
02603 if(!i) {
02604 bpm = cpl_image_new(cpl_image_get_size_x(cur_coeff),
02605 cpl_image_get_size_y(cur_coeff),
02606 CPL_TYPE_INT);
02607 }
02608 stats = cpl_stats_new_from_image(cur_coeff,
02609 CPL_STATS_MEAN | CPL_STATS_STDEV);
02610 cur_mean = cpl_stats_get_mean(stats);
02611 cur_stdev = cpl_stats_get_stdev(stats);
02612
02613 lo_cut = cur_mean - detmon_lg_config.kappa * cur_stdev;
02614 hi_cut = cur_mean + detmon_lg_config.kappa * cur_stdev;
02615
02616 cur_mask = cpl_mask_threshold_image_create(cur_coeff, lo_cut, hi_cut);
02617 cpl_mask_not(cur_mask);
02618
02619 *nbpixs += cpl_mask_count(cur_mask);
02620
02621 cur_image = cpl_image_new_from_mask(cur_mask);
02622 p = pow(2, i);
02623 cpl_image_power(cur_image, p);
02624 cpl_image_add(bpm, cur_image);
02625
02626 cpl_mask_delete(cur_mask);
02627 cpl_image_delete(cur_image);
02628 cpl_stats_delete(stats);
02629 }
02630
02631 return bpm;
02632 }
02633
02634
02635
02636
02637
02638
02639
02640
02641
02642
02643
02644
02645
02646 static double
02647 irplib_detmon_autocorr_factor(const cpl_image * image, const int pos,
02648 cpl_imagelist * autocorr_images)
02649 {
02650 cpl_image *autocorr_image;
02651 #ifdef HAVE_FFTW
02652 if(detmon_lg_config.autocorr) {
02653 cpl_msg_info(cpl_func,
02654 "Computing autocorr factor for DIT value nb %d ", pos + 1);
02655
02656
02657 autocorr_image =
02658 irplib_detmon_image_correlate(image, image, detmon_lg_config.m,
02659 detmon_lg_config.m);
02660 if(autocorr_image == NULL) {
02661 return -1;
02662 }
02663 } else {
02664 return 1.0;
02665 }
02666 #else
02667 if(detmon_lg_config.autocorr) {
02668 cpl_msg_info(cpl_func,
02669 "Computing autocorr factor for DIT value nb %d ", pos + 1);
02670
02671 autocorr_image =
02672 irplib_detmon_autocorrelate(image, detmon_lg_config.m,
02673 detmon_lg_config.m);
02674 if(autocorr_image == NULL) {
02675 return -1;
02676 }
02677 } else {
02678 return 1.0;
02679 }
02680 #endif
02681 cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), -1);
02682
02683
02684
02685
02686 if (detmon_lg_config.intermediate) {
02687 cpl_imagelist_set(autocorr_images, autocorr_image, pos);
02688 return cpl_image_get_flux(autocorr_image);
02689 } else {
02690 double autocorr = cpl_image_get_flux(autocorr_image);
02691 cpl_image_delete(autocorr_image);
02692 return autocorr;
02693 }
02694 }
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
02705 static cpl_error_code
02706 irplib_detmon_lg_save(const cpl_parameterlist * parlist,
02707 cpl_frameset * frameset,
02708 const char *recipe_name,
02709 const char *pipeline_name,
02710 const char *pafregexp,
02711 const char *procatg_lintbl,
02712 const char *procatg_gaintbl,
02713 const char *procatg_lincoeff,
02714 const char *procatg_bpm,
02715 const char *procatg_corr,
02716 const char *procatg_diff,
02717 const char *package,
02718 cpl_imagelist ** coeffs,
02719 cpl_table ** gain_table,
02720 cpl_table ** linear_table,
02721 cpl_image ** bpms,
02722 cpl_imagelist ** autocorr_images,
02723 cpl_imagelist ** diff_flats,
02724 cpl_propertylist ** qclist,
02725 const int flag_sets,
02726 const int which_set,
02727 const cpl_frameset * usedframes, cpl_boolean opt_nir)
02728 {
02729
02730 cpl_frame *ref_frame;
02731 cpl_propertylist *plist;
02732 cpl_propertylist *mainplist;
02733 char *name_o = NULL;
02734
02735
02736
02737 int nb_images;
02738 int i;
02739 cpl_error_code error;
02740 cpl_propertylist ** xplist = NULL;
02741
02742
02743
02744 if (detmon_lg_config.exts < 0) {
02745 const char * filename =
02746 cpl_frame_get_filename(cpl_frameset_get_first(frameset));
02747 xplist =
02748 (cpl_propertylist **) cpl_malloc(detmon_lg_config.nb_extensions *
02749 sizeof(cpl_propertylist *));
02750 for (i = 0; i < detmon_lg_config.nb_extensions; i ++) {
02751 xplist[i] = cpl_propertylist_load_regexp(filename, i+1,
02752 "ESO DET", 0);
02753 error = cpl_propertylist_append(xplist[i], qclist[i]);
02754 cpl_ensure_code(!error, error);
02755 }
02756 }
02757
02758
02759
02760
02761 ref_frame = cpl_frameset_get_first(frameset);
02762
02763 if((mainplist =
02764 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
02765 0)) == NULL) {
02766 cpl_msg_error(cpl_func, "getting header from reference frame");
02767 cpl_ensure_code(0, cpl_error_get_code());
02768 }
02769
02770
02771
02772
02773
02774
02775
02776
02777 if(!flag_sets) {
02778 name_o = cpl_sprintf("%s_linearity_table.fits", recipe_name);
02779 assert(name_o != NULL);
02780 } else {
02781 name_o =
02782 cpl_sprintf("%s_linearity_table_set%02d.fits", recipe_name,
02783 which_set);
02784 assert(name_o != NULL);
02785 }
02786
02787 if (detmon_lg_config.exts >= 0) {
02788
02789 if(cpl_dfs_save_table(frameset, parlist, usedframes, linear_table[0],
02790 NULL, recipe_name, procatg_lintbl, qclist[0], NULL,
02791 package, name_o)) {
02792 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
02793 cpl_free(name_o);
02794 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02795 }
02796 } else {
02797
02798 if(cpl_dfs_save_table(frameset, parlist, usedframes, linear_table[0],
02799 xplist[0], recipe_name, procatg_lintbl, NULL,
02800 NULL, package, name_o)) {
02801 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
02802 cpl_free(name_o);
02803 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02804 }
02805 for(i = 1; i < detmon_lg_config.nb_extensions; i++) {
02806 error =
02807 cpl_table_save(linear_table[i], NULL, xplist[i], name_o,
02808 CPL_IO_EXTEND);
02809 cpl_ensure_code(!error, error);
02810 }
02811 }
02812
02813
02814 cpl_free(name_o);
02815
02816
02817
02818
02819
02820
02821
02822 if(!flag_sets) {
02823 name_o = cpl_sprintf("%s_gain_table.fits", recipe_name);
02824 assert(name_o != NULL);
02825 } else {
02826 name_o =
02827 cpl_sprintf("%s_gain_table_set%02d.fits", recipe_name,
02828 which_set);
02829 assert(name_o != NULL);
02830 }
02831
02832 if (detmon_lg_config.exts >= 0) {
02833
02834 if(cpl_dfs_save_table(frameset, parlist, usedframes, gain_table[0],
02835 NULL, recipe_name, procatg_gaintbl, qclist[0],
02836 NULL, package, name_o)) {
02837 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
02838 cpl_free(name_o);
02839 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02840 }
02841 } else {
02842
02843 if(cpl_dfs_save_table(frameset, parlist, usedframes, gain_table[0],
02844 xplist[0], recipe_name, procatg_gaintbl, NULL,
02845 NULL, package, name_o)) {
02846 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
02847 cpl_free(name_o);
02848 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02849 }
02850 for(i = 1; i < detmon_lg_config.nb_extensions; i++) {
02851 error =
02852 cpl_table_save(gain_table[i], NULL, xplist[i], name_o,
02853 CPL_IO_EXTEND);
02854 cpl_ensure_code(!error, error);
02855 }
02856 }
02857
02858
02859 cpl_free(name_o);
02860
02861 if(opt_nir == NIR) {
02862
02863
02864
02865
02866
02867
02868 if(!flag_sets) {
02869 name_o =
02870 cpl_sprintf("%s_coeffs_cube.fits", recipe_name);
02871 assert(name_o != NULL);
02872 } else {
02873 name_o =
02874 cpl_sprintf("%s_coeffs_cube_set%02d.fits",
02875 recipe_name, which_set);
02876 assert(name_o != NULL);
02877 }
02878
02879
02880 if(detmon_lg_config.exts >= 0) {
02881 #if defined CPL_VERSION_CODE && CPL_VERSION_CODE > CPL_VERSION(4, 0, 1)
02882 if(cpl_dfs_save_imagelist
02883 (frameset, parlist, usedframes, *coeffs, CPL_BPP_IEEE_FLOAT,
02884 recipe_name, procatg_lincoeff, qclist[0], NULL, package,
02885 name_o)) {
02886 cpl_msg_error(cpl_func, "Cannot save the product: %s",
02887 name_o);
02888 cpl_free(name_o);
02889 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02890
02891 }
02892 #else
02893 cpl_propertylist * hlist = cpl_propertylist_new();
02894 cpl_frame * product_frame = NULL;
02895
02896 product_frame = cpl_frame_new() ;
02897 cpl_frame_set_filename(product_frame, name_o);
02898 cpl_frame_set_tag(product_frame, procatg_lincoeff);
02899 cpl_frame_set_type(product_frame, CPL_FRAME_TYPE_IMAGE);
02900 cpl_frame_set_group(product_frame, CPL_FRAME_GROUP_PRODUCT);
02901 cpl_frame_set_level(product_frame, CPL_FRAME_LEVEL_FINAL);
02902
02903 if(cpl_dfs_setup_product_header(hlist,product_frame,frameset,
02904 parlist,recipe_name,
02905 package, "PRO-1.15") !=
02906 CPL_ERROR_NONE) {
02907 cpl_msg_error(cpl_func,
02908 "Problem in the product DFS-compliance");
02909 }
02910
02911 cpl_propertylist_append(hlist, mainplist);
02912
02913 error = cpl_imagelist_save(coeffs[0], name_o, CPL_BPP_IEEE_FLOAT,
02914 hlist, CPL_IO_DEFAULT);
02915 cpl_ensure_code(!error, error);
02916 cpl_propertylist_delete(hlist);
02917 cpl_frame_delete(product_frame);
02918 #endif
02919 } else {
02920 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
02921 CPL_BPP_IEEE_FLOAT, recipe_name,
02922 procatg_lincoeff, NULL, NULL,
02923 package, name_o)) {
02924 cpl_msg_error(cpl_func, "Cannot save the product: %s",
02925 name_o);
02926 cpl_free(name_o);
02927 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02928 }
02929
02930 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
02931 error =
02932 cpl_imagelist_save(coeffs[i],
02933 name_o, CPL_BPP_IEEE_FLOAT, xplist[i],
02934 CPL_IO_EXTEND);
02935 cpl_ensure_code(!error, error);
02936 }
02937 }
02938 cpl_free(name_o);
02939
02940
02941
02942
02943
02944
02945
02946
02947 if(!flag_sets) {
02948 name_o = cpl_sprintf("%s_bpm.fits", recipe_name);
02949 assert(name_o != NULL);
02950 } else {
02951 name_o =
02952 cpl_sprintf("%s_bpm_set%02d.fits", recipe_name, which_set);
02953 assert(name_o != NULL);
02954 }
02955
02956
02957 if(detmon_lg_config.exts >= 0) {
02958 if(cpl_dfs_save_image(frameset, parlist, usedframes, *bpms,
02959 CPL_BPP_IEEE_FLOAT, recipe_name,
02960 procatg_bpm, qclist[0], NULL, package,
02961 name_o)) {
02962 cpl_msg_error(cpl_func, "Cannot save the product: %s",
02963 name_o);
02964 cpl_free(name_o);
02965 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02966 }
02967 } else {
02968 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
02969 CPL_BPP_IEEE_FLOAT, recipe_name,
02970 procatg_bpm, NULL, NULL, package,
02971 name_o)) {
02972 cpl_msg_error(cpl_func, "Cannot save the product: %s",
02973 name_o);
02974 cpl_free(name_o);
02975 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
02976 }
02977
02978 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
02979 error =
02980 cpl_image_save(bpms[i], name_o, CPL_BPP_IEEE_FLOAT,
02981 xplist[i], CPL_IO_EXTEND);
02982 cpl_ensure_code(!error, error);
02983 }
02984 }
02985
02986 cpl_free(name_o);
02987
02988
02989 }
02990
02991 if(detmon_lg_config.intermediate) {
02992
02993
02994
02995
02996 int j;
02997
02998 nb_images = cpl_imagelist_get_size(autocorr_images[0]);
02999 cpl_ensure_code(nb_images > 0, CPL_ERROR_DATA_NOT_FOUND);
03000
03001
03002 for(i = 0; i < nb_images; i++) {
03003
03004 if(!flag_sets) {
03005 name_o =
03006 cpl_sprintf("%s_autocorr_%d.fits", recipe_name, i);
03007 assert(name_o != NULL);
03008 } else {
03009 name_o =
03010 cpl_sprintf("%s_autocorr_%d_set%02d.fits",
03011 recipe_name, i, which_set);
03012 assert(name_o != NULL);
03013 }
03014
03015
03016
03017 if(detmon_lg_config.exts >= 0) {
03018 if(cpl_dfs_save_image
03019 (frameset, parlist, usedframes,
03020 cpl_imagelist_get(*autocorr_images, i), CPL_BPP_IEEE_FLOAT,
03021 recipe_name, procatg_corr, qclist[0], NULL, package,
03022 name_o)) {
03023 cpl_msg_error(cpl_func, "Cannot save the product: %s",
03024 name_o);
03025 cpl_free(name_o);
03026 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03027
03028 }
03029 } else {
03030 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
03031 CPL_BPP_IEEE_FLOAT, recipe_name,
03032 procatg_corr, NULL, NULL,
03033 package, name_o)) {
03034 cpl_msg_error(cpl_func, "Cannot save the product: %s",
03035 name_o);
03036 cpl_free(name_o);
03037 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03038 }
03039
03040 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
03041 error =
03042 cpl_image_save(cpl_imagelist_get(autocorr_images[j], i),
03043 name_o, CPL_BPP_IEEE_FLOAT, xplist[j],
03044 CPL_IO_EXTEND);
03045 cpl_ensure_code(!error, error);
03046 }
03047 }
03048 cpl_free(name_o);
03049 }
03050
03051
03052
03053
03054
03055
03056 for(i = 0; i < nb_images; i++) {
03057
03058 if(!flag_sets) {
03059 name_o =
03060 cpl_sprintf("%s_diff_flat_%d.fits", recipe_name, i);
03061 assert(name_o != NULL);
03062 } else {
03063 name_o =
03064 cpl_sprintf("%s_diff_flat_%d_set%02d.fits",
03065 recipe_name, i, which_set);
03066 assert(name_o != NULL);
03067 }
03068
03069
03070
03071 if(detmon_lg_config.exts >= 0) {
03072 if(cpl_dfs_save_image
03073 (frameset, parlist, usedframes,
03074 cpl_imagelist_get(*diff_flats, i), CPL_BPP_IEEE_FLOAT,
03075 recipe_name, procatg_diff, qclist[0], NULL, package,
03076 name_o)) {
03077 cpl_msg_error(cpl_func, "Cannot save the product: %s",
03078 name_o);
03079 cpl_free(name_o);
03080 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03081
03082 }
03083 } else {
03084 if(cpl_dfs_save_image(frameset, parlist, usedframes, NULL,
03085 CPL_BPP_IEEE_FLOAT, recipe_name,
03086 procatg_diff, NULL, NULL,
03087 package, name_o)) {
03088 cpl_msg_error(cpl_func, "Cannot save the product: %s",
03089 name_o);
03090 cpl_free(name_o);
03091 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03092 }
03093
03094 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
03095 error =
03096 cpl_image_save(cpl_imagelist_get(diff_flats[j], i),
03097 name_o, CPL_BPP_IEEE_FLOAT, xplist[j],
03098 CPL_IO_EXTEND);
03099 cpl_ensure_code(!error, error);
03100 }
03101 }
03102 cpl_free(name_o);
03103 }
03104
03105 }
03106
03107
03108
03109
03110
03111
03112 for(i = 0; i < detmon_lg_config.nb_extensions; i++) {
03113 cpl_propertylist * paflist = cpl_propertylist_new();
03114
03115
03116
03117 if(detmon_lg_config.exts >= 0) {
03118 if((plist =
03119 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03120 detmon_lg_config.exts)) == NULL) {
03121 cpl_msg_error(cpl_func, "getting header from reference frame");
03122 cpl_ensure_code(0, cpl_error_get_code());
03123 }
03124
03125 if(!flag_sets) {
03126 name_o = cpl_sprintf("%s.paf", recipe_name);
03127 assert(name_o != NULL);
03128 } else {
03129 name_o = cpl_sprintf("%s_set%02d.paf", recipe_name, which_set);
03130 assert(name_o != NULL);
03131 }
03132 } else {
03133 if((plist =
03134 cpl_propertylist_load(cpl_frame_get_filename(ref_frame),
03135 i+1)) == NULL) {
03136 cpl_msg_error(cpl_func, "getting header from reference frame");
03137 cpl_ensure_code(0, cpl_error_get_code());
03138 }
03139
03140 if(!flag_sets) {
03141 name_o = cpl_sprintf("%s_ext%02d.paf", recipe_name, i+1);
03142 assert(name_o != NULL);
03143 } else {
03144 name_o = cpl_sprintf("%s_set%02d_ext%02d.paf", recipe_name, which_set, i+1);
03145 assert(name_o != NULL);
03146 }
03147 }
03148
03149
03150 cpl_propertylist_copy_property_regexp(paflist, plist,
03151 pafregexp, 0);
03152 cpl_propertylist_copy_property_regexp(paflist, mainplist,
03153 pafregexp, 0);
03154
03155 error = cpl_propertylist_append(paflist, qclist[i]);
03156 cpl_ensure_code(!error, error);
03157
03158
03159 if(cpl_dfs_save_paf(pipeline_name, recipe_name, paflist, name_o)) {
03160 cpl_msg_error(cpl_func, "Cannot save the product: %s", name_o);
03161 cpl_free(name_o);
03162 cpl_propertylist_delete(paflist);
03163 cpl_propertylist_delete(plist);
03164 cpl_propertylist_delete(mainplist);
03165 cpl_free(name_o);
03166 cpl_ensure_code(0, CPL_ERROR_FILE_NOT_CREATED);
03167 }
03168 cpl_propertylist_delete(paflist);
03169 cpl_propertylist_delete(plist);
03170 cpl_free(name_o);
03171 }
03172
03173 cpl_propertylist_delete(mainplist);
03174
03175 return cpl_error_get_code();
03176 }
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187 static cpl_error_code
03188 irplib_detmon_opt_contamination(const cpl_image * reduced,
03189 cpl_propertylist * qclist)
03190 {
03191 cpl_error_code error;
03192 double median[5];
03193
03194 median[0] = cpl_image_get_median_window(reduced,
03195 detmon_lg_config.llx1,
03196 detmon_lg_config.lly1,
03197 detmon_lg_config.urx1,
03198 detmon_lg_config.ury1);
03199 error = cpl_propertylist_append_double(qclist, "ESO QC CONTAM1",
03200 median[0]);
03201 cpl_ensure_code(!error, error);
03202
03203 median[1] = cpl_image_get_median_window(reduced,
03204 detmon_lg_config.llx2,
03205 detmon_lg_config.lly2,
03206 detmon_lg_config.urx2,
03207 detmon_lg_config.ury2);
03208 error = cpl_propertylist_append_double(qclist, "ESO QC CONTAM2",
03209 median[1]);
03210 cpl_ensure_code(!error, error);
03211
03212 median[2] = cpl_image_get_median_window(reduced,
03213 detmon_lg_config.llx3,
03214 detmon_lg_config.lly3,
03215 detmon_lg_config.urx3,
03216 detmon_lg_config.ury3);
03217 error = cpl_propertylist_append_double(qclist, "ESO QC CONTAM3",
03218 median[2]);
03219 cpl_ensure_code(!error, error);
03220
03221 median[3] = cpl_image_get_median_window(reduced,
03222 detmon_lg_config.llx4,
03223 detmon_lg_config.lly4,
03224 detmon_lg_config.urx4,
03225 detmon_lg_config.ury4);
03226 error = cpl_propertylist_append_double(qclist, "ESO QC CONTAM4",
03227 median[3]);
03228 cpl_ensure_code(!error, error);
03229
03230 median[4] = cpl_image_get_median_window(reduced,
03231 detmon_lg_config.llx5,
03232 detmon_lg_config.lly5,
03233 detmon_lg_config.urx5,
03234 detmon_lg_config.ury5);
03235 error = cpl_propertylist_append_double(qclist, "ESO QC CONTAM5",
03236 median[4]);
03237 cpl_ensure_code(!error, error);
03238
03239 return CPL_ERROR_NONE;
03240 }
03241
03242 static int
03243 irplib_detmon_opt_lampcr(cpl_frameset * cur_fset)
03244 {
03245 cpl_image *on;
03246 cpl_image *off;
03247 cpl_frame *first_off;
03248 cpl_frame *first_on;
03249 cpl_propertylist *plist;
03250 double dit;
03251
03252 if((first_off = cpl_frameset_get_first(cur_fset)) == NULL) {
03253 cpl_ensure_code(0, cpl_error_get_code());
03254 }
03255 if((first_on = cpl_frameset_get_next(cur_fset)) == NULL) {
03256 cpl_ensure_code(0, cpl_error_get_code());
03257 }
03258
03259 on = cpl_image_load(cpl_frame_get_filename(first_on),
03260 CPL_TYPE_FLOAT, 0, 0);
03261 off = cpl_image_load(cpl_frame_get_filename(first_off),
03262 CPL_TYPE_FLOAT, 0, 0);
03263 cpl_image_subtract(on, off);
03264
03265 plist = cpl_propertylist_load(cpl_frame_get_filename(first_on), 0);
03266 if(plist == NULL) {
03267 cpl_msg_error(cpl_func, "getting header from reference frame");
03268 cpl_image_delete(on);
03269 cpl_image_delete(off);
03270 cpl_ensure_code(0, cpl_error_get_code());
03271 }
03272
03273 dit = irplib_pfits_get_exptime(plist);
03274
03275 detmon_lg_config.cr = cpl_image_get_mean(on) / dit;
03276
03277 cpl_image_delete(on);
03278 cpl_image_delete(off);
03279 cpl_propertylist_delete(plist);
03280
03281 return 0;
03282 }
03283
03284 int
03285 irplib_detmon_lg_dfs_set_groups(cpl_frameset * set,
03286 const char *tag_on, const char *tag_off)
03287 {
03288 cpl_frame *cur_frame;
03289 const char *tag;
03290 int nframes;
03291 int i;
03292
03293
03294 if(set == NULL)
03295 return -1;
03296
03297
03298 nframes = cpl_frameset_get_size(set);
03299
03300
03301 for(i = 0; i < nframes; i++) {
03302 cur_frame = cpl_frameset_get_frame(set, i);
03303 tag = cpl_frame_get_tag(cur_frame);
03304
03305
03306 if(!strcmp(tag, tag_on) || !strcmp(tag, tag_off))
03307 cpl_frame_set_group(cur_frame, CPL_FRAME_GROUP_RAW);
03308
03309
03310
03311
03312
03313 }
03314 return 0;
03315 }
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328 cpl_error_code
03329 irplib_detmon_lg_reduce_all(const cpl_table * linear_table,
03330 cpl_table * fit_table,
03331 cpl_propertylist * qclist,
03332 cpl_imagelist ** coeffs_ptr,
03333 cpl_image ** bpms_ptr,
03334 cpl_vector * x_pos,
03335 cpl_imagelist * linearity_inputs,
03336 cpl_table * gain_table, cpl_boolean opt_nir,
03337 int which_ext)
03338 {
03339
03340 int nbpixs = 0;
03341 const int nsets = cpl_table_get_nrow(linear_table);
03342 int i;
03343 double autocorr;
03344 cpl_polynomial *poly_linfit = NULL;
03345 cpl_image *fiterror = NULL;
03346 char * name_o1 = NULL;
03347 char * name_o2 = NULL;
03348
03349
03350
03351 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
03352
03353 if (!strcmp(detmon_lg_config.method, "PTC")) {
03354
03355 if (detmon_lg_config.exts >= 0) {
03356 cpl_msg_info(cpl_func,
03357 "Polynomial fitting for the GAIN (constant term method)");
03358 } else {
03359 cpl_msg_info(cpl_func,
03360 "Polynomial fitting for the GAIN (constant term method)"
03361 " for extension nb %d", which_ext);
03362 }
03363 skip_if(irplib_detmon_lg_qc_ptc(gain_table, fit_table, qclist));
03364 } else {
03365 skip_if(irplib_detmon_lg_qc_med(gain_table, qclist));
03366 }
03367
03368
03369
03370 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_LAMP_FLUX,
03371 detmon_lg_config.cr));
03372 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_LAMP_FLUX,
03373 DETMON_QC_LAMP_FLUX_C));
03374
03375
03376 autocorr = cpl_table_get_column_median(gain_table, "AUTOCORR");
03377 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_AUTOCORR,
03378 autocorr));
03379 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_AUTOCORR,
03380 DETMON_QC_AUTOCORR_C));
03381
03382 if (detmon_lg_config.exts >= 0) {
03383 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix");
03384 } else {
03385 cpl_msg_info(cpl_func, "Polynomial fitting pix-to-pix"
03386 " for extension nb %d", which_ext);
03387 }
03388
03389 if(opt_nir == OPT) {
03390 double mse;
03391
03392 const cpl_vector *x =
03393 cpl_vector_wrap(nsets,
03394 (double *)cpl_table_get_data_double_const(linear_table,
03395 "MED"));
03396 const cpl_vector *y =
03397 cpl_vector_wrap(nsets,
03398 (double *)cpl_table_get_data_double_const(linear_table,
03399 "DIT"));
03400
03401 if(x == NULL || y == NULL) {
03402 cpl_vector_unwrap((cpl_vector *)x);
03403 cpl_vector_unwrap((cpl_vector *)y);
03404
03405
03406
03407
03408
03409
03410 skip_if(1);
03411 }
03412
03413 cpl_msg_info(cpl_func, "Polynomial fitting for the LINEARITY");
03414 poly_linfit = cpl_polynomial_fit_1d_create(x, y,
03415 detmon_lg_config.order,
03416 &mse);
03417 if(poly_linfit == NULL) {
03418 cpl_vector_unwrap((cpl_vector *)x);
03419 cpl_vector_unwrap((cpl_vector *)y);
03420
03421 skip_if(1);
03422 }
03423
03424 cpl_vector_unwrap((cpl_vector *)x);
03425 cpl_vector_unwrap((cpl_vector *)y);
03426
03427 for(i = 1; i <= detmon_lg_config.order; i++) {
03428 const double coeff =
03429 cpl_polynomial_get_coeff(poly_linfit, &i);
03430 char *name_o =
03431 cpl_sprintf("ESO QC LIN COEF%d", i);
03432 assert(name_o != NULL);
03433 skip_if(cpl_propertylist_append_double(qclist, name_o, coeff));
03434 cpl_free(name_o);
03435 }
03436 } else {
03437 *coeffs_ptr =
03438 cpl_fit_imagelist_polynomial(x_pos, linearity_inputs, 0,
03439 detmon_lg_config.order, FALSE,
03440 CPL_TYPE_FLOAT, fiterror);
03441 skip_if(*coeffs_ptr == NULL);
03442
03443 for(i = 0; i < detmon_lg_config.order; i++) {
03444 cpl_image *image = cpl_imagelist_get(*coeffs_ptr, i);
03445 name_o1 = cpl_sprintf("ESO QC LIN COEF%d", i);
03446 name_o2 = cpl_sprintf("ESO QC LIN COEF%d ERR", i);
03447 assert(name_o1 != NULL);
03448 assert(name_o2 != NULL);
03449 skip_if(cpl_propertylist_append_double(qclist, name_o1,
03450 cpl_image_get_median(image)));
03451 cpl_free(name_o1);
03452 name_o1= NULL;
03453 skip_if(cpl_propertylist_append_double(qclist, name_o2,
03454 cpl_image_get_stdev(image)));
03455 cpl_free(name_o2);
03456 name_o2= NULL;
03457 }
03458 }
03459
03460
03461
03462 if (detmon_lg_config.exts >= 0) {
03463 cpl_msg_info(cpl_func, "Bad pixel detection");
03464 } else {
03465 cpl_msg_info(cpl_func, "Bad pixel detection"
03466 " for extension nb %d", which_ext);
03467 }
03468
03469 if(opt_nir == NIR) {
03470 *bpms_ptr = irplib_detmon_bpixs(*coeffs_ptr, &nbpixs);
03471 skip_if(*bpms_ptr == NULL);
03472 }
03473
03474 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_NUM_BPM, nbpixs));
03475 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_NUM_BPM,
03476 DETMON_QC_NUM_BPM_C));
03477
03478 end_skip;
03479
03480 cpl_free(name_o1);
03481 cpl_free(name_o2);
03482 cpl_image_delete(fiterror);
03483 cpl_polynomial_delete(poly_linfit);
03484
03485 return cpl_error_get_code();
03486 }
03487
03488 static cpl_error_code
03489 irplib_detmon_lg_qc_ptc(const cpl_table * gain_table,
03490 const cpl_table * fit_table,
03491 cpl_propertylist * qclist)
03492 {
03493 double mse;
03494 cpl_polynomial *poly_fit = NULL;
03495 cpl_polynomial *poly_fit2 = NULL;
03496 int i;
03497 const int nsets = cpl_table_get_nrow(gain_table);
03498
03499
03500
03501
03502
03503 const cpl_vector *x;
03504 const cpl_vector *y;
03505
03506 cpl_ensure_code(gain_table != NULL, CPL_ERROR_NULL_INPUT);
03507 cpl_ensure_code(fit_table != NULL, CPL_ERROR_NULL_INPUT);
03508 cpl_ensure_code(qclist != NULL, CPL_ERROR_NULL_INPUT);
03509
03510 x = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "X_FIT"));
03511
03512 y = cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(gain_table, "Y_FIT"));
03513
03514 skip_if(x == NULL || y == NULL);
03515
03516 poly_fit = cpl_polynomial_fit_1d_create(x, y, 1, &mse);
03517 skip_if(poly_fit == NULL);
03518
03519
03520 i = 1;
03521 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_CONAD,
03522 cpl_polynomial_get_coeff(poly_fit, &i)));
03523 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_CONAD,
03524 DETMON_QC_CONAD_C));
03525
03526 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,
03527 1 / cpl_polynomial_get_coeff(poly_fit,
03528 &i)));
03529 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
03530 DETMON_QC_GAIN_C));
03531
03532 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE, mse));
03533 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
03534 DETMON_QC_GAIN_MSE_C));
03535 i = 0;
03536 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_RON,
03537 cpl_polynomial_get_coeff(poly_fit, &i)));
03538 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_RON,
03539 DETMON_QC_RON_C));
03540
03541 if(detmon_lg_config.autocorr){
03542 const cpl_vector *x2 =
03543 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(fit_table, "X"));
03544 const cpl_vector *y2 =
03545 cpl_vector_wrap(nsets, (double *)cpl_table_get_data_double_const(fit_table, "Y"));
03546
03547 if(x2 == NULL || y2 == NULL) {
03548 cpl_vector_unwrap((cpl_vector *)x2);
03549 cpl_vector_unwrap((cpl_vector *)y2);
03550
03551
03552
03553
03554
03555
03556 skip_if(1);
03557 }
03558
03559
03560 poly_fit2 = cpl_polynomial_fit_1d_create(x2, y2, 1, &mse);
03561 if(poly_fit2 == NULL) {
03562 cpl_vector_unwrap((cpl_vector *)x2);
03563 cpl_vector_unwrap((cpl_vector *)y2);
03564
03565 skip_if(1);
03566 }
03567
03568 cpl_vector_unwrap((cpl_vector *)x2);
03569 cpl_vector_unwrap((cpl_vector *)y2);
03570
03571
03572 i = 1;
03573 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
03574 1 / cpl_polynomial_get_coeff(poly_fit, &i)));
03575 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
03576 DETMON_QC_GAIN_CORR_C));
03577 }
03578
03579 end_skip;
03580
03581
03582 cpl_vector_unwrap((cpl_vector *)x);
03583 cpl_vector_unwrap((cpl_vector *)y);
03584 cpl_polynomial_delete(poly_fit);
03585 cpl_polynomial_delete(poly_fit2);
03586
03587 return cpl_error_get_code();
03588 }
03589
03590 static cpl_error_code
03591 irplib_detmon_lg_qc_med(const cpl_table * gain_table,
03592 cpl_propertylist * qclist)
03593 {
03594 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN,
03595 cpl_table_get_column_median
03596 (gain_table, "GAIN")));
03597 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN,
03598 DETMON_QC_GAIN_C));
03599
03600 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_MSE,
03601 cpl_table_get_column_stdev
03602 (gain_table, "GAIN")));
03603 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_MSE,
03604 DETMON_QC_GAIN_MSE_C));
03605
03606 skip_if(cpl_propertylist_append_double(qclist, DETMON_QC_GAIN_CORR,
03607 cpl_table_get_column_median
03608 (gain_table, "GAIN_CORR")));
03609 skip_if(cpl_propertylist_set_comment(qclist, DETMON_QC_GAIN_CORR,
03610 DETMON_QC_GAIN_CORR_C));
03611 end_skip;
03612
03613 return cpl_error_get_code();
03614 }
03615
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628 static cpl_error_code
03629 irplib_detmon_lg_rescale(cpl_imagelist * to_rescale)
03630 {
03631 cpl_error_code error;
03632
03633 double med1 =
03634 cpl_image_get_median(cpl_imagelist_get(to_rescale, 0));
03635 double med2 =
03636 cpl_image_get_median(cpl_imagelist_get(to_rescale, 1));
03637
03638 error = cpl_error_get_code();
03639 cpl_ensure_code(!error, error);
03640
03641 if(fabs(med1 / med2 - 1) > 0.001) {
03642 if(med1 > med2)
03643 error = cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 0),
03644 med1 / med2);
03645 else
03646 error = cpl_image_divide_scalar(cpl_imagelist_get(to_rescale, 1),
03647 med2 / med1);
03648 }
03649 cpl_ensure_code(!error, error);
03650
03651 return CPL_ERROR_NONE;
03652 }
03653
03654 cpl_imagelist **
03655 irplib_detmon_ilist_load_fset(const cpl_frameset * set, cpl_type type)
03656 {
03657 int j;
03658 cpl_error_code error;
03659
03660
03661 cpl_imagelist ** lists =
03662 (cpl_imagelist **) cpl_malloc(detmon_lg_config.nb_extensions *
03663 sizeof(cpl_imagelist *));
03664 if(detmon_lg_config.exts < 0) {
03665 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
03666 lists[j] = cpl_imagelist_new();
03667 }
03668 }
03669
03670 if(detmon_lg_config.exts >= 0) {
03671 *lists = cpl_imagelist_load_frameset(set, type, 1,
03672 detmon_lg_config.exts);
03673
03674 } else {
03675 cpl_imagelist *lists_all_exts =
03676 cpl_imagelist_load_frameset(set, type, 1, -1);
03677 for(j = 0; j < detmon_lg_config.nb_extensions; j++) {
03678 int nframes = cpl_frameset_get_size(set);
03679 int k;
03680 for(k = 0; k < nframes; k++) {
03681 cpl_image *image =
03682 cpl_imagelist_unset(lists_all_exts,
03683 (detmon_lg_config.
03684 nb_extensions - 1 - j) * k);
03685 cpl_ensure(image != NULL, CPL_ERROR_ILLEGAL_INPUT, NULL);
03686 error = cpl_imagelist_set(lists[j], image, k);
03687 cpl_ensure(!error, error, NULL);
03688 }
03689 }
03690
03691 cpl_imagelist_delete(lists_all_exts);
03692 }
03693
03694 return lists;
03695 }
03696
03697
03698
03699
03700
03701
03702
03703
03704
03705
03706
03707
03708
03709
03710
03711
03712
03713
03714 cpl_frameset *
03715 irplib_detmon_pair_extract(const cpl_frameset * set,
03716 int * selection, int selected,
03717 int * nsets_extracted,
03718 int * with_equal_dit,
03719 int onoff)
03720 {
03721 cpl_frameset * pair = NULL;
03722 int new_with_equal_dit = 0;
03723
03724 cpl_ensure(set != NULL, CPL_ERROR_NULL_INPUT, NULL);
03725 cpl_ensure(selection != NULL, CPL_ERROR_NULL_INPUT, NULL);
03726 cpl_ensure(nsets_extracted != NULL, CPL_ERROR_NULL_INPUT, NULL);
03727 cpl_ensure(with_equal_dit != NULL, CPL_ERROR_NULL_INPUT, NULL);
03728
03729
03730 cpl_ensure(selected < *nsets_extracted, CPL_ERROR_ILLEGAL_INPUT, NULL);
03731
03732 pair = cpl_frameset_extract(set, selection, selected);
03733 cpl_ensure(pair != NULL, cpl_error_get_code(), NULL);
03734
03735
03736
03737
03738
03739 if(cpl_frameset_get_size(pair) % 2 != 0) {
03740
03741 cpl_frameset_delete(pair);
03742 return NULL;
03743 }
03744
03745
03746 if(cpl_frameset_get_size(pair) != 2) {
03747 new_with_equal_dit = cpl_frameset_get_size(pair) / 2;
03748 if(onoff == 1) {
03749 *with_equal_dit = new_with_equal_dit;
03750 } else {
03751 if (*with_equal_dit != 0 && new_with_equal_dit != *with_equal_dit) {
03752 cpl_msg_error(cpl_func, "Mismatch between ON and OFF pairs of frames of equal DIT value");
03753 cpl_frameset_delete(pair);
03754 return NULL;
03755 }
03756 }
03757 }
03758
03759
03760 if (new_with_equal_dit != 0) {
03761 int found = 0;
03762 int j;
03763 for(j = 0; j < cpl_frameset_get_size(set); j++) {
03764
03765 if(selection[j] == selected) {
03766 found++;
03767
03768 if((found - 1) / 2 != 0) {
03769 selection[j] =
03770 *nsets_extracted + (found - 1) / 2 - 1;
03771
03772 }
03773 }
03774 }
03775
03776 if((onoff == 1 && detmon_lg_config.collapse == TRUE ) ||
03777 (onoff == 0 && detmon_lg_config.collapse == FALSE) ){
03778 *nsets_extracted += (found - 1) / 2;
03779 }
03780 cpl_frameset_delete(pair);
03781 pair = cpl_frameset_extract(set, selection, selected);
03782
03783 }
03784
03785 return pair;
03786 }