1515app = typer .Typer (no_args_is_help = True , add_completion = False )
1616console = Console ()
1717
18+
1819@app .callback ()
1920def main () -> None :
2021 """LOPHOS — Allele-specific phasing of CTCF peaks & loops from phased HiChIP BAMs."""
2122
23+
2224@app .command ("phase" )
2325def phase (
2426 bam : Annotated [Path , typer .Option (exists = True , help = "Phased HiChIP BAM with RG tags" )],
@@ -27,13 +29,17 @@ def phase(
2729 out : Annotated [Path , typer .Option (help = "Output prefix (directory will be created)" )],
2830 mapq : Annotated [int , typer .Option (help = "Minimum MAPQ to count" )] = 30 ,
2931 peak_window : Annotated [int , typer .Option (help = "Peak summit +/- bp window" )] = 500 ,
30- anchor_pad : Annotated [int , typer .Option (help = "Anchor padding (bp) when matching mates" )] = 10_000 ,
32+ anchor_pad : Annotated [
33+ int , typer .Option (help = "Anchor padding (bp) when matching mates" )
34+ ] = 10_000 ,
3135 min_reads_peak : Annotated [int , typer .Option (help = "Min total reads to call a peak" )] = 5 ,
3236 min_pairs_loop : Annotated [int , typer .Option (help = "Min informative pairs to call a loop" )] = 3 ,
3337 fdr : Annotated [float , typer .Option (help = "BH-FDR threshold" )] = 0.05 ,
3438 keep_duplicates : Annotated [bool , typer .Option (help = "Keep PCR/optical duplicates" )] = False ,
3539 validate_loops : Annotated [str , typer .Option (help = "{none,local} (advanced later)" )] = "local" ,
36- config : Annotated [Path | None , typer .Option (help = "YAML config to override/record params" )] = None ,
40+ config : Annotated [
41+ Path | None , typer .Option (help = "YAML config to override/record params" )
42+ ] = None ,
3743) -> None :
3844 """Phase CTCF peaks and loops using a haplotype-tagged BAM."""
3945 if config :
@@ -51,16 +57,21 @@ def phase(
5157 bam = bam_handle , peaks = peaks_df , mapq = mapq , window_bp = peak_window , keep_dups = keep_duplicates
5258 )
5359 peak_stats = stats .compute_peak_stats (peak_counts )
54- peak_calls = calls .call_bias_for_peaks (peak_stats , thresholds = BiasThresholds (min_reads = min_reads_peak , fdr = fdr ))
60+ peak_calls = calls .call_bias_for_peaks (
61+ peak_stats , thresholds = BiasThresholds (min_reads = min_reads_peak , fdr = fdr )
62+ )
5563
5664 loop_counts = counts_loops .count_loops (
5765 bam = bam_handle , loops = loops_df , mapq = mapq , anchor_pad = anchor_pad , keep_dups = keep_duplicates
5866 )
5967 loop_stats = stats .compute_loop_stats (loop_counts )
60- loop_calls = calls .call_bias_for_loops (loop_stats , thresholds = BiasThresholds (min_reads = min_pairs_loop , fdr = fdr ))
68+ loop_calls = calls .call_bias_for_loops (
69+ loop_stats , thresholds = BiasThresholds (min_reads = min_pairs_loop , fdr = fdr )
70+ )
6171
6272 if validate_loops == "local" :
6373 from .core .validate_local import run_local_validation
74+
6475 loop_calls = run_local_validation (bam_handle , loops_df , loop_calls , anchor_pad , mapq )
6576
6677 writers .write_peaks (out .with_suffix (".peaks.bed" ), peak_calls )
0 commit comments