cyto.postprocessing

Contact detection, network analysis, sparse/dense table operations, and visualisation helpers.

class cyto.postprocessing.interaction_detection.DetectInteractions(verbose=True)[source]

Bases: object

class cyto.postprocessing.interaction_detection.VideoInteractions(verbose=True)[source]

Bases: object

cyto.postprocessing.interaction_detection.distance(p1, p2)[source]
class cyto.postprocessing.graph.CellTriangulation(base_image=True, verbose=True)[source]

Bases: object

class cyto.postprocessing.graph.CrossCellContactMeasures(verbose=True)[source]

Bases: object

run_single_frame(label_0, label_1, centroids_0, centroids_1, features_0, features_1, frame)[source]

Single frame process run

Parameters:
  • label_0 (arr) – Numpy array label of first cell type

  • label_1 (arr) – Numpy array label of second cell type

  • centroids_0 (arr) – Numpy array of centroid coordinates corresponding to label_0, in pixel space ij.

  • centroids_1 (arr) – Numpy array of centroid coordinates corresponding to label_1, in pixel space ij.

  • features_0 (Dataframe) – Dataframe of spares cell info of first cell type

  • features_1 (Dataframe) – Dataframe of spares cell info of second cell type

  • frame (int) – Frame number to async parallel processing positioning.

cyto.postprocessing.graph.label_centroids_to_pointlist_sitk(label, cell_type='')[source]
class cyto.postprocessing.sparse_to_sparse.CrossTableOperation(column, operation, verbose=True)[source]

Bases: object

class cyto.postprocessing.sparse_to_sparse.FeatureFilter(column, operation, value, verbose=True)[source]

Bases: object

OPS = {'!=': <built-in function ne>, '<': <built-in function lt>, '<=': <built-in function le>, '==': <built-in function eq>, '>': <built-in function gt>, '>=': <built-in function ge>}
cyto.postprocessing.sparse_to_sparse.apply_gaussian_smoothing(values, sigma)[source]

Applies Gaussian smoothing using NumPy.

cyto.postprocessing.sparse_to_sparse.cal_viability(df, pos_cols=[], neg_cols=[])[source]
cyto.postprocessing.sparse_to_sparse.calculate_cdi(df, viability_col, death_col, out_col='CDI')[source]

Calculate the Cell Death Index (CDI) and add it as a new column in the dataframe.

CDI = I_death_norm / (I_death_norm + I_live_norm)

Parameters:
  • df (pandas.DataFrame) – DataFrame containing the fluorescence intensity data.

  • viability_col (str) – Column name for the viability channel (e.g., live cell marker).

  • death_col (str) – Column name for the death channel (e.g., dead cell marker).

  • out_col (str) – Column name for CDI output (default: "CDI").

Returns:

Input DataFrame with a new column containing the calculated CDI values.

Return type:

pandas.DataFrame

cyto.postprocessing.sparse_to_sparse.compute_central_difference(values)[source]

Computes the gradient using the central finite difference method.

cyto.postprocessing.sparse_to_sparse.compute_moving_average(data, window_size)[source]

Calculates the moving average of a given data array.

cyto.postprocessing.sparse_to_sparse.compute_savgol_filter(df, track_id_col='track_id', frame_col='frame', value_col='scalar_value', window_length=10, polyorder=3)[source]

Applies the Savitzky-Golay filter to smooth the signal and compute its derivative.

Parameters:

dfpd.DataFrame

DataFrame containing the time and signal columns.

track_id_col: str

Column name of the cell track id in the DataFrame.

frame_colstr

Column name of the time data in the DataFrame.

value_colstr

Column name of the value data in the DataFrame.

window_lengthint, optional

The length of the filter window (must be odd), default is 11.

polyorderint, optional

The order of the polynomial used to fit the samples, default is 3.

Returns:

dfpd.DataFrame

The input DataFrame with additional columns for the smoothed signal and its derivative.

cyto.postprocessing.sparse_to_sparse.compute_smoothed_gradient(df, track_id_col='track_id', frame_col='frame', value_col='scalar_value', sigma=2, ma_window=10, smooth_method='gaussian', grad_method='forward')[source]

Computes a smoothed time gradient for noisy scalar values in a pandas DataFrame.

Parameters: - df: pd.DataFrame containing the data with columns for track ID, frame, and scalar values. - track_col: str, name of the column representing track IDs. - frame_col: str, name of the column representing frames (time points). - value_col: str, name of the column representing scalar values. - sigma: float, the standard deviation for Gaussian smoothing (controls the smoothness). - ma_window: int, moving average window size - smooth_method: str, smooth method between Gaussian smoothing, Levenberg Marquardt method and moving average filter, allowed options: “gaussian”, “lm”, “ma” - grad_method: str, numerical gradient difference method, allow options: “forward”, “central”

Returns: - pd.DataFrame with additional columns for smoothed scalar values and gradients.

cyto.postprocessing.sparse_to_sparse.fit_model(x, y)[source]

Fit the model to the data using Levenberg-Marquardt and return fitted values.

cyto.postprocessing.sparse_to_sparse.gaussian_kernel(size, sigma)[source]

Creates a 1D Gaussian kernel.

cyto.postprocessing.sparse_to_sparse.intensity_norm(df, channel='mean', suffix='norm', lower=0, upper=1)[source]

Calculate the normalized cell signal by user given lower and upper bounds and add it as a new column in the dataframe.

Parameters: - df: pandas DataFrame, containing the fluorescence intensity data. - channel: str, column name for normalization to take place. (default=mean) - suffix: str, suffix appending to the normalized channel output in format of {channel}_{suffix} (default=norm). - lower: float, lower bound value for min clipping range (default: 0) - upper: float, upper bound value for max clipping range (default: 1)

Returns: - df: pandas DataFrame, with a new column ‘{channel}_{suffix}’ containing the normalized signal.

cyto.postprocessing.sparse_to_sparse.intensity_norm_percentile(df, channel='mean', suffix='norm', percentile=1)[source]

Calculate the normalized cell signal by percentile clippings and add it as a new column in the dataframe.

Parameters: - df: pandas DataFrame, containing the fluorescence intensity data. - channel: str, column name for normalization to take place. (default=mean) - suffix: str, suffix appending to the normalized channel output in format of {channel}_{suffix} (default=norm). - percentile: float, percentile value for min/max range (default: 1)

Returns: - df: pandas DataFrame, with a new column ‘{channel}_{suffix}’ containing the normalized signal. - lp: float, the lower percentile value. - up: float, the upper percentile value.

cyto.postprocessing.sparse_to_sparse.left_table_merge(df1, df2, on=None)[source]

Perform a left merge between two DataFrames (pandas or Dask), keeping only unique columns and renaming overlapping columns.

Parameters:
  • df1 – pandas.DataFrame or dask.dataframe.DataFrame The left DataFrame.

  • df2 – pandas.DataFrame or dask.dataframe.DataFrame The right DataFrame.

  • on – list or str The column(s) to merge on.

Returns:

A DataFrame (pandas or Dask) resulting from the left merge.

cyto.postprocessing.sparse_to_sparse.model_func(x, a, b, c)[source]

A sample model function for fitting (e.g., a quadratic model).

class cyto.postprocessing.sparse_to_dense.KernelDensityEstimation(base_image=True, downscale_factor=1, gradient=False, verbose=True)[source]

Bases: object

Plots

cyto.postprocessing.plots.timeseries

Multi-frame statistical plots for cell network analysis.

All functions consume the all_results list produced by the spatiomics batch script (one dict per frame) and write figures to an output directory.

Time windows (early / mid / late) are defined by explicit absolute hour thresholds rather than implicit frame-count thirds, making analyses reproducible across datasets of different lengths.

No GPU dependencies — importable without pyclesperanto.

cyto.postprocessing.plots.timeseries.plot_centrality_boxplots_by_timepoint(all_results, output_dir, frame_interval_seconds, early_cutoff_h, mid_cutoff_h)[source]

Save box-and-whisker plots of centrality measures grouped by time period.

Mann-Whitney U significance bars are added between groups. One PNG and one SVG are written per cell type.

Parameters:
cyto.postprocessing.plots.timeseries.plot_centrality_histograms(all_results, output_dir, frame_interval_seconds, early_cutoff_h, mid_cutoff_h, n_bins=15)[source]

Save per-cell-type centrality histograms, stratified by time period.

One PNG and one SVG are written per cell type (<cell_type>_centrality_histograms.{png,svg}).

Parameters:
  • all_results (list of dict) – Frame-level results with keys 'frame' and 'centrality'.

  • output_dir (str or Path) – Directory to save figures.

  • frame_interval_seconds (float) – Physical duration of one frame in seconds (used for time conversion).

  • early_cutoff_h (float) – Absolute hour thresholds separating early / mid / late periods.

  • mid_cutoff_h (float) – Absolute hour thresholds separating early / mid / late periods.

  • n_bins (int, optional) – Number of histogram bins (default 15).

cyto.postprocessing.plots.timeseries.plot_clustering_boxplots_by_timepoint(all_results, output_dir, frame_interval_seconds, early_cutoff_h, mid_cutoff_h)[source]

Save box-and-whisker plots of clustering coefficients grouped by time period.

Parameters:
cyto.postprocessing.plots.timeseries.plot_clustering_histograms(all_results, output_dir, frame_interval_seconds, early_cutoff_h, mid_cutoff_h, n_bins=15)[source]

Save per-cell-type clustering-coefficient histograms by time period.

Parameters:
  • all_results (list of dict)

  • output_dir (str or Path)

  • frame_interval_seconds (float)

  • early_cutoff_h (float)

  • mid_cutoff_h (float)

  • n_bins (int, optional)

cyto.postprocessing.plots.timeseries.plot_contact_vs_time(all_results, output_dir, frame_interval_seconds, skip_frames=1)[source]

Save a two-panel figure: cross-cell contacts and cell counts vs time.

Parameters:
  • all_results (list of dict)

  • output_dir (str or Path)

  • frame_interval_seconds (float) – Physical duration of one frame before any subsampling.

  • skip_frames (int, optional) – Subsampling step used when processing frames (default 1).

cyto.postprocessing.plots.network

Single-frame network overlay visualisations for cell network analysis.

All functions operate on a single NetworkX graph (one frame, one cell type) and produce image-space overlays. Designed for interactive notebook use.

No GPU dependencies — importable without pyclesperanto.

cyto.postprocessing.plots.network.draw_network_with_clustering(G, ax, title, vmin, vmax)[source]

Draw a NetworkX graph coloured by per-node clustering coefficient.

Nodes are coloured on the plasma colormap from vmin to vmax. Edges are drawn in grey. A colorbar labelled “Clustering Coefficient” is added to the axes.

Parameters:
  • G (networkx.Graph) – Graph with a 'pos' node attribute giving (x, y) image coordinates.

  • ax (matplotlib.axes.Axes) – Target axes.

  • title (str) – Axes title.

  • vmin (float) – Colormap limits (use a shared range across subplots for comparability).

  • vmax (float) – Colormap limits (use a shared range across subplots for comparability).

cyto.postprocessing.plots.network.hex_to_rgb(hex_color)[source]

Convert a hex colour string to an (R, G, B) tuple in [0, 1] range.

Parameters:

hex_color (str) – Hex colour string, e.g. "#39FF14" or "39FF14".

Returns:

(R, G, B) each in [0, 1].

Return type:

tuple of float

cyto.postprocessing.plots.network.plot_network_centrality(G, centrality, title, ax, cmap=None, vmin=None, vmax=None)[source]

Draw a NetworkX graph coloured by an arbitrary centrality measure.

Parameters:
  • G (networkx.Graph) – Graph with a 'pos' node attribute.

  • centrality (dict) – Mapping of node → centrality value (output of any nx.*_centrality function).

  • title (str) – Axes title.

  • ax (matplotlib.axes.Axes) – Target axes.

  • cmap (matplotlib.colors.Colormap, optional) – Defaults to plt.cm.viridis.

  • vmin (float, optional) – Colormap limits.

  • vmax (float, optional) – Colormap limits.

cyto.postprocessing.plots.network.visualize_segmentations(image_stack1, seg_label1, title1, color_rgb1, image_stack2, seg_label2, title2, color_rgb2, tail=1)[source]

Plot two segmentation results side by side with boundary overlays.

Parameters:
  • image_stack1 (ndarray) – 2-D grayscale images for the first and second cell type.

  • image_stack2 (ndarray) – 2-D grayscale images for the first and second cell type.

  • seg_label1 (ndarray) – Corresponding integer label arrays.

  • seg_label2 (ndarray) – Corresponding integer label arrays.

  • title1 (str) – Subplot titles.

  • title2 (str) – Subplot titles.

  • color_rgb1 (array-like of float) – RGB colour (values in [0, 1]) used to tint each cell-type image.

  • color_rgb2 (array-like of float) – RGB colour (values in [0, 1]) used to tint each cell-type image.

  • tail (float, optional) – Percentile clipping for intensity rescaling (default 1).

Return type:

matplotlib.figure.Figure