diff --git a/RTCP/Cobalt/InputProc/src/Delays/Delays.cc b/RTCP/Cobalt/InputProc/src/Delays/Delays.cc index e2b600d35ab32f51ce623241f43b96dcfcad44db..240c3e9aabe85da7790007467cc0e21740263e8d 100644 --- a/RTCP/Cobalt/InputProc/src/Delays/Delays.cc +++ b/RTCP/Cobalt/InputProc/src/Delays/Delays.cc @@ -27,11 +27,24 @@ #include <Common/Thread/Mutex.h> #include <Common/Thread/Cancellation.h> #include <CoInterface/Exceptions.h> +#include <CoInterface/TimeFuncs.h> #ifdef HAVE_CASACORE #include <casacore/measures/Measures/MEpoch.h> #include <casacore/measures/Measures/MCDirection.h> #include <casacore/casa/Exceptions/Error.h> +#include <casacore/measures/Measures/MeasIERS.h> +#include <casacore/tables/Tables/Table.h> +#include <casacore/tables/Tables/TableRecord.h> +#include <casacore/tables/Tables/ScalarColumn.h> +#include <casacore/casa/Containers/RecordField.h> +#include <casacore/casa/OS/Time.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <cstdlib> +#include <limits.h> #endif @@ -39,6 +52,10 @@ namespace LOFAR { namespace Cobalt { + static std::string time2str(const time_t time) + { + return TimeDouble::toString(time, false); + } //##---------------- Public methods ----------------##// @@ -53,6 +70,11 @@ namespace LOFAR ASSERTSTR(test(), "Delay compensation engine is broken"); init(); + + // Log TAI_UTC table information to inform the user about the age of the delay information we're about to use + struct IERS_tablestats stats = get_IERS_tablestats(); + + LOG_INFO_STR("Using IERS table " << stats.realpath << ", last entry is " << time2str(stats.last_entry_timestamp) << ", table written on " << time2str(stats.last_fs_modification)); } @@ -91,9 +113,56 @@ namespace LOFAR return MVEpoch(day + 40587., frac); } + struct Delays::IERS_tablestats Delays::get_IERS_tablestats() + { + struct IERS_tablestats result; + + Table table; + TableRecord kws; + ROTableRow row; + RORecordFieldPtr<Double> rfp[1]; + String vs; + Double dt; + Int N = 0; + String rfn[1]; + + // locate TAI_UTC table + if (!MeasIERS::getTable(table, kws, row, rfp, vs, dt, N, rfn, "IERSeop97", "measures.ierseop97.directory", "")) + THROW(Exception, "Cannot open IERSeop97 table"); + + result.path = table.tableName(); + + // resolve any symlinks, which typically includes f.e. "current" + char resolved_path[PATH_MAX]; + if (!realpath(table.tableName().c_str(), resolved_path)) + THROW_SYSCALL("realpath()"); + + result.realpath = resolved_path; + + // obtain table last modification on file system + struct stat filestats; + + if (stat(resolved_path, &filestats) != 0) + THROW_SYSCALL("stat(): Cannot access IERSeop97 table"); + + result.last_fs_modification = filestats.st_mtime; + + // read which timestamps the table contains + casacore::Vector<Double> mjds; + ScalarColumn<Double>(table, "MJD").getColumn(mjds); + casacore::Double last_mjd = mjds[mjds.size()-1]; + + Time last_time(last_mjd + 2400000); + + // MJD -> seconds since 1970 + result.last_entry_timestamp = (last_mjd - 40587) * 86400; + + return result; + } bool Delays::test() { + // Test whether delays can be calculated try { ScopedLock lock(casacoreMutex); ScopedDelayCancellation dc; @@ -122,6 +191,8 @@ namespace LOFAR return false; } + // Print information about age of TAI_UTC table + return true; } @@ -234,6 +305,19 @@ namespace LOFAR void Delays::init() { } + struct Delays::IERS_tablestats Delays::get_IERS_tablestats() { + struct IERS_tablestats result; + result.path = "/dev/null"; + result.realpath = "/dev/null"; + result.last_fs_modification = 0; + result.last_entry_timestamp = 0; + return result; + } + + std::time_t Delays::TAI_UTC_tableage() { + return 0; + } + void Delays::calcDelays( const TimeStamp ×tamp, AllDelays &result ) { (void)timestamp;