gunz_cm.preprocs.matrices#

Module contents#

Re-export the contact selection primitives for the matrices subpackage.

gunz_cm.preprocs.matrices.filter_bimodal_outliers(df: DataFrame, points: ndarray, raw_threshold: int = 2, dist_factor: float = 2.0, k_band: int = 50, mask: numpy.ndarray | None = None, pooled_points: numpy.ndarray | None = None) dict[str, Any][source]#

Identify bimodal outlier contacts: low raw count AND high predicted distance.

A contact (i, j) is a “bimodal outlier” if both conditions hold:

  1. hic_raw_count[i, j] < raw_threshold (likely PCR / sequencing noise)

  2. predicted_distance[i, j] > dist_factor * local_median_distance (the structure says the two loci are far apart, contradicting the absence of a Hi-C signal — i.e., the contact is at once low-confidence in Hi-C and rejected by the structure).

Such contacts carry no useful rank signal for Spearman correlation: the structure’s “far apart” is not contradicting high-confidence Hi-C (because there is no high-confidence Hi-C), so the only thing they contribute is noise that deflates the global Spearman.

Parameters:
  • df (pd.DataFrame) – Must contain columns ['row_ids', 'col_ids', 'raw_counts'] — typically the output of load_cm_data(return_raw_counts=True). row_ids and col_ids are bin indices in [0, N-1].

  • points (np.ndarray) – (N, 3) 3D coordinates of the structure under evaluation. Pairwise Euclidean distance is computed only for these points and must align with df row/col ids.

  • raw_threshold (int) – Contacts with raw_counts strictly less than this value are noise candidates. Default 2 drops 0-count and 1-count contacts.

  • dist_factor (float) – Multiplier on the local median distance at each genomic distance s. A contact at genomic distance s whose predicted 3D distance exceeds dist_factor * median_at_s is an outlier. Default 2.0.

  • k_band (int) – Maximum genomic distance (in bins) considered. Contacts beyond k_band are not classified — they are returned as kept by default. Default 50 (covers roughly 100 kb to 2.5 Mb at 10 kb resolution).

  • mask (np.ndarray | None) – Optional (N,) boolean mask of valid bins. Invalid bins are excluded from the distance matrix used for the per-structure median curve.

  • pooled_points (np.ndarray | None) – Optional (N, 3) reference structure used to compute the local median distance curve. If None, points is used. Useful when comparing structures of different complexity (e.g., smooth naive vs. wiggly real) so the median is derived from a common reference (e.g., 25 kb Golden).

Returns:

keep_masknp.ndarray of bool, length n_total_in_band

True for contacts that pass the filter (NOT outliers).

is_outliernp.ndarray of bool, same length as

keep_mask; True for contacts that ARE outliers.

raw_countsnp.ndarray

Raw counts of the contacts in the band.

predicted_distancesnp.ndarray

Predicted 3D distances for the contacts in the band.

genomic_distancesnp.ndarray

Genomic distances (in bins) for the contacts in the band.

median_dist_curvedict[int, float]

Median predicted distance per genomic distance s from 1 to k_band. Genomic distances with no pairs are omitted.

n_totalint

Total contacts in the band.

n_outliersint

Number of outliers removed.

n_keptint

Number of contacts kept.

raw_thresholdint

Echo of the parameter for downstream auditability.

dist_factorfloat

Echo of the parameter for downstream auditability.

Return type:

dict

Raises:

PreprocError – If raw_counts is missing from df, or if any of raw_threshold < 1, k_band < 1, dist_factor < 1.0, or points.ndim != 2 / shape[1] != 3.

gunz_cm.preprocs.matrices.naive_predicted_contacts(p_naive: ndarray, alpha: float, k_band: int = 100) ndarray[source]#

Compute naive baseline’s predicted Hi-C contact matrix from structure.

Uses a power-law of pairwise Euclidean distance: C_pred(i,j) = d(i,j) ** -alpha where d is the Euclidean distance between p_naive[i] and p_naive[j]. Only pairs within k_band genomic-distance bins are populated; everything beyond the band is zeroed, and the main diagonal is zeroed as well.

Parameters:
  • p_naive (np.ndarray) – Naive baseline structure of shape (N, 3).

  • alpha (float) – Power-law exponent (typical: 0.6 to 0.9 for chromatin).

  • k_band (int) – Max genomic distance in bins. Pairs beyond this band get value 0.

Returns:

Dense (N, N) symmetric array with the band populated; outside band = 0; diagonal = 0.

Return type:

np.ndarray

gunz_cm.preprocs.matrices.select_informative_contacts(hic_dense: ndarray, p_naive: ndarray, threshold_quantile: float = 0.5, k_band: int = 100, alpha: float | None = None) ndarray[source]#

Return boolean mask of contacts where naive diverges from Hi-C.

For each (i, j) pair in the upper-triangular band of width k_band:

  • d_naive[i, j] = ||p_naive[i] - p_naive[j]||

  • hic_pred[i, j] = d_naive[i, j] ** -alpha if alpha is given, otherwise hic_pred[i, j] = hic_dense[i, j] (skip prediction).

  • residual[i, j] = |hic_dense[i, j] - hic_pred[i, j]|

Returns a boolean mask where the residual exceeds the threshold_quantile-quantile of all residuals in the band. Default 0.5 selects the upper half by residual.

Parameters:
  • hic_dense (np.ndarray) – Square Hi-C matrix of shape (N, N).

  • p_naive (np.ndarray) – Naive baseline structure of shape (N, 3).

  • threshold_quantile (float) – Quantile in [0, 1]. Higher = more selective.

  • k_band (int) – Max genomic distance in bins.

  • alpha (float | None) – If given, predict naive Hi-C via power law; else use hic_dense directly so the residual is zero and the mask is all-False.

Returns:

Boolean (N, N) array. True for “informative” contacts.

Return type:

np.ndarray