uchrom.strc.tad

class uchrom.strc.tad.FISHnetParams(thresholds: ndarray | None = None, threshold_step: float | None = None, threshold_min: float | None = None, threshold_max: float | None = None, plateau_size: int = 4, window_size: int = 2, size_exclusion: int = 3, merge_tol: int = 3, n_louvain_runs: int = 20, resolution: float = 1.0, min_coverage: float = 0.6, max_thresholds: int = 200, impute: bool = True)[source]

Bases: object

Runtime parameters for call_domains_fishnet_trace().

Defaults follow Patel et al. 2025.

impute: bool = True
max_thresholds: int = 200
merge_tol: int = 3
min_coverage: float = 0.6
n_louvain_runs: int = 20
plateau_size: int = 4
resolution: float = 1.0
size_exclusion: int = 3
threshold_max: float | None = None
threshold_min: float | None = None
threshold_step: float | None = None
thresholds: ndarray | None = None
window_size: int = 2
class uchrom.strc.tad.TADCallerParams(window_bp: float = 100000.0, fdr_cutoff: float = 0.1, hierarchical: bool = True, max_levels: int = 4, prominence: float = 0.0, distance: int = 1, k_sigma: float = 4.0, frac: float = 0.1)[source]

Bases: object

Runtime parameters for call_tads_by_pval().

Defaults follow ArcFISH’s TADCaller(method='pval').

distance: int = 1
fdr_cutoff: float = 0.1
frac: float = 0.1
hierarchical: bool = True
k_sigma: float = 4.0
max_levels: int = 4
prominence: float = 0.0
window_bp: float = 100000.0
uchrom.strc.tad.calc_directionality_index(contact_mat, window=50, device='auto')[source]

Calculate Directionality Index for each genomic bin.

uchrom.strc.tad.call_domains_fishnet(cd, chrom: str, params: FISHnetParams | None = None, store: bool = True, result_key: str = 'fishnet_domains', ensemble_key: str = 'fishnet_ensemble', verbose: bool = False, max_traces: int | None = None) DataFrame[source]

Run FISHnet on every trace of chrom in cd.

Parameters:
  • cd (ChromData)

  • chrom (str)

  • params (FISHnetParams, optional)

  • store (bool) – If True, write results to cd.results[result_key] and the ensemble domain mask to cd.results[ensemble_key].

  • max_traces (int, optional) – Hard cap on the number of traces processed (useful for quick previews — FISHnet is O(n_bins² · n_thresholds) per trace).

Returns:

chrom, trace_id, domain_idx, start, end, start_bin, end_bin.

Return type:

DataFrame with one row per (trace, domain)

uchrom.strc.tad.call_domains_fishnet_trace(dist: ndarray, params: FISHnetParams | None = None, seed_base: int = 0) dict[source]

Run FISHnet on a single-allele pairwise distance matrix.

Parameters:
  • dist (ndarray (n_bins, n_bins)) – Symmetric pairwise distance matrix, NaN for missing spots, in nm.

  • params (FISHnetParams, optional) – Hyperparameters. Use defaults if None.

  • seed_base (int) – Base seed for the 20 Louvain runs (reproducibility).

Returns:

domains : list of (start, end_exclusive) bin indices per plateau boundaries : sorted list of canonical boundary bin indices domain_mask : (n_bins, n_bins) int — count of plateaus in which

bins i and j fall in the same domain (0 if never).

n_plateaus : number of plateaus detected coverage : fraction of bins with ≥1 non-NaN distance

Return type:

dict with keys

uchrom.strc.tad.call_tads_by_pval(cd, chrom: str, params: TADCallerParams | None = None, device: str = 'auto', store: bool = True, result_key: str = 'tads', verbose: bool = False) DataFrame[source]

ArcFISH-style TAD caller on a single chromosome.

Returns a DataFrame of called TADs; stores it in cd.results[result_key] when store=True. Columns: chrom, start, end, level, score, pval, fdr. Level 1 is the top-level TAD partition; higher levels are nested children when params.hierarchical=True.

uchrom.strc.tad.detect_tad_boundaries(di, min_size_frac=0.05)[source]

Detect TAD boundaries from sign changes (negative -> positive).

uchrom.strc.tad.get_domains(contact_mat, smoothing_param=0.1, min_size_frac=0.05, window=50, device='auto')[source]

Identify TADs: DI calculation -> smoothing -> boundary detection.

uchrom.strc.tad.load_tad_from_bed(bed_path)[source]

Load TAD regions from BED file.

uchrom.strc.tad.substructures_from_tads(tad_indices, structure_coords)[source]

Extract substructures based on TAD boundaries.

FISHnet (per-allele, graph-theory)

class uchrom.strc.tad.fishnet.FISHnetParams(thresholds: ndarray | None = None, threshold_step: float | None = None, threshold_min: float | None = None, threshold_max: float | None = None, plateau_size: int = 4, window_size: int = 2, size_exclusion: int = 3, merge_tol: int = 3, n_louvain_runs: int = 20, resolution: float = 1.0, min_coverage: float = 0.6, max_thresholds: int = 200, impute: bool = True)[source]

Bases: object

Runtime parameters for call_domains_fishnet_trace().

Defaults follow Patel et al. 2025.

impute: bool = True
max_thresholds: int = 200
merge_tol: int = 3
min_coverage: float = 0.6
n_louvain_runs: int = 20
plateau_size: int = 4
resolution: float = 1.0
size_exclusion: int = 3
threshold_max: float | None = None
threshold_min: float | None = None
threshold_step: float | None = None
thresholds: ndarray | None = None
window_size: int = 2
uchrom.strc.tad.fishnet.call_domains_fishnet(cd, chrom: str, params: FISHnetParams | None = None, store: bool = True, result_key: str = 'fishnet_domains', ensemble_key: str = 'fishnet_ensemble', verbose: bool = False, max_traces: int | None = None) DataFrame[source]

Run FISHnet on every trace of chrom in cd.

Parameters:
  • cd (ChromData)

  • chrom (str)

  • params (FISHnetParams, optional)

  • store (bool) – If True, write results to cd.results[result_key] and the ensemble domain mask to cd.results[ensemble_key].

  • max_traces (int, optional) – Hard cap on the number of traces processed (useful for quick previews — FISHnet is O(n_bins² · n_thresholds) per trace).

Returns:

chrom, trace_id, domain_idx, start, end, start_bin, end_bin.

Return type:

DataFrame with one row per (trace, domain)

uchrom.strc.tad.fishnet.call_domains_fishnet_trace(dist: ndarray, params: FISHnetParams | None = None, seed_base: int = 0) dict[source]

Run FISHnet on a single-allele pairwise distance matrix.

Parameters:
  • dist (ndarray (n_bins, n_bins)) – Symmetric pairwise distance matrix, NaN for missing spots, in nm.

  • params (FISHnetParams, optional) – Hyperparameters. Use defaults if None.

  • seed_base (int) – Base seed for the 20 Louvain runs (reproducibility).

Returns:

domains : list of (start, end_exclusive) bin indices per plateau boundaries : sorted list of canonical boundary bin indices domain_mask : (n_bins, n_bins) int — count of plateaus in which

bins i and j fall in the same domain (0 if never).

n_plateaus : number of plateaus detected coverage : fraction of bins with ≥1 non-NaN distance

Return type:

dict with keys

F-test caller

class uchrom.strc.tad.arc_pval.TADCallerParams(window_bp: float = 100000.0, fdr_cutoff: float = 0.1, hierarchical: bool = True, max_levels: int = 4, prominence: float = 0.0, distance: int = 1, k_sigma: float = 4.0, frac: float = 0.1)[source]

Bases: object

Runtime parameters for call_tads_by_pval().

Defaults follow ArcFISH’s TADCaller(method='pval').

distance: int = 1
fdr_cutoff: float = 0.1
frac: float = 0.1
hierarchical: bool = True
k_sigma: float = 4.0
max_levels: int = 4
prominence: float = 0.0
window_bp: float = 100000.0
uchrom.strc.tad.arc_pval.call_tads_by_pval(cd, chrom: str, params: TADCallerParams | None = None, device: str = 'auto', store: bool = True, result_key: str = 'tads', verbose: bool = False) DataFrame[source]

ArcFISH-style TAD caller on a single chromosome.

Returns a DataFrame of called TADs; stores it in cd.results[result_key] when store=True. Columns: chrom, start, end, level, score, pval, fdr. Level 1 is the top-level TAD partition; higher levels are nested children when params.hierarchical=True.

Directionality index

uchrom.strc.tad.di.calc_di_batch(contact_mat, window=50, device='auto')[source]

Batch-optimized DI calculation using matrix operations.

uchrom.strc.tad.di.calc_directionality_index(contact_mat, window=50, device='auto')[source]

Calculate Directionality Index for each genomic bin.

uchrom.strc.tad.di.detect_tad_boundaries(di, min_size_frac=0.05)[source]

Detect TAD boundaries from sign changes (negative -> positive).

uchrom.strc.tad.di.get_device(device='auto')[source]

Get appropriate torch device.

uchrom.strc.tad.di.get_domains(contact_mat, smoothing_param=0.1, min_size_frac=0.05, window=50, device='auto')[source]

Identify TADs: DI calculation -> smoothing -> boundary detection.

uchrom.strc.tad.di.get_dtype(device)[source]

MPS only supports float32.

uchrom.strc.tad.di.smooth_with_moving_average(signal, window_size)[source]

Apply moving average smoothing via 1D convolution.

uchrom.strc.tad.utils.load_tad_from_bed(bed_path)[source]

Load TAD regions from BED file.

uchrom.strc.tad.utils.merge_substructures(substructures, tad_indices, total_bins)[source]

Merge TAD substructures back into full structure.

uchrom.strc.tad.utils.save_tads_to_bed(tad_indices, bins_df, output_path)[source]

Save detected TAD regions to BED file.

uchrom.strc.tad.utils.substructures_from_tads(tad_indices, structure_coords)[source]

Extract substructures based on TAD boundaries.

uchrom.strc.tad.utils.tad_regions_to_bin_indices(regions, bins_df, chrom=None)[source]

Convert TAD genomic regions to bin indices.