40 #include "irplib_framelist.h"
42 #include "visir_spc_photom.h"
44 #include "visir_parameter.h"
45 #include "visir_utils.h"
46 #include "visir_pfits.h"
47 #include "visir_spc_distortion.h"
53 static cpl_bivector * visir_spc_phot_model_from_cat(
const char *,
double,
55 static int visir_spc_phot_model_rebin(
const cpl_bivector *, cpl_table *);
58 double *,
double *,
double *,
61 static cpl_error_code visir_spc_phot_qc(cpl_propertylist *,
62 const char *,
double,
double,
double,
92 const cpl_propertylist * plist,
93 const char * star_cat,
94 cpl_image ** pweight2d,
95 cpl_propertylist * qclist,
96 cpl_table * spc_table,
100 cpl_errorstate cleanstate = cpl_errorstate_get();
101 cpl_bivector * flux_model = NULL;
105 double sens_median = -1.0;
106 double sens_mean = -1.0;
107 double sens_stdev = -1.0;
108 double exptime, factor, exectime = -1.;
112 const char * star_name;
118 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
120 CPL_TYPE_DOUBLE, CPL_TRUE, 1e-5)) {
123 visir_error_reset(
"DIT differs by more than %g", 1e-5);
128 CPL_TYPE_DOUBLE, CPL_FALSE, 0.0));
132 CPL_TYPE_DOUBLE, CPL_TRUE, 1.0));
135 CPL_TYPE_INT, CPL_TRUE, 0.0));
138 CPL_TYPE_INT, CPL_TRUE, 0.0));
141 CPL_TYPE_STRING, CPL_TRUE, 0.0)) {
142 visir_error_reset(
"Rawframe(s) missing standard star name");
145 if (cpl_propertylist_has(plist,
"ESO QC EXPTIME"))
146 exptime = cpl_propertylist_get_double(plist,
"ESO QC EXPTIME");
149 exptime = visir_utils_get_exptime(nnod, plist);
151 cpl_msg_info(cpl_func,
"Exposure time: %.3f", exptime);
152 if (cpl_propertylist_has(plist,
"ESO QC EXECTIME"))
153 exectime = cpl_propertylist_get_double(plist,
"ESO QC EXECTIME");
155 skip_if (exptime <= 0.0);
157 factor = sqrt(exptime)/6.0;
161 if (star_name == NULL) visir_error_reset(
"Could not get standard star name");
164 if ((flux_model=visir_spc_phot_model_from_cat(star_cat, ra, dec)) == NULL) {
165 cpl_msg_error(cpl_func,
"Cannot retrieve the flux model from the cat.");
170 if (visir_spc_phot_model_rebin(flux_model, spc_table) == -1) {
171 cpl_msg_error(cpl_func,
"Cannot rebin the flux model");
174 cpl_bivector_delete(flux_model);
180 cpl_table_duplicate_column(spc_table,
"SENSITIVITY", spc_table,
182 cpl_table_set_column_unit(spc_table,
"SENSITIVITY",
"mJy");
184 ext_array = cpl_table_get_data_double(spc_table,
"SENSITIVITY");
185 spc_array = cpl_table_get_data_double(spc_table,
"SPC_EXTRACTED");
186 err_array = cpl_table_get_data_double(spc_table,
"SPC_ERROR");
188 for (cpl_size i = 0; i < cpl_table_get_nrow(spc_table); i++) {
189 ext_array[i] *= factor * err_array[i];
190 if (ext_array[i] < 0 || spc_array[i] <= 0) {
191 cpl_msg_warning(cpl_func,
"Setting non-physical sensitivity in row %d "
192 "to 0: %g/%g", (
int)i+1, ext_array[i], spc_array[i]);
195 ext_array[i] /= spc_array[i];
199 skip_if(visir_spc_sens_stat(pconfig, &sens_median, &sens_mean, &sens_stdev, spc_table));
202 skip_if (cpl_table_erase_column(spc_table,
"SPC_EMISSIVITY"));
204 skip_if (visir_spc_phot_qc(qclist, star_name, exptime, exectime,
205 sens_median, sens_mean, sens_stdev));
209 visir_table_plot(
"",
"t 'Extracted spectrum' w lines",
"", spc_table,
210 "WLEN",
"SPC_EXTRACTED");
211 visir_table_plot(
"",
"t 'Extracted spectrum error' w lines",
"",
212 spc_table,
"WLEN",
"SPC_ERROR");
213 visir_table_plot(
"",
"t 'Standard star model' w lines",
"", spc_table,
214 "WLEN",
"STD_STAR_MODEL");
215 visir_table_plot(
"set grid;",
"t 'Sensitivity (mJy)' w lines",
"",
216 spc_table,
"WLEN",
"SENSITIVITY");
217 visir_image_plot(
"",
"t 'The weight map'",
"", *pweight2d);
221 cpl_bivector_delete(flux_model);
223 return cpl_error_get_code();
250 const irplib_framelist * rawframes,
252 const char * star_cat,
253 const char * spc_cal_lines,
254 const char * spc_cal_qeff,
255 cpl_image ** pweight2d,
256 cpl_propertylist * qclist,
262 const visir_spc_resol resol,
263 const char * dit_key)
265 const cpl_propertylist * plist;
266 const cpl_frame * frm = NULL;
267 cpl_imagelist * hcycle = NULL;
268 cpl_image * imhcycle = NULL;
269 cpl_image * flipped = NULL;
270 cpl_image * comorder = NULL;
271 cpl_image * order = NULL;
272 cpl_table * spc_table = NULL;
273 visir_data_type dtype;
277 skip_if (rawframes == NULL);
283 skip_if (visir_get_data_type(frm, plist, &dtype, NULL));
289 skip_if (pconfig->do_fixcombi &&
290 visir_spc_det_fix(combined, 1, CPL_TRUE,
299 imhcycle = cpl_imagelist_unset(hcycle, 0);
302 skip_if (visir_spc_det_fix(&imhcycle, 1, CPL_FALSE,
311 flipped = visir_spc_flip(*combined, wlen, resol, dtype);
313 cpl_image_delete(*combined);
318 flipped = visir_spc_flip(imhcycle, wlen, resol, dtype);
320 cpl_image_delete(imhcycle);
324 skip_if(visir_spc_extract_order(&order, &comorder,
326 wlen, pconfig, do_ech,
327 visir_data_is_aqu(dtype)));
331 skip_if (visir_spc_echelle_limit(&icol1, &icol2, wlen,
332 pconfig->orderoffset,
333 1, cpl_image_get_size_y(*combined),
334 visir_data_is_aqu(dtype)));
335 skip_if(visir_qc_append_background(qclist, rawframes, icol1, icol2));
338 skip_if(visir_qc_append_background(qclist, rawframes, 0, 0));
341 skip_if (visir_spc_extract_wcal(comorder,
342 order, wlen, slitw, temp, fwhm,
343 resol, pconfig->orderoffset,
344 spc_cal_lines, spc_cal_qeff,
345 &spc_table, pweight2d,
347 pconfig->plot, CPL_FALSE,
348 visir_data_is_aqu(dtype)));
351 qclist, spc_table, dit_key);
353 cpl_imagelist_delete(hcycle);
359 cpl_imagelist_delete(hcycle);
361 cpl_image_delete(flipped);
362 cpl_image_delete(imhcycle);
363 cpl_image_delete(order);
364 cpl_image_delete(comorder);
366 if (cpl_error_get_code()) {
367 cpl_table_delete(spc_table);
369 cpl_image_delete(*pweight2d);
391 static cpl_bivector * visir_spc_phot_model_from_cat(
const char * star_cat,
395 const double max_radius = VISIR_STAR_MAX_RADIUS;
396 const cpl_table * catalog = NULL;
399 const cpl_array * da;
400 cpl_vector * v_ra = NULL;
401 cpl_vector * v_dec = NULL;
403 cpl_bivector * model = NULL;
404 cpl_vector * model_x = NULL;
405 cpl_vector * model_y = NULL;
406 const double conv_mJy = 3.33E8;
414 catalog = cpl_table_load(star_cat, 1, 0);
415 if (catalog == NULL) {
416 cpl_msg_error(cpl_func,
"Could not open the star catalog: %s",
417 star_cat ? star_cat :
"<NULL>");
421 nb_stars = cpl_table_get_nrow(catalog);
423 skip_if(nb_stars < 1);
426 dd = cpl_table_get_data_double_const(catalog,
"RA");
427 skip_if (dd == NULL);
428 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
429 v_ra = cpl_vector_wrap(nb_stars, (
double*)dd);
430 IRPLIB_DIAG_PRAGMA_POP;
431 bug_if( v_ra == NULL);
433 dd = cpl_table_get_data_double_const(catalog,
"DEC");
434 skip_if (dd == NULL);
435 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
436 v_dec = cpl_vector_wrap(nb_stars, (
double*)dd);
437 IRPLIB_DIAG_PRAGMA_POP;
438 bug_if( v_dec == NULL);
441 min_dist_ind = visir_star_find(v_ra, v_dec, ra, dec, max_radius, &star_dist);
443 skip_if (min_dist_ind < 0);
445 cpl_msg_info(cpl_func,
"The standard star closest to (RA,DEC)=(%g,%g) is "
446 "no. %d, '%s' at (RA,DEC)=(%g,%g) with the distance [degree]: "
447 "%g", ra, dec, 1+min_dist_ind,
448 cpl_table_get_string(catalog,
"STARS", min_dist_ind),
449 cpl_table_get_double(catalog,
"RA", min_dist_ind, NULL),
450 cpl_table_get_double(catalog,
"DEC", min_dist_ind, NULL),
454 da = cpl_table_get_array(catalog,
"WAVELENGTHS", min_dist_ind);
455 skip_if (da == NULL);
456 dd = cpl_array_get_data_double_const(da);
457 skip_if (dd == NULL);
459 nb_vals = cpl_array_get_size(da);
461 model_x = cpl_vector_new(nb_vals);
462 memcpy(cpl_vector_get_data(model_x), dd, nb_vals *
sizeof(
double));
465 da = cpl_table_get_array(catalog,
"MODEL_FLUX", min_dist_ind);
466 skip_if (da == NULL);
467 dd = cpl_array_get_data_double_const(da);
468 skip_if (dd == NULL);
470 skip_if (nb_vals != cpl_array_get_size(da));
472 model_y = cpl_vector_new(nb_vals);
473 memcpy(cpl_vector_get_data(model_y), dd, nb_vals *
sizeof(
double));
476 bug_if (cpl_vector_multiply_scalar(model_y, conv_mJy));
477 bug_if (cpl_vector_multiply(model_y, model_x));
478 bug_if (cpl_vector_multiply(model_y, model_x));
481 bug_if (cpl_vector_multiply_scalar(model_x, 1e-6));
483 model = cpl_bivector_wrap_vectors(model_x, model_y);
485 bug_if (model == NULL);
489 (void)cpl_vector_unwrap(v_ra);
490 (void)cpl_vector_unwrap(v_dec);
491 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
492 cpl_table_delete((cpl_table*)catalog);
493 IRPLIB_DIAG_PRAGMA_POP;
495 if (cpl_error_get_code()) {
497 cpl_vector_delete(model_x);
498 cpl_vector_delete(model_y);
511 static int visir_spc_phot_model_rebin(
512 const cpl_bivector * model,
513 cpl_table * spec_tab)
515 cpl_vector * bounds = NULL;
516 cpl_vector * spec = NULL;
518 const int nrow = cpl_table_get_nrow(spec_tab);
525 bounds = cpl_vector_new(nrow + 1);
526 for (i=1 ; i<cpl_vector_get_size(bounds) - 1 ; i++) {
527 bin_pos = (cpl_table_get(spec_tab,
"WLEN", i-1, NULL) +
528 cpl_table_get(spec_tab,
"WLEN", i, NULL)) / 2.0;
529 cpl_vector_set(bounds, i, bin_pos);
531 bin_pos = cpl_table_get(spec_tab,
"WLEN", 0, NULL) -
532 ((cpl_table_get(spec_tab,
"WLEN", 1, NULL) -
533 cpl_table_get(spec_tab,
"WLEN", 0, NULL)) / 2.0);
534 cpl_vector_set(bounds, 0, bin_pos);
536 cpl_table_get(spec_tab,
"WLEN", nrow-1, NULL) +
537 ((cpl_table_get(spec_tab,
"WLEN", 1, NULL) -
538 cpl_table_get(spec_tab,
"WLEN", 0, NULL)) / 2.0);
539 cpl_vector_set(bounds, cpl_vector_get_size(bounds)-1, bin_pos);
542 spec = cpl_vector_new(nrow);
545 if (visir_vector_resample(spec, bounds, model)) {
546 cpl_msg_error(cpl_func,
"Cannot rebin the spectrum");
551 cpl_table_new_column(spec_tab,
"STD_STAR_MODEL", CPL_TYPE_DOUBLE);
552 cpl_table_set_column_unit(spec_tab,
"STD_STAR_MODEL",
"mJy");
553 for (i=0 ; i<nrow ; i++) {
554 cpl_table_set_double(spec_tab,
"STD_STAR_MODEL", i,
555 cpl_vector_get(spec, i));
560 cpl_vector_delete(spec);
561 cpl_vector_delete(bounds);
563 return cpl_error_get_code();
578 double * psens_median,
580 double * psens_stdev,
581 const cpl_table * spc_table)
584 cpl_vector * sens_ignore = NULL;
585 cpl_vector * sens_mini = NULL;
586 double emis_min, emis_max;
587 const int npix = cpl_table_get_nrow(spc_table);
588 const int npix_ignore = 3;
594 skip_if(pconfig == NULL);
600 IRPLIB_DIAG_PRAGMA_PUSH_IGN(-Wcast-qual);
601 sens_ignore = cpl_vector_wrap( npix - 2*npix_ignore, (
double*)
602 cpl_table_get_data_double_const(spc_table,
603 "SENSITIVITY") + npix_ignore);
604 IRPLIB_DIAG_PRAGMA_POP;
608 visir_vector_plot(
"set grid;",
"t 'Truncated Sensitivity (mJy)' w lines",
611 sens_mini = cpl_vector_duplicate(sens_ignore);
614 emis_min = cpl_table_get_column_min(spc_table,
"SPC_EMISSIVITY");
615 emis_max = cpl_table_get_column_max(spc_table,
"SPC_EMISSIVITY");
618 emis_max = emis_min + pconfig->phot_emis_tol * (emis_max - emis_min);
621 for (i=0; i < npix - 2*npix_ignore; i++) {
622 const double emis = cpl_table_get(spc_table,
"SPC_EMISSIVITY",
623 i + npix_ignore, NULL);
627 if (emis > emis_max)
continue;
630 skip_if(cpl_vector_set(sens_mini, iok, cpl_vector_get(sens_mini, i)));
638 skip_if(cpl_vector_set_size(sens_mini, iok));
640 *psens_mean = cpl_vector_get_mean(sens_mini);
643 cpl_msg_warning(cpl_func,
"Sensitivity computed on only 1 wavelength "
644 "with emissivity %f", emis_max);
647 cpl_msg_info(cpl_func,
"Sensitivity computed on %d wavelengths with "
648 "emissivity at most %f", iok, emis_max);
650 *psens_stdev = cpl_vector_get_stdev(sens_mini);
654 *psens_median = cpl_vector_get_median(sens_mini);
658 cpl_vector_unwrap(sens_ignore);
659 cpl_vector_delete(sens_mini);
661 return cpl_error_get_code();
680 static cpl_error_code visir_spc_phot_qc(cpl_propertylist *
self,
681 const char * star_name,
689 bug_if (cpl_propertylist_append_double(
self,
"ESO QC EXPTIME", exptime));
691 bug_if (cpl_propertylist_append_double(
self,
"ESO QC EXECTIME",
694 bug_if (cpl_propertylist_append_double(
self,
"ESO QC SENS MEDIAN",
696 bug_if (cpl_propertylist_append_double(
self,
"ESO QC SENS MEAN", sens_mean));
697 bug_if (cpl_propertylist_append_double(
self,
"ESO QC SENS STDEV",
700 bug_if (cpl_propertylist_append_string(
self,
"ESO QC STARNAME",
701 star_name ? star_name :
""));
705 return cpl_error_get_code();
double visir_pfits_get_dec(const cpl_propertylist *self)
The DEC.
cpl_error_code visir_spc_phot_sensit(const irplib_framelist *rawframes, const visir_spc_config *pconfig, const cpl_propertylist *plist, const char *star_cat, cpl_image **pweight2d, cpl_propertylist *qclist, cpl_table *spc_table, const char *dit_key)
Compute the sensitivity from an extracted spectrum.
const char * visir_pfits_get_starname(const cpl_propertylist *self)
The std star name.
const cpl_propertylist * irplib_framelist_get_propertylist_const(const irplib_framelist *self, int pos)
Get the propertylist of the specified frame in the framelist.
const cpl_frame * irplib_framelist_get_const(const irplib_framelist *self, int pos)
Get the specified frame from the framelist.
cpl_table * visir_spc_phot_sensit_from_image(cpl_image **combined, const irplib_framelist *rawframes, const visir_spc_config *pconfig, const char *star_cat, const char *spc_cal_lines, const char *spc_cal_qeff, cpl_image **pweight2d, cpl_propertylist *qclist, cpl_boolean do_ech, double wlen, double slitw, double temp, double fwhm, const visir_spc_resol resol, const char *dit_key)
Extract spectrum from image and compute sensitivity.
cpl_error_code irplib_framelist_contains(const irplib_framelist *self, const char *key, cpl_type type, cpl_boolean is_equal, double fp_tol)
Verify that a property is present for all frames.
double visir_pfits_get_ra(const cpl_propertylist *self)
The RA.
int irplib_framelist_get_size(const irplib_framelist *self)
Get the size of a framelist.