42 #include <uves_response_efficiency.h>
43 #include <uves_response_utils.h>
44 #include <uves_reduce.h>
45 #include <uves_reduce_utils.h>
47 #include <uves_pfits.h>
48 #include <uves_wavecal_utils.h>
49 #include <uves_utils_polynomial.h>
50 #include <uves_utils.h>
51 #include <uves_utils_wrappers.h>
52 #include <uves_utils_cpl.h>
54 #include <uves_error.h>
64 #define H_BAR 6.626068e-34
65 #define PRIMARY_DIA 818
67 #define TELESCOPE_EFFECTIVE_AREA \
68 (M_PI * (PRIMARY_DIA * PRIMARY_DIA - OBSTR_DIA * OBSTR_DIA) / 4.0)
103 const cpl_image *master_bias,
105 const cpl_image *master_dark,
107 const cpl_table *ordertable,
109 const cpl_table *linetable[3],
112 const cpl_table *flux_table,
113 const cpl_table *atm_extinction,
116 const cpl_parameterlist *parameters,
120 cpl_table **efficiency,
121 cpl_table **blaze_efficiency)
123 cpl_image *background = NULL;
124 cpl_image *rebinned_spectrum = NULL;
125 cpl_image *rebinned_noise = NULL;
126 cpl_image *merged_sky = NULL;
127 cpl_image *merged_spectrum = NULL;
128 cpl_image *merged_noise = NULL;
129 cpl_image *reduced_spectrum = NULL;
130 cpl_image *reduced_noise = NULL;
131 cpl_image *reduced_rebinned = NULL;
132 cpl_image *reduced_rebinned_noise = NULL;
137 cpl_image *response_orders = NULL;
138 cpl_image *efficiency_spectrum = NULL;
139 cpl_table *central_efficiency = NULL;
141 cpl_table *info_tbl = NULL;
146 char *ref_obj_id = NULL;
149 double extraction_slit;
150 cpl_image* wave_map=NULL;
151 cpl_image* reduced_rebinned_no_bpm=NULL;
163 check( uves_get_parameter(parameters, NULL,
164 make_str(UVES_RESPONSE_ID)
"",
"reduce.rebin.wavestep",
165 CPL_TYPE_DOUBLE, &wavestep),
166 "Error getting resampling step size");
168 check( smooth_step = cpl_table_get_column_mean(linetable[1], LINETAB_PIXELSIZE),
169 "Error reading mean pixelsize");
171 smooth_step = 10*2*smooth_step/3;
177 check( uves_set_parameter((cpl_parameterlist *) parameters,
178 make_str(UVES_RESPONSE_ID)
"",
"reduce.rebin.wavestep",
179 CPL_TYPE_DOUBLE, &smooth_step),
180 "Error setting resampling step size");
200 make_str(UVES_RESPONSE_ID),
222 &reduced_rebinned_noise,
228 "Could not reduce frame");
235 check( uves_set_parameter((cpl_parameterlist *) parameters,
236 make_str(UVES_RESPONSE_ID)
"",
"reduce.rebin.wavestep",
237 CPL_TYPE_DOUBLE, &wavestep),
238 "Error resetting resampling step size");
246 check( uves_save_image_local(
"Reduced spectrum (2d)",
"reduced",
247 reduced_rebinned, chip, -1, -1, rebinned_header,
true),
248 "Error saving reduced spectrum (2d)");
250 check( uves_save_image_local(
"Reduced spectrum (2d) noise",
"errreduced",
251 reduced_rebinned_noise, chip, -1, -1, rebinned_header,
true),
252 "Error saving reduced spectrum (2d) noise");
254 check( uves_save_image_local(
"Reduced spectrum",
"merged",
255 reduced_spectrum, chip, -1, -1, reduced_header,
true),
256 "Error saving reduced spectrum");
258 check( uves_save_image_local(
"Reduced spectrum noise",
"errmerged",
259 reduced_noise, chip, -1, -1, reduced_header,
true),
260 "Error saving reduced spectrum noise");
263 uves_msg(
"Dividing by catalogue flux");
272 reduced_rebinned_no_bpm=cpl_image_duplicate(reduced_rebinned);
273 bpm=cpl_image_unset_bpm(reduced_rebinned_no_bpm);
277 raw_header, PACCURACY,
280 "Could not calculate response curve");
282 uves_free_image(&reduced_rebinned_no_bpm);
283 uves_free_mask(&bpm);
287 check( uves_save_image_local(
"2d response curve",
"resp",
288 response_orders, chip, -1, -1, rebinned_header,
true),
289 "Error saving 2d response curve");
296 int n_traces = cpl_image_get_size_y(merged_spectrum);
298 assure( n_traces == 1, CPL_ERROR_ILLEGAL_INPUT,
299 "2d extraction/reduction not supported");
310 "Could not normalize spectrum");
316 uves_msg(
"Applying 7x1 median filter");
318 "Error applying median filter");
321 uves_msg(
"Calculating quantum detection efficiency");
324 int nx, nbins, norders, order;
325 int first_abs_order, last_abs_order, abs_order;
327 double average_noise;
330 double *efficiency_data;
331 double *reduced_noise_data;
333 efficiency_data = cpl_image_get_data_double(efficiency_spectrum);
334 reduced_noise_data = cpl_image_get_data_double(reduced_rebinned_noise);
336 nx = cpl_image_get_size_x(raw_image);
337 nbins = cpl_image_get_size_x(efficiency_spectrum);
338 norders = cpl_image_get_size_y(efficiency_spectrum);
340 *efficiency = cpl_table_new(nbins * norders);
341 cpl_table_new_column(*efficiency,
"Wave", CPL_TYPE_DOUBLE);
342 cpl_table_new_column(*efficiency,
"Eff", CPL_TYPE_DOUBLE);
343 cpl_table_new_column(*efficiency,
"Binsize", CPL_TYPE_DOUBLE);
344 cpl_table_new_column(*efficiency,
"Order", CPL_TYPE_INT);
345 cpl_table_set_column_unit(*efficiency,
"Wave",
"Angstrom");
346 cpl_table_set_column_unit(*efficiency,
"Eff",
" ");
347 cpl_table_set_column_unit(*efficiency,
"Binsize",
"Angstrom");
348 cpl_table_set_column_unit(*efficiency,
"Order",
" ");
353 "Could not read order numbers from line table header");
355 "Could not read order numbers from line table header");
358 "Error reading bin width from header");
360 check( average_noise = cpl_image_get_median(reduced_rebinned_noise),
361 "Error reading median noise level");
363 for (order = 1; order <= norders; order++)
365 double lambda_start, lambda, lambda_end;
372 "Error reading start wavelength from header");
375 "Error reading end wavelength from header");
387 "Error getting 1d dispersion relation for absolute order #%d", abs_order);
390 for (lambda = lambda_start, bin = 1;
391 lambda < lambda_end + 0.5 * dlambda && bin <= nbins;
392 bin++, lambda += dlambda)
403 flux = efficiency_data [(bin-1) + (order-1) * nbins];
404 noise = reduced_noise_data[(bin-1) + (order-1) * nbins];
427 "Could not solve dispersion relation for x "
428 "at (m, lambda) = (%d, %f)", abs_order, lambda);
436 dispersion_relation[1],
438 abs_order, 1) / abs_order),
439 "Could not evaluate dispersion relation");
455 flux = flux * 1e16 * 1e17 * H_BAR * SPEED_OF_LIGHT /
456 (dldx * lambda * TELESCOPE_EFFECTIVE_AREA);
463 if (noise < 3*average_noise)
465 check(( cpl_table_set_double(*efficiency,
"Wave", row, lambda),
466 cpl_table_set_double(*efficiency,
"Eff", row, flux),
467 cpl_table_set_double(*efficiency,
"Binsize", row, dldx),
468 cpl_table_set_int (*efficiency,
"Order", row, order),
470 "Error updating efficiency table row %d", row);
476 check( cpl_table_set_size(*efficiency, row),
477 "Error setting size of efficiency table to %d rows", row);
479 cpl_table* tmp=cpl_table_duplicate(*efficiency);
480 row=cpl_table_and_selected_double(tmp,
"Eff",CPL_GREATER_THAN,0.);
481 uves_free_table(efficiency);
482 *efficiency=cpl_table_extract_selected(tmp);
483 uves_free_table(&tmp);
488 *blaze_efficiency = cpl_table_new(norders);
489 cpl_table_new_column(*blaze_efficiency,
"Order", CPL_TYPE_INT);
490 cpl_table_new_column(*blaze_efficiency,
"Wave" , CPL_TYPE_DOUBLE);
491 cpl_table_new_column(*blaze_efficiency,
"Eff" , CPL_TYPE_DOUBLE);
494 for (order = 1; order <= norders; order++)
497 double lambda_central_min;
498 double lambda_central;
499 double lambda_central_max;
501 double top_efficiency;
507 "Error reading bin width from header");
510 "Error reading bin width from header");
512 lambda_central_min = lambda_min + 0.4 * (lambda_max - lambda_min);
513 lambda_central = lambda_min + 0.5 * (lambda_max - lambda_min);
514 lambda_central_max = lambda_min + 0.6 * (lambda_max - lambda_min);
518 cpl_table_select_all(*efficiency);
519 cpl_table_and_selected_int (*efficiency,
"Order",
520 CPL_EQUAL_TO , order);
521 cpl_table_and_selected_double(*efficiency,
"Wave" ,
522 CPL_GREATER_THAN, lambda_central_min);
523 cpl_table_and_selected_double(*efficiency,
"Wave" ,
524 CPL_LESS_THAN , lambda_central_max);
526 uves_msg_debug(
"%" CPL_SIZE_FORMAT
" bins in central 20 %% range of order #%d",
527 cpl_table_count_selected(*efficiency), order);
529 if ( cpl_table_count_selected(*efficiency) > 0)
531 uves_free_table(¢ral_efficiency);
532 central_efficiency = cpl_table_extract_selected(*efficiency);
535 uves_sort_table_1(central_efficiency,
"Eff",
false);
537 top_efficiency = cpl_table_get_double(
538 central_efficiency,
"Eff",
539 (
int) (0.9 * cpl_table_get_nrow(central_efficiency)), NULL);
543 uves_msg_debug(
"No wavelength bins in central 20%% range of order #%d",
548 uves_msg(
"Efficiency(lambda = %.2f A) = %.2f%%",
549 lambda_central, top_efficiency*100);
551 check(( cpl_table_set_int (*blaze_efficiency,
"Order", row, order),
552 cpl_table_set_double(*blaze_efficiency,
"Wave" , row, lambda_central),
553 cpl_table_set_double(*blaze_efficiency,
"Eff" , row, top_efficiency),
555 "Error updating blaze efficiency table");
560 uves_free_image(&background);
561 uves_free_image(&rebinned_spectrum);
562 uves_free_image(&rebinned_noise);
563 uves_free_image(&merged_sky);
564 uves_free_image(&merged_spectrum);
565 uves_free_image(&merged_noise);
566 uves_free_image(&reduced_spectrum);
567 uves_free_image(&reduced_noise);
568 uves_free_image(&reduced_rebinned);
569 uves_free_image(&reduced_rebinned_noise);
570 uves_free_propertylist(&reduced_header);
571 uves_free_propertylist(&rebinned_header);
574 uves_free_image(&response_orders);
575 uves_free_image(&efficiency_spectrum);
576 uves_free_table(¢ral_efficiency);
577 uves_free_table(&info_tbl);
579 cpl_free(ref_obj_id);
581 if (cpl_error_get_code() != CPL_ERROR_NONE)
583 uves_free_table(efficiency);
584 uves_free_table(blaze_efficiency);
587 return cpl_error_get_code();
int uves_pfits_get_firstabsorder(const uves_propertylist *plist)
Get first absolute order number.
polynomial * uves_polynomial_collapse(const polynomial *p, int varno, double value)
Collapse a polynomial by fixing one variable to a constant.
cpl_error_code uves_filter_image_median(cpl_image **image, int xwindow, int ywindow, bool extrapolate_border)
Median filter.
void uves_polynomial_delete(polynomial **p)
Delete a polynomial.
int uves_pfits_get_lastabsorder(const uves_propertylist *plist)
Get last absolute order number.
int uves_absolute_order(int first_abs_order, int last_abs_order, int relative_order)
Get the absolute order number.
double uves_pfits_get_wstart(const uves_propertylist *plist, int order)
Read the wstart keyword.
double uves_polynomial_derivative_2d(const polynomial *p, double x1, double x2, int varno)
Evaluate the partial derivative of a 2d polynomial.
#define uves_msg(...)
Print a message on 'info' or 'debug' level.
cpl_image * uves_normalize_spectrum(const cpl_image *spectrum, const cpl_image *spectrum_error, const uves_propertylist *spectrum_header, const uves_propertylist *raw_header, int n_traces, enum uves_chip chip, const cpl_table *atm_extinction, bool correct_binning, cpl_image **scaled_error)
Normalize a spectrum.
#define uves_msg_debug(...)
Print a debug message.
double uves_pfits_get_cdelt1(const uves_propertylist *plist)
Find out the cdelt1.
cpl_error_code uves_response_efficiency(const cpl_image *raw_image, const uves_propertylist *raw_header, const uves_propertylist *rotated_header, const cpl_image *master_bias, const uves_propertylist *mbias_header, const cpl_image *master_dark, const uves_propertylist *mdark_header, const cpl_table *ordertable, const polynomial *order_locations, const cpl_table *linetable[3], const uves_propertylist *linetable_header[3], const polynomial *dispersion_relation[3], const cpl_table *flux_table, const cpl_table *atm_extinction, enum uves_chip chip, bool debug_mode, const cpl_parameterlist *parameters, double PACCURACY, cpl_table **efficiency, cpl_table **blaze_efficiency)
Calculate quantum detection efficiency.
cpl_image * uves_calculate_response(const cpl_image *spectrum, const uves_propertylist *spectrum_header, const cpl_table *flux_table, const uves_propertylist *raw_header, double PACCURACY, bool inverse, char **ref_obj_id)
Calculate response.
double uves_polynomial_solve_1d(const polynomial *p, double value, double guess, int multiplicity)
Solve p(x) = value.
cpl_error_code uves_reduce(const cpl_image *raw_image, const uves_propertylist *raw_header, const uves_propertylist *rotated_header, const cpl_image *master_bias, const uves_propertylist *mbias_header, const cpl_image *master_dark, const uves_propertylist *mdark_header, const cpl_image *master_flat, const uves_propertylist *mflat_header, const cpl_table *ordertable, const polynomial *order_locations, const cpl_table *linetable[3], const uves_propertylist *linetable_header[3], const polynomial *dispersion_relation[3], enum uves_chip chip, bool debug_mode, const cpl_parameterlist *parameters, const char *rec_id, const char *mode, cpl_image **x, uves_propertylist **x_header, cpl_image **fx, cpl_table **cosmic_mask, cpl_image **wave_map, cpl_image **background, cpl_image **flatfielded_variance, uves_propertylist **flatfielded_variance_header, cpl_image **resampled_spectrum, cpl_image **resampled_mf, cpl_image **merged_sky, cpl_image **rebinned_spectrum, cpl_image **rebinned_noise, uves_propertylist **rebinned_header, cpl_image **merged_spectrum, cpl_image **merged_noise, uves_propertylist **merged_header, cpl_image **reduced_rebinned_spectrum, cpl_image **reduced_rebinned_noise, cpl_image **reduced_spectrum, cpl_image **reduced_noise, cpl_table **info_tbl, double *extraction_slit, cpl_table **order_trace)
Reduce a science frame.
double uves_pfits_get_wend(const uves_propertylist *plist, int order)
Read the wend keyword.