1010from concurrent .futures import ThreadPoolExecutor , as_completed
1111from itertools import zip_longest
1212from pathlib import Path
13- import shutil
14- from typing import Any , Dict , Iterable , List , Optional , Tuple , Union , TYPE_CHECKING
13+ from typing import TYPE_CHECKING , Any , Dict , Iterable , List , Optional , Tuple , Union
1514
1615import numpy as np
1716from tqdm import tqdm
@@ -76,9 +75,10 @@ def _resolve_samtools_backend(backend: str | None) -> str:
7675
7776def _has_bam_index (bam_path : Path ) -> bool :
7877 """Return True if the BAM index exists alongside the BAM."""
79- return bam_path .with_suffix (bam_path .suffix + ".bai" ).exists () or Path (
80- str (bam_path ) + ".bai"
81- ).exists ()
78+ return (
79+ bam_path .with_suffix (bam_path .suffix + ".bai" ).exists ()
80+ or Path (str (bam_path ) + ".bai" ).exists ()
81+ )
8282
8383
8484def _ensure_bam_index (bam_path : Path , backend : str ) -> None :
@@ -215,9 +215,7 @@ def _index_bam_with_pysam(bam_path: Union[str, Path], threads: Optional[int] = N
215215 pysam_mod .index (bam_path )
216216
217217
218- def _bam_to_fastq_with_samtools (
219- bam_path : Union [str , Path ], fastq_path : Union [str , Path ]
220- ) -> None :
218+ def _bam_to_fastq_with_samtools (bam_path : Union [str , Path ], fastq_path : Union [str , Path ]) -> None :
221219 """Convert BAM to FASTQ using samtools."""
222220 if not shutil .which ("samtools" ):
223221 raise RuntimeError ("samtools is required but not available in PATH." )
@@ -881,7 +879,8 @@ def _to_path_pair(x) -> Tuple[Path, Path]:
881879 rg_fields = [f"ID:{ bc } " ]
882880 if rg_sample_field :
883881 rg_fields .append (f"SM:{ rg_sample_field } " )
884- header_lines .append (f"@RG\t { '\t ' .join (rg_fields )} " )
882+ rg_body = "\t " .join (rg_fields )
883+ header_lines .append (f"@RG\t { rg_body } " )
885884 header_lines .append ("@PG\t ID:concat-fastq\t PN:concatenate_fastqs_to_bam\t VN:1" )
886885 bam_out_ctx .stdin .write ("\n " .join (header_lines ) + "\n " )
887886
@@ -917,7 +916,9 @@ def _clean(n: Optional[str]) -> Optional[str]:
917916 )
918917 if name is None :
919918 name = (
920- _clean (getattr (rec2 , "name" , None ) if backend_choice == "python" else rec2 [0 ])
919+ _clean (
920+ getattr (rec2 , "name" , None ) if backend_choice == "python" else rec2 [0 ]
921+ )
921922 if rec2 is not None
922923 else None
923924 )
@@ -1354,9 +1355,10 @@ def extract_readnames_from_bam(aligned_BAM, samtools_backend: str | None = "auto
13541355
13551356 if backend_choice == "python" :
13561357 pysam_mod = _require_pysam ()
1357- with pysam_mod .AlignmentFile (aligned_BAM , "rb" ) as bam , open (
1358- txt_output , "w" , encoding = "utf-8"
1359- ) as output_file :
1358+ with (
1359+ pysam_mod .AlignmentFile (aligned_BAM , "rb" ) as bam ,
1360+ open (txt_output , "w" , encoding = "utf-8" ) as output_file ,
1361+ ):
13601362 for read in bam :
13611363 output_file .write (f"{ read .query_name } \n " )
13621364 return
@@ -1370,7 +1372,7 @@ def extract_readnames_from_bam(aligned_BAM, samtools_backend: str | None = "auto
13701372 if not line .strip ():
13711373 continue
13721374 qname = line .split ("\t " , 1 )[0 ]
1373- output_file .write (f"{ qname } \n " )
1375+ output_file .write (f"{ qname } \n " )
13741376 rc = samtools_view .wait ()
13751377 if rc != 0 :
13761378 stderr = samtools_view .stderr .read () if samtools_view .stderr else ""
0 commit comments