utils.visualize#

Saliency visualization utilities for BRIDGE models.

This module provides:
  1. inference(…): batched model inference that returns sigmoid probabilities.

  2. PWM/logo rendering utilities (normalize_pwm, get_nt_height, seq_logo):

    • Convert a 4xL PWM (A/C/G/U) into an RGB logo image by stacking pre-rendered nucleotide glyphs with per-position heights.

  3. plot_saliency(…): end-to-end saliency plotting that combines:

    • saliency logo (normalized saliency PWM -> logo)

    • saliency heatmap (raw weights resized to a fixed canvas)

    • raw sequence logo

    • optional structure saliency track + structure trace overlay

Expected inputs#

Xnp.ndarray
Input feature matrix with shape:
  • sequence-only mode: (4, L)

  • sequence+structure mode: (>=5, L) where X[4, :] is per-position structure score (typically in [0, 1], with higher = more “pairedness”/signal depending on upstream).

Padding positions are represented by all zeros across X[:4, pos]. The plotting code automatically removes such padded columns.

Wnp.ndarray

Saliency/importance weights aligned to X. Must have at least the first 4 rows corresponding to nucleotide channels (A/C/G/U or A/C/G/T treated as U). Shape should match X for the plotted channels, typically (4, L) or (>=5, L).

str_nullnp.ndarray, optional

Mask marking “null” structure positions (e.g., regions without valid structure scores). Required when X has a structure row (X.shape[0] > 4). The plotting code uses str_null.T == 1 to select null positions, so the input should be shaped/broadcastable accordingly.

External assets & dependencies#

  • ./acgu.npz is required by seq_logo(…). It must contain an array under key ‘data’ with 4 RGB glyph images (A,C,G,U) that can be indexed by nucleotide channel index. Glyphs are resized per position with skimage.

  • skimage.transform.resize is used for resizing glyphs and heatmaps.

Output#

plot_saliency(…) saves a single PNG image to outdir, but note:
  • Despite the name, outdir is treated as a file path in the current implementation (e.g., “results/foo.png”), not a directory.

Backend note#

The script sets mpl.use(“pdf”) but saves figures as PNG via fig.savefig(…, format=”png”). For headless servers, a more typical choice is mpl.use(“Agg”). The current behavior is preserved for compatibility.

Common pitfalls#

  • If acgu.npz is missing or malformed, seq_logo will fail at load time.

  • If X/W include negative values, information-content scaling in get_nt_height is not strictly meaningful unless norm == 1 (fixed-height mode).

Functions

get_nt_height(pwm, height, norm)

Convert PWM columns into integer per-nucleotide heights for logo plotting.

inference(args, model, device, test_loader)

Run model inference on a DataLoader and return sigmoid probabilities.

normalize_pwm(pwm[, factor, MAX])

Normalize a position weight matrix (PWM) for visualization.

plot_saliency(X, W[, nt_width, norm_factor, ...])

Plot a saliency visualization combining sequence logo and saliency heatmaps.

seq_logo(pwm[, height, nt_width, norm, ...])

Render a sequence/logo image from a PWM as an RGB NumPy array.

utils.visualize.inference(args, model, device, test_loader)[source]#

Run model inference on a DataLoader and return sigmoid probabilities.

This function:
  1. switches the model to eval mode,

  2. disables gradient computation,

  3. iterates over test_loader,

  4. applies torch.sigmoid to model outputs (assumes logits),

  5. concatenates all batches into a single NumPy array on CPU.

Parameters:
  • args – Unused in the current implementation. Kept for API compatibility with other training/inference entry points.

  • model (torch.nn.Module) – A PyTorch model that maps inputs x to logits of shape (B, …) compatible with torch.sigmoid.

  • device (torch.device) – Device where inference runs (e.g., torch.device(“cuda”) or “cpu”).

  • test_loader (torch.utils.data.DataLoader) – DataLoader that yields batches of (x0, y0). Labels y0 are moved to device but are not used in computing the returned probabilities.

Returns:

np.ndarray – Concatenated probabilities for all samples, with shape matching the model output after sigmoid. For a binary classifier that outputs (B, 1), the return shape is (N, 1).

Notes

  • The labels are read and moved to device but are not used; this is typical for evaluation pipelines that only need predicted probabilities.

  • If the model output is multi-dimensional (e.g., (B, C)), the returned array will preserve that shape.

utils.visualize.normalize_pwm(pwm, factor=None, MAX=None)[source]#

Normalize a position weight matrix (PWM) for visualization.

The function first scales pwm by the maximum absolute value, optionally applies an exponential sharpening (exp(pwm * factor)), and then normalizes each column by the L1 norm (sum of absolute values across nucleotides).

Parameters:
  • pwm (np.ndarray) – Numeric array of shape (num_nt, num_positions). Typically num_nt=4 for A/C/G/U(T).

  • factor (float, optional) – If provided, apply np.exp(pwm * factor) after scaling. This is often used to increase contrast.

  • MAX (float, optional) – If provided, use this value as the divisor instead of max(abs(pwm)). This can be used to enforce consistent scaling across multiple PWMs.

Returns:

np.ndarray – Normalized PWM of the same shape as input.

Notes

  • Column-wise normalization uses sum(abs(pwm[:, i])). If a column is all zeros, this will divide by zero and produce inf/nan. Ensure input columns have non-zero mass or handle zeros upstream.

  • The normalization uses absolute values, which allows negative entries but normalizes by their magnitude.

utils.visualize.get_nt_height(pwm, height, norm)[source]#

Convert PWM columns into integer per-nucleotide heights for logo plotting.

This computes per-position total height and allocates integer heights to each nucleotide proportional to pwm[:, i].

Parameters:
  • pwm (np.ndarray) – PWM array of shape (num_nt, num_positions). Typically 4 x L. Values are treated as probabilities or non-negative weights when computing entropy.

  • height (int | float) – Base height scaling factor used in the logo renderer.

  • norm (int) – Controls whether to use a fixed total height per position. - If norm == 1, the total height per position is set to height. - Otherwise, the total height is scaled by information content:

    (log2(num_nt) - entropy(pwm[:, i])) * height.

Returns:

np.ndarray – Integer heights of shape (num_nt, num_positions), dtype int. Heights are computed with np.floor(…).

Notes

  • Entropy is computed only over entries > 0.

  • The final per-position total height is clipped by min(total_height, height*2).

  • If pwm contains negative values, the entropy/information-content interpretation is not strictly valid; this function assumes non-negative columns for that mode.

Render a sequence/logo image from a PWM as an RGB NumPy array.

This is a low-level renderer that stacks resized nucleotide glyph images according to per-position heights computed from the PWM.

Parameters:
  • pwm (np.ndarray) – PWM array of shape (num_nt, num_positions). Commonly (4, L).

  • height (int, optional) – Base height used by the renderer. The internal canvas height is height*2.

  • nt_width (int, optional) – Width in pixels allocated per position.

  • norm (int, optional) – Passed to get_nt_height. If 1, uses fixed height per position; otherwise uses information-content scaling.

  • alphabet (str, optional) – Currently unused. Present for API compatibility (e.g., “rna” vs “dna”).

  • colormap (str, optional) – Currently unused. Present for API compatibility.

Returns:

np.ndarray – RGB image of shape (height*2, ceil(nt_width * num_positions), 3), dtype uint8.

Notes

  • This function expects an acgu.npz file at ./acgu.npz containing nucleotide glyphs under the key ‘data’. The glyph array is expected to be indexable by nucleotide index.

utils.visualize.plot_saliency(X, W, nt_width=100, norm_factor=3, str_null=None, outdir='results/')[source]#

Plot a saliency visualization combining sequence logo and saliency heatmaps.

This function creates a multi-row figure that typically includes:
  • saliency logo (logo built from normalized saliency PWM)

  • saliency heatmap (resized raw weights)

  • raw sequence logo

  • (optional) structure saliency heatmap + structure trace (if X includes structure)

Parameters:
  • X (np.ndarray) – Input features array. Expected shape depends on mode: - Sequence-only mode: shape (4, L) where rows correspond to A/C/G/U(T). - Sequence+structure mode: shape (>=5, L) where X[4, :] stores per-position structure scores. Padding positions are expected to be all zeros across X[:4, :].

  • W (np.ndarray) – Saliency/importance weights aligned to X. Expected shape matches X (at least first 4 rows).

  • nt_width (int, optional) – Pixel width per nucleotide position in rendered images.

  • norm_factor (float, optional) – Sharpening factor passed to normalize_pwm(…, factor=norm_factor) for saliency logo.

  • str_null (np.ndarray, optional) – Mask for null structure positions. Required if X.shape[0] > 4. Expected to be broadcastable such that str_null.T == 1 selects null positions.

  • outdir (str, optional) – Output filepath used by fig.savefig. Despite the name, this argument is treated as a file path in the current implementation.

Returns:

None – The figure is saved to disk and all matplotlib figures are closed.