Skip to content

Convert timetables, like tables - #253

Open
Thenewmanator15 wants to merge 1 commit into
JuliaIO:masterfrom
Thenewmanator15:timetable-conversion
Open

Thenewmanator15 wants to merge 1 commit into
JuliaIO:masterfrom
Thenewmanator15:timetable-conversion

Conversation

@Thenewmanator15

@Thenewmanator15 Thenewmanator15 commented Sep 25, 2026 •

Copy link
Copy Markdown

A MATLAB timetable is read as a MatlabOpaque: its parts (variable names, data, row times, units) are all decoded, but never assembled. This converts it the way table already is — to MatlabTable by default, or to the table type (DataFrame, ...) — with the row times as the first column, named after the row dimension (Time unless renamed).

vars = matread("timetable.mat"; table = DataFrame)
vars["tt_datetime"]
# 3×3 DataFrame
#  Row │ Time                     Current   Channel
#      │ DateTime                 Float64   String

Row times, in the forms MATLAB saves them:

  • one per row, as datetime or duration — already converted to DateTime / Millisecond by the time the timetable is;
  • regular timetables (SampleRate or TimeStep), which MATLAB stores as a start time plus a rate or step — the row times are generated;
  • a step in calendar units (calmonths, ...) has no fixed rate: the timetable is left as the MatlabOpaque, with a warning.

table = Nothing keeps the raw object, as for tables.

Tests, and a request. test/timetable_gen.m writes test/v7/timetable.mat and test/v7.3/timetable.mat with one variable per case — datetime and duration row times (sub-millisecond ones included), sample rate, time step from a datetime start, an empty timetable, a two-column variable, a renamed row dimension, and calendar months. I can't contribute the .mat files themselves, so they are not in this PR: could someone with MATLAB run the script in test/ and commit its two files? Until then the new testset skips (@test_skip), so CI stays green. Run locally against the files the script writes (MATLAB R2025a), all 48 new assertions pass and the full suite passes (629) on Julia 1.13; read.jl also passes on 1.9. Without the files: 581 pass, 2 skipped.

I also checked it on a real acquisition file (v7.3, a user-defined class holding four timetables, one of them empty): every value matches two other readers of the same file, and the row times agree to within DateTime's millisecond resolution.

A note on ms_to_datetime, which asks whether the imaginary part of a stored datetime is the sub-millisecond part: it is the low half of a double-double, below the resolution of the real part (on that file, |imag| ≤ half an ulp of the real part in every row), so real + imag in Float64 equals real and dropping it loses nothing at DateTime resolution. The sub-millisecond detail is the real part's own fraction, which DateTime rounds away.

Independent of #251 (no overlapping lines); docs: a timetable row in docs/src/types.md and the matopen / matread docstrings.

🤖 Generated with Claude Code

A timetable was returned as a MatlabOpaque, its parts decoded but not assembled.
It now becomes a table (MatlabTable by default, or the `table` type) whose first
column holds the row times, named after the row dimension ("Time" unless renamed),
followed by the variables.

Row times are stored one per row (datetime or duration, already converted to
DateTime or Millisecond), or, for a regular timetable, as a start time and a sample
rate or time step; those are generated. A timetable stepped in calendar units has
no fixed rate and is left as the MatlabOpaque, with a warning. `table=Nothing`
keeps the raw object, as for tables.

test/timetable_gen.m writes test/v7 and test/v7.3/timetable.mat: datetime and
duration row times, sample rate, time step from a datetime start, an empty
timetable, a two-column variable, a renamed row dimension, calendar months. The
.mat files are not included; the timetable tests are skipped until they are
generated in MATLAB and committed.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant