itasc.contact_analysis.contacts¶
Cell-cell contact quantifier: edges, T1 events, neighbourhood & density.
The contacts domain logic that used to live at the top-level
itasc.contact_analysis package. It is one quantifier within
itasc.contact_analysis; its public API is re-exported from the
package root for stability. All of it is label-agnostic.
- itasc.contact_analysis.contacts.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_idandlengthare 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.homotypic—label_a == label_b(True for two unclassified; gate onfully_classifiedif 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.
- itasc.contact_analysis.contacts.signed_central_junction_lengths(analysis, *, pixel_size_um=None, labels=None)[source]¶
Signed central junction length per T1 event, per frame.
For each T1 event the central junction is the edge that flips from the losing cell pair (pre-transition) to the gaining pair (post-transition). Every frame in which an event’s losing edge exists contributes a negative sample (
−length); every frame its gaining edge exists contributes a positive one (+length). The magnitude is the edge length; it crosses zero at the four-fold vertex, so pooled and inverted these reproduce the reference’s double-well potential without curated quads.Fragmented contacts are joined first: the build splits a single cell-cell boundary into several edge rows (one per disconnected segment from
_coordinate_segments), so the lengths of all rows sharing a(frame, cell-pair)are summed into one total junction length before signing. Otherwise each fragment would enter the landscape as its own (short) sample. This is the headless analogue of the v1find_shared_boundary/order_boundary_pixelsjoin that produced one length per junction.All frames an edge exists are used (no ± window) — matching the reference, which histograms the whole movie.
Columns (column-major, all equal length):
t1_event_id— the event each sample belongs to.frame— the frame the sample is read from.signed_length—±length, in µm when pixel_size_um is given else px.role—"losing"(negative) or"gaining"(positive).contact_type— the event’s transition pair"<losing>→<gaining>"(e.g."A-A→A-B"), where each side is the contact label (contact_labels.contact_label_for()) of that junction’s cell pair.""when no labels map is given (the label-agnostic default). A single per-event label is used (not per-side), so both the negative losing lobe and the positive gaining lobe of an event share it and a grouped curve still spansL = 0for the barrier.
labels maps
cell_id -> label(an optional, caller-supplied per-cell classification); a cell absent from it is"unclassified".Returns empty (but typed) arrays when there are no events or no matching edges; an event whose losing/gaining edges never appear in
edgessimply contributes nothing.
- itasc.contact_analysis.contacts.cell_neighbor_counts(analysis)[source]¶
Per
(frame, cell_id)adjacency degree — the headline neighbor count.One row per cell present in the
cellstable for that frame, withn_neighborsits number of distinctcell_cellneighbors (0 for an isolated cell). This count is also the numerator for density.Columns (column-major, equal length):
frame,cell_id,n_neighbors(int).- Return type:
- Parameters:
analysis (PositionContactAnalysis)
- itasc.contact_analysis.contacts.cell_density(frame_cells, *, fov_area_mm2)[source]¶
Per
framecell count anddensity = n_cells / fov_area_mm2.Emits one
label="all"row per frame that counts every cell in the frame.densityis in cells/mm²; fov_area_mm2 is the user’s field-of-view area and is required (a positive number) — there is no silent image-area fallback.frame_cells maps
frame -> [cell_id, …](the cell labels present in that frame), so this counts straight off the cell labels with no contacts dependency.Columns:
frame,label(str, always"all"),n_cells(int),density(float, cells/mm²).
Submodules
Name-based batch discovery and headless contact-analysis builds. |
|
Contact cell-type labels — propagate a per-cell label onto contacts. |
|
Neighborhood & density derivations over the cell–cell contact graph. |
|
Signed contact length — the signed central junction-length reaction coordinate. |