Summary
py3r.behaviour.summary.summary.Summary ¶
Summary(trackingfeatures: Features)
stores and computes summary statistics from features objects
save ¶
save(
dirpath: str,
*,
data_format: str = "parquet",
overwrite: bool = False,
) -> None
Save this Summary (including nested Features/Tracking) to a directory.
Examples:
>>> import tempfile, os, pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> # add a boolean feature for summary methods to use
>>> mask = pd.Series([True, False] * (len(t.data)//2 + 1))[:len(t.data)]
>>> mask.index = t.data.index
>>> f.store(mask, 'mask', meta={})
>>> s = Summary(f)
>>> with tempfile.TemporaryDirectory() as d:
... s.save(d, data_format='csv', overwrite=True)
... os.path.exists(os.path.join(d, 'manifest.json'))
True
load
classmethod
¶
load(dirpath: str) -> Summary
Load a Summary previously saved with save().
Examples:
>>> import tempfile, pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> f.store(pd.Series(range(len(t.data)), index=t.data.index), 'counter', meta={})
>>> s = Summary(f)
>>> with tempfile.TemporaryDirectory() as d:
... s.save(d, data_format='csv', overwrite=True)
... s2 = Summary.load(d)
>>> isinstance(s2, Summary) and 'counter' in s2.features.data.columns
True
count_onset ¶
count_onset(column: str) -> SummaryResult
Count times boolean series changes False->True, ignoring nans. If first non-nan value is True, that counts as an onset.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> mask = pd.Series([False, True, False, True, False][:len(t.data)], index=t.data.index)
>>> f.store(mask, 'mask', meta={})
>>> s = Summary(f)
>>> res = s.count_onset('mask')
>>> bool(res.value == 2)
True
calculate_latency_nth_onset ¶
calculate_latency_nth_onset(
column: str,
target_value: str | float | int = None,
threshold_op: Literal[
">", ">=", "<=", "<", "==", "!="
] = "==",
nth_event: int = 1,
integration_window=1,
)
Compute the latency (in seconds) of the N-th onset event in a feature column.
This method extracts a column from features.data,
passes it on to latencies_from_series, and returns the index
of the N-th False → True transition. If fewer than nth_event
events are present, NaN is returned.
The column may already be boolean or may be thresholded against
target_value using threshold_op. Optional temporal integration
(boolean smoothing) can be applied prior to onset detection.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Name of the column in |
required |
|
str | float | int | None
|
Value to compare against for non-boolean columns. Required unless the column is already boolean. |
None
|
|
('>', '>=', '<=', '<', '==', '!=')
|
Comparison operator used to generate the boolean condition. Only "==" and "!=" are valid for string-valued columns. |
">"
|
|
int
|
Index of the onset event to return (1 = first, note). |
1
|
|
int
|
Window size for boolean integration/smoothing prior to latency extraction. |
1 = no smoothing
|
Returns:
| Type | Description |
|---|---|
SummaryResult
|
A SummaryResult whose value is the index of the selected onset event, or NaN if the event does not exist. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
ValueError
|
Propagated from |
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=1)
>>> f = Features(t)
>>> mask = pd.Series([False, True, False, True, False], dtype = bool)
>>> f.store(mask, 'mask', meta={})
>>> s = Summary(f)
>>> res = s.calculate_latency_nth_onset('mask')
>>> res.value
1.0
>>> print(res._func_name)
latency_mask_==_True_int1_n1
Selecting a later onset:
>>> res = s.calculate_latency_nth_onset('mask', nth_event=2)
>>> res.value
3.0
Selecting a later onset (i.e non existing) creates nan:
>>> res = s.calculate_latency_nth_onset('mask', nth_event=3)
>>> res.value
nan
Using thresholding on numeric data:
>>> speed = pd.Series([0.1, 0.2, 0.8, 0.9, 0.1], dtype = float)
>>> f.store(speed, 'speed', meta={})
>>> res = s.calculate_latency_nth_onset('speed', target_value=0.5, threshold_op='>')
>>> res.value
2.0
Using thresholding on int data:
>>> id = pd.Series([2, 1, 3, 2, 1], dtype = int)
>>> f.store(id, 'id', meta={})
>>> res = s.calculate_latency_nth_onset('id', target_value=2, threshold_op='<')
>>> res.value
1.0
Using thresholding on string value:
>>> cluster = pd.Series(['A', 'A', 'B', 'A', 'A'], dtype = str)
>>> f.store(cluster, 'cluster', meta={})
>>> res = s.calculate_latency_nth_onset('cluster', target_value='B')
>>> res.value
2.0
time_true ¶
time_true(column: str) -> SummaryResult
returns time in seconds that condition in the given column is true
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> mask = pd.Series([True] * len(t.data), index=t.data.index)
>>> f.store(mask, 'mask', meta={})
>>> s = Summary(f)
>>> res = s.time_true('mask')
>>> bool(res.value > 0)
True
time_false ¶
time_false(column: str) -> SummaryResult
returns time in seconds that condition in the given column is false
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> mask = pd.Series([False] * len(t.data), index=t.data.index)
>>> f.store(mask, 'mask', meta={})
>>> s = Summary(f)
>>> res = s.time_false('mask')
>>> bool(res.value > 0)
True
total_distance ¶
total_distance(
point: str,
startframe: int | None = None,
endframe: int | None = None,
) -> SummaryResult
returns total distance traveled by a tracked point between optional start and end frames
Examples:
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = Summary(f)
>>> res = s.total_distance('p1', 0, 4)
>>> isinstance(res.value, (int, float))
True
by_state ¶
by_state(
column: str,
all_states: list | None = None,
max_states: int = 100,
) -> _ByStateDispatcher
Return a dynamic state-grouped dispatcher for Summary methods.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Name of the state column in |
required |
|
list | None
|
Optional explicit state list to define which states are evaluated and in what output order. This list is inclusive: states not present in the data are still evaluated on empty subsets and included in the output. |
None
|
|
int
|
Safety guard limiting the number of evaluated states. Raises |
100
|
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> idx = t.data.index
>>> f.store(pd.Series(['A', 'A', 'B', 'B', 'A'][:len(idx)], index=idx), 'state', meta={})
>>> f.store(pd.Series([1, 2, 3, 4, 5][:len(idx)], index=idx), 'x', meta={})
>>> s = Summary(f)
>>> res = s.by_state('state', all_states=['B', 'C', 'A']).sum_column('x')
>>> res.value.index.tolist()
['B', 'C', 'A']
>>> int(res.value['C']) # inclusive all_states: state absent in data still included
0
>>> int(res.value['B'])
7
sum_column ¶
sum_column(column: str) -> SummaryResult
Sum all non-NaN values in a features.data column and return as a SummaryResult.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = pd.Series([1, 2, 3, 4, 5][:len(t.data)], index=t.data.index)
>>> f.store(s, 'x', meta={})
>>> summ = Summary(f)
>>> res = summ.sum_column('x')
>>> bool(res.value == 15)
True
mean_column ¶
mean_column(column: str) -> SummaryResult
Mean of all non-NaN values in a features.data column and return as a SummaryResult.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = pd.Series([1, 2, 3, 4, 5][:len(t.data)], index=t.data.index)
>>> f.store(s, 'x', meta={})
>>> summ = Summary(f)
>>> res = summ.mean_column('x')
>>> bool(res.value == 3)
True
median_column ¶
median_column(column: str) -> SummaryResult
Median of all non-NaN values in a features.data column and return as a SummaryResult.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = pd.Series([1, 2, 3, 4, 5][:len(t.data)], index=t.data.index)
>>> f.store(s, 'x', meta={})
>>> summ = Summary(f)
>>> res = summ.median_column('x')
>>> bool(res.value == 3)
True
max_column ¶
max_column(column: str) -> SummaryResult
Max of all non-NaN values in a features.data column and return as a SummaryResult.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = pd.Series([1, 2, 3, 4, 5][:len(t.data)], index=t.data.index)
>>> f.store(s, 'x', meta={})
>>> summ = Summary(f)
>>> res = summ.max_column('x')
>>> bool(res.value == 5)
True
min_column ¶
min_column(column: str) -> SummaryResult
Min of all non-NaN values in a features.data column and return as a SummaryResult.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = pd.Series([1, 2, 3, 4, 5][:len(t.data)], index=t.data.index)
>>> f.store(s, 'x', meta={})
>>> summ = Summary(f)
>>> res = summ.min_column('x')
>>> bool(res.value == 1)
True
store ¶
store(
summarystat: Any,
name: str,
overwrite: bool = False,
meta: Any = None,
) -> None
stores a summary statistic and optional metadata, with optional overwrite protection
Examples:
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = Summary(f)
>>> s.store(123, 'num_events', meta={'unit':'count'})
>>> s.data['num_events'] == 123 and s.meta['num_events']['unit'] == 'count'
True
copy ¶
copy() -> Summary
Creates an independent copy of this Summary object.
The returned object shares no mutable state with the original: Features is copied via Features.copy(), and data/meta/tags via deepcopy.
Examples:
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = Summary(f)
>>> s_copy = s.copy()
>>> s_copy.handle == s.handle
True
>>> s_copy.features.tracking.data is not s.features.tracking.data
True
make_bin ¶
make_bin(startframe: int, endframe: int) -> Summary
creates a copy of the Summary object with the dataframes restricted from startframe to endframe, inclusive
Examples:
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = Summary(f)
>>> b = s.make_bin(0, 2)
>>> isinstance(b, Summary)
True
make_bins ¶
make_bins(numbins: int) -> list[Summary]
creates a list of Summary objects, with frames restricted into numbins even intervals. start/endpoints are duplicated between intervals to ensure no loss in e.g. distance calculations
Examples:
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> s = Summary(f)
>>> bins = s.make_bins(3)
>>> len(bins) == 3 and all(isinstance(b, Summary) for b in bins)
True
transition_matrix ¶
transition_matrix(
column: str, all_states=None
) -> SummaryResult
Returns a transition matrix for a given column in self.features.data, with rows and columns as the unique values of the column or as specified by all_states.
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> states = pd.Series(['A','A','B','B','A'][:len(t.data)], index=t.data.index)
>>> f.store(states, 'state', meta={})
>>> s = Summary(f)
>>> res = s.transition_matrix('state')
>>> isinstance(res.value, pd.DataFrame)
True
count_state_onsets ¶
count_state_onsets(
column: str, all_states: list | None = None
) -> SummaryResult
counts the number of times a state is entered in a given column
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Name of the state column in |
required |
|
list | None
|
Optional explicit state ordering to control index presence/order in the
returned Series. When provided, the output is reindexed to |
None
|
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> states = pd.Series(['A','A','B','B','A'][:len(t.data)], index=t.data.index)
>>> f.store(states, 'state', meta={})
>>> s = Summary(f)
>>> res = s.count_state_onsets('state', all_states=['B', 'C', 'A'])
>>> res.value.index.tolist()
['B', 'C', 'A']
>>> res.value.tolist()
[1, 0, 2]
>>> res._params['all_states']
['B', 'C', 'A']
>>> res = s.count_state_onsets('state', all_states=['A'])
>>> res.value.tolist()
[2]
>>> res.value.index.tolist()
['A']
>>> hasattr(res, 'value')
True
time_in_state ¶
time_in_state(
column: str, all_states: list | None = None
) -> SummaryResult
returns the time spent in each state in a given column
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Name of the state column in |
required |
|
list | None
|
Optional explicit state ordering to control index presence/order in the
returned Series. When provided, the output is reindexed to |
None
|
Examples:
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='ex', fps=30)
>>> f = Features(t)
>>> states = pd.Series(['A','A','B','B','A'][:len(t.data)], index=t.data.index)
>>> f.store(states, 'state', meta={})
>>> s = Summary(f)
>>> res = s.time_in_state('state', all_states=['B', 'C', 'A'])
>>> res.value.index.tolist()
['B', 'C', 'A']
>>> [round(v, 4) for v in res.value.tolist()]
[0.0667, 0.0, 0.1]
>>> res._params['all_states']
['B', 'C', 'A']
>>> res = s.time_in_state('state', all_states=['A'])
>>> [round(v, 4) for v in res.value.tolist()]
[0.1]
>>> res.value.index.tolist()
['A']
>>> hasattr(res, 'value')
True
plot_chord ¶
plot_chord(
column: str,
all_states: list[str | int] | None = None,
*,
fromkey: str | None = None,
cmap: str | list | None = None,
show: bool = True,
save_dir: str | None = None,
**kwargs,
)
Plot a simple chord diagram of state transitions for this recording.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
|
str
|
Name of the categorical column in |
required |
|
list[str | int] | None
|
Optional explicit list/array of states to define row/column presence and order.
Required when |
None
|
|
str | None
|
Optional key in |
None
|
|
Additional keyword arguments to pass to pycirclize.chordDiagram. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
fig_like |
Backend-dependent figure-like handle (from pycirclize). |
Examples:
>>> # xdoctest: +REQUIRES(module: pycirclize)
>>> import tempfile, os
>>> import pandas as pd
>>> from py3r.behaviour.util.docdata import data_path
>>> from py3r.behaviour.tracking.tracking import Tracking
>>> from py3r.behaviour.features.features import Features
>>> from py3r.behaviour.summary.summary import Summary
>>> with data_path('py3r.behaviour.tracking._data', 'dlc_single.csv') as p:
... t = Tracking.from_dlc(str(p), handle='A', fps=30)
>>> f = Features(t)
>>> # simple 3-state sequence to induce transitions
>>> states = pd.Series(['0','1','2','1','0'] * (len(t.data)//5 + 1))[:len(t.data)]
>>> states.index = t.data.index
>>> f.store(states, 'state', meta={})
>>> s = Summary(f)
>>> with tempfile.TemporaryDirectory() as outdir:
... _ = s.plot_chord('state', all_states=['0','1','2'], show=False, save_dir=outdir)
... os.path.exists(os.path.join(outdir, 'A_chord_state.png'))
True
snssuperplot ¶
snssuperplot(metric, **kwargs)
Superplot -- see :meth:SummaryCollection.snssuperplot.