• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

broadinstitute / viral-core / 19193698996

08 Nov 2025 01:28PM UTC coverage: 68.273% (+2.5%) from 65.78%
19193698996

push

github

web-flow
Merge pull request #119 from broadinstitute/ct-swiftseq-demux-integration

Add demultiplexing of 3-barcode sheets with splitcode

1059 of 1372 new or added lines in 8 files covered. (77.19%)

8 existing lines in 1 file now uncovered.

3867 of 5664 relevant lines covered (68.27%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.29
/tools/splitcode.py
1
import logging
1✔
2
import shutil
1✔
3
import subprocess
1✔
4
import tools
1✔
5

6
TOOL_NAME = 'splitcode'
1✔
7

8
log = logging.getLogger(__name__)
1✔
9

10
class SplitCodeTool(tools.Tool):
1✔
11

12
    def __init__(self, install_methods=None):
1✔
13
        if install_methods is None:
1✔
14
            install_methods = [tools.PrexistingUnixCommand(shutil.which(TOOL_NAME), require_executability=True)]
1✔
15
        super(SplitCodeTool, self).__init__(install_methods=install_methods)
1✔
16

17
    def _get_tool_version(self):
1✔
NEW
18
        self.tool_version = subprocess.check_output([self.install_and_get_path(), '--version']).decode('UTF-8').strip()
×
19

20
    def execute(    self,
1✔
21
                    n_fastqs,
22
                    threads,
23
                    config_file,
24
                    keep_file,
25
                    unassigned_r1,
26
                    unassigned_r2,
27
                    summary_stats,
28
                    r1,
29
                    r2,
30
                    splitcode_opts=None,
31
                    gzip_output=False,
32
                    keep_r1_r2_suffixes=True,
33
                    predemux_r1_trim_5prime_num_bp=None,
34
                    predemux_r1_trim_3prime_num_bp=None,
35
                    predemux_r2_trim_5prime_num_bp=None,
36
                    predemux_r2_trim_3prime_num_bp=None
37
                ):
38
        """
39
        Execute the splitcode command with the provided parameters.
40

41
        :param n_fastqs: Number of FASTQ files (e.g., 2 for paired-end reads).
42
        :param threads: Number of threads to use.
43
        :param config_file: Path to the configuration file.
44
        :param keep_file: Path to the keep file.
45
        :param unassigned_r1: Path for unassigned R1 reads.
46
        :param unassigned_r2: Path for unassigned R2 reads.
47
        :param summary_stats: Path to the summary statistics file.
48
        :param r1: Input FASTQ file for R1 reads.
49
        :param r2: Input FASTQ file for R2 reads.
50
        :param splitcode_opts: additional parameters to pass to splitcode
51
        """
52
        splitcode_opts = splitcode_opts or []
1✔
53

54
        # documentation: 
55
        #   https://splitcode.readthedocs.io/en/latest/reference_guide.html#command-line-config-optional
56

57
        tool_cmd = [
1✔
58
            self.install_and_get_path(),
59
            f"--nFastqs={n_fastqs}",
60
            f"-t", str(threads),
61
            f"-c", config_file,
62
            f"--keep={keep_file}",
63
            f"--unassigned={unassigned_r1},{unassigned_r2}",
64
            f"--summary", summary_stats
65
        ]
66
        if gzip_output and "--gzip" not in splitcode_opts:
1✔
NEW
67
            tool_cmd.append("--gzip")
×
68
        if keep_r1_r2_suffixes and "--keep-r1-r2" not in splitcode_opts:
1✔
69
            tool_cmd.append("--keep-r1-r2")
1✔
70
        if predemux_r1_trim_3prime_num_bp or predemux_r2_trim_3prime_num_bp:
1✔
NEW
71
            r1_3prime_bp_to_remove = predemux_r1_trim_3prime_num_bp or 0
×
NEW
72
            r2_3prime_bp_to_remove = predemux_r2_trim_3prime_num_bp or 0
×
NEW
73
            tool_cmd.extend(["--trim-3",
×
74
                                f"{r1_3prime_bp_to_remove},{r2_3prime_bp_to_remove}"])
75
        if predemux_r1_trim_5prime_num_bp or predemux_r2_trim_5prime_num_bp:
1✔
NEW
76
            r1_5prime_bp_to_remove = predemux_r1_trim_5prime_num_bp or 0
×
NEW
77
            r2_5prime_bp_to_remove = predemux_r2_trim_5prime_num_bp or 0
×
NEW
78
            tool_cmd.extend(["--trim-5", 
×
79
                                f"{r1_5prime_bp_to_remove},{r2_5prime_bp_to_remove}"])
80

81
        tool_cmd.extend(splitcode_opts)
1✔
82
        tool_cmd.extend([r1,r2])
1✔
83

84
        log.debug('Running splitcode with command: %s', ' '.join(tool_cmd))
1✔
85
        try:
1✔
86
            return subprocess.check_call(tool_cmd)
1✔
NEW
87
        except subprocess.CalledProcessError as e:
×
NEW
88
            log.error(f'Splitcode failed with return code {e.returncode}')
×
NEW
89
            log.error(f'Command was: {" ".join(tool_cmd)}')
×
NEW
90
            raise
×
91

92
    def check_installation(self):
1✔
93
        """Ensure the tool is properly installed."""
NEW
94
        if not shutil.which(TOOL_NAME):
×
NEW
95
            raise FileNotFoundError(f"{TOOL_NAME} is not installed or not in PATH.")
×
96

97
    def run_splitcode(self, **kwargs):
1✔
98
        """
99
        Wrapper method to execute the splitcode command with named parameters.
100

101
        Expected kwargs:
102
        - n_fastqs, threads, config_file, keep_file, unassigned_r1, unassigned_r2, summary_stats, r1, r2
103
        """
NEW
104
        self.execute(
×
105
            kwargs.get('n_fastqs', 2),
106
            kwargs.get('threads', 1),
107
            kwargs['config_file'],
108
            kwargs['keep_file'],
109
            kwargs['unassigned_r1'],
110
            kwargs['unassigned_r2'],
111
            kwargs['summary_stats'],
112
            kwargs['r1'],
113
            kwargs['r2']
114
        )
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc