LUIDA Docs
ComponentsWeb console

Downloading data

Three tabs — questionnaire answers, participant info, custom logs — exportable as CSV, JSON, or ZIP.

These pages are not yet fully reviewed. The LUIDA team is continuing to review and improve them. If you find anything wrong on these pages, or have questions that aren't resolved by reading them, please ask or report to the LUIDA team.

The data your experiment captures — questionnaire answers, participant environment info, SendDataToCollector payloads — lands on the experiment detail page's Data section. This page is where the four data streams come together, and where you pull them out as CSV, JSON, or ZIP for analysis.

You won't see any data here until at least one session has run against the experiment (with isTestMode=true test sessions counting as well).

Screenshot pending — the Data section of an experiment detail page, with the three tabs visible (Questionnaire Answers, Participant Info, Custom Logs), showing the Custom Logs tab with five rows of sample data and the format dropdown set to CSV.

The three tabs

The Data section is organized into three sub-tabs, one per data stream. The fourth stream (between-subjects assignments) is folded into the Participant Info tab rather than getting its own.

1. Questionnaire Answers

One row per (session, participant, question) tuple. Columns:

ColumnSourceNotes
experimentIdAutoThe eID — same for every row.
questionnaireIdAutoThe qID (1-based).
participantsIdfcAutoThe participant's Cluster IDFC. Same participant across sessions has the same value.
participantsRoleAutoThe participant's role for paired sessions (participant_1, participant_2).
questionTitleFrom the questionnaireThe question text.
answerParticipant submissionAn array — single value for Radio/Toggle/Text/Linear Scale, multiple values for Checkboxes.
answerAtAutoUTC timestamp of submission.

There is no sessionId column on questionnaire answer records. To join answers back to a session for between-subjects analysis, you'll have to match on (participantsIdfc, answerAt) against the Participant Info records. This is acknowledged as a limitation; see the Web Console roadmap.

A filter row at the top lets you narrow by qID, by participant role, and by time range before exporting.

2. Participant Info

One row per (session, participant) pair. Records environment info and the between-subjects assignment for that session. Columns include:

ColumnSourceNotes
sessionIdAutoThe sID. Multiple participants in one session share this.
participantsIdfcAutoThe participant's Cluster IDFC.
participantsRoleAutoparticipant_1, participant_2, etc.
platformFrom the join requestVR, WINDOWS, MACOS, ANDROID, IOS.
deviceFrom the join requestHeadset / device model (where Cluster provides it).
osFrom the join requestOperating system version.
betweenSubjectsConditionsConditionManagerA JSON object keyed by variable name, containing the between-subjects values assigned at session start.
joinedAtAutoUTC timestamp of join.
leftAtAuto, nullableUTC timestamp of disconnect, if applicable.

This is the canonical record of "who ran what condition," which is what you'd join your custom-data table against for between-subjects analyses.

3. Custom Logs

One row per ProcessAndSaveCollectedData() invocation in your scene. The columns are whatever your per-scene data calculator script (Assets/_Experiment_/Scripts/DataCollectors/<SceneName>.js) returns from its calculateData() function.

For a Stroop tutorial setup, a typical row might look like:

ColumnValue (example)
sID64e2f9...
pID1
trialID7
depthnear
fontColorred
textMeaningBLUE
responseTargetcolor
correctfalse
rt_ms812

The shape of each row is entirely up to you — it's whatever object your calculateData() returns. See Reference → Variables → COLLECTED_DATA for the patterns and gotchas of writing that function.

The filter row at the top lets you narrow by session ID, participant role, and time range.

Export formats

Each tab has a Format dropdown and a Download button. Three formats are supported:

FormatWhen to use
CSVStatistical software (R, JASP, SPSS, Python pandas, MATLAB). Default.
JSONCustom analytics pipelines, scripts that need the original nested structures (e.g., the answer array on questionnaire records).
ZIPBundle of both CSV and JSON in one download — useful for archival.

The download contains only the current filter's matching rows. To pull everything, clear the filters before clicking Download.

Custom-log columns can include nested objects or arrays if your calculateData() returns them. CSV will flatten via JSON.stringify (creating a single string column); JSON preserves the structure. For nested data, JSON is usually the right choice.

What about between-subjects assignments?

Between-subjects assignments are part of the Participant Info tab — every row's betweenSubjectsConditions column carries the JSON object of variable values that were assigned for that session. There's no separate "assignments" download.

If you only want the assignments without the rest of the Participant Info, download the Participant Info tab as JSON and project to {sessionId, betweenSubjectsConditions} in your analysis script.

Storage and retention

The Web Console stores all four streams in MongoDB:

  • Questionnaire answers, custom logs, participant info: indexed by eID and timestamped.
  • Retention is currently indefinite — LUIDA doesn't auto-delete old data. (The LUIDA team will give 30 days' notice if retention policy changes.)
  • Deleted experiments take their data with them — confirm the data is exported before you delete an experiment row.

Common pitfalls

  • No sessionId on questionnaire answers. The most common analysis surprise. Join via participantsIdfc and timestamp; see the Concepts page note.
  • CSV flattening nested objects unexpectedly. Use JSON if your custom-log rows have arrays or nested objects.
  • Filtering by pID and finding nothing. Use participantsRole (participant_1, etc.), not pID directly — the column name is the Cluster convention, not LUIDA's 1-based index.
  • Exporting an empty data set without realizing it. Check the row count at the top of each tab before downloading. If it's 0, no sessions have produced data of that type yet.
  • Test-mode data mixed with production. Test sessions (isTestMode=true) are recorded with the same schema as production sessions. Use the session ID exclusion lists or filter on joinedAt to separate them.

Where to go next