Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- **Lever push durations.** `visiomode-analysis session` picks up a sibling
`sub-<id>_exp-<experiment>_ses-<date>_lever-durations.csv` (or one passed with
`--lever-durations`) and adds a `lever_duration` column (ms) to the trials CSV,
matching pushes to precued, hit and false alarm trials in order. If the file can't
be matched (empty or unparseable, missing `push_id`/`duration` columns, non-numeric
durations, `push_id` not running 0..n-1, or a push count that differs from the
number of lever push trials) a warning is printed and the column is left empty; no
durations file means no column. Session and
subject summaries report the mean, median, SD and IQR of lever durations for all
pushes, cued pushes, hits, false alarms and precued trials, each with a `_wc`
variant, and the session report gains a median lever push duration plot.
- **Summaries and reports from an existing trials dataframe.** `session.summary()` now
also accepts a trials dataframe from `session.get_trials()`, and
`session.generate_report()` takes an optional `trials` dataframe, so a session is
parsed once rather than re-read for every metric and plot.

### Fixed

- **Reaction time IQR error bars.** The median reaction time plots in the session
report passed the 25th/75th percentiles to Plotly as error bar lengths, which
Plotly treats as offsets from the median, so bars spanned `median - q25` to
`median + q75`. They now span the IQR (`q25` to `q75`).

## [0.3.0] - 2026-09-23

### Added
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ visiomode-analysis session path/to/session.json -o output/ --no-report
visiomode-analysis session path/to/session.json -o output/ --with-regressors --regressor-timestamps frame_times.csv
```

**Lever push durations.** If a `sub-<id>_exp-<experiment>_ses-<date>_lever-durations.csv` file (columns `push_id`, `duration` in ms) sits next to the session JSON, `session` matches each push to its lever push trial (precued trials, hits and false alarms, in trial order) and adds a `lever_duration` column to the trials CSV. Point it at a file elsewhere with `--lever-durations path/to/durations.csv`. Trials without a lever push have an empty `lever_duration`, and sessions without a durations file have no `lever_duration` column at all. If the durations can't be matched (the file is empty or malformed, `push_id` doesn't run 0..n-1, or the number of pushes doesn't match the number of lever push trials), a warning is printed and the column is left empty for that session.

**Generate regressors** for an already-processed session, aligned to an external timestamp series:

```bash
Expand All @@ -72,6 +74,8 @@ visiomode-analysis session-start-time path/to/session.json
visiomode-analysis subject path/to/subject_dir/ -o output/
```

When the trials CSVs have a `lever_duration` column, the summary also reports `lever_duration_<mean|median|sd|iqr>[_<subset>][_wc]` (in ms) for all lever pushes and for the `cued`, `hits`, `false_alarms` and `precued` subsets, with `_wc` variants that include correction trials. These columns are omitted if no session has lever durations.

Run `visiomode-analysis --help` or `visiomode-analysis <command> --help` for full option details.

### Python API
Expand All @@ -85,7 +89,7 @@ trials = session.get_trials("path/to/session.json")
metadata = session.get_metadata("path/to/session.json")
summary = session.summary(trials)

session.generate_report(trials, metadata, output_dir="output/")
session.generate_report("path/to/session.json", output_dir="output/", trials=trials)
```

### Input files and naming convention
Expand Down
14 changes: 14 additions & 0 deletions src/visiomode_analysis/reports/templates/session.html
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ <h6>Cued:uncued response breakdown</h6>
<h6>Median reaction time</h6>
{{ fig_rt_median | safe }}
</div>

{% if fig_lever_duration_median %}
<div class="row mb-2 mt-4">
<h6>Median lever push duration</h6>
{{ fig_lever_duration_median | safe }}
</div>
{% endif %}
</div>

{% if corrections_enabled %}
Expand All @@ -143,6 +150,13 @@ <h6>Cued:uncued response breakdown (all trials)</h6>
<h6>Median reaction time (all trials)</h6>
{{ fig_rt_median_wc | safe }}
</div>

{% if fig_lever_duration_median_wc %}
<div class="row mb-2 mt-4">
<h6>Median lever push duration (all trials)</h6>
{{ fig_lever_duration_median_wc | safe }}
</div>
{% endif %}
</div>

<hr>
Expand Down
Loading
Loading