Skip to content

Commit

Permalink
Allow multiple AdapterCutters and ReverseComplementers in a pipeline
Browse files Browse the repository at this point in the history
Closes #777

Co-authored-by: Chang Y <[email protected]>
  • Loading branch information
marcelm and y9c committed Apr 23, 2024
1 parent ac5ccde commit 2be8d12
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/cutadapt/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,16 +177,28 @@ def _collect_modifier(self, m) -> None:
if isinstance(modifier, PolyATrimmer):
self.poly_a_trimmed_lengths[i] = modifier.trimmed_bases
elif isinstance(modifier, AdapterCutter):
assert self.with_adapters[i] is None
self.with_adapters[i] = modifier.with_adapters
self.adapter_stats[i] = list(modifier.adapter_statistics.values())
if self.with_adapters[i] is None:
self.with_adapters[i] = modifier.with_adapters
self.adapter_stats[i] = list(modifier.adapter_statistics.values())
else:
self.with_adapters[i] += modifier.with_adapters # type: ignore
self.adapter_stats[i] += list(modifier.adapter_statistics.values())
elif isinstance(modifier, ReverseComplementer):
assert self.with_adapters[i] is None
self.with_adapters[i] = modifier.adapter_cutter.with_adapters
self.adapter_stats[i] = list(
modifier.adapter_cutter.adapter_statistics.values()
)
self.reverse_complemented = modifier.reverse_complemented
if self.with_adapters[i] is None:
self.with_adapters[i] = modifier.adapter_cutter.with_adapters
self.adapter_stats[i] = list(
modifier.adapter_cutter.adapter_statistics.values()
)
self.reverse_complemented = modifier.reverse_complemented
else:
assert self.with_adapters[i] is not None
self.with_adapters[i] += modifier.adapter_cutter.with_adapters # type: ignore
self.adapter_stats[i] += list(
modifier.adapter_cutter.adapter_statistics.values()
)
self.reverse_complemented = add_if_not_none(
self.reverse_complemented, modifier.reverse_complemented
)

def as_json(self, gc_content: float = 0.5, one_line: bool = False) -> Dict:
"""
Expand Down
28 changes: 28 additions & 0 deletions tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,31 @@ def test_pipeline_paired(tmp_path, cores):
# - too many submodules (flatter namespace)
# - use xopen directly instead of file_opener;
# possibly with myxopen = functools.partial(xopen, ...)


def test_two_adapter_cutters_and_reverse_complementer(tmp_path):
from cutadapt.pipeline import SingleEndPipeline
from cutadapt.files import OutputFiles, InputPaths
from cutadapt.modifiers import AdapterCutter, ReverseComplementer
from cutadapt.adapters import BackAdapter

adapter = BackAdapter(sequence="GATCGGAAGA")
modifiers = [
AdapterCutter([adapter]),
AdapterCutter([adapter]),
ReverseComplementer(AdapterCutter([adapter])),
]
inpaths = InputPaths(datapath("small.fastq"))
with make_runner(inpaths, cores=1) as runner:
outfiles = OutputFiles(
proxied=False,
qualities=True,
interleaved=False,
)
steps = [SingleEndSink(outfiles.open_record_writer(tmp_path / "out.fastq"))]
pipeline = SingleEndPipeline(modifiers, steps)
stats = runner.run(pipeline, DummyProgress(), outfiles)
outfiles.close()

assert stats is not None
assert len(stats.as_json()["adapters_read1"]) == 3

0 comments on commit 2be8d12

Please sign in to comment.