torchcell.data.IncidenceSubgraphRepresentation

class IncidenceSubgraphRepresentation[source]

Bases: GraphProcessor

Graph processor using precomputed node-to-edge incidence structures.

Algorithm: - Precomputes which edges touch each node (incidence mapping) once at initialization - For each perturbation, directly looks up edges to remove via the incidence map - Achieves O(k×d) complexity for edge filtering where k=removed nodes, d=degree - Still performs node relabeling and returns standard subgraph format

Complexity: - Precomputation: O(E) once per dataset - Per sample: O(k×d + E’) where k<<N (small perturbations) and E’≈E - vs standard subgraph: O(N + E) per edge type per sample

Memory: - Stores list of edge positions for each node (~O(E) total) - Minimal overhead compared to graph structure itself

Output: - Identical format to SubgraphRepresentation (filtered, relabeled subgraphs) - Full backward compatibility with existing models

property edge_incidence_cache: dict[Any, list[Tensor]]

Lazily build and return edge incidence cache.

Maps each node to tensor of edge positions where that node appears. Built on first use and rebuilt whenever a different cell graph arrives (see _build_incidence_cache).

build_cache(cell_graph: HeteroData) → dict[str, Any][source]

Explicitly build incidence cache and return timing information.

This should be called once during dataset initialization or before benchmarking to separate one-time cache build cost from per-sample processing time.

Returns:

dict with cache build timing:

{
    'total_time_ms': float,
    'num_edge_types': int,
    'total_edges': int
}

process(cell_graph: HeteroData, phenotype_info: list[Any], data: list[dict[str, Any]]) → HeteroData[source]

Build incidence-based subgraph representations and attach phenotypes.