diff --git a/prymer/offtarget/offtarget_detector.py b/prymer/offtarget/offtarget_detector.py index b446846..592eb30 100644 --- a/prymer/offtarget/offtarget_detector.py +++ b/prymer/offtarget/offtarget_detector.py @@ -104,6 +104,9 @@ ReferenceName: TypeAlias = str """Alias for a reference sequence name.""" +MINIMUM_THREE_PRIME_REGION_LENGTH: int = 8 +"""Minimum allowable seed length for the 3' region.""" + @dataclass(init=True, frozen=True) class OffTargetResult: @@ -189,6 +192,8 @@ def __init__( # noqa: C901 3. Checking of primer pairs: `max_primer_hits`, `min_primer_pair_hits`, `max_primer_pair_hits`, and `max_amplicon_size`. + The `three_prime_region_length` parameter is used as the seed length for `bwa aln`. + Args: ref: the reference genome fasta file (must be indexed with BWA) max_primer_hits: the maximum number of hits an individual primer can have in the genome @@ -204,8 +209,8 @@ def __init__( # noqa: C901 reference sequence, it may be appropriate to set this value to 0. Must be greater than or equal to 0. three_prime_region_length: the number of bases at the 3' end of the primer in which the - parameter `max_mismatches_in_three_prime_region` is evaluated. Must be greater than - 0. + parameter `max_mismatches_in_three_prime_region` is evaluated. This value is used as + the seed length (`bwa aln -l`). Must be a minimum of 8. max_mismatches_in_three_prime_region: the maximum number of mismatches that are tolerated in the three prime region of each primer defined by `three_prime_region_length`. Must be between 0 and `three_prime_region_length`, @@ -232,7 +237,7 @@ def __init__( # noqa: C901 ValueError: If `max_amplicon_size` is not greater than 0. ValueError: If any of `max_primer_hits`, `max_primer_pair_hits`, or `min_primer_pair_hits` are not greater than or equal to 0. - ValueError: If `three_prime_region_length` is not greater than 0. + ValueError: If `three_prime_region_length` is not greater than or equal to 8. ValueError: If `max_mismatches_in_three_prime_region` is outside the range 0 to `three_prime_region_length`, inclusive. ValueError: If `max_mismatches` is not greater than or equal to 0. @@ -256,10 +261,10 @@ def __init__( # noqa: C901 "'min_primer_pair_hits' must be greater than or equal to 0. " f"Saw {min_primer_pair_hits}" ) - if three_prime_region_length < 1: + if three_prime_region_length < MINIMUM_THREE_PRIME_REGION_LENGTH: errors.append( - "'three_prime_region_length' must be greater than 0. " - f"Saw {three_prime_region_length}" + "'three_prime_region_length' must be greater than or equal to " + f"{MINIMUM_THREE_PRIME_REGION_LENGTH}. Saw {three_prime_region_length}" ) if ( max_mismatches_in_three_prime_region < 0 diff --git a/tests/offtarget/test_offtarget.py b/tests/offtarget/test_offtarget.py index 6b08820..7cd3ae9 100644 --- a/tests/offtarget/test_offtarget.py +++ b/tests/offtarget/test_offtarget.py @@ -363,7 +363,7 @@ class CustomPrimer(Oligo): (-1, 1, 1, 20, 0, 0, 1, 0, 0, "'max_primer_hits' must be greater than or equal to 0. Saw -1"), # noqa: E501 (1, -1, 1, 20, 0, 0, 1, 0, 0, "'max_primer_pair_hits' must be greater than or equal to 0. Saw -1"), # noqa: E501 (1, 1, -1, 20, 0, 0, 1, 0, 0, "'min_primer_pair_hits' must be greater than or equal to 0. Saw -1"), # noqa: E501 - (1, 1, 1, 0, 0, 0, 1, 0, 0, "'three_prime_region_length' must be greater than 0. Saw 0"), + (1, 1, 1, 5, 0, 0, 1, 0, 0, "'three_prime_region_length' must be greater than or equal to 8. Saw 5"), # noqa: E501 (1, 1, 1, 20, -1, 0, 1, 0, 0, "'max_mismatches_in_three_prime_region' must be between 0 and 'three_prime_region_length'=20 inclusive. Saw -1"), # noqa: E501 (1, 1, 1, 20, 21, 0, 1, 0, 0, "'max_mismatches_in_three_prime_region' must be between 0 and 'three_prime_region_length'=20 inclusive. Saw 21"), # noqa: E501 (1, 1, 1, 20, 0, -1, 1, 0, 0, "'max_mismatches' must be greater than or equal to 0. Saw -1"), # noqa: E501