31 #include "muse_xcombine.h"
33 #include "muse_pfits.h"
35 #include "muse_utils.h"
83 cpl_ensure_code(aPixtables, CPL_ERROR_NULL_INPUT);
85 while (aPixtables[npt++]) ;
86 cpl_ensure_code(--npt > 1, CPL_ERROR_ILLEGAL_INPUT);
88 cpl_msg_info(__func__,
"%d tables, not weighting them", npt);
89 return CPL_ERROR_NONE;
92 cpl_msg_warning(__func__,
"Unknown exposure weighting scheme (%d)",
94 return cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
97 cpl_msg_info(__func__,
"%d tables to be weighted using %s", npt,
101 if (exptime0 == 0.0) {
102 return cpl_error_set(__func__, CPL_ERROR_INCOMPATIBLE_INPUT);
111 for (i = 0; i < npt; i++) {
113 weight = exptime / exptime0;
114 if (!cpl_table_has_column(aPixtables[i]->table, MUSE_PIXTABLE_WEIGHT)) {
115 cpl_table_new_column(aPixtables[i]->table, MUSE_PIXTABLE_WEIGHT,
120 cpl_errorstate prestate = cpl_errorstate_get();
123 if (fwhm == 0. || !cpl_errorstate_is_equal(prestate)) {
124 cpl_msg_warning(__func__,
"No seeing info in table %d. Weighting it "
125 "equal to first table!", i+1);
128 weight *= fwhm0 / fwhm;
130 cpl_msg_debug(__func__,
"Table %d, weight = %f", i+1, weight);
131 cpl_table_fill_column_window_float(aPixtables[i]->table,
132 MUSE_PIXTABLE_WEIGHT,
139 MUSE_HDR_PT_WEIGHTED_COMMENT);
142 return CPL_ERROR_NONE;
194 cpl_ensure(aPixtables, CPL_ERROR_NULL_INPUT, NULL);
195 unsigned int npt = 0;
196 while (aPixtables[npt++]) ;
197 cpl_ensure(--npt > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
199 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
200 cpl_msg_info(__func__,
"%u tables to be combined", npt);
203 cpl_array *dra = NULL,
205 char *raenv = getenv(
"MUSE_XCOMBINE_RA_OFFSETS"),
206 *decenv = getenv(
"MUSE_XCOMBINE_DEC_OFFSETS");
209 unsigned int nra = cpl_array_get_size(dra);
211 cpl_msg_warning(__func__,
"Found %u RA offsets for %u exposures, not "
212 "using them!", nra, npt);
213 cpl_array_delete(dra);
216 cpl_msg_info(__func__,
"Using %u RA offsets", nra);
221 unsigned int ndec = cpl_array_get_size(ddec);
223 cpl_msg_warning(__func__,
"Found %u DEC offsets for %u exposures, not "
224 "using them!", ndec, npt);
225 cpl_array_delete(ddec);
228 cpl_msg_info(__func__,
"Using %u DEC offsets", ndec);
232 double timeinit = cpl_test_get_walltime(),
233 cpuinit = cpl_test_get_cputime();
236 aPixtables[0] = NULL;
239 cpl_msg_warning(__func__,
"Data of exposure 1 (DATE-OBS=%s) was not radial-"
245 char keyword[KEYWORD_LENGTH], comment[KEYWORD_LENGTH];
247 cpl_propertylist_append_long_long(pt->
header, keyword, 0);
248 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_FST_COMMENT, 1);
249 cpl_propertylist_set_comment(pt->
header, keyword, comment);
251 cpl_propertylist_append_long_long(pt->
header, keyword,
253 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_LST_COMMENT, 1);
254 cpl_propertylist_set_comment(pt->
header, keyword, comment);
259 double raoff = atof(cpl_array_get_string(dra, 0));
262 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA, 1);
263 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA_C, raoff * 3600.);
264 cpl_propertylist_append_double(pt->
header, keyword, raoff);
265 cpl_propertylist_set_comment(pt->
header, keyword, comment);
268 double decoff = atof(cpl_array_get_string(ddec, 0));
271 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC, 1);
272 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC_C, decoff * 3600.);
273 cpl_propertylist_append_double(pt->
header, keyword, decoff);
274 cpl_propertylist_set_comment(pt->
header, keyword, comment);
278 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS, 1);
279 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS_C, 1);
280 cpl_propertylist_append_string(pt->
header, keyword,
282 cpl_propertylist_set_comment(pt->
header, keyword, comment);
286 unsigned int i, nskipped = 0;
287 for (i = 1; i < npt; i++) {
289 cpl_msg_warning(__func__,
"Exposure %d was not projected to native "
290 "spherical coordinates, skipping this one!", i + 1);
295 cpl_msg_warning(__func__,
"Data of exposure %u (DATE-OBS=%s) was not "
296 "radial-velocity corrected!", i+1,
304 double raoff = atof(cpl_array_get_string(dra, i));
306 cpl_msg_debug(__func__,
"positioning not to RA %f but to %f (dRA = %f "
307 "deg)", ra + raoff, ra, raoff);
309 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA, i + 1);
310 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA_C, raoff * 3600.);
311 cpl_propertylist_append_double(pt->
header, keyword, raoff);
312 cpl_propertylist_set_comment(pt->
header, keyword, comment);
315 double decoff = atof(cpl_array_get_string(ddec, i));
317 cpl_msg_debug(__func__,
"positioning not to DEC %f but to %f (dDEC = %f "
318 "deg)", dec + decoff, dec, decoff);
320 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC, i + 1);
321 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC_C, decoff * 3600.);
322 cpl_propertylist_append_double(pt->
header, keyword, decoff);
323 cpl_propertylist_set_comment(pt->
header, keyword, comment);
327 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS, i + 1);
328 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS_C, i + 1);
329 cpl_propertylist_append_string(pt->
header, keyword,
331 cpl_propertylist_set_comment(pt->
header, keyword, comment);
336 double raoffset = ra - ra0,
337 decoffset = dec - dec0;
341 float *xpos = cpl_table_get_data_float(aPixtables[i]->table, MUSE_PIXTABLE_XPOS),
342 *ypos = cpl_table_get_data_float(aPixtables[i]->table, MUSE_PIXTABLE_YPOS);
344 #pragma omp parallel for default(none) \
345 shared(decoffset, nrowi, raoffset, xpos, ypos)
346 for (irow = 0; irow < nrowi; irow++) {
347 xpos[irow] += raoffset;
348 ypos[irow] += decoffset;
352 cpl_table_add_scalar(aPixtables[i]->table, MUSE_PIXTABLE_XPOS, raoffset);
353 cpl_table_add_scalar(aPixtables[i]->table, MUSE_PIXTABLE_YPOS, decoffset);
357 double avdec = (dec + dec0) / 2.,
358 raoff = (ra - ra0) * cos(avdec * CPL_MATH_RAD_DEG),
360 cpl_msg_info(__func__,
"Approx. offset of exposure %u: %.3e,%.3e deg", i+1,
365 cpl_table_insert(pt->
table, aPixtables[i]->
table, nrow);
369 aPixtables[i] = NULL;
373 cpl_propertylist_append_long_long(pt->
header, keyword, nrow);
374 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_FST_COMMENT, i + 1);
375 cpl_propertylist_set_comment(pt->
header, keyword, comment);
377 cpl_propertylist_append_long_long(pt->
header, keyword,
379 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_LST_COMMENT, i + 1);
380 cpl_propertylist_set_comment(pt->
header, keyword, comment);
382 cpl_array_delete(dra);
383 cpl_array_delete(ddec);
388 MUSE_HDR_PT_COMBINED_COMMENT);
390 double timefini = cpl_test_get_walltime(),
391 cpufini = cpl_test_get_cputime();
393 cpl_msg_debug(__func__,
"Combining %u tables took %gs (wall-clock) and %gs "
394 "(CPU)", npt, timefini - timeinit, cpufini - cpuinit);
#define MUSE_HDR_PT_EXP_FST
FITS header keyword defining the first row index for a given exposure.
double muse_pfits_get_ra(const cpl_propertylist *aHeaders)
find out the right ascension
cpl_size muse_pixtable_get_nrow(const muse_pixtable *aPixtable)
get the number of rows within the pixel table
#define MUSE_HDR_PT_EXP_LST
FITS header keyword defining the last row index for a given exposure.
void muse_utils_memory_dump(const char *aMarker)
Display the current memory usage of the given program.
const char * muse_pfits_get_dateobs(const cpl_propertylist *aHeaders)
find out the date of observations
#define MUSE_HDR_PT_COMBINED
cpl_table * table
The pixel table.
cpl_error_code muse_xcombine_weights(muse_pixtable **aPixtables, muse_xcombine_types aWeighting)
compute the weights for combination of two or more exposures
cpl_error_code muse_pixtable_origin_copy_offsets(muse_pixtable *aOut, muse_pixtable *aFrom, unsigned int aNum)
Copy MUSE_HDR_PT_IFU_SLICE_OFFSET keywords between pixel tables.
cpl_array * muse_cplarray_new_from_delimited_string(const char *aString, const char *aDelim)
Convert a delimited string into an array of strings.
double muse_pfits_get_fwhm_end(const cpl_propertylist *aHeaders)
find out the ambient seeing at end of exposure (in arcsec)
Structure definition of MUSE pixel table.
#define MUSE_HDR_PT_WEIGHTED
muse_pixtable_wcs muse_pixtable_wcs_check(muse_pixtable *aPixtable)
Check the state of the world coordinate system of a pixel table.
double muse_pfits_get_fwhm_start(const cpl_propertylist *aHeaders)
find out the ambient seeing at start of exposure (in arcsec)
double muse_pfits_get_dec(const cpl_propertylist *aHeaders)
find out the declination
muse_pixtable * muse_xcombine_tables(muse_pixtable **aPixtables)
combine the pixel tables of several exposures into one
double muse_pfits_get_exptime(const cpl_propertylist *aHeaders)
find out the exposure time
cpl_error_code muse_wcs_position_celestial(muse_pixtable *aPixtable, double aRA, double aDEC)
Convert native to celestial spherical coordinates in a pixel table.
void muse_pixtable_delete(muse_pixtable *aPixtable)
Deallocate memory associated to a pixel table object.
muse_xcombine_types
Xposure combination types.
cpl_error_code muse_pixtable_compute_limits(muse_pixtable *aPixtable)
(Re-)Compute the limits of the coordinate columns of a pixel table.
cpl_propertylist * header
The FITS header.
cpl_boolean muse_pixtable_is_rvcorr(muse_pixtable *aPixtable)
Determine whether the pixel table is radial-velocity corrected.