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);
348 "Could not read order numbers from line table header");
350 "Could not read order numbers from line table header");
353 "Error reading bin width from header");
355 check( average_noise = cpl_image_get_median(reduced_rebinned_noise),
356 "Error reading median noise level");
358 for (order = 1; order <= norders; order++)
360 double lambda_start, lambda, lambda_end;
367 "Error reading start wavelength from header");
370 "Error reading end wavelength from header");
382 "Error getting 1d dispersion relation for absolute order #%d", abs_order);
385 for (lambda = lambda_start, bin = 1;
386 lambda < lambda_end + 0.5 * dlambda && bin <= nbins;
387 bin++, lambda += dlambda)
398 flux = efficiency_data [(bin-1) + (order-1) * nbins];
399 noise = reduced_noise_data[(bin-1) + (order-1) * nbins];
422 "Could not solve dispersion relation for x "
423 "at (m, lambda) = (%d, %f)", abs_order, lambda);
431 dispersion_relation[1],
433 abs_order, 1) / abs_order),
434 "Could not evaluate dispersion relation");
450 flux = flux * 1e16 * 1e17 * H_BAR * SPEED_OF_LIGHT /
451 (dldx * lambda * TELESCOPE_EFFECTIVE_AREA);
458 if (noise < 3*average_noise)
460 check(( cpl_table_set_double(*efficiency,
"Wave", row, lambda),
461 cpl_table_set_double(*efficiency,
"Eff", row, flux),
462 cpl_table_set_double(*efficiency,
"Binsize", row, dldx),
463 cpl_table_set_int (*efficiency,
"Order", row, order),
465 "Error updating efficiency table row %d", row);
471 check( cpl_table_set_size(*efficiency, row),
472 "Error setting size of efficiency table to %d rows", row);
474 cpl_table* tmp=cpl_table_duplicate(*efficiency);
475 row=cpl_table_and_selected_double(tmp,
"Eff",CPL_GREATER_THAN,0.);
476 uves_free_table(efficiency);
477 *efficiency=cpl_table_extract_selected(tmp);
478 uves_free_table(&tmp);
483 *blaze_efficiency = cpl_table_new(norders);
484 cpl_table_new_column(*blaze_efficiency,
"Order", CPL_TYPE_INT);
485 cpl_table_new_column(*blaze_efficiency,
"Wave" , CPL_TYPE_DOUBLE);
486 cpl_table_new_column(*blaze_efficiency,
"Eff" , CPL_TYPE_DOUBLE);
489 for (order = 1; order <= norders; order++)
492 double lambda_central_min;
493 double lambda_central;
494 double lambda_central_max;
496 double top_efficiency;
502 "Error reading bin width from header");
505 "Error reading bin width from header");
507 lambda_central_min = lambda_min + 0.4 * (lambda_max - lambda_min);
508 lambda_central = lambda_min + 0.5 * (lambda_max - lambda_min);
509 lambda_central_max = lambda_min + 0.6 * (lambda_max - lambda_min);
513 cpl_table_select_all(*efficiency);
514 cpl_table_and_selected_int (*efficiency,
"Order",
515 CPL_EQUAL_TO , order);
516 cpl_table_and_selected_double(*efficiency,
"Wave" ,
517 CPL_GREATER_THAN, lambda_central_min);
518 cpl_table_and_selected_double(*efficiency,
"Wave" ,
519 CPL_LESS_THAN , lambda_central_max);
521 uves_msg_debug(
"%" CPL_SIZE_FORMAT
" bins in central 20 %% range of order #%d",
522 cpl_table_count_selected(*efficiency), order);
524 if ( cpl_table_count_selected(*efficiency) > 0)
526 uves_free_table(¢ral_efficiency);
527 central_efficiency = cpl_table_extract_selected(*efficiency);
530 uves_sort_table_1(central_efficiency,
"Eff",
false);
532 top_efficiency = cpl_table_get_double(
533 central_efficiency,
"Eff",
534 (
int) (0.9 * cpl_table_get_nrow(central_efficiency)), NULL);
538 uves_msg_debug(
"No wavelength bins in central 20%% range of order #%d",
543 uves_msg(
"Efficiency(lambda = %.2f A) = %.2f%%",
544 lambda_central, top_efficiency*100);
546 check(( cpl_table_set_int (*blaze_efficiency,
"Order", row, order),
547 cpl_table_set_double(*blaze_efficiency,
"Wave" , row, lambda_central),
548 cpl_table_set_double(*blaze_efficiency,
"Eff" , row, top_efficiency),
550 "Error updating blaze efficiency table");
555 uves_free_image(&background);
556 uves_free_image(&rebinned_spectrum);
557 uves_free_image(&rebinned_noise);
558 uves_free_image(&merged_sky);
559 uves_free_image(&merged_spectrum);
560 uves_free_image(&merged_noise);
561 uves_free_image(&reduced_spectrum);
562 uves_free_image(&reduced_noise);
563 uves_free_image(&reduced_rebinned);
564 uves_free_image(&reduced_rebinned_noise);
565 uves_free_propertylist(&reduced_header);
566 uves_free_propertylist(&rebinned_header);
569 uves_free_image(&response_orders);
570 uves_free_image(&efficiency_spectrum);
571 uves_free_table(¢ral_efficiency);
572 uves_free_table(&info_tbl);
574 cpl_free(ref_obj_id);
576 if (cpl_error_get_code() != CPL_ERROR_NONE)
578 uves_free_table(efficiency);
579 uves_free_table(blaze_efficiency);
582 return cpl_error_get_code();