00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifdef HAVE_CONFIG_H
00023 #include <config.h>
00024 #endif
00025
00026
00027
00028
00029 #include <cpl.h>
00030 #include <string.h>
00031
00032 #include "muse_xcombine.h"
00033
00034 #include "muse_pfits.h"
00035 #include "muse_wcs.h"
00036 #include "muse_utils.h"
00037 #include "muse_data_format_z.h"
00038
00039
00043
00044
00047
00061
00062 static cpl_table *
00063 muse_xcombine_weights_infotable(muse_pixtable **aPixtables)
00064 {
00065 unsigned int npt = 0;
00066 while (aPixtables[npt++]) ;
00067 --npt;
00068
00069
00070 cpl_table *table = cpl_table_new(npt);
00071 cpl_table_new_column(table, "EXPTIME", CPL_TYPE_DOUBLE);
00072 cpl_table_new_column(table, "AGX_AVG", CPL_TYPE_DOUBLE);
00073 cpl_table_new_column(table, "AGX_RMS", CPL_TYPE_DOUBLE);
00074 cpl_table_new_column(table, "AGY_AVG", CPL_TYPE_DOUBLE);
00075 cpl_table_new_column(table, "AGY_RMS", CPL_TYPE_DOUBLE);
00076 cpl_table_new_column(table, "IA_FWHM", CPL_TYPE_DOUBLE);
00077 cpl_table_new_column(table, "DIMM_START", CPL_TYPE_DOUBLE);
00078 cpl_table_new_column(table, "DIMM_END", CPL_TYPE_DOUBLE);
00079
00080
00081 cpl_errorstate prestate = cpl_errorstate_get();
00082 unsigned int i;
00083 for (i = 0; i < npt; i++) {
00084
00085 cpl_errorstate state = cpl_errorstate_get();
00086 double value = muse_pfits_get_exptime(aPixtables[i]->header);
00087 if (cpl_errorstate_is_equal(state)) {
00088 cpl_table_set_double(table, "EXPTIME", i, value);
00089 }
00090
00091
00092 state = cpl_errorstate_get();
00093 value = muse_pfits_get_agx_avg(aPixtables[i]->header);
00094 if (cpl_errorstate_is_equal(state)) {
00095 cpl_table_set_double(table, "AGX_AVG", i, value);
00096 }
00097 state = cpl_errorstate_get();
00098 value = muse_pfits_get_agx_rms(aPixtables[i]->header);
00099 if (cpl_errorstate_is_equal(state)) {
00100 cpl_table_set_double(table, "AGX_RMS", i, value);
00101 }
00102 state = cpl_errorstate_get();
00103 value = muse_pfits_get_agy_avg(aPixtables[i]->header);
00104 if (cpl_errorstate_is_equal(state)) {
00105 cpl_table_set_double(table, "AGY_AVG", i, value);
00106 }
00107 state = cpl_errorstate_get();
00108 value = muse_pfits_get_agy_rms(aPixtables[i]->header);
00109 if (cpl_errorstate_is_equal(state)) {
00110 cpl_table_set_double(table, "AGY_RMS", i, value);
00111 }
00112
00113
00114 state = cpl_errorstate_get();
00115 value = muse_pfits_get_ia_fwhm(aPixtables[i]->header);
00116 if (cpl_errorstate_is_equal(state)) {
00117 cpl_table_set_double(table, "IA_FWHM", i, value);
00118 }
00119
00120
00121 state = cpl_errorstate_get();
00122 value = muse_pfits_get_fwhm_start(aPixtables[i]->header);
00123 if (cpl_errorstate_is_equal(state) && value > 0.) {
00124 cpl_table_set_double(table, "DIMM_START", i, value);
00125 }
00126 state = cpl_errorstate_get();
00127 value = muse_pfits_get_fwhm_end(aPixtables[i]->header);
00128 if (cpl_errorstate_is_equal(state) && value > 0.) {
00129 cpl_table_set_double(table, "DIMM_END", i, value);
00130 }
00131 }
00132 cpl_errorstate_set(prestate);
00133
00134
00135 cpl_table_duplicate_column(table, "AG_AVG", table, "AGX_AVG");
00136 cpl_table_add_columns(table, "AG_AVG", "AGY_AVG");
00137 cpl_table_multiply_scalar(table, "AG_AVG", 0.5);
00138
00139 cpl_table_duplicate_column(table, "AG_RMS", table, "AGX_RMS");
00140 cpl_table_power_column(table, "AG_RMS", 2);
00141 cpl_table_duplicate_column(table, "AG2_RMS", table, "AGY_RMS");
00142 cpl_table_power_column(table, "AG2_RMS", 2);
00143 cpl_table_add_columns(table, "AG_RMS", "AG2_RMS");
00144 cpl_table_erase_column(table, "AG2_RMS");
00145 cpl_table_power_column(table, "AG_RMS", 0.5);
00146
00147 cpl_table_duplicate_column(table, "DIMM", table, "DIMM_START");
00148 cpl_table_add_columns(table, "DIMM", "DIMM_END");
00149 cpl_table_multiply_scalar(table, "DIMM", 0.5);
00150
00151 #if 0
00152 printf("%s:\n", __func__);
00153 const char *p, *cols[] = { "EXPTIME", "AG_AVG", "IA_FWHM", "DIMM", NULL };
00154 for (i = 0, p = cols[i] ; p; p = cols[i++ + 1]) {
00155 prestate = cpl_errorstate_get();
00156 printf("%s: %.3f +/- %.3f (%"CPL_SIZE_FORMAT" invalid)\n", p,
00157 cpl_table_get_column_mean(table, p), cpl_table_get_column_stdev(table, p),
00158 cpl_table_count_invalid(table, p));
00159
00160 cpl_errorstate_set(prestate);
00161 }
00162 cpl_table_dump(table, 0, npt, stdout);
00163 fflush(stdout);
00164 #endif
00165
00166 return table;
00167 }
00168
00169
00203
00204 cpl_error_code
00205 muse_xcombine_weights(muse_pixtable **aPixtables, muse_xcombine_types aWeighting)
00206 {
00207 cpl_ensure_code(aPixtables, CPL_ERROR_NULL_INPUT);
00208 unsigned int npt = 0;
00209 while (aPixtables[npt++]) ;
00210 cpl_ensure_code(--npt > 1, CPL_ERROR_ILLEGAL_INPUT);
00211 if (aWeighting == MUSE_XCOMBINE_NONE) {
00212 cpl_msg_info(__func__, "%d tables, not weighting them", npt);
00213 return CPL_ERROR_NONE;
00214 }
00215 if (aWeighting != MUSE_XCOMBINE_EXPTIME && aWeighting != MUSE_XCOMBINE_FWHM) {
00216 cpl_msg_warning(__func__, "Unknown exposure weighting scheme (%d)",
00217 aWeighting);
00218 return cpl_error_set(__func__, CPL_ERROR_UNSUPPORTED_MODE);
00219 }
00220
00221
00222
00223 cpl_table *tinfo = muse_xcombine_weights_infotable(aPixtables);
00224 int err;
00225 double exptime0 = cpl_table_get_double(tinfo, "EXPTIME", 0, &err);
00226 if (err || exptime0 == 0.0) {
00227 cpl_table_delete(tinfo);
00228 return cpl_error_set(__func__, CPL_ERROR_INCOMPATIBLE_INPUT);
00229 }
00230
00231 double fwhm0 = 0.;
00232 const char *fwhmcolumn = NULL,
00233 *fwhmerrcol = NULL;
00234 if (aWeighting == MUSE_XCOMBINE_FWHM) {
00235 cpl_size ninvalid = cpl_table_count_invalid(tinfo, "AG_AVG");
00236 if (ninvalid > 0) {
00237 ninvalid = cpl_table_count_invalid(tinfo, "IA_FWHM");
00238 if (ninvalid > 0) {
00239 ninvalid = cpl_table_count_invalid(tinfo, "DIMM");
00240 if (!ninvalid) {
00241 fwhmcolumn = "DIMM";
00242 cpl_msg_info(__func__, "%d tables to be weighted using EXPTIME & FWHM "
00243 "(using DIMM measurements)", npt);
00244 }
00245 } else {
00246 fwhmcolumn = "IA_FWHM";
00247 cpl_msg_info(__func__, "%d tables to be weighted using EXPTIME & FWHM "
00248 "(using active optics image analysis)", npt);
00249 }
00250 } else {
00251 fwhmcolumn = "AG_AVG";
00252 fwhmerrcol = "AG_RMS";
00253 cpl_msg_info(__func__, "%d tables to be weighted using EXPTIME & FWHM "
00254 "(using auto-guider info)", npt);
00255 }
00256 if (!fwhmcolumn) {
00257 cpl_msg_warning(__func__, "%d tables to be weighted using EXPTIME.", npt);
00258 cpl_msg_warning(__func__, "(FWHM-based weighting was requested but cannot"
00259 " be carried due to incomplete FITS headers in some "
00260 "exposures.)");
00261 cpl_error_set_message(__func__, CPL_ERROR_DATA_NOT_FOUND, "missing FITS "
00262 "headers for FWHM-based exposure weighting");
00263 } else {
00264 fwhm0 = cpl_table_get_double(tinfo, fwhmcolumn, 0, &err);
00265 }
00266 } else {
00267
00268 cpl_msg_info(__func__, "%d tables to be weighted using EXPTIME.", npt);
00269 }
00270
00271
00272 unsigned int i;
00273 for (i = 0; i < npt; i++) {
00274 double exptime = cpl_table_get_double(tinfo, "EXPTIME", i, &err),
00275 weight = exptime / exptime0;
00276 if (!cpl_table_has_column(aPixtables[i]->table, MUSE_PIXTABLE_WEIGHT)) {
00277 cpl_table_new_column(aPixtables[i]->table, MUSE_PIXTABLE_WEIGHT,
00278 CPL_TYPE_FLOAT);
00279 }
00280
00281 char *fwhmstr = NULL;
00282 if (fwhmcolumn) {
00283 double fwhm = cpl_table_get_double(tinfo, fwhmcolumn, i, &err),
00284 fwhmerr = fwhmerrcol
00285 ? cpl_table_get_double(tinfo, fwhmerrcol, i, NULL) : 0.;
00286 weight *= fwhm0 / fwhm;
00287 if (fwhmerrcol) {
00288 fwhmstr = cpl_sprintf(", FWHM = %.2f +/- %.2f", fwhm, fwhmerr);
00289 } else {
00290 fwhmstr = cpl_sprintf(", FWHM = %.2f", fwhm);
00291 }
00292 }
00293 cpl_msg_debug(__func__, "Table %d, weight = %f (EXPTIME = %f%s)", i+1, weight,
00294 exptime, fwhmstr ? fwhmstr : "");
00295 cpl_free(fwhmstr);
00296 cpl_table_fill_column_window_float(aPixtables[i]->table,
00297 MUSE_PIXTABLE_WEIGHT,
00298 0, muse_pixtable_get_nrow(aPixtables[i]),
00299 weight);
00300
00301 cpl_propertylist_update_bool(aPixtables[i]->header, MUSE_HDR_PT_WEIGHTED,
00302 CPL_TRUE);
00303 cpl_propertylist_set_comment(aPixtables[i]->header, MUSE_HDR_PT_WEIGHTED,
00304 MUSE_HDR_PT_WEIGHTED_COMMENT);
00305 }
00306 cpl_table_delete(tinfo);
00307
00308 return CPL_ERROR_NONE;
00309 }
00310
00311
00332
00333 double *
00334 muse_xcombine_find_offsets(const cpl_table *aOffsets, const char *aDateObs)
00335 {
00336 const char *id = "muse_xcombine_tables";
00337 cpl_ensure(aOffsets && aDateObs, CPL_ERROR_NULL_INPUT, NULL);
00338
00339
00340 cpl_ensure(strlen(aDateObs) >= 19 && strlen(aDateObs) <= 68,
00341 CPL_ERROR_ILLEGAL_INPUT, NULL);
00342
00343 int ioff, noff = cpl_table_get_nrow(aOffsets);
00344 for (ioff = 0; ioff < noff; ioff++) {
00345 const char *dateobs = cpl_table_get_string(aOffsets, MUSE_OFFSETS_DATEOBS,
00346 ioff);
00347
00348
00349 if (dateobs && !strncmp(dateobs, aDateObs, 23)) {
00350 double *offsets = cpl_calloc(3, sizeof(double));
00351 #if 0
00352 cpl_msg_debug(__func__, "found:");
00353 cpl_table_dump(aOffsets, ioff, 1, stdout);
00354 fflush(stdout);
00355 #endif
00356 int err;
00357 offsets[0] = cpl_table_get_double(aOffsets, MUSE_OFFSETS_DRA, ioff, &err);
00358 if (err) {
00359 cpl_msg_warning(id, "%s for %s could not be read from %s!",
00360 MUSE_OFFSETS_DRA, aDateObs, MUSE_TAG_OFFSET_LIST);
00361 offsets[0] = NAN;
00362 }
00363 offsets[1] = cpl_table_get_double(aOffsets, MUSE_OFFSETS_DDEC, ioff, &err);
00364 if (err) {
00365 cpl_msg_warning(id, "%s for %s could not be read from %s!",
00366 MUSE_OFFSETS_DDEC, aDateObs, MUSE_TAG_OFFSET_LIST);
00367 offsets[1] = NAN;
00368 }
00369 offsets[2] = cpl_table_has_column(aOffsets, MUSE_OFFSETS_FSCALE)
00370 ? cpl_table_get_double(aOffsets, MUSE_OFFSETS_FSCALE, ioff, &err)
00371 : NAN;
00372 if (err) {
00373 offsets[2] = NAN;
00374 }
00375 return offsets;
00376 }
00377 }
00378 return NULL;
00379 }
00380
00381
00433
00434 muse_pixtable *
00435 muse_xcombine_tables(muse_pixtable **aPixtables, const cpl_table *aOffsets)
00436 {
00437 cpl_ensure(aPixtables, CPL_ERROR_NULL_INPUT, NULL);
00438 unsigned int npt = 0;
00439 while (aPixtables[npt++]) ;
00440 cpl_ensure(--npt > 1, CPL_ERROR_ILLEGAL_INPUT, NULL);
00441 cpl_ensure(muse_pixtable_wcs_check(aPixtables[0]) == MUSE_PIXTABLE_WCS_NATSPH,
00442 CPL_ERROR_INCOMPATIBLE_INPUT, NULL);
00443 cpl_msg_info(__func__, "%u tables to be combined", npt);
00444
00445 double timeinit = cpl_test_get_walltime(),
00446 cpuinit = cpl_test_get_cputime();
00447 muse_utils_memory_dump("muse_xcombine_tables() start");
00448 muse_pixtable *pt = aPixtables[0];
00449 aPixtables[0] = NULL;
00450
00451 if (!muse_pixtable_is_rvcorr(pt)) {
00452 cpl_msg_warning(__func__, "Data of exposure 1 (DATE-OBS=%s) was not radial-"
00453 "velocity corrected!", muse_pfits_get_dateobs(pt->header));
00454 }
00455
00456 muse_pixtable_origin_copy_offsets(pt, NULL, 1);
00457
00458 char keyword[KEYWORD_LENGTH], comment[KEYWORD_LENGTH];
00459 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_FST, 1);
00460 cpl_propertylist_append_long_long(pt->header, keyword, 0);
00461 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_FST_COMMENT, 1);
00462 cpl_propertylist_set_comment(pt->header, keyword, comment);
00463 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_LST, 1);
00464 cpl_propertylist_append_long_long(pt->header, keyword,
00465 muse_pixtable_get_nrow(pt) - 1);
00466 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_LST_COMMENT, 1);
00467 cpl_propertylist_set_comment(pt->header, keyword, comment);
00468
00469 double ra0 = muse_pfits_get_ra(pt->header),
00470 dec0 = muse_pfits_get_dec(pt->header),
00471 *offsets = aOffsets
00472 ? muse_xcombine_find_offsets(aOffsets,
00473 muse_pfits_get_dateobs(pt->header))
00474 : NULL;
00475 if (offsets) {
00476 if (isfinite(offsets[0]) && isfinite(offsets[1])) {
00477 ra0 -= offsets[0];
00478 dec0 -= offsets[1];
00479 cpl_msg_debug(__func__, "Applying coordinate offsets to exposure 1: %e/%e"
00480 " deg", offsets[0], offsets[1]);
00481
00482 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA, 1);
00483 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA_C, offsets[0] * 3600.);
00484 cpl_propertylist_append_double(pt->header, keyword, offsets[0]);
00485 cpl_propertylist_set_comment(pt->header, keyword, comment);
00486 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC, 1);
00487 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC_C, offsets[1] * 3600.);
00488 cpl_propertylist_append_double(pt->header, keyword, offsets[1]);
00489 cpl_propertylist_set_comment(pt->header, keyword, comment);
00490 }
00491 if (isnormal(offsets[2])) {
00492
00493 cpl_msg_debug(__func__, "Scaling flux of exposure 1 by %g.", offsets[2]);
00494 muse_pixtable_flux_multiply(pt, offsets[2]);
00495
00496 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_FLUX_SCALEi, 1);
00497 cpl_propertylist_append_double(pt->header, keyword, offsets[2]);
00498 cpl_propertylist_set_comment(pt->header, keyword, MUSE_HDR_FLUX_SCALEi_C);
00499 }
00500
00501 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS, 1);
00502 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS_C, 1);
00503 cpl_propertylist_append_string(pt->header, keyword,
00504 muse_pfits_get_dateobs(pt->header));
00505 cpl_propertylist_set_comment(pt->header, keyword, comment);
00506 }
00507 cpl_free(offsets);
00508 muse_wcs_position_celestial(pt, ra0, dec0);
00509
00510 unsigned int i, nskipped = 0;
00511 for (i = 1; i < npt; i++) {
00512 if (muse_pixtable_wcs_check(aPixtables[i]) != MUSE_PIXTABLE_WCS_NATSPH) {
00513 cpl_msg_warning(__func__, "Exposure %d was not projected to native "
00514 "spherical coordinates, skipping this one!", i + 1);
00515 nskipped++;
00516 continue;
00517 }
00518 if (!muse_pixtable_is_rvcorr(pt)) {
00519 cpl_msg_warning(__func__, "Data of exposure %u (DATE-OBS=%s) was not "
00520 "radial-velocity corrected!", i+1,
00521 muse_pfits_get_dateobs(aPixtables[i]->header));
00522 }
00523
00524
00525 double ra = muse_pfits_get_ra(aPixtables[i]->header),
00526 dec = muse_pfits_get_dec(aPixtables[i]->header);
00527 offsets = aOffsets
00528 ? muse_xcombine_find_offsets(aOffsets,
00529 muse_pfits_get_dateobs(aPixtables[i]->header))
00530 : NULL;
00531 cpl_boolean offcor = CPL_FALSE;
00532 if (offsets) {
00533 if (isfinite(offsets[0]) && isfinite(offsets[1])) {
00534 ra -= offsets[0];
00535 dec -= offsets[1];
00536 cpl_msg_debug(__func__, "Applying coordinate offsets to exposure %d: "
00537 "%e/%e deg", i + 1, offsets[0], offsets[1]);
00538 offcor = CPL_TRUE;
00539
00540 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA, i + 1);
00541 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DRA_C, offsets[0] * 3600.);
00542 cpl_propertylist_append_double(pt->header, keyword, offsets[0]);
00543 cpl_propertylist_set_comment(pt->header, keyword, comment);
00544 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC, i + 1);
00545 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DDEC_C, offsets[1] * 3600.);
00546 cpl_propertylist_append_double(pt->header, keyword, offsets[1]);
00547 cpl_propertylist_set_comment(pt->header, keyword, comment);
00548 }
00549 if (isnormal(offsets[2])) {
00550 cpl_msg_debug(__func__, "Scaling flux of exposure %u by %g.", i + 1,
00551 offsets[2]);
00552 muse_pixtable_flux_multiply(aPixtables[i], offsets[2]);
00553
00554 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_FLUX_SCALEi, i + 1);
00555 cpl_propertylist_append_double(pt->header, keyword, offsets[2]);
00556 cpl_propertylist_set_comment(pt->header, keyword, MUSE_HDR_FLUX_SCALEi_C);
00557 }
00558
00559 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS, i + 1);
00560 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_OFFSETi_DATEOBS_C, i + 1);
00561 cpl_propertylist_append_string(pt->header, keyword,
00562 muse_pfits_get_dateobs(aPixtables[i]->header));
00563 cpl_propertylist_set_comment(pt->header, keyword, comment);
00564 }
00565 cpl_free(offsets);
00566 muse_wcs_position_celestial(aPixtables[i], ra, dec);
00567
00568
00569 double raoffset = ra - ra0,
00570 decoffset = dec - dec0;
00571 #if 0
00572
00573
00574 float *xpos = cpl_table_get_data_float(aPixtables[i]->table, MUSE_PIXTABLE_XPOS),
00575 *ypos = cpl_table_get_data_float(aPixtables[i]->table, MUSE_PIXTABLE_YPOS);
00576 cpl_size irow, nrowi = muse_pixtable_get_nrow(aPixtables[i]);
00577 #pragma omp parallel for default(none) \
00578 shared(decoffset, nrowi, raoffset, xpos, ypos)
00579 for (irow = 0; irow < nrowi; irow++) {
00580 xpos[irow] += raoffset;
00581 ypos[irow] += decoffset;
00582 }
00583 #else
00584
00585 cpl_table_add_scalar(aPixtables[i]->table, MUSE_PIXTABLE_XPOS, raoffset);
00586 cpl_table_add_scalar(aPixtables[i]->table, MUSE_PIXTABLE_YPOS, decoffset);
00587 #endif
00588
00589
00590 double avdec = (dec + dec0) / 2.,
00591 raoff = (ra - ra0) * cos(avdec * CPL_MATH_RAD_DEG) * 3600.,
00592 decoff = dec - dec0 * 3600.;
00593 cpl_msg_info(__func__, "Distance of exposure %u (relative to exp. 1): "
00594 "%.1f,%.1f arcsec%s", i+1, raoff, decoff,
00595 offcor ? " (corrected offset)" : "");
00596
00597
00598 cpl_size nrow = muse_pixtable_get_nrow(pt);
00599 cpl_table_insert(pt->table, aPixtables[i]->table, nrow);
00600
00601 muse_pixtable_origin_copy_offsets(pt, aPixtables[i], i + 1);
00602 muse_pixtable_delete(aPixtables[i]);
00603 aPixtables[i] = NULL;
00604
00605
00606 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_FST, i + 1);
00607 cpl_propertylist_append_long_long(pt->header, keyword, nrow);
00608 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_FST_COMMENT, i + 1);
00609 cpl_propertylist_set_comment(pt->header, keyword, comment);
00610 snprintf(keyword, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_LST, i + 1);
00611 cpl_propertylist_append_long_long(pt->header, keyword,
00612 muse_pixtable_get_nrow(pt) - 1);
00613 snprintf(comment, KEYWORD_LENGTH, MUSE_HDR_PT_EXP_LST_COMMENT, i + 1);
00614 cpl_propertylist_set_comment(pt->header, keyword, comment);
00615 }
00616 muse_pixtable_compute_limits(pt);
00617
00618 cpl_propertylist_update_int(pt->header, MUSE_HDR_PT_COMBINED, npt - nskipped);
00619 cpl_propertylist_set_comment(pt->header, MUSE_HDR_PT_COMBINED,
00620 MUSE_HDR_PT_COMBINED_COMMENT);
00621
00622 double timefini = cpl_test_get_walltime(),
00623 cpufini = cpl_test_get_cputime();
00624 muse_utils_memory_dump("muse_xcombine_tables() end");
00625 cpl_msg_debug(__func__, "Combining %u tables took %gs (wall-clock) and %gs "
00626 "(CPU)", npt, timefini - timeinit, cpufini - cpuinit);
00627 return pt;
00628 }
00629