PSTH Widget Roadmap
PSTHWidget Development Roadmap
This document tracks remaining development tasks for the PSTH Widget. For documentation of completed features and current architecture, see the main developer documentation.
Completed Work Summary
The following features are complete and documented in index.qmd:
- Core rendering: OpenGL pipeline,
GatherResultintegration,HistogramMapper,SceneRenderer - Binning: Uniform time bins with configurable bin size
- Plot styles: Bar chart and step-function line rendering via shared
HistogramMapper - Interaction: Separated X/Y zoom, pan, double-click time navigation
- Axis system:
RelativeTimeAxisWidget(X) andVerticalAxisWidget(Y) with bidirectional sync - Properties panel: Alignment controls, event series management, style selection, per-event color picker
- State serialization: Full round-trip JSON via
rfl::json - Rate estimation integration:
PSTHStateDatanow storesEstimationParamsvariant directly.PSTHPropertiesWidgetuses the sharedEstimationMethodControlswidget fromRateEstimationControlslibrary for method selection and per-method parameter editing. Renderer extracts bin size fromestimationParams()viastd::get_if<BinningParams>. - Normalization/scaling :
PSTHStateDatastoresScalingModefrom the sharedRateEstimate.hpp.PSTHPropertiesWidgetuses the sharedScalingModeControlswidget.PSTHPlotOpenGLWidget::rebuildScene()applies scaling viaapplyScaling()fromRateNormalization.hpp, supporting all scaling modes (Raw Count, Firing Rate Hz, Z-Score, Normalized [0,1], Count/Trial).
Phase 3: Variability and Confidence Intervals
Status: Design phase. Depends on Phase 1 (normalization) and the Rate Estimation Redesign.
Goal: Display trial-to-trial variability in the PSTH, providing a visual measure of the reliability of the rate estimate.
This phase uses the shared uncertainty infrastructure from the redesign rather than defining bespoke per-trial histogram or confidence band types.
3.1 Per-Trial Data via estimateRateWithTrials()
The shared library provides estimateRateWithTrials(), which returns a RateEstimateWithTrials containing both the aggregate RateEstimate (mean across trials) and a PerTrialData matrix (each trial’s individual rate curve). This is the opt-in computation path — estimateRate() (the default) does not allocate per-trial storage.
3.3 Rendering Confidence Bands
Confidence bands should be rendered as a filled semi-transparent region behind the mean line/bars. The ConfidenceBand provides lower[i] and upper[i] at each time point, which maps directly to a filled polygon or rectangle batch.
The HistogramMapper could be extended with a toConfidenceBand() method that produces a filled polygon batch, or a new ConfidenceBandMapper could be introduced. The band should use the same fill color as the histogram but with reduced opacity (e.g., alpha = 0.2).
3.4 Properties Panel
Add controls to PSTHPropertiesWidget:
- Variability mode combo box (
None,SEM,CI95,Percentile,Bootstrap) - Confidence band color/opacity slider
- For Percentile mode: lower and upper percentile spinboxes
Phase 4: Cross-Widget Linking
Status: Design complete. pinned field exists in EventPlotWidget state. Implementation needed for PSTHWidget.
Goal: Enable PSTH, EventPlotWidget, and HeatmapWidget to synchronize on active unit selection.
4.1 SelectionContext Integration
Following the existing SelectionContext pattern used by DataInspector widgets and described in the EventPlot Roadmap:
void PSTHPropertiesWidget::_onSelectionChanged(SelectionSource const & source) {
if (_state && _state->isPinned()) return;
if (_state && source.editor_instance_id.toString() == _state->getInstanceId()) return;
if (_selection_context) {
auto const selected = _selection_context->primarySelectedData();
if (selected.isValid()) {
auto type = _data_manager->getType(selected.toString().toStdString());
if (type == DM_DataType::DigitalEventSeries) {
updateDisplayedEventSeries(selected.toString());
}
}
}
}4.3 Heatmap → PSTH + Raster Flow
The primary cross-widget workflow:
HeatmapWidget row click
↓
SelectionContext::setSelectedData("unit_42", source)
↓
PSTHWidget (if not pinned) receives selectionChanged
↓
Checks type == DigitalEventSeries → updates histogram
↓
EventPlotWidget (if not pinned) also receives selectionChanged
↓
Updates raster plot for same unit
This enables rapid exploration of neural data: click through units in the heatmap while the PSTH and raster plot update in sync. See the EventPlot Roadmap Phase 6 for the complementary EventPlot implementation.
Phase 5: SVG Export
Status: Infrastructure exists in CorePlotting::Export. Implementation needed for PSTHWidget.
Goal: Export the current PSTH plot to SVG for publication-quality figures.
5.1 Existing Infrastructure
The project already has SVG export infrastructure in CorePlotting/Export/SVGPrimitives.hpp:
buildSVGDocument(RenderableScene, SVGExportParams)— generates a complete SVG from anyRenderableScenerenderRectangleBatchToSVG()— converts bar charts to<rect>elementsrenderPolyLineBatchToSVG()— converts line plots to<polyline>elementsrenderSceneToSVG()— renders a full scene including all batch types
The DataViewerWidget already uses this infrastructure via a bespoke SVGExporter class that builds scenes from the DataViewer’s specific state format.
5.3 UI Integration
Add an “Export SVG…” action to the PSTH properties panel or a right-click context menu on the plot. The action should:
- Open a file save dialog
- Build the SVG from the cached
RenderableSceneand current view/projection matrices - Optionally include axis labels, title, and scalebar
- Save to the chosen path
5.4 Export Options
struct PlotSVGExportOptions {
int width = 1920;
int height = 1080;
bool include_axes = true;
bool include_title = true;
bool include_scalebar = false;
int scalebar_length = 100; // in time units
std::string background_color = "#FFFFFF"; // White for publication
};Phase 6: Embeddable PSTH for Tooltips
Status: Design exploration. Depends on histogram infrastructure being factored for lightweight use.
Goal: Provide a lightweight, embeddable PSTH rendering that can appear in tooltips — for example, when hovering over a row of the HeatmapWidget.
6.1 Concept
When a user hovers over a unit row in the HeatmapWidget, a tooltip could display:
- A miniature PSTH for that unit
- Optionally, a combined raster + PSTH view
This requires decoupling the PSTH computation and rendering from the full widget machinery.
6.2 Lightweight Histogram Renderer
Use the shared estimateRate() from the EventRateEstimation library to compute the histogram data. The RateEstimate output (paired times[] + values[]) can be rendered directly by a lightweight QPainter-based renderer without needing the full OpenGL widget machinery.
For tooltip rendering, there are two approaches:
- QPixmap approach: Render the histogram to a
QPixmapvia a headless OpenGL context or a software rasterizer, then display inQToolTip - QPainter approach: Implement a simple
QPainter-based histogram renderer that doesn’t require OpenGL. This is simpler and avoids GL context issues in tooltips.
6.3 QPainter-based Mini Renderer
namespace CorePlotting::PSTH {
QPixmap renderMiniPSTH(
HistogramData const & data,
HistogramStyle const & style,
QSize size = {200, 80});
}This would use QPainter to draw bars/lines onto a QPixmap, suitable for embedding in tooltips, table cells, or any widget that can display a pixmap.
6.4 Combined Raster + PSTH Tooltip
For the HeatmapWidget tooltip showing both raster and PSTH:
┌─────────────────────┐
│ ▎ ▎ ▎▎ ▎ ▎ │ ← raster (mini)
│ ▎▎ ▎ ▎ ▎ ▎▎ │
│ ▎ ▎▎ ▎ ▎ ▎ │
├─────────────────────┤
│ ▓▓▓▓████▓▓▓▓▓▓▓▓▓ │ ← PSTH (mini)
└─────────────────────┘
Unit: spikes_unit_42
This requires factoring out the EventPlot’s raster rendering in a similar lightweight fashion.
6.5 Reuse with ACFWidget
The same QPainter-based mini histogram renderer could serve ACFWidget for ISI distribution tooltips or summary displays in other contexts where a full OpenGL widget is overkill.
Phase 7: Per-Series Histograms and Multi-Color Overlay
Status: Partially implemented. Multiple event series can be added but currently all events are binned into a single histogram.
Goal: When multiple DigitalEventSeries are overlaid, render separate histograms per series with distinct colors, with optional stacking or transparency.
7.1 Per-Series Binning
Modify rebuildScene() to produce separate HistogramData per event series rather than accumulating all events into a single histogram.
7.2 Overlay Modes
enum class PSTHOverlayMode {
Stacked, ///< Bars stacked vertically (colors distinguish series)
Overlaid, ///< Semi-transparent bars overlaid at same baseline
SideBySide ///< Bars placed side-by-side within each bin
};7.3 Color Application
The existing per-event hex_color in PSTHEventOptions should be applied to the HistogramStyle::fill_color when building each series’ scene. Currently, all series share a single default color.
Implementation Priority
Next Up
- Phase 2 (remaining): Migrate
PSTHPlotOpenGLWidget::rebuildScene()to useEventRateEstimationlibrary’sestimateRate(); then add Gaussian kernel and other smoothing methods - Phase 4: Cross-widget linking with pin support
- Phase 5: SVG export (infrastructure already exists)
Following
- Phase 7: Per-series histograms and multi-color overlay
- Phase 3: Variability / confidence intervals
Later
- Phase 6: Embeddable PSTH for tooltips
Open Questions
SVG export scope: Should SVG export be a per-widget feature (button in each widget), or a centralized “Export All Visible Plots” action? The DataViewerWidget already has its own bespoke SVG exporter — should that be migrated to the shared infrastructure?
Tooltip rendering: Should tooltip histograms use
QPainter(simpler, no GL context needed) or render toQPixmapvia GL (consistent with main rendering)?QPainteris strongly preferred for reliability.Multiple event series: When overlaying multiple event series, should the default be stacked or overlaid? Neuroscience convention varies — PSTH typically shows one unit at a time, but comparing two conditions on the same unit is common.
See Also
- PSTHWidget Documentation — Full architecture and feature documentation
- Plot Widget Guide — Shared architecture, axis types, DataManager integration
- EventPlotWidget — Raster plot (natural companion)
- EventPlot Roadmap — Cross-widget linking design (Phase 6), SVG export plans
- HeatmapWidget — Shares alignment, GatherResult, and planned linking
- ACFWidget — Shares HistogramMapper, bar chart rendering; ISI histograms