itasc.contact_analysis.contacts.contact_labels

Contact cell-type labels — propagate a per-cell label onto contacts.

Each cell–cell contact (a row of the edges table) is labelled by the unordered pair of its two cells’ labels, supplied as a generic cell_id -> label map. A contact between cell types A and B is labelled "A-B" (sorted), so a consumer can ask how subpopulations contact each other — homotypic vs heterotypic — without that aggregation living here. The label map is the caller’s concern (e.g. a downstream, dataset-specific classification); this module is label-agnostic.

Headless and Qt-free, like itasc.contact_analysis.contacts.signed_contact_length: it operates on an already-read PositionContactAnalysis plus a cell_id -> label map, so it never opens HDF5 itself and runs unchanged in scripts, notebooks, and plugins.

Functions

contact_label_for(labels, cell_a, cell_b, *)

The sorted "label_a-label_b" contact label for one cell pair.

label_contacts(analysis, labels, *[, ...])

Label every cell–cell contact by its two cells' NLS subpopulation labels.

itasc.contact_analysis.contacts.contact_labels.contact_label_for(labels, cell_a, cell_b, *, unclassified='unclassified')[source]

The sorted "label_a-label_b" contact label for one cell pair.

Each cell’s label is looked up in labels (cell_id -> label); a cell absent from the map takes unclassified. The pair is sorted so the contact type is orientation-independent ("A-B" == "B-A"). This is the single definition shared by label_contacts() (the per-edge table) and the signed-contact-length reaction coordinate, so a contact types identically wherever it is seen.

Return type:

str

Parameters:
itasc.contact_analysis.contacts.contact_labels.label_contacts(analysis, labels, *, unclassified='unclassified')[source]

Label every cell–cell contact by its two cells’ NLS subpopulation labels.

For each kind == "cell_cell" edge, each endpoint’s label is looked up in labels (cell_id -> label; a cell absent from the map takes unclassified) and the unordered-pair contact label "-".join(sorted([label_a, label_b])) is formed. The vocabulary is whatever labels holds — nothing here is hard-wired to positive/negative.

Border edges (kind == "border", cell_b == 0) are not contacts between two cells and are excluded. Fragments are not joined: a boundary split across several edge rows yields several labelled rows that share the same (frame, cell_a, cell_b) and therefore the same label; edge_id and length are carried through so a consumer can join or length-weight later.

Columns (column-major, all equal length, one row per cell–cell edge):

  • frame — the edge’s frame.

  • edge_id — the edge’s id within its frame.

  • cell_a / cell_b — the contacting cell ids (as stored, a < b).

  • label_a / label_b — each cell’s NLS label, or unclassified.

  • contact_label — sorted "label_a-label_b" pair.

  • homotypiclabel_a == label_b (True for two unclassified; gate on fully_classified if that matters).

  • fully_classified — both cells had a label in labels.

  • length — the edge length, carried through for weighting.

Returns empty (but typed) arrays when there are no cell–cell edges.

Return type:

dict[str, ndarray]

Parameters: