graintrace.graph_spatial_cluster#

Graph-based spatial clustering of field data (grid/kNN edges, NetworKit segmentation).

class graintrace.graph_spatial_cluster.GraphSpatialCluster(csv_path, id_col='id', coord_cols=('x', 'y', 'z'))[source]#

Bases: object

Cluster point-cloud field data by building a spatial graph and segmenting it.

Parameters:
load_data()[source]#

Load CSV and populate data, features, coords.

Return type:

None

check_feature_matrix(spec)[source]#

Validate that all feature columns required by spec exist in the data.

Parameters:

spec (SimilarityMetric)

Return type:

None

run(spec, graph_mode='auto', k=16, manhattan_radius=1, grid_tol=1e-06, n_jobs=1, weight_chunk_size=1000000, nodes_chunk=250000, segmenter='auto', seed=42, n_threads=1, feature_names=None, output_csv_path=None, return_labels=False, reduce_edges_topweights_k=None, max_edge_distance=None, weight_cfg=WeightConfig(mode='inverse', eps=1e-08, sigma=None, sigma_auto=None, power=2.0), networkit_kwargs=None, checkpoint_base_path=None, resume_from_checkpoint=False, mp_start_method=None)[source]#

Run the full pipeline: build edges, weight them, segment, return labels/props.

Parameters:
Return type:

Dict[str, Any]

segment_graph_networkit(n_nodes, edges, weights, method='leiden', seed=42, n_threads=1, **networkit_kwargs)[source]#

Segment a weighted graph with NetworKit (leiden/plm/plp), returning labels.

Parameters:
Return type:

ndarray

compute_edge_distances(edges, X, spec, n_jobs=1, chunk_size=1000000, mp_start_method=None)[source]#

Compute per-edge distances with spec.func, chunked and single-process.

Parameters:
Return type:

ndarray

static distances_to_weights(distances, weight_cfg)[source]#

Convert edge distances to edge weights per weight_cfg.

Parameters:
Return type:

ndarray

static estimate_sigma_from_distances(distances, quantile=0.5)[source]#

Estimate an RBF sigma as the given quantile of the distance array.

Parameters:
Return type:

float

compute_edge_weights(edges, X, spec, weight_cfg, n_jobs=1, chunk_size=1000000)[source]#

Compute edge weights = distances_to_weights(compute_edge_distances(…)).

Parameters:
Return type:

ndarray

static prune_topk_per_node_parallel(n_nodes, edges, weights, k, n_jobs=1, nodes_chunk=250000, mp_start_method=None)[source]#

Keep each node’s k highest-weight incident edges (union over endpoints).

Uses a numba thread-parallel kernel when available (n_jobs = thread count), else a single-threaded numpy fallback. nodes_chunk / mp_start_method are accepted for backward compat only and have no effect.

Selection is deterministic: among equal weights the lower half-edge index wins. Edge e contributes half-edge e at its first endpoint and half-edge E + e at its second, so for a given node the tie-break prefers the edges where it is the first endpoint, each in ascending edge id. Both code paths implement that rule, so an input with exact ties – routine, since identical orientations give an RBF weight of exactly 1.0 – prunes to the same graph whether or not numba is installed.

Parameters:
Return type:

Tuple[ndarray, ndarray]

get_cluster_properties(labels, coords, X, feature_names)[source]#

Aggregate per-cluster stats: size, centroid, feature means, tensor norms.

Parameters:
Return type:

DataFrame

estimate_sigma_from_sampled_edges(edges, X, spec, sample_size=200000, quantile=0.5, seed=0)[source]#

Estimate an RBF sigma from a random sample of edge distances.

Parameters:
Return type:

float