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
00038
00042
00043
00044
00045
00046 #include "uves_reduce.h"
00047
00048 #include <uves.h>
00049 #include <uves_extract.h>
00050 #include <uves_backsub.h>
00051 #include <uves_parameters.h>
00052 #include <uves_flatfield.h>
00053 #include <uves_rebin.h>
00054 #include <uves_merge.h>
00055 #include <uves_utils_cpl.h>
00056 #include <uves_utils_wrappers.h>
00057 #include <uves_pfits.h>
00058 #include <uves_dfs.h>
00059 #include <uves_dump.h>
00060 #include <uves_plot.h>
00061 #include <uves_error.h>
00062
00063 #include <cpl.h>
00064 #include <float.h>
00065 #include <string.h>
00066
00067
00068
00069 #define UVES_MIN_LINE_ROWS_TO_MAKE_FIT 5
00070 #define UVES_BLAZE_DUMMY_VAL 999.
00071 static cpl_error_code
00072 extract_ff_rebin_merge(cpl_image *back_subbed,
00073 cpl_image *backsubbed_noise,
00074 const uves_propertylist *backsubbed_header,
00075 const cpl_image *master_flat,
00076 cpl_image *mflat_noise,
00077 const cpl_table *ordertable,
00078 const polynomial *order_locations,
00079 const cpl_table *linetable,
00080 const uves_propertylist *linetable_header[3],
00081 const polynomial *dispersion_relation[3],
00082 double slit_length,
00083 double slit_offset,
00084 int window,
00085 enum uves_chip chip,
00086 bool blaze_correct,
00087 bool tilt_corr,
00088 bool DEBUG,
00089 const cpl_parameterlist *parameters,
00090 const char *context,
00091 const char *mode,
00092 flatfielding_method ff_method,
00093 extract_method ee_method,
00094 merge_method m_method,
00095
00096 cpl_image **x,
00097 uves_propertylist **x_header,
00098 cpl_image **fx,
00099 cpl_table **cosmic_mask,
00100 cpl_image **wave_map,
00101 cpl_image **flatfielded_variance,
00102 uves_propertylist **flatfielded_variance_header,
00103 cpl_image **resampled_spectrum,
00104 cpl_image **resampled_mf,
00105 cpl_image **merged_sky,
00106 cpl_image **rebinned_spectrum,
00107 cpl_image **rebinned_noise,
00108 uves_propertylist **rebinned_header,
00109 cpl_image **merged_spectrum,
00110 cpl_image **merged_noise,
00111 uves_propertylist **merged_header,
00112 cpl_table** info_tbl,
00113 cpl_table **order_trace);
00114
00115 static cpl_image *
00116 subtract_sky(cpl_image *rebinned_obj,
00117 cpl_image *rebinned_obj_noise,
00118 uves_propertylist *rebinned_obj_header,
00119 const cpl_image *rebinned_sky1,
00120 const cpl_image *rebinned_sky1_noise,
00121 const uves_propertylist *rebinned_sky1_header,
00122 const cpl_image *rebinned_sky2,
00123 const cpl_image *rebinned_sky2_noise,
00124 const uves_propertylist *rebinned_sky2_header,
00125 cpl_image **merged_obj,
00126 cpl_image **merged_obj_noise,
00127 uves_propertylist *merged_obj_header,
00128 const cpl_image *merged_sky1,
00129 const cpl_image *merged_sky1_noise,
00130 const uves_propertylist *merged_sky1_header,
00131 const cpl_image *merged_sky2,
00132 const cpl_image *merged_sky2_noise,
00133 const uves_propertylist *merged_sky2_header,
00134 double obj_slit,
00135 double sky1_slit,
00136 double sky2_slit);
00137
00138
00139 static cpl_image *
00140 subtract_sky_row(cpl_image *obj,
00141 cpl_image *obj_noise,
00142 double obj_start,
00143 double obj_end,
00144 double obj_slit,
00145 const cpl_image *sky1,
00146 const cpl_image *sky1_noise,
00147 double sky1_start,
00148 double sky1_end,
00149 double sky1_slit,
00150 const cpl_image *sky2,
00151 const cpl_image *sky2_noise,
00152 double sky2_start,
00153 double sky2_end,
00154 double sky2_slit,
00155 int row,
00156 double wavestep,
00157 double *common_start,
00158 double *common_end);
00159
00160 static double get_offset(const cpl_image *back_subbed,
00161 const cpl_table *ordertable,
00162 const polynomial *order_locations,
00163 double search_range,
00164 int nsamples,
00165 double *doffset);
00166
00167 static cpl_image *
00168 uves_get_blaze_ratio(const cpl_image *spectrum,
00169 const cpl_image *spectrum_noise);
00170
00171
00172
00173
00174
00175
00176
00177
00184
00185
00186 cpl_parameterlist *
00187 uves_reduce_define_parameters(void)
00188 {
00189 const char *name = "";
00190 char *full_name = NULL;
00191 cpl_parameterlist *parameters = NULL;
00192 cpl_parameter *p = NULL;
00193
00194 parameters = cpl_parameterlist_new();
00195
00196
00197
00198
00199 if (cpl_error_get_code() == CPL_ERROR_NONE)
00200 {
00201 uves_propagate_parameters_step(UVES_BACKSUB_ID, parameters,
00202 UVES_REDUCE_ID, NULL);
00203 }
00204
00205
00206
00207
00208
00209 if (cpl_error_get_code() == CPL_ERROR_NONE)
00210 {
00211 uves_propagate_parameters_step(UVES_EXTRACT_ID, parameters,
00212 UVES_REDUCE_ID, NULL);
00213 }
00214
00215
00216
00217
00218
00219 if (cpl_error_get_code() == CPL_ERROR_NONE)
00220 {
00221 name = "slitlength";
00222 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00223
00224 uves_parameter_new_range(p, full_name,
00225 CPL_TYPE_DOUBLE,
00226 "Extraction slit length (in pixels). "
00227 "If negative, the value "
00228 "inferred from the raw frame header is used",
00229 UVES_REDUCE_ID,
00230 -1.0,
00231 -2.0, DBL_MAX);
00232
00233 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00234 cpl_parameterlist_append(parameters, p);
00235 cpl_free(full_name);
00236 }
00237
00238 if (cpl_error_get_code() == CPL_ERROR_NONE)
00239 {
00240 name = "skysub";
00241 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00242
00243 uves_parameter_new_value(p, full_name,
00244 CPL_TYPE_BOOL,
00245 "Do sky-subtraction (only applicable to linear "
00246 "and average extractions)?",
00247 UVES_REDUCE_ID,
00248 true);
00249
00250 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00251 cpl_parameterlist_append(parameters, p);
00252 cpl_free(full_name);
00253 }
00254
00255 if (cpl_error_get_code() == CPL_ERROR_NONE)
00256 {
00257 name = "objoffset";
00258 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00259
00260 uves_parameter_new_value(p, full_name,
00261 CPL_TYPE_DOUBLE,
00262 "Offset (in pixels) of extraction slit "
00263 "with respect to center of order. "
00264 "This parameter applies to linear/average/"
00265 "optimal extraction. "
00266 "For linear/average extraction, if the related "
00267 "parameter objslit is negative, the offset is "
00268 "automatically determined by measuring the "
00269 "actual object position. ",
00270 UVES_REDUCE_ID,
00271 0.0);
00272
00273 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00274 cpl_parameterlist_append(parameters, p);
00275 cpl_free(full_name);
00276 }
00277
00278 if (cpl_error_get_code() == CPL_ERROR_NONE)
00279 {
00280 name = "objslit";
00281 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00282
00283 uves_parameter_new_range(p, full_name,
00284 CPL_TYPE_DOUBLE,
00285 "Object window size (in pixels). This must "
00286 "be less than the total slit length. If "
00287 "negative, the default value (half of full "
00288 "slit length) is used. The upper and lower "
00289 "sky windows are defined as the part of the "
00290 "full slit (if any) outside the object "
00291 "window. The center of the object window "
00292 "is determined by the offset parameter. "
00293 "This parameter does not apply to optimal "
00294 "extraction.",
00295 UVES_REDUCE_ID,
00296 -1.0,
00297 -2.0, DBL_MAX);
00298
00299 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00300 cpl_parameterlist_append(parameters, p);
00301 cpl_free(full_name);
00302 }
00303
00304 if (cpl_error_get_code() == CPL_ERROR_NONE)
00305 {
00306 name = "tiltcorr";
00307 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00308
00309 uves_parameter_new_value(p, full_name,
00310 CPL_TYPE_BOOL,
00311 "If enabled (recommended), the provided "
00312 "dispersion solutions "
00313 "obtained at different slit positions are "
00314 "interpolated linearly at the actually "
00315 "measured position of the object/sky. "
00316 "Line tilt correction is currently not supported "
00317 "for 2d extraction, in which case the "
00318 "dispersion solution obtained at the middle of "
00319 "the slit is always used.",
00320 UVES_REDUCE_ID,
00321 true);
00322
00323 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00324 cpl_parameterlist_append(parameters, p);
00325 cpl_free(full_name);
00326 }
00327
00328
00329
00330
00331
00332
00333
00334 if (cpl_error_get_code() == CPL_ERROR_NONE)
00335 {
00336 name = "ffmethod";
00337 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00338
00339 uves_parameter_new_enum(p, full_name,
00340 CPL_TYPE_STRING,
00341 "Flat-fielding method. If set to 'pixel', "
00342 "flat-fielding is done in pixel-pixel space "
00343 "(before extraction); if set to 'extract', "
00344 "flat-fielding is performed in pixel-order "
00345 "space (i.e. after extraction). If set to "
00346 "'no', no flat-field correction is done",
00347 UVES_REDUCE_ID,
00348 "extract",
00349
00350 3,
00351 "pixel", "extract", "no");
00352
00353 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00354 cpl_parameterlist_append(parameters, p);
00355 cpl_free(full_name);
00356 }
00357
00358
00359
00360
00361
00362 if (cpl_error_get_code() == CPL_ERROR_NONE)
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 if (cpl_error_get_code() == CPL_ERROR_NONE)
00388 {
00389 uves_propagate_parameters_step(UVES_REBIN_ID, parameters,
00390 UVES_REDUCE_ID, NULL);
00391 }
00392
00393
00394
00395
00396
00397 if (cpl_error_get_code() == CPL_ERROR_NONE)
00398 {
00399 name = "merge";
00400 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00401
00402 uves_parameter_new_enum(p, full_name,
00403 CPL_TYPE_STRING,
00404 "Order merging method. If 'optimal', the "
00405 "flux in the overlapping region is set "
00406 "to the (optimally computed, using the "
00407 "uncertainties) average of single order "
00408 "spectra. If 'sum', the flux in the "
00409 "overlapping region is computed as the "
00410 "sum of the single order spectra. If 'noappend' "
00411 "the spectrum is simply rebinned but not merged."
00412 "If flat-fielding is done, method 'optimal' "
00413 "is recommended, otherwise 'sum'.",
00414 UVES_REDUCE_ID,
00415 "optimal",
00416 3,
00417 "optimal", "sum", "noappend");
00418
00419 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00420 cpl_parameterlist_append(parameters, p);
00421 cpl_free(full_name);
00422
00423
00424 name = "merge_delt1";
00425 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00426
00427 uves_parameter_new_range(p, full_name,
00428 CPL_TYPE_DOUBLE,
00429 "Order merging left hand (short wavelength) "
00430 "cut. To reduce the amount of order "
00431 "overlapping regions we allow to cut short and "
00432 "long wavelength ranges. "
00433 "This may reduce the ripple possibly "
00434 "introduced by the order merging. "
00435 "Suggested values are: "
00436 "10 (W<=390), 12 (390<W<=437, 520<W<=564), "
00437 "14 (437<W<=520, 564<W) ",
00438 UVES_REDUCE_ID,
00439 0.,0.,20.);
00440
00441 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00442 cpl_parameterlist_append(parameters, p);
00443 cpl_free(full_name);
00444
00445
00446 name = "merge_delt2";
00447 full_name = uves_sprintf("%s.%s", UVES_REDUCE_ID, name);
00448
00449 uves_parameter_new_range(p, full_name,
00450 CPL_TYPE_DOUBLE,
00451 "Order merging right hand (long wavelength) "
00452 "cut. To reduce the amount of order "
00453 "overlapping regions we allow to cut short and "
00454 "long wavelength ranges. "
00455 "This may reduce the ripple possibly "
00456 "introduced by the order merging. "
00457 "Suggested values is 4",
00458 UVES_REDUCE_ID,
00459 0.,0.,20.);
00460
00461 cpl_parameter_set_alias(p, CPL_PARAMETER_MODE_CLI, name);
00462 cpl_parameterlist_append(parameters, p);
00463 cpl_free(full_name);
00464
00465
00466
00467 }
00468
00469 if (cpl_error_get_code() != CPL_ERROR_NONE)
00470 {
00471 cpl_msg_error(__func__, "Creation of reduction parameters failed: '%s'",
00472 cpl_error_get_where());
00473 cpl_parameterlist_delete(parameters);
00474 return NULL;
00475 }
00476
00477
00478 return parameters;
00479 }
00480
00481
00572
00573
00574 cpl_error_code uves_reduce(const cpl_image *raw_image,
00575 const uves_propertylist *raw_header,
00576 const uves_propertylist *rotated_header,
00577 const cpl_image *master_bias,
00578 const cpl_image *master_dark,
00579 const uves_propertylist *mdark_header,
00580 const cpl_image *master_flat,
00581 const uves_propertylist *mflat_header,
00582 const cpl_table *ordertable,
00583 const polynomial *order_locations,
00584 const cpl_table *linetable[3],
00585 const uves_propertylist *linetable_header[3],
00586 const polynomial *dispersion_relation[3],
00587 enum uves_chip chip,
00588
00589 bool DEBUG,
00590
00591
00592
00593
00594 const cpl_parameterlist *parameters,
00595 const char *rec_id,
00596 const char *mode,
00597
00598 cpl_image **x, uves_propertylist **x_header,
00599 cpl_image **fx,
00600 cpl_table **cosmic_mask,
00601 cpl_image **wave_map,
00602 cpl_image **background,
00603 cpl_image **flatfielded_variance,
00604 uves_propertylist **flatfielded_variance_header,
00605 cpl_image **resampled_spectrum,
00606 cpl_image **resampled_mf,
00607 cpl_image **merged_sky,
00608
00609 cpl_image **rebinned_spectrum,
00610 cpl_image **rebinned_noise,
00611 uves_propertylist **rebinned_header,
00612 cpl_image **merged_spectrum ,
00613 cpl_image **merged_noise,
00614 uves_propertylist **merged_header,
00615
00616 cpl_image **reduced_rebinned_spectrum,
00617 cpl_image **reduced_rebinned_noise,
00618 cpl_image **reduced_spectrum ,
00619 cpl_image **reduced_noise,
00620 cpl_table **info_tbl,
00621 double *extraction_slit,
00622 cpl_table **order_trace)
00623 {
00624
00625 char context[80];
00626 flatfielding_method ff_method;
00627 merge_method m_method;
00628 extract_method ex_method;
00629 bool blaze_corr=false;
00630 bool sky_sub;
00631 bool tilt_corr;
00632 double full_slit;
00633 double obj_slit;
00634 double obj_offset;
00635 double exptime=0;
00636 cpl_image *back_subbed = NULL;
00637 cpl_image *backsubbed_noise = NULL;
00638
00639 cpl_image *mflat_noise = NULL;
00640
00641 cpl_image *simple_extracted = NULL;
00642 cpl_image *simple_extracted_mf = NULL;
00643
00644 cpl_image *sky_lo = NULL;
00645 cpl_image *sky_lo_noise = NULL;
00646 cpl_image *sky_hi = NULL;
00647 cpl_image *sky_hi_noise = NULL;
00648 uves_propertylist *sky_lo_header = NULL;
00649 uves_propertylist *sky_hi_header = NULL;
00650
00651 cpl_image *sky_lo_rebinned = NULL;
00652 cpl_image *sky_lo_rebinned_noise = NULL;
00653 cpl_image *sky_hi_rebinned = NULL;
00654 cpl_image *sky_hi_rebinned_noise = NULL;
00655 uves_propertylist *sky_lo_rebinned_header = NULL;
00656 uves_propertylist *sky_hi_rebinned_header = NULL;
00657
00658 char *subcontext = NULL;
00659 double header_full_slit;
00660
00661 char *ex_method_string = NULL;
00662 double dnoise=-999;
00663 double bnoise=-999;
00664 bool has_fnoise=false;
00665 double fnoise=0;
00666 uves_propertylist* local_raw_header=NULL;
00667
00668 passure( background != NULL, " "); *background = NULL;
00669
00670 passure( rebinned_spectrum != NULL, " "); *rebinned_spectrum = NULL;
00671 passure( rebinned_noise != NULL, " "); *rebinned_noise = NULL;
00672 passure( rebinned_header != NULL, " "); *rebinned_header = NULL;
00673 passure( merged_spectrum != NULL, " "); *merged_spectrum = NULL;
00674 passure( merged_sky != NULL, " "); *merged_sky = NULL;
00675 passure( merged_noise != NULL, " "); *merged_noise = NULL;
00676 passure( merged_header != NULL, " "); *merged_header = NULL;
00677 passure( reduced_rebinned_spectrum != NULL, " "); *reduced_rebinned_spectrum = NULL;
00678 passure( reduced_rebinned_noise != NULL, " "); *reduced_rebinned_noise = NULL;
00679 passure( reduced_spectrum != NULL, " "); *reduced_spectrum = NULL;
00680 passure( reduced_noise != NULL, " "); *reduced_noise = NULL;
00681
00682 passure( (flatfielded_variance == NULL) == (flatfielded_variance_header == NULL),
00683 "%d %d", flatfielded_variance == NULL, flatfielded_variance_header == NULL);
00684
00685 assure_nomsg( extraction_slit != NULL, CPL_ERROR_NULL_INPUT );
00686
00687
00688
00689 {
00690 if(strcmp(mode,".efficiency")==0) {
00691 sprintf(context,"%s%s",rec_id,mode);
00692 } else {
00693 sprintf(context,"%s",rec_id);
00694 }
00695 check( ff_method = uves_get_flatfield_method(parameters, context, UVES_REDUCE_ID),
00696 "Could not read flat-fielding method");
00697
00698 assure( ff_method == FF_NO || master_flat != NULL, CPL_ERROR_NULL_INPUT,
00699 "Flat-fielding requested, but no flat field provided");
00700
00701
00702 check( ex_method = uves_get_extract_method(parameters, context,
00703 UVES_REDUCE_ID "." UVES_EXTRACT_ID),
00704 "Could not get extraction method");
00705
00706 assure( ex_method != EXTRACT_WEIGHTED, CPL_ERROR_ILLEGAL_INPUT,
00707 "Weighted extraction is used only internally, "
00708 "as a part of optimal extraction");
00709
00710 check( m_method = uves_get_merge_method(parameters, context, UVES_REDUCE_ID),
00711 "Could not get merging method");
00712
00713
00714
00715
00716
00717
00718
00719 blaze_corr=false;
00720 check( uves_get_parameter(parameters, rec_id, UVES_REDUCE_ID,
00721 "skysub", CPL_TYPE_BOOL, &sky_sub),
00722 "Could not read parameter");
00723
00724 check( uves_get_parameter(parameters, rec_id, UVES_REDUCE_ID,
00725 "tiltcorr", CPL_TYPE_BOOL, &tilt_corr),
00726 "Could not read parameter");
00727
00728 assure( !blaze_corr || ff_method != FF_NO, CPL_ERROR_INCOMPATIBLE_INPUT,
00729 "Sorry, cannot apply blaze function "
00730 "correction when no flatfielding is done");
00731
00732 if (blaze_corr && ex_method == EXTRACT_2D)
00733 {
00734 uves_msg_warning("There will be no blaze function correction "
00735 "for 2d extraction");
00736 }
00737
00738 if (ff_method == FF_NO && m_method == MERGE_OPTIMAL)
00739 {
00740 uves_msg_warning("No flat-fielding done, but merge method = optimal. "
00741 "Is this really what you want?");
00742 }
00743 if (ff_method != FF_NO && m_method == MERGE_SUM)
00744 {
00745 uves_msg_warning("Flat-fielding will be done, but merge method = sum. "
00746 "Is this really what you want?");
00747 }
00748
00749 check( uves_get_parameter(parameters, rec_id, UVES_REDUCE_ID, "slitlength",
00750 CPL_TYPE_DOUBLE, &full_slit), "Could not read parameter");
00751
00752 check( uves_get_parameter(parameters, rec_id, UVES_REDUCE_ID, "objoffset",
00753 CPL_TYPE_DOUBLE, &obj_offset),
00754 "Could not read parameter");
00755 check( uves_get_parameter(parameters, rec_id, UVES_REDUCE_ID, "objslit",
00756 CPL_TYPE_DOUBLE, &obj_slit),
00757 "Could not read parameter");
00758 }
00759
00760
00761 subcontext = uves_sprintf("%s.%s", rec_id, UVES_REDUCE_ID);
00762
00763
00764 check( back_subbed = cpl_image_duplicate(raw_image),
00765 "Error copying raw image");
00766
00767 local_raw_header=(uves_propertylist* )raw_header;
00768 if (master_bias != NULL)
00769 {
00770 uves_msg("Subtracting master bias");
00771 check( uves_subtract_bias(back_subbed, master_bias),
00772 "Error subtracting master bias");
00773 bnoise=cpl_image_get_stdev(master_bias);
00774 uves_propertylist_append_c_double(local_raw_header,UVES_BNOISE,bnoise,
00775 "Master bias RMS on frame");
00776
00777 }
00778 else
00779 {
00780 uves_msg("Skipping bias subtraction");
00781 }
00782
00783
00784 if (master_dark != NULL)
00785 {
00786 uves_msg("Subtracting master dark");
00787 check( uves_subtract_dark(back_subbed, raw_header,
00788 master_dark, mdark_header),
00789 "Error subtracting master dark");
00790 dnoise=cpl_image_get_stdev(master_dark);
00791 uves_msg_warning("noise master dark (not rescaled) %g",dnoise);
00792 exptime=uves_pfits_get_exptime(mdark_header);
00793 uves_msg_warning("Exptime master dark %g",exptime);
00794
00795 uves_propertylist_append_c_double(local_raw_header,UVES_DNOISE,dnoise,
00796 "Master dark RMS on frame");
00797 uves_propertylist_append_c_double(local_raw_header,UVES_DTIME,exptime,
00798 "Master dark RMS on frame");
00799 }
00800 else
00801 {
00802 uves_msg("Skipping dark subtraction");
00803 }
00804
00805 if (master_flat != NULL)
00806 {
00807 has_fnoise=uves_propertylist_contains(mflat_header,UVES_FNOISE);
00808 if(has_fnoise) {
00809 fnoise=uves_propertylist_get_double(mflat_header,UVES_FNOISE);
00810 }
00811 }
00812 if (DEBUG) check( uves_save_image_local("Bias/dark subtracted raw image", "pre",
00813 back_subbed, chip, -1, -1, rotated_header, true),
00814 "Error saving image");
00815
00816 uves_msg("Creating noise image");
00817
00818
00819 check( backsubbed_noise = uves_define_noise(back_subbed, raw_header,
00820 1, chip),
00821 "Could not calculate noise image");
00822
00823
00824 if (DEBUG) check( uves_save_image_local("Background subtracted raw image noise",
00825 "errb", backsubbed_noise,
00826 chip, -1, -1, rotated_header, true),
00827 "Error saving image");
00828
00829
00830 uves_msg("Subtracting inter-order background");
00831
00832 check( uves_backsub_spline(back_subbed, raw_header,
00833 ordertable, order_locations,
00834 parameters, subcontext,
00835 chip,
00836 false,
00837 background),
00838 "Error subtracting background");
00839
00840
00841 if (DEBUG) check( uves_save_image_local("Background subtracted raw image", "b",
00842 back_subbed, chip, -1, -1, rotated_header, true),
00843 "Error saving image");
00844
00845
00846
00847
00848
00849 if (ff_method == FF_NO)
00850 {
00851 uves_msg("Skipping flat-field correction");
00852 }
00853
00854 if (ff_method != FF_NO || resampled_mf != NULL)
00855 {
00856 int mflat_datancom;
00857
00858
00859 if (DEBUG)
00860 {
00861 check( uves_save_image_local("Master flat image", "mf",
00862 master_flat,
00863 chip, -1, -1, rotated_header, true),
00864 "Error saving master flat image");
00865 }
00866
00867
00868
00869 check( mflat_datancom = uves_pfits_get_datancom(mflat_header),
00870 "Error reading number of raw flat field frames "
00871 "used for master flat image");
00872
00873 uves_msg("Creating master flat noise image");
00874
00875 check( mflat_noise = uves_define_noise(master_flat, mflat_header,
00876 mflat_datancom,chip),
00877 "Could not define master flat noise");
00878
00879
00880
00881 if (DEBUG)
00882 {
00883 check( uves_save_image_local("Master flat noise", "errmf", mflat_noise,
00884 chip, -1, -1, rotated_header, true),
00885 "Error saving master flat image");
00886 }
00887 }
00888
00889
00890
00891
00892
00893 check( header_full_slit = uves_pfits_get_slitlength_pixels(raw_header, chip),
00894 "Could not read slit length");
00895
00896
00897 if (full_slit < 0)
00898 {
00899
00900
00901
00902 full_slit = uves_max_double(1.0, header_full_slit - 2);
00903 }
00904 else
00905 {
00906
00907 if (full_slit > header_full_slit)
00908 {
00909 uves_msg_warning("Specified full slit length (%e pixels) "
00910 "is larger than input header slit "
00911 "length (%e pixels)",
00912 full_slit, header_full_slit);
00913 }
00914 }
00915
00916 uves_msg("Slit length = %.2f pixels", full_slit);
00917 *extraction_slit = full_slit;
00918
00919 if (ff_method == FF_PIXEL)
00920 {
00921 uves_msg("Dividing by normalized master flat-field (method = pixel)");
00922
00923 check( uves_flatfielding(back_subbed, backsubbed_noise,
00924 master_flat, mflat_noise),
00925 "Could not perform flat-fielding");
00926
00927
00928 if (DEBUG)
00929 {
00930 check( uves_save_image_local("Flat-fielded image", "fb",
00931 back_subbed, chip, -1, -1,
00932 rotated_header, true),
00933 "Error saving flat-fielded image");
00934
00935 check( uves_save_image_local("Flat-fielded image noise", "errfb",
00936 backsubbed_noise, chip, -1, -1,
00937 rotated_header, true),
00938 "Error saving noise of flat-fielded image");
00939 }
00940 }
00941
00942
00943 switch(ex_method)
00944 {
00945 case EXTRACT_OPTIMAL:
00946 {
00947 int window_number = 2;
00948
00949 check( extract_ff_rebin_merge(back_subbed,
00950 backsubbed_noise,
00951 raw_header,
00952 master_flat,
00953 mflat_noise,
00954 ordertable,
00955 order_locations,
00956 linetable[window_number-1],
00957 linetable_header,
00958 dispersion_relation,
00959 full_slit,
00960 obj_offset,
00961 window_number,
00962 chip,
00963 blaze_corr,
00964 tilt_corr,
00965 DEBUG,
00966 parameters,
00967 subcontext,
00968 mode,
00969 ff_method,
00970 ex_method,
00971 m_method,
00972 NULL,
00973 NULL,
00974 NULL,
00975 cosmic_mask,
00976 wave_map,
00977 flatfielded_variance,
00978 flatfielded_variance_header,
00979 resampled_spectrum,
00980 resampled_mf,
00981 merged_sky,
00982
00983
00984 rebinned_spectrum,
00985 rebinned_noise,
00986 rebinned_header,
00987 merged_spectrum,
00988 merged_noise,
00989 merged_header,
00990 info_tbl,
00991 order_trace),
00992 "Error during reduction");
00993
00994
00995
00996
00997 check(( *reduced_spectrum = cpl_image_duplicate(*merged_spectrum),
00998 *reduced_noise = cpl_image_duplicate(*merged_noise),
00999 *reduced_rebinned_spectrum = cpl_image_duplicate(*rebinned_spectrum),
01000 *reduced_rebinned_noise = cpl_image_duplicate(*rebinned_noise)),
01001 "Error creating sky-subtracted spectra");
01002 }
01003 break;
01004 case EXTRACT_LINEAR:
01005 case EXTRACT_AVERAGE:
01006 {
01007
01008
01009
01010
01011
01012 const char *slicer_name;
01013 double doffset = 0;
01014 double obj_hi, obj_lo;
01015 double sky_lo_slit, sky_hi_slit;
01016 int window_number;
01017
01018
01019
01020
01021
01022
01023 check( slicer_name = uves_pfits_get_slit1_name(raw_header),
01024 "Could not read slicer id");
01025
01026 uves_msg("Slicer name = '%s'%s", slicer_name,
01027 (strcmp(slicer_name, "FREE") == 0) ? " (no slicer)" : "");
01028
01029 if ( strncmp(slicer_name, "SLIC", 4) == 0)
01030 {
01031
01032
01033
01034
01035 obj_hi = uves_min_double(+full_slit/2, obj_offset + full_slit/2);
01036 obj_lo = uves_max_double(-full_slit/2, obj_offset - full_slit/2);
01037
01038 obj_slit = obj_hi - obj_lo;
01039
01040 sky_lo_slit = -1;
01041 sky_hi_slit = -1;
01042
01043 uves_msg("Extraction slits (full slit = %.2f pixels)", full_slit);
01044 uves_msg("|* Sky 1 *|******** Obj ********|* Sky 2 *|");
01045 uves_msg("|* %-5.1f *|******* %-5.1f *******|* %-5.1f *|",
01046 0.0, obj_slit, 0.0);
01047 }
01048 else
01049 {
01050
01051 assure( strncmp(slicer_name, "FREE", 4) == 0, CPL_ERROR_UNSUPPORTED_MODE,
01052 "Unrecognized slicer name: '%s'. "
01053 "Recognized names include 'FREE', 'SLIC#1', 'SLIC#2', 'SLIC#3'.",
01054 slicer_name);
01055
01056
01057 if (obj_slit < 0)
01058 {
01059 check( obj_offset =
01060 get_offset(back_subbed,
01061 ordertable, order_locations,
01062 full_slit/2,
01063 10,
01064 &doffset),
01065 "Could not find object offset");
01066
01067 uves_msg("Measured object position = %.2f +- %.2f pixels",
01068 obj_offset, doffset);
01069
01070 if (sky_sub)
01071 {
01072
01073
01074 obj_hi = uves_min_double(+full_slit/2,
01075 obj_offset + full_slit/4.0);
01076 obj_lo = uves_max_double(-full_slit/2,
01077 obj_offset - full_slit/4.0);
01078 }
01079 else
01080
01081 {
01082 obj_hi = uves_min_double(+full_slit/2,
01083 obj_offset + full_slit/2.0);
01084 obj_lo = uves_max_double(-full_slit/2,
01085 obj_offset - full_slit/2.0);
01086 }
01087 obj_slit = obj_hi - obj_lo;
01088 }
01089 else
01090
01091 {
01092 uves_msg("Object offset = %.2f pixels", obj_offset);
01093
01094 obj_hi = obj_offset + obj_slit / 2;
01095 obj_lo = obj_offset - obj_slit / 2;
01096 }
01097
01098 uves_msg("Object slit = %.2f pixels", obj_slit);
01099
01100 assure( -full_slit / 2 < obj_offset && obj_offset < full_slit / 2,
01101 CPL_ERROR_ILLEGAL_INPUT,
01102 "Object is outside slit! Offset = %f, Slit length = %f",
01103 obj_offset, full_slit);
01104
01105
01106 if (sky_sub)
01107 {
01108 sky_lo_slit = obj_lo - (-full_slit/2);
01109 sky_hi_slit = full_slit/2 - obj_hi;
01110
01111 assure( sky_lo_slit > 0 || sky_hi_slit > 0, CPL_ERROR_ILLEGAL_INPUT,
01112 "At least one sky slit length must be positive. "
01113 "They are %f and %f pixels", sky_lo_slit, sky_hi_slit);
01114 }
01115 else
01116 {
01117 sky_lo_slit = -1;
01118 sky_hi_slit = -1;
01119 }
01120
01121 uves_msg("Extraction slits (full slit = %.2f pixels)", full_slit);
01122 uves_msg("|*** Sky 1 **%s|**** Obj ****|%s** Sky 2 ***|",
01123 (obj_lo > -obj_hi) ? "*" : "",
01124 (obj_lo > -obj_hi) ? "" : "*");
01125 uves_msg("|*** %-5.1f **%s|*** %-5.1f ***|%s** %-5.1f ***|",
01126 sky_lo_slit, (obj_lo > -obj_hi) ? "*" : "",
01127 obj_slit , (obj_lo > -obj_hi) ? "" : "*",
01128 sky_hi_slit);
01129 }
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143 window_number = 1;
01144 if ( sky_lo_slit > 0 )
01145 {
01146 uves_msg("Processing sky 1 window");
01147 check( extract_ff_rebin_merge(back_subbed,
01148 backsubbed_noise,
01149 raw_header,
01150 master_flat,
01151 mflat_noise,
01152 ordertable,
01153 order_locations,
01154 linetable[2-1],
01155 linetable_header,
01156 dispersion_relation,
01157 sky_lo_slit,
01158 -full_slit/2 + sky_lo_slit/2,
01159
01160 window_number,
01161 chip,
01162 blaze_corr,
01163 tilt_corr,
01164 DEBUG,
01165 parameters,
01166 subcontext,
01167 mode,
01168 ff_method,
01169 ex_method,
01170 m_method,
01171 NULL,
01172 NULL,
01173 NULL,
01174 NULL,
01175 wave_map,
01176 NULL,
01177 NULL,
01178 NULL,
01179 NULL,
01180 NULL,
01181 &sky_lo_rebinned,
01182 &sky_lo_rebinned_noise,
01183 &sky_lo_rebinned_header,
01184 &sky_lo,
01185 &sky_lo_noise,
01186 &sky_lo_header,
01187 NULL,
01188 NULL),
01189 "Error processing lower sky window");
01190 }
01191 else
01192 {
01193 uves_msg("Skipping sky 1 window");
01194 sky_lo_rebinned = NULL;
01195 sky_lo = NULL;
01196 }
01197
01198
01199 window_number = 3;
01200 if ( sky_hi_slit > 0 )
01201 {
01202 uves_msg("Processing sky 2 window");
01203
01204 uves_free_propertylist(rebinned_header);
01205 check( extract_ff_rebin_merge(back_subbed,
01206 backsubbed_noise,
01207 raw_header,
01208 master_flat,
01209 mflat_noise,
01210 ordertable,
01211 order_locations,
01212 linetable[2-1],
01213 linetable_header,
01214 dispersion_relation,
01215 sky_hi_slit,
01216 full_slit/2 - sky_hi_slit/2,
01217
01218 window_number,
01219 chip,
01220 blaze_corr,
01221 tilt_corr,
01222 DEBUG,
01223 parameters,
01224 subcontext,
01225 mode,
01226 ff_method,
01227 ex_method,
01228 m_method,
01229 NULL,
01230 NULL,
01231 NULL,
01232 NULL,
01233 wave_map,
01234 NULL,
01235 NULL,
01236 NULL,
01237 NULL,
01238 NULL,
01239 &sky_hi_rebinned,
01240 &sky_hi_rebinned_noise,
01241 &sky_hi_rebinned_header,
01242 &sky_hi,
01243 &sky_hi_noise,
01244 &sky_hi_header,
01245 NULL,
01246 NULL),
01247 "Error processing upper sky window");
01248 }
01249 else
01250 {
01251 uves_msg("Skipping sky 2 window");
01252 sky_hi_rebinned = NULL;
01253 sky_hi = NULL;
01254 }
01255
01256
01257 window_number = 2;
01258 uves_msg("Processing object window");
01259 uves_free_propertylist(rebinned_header);
01260 check( extract_ff_rebin_merge(back_subbed, backsubbed_noise, raw_header,
01261 master_flat, mflat_noise,
01262 ordertable, order_locations,
01263 linetable[window_number-1],
01264 linetable_header,
01265 dispersion_relation,
01266 obj_slit,
01267 obj_offset,
01268
01269 window_number,
01270 chip,
01271 blaze_corr,
01272 tilt_corr,
01273 DEBUG,
01274 parameters,
01275 subcontext,
01276 mode,
01277 ff_method,
01278 ex_method,
01279 m_method,
01280 NULL,
01281 NULL,
01282 NULL,
01283 NULL,
01284 wave_map,
01285 flatfielded_variance,
01286 flatfielded_variance_header,
01287 resampled_spectrum,
01288 resampled_mf,
01289 NULL,
01290 rebinned_spectrum,
01291 rebinned_noise,
01292 rebinned_header,
01293 merged_spectrum,
01294 merged_noise,
01295 merged_header,
01296 info_tbl,
01297 NULL),
01298 "Error processing object window");
01299
01300 if (info_tbl != NULL && *info_tbl != NULL)
01301 {
01302
01303
01304 int i;
01305 for (i = 0; i < cpl_table_get_nrow(*info_tbl); i++)
01306 {
01307 cpl_table_set_double(*info_tbl, "ObjPosOnSlit", i,
01308 cpl_table_get_double(*info_tbl, "ObjPosOnSlit", i, NULL)
01309 +
01310 ((sky_lo_slit >= 0) ? sky_lo_slit : 0));
01311
01312 }
01313 }
01314
01315
01316
01317
01318
01319
01320
01321 check(( *reduced_spectrum = cpl_image_duplicate(*merged_spectrum),
01322 *reduced_noise = cpl_image_duplicate(*merged_noise)),
01323 "Error allocating sky-subtracted spectra");
01324
01325
01326 check(( *reduced_rebinned_spectrum =
01327 cpl_image_duplicate(*rebinned_spectrum),
01328 *reduced_rebinned_noise =
01329 cpl_image_duplicate(*rebinned_noise)),
01330 "Error allocating sky-subtracted spectra");
01331
01332 if (sky_lo != NULL || sky_hi != NULL)
01333 {
01334 uves_msg("Subtracting sky");
01335
01336 check( *merged_sky =
01337 subtract_sky(*reduced_rebinned_spectrum,
01338 *reduced_rebinned_noise, *rebinned_header,
01339 sky_lo_rebinned, sky_lo_rebinned_noise,
01340 sky_lo_rebinned_header,
01341 sky_hi_rebinned, sky_hi_rebinned_noise,
01342 sky_hi_rebinned_header,
01343 reduced_spectrum, reduced_noise, *merged_header,
01344 sky_lo, sky_lo_noise, sky_lo_header,
01345 sky_hi, sky_hi_noise, sky_hi_header,
01346 (ex_method == EXTRACT_AVERAGE) ? 1.0 : obj_slit,
01347 (ex_method == EXTRACT_AVERAGE) ? 1.0 : sky_lo_slit,
01348 (ex_method == EXTRACT_AVERAGE) ? 1.0 : sky_hi_slit),
01349 "Could not subtract sky");
01350
01351 if (*merged_sky == NULL)
01352 {
01353 uves_msg_warning("Could not subtract sky");
01354 }
01355 }
01356 else
01357 {
01358 uves_msg_low("Skipping sky subtraction");
01359
01360
01361 *merged_sky = NULL;
01362 }
01363 }
01364 break;
01365 case EXTRACT_2D:
01366 {
01367 int window_number = 2;
01368
01369
01370 int half_slit_length;
01371
01372
01373
01374 half_slit_length =
01375 uves_max_int(1, uves_round_double(header_full_slit/2) - 1);
01376
01377 check( extract_ff_rebin_merge(back_subbed,
01378 backsubbed_noise,
01379 raw_header,
01380 master_flat,
01381 mflat_noise,
01382 ordertable,
01383 order_locations,
01384 linetable[window_number-1],
01385 linetable_header,
01386 dispersion_relation,
01387 2*half_slit_length,
01388 0,
01389 window_number,
01390 chip,
01391 blaze_corr,
01392 tilt_corr,
01393 DEBUG,
01394 parameters,
01395 subcontext,
01396 mode,
01397 ff_method,
01398 ex_method,
01399 m_method,
01400 x,
01401 x_header,
01402 fx,
01403 NULL, NULL,
01404 NULL,
01405 NULL,
01406 NULL,
01407
01408 NULL,
01409 NULL,
01410
01411 rebinned_spectrum,
01412 rebinned_noise,
01413 rebinned_header,
01414 merged_spectrum,
01415 merged_noise,
01416 merged_header,
01417 info_tbl,
01418 NULL),
01419 "Error during reduction");
01420
01421 if (x_header != NULL)
01422 {
01423 uves_pfits_set_hs(*x_header,
01424 uves_round_double(2*half_slit_length));
01425 }
01426 if (rebinned_header != NULL)
01427 {
01428 uves_pfits_set_hs(*rebinned_header,
01429 uves_round_double(2*half_slit_length));
01430 }
01431 if (merged_header != NULL)
01432 {
01433 uves_pfits_set_hs(*merged_header,
01434 uves_round_double(2*half_slit_length));
01435 }
01436
01437
01438
01439
01440
01441 check(( *reduced_spectrum = cpl_image_duplicate(*merged_spectrum),
01442 *reduced_noise = cpl_image_duplicate(*merged_noise),
01443 *reduced_rebinned_spectrum = cpl_image_duplicate(*rebinned_spectrum),
01444 *reduced_rebinned_noise = cpl_image_duplicate(*rebinned_noise)),
01445 "Error allocating reduced spectra");
01446 }
01447 break;
01448 default:
01449 assure( false, CPL_ERROR_ILLEGAL_INPUT,
01450 "Unknown extraction method: %d", ex_method);
01451 break;
01452 }
01453
01454 cleanup:
01455 uves_free_image(&back_subbed);
01456 uves_free_image(&backsubbed_noise);
01457 uves_free_image(&mflat_noise);
01458 uves_free_image(&simple_extracted);
01459 uves_free_image(&simple_extracted_mf);
01460 uves_free_image(&sky_lo);
01461 uves_free_image(&sky_lo_noise);
01462 uves_free_image(&sky_hi);
01463 uves_free_image(&sky_hi_noise);
01464 uves_free_image(&sky_lo_rebinned);
01465 uves_free_image(&sky_lo_rebinned_noise);
01466 uves_free_image(&sky_hi_rebinned);
01467 uves_free_image(&sky_hi_rebinned_noise);
01468 uves_free_propertylist(&sky_lo_header);
01469 uves_free_propertylist(&sky_hi_header);
01470 uves_free_propertylist(&sky_lo_rebinned_header);
01471 uves_free_propertylist(&sky_hi_rebinned_header);
01472
01473 cpl_free(subcontext);
01474 cpl_free(ex_method_string);
01475
01476 if (cpl_error_get_code() != CPL_ERROR_NONE)
01477 {
01478 uves_free_image(background);
01479 uves_free_image(flatfielded_variance);
01480 uves_free_propertylist(flatfielded_variance_header);
01481 uves_free_image(resampled_spectrum);
01482 uves_free_image(resampled_mf);
01483 uves_free_image(merged_sky);
01484 uves_free_image(rebinned_spectrum);
01485 uves_free_image(rebinned_noise);
01486 uves_free_propertylist(rebinned_header);
01487
01488 uves_free_image(merged_noise);
01489 uves_free_image(merged_spectrum);
01490 uves_free_propertylist(merged_header);
01491 }
01492
01493 return cpl_error_get_code();
01494 }
01495
01496
01497
01507
01508 static polynomial *
01509 interpolate_wave(const polynomial *dispersion_relation[3],
01510 const uves_propertylist *linetable_header[3],
01511 double objoffset)
01512 {
01513 polynomial *dispersion = NULL;
01514 polynomial *q1 = NULL;
01515 polynomial *q2 = NULL;
01516 cpl_table *offset = cpl_table_new(3);
01517 int ilow, ihigh;
01518 double offset1, offset2;
01519
01520
01521 cpl_table_new_column(offset, "Index", CPL_TYPE_INT);
01522 cpl_table_new_column(offset, "Offset", CPL_TYPE_DOUBLE);
01523
01524 {
01525 int i;
01526 bool reverse;
01527 for (i = 0; i < 3; i++) {
01528 cpl_table_set_int(offset, "Index", i, i);
01529 cpl_table_set_double(offset, "Offset", i,
01530 uves_pfits_get_offset(linetable_header[i]));
01531
01532 uves_msg_debug("Wavecal %d offset is %f pixels", i,
01533 cpl_table_get_double(offset, "Offset", i, NULL));
01534 }
01535
01536 reverse = false;
01537 uves_sort_table_1(offset, "Offset", reverse);
01538 }
01539
01540
01541 if (objoffset <= cpl_table_get_double(offset, "Offset", 1, NULL))
01542 {
01543 ilow = cpl_table_get_int(offset, "Index", 0, NULL);
01544 ihigh = cpl_table_get_int(offset, "Index", 1, NULL);
01545 offset1 = cpl_table_get_double(offset, "Offset", 0, NULL);
01546 offset2 = cpl_table_get_double(offset, "Offset", 1, NULL);
01547 }
01548 else
01549 {
01550 ilow = cpl_table_get_int(offset, "Index", 1, NULL);
01551 ihigh = cpl_table_get_int(offset, "Index", 2, NULL);
01552 offset1 = cpl_table_get_double(offset, "Offset", 1, NULL);
01553 offset2 = cpl_table_get_double(offset, "Offset", 2, NULL);
01554 }
01555
01556 uves_msg("Interpolating dispersion relation at offset = %.2f",
01557 objoffset);
01558
01559 uves_msg_debug("Using previous solutions at %.2f and %.2f pixels",
01560 offset1, offset2);
01561
01562
01563
01564 assure( offset1 < offset2,
01565 CPL_ERROR_DIVISION_BY_ZERO,
01566 "Dispersion solution %d offset = %.2f pixels; "
01567 "dispersion solution %d offset = %.2f pixels; cannot extrapolate",
01568 ilow, offset1,
01569 ihigh, offset2);
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581
01582 {
01583 double a = (offset2 - objoffset) / (offset2 - offset1);
01584 double b = (offset1 - objoffset) / (offset1 - offset2);
01585
01586 q1 = uves_polynomial_duplicate(dispersion_relation[ilow]);
01587 uves_polynomial_rescale(q1, 0, a);
01588
01589
01590 q2 = uves_polynomial_duplicate(dispersion_relation[ihigh]);
01591 uves_polynomial_rescale(q2, 0, b);
01592
01593
01594 dispersion = uves_polynomial_add_2d(q1, q2);
01595 }
01596
01597 cleanup:
01598 uves_free_table(&offset);
01599 uves_polynomial_delete(&q1);
01600 uves_polynomial_delete(&q2);
01601 return dispersion;
01602 }
01603
01604
01605
01684
01685
01686 static cpl_error_code
01687 extract_ff_rebin_merge(cpl_image *back_subbed,
01688 cpl_image *backsubbed_noise,
01689 const uves_propertylist *backsubbed_header,
01690 const cpl_image *master_flat,
01691 cpl_image *mflat_noise,
01692 const cpl_table *ordertable,
01693 const polynomial *order_locations,
01694 const cpl_table *linetable,
01695 const uves_propertylist *linetable_header[3],
01696 const polynomial *dispersion_relation[3],
01697 double slit_length,
01698 double slit_offset,
01699 int window,
01700 enum uves_chip chip,
01701 bool blaze_correct,
01702 bool tilt_corr,
01703 bool DEBUG,
01704 const cpl_parameterlist *parameters,
01705 const char *context,
01706 const char *mode,
01707 flatfielding_method ff_method,
01708 extract_method ex_method,
01709 merge_method m_method,
01710
01711 cpl_image **x, uves_propertylist **x_header,
01712 cpl_image **fx,
01713 cpl_table **cosmic_mask,
01714 cpl_image **wave_map,
01715 cpl_image **flatfielded_variance,
01716 uves_propertylist **flatfielded_variance_header,
01717 cpl_image **resampled_spectrum,
01718 cpl_image **resampled_mf,
01719 cpl_image **merged_sky,
01720 cpl_image **rebinned_spectrum,
01721 cpl_image **rebinned_noise,
01722 uves_propertylist **rebinned_header,
01723 cpl_image **merged_spectrum,
01724 cpl_image **merged_noise,
01725 uves_propertylist **merged_header,
01726 cpl_table **info_tbl,
01727 cpl_table **order_trace)
01728 {
01729 cpl_image *extracted = NULL;
01730 cpl_image *extracted_noff = NULL;
01731 cpl_image *extracted_noise = NULL;
01732 cpl_image *extracted_sky = NULL;
01733 cpl_image *extracted_sky_noise = NULL;
01734 cpl_image *blaze_ratio = NULL;
01735
01736
01737 cpl_image *cosmic_image = NULL;
01738 cpl_image *weights = NULL;
01739 cpl_table *profile_table = NULL;
01740 uves_propertylist *extracted_header = NULL;
01741
01742 cpl_image *extracted_mf = NULL;
01743 cpl_image *extracted_mf_noise = NULL;
01744
01745 cpl_image *rebinned_sky = NULL;
01746 cpl_image *rebinned_sky_noise = NULL;
01747 cpl_image *merged_sky_noise = NULL;
01748
01749 polynomial *dispersion_int = NULL;
01750 polynomial *dispersion_int_sky = NULL;
01751
01752
01753
01754 cpl_table *poly_table = NULL;
01755 cpl_image *temp_image = NULL;
01756
01757 int n_traces;
01758
01759 int first_abs_order, last_abs_order;
01760 int filename_window;
01761
01762
01763 double delt1=0;
01764 double delt2=0;
01765
01766
01767
01768
01769 passure((ff_method != FF_EXTRACT && resampled_mf == NULL)
01770 ||
01771 master_flat != NULL, " ");
01772
01773
01774
01775 passure( !blaze_correct || ff_method != FF_NO, " ");
01776
01777 passure( ex_method != EXTRACT_OPTIMAL || merged_sky != NULL, " ");
01778 passure( ex_method != EXTRACT_OPTIMAL || cosmic_mask != NULL, " ");
01779
01780 passure(1 <= window && window <= 3, "Illegal window: %d", window);
01781
01782 passure( (x == NULL) == (x_header == NULL) &&
01783 (x == NULL) == (fx == NULL), " ");
01784
01785
01786
01787
01788
01789 check( uves_get_parameter(parameters, NULL,
01790 context, "merge_delt1",
01791 CPL_TYPE_DOUBLE, &delt1),
01792 "Could not read parameter delt1");
01793
01794 check( uves_get_parameter(parameters, NULL,
01795 context, "merge_delt2",
01796 CPL_TYPE_DOUBLE, &delt2),
01797 "Could not read parameter delt2");
01798
01799
01800
01801
01802
01803
01804 if (ex_method == EXTRACT_OPTIMAL || ex_method == EXTRACT_2D)
01805 {
01806
01807
01808
01809
01810
01811
01812 filename_window = -1;
01813
01814 }
01815 else
01816 {
01817 filename_window = window;
01818 }
01819
01820 n_traces = (ex_method == EXTRACT_2D) ? uves_round_double(slit_length) : 1;
01821
01822 check( first_abs_order = uves_pfits_get_firstabsorder(linetable_header[0]),
01823 "Could not read order numbers from line table header");
01824 check( last_abs_order = uves_pfits_get_lastabsorder (linetable_header[0]),
01825 "Could not read order numbers from line table header");
01826
01827 if (window == 2)
01828 {
01829 uves_msg("Extracting object");
01830 }
01831 if( ff_method == FF_EXTRACT ) {
01832 check_nomsg(cosmic_image=uves_image_mflat_detect_blemishes(master_flat,
01833 backsubbed_header));
01834 }
01835
01836 check( extracted =
01837 uves_extract(back_subbed,
01838 backsubbed_noise,
01839 backsubbed_header,
01840 ordertable,
01841 order_locations,
01842 slit_length,
01843 slit_offset,
01844 parameters,
01845 context,
01846 mode,
01847 false,
01848 DEBUG,
01849 chip,
01850 &extracted_header,
01851 &extracted_noise,
01852
01853 &extracted_sky,
01854 &extracted_sky_noise,
01855 cosmic_mask,
01856 &cosmic_image,
01857 (DEBUG) ?
01858 &profile_table : NULL,
01859 &weights,
01860
01861 info_tbl,
01862 order_trace),
01863 "Error extracting spectrum");
01864
01865 if (x != NULL) {
01866 *x = cpl_image_duplicate(extracted);
01867 *x_header = uves_propertylist_duplicate(extracted_header);
01868 }
01869
01870 if (ex_method == EXTRACT_OPTIMAL) {
01871 uves_msg_low("%" CPL_SIZE_FORMAT " hot pixels were detected during optimal extraction",
01872 cpl_table_get_nrow(*cosmic_mask));
01873
01874 if (cpl_table_get_nrow(*cosmic_mask) > 0) {
01875 check( uves_plot_table(*cosmic_mask, "X", "Y",
01876 "%" CPL_SIZE_FORMAT "hot/cold pixels",
01877 cpl_table_get_nrow(*cosmic_mask)),
01878 "Plotting failed");
01879 }
01880 }
01881
01882
01883
01884 if (DEBUG) {
01885
01886
01887
01888
01889
01890
01891
01892 check(uves_propertylist_copy_property_regexp(extracted_header,
01893 backsubbed_header,
01894 "^ESO ",0),"error copying hierarch keys");
01895
01896
01897 check( uves_save_image_local((ff_method == FF_PIXEL) ?
01898 "Extracted, flatfielded spectrum" :
01899 "Extracted spectrum",
01900 (ff_method == FF_PIXEL) ?
01901 "xfb" : "xb",
01902 extracted, chip, -1,
01903 filename_window, extracted_header, true),
01904 "Error saving extracted%s spectrum",
01905 (ff_method == FF_PIXEL) ? ", flatfielded" : "");
01906
01907 check( uves_save_image_local((ff_method == FF_PIXEL) ?
01908 "Extracted, flatfielded spectrum noise" :
01909 "Extracted spectrum noise",
01910 (ff_method == FF_PIXEL) ?
01911 "errxfb" : "errxb",
01912 extracted_noise, chip, -1,
01913 filename_window, extracted_header, true),
01914 "Error saving noise of extracted%s spectrum",
01915 (ff_method == FF_PIXEL) ? ", flatfielded" : "");
01916
01917 if (extracted_sky != NULL)
01918 {
01919 check( uves_save_image_local((ff_method == FF_PIXEL) ?
01920 "Extracted, flatfielded sky" :
01921 "Extracted sky",
01922 (ff_method == FF_PIXEL) ?
01923 "xfsky" : "xsky",
01924 extracted_sky, chip, -1,
01925 filename_window, extracted_header, true),
01926 "Error saving extracted%s sky",
01927 (ff_method == FF_PIXEL) ? ", flatfielded" : "");
01928
01929 check( uves_save_image_local((ff_method == FF_PIXEL) ?
01930 "Noise of extracted, flatfielded sky" :
01931 "Noise of extracted sky",
01932 (ff_method == FF_PIXEL) ?
01933 "errxfsky" : "errxsky",
01934 extracted_sky_noise, chip, -1,
01935 filename_window, extracted_header, true),
01936 "Error saving extracted%s sky noise",
01937 (ff_method == FF_PIXEL) ? ", flatfielded" : "");
01938 }
01939
01940 if (ex_method == EXTRACT_OPTIMAL)
01941 {
01942 check( uves_save_image_local("Optimal extraction weights",
01943 "weights",
01944 weights, chip, -1,
01945 filename_window,
01946 backsubbed_header, true),
01947 "Error saving weights map");
01948
01949 check( uves_save_table_local("Cosmic ray table", "crmask",
01950 *cosmic_mask, chip, -1,
01951 filename_window,
01952 backsubbed_header, NULL),
01953 "Error saving cosmic ray mask");
01954
01955 check( uves_save_image_local("Cosmic ray image", "crimage",
01956 cosmic_image, chip, -1,
01957 filename_window,
01958 backsubbed_header, true),
01959 "Error saving cosmic ray mask");
01960
01961 if (profile_table != NULL)
01962 {
01963 check( uves_save_table_local("Profile table", "profile",
01964 profile_table, chip, -1,
01965 filename_window,
01966 backsubbed_header, NULL),
01967 "Error saving profile table");
01968 }
01969 }
01970 }
01971
01972
01973 if (master_flat != NULL && (ff_method == FF_EXTRACT || resampled_mf != NULL))
01974 {
01975 uves_msg("Extracting master flat field");
01976
01977
01978
01979
01980
01981 if (ex_method == EXTRACT_OPTIMAL)
01982 {
01983 const char *temp_method = "weighted";
01984
01985
01986
01987
01988
01989
01990 check( uves_set_parameter((cpl_parameterlist *) parameters,
01991 context, UVES_EXTRACT_ID ".method",
01992 CPL_TYPE_STRING, &temp_method),
01993 "Error setting extraction method to '%s'", temp_method);
01994 }
01995
01996 check( extracted_mf =
01997 uves_extract((cpl_image *)master_flat,
01998
01999
02000
02001 mflat_noise,
02002 NULL,
02003 ordertable,
02004 order_locations,
02005 slit_length,
02006 slit_offset,
02007 parameters, context,
02008
02009 mode,
02010 false,
02011 DEBUG,
02012 chip,
02013 NULL,
02014 &extracted_mf_noise,
02015 NULL,
02016 NULL,
02017 NULL,
02018 NULL,
02019 NULL,
02020
02021 &weights,
02022 NULL,
02023 NULL),
02024 "Error extracting master flat spectrum");
02025
02026
02027
02028 if (ex_method == EXTRACT_OPTIMAL) {
02029 const char *method = "optimal";
02030
02031
02032
02033 check( uves_set_parameter((cpl_parameterlist *) parameters,
02034 context, UVES_EXTRACT_ID ".method",
02035 CPL_TYPE_STRING, &method),
02036 "Error resetting extraction method to '%s'", method);
02037 }
02038
02039 if (DEBUG) {
02040 double ff_mean;
02041
02042
02043 uves_free_image(&temp_image);
02044
02045 ff_mean = cpl_image_get_mean(extracted_mf);
02046
02047 check( temp_image =
02048 cpl_image_divide_scalar_create(extracted_mf, ff_mean),
02049 "Could not normalize master flat spectrum");
02050
02051 check( uves_save_image_local("Normalized master flat spectrum",
02052 "xmf",
02053 temp_image, chip, -1,
02054 filename_window, extracted_header, true),
02055 "Error saving image");
02056
02057
02058 uves_free_image(&temp_image);
02059 check( temp_image =
02060 cpl_image_divide_scalar_create(extracted_mf_noise,
02061 ff_mean),
02062 "Could not rescale master flat noise spectrum");
02063
02064 check( uves_save_image_local("Noise of normalized "
02065 "master flat spectrum", "errxmf",
02066 temp_image, chip, -1,
02067 filename_window, extracted_header, true),
02068 "Error saving image");
02069
02070 uves_free_image(&temp_image);
02071 }
02072
02073
02074 if (resampled_mf != NULL) {
02075 uves_msg("Rebinning master flat spectrum");
02076
02077
02078
02079
02080
02081
02082
02083 check( *resampled_mf = uves_rebin(extracted_mf,
02084 parameters, context,
02085 linetable,
02086 dispersion_relation[1],
02087 first_abs_order,
02088 last_abs_order,
02089 n_traces,
02090 false,
02091 false,
02092 rebinned_header),
02093 "Error resampling master flat");
02094
02095
02096 check( *wave_map = uves_get_wave_map(back_subbed,
02097 context,
02098 parameters,
02099 ordertable,
02100 linetable,
02101 order_locations,
02102 dispersion_relation[1],
02103 first_abs_order,
02104 last_abs_order,
02105 slit_length),
02106 "Error generating wave map");
02107
02108 check( uves_save_image_local("Wave map",
02109 "wave_map",
02110 *wave_map, chip, -1,
02111 filename_window,
02112 extracted_header, true),
02113 "Error saving wavemap image");
02114
02115
02116
02117 if (DEBUG) {
02118
02119 check(uves_propertylist_copy_property_regexp(*rebinned_header,
02120 backsubbed_header,
02121 "^ESO ", 0),"error copying hierarch keys");
02122
02123
02124 check( uves_save_image_local("Resampled master flat spectrum",
02125 "wxmf", *resampled_mf, chip, -1,
02126 filename_window, *rebinned_header, true),
02127 "Error saving image");
02128 }
02129 }
02130 }
02131
02132
02133 if (ff_method == FF_EXTRACT)
02134 {
02135
02136 uves_msg("Dividing by normalized master flat-field (method = extract)");
02137
02138
02139 extracted_noff = cpl_image_duplicate(extracted);
02140
02141 check( uves_flatfielding(extracted , extracted_noise,
02142 extracted_mf, extracted_mf_noise),
02143 "Could not perform flat-fielding");
02144
02145 if (extracted_sky != NULL)
02146 {
02147 check( uves_flatfielding(extracted_sky, extracted_sky_noise,
02148 extracted_mf, extracted_mf_noise),
02149 "Could not perform flat-fielding");
02150 }
02151
02152
02153 if (DEBUG)
02154 {
02155 check( uves_save_image_local("Flat-fielded spectrum", "fxb",
02156 extracted, chip, -1, filename_window,
02157 extracted_header, true),
02158 "Error saving image");
02159
02160 check( uves_save_image_local("Flat-fielded spectrum noise",
02161 "errfxb", extracted_noise, chip,
02162 -1, filename_window, extracted_header, true),
02163 "Error saving noise of flat-fielded image");
02164 }
02165
02166 if (DEBUG && extracted_sky != NULL)
02167 {
02168 check( uves_save_image_local("Flat-fielded sky", "fxsky",
02169 extracted_sky, chip, -1,
02170 filename_window, extracted_header, true),
02171 "Error saving image");
02172
02173 check( uves_save_image_local("Flat-fielded sky noise", "errfxsky",
02174 extracted_sky_noise, chip, -1,
02175 filename_window, extracted_header, true),
02176 "Error saving noise of flat-fielded image");
02177 }
02178 }
02179
02180 if (fx != NULL)
02181 {
02182 *fx = cpl_image_duplicate(extracted);
02183 }
02184
02185
02186
02187 if (flatfielded_variance != NULL)
02188 {
02189
02190 check( *flatfielded_variance =
02191 cpl_image_multiply_create(extracted_noise,
02192 extracted_noise),
02193 "Error creating variance of flatfielded spectrum");
02194
02195 passure(flatfielded_variance_header != NULL, " ");
02196 check( *flatfielded_variance_header =
02197 uves_propertylist_duplicate(extracted_header),
02198 "Could not copy extracted spectrum header");
02199 }
02200
02201 if (blaze_correct)
02202 {
02203 if (ex_method == EXTRACT_2D)
02204 {
02205
02206 uves_msg_low("Skipping blaze function correction for 2d extraction mode");
02207 }
02208 else
02209 {
02210 uves_msg("Calculating blaze function correction");
02211
02212 check( blaze_ratio = uves_get_blaze_ratio(extracted, extracted_noise),
02213 "Error calculating blaze function correction");
02214
02215 uves_msg("Applying blaze function correction");
02216
02217 check(( cpl_image_divide(extracted , blaze_ratio),
02218 cpl_image_divide(extracted_noise, blaze_ratio)),
02219 "Error applying blaze function correction");
02220
02221 if (extracted_sky != NULL)
02222 {
02223 check(( cpl_image_multiply(extracted_sky, blaze_ratio),
02224 cpl_image_multiply(extracted_sky_noise, blaze_ratio)),
02225 "Error applying blaze function correction");
02226 }
02227 }
02228 }
02229
02230
02231 uves_msg("Rebinning spectrum");
02232 if (ex_method == EXTRACT_2D) {
02233 if (tilt_corr) {
02234 uves_msg_warning("Line tilt correction in rebinning "
02235 "of 2d spectra is unsupported");
02236 }
02237 dispersion_int = uves_polynomial_duplicate(dispersion_relation[window-1]);
02238 }
02239 else if (tilt_corr) {
02240 double objoffset;
02241
02242 if (info_tbl != NULL) {
02243 objoffset = cpl_table_get_column_median(*info_tbl, "ObjPosOnSlit");
02244
02245
02246
02247
02248
02249 uves_msg_debug("Object position (from bottom of extraction window) = %.2f pixels",
02250 objoffset);
02251
02252 objoffset -= slit_length / 2;
02253
02254
02255 objoffset += slit_offset;
02256
02257
02258 uves_msg_debug("Object position (from slit center) = %.2f pixels",
02259 objoffset);
02260 }
02261 else {
02262
02263 uves_msg_debug("Object offset not measured during extraction, "
02264 "using %.2f pixels", slit_offset);
02265 objoffset = slit_offset;
02266 }
02267
02268 check( dispersion_int = interpolate_wave(dispersion_relation,
02269 linetable_header,
02270 objoffset),
02271 "Could not interpolate dispersion solutions");
02272
02273 if (DEBUG) {
02274 check( poly_table = uves_polynomial_convert_to_table(dispersion_int),
02275 "Error converting polynomial to table");
02276
02277 check( uves_save_table_local("Interpolated dispersion relation",
02278 "intdisp",
02279 poly_table, chip, -1,
02280 filename_window, backsubbed_header, NULL),
02281 "Error saving interpolated dispersion solution");
02282 }
02283 }
02284 else {
02285 dispersion_int = uves_polynomial_duplicate(dispersion_relation[window-1]);
02286 }
02287
02288 uves_free_propertylist(rebinned_header);
02289 check( *rebinned_spectrum = uves_rebin(extracted,
02290 parameters, context,
02291 linetable, dispersion_int,
02292 first_abs_order,
02293 last_abs_order,
02294 n_traces,
02295 false,
02296 false,
02297 rebinned_header),
02298 "Could not rebin spectrum");
02299
02300 uves_msg("Rebinning spectrum noise");
02301
02302
02303
02304
02305
02306
02307
02308
02309 {
02310 bool threshold_to_positive = true;
02311
02312 uves_free_propertylist(rebinned_header);
02313 check( *rebinned_noise = uves_rebin(extracted_noise,
02314 parameters, context,
02315 linetable, dispersion_int,
02316 first_abs_order,
02317 last_abs_order,
02318 n_traces,
02319 threshold_to_positive,
02320 true,
02321 rebinned_header),
02322 "Could not rebin spectrum noise");
02323 }
02324
02325 if (extracted_sky != NULL) {
02326 uves_msg("Rebinning sky spectrum");
02327
02328 if (tilt_corr) {
02329
02330
02331
02332
02333
02334
02335
02336 check( dispersion_int_sky = interpolate_wave(dispersion_relation,
02337 linetable_header,
02338 slit_offset),
02339 "Could not interpolate dispersion solutions");
02340 }
02341 else {
02342
02343 dispersion_int_sky = uves_polynomial_duplicate(dispersion_relation[1]);
02344 }
02345
02346
02347 uves_free_propertylist(rebinned_header);
02348 check( rebinned_sky = uves_rebin(extracted_sky,
02349 parameters, context,
02350 linetable, dispersion_int_sky,
02351 first_abs_order,
02352 last_abs_order,
02353 n_traces,
02354 false,
02355 false,
02356 rebinned_header),
02357 "Could not rebin sky noise");
02358
02359 uves_msg("Rebinning sky spectrum noise");
02360
02361 uves_free_propertylist(rebinned_header);
02362 check( rebinned_sky_noise = uves_rebin(extracted_sky_noise,
02363 parameters, context,
02364 linetable, dispersion_int_sky,
02365 first_abs_order,
02366 last_abs_order,
02367 n_traces,
02368 true,
02369 true,
02370 rebinned_header),
02371 "Could not rebin sky noise");
02372 }
02373
02374
02375 if (DEBUG)
02376 {
02377 const char *filename = "";
02378 const char *filename_err = "";
02379 const char *filename_sky = "";
02380 const char *filename_sky_err = "";
02381 if (ff_method == FF_PIXEL)
02382 {
02383 filename = "wxfb";
02384 filename_err = "errwxfb";
02385 filename_sky = "wxfsky";
02386 filename_sky_err = "errwxfsky";
02387 }
02388 else if (ff_method == FF_EXTRACT)
02389 {
02390 filename = "wfxb";
02391 filename_err = "errwfxb";
02392 filename_sky = "wfxsky";
02393 filename_sky_err = "errwfxsky";
02394 }
02395 else if (ff_method == FF_NO)
02396 {
02397 filename = "wxb";
02398 filename_err = "errwxb";
02399 filename_sky = "wxsky";
02400 filename_sky_err = "errwxsky";
02401 }
02402 else
02403 {
02404 passure( false, "Unknown ff_method: %d", ff_method);
02405 }
02406
02407 check(uves_propertylist_copy_property_regexp(*rebinned_header,
02408 backsubbed_header,
02409 "^ESO ", 1),"error copying hierarch keys");
02410
02411
02412 check( uves_save_image_local("Rebinned spectrum",
02413 filename, *rebinned_spectrum,
02414 chip, -1, filename_window, *rebinned_header, true),
02415 "Error saving image");
02416
02417 check( uves_save_image_local("Noise of rebinned spectrum", filename_err,
02418 *rebinned_noise, chip, -1, filename_window,
02419 *rebinned_header, true),
02420 "Error saving image");
02421
02422 if (extracted_sky != NULL)
02423 {
02424 check( uves_save_image_local("Rebinned sky", filename_sky,
02425 rebinned_sky, chip, -1,
02426 filename_window, *rebinned_header, true),
02427 "Error saving image");
02428
02429 check( uves_save_image_local("Noise of rebinned sky",
02430 filename_sky_err,
02431 rebinned_sky_noise, chip, -1,
02432 filename_window, *rebinned_header, true),
02433 "Error saving image");
02434 }
02435 }
02436
02437
02438
02439
02440
02441
02442 if (resampled_spectrum != NULL)
02443 {
02444 if (ff_method == FF_EXTRACT)
02445 {
02446
02447 uves_msg("Rebinning pre-flatfielded spectrum");
02448
02449 uves_free_propertylist(rebinned_header);
02450 check( *resampled_spectrum =
02451 uves_rebin(extracted_noff,
02452 parameters, context,
02453 linetable, dispersion_int,
02454 first_abs_order,
02455 last_abs_order,
02456 n_traces,
02457 false,
02458 false,
02459 rebinned_header),
02460 "Could not rebin spectrum");
02461
02462 if (DEBUG) {
02463
02464 check( uves_save_image_local("Rebinned, extracted spectrum",
02465 "wx", *resampled_spectrum,
02466 chip, -1, filename_window,
02467 *rebinned_header, true),
02468 "Error saving image");
02469 }
02470
02471 }
02472 else
02473 {
02474 check( *resampled_spectrum = cpl_image_duplicate(*rebinned_spectrum),
02475 "Error copying rebinned spectrum");
02476 }
02477 }
02478
02479
02480 if (extracted_sky != NULL)
02481 {
02482 uves_msg("Merging sky");
02483 check( *merged_sky = uves_merge_orders(rebinned_sky,
02484 rebinned_sky_noise,
02485 *rebinned_header,
02486 m_method,
02487 n_traces,
02488 merged_header,
02489 delt1,delt2,chip,
02490 &merged_sky_noise),
02491 "Error merging sky");
02492 }
02493
02494 uves_msg("Merging spectrum");
02495 uves_free_propertylist(merged_header);
02496 check( *merged_spectrum = uves_merge_orders(*rebinned_spectrum,
02497 *rebinned_noise,
02498 *rebinned_header,
02499 m_method,
02500 n_traces,
02501 merged_header,
02502 delt1,delt2,chip,
02503 merged_noise),
02504 "Error merging orders");
02505
02506 check(uves_propertylist_copy_property_regexp(*merged_header,
02507 backsubbed_header,
02508 "^ESO ", 0),"error copying hierarch keys");
02509
02510 if (DEBUG)
02511 {
02512 check( uves_save_image_local("Merged spectrum", "m", *merged_spectrum,
02513 chip, -1, filename_window, *merged_header, true),
02514 "Error saving image");
02515
02516 check( uves_save_image_local("Noise of merged spectrum", "errm",
02517 *merged_noise, chip, -1,
02518 filename_window, *merged_header, true),
02519 "Error saving image");
02520 }
02521
02522 if (DEBUG && extracted_sky != NULL)
02523 {
02524 check( uves_save_image_local("Merged sky", "msky", *merged_sky,
02525 chip, -1,
02526 filename_window, *merged_header, true),
02527 "Error saving image");
02528
02529 check( uves_save_image_local("Noise of merged sky", "errmsky",
02530 merged_sky_noise, chip, -1,
02531 filename_window, *merged_header, true),
02532 "Error saving image");
02533 }
02534
02535 cleanup:
02536 uves_free_image(&extracted);
02537 uves_free_image(&extracted_noff);
02538 uves_free_image(&extracted_noise);
02539 uves_free_image(&extracted_sky);
02540 uves_free_image(&extracted_sky_noise);
02541 uves_free_image(&cosmic_image);
02542 uves_free_image(&blaze_ratio);
02543 uves_free_image(&weights);
02544 uves_polynomial_delete(&dispersion_int);
02545 uves_polynomial_delete(&dispersion_int_sky);
02546 uves_free_table(&poly_table);
02547 uves_free_propertylist(&extracted_header);
02548 uves_free_table(&profile_table);
02549 uves_free_image(&extracted_mf);
02550 uves_free_image(&extracted_mf_noise);
02551 uves_free_image(&rebinned_sky);
02552 uves_free_image(&rebinned_sky_noise);
02553 uves_free_image(&merged_sky_noise);
02554
02555 uves_free_image(&temp_image);
02556
02557 return cpl_error_get_code();
02558 }
02559
02560
02561
02597
02598
02599 static cpl_image *
02600 subtract_sky(cpl_image *rebinned_obj, cpl_image *rebinned_obj_noise,
02601 uves_propertylist *rebinned_obj_header,
02602 const cpl_image *rebinned_sky1, const cpl_image *rebinned_sky1_noise,
02603 const uves_propertylist *rebinned_sky1_header,
02604 const cpl_image *rebinned_sky2, const cpl_image *rebinned_sky2_noise,
02605 const uves_propertylist *rebinned_sky2_header,
02606 cpl_image **merged_obj, cpl_image **merged_obj_noise,
02607 uves_propertylist *merged_obj_header,
02608 const cpl_image *merged_sky1, const cpl_image *merged_sky1_noise,
02609 const uves_propertylist *merged_sky1_header,
02610 const cpl_image *merged_sky2, const cpl_image *merged_sky2_noise,
02611 const uves_propertylist *merged_sky2_header,
02612 double obj_slit, double sky1_slit, double sky2_slit)
02613 {
02614 double wavestep;
02615 int norders;
02616
02617 cpl_image *merged_sky = NULL;
02618
02619 passure( rebinned_obj != NULL, " ");
02620 passure( rebinned_obj_noise != NULL, " ");
02621 passure( rebinned_obj_header != NULL, " ");
02622 passure( merged_obj != NULL, " ");
02623 passure( merged_obj_noise != NULL, " ");
02624 passure( merged_obj_header != NULL, " ");
02625 passure( *merged_obj != NULL, " ");
02626 passure( *merged_obj_noise != NULL, " ");
02627
02628
02629 check( wavestep = uves_pfits_get_cdelt1(rebinned_obj_header),
02630 "Error reading wavelength step");
02631 norders = cpl_image_get_size_y(rebinned_obj);
02632
02633
02634
02635 assure((rebinned_sky1 == NULL || norders == cpl_image_get_size_y(rebinned_sky1)) &&
02636 (rebinned_sky2 == NULL || norders == cpl_image_get_size_y(rebinned_sky2)),
02637 CPL_ERROR_ILLEGAL_INPUT,
02638 "Different number of orders in object/sky spectra: obj = %d, "
02639 "sky1 = %" CPL_SIZE_FORMAT ", sky3 = %" CPL_SIZE_FORMAT "",
02640 norders,
02641 cpl_image_get_size_y(rebinned_sky1),
02642 cpl_image_get_size_y(rebinned_sky2));
02643
02644 if (rebinned_sky1 != NULL)
02645 {
02646 double wavestep1;
02647 check( wavestep1 = uves_pfits_get_cdelt1(rebinned_sky1_header),
02648 "Error reading wavelength step");
02649 assure( fabs(wavestep1 - wavestep) / wavestep < 0.01,
02650 CPL_ERROR_ILLEGAL_INPUT,
02651 "Different bin widths: sky1 = %f ; obj = %f",
02652 wavestep1, wavestep);
02653 }
02654 if (rebinned_sky2 != NULL)
02655 {
02656 double wavestep2;
02657 check( wavestep2 = uves_pfits_get_cdelt1(rebinned_sky2_header),
02658 "Error reading wavelength step");
02659 assure( fabs(wavestep2 - wavestep) / wavestep < 0.01,
02660 CPL_ERROR_ILLEGAL_INPUT,
02661 "Different bin widths: sky3 = %f ; obj = %f",
02662 wavestep2, wavestep);
02663 }
02664
02665
02666 {
02667 int order;
02668 for (order = 1; order <= norders; order++)
02669 {
02670 double obj_start , obj_end;
02671 double sky1_start , sky1_end;
02672 double sky2_start , sky2_end;
02673 double common_start, common_end;
02674
02675 check( obj_start = uves_pfits_get_wstart(rebinned_obj_header, order),
02676 "Error reading start wavelength for order #%d", order);
02677 check( obj_end = uves_pfits_get_wend (rebinned_obj_header, order),
02678 "Error reading end wavelength for order #%d", order);
02679
02680 if (rebinned_sky1 != NULL)
02681 {
02682 check( sky1_start =
02683 uves_pfits_get_wstart(rebinned_sky1_header, order),
02684 "Error reading start wavelength for order #%d", order);
02685 check( sky1_end =
02686 uves_pfits_get_wend (rebinned_sky1_header, order),
02687 "Error reading end wavelength for order #%d", order);
02688 }
02689 else
02690 {
02691 sky1_start = obj_start;
02692 sky1_end = obj_end;
02693 }
02694
02695 if (rebinned_sky2 != NULL)
02696 {
02697 check( sky2_start =
02698 uves_pfits_get_wstart(rebinned_sky2_header, order),
02699 "Error reading start wavelength for order #%d", order);
02700 check( sky2_end =
02701 uves_pfits_get_wend (rebinned_sky2_header, order),
02702 "Error reading end wavelength for order #%d", order);
02703 }
02704 else
02705 {
02706 sky2_start = obj_start;
02707 sky2_end = obj_end;
02708 }
02709
02710 check( merged_sky =
02711 subtract_sky_row(rebinned_obj , rebinned_obj_noise ,
02712 obj_start , obj_end, obj_slit,
02713 rebinned_sky1, rebinned_sky1_noise,
02714 sky1_start, sky1_end, sky1_slit,
02715 rebinned_sky2, rebinned_sky2_noise,
02716 sky2_start, sky2_end, sky2_slit,
02717 order, wavestep, &common_start,
02718 &common_end),
02719 "Could not subtract sky for rebinned spectrum order #%d", order);
02720 uves_free_image(&merged_sky);
02721
02722 check( uves_pfits_set_wstart(rebinned_obj_header, order, common_start),
02723 "Error updating start wavelength for order #%d", order);
02724 check( uves_pfits_set_wend (rebinned_obj_header, order, common_end ),
02725 "Error updating start wavelength for order #%d", order);
02726 }
02727 }
02728
02729
02730 {
02731 double obj_start , obj_end;
02732 double sky1_start , sky1_end;
02733 double sky2_start , sky2_end;
02734 double common_start, common_end;
02735
02736 obj_start = uves_pfits_get_crval1(merged_obj_header);
02737 obj_end = obj_start + wavestep * (cpl_image_get_size_x(*merged_obj) - 1);
02738
02739 if (merged_sky1 != NULL)
02740 {
02741 sky1_start = uves_pfits_get_crval1(merged_sky1_header);
02742 sky1_end = sky1_start +
02743 wavestep * (cpl_image_get_size_x(merged_sky1) - 1);
02744 }
02745 else
02746 {
02747 sky1_start = obj_start;
02748 sky1_end = obj_end;
02749 }
02750
02751 if (merged_sky2 != NULL)
02752 {
02753 sky2_start = uves_pfits_get_crval1(merged_sky2_header);
02754 sky2_end = sky2_start +
02755 wavestep * (cpl_image_get_size_x(merged_sky2) - 1);
02756 }
02757 else
02758 {
02759 sky2_start = obj_start;
02760 sky2_end = obj_end;
02761 }
02762
02763
02764 check( merged_sky = subtract_sky_row(*merged_obj, *merged_obj_noise,
02765 obj_start , obj_end, obj_slit,
02766 merged_sky1, merged_sky1_noise,
02767 sky1_start, sky1_end, sky1_slit,
02768 merged_sky2, merged_sky2_noise,
02769 sky2_start, sky2_end, sky2_slit,
02770 1, wavestep, &common_start,
02771 &common_end),
02772 "Error subtracting sky of merged spectrum");
02773
02774 check( uves_pfits_set_crval1(merged_obj_header, common_start),
02775 "Could not update start wavelength");
02776
02777
02778 check( uves_crop_image(merged_obj,
02779 1, 1,
02780 1 + uves_round_double((common_end -
02781 common_start)/wavestep),
02782 1),
02783 "Error cropping merged spectrum");
02784
02785 check( uves_crop_image(merged_obj_noise,
02786 1, 1,
02787 1 + uves_round_double((common_end -
02788 common_start)/wavestep),
02789 1),
02790 "Error cropping merged spectrum noise");
02791
02792 if (merged_sky != NULL)
02793 {
02794
02795 assure( cpl_image_get_size_x(merged_sky) ==
02796 cpl_image_get_size_x(*merged_obj), CPL_ERROR_ILLEGAL_OUTPUT,
02797 "Sky and object spectrum sizes differ, "
02798 "sky = %" CPL_SIZE_FORMAT " bins, obj = %" CPL_SIZE_FORMAT " bins",
02799 cpl_image_get_size_x(merged_sky),
02800 cpl_image_get_size_x(*merged_obj));
02801 }
02802 }
02803
02804 cleanup:
02805 if (cpl_error_get_code() != CPL_ERROR_NONE)
02806 {
02807 uves_free_image(&merged_sky);
02808 }
02809 return merged_sky;
02810 }
02811
02812
02844
02845
02846 static cpl_image *
02847 subtract_sky_row(cpl_image *obj, cpl_image *obj_noise,
02848 double obj_start, double obj_end, double obj_slit,
02849 const cpl_image *sky1, const cpl_image *sky1_noise,
02850 double sky1_start, double sky1_end, double sky1_slit,
02851 const cpl_image *sky2, const cpl_image *sky2_noise,
02852 double sky2_start, double sky2_end, double sky2_slit,
02853 int row, double wavestep,
02854 double *common_start, double *common_end)
02855 {
02856 int first_bin_obj;
02857 int first_bin_sky1;
02858 int first_bin_sky2;
02859 int nbins;
02860 cpl_image *common_obj = NULL;
02861 cpl_image *common_sky1 = NULL;
02862 cpl_image *common_sky2 = NULL;
02863 cpl_image *common_obj_noise = NULL;
02864 cpl_image *common_sky1_noise = NULL;
02865 cpl_image *common_sky2_noise = NULL;
02866 bool is_good1, is_good2;
02867
02868 cpl_image *common_sky = NULL;
02869
02870 cpl_image *common_sky_noise = NULL;
02871
02872 cpl_image *temp = NULL;
02873
02874 *common_start = uves_max_double(obj_start, uves_max_double(sky1_start, sky2_start));
02875 *common_end = uves_min_double(obj_end , uves_min_double(sky1_end , sky2_end ));
02876
02877 if (*common_start <= *common_end)
02878 {
02879 nbins = 1 + uves_round_double((*common_end - *common_start) / wavestep);
02880
02881 uves_msg_debug("Lower sky range: %f - %f w.l.u.", sky1_start, sky1_end);
02882 uves_msg_debug("Upper sky range: %f - %f w.l.u.", sky2_start, sky2_end);
02883 uves_msg_debug("Object sky range: %f - %f w.l.u.", obj_start, obj_end);
02884 uves_msg_debug("Sky/object common wavelength range in order %d: "
02885 "%f - %f w.l.u. (%d bins)",
02886 row, *common_start, *common_end, nbins);
02887
02888 first_bin_obj = 1 + uves_round_double((*common_start - obj_start )/wavestep);
02889 first_bin_sky1 = 1 + uves_round_double((*common_start - sky1_start)/wavestep);
02890 first_bin_sky2 = 1 + uves_round_double((*common_start - sky2_start)/wavestep);
02891
02892
02893 check( common_obj = cpl_image_extract(obj,
02894 first_bin_obj, row,
02895 first_bin_obj + nbins-1, row),
02896 "Error extracting common rows (object)");
02897
02898 check( common_obj_noise = cpl_image_extract(obj_noise,
02899 first_bin_obj, row,
02900 first_bin_obj + nbins-1, row),
02901 "Error extracting common rows (object noise)");
02902
02903 if (sky1 != NULL)
02904 {
02905 check( common_sky1 =
02906 cpl_image_extract(sky1,
02907 first_bin_sky1, row,
02908 first_bin_sky1 + nbins-1, row),
02909 "Error extracting common rows (lower sky)");
02910
02911 check( common_sky1_noise =
02912 cpl_image_extract(sky1_noise,
02913 first_bin_sky1, row,
02914 first_bin_sky1 + nbins-1, row),
02915 "Error extracting common rows (lower sky noise)");
02916
02917 check(( cpl_image_multiply_scalar(common_sky1 , obj_slit / sky1_slit),
02918 cpl_image_multiply_scalar(common_sky1_noise, obj_slit / sky1_slit)),
02919 "Error normalizing sky flux");
02920
02921 is_good1 =
02922 cpl_image_count_rejected(common_sky1) <
02923 cpl_image_get_size_x(common_sky1)*
02924 cpl_image_get_size_y(common_sky1) &&
02925
02926
02927 cpl_image_get_min(common_sky1_noise) > 0;
02928 }
02929 else
02930 {
02931 is_good1 = false;
02932 }
02933 if (sky2 != NULL)
02934 {
02935 check( common_sky2 = cpl_image_extract(sky2,
02936 first_bin_sky2, row,
02937 first_bin_sky2 + nbins-1, row),
02938 "Error extracting common rows (upper sky)");
02939
02940 check( common_sky2_noise = cpl_image_extract(sky2_noise,
02941 first_bin_sky2, row,
02942 first_bin_sky2 + nbins-1, row),
02943 "Error extracting common rows (upper sky noise)");
02944
02945 check(( cpl_image_multiply_scalar(common_sky2 , obj_slit / sky2_slit),
02946 cpl_image_multiply_scalar(common_sky2_noise, obj_slit / sky2_slit)),
02947 "Error normalizing sky flux");
02948
02949 is_good2 =
02950 cpl_image_count_rejected(common_sky2) <
02951 cpl_image_get_size_x(common_sky2)*
02952 cpl_image_get_size_y(common_sky2) &&
02953 cpl_image_get_min(common_sky2_noise) > 0;
02954 }
02955 else
02956 {
02957 is_good2 = false;
02958 }
02959
02960
02961
02962
02963 if (is_good1 && is_good2)
02964 {
02965 check( common_sky =
02966 uves_average_images(common_sky1, common_sky1_noise,
02967 common_sky2, common_sky2_noise,
02968 &common_sky_noise),
02969 "Error combining sky windows");
02970 }
02971 else if (is_good1 && !is_good2)
02972 {
02973 common_sky = cpl_image_duplicate(common_sky1);
02974 common_sky_noise = cpl_image_duplicate(common_sky1_noise);
02975 }
02976 else if (!is_good1 && is_good2)
02977 {
02978 common_sky = cpl_image_duplicate(common_sky2);
02979 common_sky_noise = cpl_image_duplicate(common_sky2_noise);
02980 }
02981 else
02982 {
02983 common_sky = NULL;
02984 }
02985
02986 if (common_sky != NULL)
02987 {
02988
02989
02990
02991
02992
02993
02994
02995
02996 check(( cpl_image_subtract (common_obj, common_sky)),
02997 "Error subtracting combined sky");
02998
02999
03000
03001 check(( cpl_image_power(common_obj_noise, 2),
03002 cpl_image_power(common_sky_noise, 2),
03003 cpl_image_add (common_obj_noise, common_sky_noise),
03004 cpl_image_power(common_obj_noise, 0.5)),
03005 "Error propagating noise during sky subtration");
03006
03007
03008 check(( cpl_image_copy(obj,
03009 common_obj,
03010 1, row),
03011 cpl_image_copy(obj_noise,
03012 common_obj_noise,
03013 1, row)),
03014 "Error writing subtracted flux to row %d of spectrum", row);
03015 }
03016
03017 }
03018 else
03019 {
03020 int x;
03021
03022 uves_msg_low("Extracted object and sky spectra have no overlap in order #%d. "
03023 "Order marked as bad", row);
03024
03025 for (x = 1; x <= cpl_image_get_size_x(obj); x++)
03026 {
03027 check(( cpl_image_reject(obj , x, row),
03028 cpl_image_reject(obj_noise, x, row)),
03029 "Error rejecting sky-subtracted spectrum "
03030 "at (x, row) = (%d, %d)", x, row);
03031 }
03032 }
03033
03034 cleanup:
03035 uves_free_image(&common_obj);
03036 uves_free_image(&common_sky1);
03037 uves_free_image(&common_sky2);
03038 uves_free_image(&common_obj_noise);
03039 uves_free_image(&common_sky_noise);
03040 uves_free_image(&common_sky1_noise);
03041 uves_free_image(&common_sky2_noise);
03042 uves_free_image(&temp);
03043 if (cpl_error_get_code() != CPL_ERROR_NONE)
03044 {
03045 uves_free_image(&common_sky);
03046 }
03047
03048 return common_sky;
03049 }
03050
03051
03068
03069 static double get_offset(const cpl_image *back_subbed,
03070 const cpl_table *ordertable,
03071 const polynomial *order_locations,
03072 double search_range, int nsamples, double *doffset)
03073 {
03074 cpl_image *chunk = NULL;
03075 cpl_image *chunk_col = NULL;
03076
03077 int minorder, maxorder;
03078 int order, x, nx, ny;
03079 double sum = 0, sum_o = 0, sum_oo = 0;
03080
03081 int s_r_int = uves_round_double(search_range);
03082
03083 passure( back_subbed != NULL, " ");
03084 passure( ordertable != NULL, " ");
03085 passure( order_locations != NULL, " ");
03086
03087 assure( nsamples >= 1, CPL_ERROR_ILLEGAL_INPUT,
03088 "Illegal number of sample points per order: %d", nsamples);
03089
03090 minorder = cpl_table_get_column_min(ordertable, "Order");
03091 maxorder = cpl_table_get_column_max(ordertable, "Order");
03092 nx = cpl_image_get_size_x(back_subbed);
03093 ny = cpl_image_get_size_y(back_subbed);
03094
03095 sum = 0;
03096 sum_o = 0;
03097 sum_oo = 0;
03098 for (order = minorder; order <= maxorder; order++)
03099 {
03100 int stepx = nx / nsamples;
03101
03102 for (x = stepx/2; x <= nx; x += stepx)
03103 {
03104 int y = uves_round_double(
03105 uves_polynomial_evaluate_2d(order_locations, x, order));
03106
03107 if (1 <= y - s_r_int && y + s_r_int <= ny)
03108 {
03109 double offset;
03110
03111
03112
03113 chunk =
03114 cpl_image_extract(back_subbed,
03115 uves_max_int(1 , x - stepx/2),
03116 y - s_r_int,
03117 uves_min_int(nx, x + stepx/2),
03118 y + s_r_int);
03119
03120 chunk_col =
03121
03122 cpl_image_collapse_median_create(chunk,
03123 1,
03124 0, 0);
03125
03126
03127
03128
03129 offset = (y - s_r_int - 1) +
03130 cpl_image_get_centroid_y_window(chunk_col,
03131 1, 1,
03132 1,
03133 cpl_image_get_size_y(chunk_col));
03134
03135
03136 offset -= y;
03137
03138 uves_free_image(&chunk);
03139 uves_free_image(&chunk_col);
03140
03141 sum += 1;
03142 sum_o += offset;
03143 sum_oo += offset*offset;
03144 }
03145 }
03146 }
03147
03148
03149
03150 assure( sum > 0, CPL_ERROR_ILLEGAL_OUTPUT,
03151 "No evaluation points inside image!");
03152
03153 if (doffset != NULL)
03154 {
03155 *doffset = sqrt(sum_oo/(1.0*sum) -
03156 (sum_o*sum_o) / (sum*1.0*sum));
03157 }
03158
03159 cleanup:
03160 uves_free_image(&chunk);
03161 uves_free_image(&chunk_col);
03162
03163 return (1.0*sum_o) / sum;
03164 }
03165
03166
03167
03189
03190 static cpl_image *
03191 uves_get_blaze_ratio(const cpl_image *spectrum,
03192 const cpl_image *spectrum_noise)
03193 {
03194 int nx, ny;
03195 int smooth_x, smooth_y;
03196
03197 cpl_image *blaze_ratio = NULL;
03198 cpl_image *blaze_ratio_noise = NULL;
03199
03200 cpl_table *values = NULL;
03201 polynomial *p = NULL;
03202
03203 passure( spectrum != NULL, " ");
03204 passure( spectrum_noise != NULL, " ");
03205
03206 nx = cpl_image_get_size_x(spectrum);
03207 ny = cpl_image_get_size_y(spectrum);
03208
03209 blaze_ratio = cpl_image_duplicate(spectrum);
03210 blaze_ratio_noise = cpl_image_duplicate(spectrum_noise);
03211 assure_mem( blaze_ratio );
03212 assure_mem( blaze_ratio_noise );
03213
03214
03215
03216
03217
03218
03219 {
03220 int x, y;
03221
03222 for (y = 1; y <= ny; y++)
03223 {
03224 double median = cpl_image_get_median_window(blaze_ratio,
03225 1, y,
03226 nx, y);
03227
03228 if (median == 0)
03229 {
03230
03231
03232
03233
03234
03235
03236 double max_noise = cpl_image_get_max(blaze_ratio_noise);
03237
03238 for (x = 1; x <= nx; x++)
03239 {
03240 cpl_image_set(blaze_ratio , x, y, 1);
03241
03242
03243 cpl_image_set(blaze_ratio_noise, x, y, max_noise);
03244 }
03245 }
03246 else
03247 {
03248
03249
03250 double exclude = 2;
03251
03252 for (x = 1; x <= nx; x++)
03253 {
03254 int pis_rejected1, pis_rejected2;
03255 double val1, val2;
03256
03257 val1 = cpl_image_get(blaze_ratio ,
03258 x, y, &pis_rejected1);
03259 val2 = cpl_image_get(blaze_ratio_noise,
03260 x, y, &pis_rejected2);
03261
03262 if (!pis_rejected1 && !pis_rejected2 &&
03263 val1/median < exclude && val1/median > 1/exclude)
03264 {
03265 cpl_image_set(blaze_ratio ,
03266 x, y, val1 / median);
03267 cpl_image_set(blaze_ratio_noise,
03268 x, y, val2 / median);
03269 }
03270 else
03271 {
03272
03273
03274 cpl_image_set (blaze_ratio , x, y, 1);
03275
03276 cpl_image_reject(blaze_ratio , x, y);
03277 cpl_image_reject(blaze_ratio_noise, x, y);
03278 }
03279 }
03280 }
03281 }
03282
03283 uves_plot_image_rows(blaze_ratio, 1, ny, ny/10,
03284 "x", "y", "ratio (normalized to 1)");
03285 }
03286
03287 smooth_x = nx / 20 + 1;
03288 smooth_y = ny / 20 + 1;
03289 check( uves_filter_image_median(&blaze_ratio,
03290 smooth_x, smooth_y,
03291 false),
03292 "Error creating smoothed ratio");
03293
03294 uves_plot_image_rows(blaze_ratio, 1, ny, ny/10, "x", "y", "ratio (smoothed)");
03295
03296
03297
03298
03299
03300
03301
03302 {
03303 int x, y;
03304 double interpolated=0;
03305 for (x = 1; x <= nx; x++)
03306 {
03307 int current_row;
03308
03309
03310
03311
03312 uves_free_table(&values);
03313 values = cpl_table_new(ny);
03314 cpl_table_new_column(values, "Y", CPL_TYPE_INT);
03315 cpl_table_new_column(values, "Ratio", CPL_TYPE_DOUBLE);
03316 cpl_table_new_column(values, "dRatio", CPL_TYPE_DOUBLE);
03317
03318 assure_mem( values );
03319
03320 current_row = 0;
03321 for (y = 1; y <= ny; y++)
03322 {
03323 double ratio=0., dratio=0.;
03324 int pis_rejected1=0, pis_rejected2=0;
03325
03326 ratio = cpl_image_get(blaze_ratio ,
03327 x, y, &pis_rejected1);
03328 check_nomsg(dratio = cpl_image_get(blaze_ratio_noise,
03329 x, y, &pis_rejected2));
03330
03331
03332
03333
03334 if (!pis_rejected1 && !pis_rejected2)
03335 {
03336 cpl_table_set_int (values, "Y" ,
03337 current_row, y);
03338 cpl_table_set_double(values, "Ratio" ,
03339 current_row, ratio);
03340 cpl_table_set_double(values, "dRatio",
03341 current_row, dratio);
03342 current_row += 1;
03343 }
03344 else
03345 {
03346
03347 }
03348 }
03349
03350 cpl_table_set_size(values, current_row);
03351 if(current_row>UVES_MIN_LINE_ROWS_TO_MAKE_FIT)
03352 {
03353 int degree = 2;
03354 double kappa = 2;
03355
03356 uves_polynomial_delete(&p);
03357 p = uves_polynomial_regression_1d(values,
03358 "Y", "Ratio", "dRatio",
03359 degree,
03360 NULL, NULL,
03361 NULL,
03362 kappa);
03363
03364
03365
03366 if (cpl_error_get_code() == CPL_ERROR_ILLEGAL_INPUT ||
03367 cpl_error_get_code() == CPL_ERROR_ILLEGAL_OUTPUT)
03368 {
03369 uves_error_reset();
03370
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380
03381 uves_free_table(&values);
03382 values = cpl_table_new(2);
03383 cpl_table_new_column(values, "Y", CPL_TYPE_INT);
03384 cpl_table_new_column(values, "Ratio", CPL_TYPE_DOUBLE);
03385 cpl_table_set_int (values, "Y" , 0, 1);
03386 cpl_table_set_double(values, "Ratio" , 0, 1);
03387 cpl_table_set_int (values, "Y" , 1, 2);
03388 cpl_table_set_double(values, "Ratio" , 1, 1);
03389
03390 degree = 2;
03391 kappa = -1;
03392 uves_polynomial_delete(&p);
03393 p = uves_polynomial_regression_1d(values,
03394 "Y", "Ratio", NULL,
03395 degree,
03396 NULL, NULL,
03397 NULL,
03398 kappa);
03399 }
03400 assure( cpl_error_get_code() == CPL_ERROR_NONE, cpl_error_get_code(),
03401 "Could not fit %d. degree polynomial to column %d", degree, x);
03402
03403 } else {
03404 interpolated=UVES_BLAZE_DUMMY_VAL;
03405 }
03406
03407 for (y = 1; y <= ny; y++)
03408 {
03409 if(current_row>UVES_MIN_LINE_ROWS_TO_MAKE_FIT) {
03410 interpolated = uves_polynomial_evaluate_1d(p, y);
03411 }
03412 cpl_image_set(blaze_ratio, x, y, fabs(interpolated));
03413 }
03414
03415 }
03416
03417
03418 check( uves_filter_image_median(&blaze_ratio,
03419 2*smooth_x, 2*smooth_y,
03420 false),
03421 "Error creating smoothed ratio");
03422
03423 uves_plot_image_rows(blaze_ratio, 1, ny, ny/10, "x", "y", "ratio (poly. fit)");
03424
03425 }
03426
03427
03428
03429
03430
03431
03432
03433
03434
03435
03436
03437
03438
03439
03440 cleanup:
03441 uves_free_table(&values);
03442 uves_polynomial_delete(&p);
03443 uves_free_image(&blaze_ratio_noise);
03444
03445 if (cpl_error_get_code() != CPL_ERROR_NONE)
03446 {
03447 uves_free_image(&blaze_ratio);
03448 }
03449 return blaze_ratio;
03450 }
03451
03452