Coverage for src / optwps / utils.py: 91%

22 statements  

« prev     ^ index     » next       coverage.py v7.14.0, created at 2026-05-26 00:24 +0200

1""" 

2Utility functions for optwps package. 

3 

4This module provides helper functions for BAM file processing and file I/O operations. 

5""" 

6 

7_open = open 

8 

9import os 

10import sys 

11import gzip 

12 

13from contextlib import nullcontext 

14 

15 

16def is_soft_clipped(cigar): 

17 """ 

18 Check if a read has soft clipping in its CIGAR string. 

19 

20 Soft clipping (op=4) indicates that some bases at the start or end of the read 

21 are not aligned to the reference but are present in the sequence. 

22 

23 Args: 

24 cigar (list): CIGAR tuples from pysam AlignedSegment.cigartuples 

25 Each tuple is (operation, length) 

26 

27 Returns: 

28 bool: True if any soft clipping operation is present, False otherwise 

29 """ 

30 return any(op == 4 for op, _ in cigar) 

31 

32 

33def ref_aln_length(cigar): 

34 """ 

35 Calculate the length of alignment on the reference sequence from CIGAR. 

36 

37 Computes the total length consumed on the reference by summing lengths of 

38 operations that consume reference bases: M(0), D(2), N(3), =(7), X(8). 

39 

40 Args: 

41 cigar (list): CIGAR tuples from pysam AlignedSegment.cigartuples 

42 Each tuple is (operation, length) 

43 

44 Returns: 

45 int: Total length on reference sequence 

46 """ 

47 return sum(l for op, l in cigar if op in (0, 2, 3, 7, 8)) 

48 

49 

50def exopen(fil: str, mode: str = "r", *args, njobs=-1, **kwargs): 

51 """ 

52 Open a file with automatic gzip support and parallel compression. 

53 

54 This function wraps the standard open() function with automatic detection 

55 and handling of gzipped files. Also supports 

56 writing to stdout when fil='stdout'. 

57 

58 Args: 

59 fil (str): Path to the file to open, or 'stdout' for standard output 

60 mode (str, optional): File open mode ('r', 'w', 'rb', 'wb', etc.). 

61 Default: 'r' 

62 *args: Additional positional arguments passed to open function 

63 njobs (int, optional): Number of parallel jobs for gzip compression. 

64 If -1, uses all available CPU cores. Default: -1 

65 **kwargs: Additional keyword arguments passed to open function 

66 

67 Returns: 

68 file object: Opened file handle (stdout, standard file, or gzipped file) 

69 """ 

70 if njobs == -1: 

71 njobs = os.cpu_count() 

72 if fil == "stdout": 

73 assert "r" not in mode, "Cannot open stdout in read mode" 

74 return nullcontext(sys.stdout) 

75 if fil.endswith(".gz"): 

76 open_func = gzip.open 

77 try: 

78 return open_func( 

79 fil, mode + "t" if not mode.endswith("b") else mode, *args, **kwargs 

80 ) 

81 except BaseException: 

82 return open_func(fil, mode + "t" if not mode.endswith("b") else mode) 

83 

84 return _open(fil, mode, *args, **kwargs)