Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract the body of the main for loop in build_primer_pairs() into an alternative constructor on PrimerPair #85

Open
msto opened this issue Nov 13, 2024 · 0 comments
Assignees

Comments

@msto
Copy link
Collaborator

msto commented Nov 13, 2024

This would reduce the complexity of that function, make it easier for the user to write custom pairing functions, and make things easier to test.

with NtThermoAlign() as ntthal:
# generate all the primer pairs that don't violate hard size and Tm constraints
for lp in left_primers:
for rp in right_primers:
if rp.span.end - lp.span.start + 1 > amplicon_sizes.max:
continue
amp_mapping = Span(refname=target.refname, start=lp.span.start, end=rp.span.end)
amp_bases = bases[
amp_mapping.start - region_start : amp_mapping.end - region_start + 1
]
amp_tm = calculate_long_seq_tm(amp_bases)
if amp_tm < amplicon_tms.min or amp_tm > amplicon_tms.max:
continue
if max_heterodimer_tm is not None:
if ntthal.duplex_tm(lp.bases, rp.bases) > max_heterodimer_tm:
continue
penalty = score(
left_primer=lp,
right_primer=rp,
amplicon=amp_mapping,
amplicon_tm=amp_tm,
amplicon_sizes=amplicon_sizes,
amplicon_tms=amplicon_tms,
weights=weights,
)
pp = PrimerPair(
left_primer=lp,
right_primer=rp,
amplicon_sequence=amp_bases,
amplicon_tm=amp_tm,
penalty=penalty,
)
yield pp

e.g.

@classmethod
def from_primers(cls, left_primer: Oligo, right_primer: Oligo, ...) -> "PrimerPair"
    ...

and so the body becomes:

for left_primer, right_primer in itertools.product(left_primers, right_primers):
    pair = PrimerPair.from_primers(
        left_primer=left_primer, 
        right_primer=right_primer,
        ...
        )
        
    # Implement filtering in terms of PrimerPair attributes
    ...
    
    yield pair

The constructor could accept an optional Path or FastaFile from which to extract the amplicon sequence. The constructor could accept the various amplicon parameters and weights to compute the score internally, or simply have the score be provided as an argument.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants