Skip to content

connections

champalimaud.connections

Columns of a connection table: the cells and types at its ends.

A connection table has one row per pair of cells, with the root ids pre_pt_root_id and post_pt_root_id and the synapse count weight.

reversed_connections(connections)

Swap the presynaptic and postsynaptic cell of each connection.

Parameters:

Name Type Description Default
connections DataFrame

Has pre_pt_root_id and post_pt_root_id.

required

Returns:

Type Description
DataFrame

connections with the two id columns swapped; every other column stays with its row.

Examples:

>>> import polars as pl
>>> connections = pl.DataFrame(
...     {
...         "pre_pt_root_id": [1],
...         "post_pt_root_id": [2],
...         "weight": [7],
...     }
... )
>>> reversed_connections(connections).row(0, named=True)
{'post_pt_root_id': 1, 'pre_pt_root_id': 2, 'weight': 7}
Source code in champalimaud/connections.py
def reversed_connections(connections: pl.DataFrame) -> pl.DataFrame:
    """Swap the presynaptic and postsynaptic cell of each connection.

    Parameters
    ----------
    connections : polars.DataFrame
        Has ``pre_pt_root_id`` and ``post_pt_root_id``.

    Returns
    -------
    polars.DataFrame
        `connections` with the two id columns swapped; every other
        column stays with its row.

    Examples
    --------
    >>> import polars as pl
    >>> connections = pl.DataFrame(
    ...     {
    ...         "pre_pt_root_id": [1],
    ...         "post_pt_root_id": [2],
    ...         "weight": [7],
    ...     }
    ... )
    >>> reversed_connections(connections).row(0, named=True)
    {'post_pt_root_id': 1, 'pre_pt_root_id': 2, 'weight': 7}
    """
    return connections.rename(
        {
            "pre_pt_root_id": "post_pt_root_id",
            "post_pt_root_id": "pre_pt_root_id",
        }
    )

with_cell_columns(connections, cells, *, end='pre')

Add the columns of a cell table for one end of each connection.

Parameters:

Name Type Description Default
connections DataFrame

Has pre_pt_root_id and post_pt_root_id.

required
cells DataFrame

Has root_id and other columns, one row per cell: a repeated root_id would repeat the connections of that cell.

required
end (pre, post)

Which end of each connection to look up.

"pre"

Returns:

Type Description
DataFrame

connections in its order, with the other columns of cells added as pre_<column> or post_<column>; a cell missing from cells gets nulls.

Raises:

Type Description
ValueError

For any other end, or when root_id repeats in cells.

Examples:

>>> import polars as pl
>>> connections = pl.DataFrame(
...     {"pre_pt_root_id": [1, 2], "post_pt_root_id": [2, 9]}
... )
>>> cells = pl.DataFrame({"root_id": [1, 2], "side": ["L", "R"]})
>>> with_cell_columns(connections, cells)["pre_side"].to_list()
['L', 'R']
Source code in champalimaud/connections.py
def with_cell_columns(
    connections: pl.DataFrame, cells: pl.DataFrame, *, end: str = "pre"
) -> pl.DataFrame:
    """Add the columns of a cell table for one end of each connection.

    Parameters
    ----------
    connections : polars.DataFrame
        Has ``pre_pt_root_id`` and ``post_pt_root_id``.
    cells : polars.DataFrame
        Has ``root_id`` and other columns, one row per cell: a
        repeated ``root_id`` would repeat the connections of that
        cell.
    end : {"pre", "post"}, default "pre"
        Which end of each connection to look up.

    Returns
    -------
    polars.DataFrame
        `connections` in its order, with the other columns of `cells`
        added as ``pre_<column>`` or ``post_<column>``; a cell missing
        from `cells` gets nulls.

    Raises
    ------
    ValueError
        For any other `end`, or when ``root_id`` repeats in `cells`.

    Examples
    --------
    >>> import polars as pl
    >>> connections = pl.DataFrame(
    ...     {"pre_pt_root_id": [1, 2], "post_pt_root_id": [2, 9]}
    ... )
    >>> cells = pl.DataFrame({"root_id": [1, 2], "side": ["L", "R"]})
    >>> with_cell_columns(connections, cells)["pre_side"].to_list()
    ['L', 'R']
    """
    if end not in ("pre", "post"):
        msg = f"end must be 'pre' or 'post', not {end!r}"
        raise ValueError(msg)
    if cells["root_id"].is_duplicated().any():
        msg = "root_id repeats in cells; each cell needs one row"
        raise ValueError(msg)
    prefixed = cells.rename(
        {
            column: f"{end}_{column}"
            for column in cells.columns
            if column != "root_id"
        }
    )
    return connections.join(
        prefixed,
        left_on=f"{end}_pt_root_id",
        right_on="root_id",
        how="left",
        maintain_order="left",
    )

with_post_type(connections, cells_by_type)

Add post_type, the type of the postsynaptic cell.

Parameters:

Name Type Description Default
connections DataFrame

Has post_pt_root_id.

required
cells_by_type dict of str to list

Maps a type name to the ids of its cells; a cell may belong to only one type.

required

Returns:

Type Description
DataFrame

connections with post_type, null for a cell in no type.

See Also

with_pre_type : The same for the presynaptic cell.

Examples:

>>> import polars as pl
>>> connections = pl.DataFrame(
...     {"pre_pt_root_id": [1, 5], "post_pt_root_id": [2, 2]}
... )
>>> with_post_type(connections, {"B": [2]})["post_type"].to_list()
['B', 'B']
Source code in champalimaud/connections.py
def with_post_type(
    connections: pl.DataFrame, cells_by_type: dict[str, list]
) -> pl.DataFrame:
    """Add ``post_type``, the type of the postsynaptic cell.

    Parameters
    ----------
    connections : polars.DataFrame
        Has ``post_pt_root_id``.
    cells_by_type : dict of str to list
        Maps a type name to the ids of its cells; a cell may belong
        to only one type.

    Returns
    -------
    polars.DataFrame
        `connections` with ``post_type``, null for a cell in no type.

    See Also
    --------
    with_pre_type : The same for the presynaptic cell.

    Examples
    --------
    >>> import polars as pl
    >>> connections = pl.DataFrame(
    ...     {"pre_pt_root_id": [1, 5], "post_pt_root_id": [2, 2]}
    ... )
    >>> with_post_type(connections, {"B": [2]})["post_type"].to_list()
    ['B', 'B']
    """
    return with_cell_columns(
        connections, type_table(cells_by_type), end="post"
    )

with_pre_type(connections, cells_by_type)

Add pre_type, the type of the presynaptic cell.

Parameters:

Name Type Description Default
connections DataFrame

Has pre_pt_root_id.

required
cells_by_type dict of str to list

Maps a type name to the ids of its cells; a cell may belong to only one type.

required

Returns:

Type Description
DataFrame

connections with pre_type, null for a cell in no type.

See Also

with_post_type : The same for the postsynaptic cell.

Examples:

>>> import polars as pl
>>> connections = pl.DataFrame(
...     {"pre_pt_root_id": [1, 5], "post_pt_root_id": [2, 2]}
... )
>>> with_pre_type(connections, {"A": [1]})["pre_type"].to_list()
['A', None]
Source code in champalimaud/connections.py
def with_pre_type(
    connections: pl.DataFrame, cells_by_type: dict[str, list]
) -> pl.DataFrame:
    """Add ``pre_type``, the type of the presynaptic cell.

    Parameters
    ----------
    connections : polars.DataFrame
        Has ``pre_pt_root_id``.
    cells_by_type : dict of str to list
        Maps a type name to the ids of its cells; a cell may belong
        to only one type.

    Returns
    -------
    polars.DataFrame
        `connections` with ``pre_type``, null for a cell in no type.

    See Also
    --------
    with_post_type : The same for the postsynaptic cell.

    Examples
    --------
    >>> import polars as pl
    >>> connections = pl.DataFrame(
    ...     {"pre_pt_root_id": [1, 5], "post_pt_root_id": [2, 2]}
    ... )
    >>> with_pre_type(connections, {"A": [1]})["pre_type"].to_list()
    ['A', None]
    """
    return with_cell_columns(connections, type_table(cells_by_type), end="pre")