Repository navigation
feat(write): write T4Dataset 1.0 datasets - #316
Merged
Merged
Conversation
jacoblambert
force-pushed
the
v1/sanity
branch
from
October 15, 2026 03:36
5b8948c to
2c6ec49
Compare
jacoblambert
force-pushed
the
v1/write
branch
from
October 15, 2026 03:36
91717b6 to
523aab6
Compare
jacoblambert
force-pushed
the
v1/write
branch
from
October 15, 2026 05:23
523aab6 to
b4370fc
Compare
jacoblambert
force-pushed
the
v1/sanity
branch
from
October 15, 2026 05:23
2c6ec49 to
04dfa9c
Compare
jacoblambert
force-pushed
the
v1/write
branch
from
October 15, 2026 05:40
b4370fc to
4c1df11
Compare
jacoblambert
force-pushed
the
v1/sanity
branch
2 times, most recently
from
October 15, 2026 08:26
14bf681 to
f5070ca
Compare
jacoblambert
force-pushed
the
v1/write
branch
from
October 15, 2026 08:26
4c1df11 to
97a4014
Compare
jacoblambert
force-pushed
the
v1/sanity
branch
from
October 15, 2026 10:37
f5070ca to
f5ed9a6
Compare
jacoblambert
force-pushed
the
v1/write
branch
2 times, most recently
from
October 21, 2026 01:31
6771c60 to
c044b97
Compare
jacoblambert
force-pushed
the
v1/sanity
branch
from
October 21, 2026 01:31
f5ed9a6 to
6a7bfab
Compare
ktro2828
self-requested a review
October 21, 2026 05:31
ktro2828
approved these changes
Oct 22, 2026
jacoblambert
force-pushed
the
v1/sanity
branch
from
October 22, 2026 09:56
6a7bfab to
f951085
Compare
jacoblambert
force-pushed
the
v1/write
branch
from
October 22, 2026 09:56
c044b97 to
bf1cea8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a writer for 1.0 datasets. Migration (next PR) and later converters use it.
The writer writes files. The caller decides what goes in them.
Data files
t4_devkit/common/io.py, next to the readers:save_pointcloudwrites the frames of a LiDAR channel to one Parquet file. Each frame is one row group, so a frame can be read alone. Empty frames get a row group too, so frame indices stay aligned. A field that is missing orNonein a frame is written asnullon every point, for point labels of frames without labels. The reader leaves such a column out, so what it returns can be written back as it is.save_videowrites the frames of a camera channel to one AV1 video. It uses the SVT-AV1 encoder that comes with PyAV, so no FFmpeg install is needed. Every frame is a keyframe, so any frame can be read alone. The timescale is the frame rate, so a frame's pts is its index. uint16 frames give a 10-bit video.DatasetWritert4_devkit/schema/v1/writer.py:write_lidarandwrite_camerawrite a channel todata/<CHANNEL>/<CHANNEL>.parquetor.mp4.copycopies files as they are, for example the map orinput_bag/.savewrites the tables, thenmanifest.json. The manifest lists every table and every file underdata/,map/andinput_bag/with its hash and size.savealso fills in two manifest fields:generators: t4-devkit is added.capabilities: computed from the tables, unless the caller gives them.Capabilities
Capabilities.from_tablesworks out what a dataset contains from its tables. The writer uses it to fillcapabilities. Sanity rulesREC023andREC024use it to compare the manifest with the tables. Before, sanity had its own copy of this logic.predictionandplanningare now checked too:prediction: every sample has a key frame, so all frames are annotated.planning:scenario.jsonhas records.The 1.0 sample has scenarios, so its manifest now lists
planning.Dataset ID and version
The writer does not choose or increase the version.
The caller gives the folder, usually
<DATASET_ID>/<VERSION>. The caller also givesdataset_idandversionformanifest.json. The writer refuses a folder that already exists, so it never overwrites a version.This is on purpose. The version number comes from Web.Auto when a new version is uploaded. Migration will run in Web.Auto, so Web.Auto sets the version. A local tool cannot know the next number.
The folder and the manifest are not tied together by the writer. If they differ, sanity rule
STR015warns.Parquet settings
save_pointcloudpicks the encoding of each column by its type:We benchmarked this on 13 real 0.x datasets (6,296 frames, 40.8 GB of
.bin). These were the smallest settings that every reader we tried can read: pyarrow 14+, Polars and DuckDB.On 4 of them (4, 5, 7 and 9 columns), the result is 43.4 % of the
.binsize, with every value unchanged. Before, it was about 46 %. The 7-column dataset with per-point timestamps gains the most: 44.5 % to 38.6 %.Two settings were left out on purpose:
Sample dataset
make_sample_v1.pynow writes the 1.0 sample withDatasetWriter, like a real dataset. It no longer needs an FFmpeg build with SVT-AV1, or npx.generatorsnow has the real t4-devkit version instead of"sample".prettier now skips
tests/sample/t4dataset_v1/. It reformatted the JSON after the hashes inmanifest.jsonwere taken.Other changes
record/base.py, constants used only once moved into their function.save_videosetsSVT_LOG=1unless it is already set. Without it, SVT-AV1 prints about 20 lines for every video.Tests
labelcolumn that isNonein one frame: written asnull, left out when read, and written back the same.--checksum.predictionandplanningappear and disappear with their tables.