.mp4..csv with a time column (named
Time, time, any casing) in seconds, plus one or more
measurement columns. The builder auto-splits a
multi-column CSV into one data type per column; if you hand-edit the study, use
one measurement column per file.{ "segments": [ {start, end, speaker, text} ] }..eaf file.Time axis is mapped directly onto the video clock, so a
session's video length and time-series length should match. If they differ, the video and
signals won't line up (dead space, or the signal cut off).git clone https://github.com/dims-network/dims pip install -e "./dims[builder]" dims-builderThe last command opens the wizard in your browser and walks you through it. Once the package is published this becomes
pip install "dims-network[builder]".A point-and-click app: drop your files in, click through a wizard, get a ready-to-deploy dashboard. No JSON editing, no file renaming, no terminal scripts.
mediapipe wheel for it.
Once the builder is installed, no internet is required to build a dashboard.Clone it, or download the ZIP from that page and unzip it. The builder is the
apps/builder/ folder, and the dashboard code it builds against is in the
same repository — so there is nothing else to fetch.
Double-click the launcher in apps/builder/. It installs everything the
first time and then opens the wizard in your browser:
run.commandrun.batrun.shrun.command.
This only happens once. (It's macOS flagging any downloaded, unsigned script — not a
problem with the builder.)Prefer the terminal? That also avoids the macOS prompt above — open a terminal in
apps/builder/ and run exactly what the launcher runs:
pip install -r requirements.txt python -m dims_builder
requirements.txt installs what the builder needs, not the
builder itself, so run it as a module from that folder. If you installed the package
(pip install -e "./dims[builder]") the command is just
dims-builder, from anywhere.
Choose an empty output folder and a title/authors, and say who may see the data — private is the default, and it turns on the commit hook, push hook and CI check that keep recordings out of git. There is nothing to choose about the dashboard code: one scaffold ships in the repository and it is the one used, so a study the builder makes is identical to one made by hand.
Drag in your .mp4 video, your time-series .csv files, your
_transcript.json, and optionally an ELAN .eaf. The builder
recognises each file, groups them under a session, and checks them as you go —
so problems surface before you build.
Got one CSV with several signals? Drop it in as-is — a CSV with a
Time column plus several measurement columns is split automatically
into one data type per column, so you don't have to prepare separate files by hand.
This is where the mismatch warned about at the top of this page gets fixed. Per session, a shared-timeline preview shows the video track above each measurement track, and you either trim the video to a window you pick with a dual-handle slider, or pad the measurements with zeros at either end. Edits are non-destructive: your originals are never modified, and the trim or pad is applied only to the copies written at build time.
Toggle RQA, cross-wavelet, cross-RQA, the cross-effector network, and ELAN annotations — the wizard explains what each tab shows.
bodysync × neuralsync and neuralsync × gaze
but skip bodysync × gaze. A signal can appear in several pairs.Each analysis has a Settings panel for what the study can tune — the recurrence window and target rate, the cross-wavelet picture size and its surrogate count. A line at the foot of the step totals up how many runs that comes to and flags the slow ones, because the first sign that a choice was expensive should not be being forty minutes into the next step.
Build writes config.json and copies your files into the exact
assets/ layout. Precompute then runs the RQA / cross-wavelet / cross-RQA
steps for you in a project-local Python environment — progress streams live.
Preview opens the finished dashboard locally. The output folder is self-contained and ready to host — the builder shows copy-paste commands for GitHub Pages, Netlify, or Vercel.
Full control: copy the empty dashboard scaffold, drop files into assets/
with the right names, edit config.json, and (optionally) run the analyses.
mediapipe ships no wheel yet.All DIMS code lives in one repository. Install it, then let it write
you a study: dims-case new copies the scaffold and the
pinned dashboard code into vendor/, which is what makes the
page load at all.
git clone https://github.com/dims-network/dims
pip install -e ./dims
dims-case new my-dashboard --visibility public # -> ./case-my-dashboard
cd case-my-dashboard
vendor/, so eight script tags 404 and you get a
blank page with no error worth reading. dims-case new is the
command that produces something that runs.File names are a strict convention — the dashboard finds your data by name. For a
session id (e.g. session1) and a data type (e.g. bodysync):
{videoID}_{dataType}.csv, {videoID}.mp4,
{videoID}_transcript.json. A missing Time column or a
mismatched name is the most common reason a tab stays blank.config.jsonDeclare your sessions, their data types, which analyses to enable, and the page text:
{
"videoIDs": ["session1"],
"dataTypes": { "session1": ["bodysync", "neuralsync"] },
"include_RQA": ["bodysync", "neuralsync"],
"include_crosswavelet": [["bodysync", "neuralsync"]],
"include_cRQA": [["bodysync", "neuralsync"]],
"include_network": { "band": [0.0, 12.0] },
"include_elan": false,
"defaultWindowSize": 5,
"title": "My DIMS Dashboard",
"subtitle": "Dynamic Interaction and Multimodal Signals",
"authors": "Your name(s)",
"contacts": "you@example.org"
}
include_RQA is a list of data types. Cross-wavelet and
cross-RQA compare pairs: list each pair as ["typeA", "typeB"],
so you control exactly which pairs run. Every name you reference must have a matching CSV.
(include_crosswavelet also still accepts a flat list of data types, expanded
to all pairs, for backward compatibility.)
include_network switches on the cross-effector network, drawn from the
cross-wavelet results — setting it also switches on the chance-level simulation, at 100
surrogates, because without one no edge can be told from chance. If your measures divide
into groups (two people, two instruments), say so here, or they all land in one column:
"groups": [{"label": "Teacher", "match": "^teacher"}, …], each
match a regular expression on the data type name.
RQA, cross-wavelet, and cross-RQA read your CSVs and write JSON the dashboard loads. Run them once whenever those toggles are on:
# already installed above; the analyses come with it python build_assets.py --check # what would run, and what is missing python build_assets.py
--check computes nothing. It reports which recordings it can
see, which analyses are switched on, and which time series it could not
find — the quickest way to discover that a file is misnamed.
This produces assets/rqa/{videoID}_rqa_data.json,
assets/crosswavelet/{videoID}_crosswavelet_data.json, and
assets/crqa/{videoID}_crqa_data.json. Each analysis runs
only if its key is set in config.json, so the one command
does the right thing whatever you enabled.
Use the bundled server (it supports HTTP Range requests, which the video needs for seeking):
python serve.py 8000 # then open http://localhost:8000
It prints which study it is serving and from which directory — worth a glance if you keep several dashboards side by side.
A public study created with dims-case already carries the Pages workflow
that deploys it: push to main and it goes live. (Setting Pages up by hand
is branch main, folder / (root).) Any static host works —
just make sure it serves Range requests, or video seeking will not.