Saved Data Structure

Trial Data Format

If you are not using the pybpodapi library, you must implement a method that returns trial data as a dictionary with the exact structure described below. This dictionary must be returned at the end of each trial.

Required Dictionary Structure

{
    "Trial start timestamp": float,
    "States timestamps": dict,
    "Events timestamps": dict,
}

Field Descriptions

"Trial start timestamp"float

The time at which the trial started, expressed as a UNIX epoch timestamp in seconds (i.e., seconds since 1970-01-01 00:00:00 UTC).

You can obtain this value using:

from datetime import datetime
trial_start_timestamp = datetime.now().timestamp()

"States timestamps"dict[str, list[tuple[float, float]]]

A dictionary where:

  • Each key is the name of a state (str).

  • Each value is a list of tuples (start_timestamp, end_timestamp), representing every time that state was visited during the trial.

  • Timestamps must be absolute UNIX epoch timestamps in seconds.

  • If a state was defined but never visited, its value must be [(float('nan'), float('nan'))].

Example:

{
    "WaitForPoke": [(1711446000.000, 1711446001.234)],
    "Reward":      [(1711446001.234, 1711446002.567)],
    "ITI":         [(1711446002.567, 1711446003.000)],
    "Punish":      [(float('nan'), float('nan'))],  # not visited
}

"Events timestamps"dict[str, list[float]]

A dictionary where:

  • Each key is the name of an event (str).

  • Each value is a list of float timestamps (absolute UNIX epoch in seconds), one for each occurrence of that event during the trial.

  • Only events that actually occurred should be included.

Example:

{
    "Tup":      [1711446001.234, 1711446002.567],
    "Port1In":  [1711446000.500],
    "Port1Out": [1711446000.800, 1711446001.100],
}

Complete Example

from datetime import datetime

def get_trial_data() -> dict:
    return {
        "Trial start timestamp": 1711446000.000,
        "States timestamps": {
            "WaitForPoke": [(1711446000.000, 1711446001.234)],
            "Reward":      [(1711446001.234, 1711446002.567)],
            "ITI":         [(1711446002.567, 1711446003.000)],
            "Punish":      [(float('nan'), float('nan'))],
        },
        "Events timestamps": {
            "Tup":      [1711446001.234, 1711446002.567],
            "Port1In":  [1711446000.500],
            "Port1Out": [1711446000.800, 1711446001.100],
        },
    }

[!IMPORTANT]

  • All timestamps must be in seconds (not milliseconds).

  • All timestamps must be absolute (UNIX epoch), not relative to the trial start.

  • State and event names are free-form strings, but should be consistent across trials.