Skip to content

Commit

Permalink
Version 4.2.2 bump
Browse files Browse the repository at this point in the history
  • Loading branch information
minknowbot committed Apr 27, 2021
1 parent 50955d3 commit 541d0e1
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 452 deletions.
366 changes: 3 additions & 363 deletions LICENSE.txt

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions proto/minknow_api/protocol.proto
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,12 @@ message BarcodeUserData {

// Indended to show that a result has not occured due to contamination.
no_template_control = 3;

// Separate positive controls for when kits expect 2.
positive_control_1 = 4;

// Separate positive controls for when kits expect 2.
positive_control_2 = 5;
}

// Barcode name the user data applies to, eg: "barcode02"
Expand Down
50 changes: 48 additions & 2 deletions python/examples/start_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ def parse_args():
help="IP address of the machine running MinKNOW (defaults to localhost)",
)
parser.add_argument(
"--port", help="Port to connect to on host (defaults to standard MinKNOW port)",
"--port",
help="Port to connect to on host (defaults to standard MinKNOW port based on tls setting)",
)
parser.add_argument(
"--no-tls", help="Disable tls connection", default=False, action="store_true"
)
parser.add_argument("--verbose", action="store_true", help="Enable debug logging")

Expand Down Expand Up @@ -182,6 +186,22 @@ def parse_args():
help="set the number of reads combined into one BAM file.",
)

# Read until
parser.add_argument(
"--read-until-reference", type=str, help="Reference file to use in read until",
)

parser.add_argument(
"--read-until-bed-file", type=str, help="Bed file to use in read until",
)

parser.add_argument(
"--read-until-filter",
type=str,
choices=["deplete", "enrich"],
help="Filter type to use in read until",
)

# Experiment
parser.add_argument(
"--experiment-duration",
Expand Down Expand Up @@ -213,6 +233,21 @@ def parse_args():
args = parser.parse_args()

# Further argument checks

# Read until must have a reference and a filter type, if enabled:
if (
args.read_until_filter is not None
or args.read_until_reference is not None
or args.read_until_bed_file is not None
):
if args.read_until_filter is None:
print("Unable to specify read until arguments without a filter type.")
sys.exit(1)

if args.read_until_reference is None:
print("Unable to specify read until arguments without a reference type.")
sys.exit(1)

if args.bed_file and not args.alignment_reference:
print("Unable to specify `--bed-file` without `--alignment-reference`.")
sys.exit(1)
Expand Down Expand Up @@ -265,7 +300,7 @@ def main():
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)

# Construct a manager using the host + port provided:
manager = Manager(host=args.host, port=args.port, use_tls=False)
manager = Manager(host=args.host, port=args.port, use_tls=not args.no_tls)

# Find which positions we are going to start protocol on:
positions = manager.flow_cell_positions()
Expand Down Expand Up @@ -370,6 +405,16 @@ def main():
alignment=alignment_args,
)

read_until_args = None
if args.read_until_filter:
read_until_args = protocols.ReadUntilArgs(
filter_type=args.read_until_filter,
reference_files=[args.read_until_reference],
bed_file=args.read_until_bed_file,
first_channel=None, # These default to all channels.
last_channel=None,
)

def build_output_arguments(args, name):
if not getattr(args, name):
return None
Expand All @@ -388,6 +433,7 @@ def build_output_arguments(args, name):
sample_id=args.sample_id,
experiment_group=args.experiment_group,
basecalling=basecalling_args,
read_until=read_until_args,
fastq_arguments=fastq_arguments,
fast5_arguments=fast5_arguments,
bam_arguments=bam_arguments,
Expand Down
2 changes: 1 addition & 1 deletion python/minknow_api/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = '4.1.5'
__version__ = '4.2.2'
164 changes: 86 additions & 78 deletions python/minknow_api/protocol_pb2.py

Large diffs are not rendered by default.

47 changes: 46 additions & 1 deletion python/minknow_api/tools/protocols.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ def find_protocol(
if tags["barcoding"].bool_value != barcoding:
if barcoding:
LOGGER.debug("Protocol does not support barcoding")
continue
else:
if basecalling:
LOGGER.warning("Not using barcoding for a barcoding kit")
LOGGER.debug("Protocol requires barcoding")
continue

supported_kits = tags["barcoding kits"].array_value
# workaround for the set of barcoding kits being returned as a string rather
Expand All @@ -108,6 +110,8 @@ def find_protocol(
supported_kits = (
tags["barcoding kits"].array_value[1:-1].replace('"', "").split(",")
)
if tags["barcoding"].bool_value:
supported_kits.append(tags["kit"].string_value)
if barcoding_kits and not set(barcoding_kits).issubset(supported_kits):
LOGGER.debug(
"barcoding kits specified %s not amongst those supported %s",
Expand Down Expand Up @@ -156,10 +160,27 @@ def find_protocol(
)
OutputArgs = collections.namedtuple("OutputArgs", ["reads_per_file"])

ReadUntilArgs = collections.namedtuple(
"ReadUntilArgs",
[
# "enrich", or "deplete"
"filter_type",
# List of reference files to pass to guppy for read until (only one file supported at the moment).
"reference_files",
# Bed file to pass to guppy for read until
"bed_file",
# First channel for read until to operate on.
"first_channel",
# Last channel for read until to operate on.
"last_channel",
],
)


def make_protocol_arguments(
experiment_duration: float = 72,
basecalling: BasecallingArgs = None,
read_until: ReadUntilArgs = None,
fastq_arguments: OutputArgs = None,
fast5_arguments: OutputArgs = None,
bam_arguments: OutputArgs = None,
Expand All @@ -175,6 +196,7 @@ def make_protocol_arguments(
Args:
experiment_duration(float): Length of the experiment in hours.
basecalling(:obj:`BasecallingArgs`): Arguments to control basecalling.
read_until(:obj:`ReadUntilArgs): Arguments to control read until.
fastq_arguments(:obj:`OutputArgs`): Control fastq file generation.
fast5_arguments(:obj:`OutputArgs`): Control fastq file generation.
bam_arguments(:obj:`OutputArgs`): Control bam file generation.
Expand Down Expand Up @@ -264,6 +286,29 @@ def on_off(value: bool):
)
protocol_args.extend(["--alignment"] + alignment_args)

if read_until:
read_until_args = []
if read_until.filter_type:
read_until_args.append("filter_type={}".format(read_until.filter_type))

if read_until.reference_files:
read_until_args.append(
"reference_files=['" + "','".join(read_until.reference_files) + "',]"
)

if read_until.bed_file:
read_until_args.append("bed_file='{}'".format(read_until.bed_file))

if read_until.first_channel:
read_until_args.append("first_channel={}".format(read_until.first_channel))

if read_until.last_channel:
read_until_args.append("last_channel={}".format(read_until.last_channel))

# --read_until filter_type='enrich' reference_files=['/data/my-alignment-file'] bed_file='/data/bed_file.bed' first_channel=1 last_channel=512
print(read_until_args)
protocol_args.extend(["--read_until"] + read_until_args)

protocol_args.append("--experiment_time={}".format(experiment_duration))
protocol_args.append("--fast5=" + on_off(fast5_arguments))
if fast5_arguments:
Expand Down
6 changes: 0 additions & 6 deletions python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,4 @@
packages=find_packages(),
install_requires=INSTALL_REQUIRES,
entry_points={"console_scripts": []},
classifiers=[
"Development Status :: 5 - Production/Stable",
"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
"Programming Language :: Python :: 3 :: Only",
"Topic :: Scientific/Engineering :: Bio-Informatics",
],
)
126 changes: 125 additions & 1 deletion python/test/example_tests/test_start_protocol.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,14 @@

def run_start_protocol_example(port, args):
p = subprocess.run(
[sys.executable, str(start_protocol_source), "--port", str(port), "--verbose"]
[
sys.executable,
str(start_protocol_source),
"--port",
str(port),
"--no-tls",
"--verbose",
]
+ args,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
Expand Down Expand Up @@ -680,3 +687,120 @@ def test_output_start_protocol():
"--active_channel_selection=on",
"--mux_scan_period=1.5",
]


def test_read_until_start_protocol():
"""Verify read until arguments work as expected."""

position_info = PositionInfo(position_name="MN00000")

with SequencingPositionTestServer(position_info) as sequencing_position:
test_positions = [
manager_pb2.FlowCellPosition(
name=position_info.position_name,
state=manager_pb2.FlowCellPosition.State.STATE_RUNNING,
rpc_ports=manager_pb2.FlowCellPosition.RpcPorts(
secure=0, insecure=sequencing_position.port
),
),
]

with ManagerTestServer(positions=test_positions) as server:
# Setup for experiment
test_flow_cell_id = "foo-bar-flow-cell"
sequencing_position.set_flow_cell_info(
FlowCellInfo(has_flow_cell=True, flow_cell_id=test_flow_cell_id)
)
sequencing_position.set_protocol_list([TEST_PROTOCOL])

# Running without filter type:
assert (
run_start_protocol_example(
server.port,
[
"--kit",
TEST_KIT_NAME,
"--position",
position_info.position_name,
"--read-until-reference",
"test.fasta",
"--read-until-bed-file",
"test.bed",
],
)[0]
!= 0
)

# Running without reference file:
assert (
run_start_protocol_example(
server.port,
[
"--kit",
TEST_KIT_NAME,
"--position",
position_info.position_name,
"--read-until-bed-file",
"test.bed",
"--read-until-filter",
"enrich",
],
)[0]
!= 0
)

# Incorrect filter type
assert (
run_start_protocol_example(
server.port,
[
"--kit",
TEST_KIT_NAME,
"--position",
position_info.position_name,
"--read-until-reference",
"test.fasta",
"--read-until-bed-file",
"test.bed",
"--read-until-filter",
"foo",
],
)[0]
!= 0
)

# Read until enabled
assert (
run_start_protocol_example(
server.port,
[
"--kit",
TEST_KIT_NAME,
"--position",
position_info.position_name,
"--read-until-reference",
"test.fasta",
"--read-until-bed-file",
"test.bed",
"--read-until-filter",
"deplete",
],
)[0]
== 0
)
assert len(sequencing_position.protocol_service.protocol_runs) == 1
protocol = sequencing_position.protocol_service.protocol_runs[-1]
assert protocol.identifier == TEST_PROTOCOL_IDENTIFIER
print(protocol.args)
assert protocol.args == [
"--read_until",
"filter_type=deplete",
"reference_files=['test.fasta',]",
"bed_file='test.bed'",
"--experiment_time=72",
"--fast5=off",
"--fastq=off",
"--bam=off",
"--active_channel_selection=on",
"--mux_scan_period=1.5",
]

0 comments on commit 541d0e1

Please sign in to comment.