Skip to content

Commit 0627add

Browse files
committed
main: Support input with ambiguous DNA codes by converting to N
1 parent c59fa66 commit 0627add

1 file changed

Lines changed: 15 additions & 1 deletion

File tree

src/geneml/main.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from concurrent.futures import ProcessPoolExecutor, as_completed
66

77
import enlighten
8+
from Bio.Data import IUPACData
89
from Bio.Seq import reverse_complement
910
from helperlibs.bio import seqio
1011

@@ -38,12 +39,16 @@
3839

3940
logger = logging.getLogger("geneml")
4041

42+
AMBIGUOUS_DNA_LETTERS = frozenset(IUPACData.ambiguous_dna_letters) - frozenset('ACGTN')
43+
AMBIGUOUS_DNA_TO_N = str.maketrans({base: 'N' for base in AMBIGUOUS_DNA_LETTERS})
44+
4145

4246
def parse_contigs(inpath: str, contigs_filter: list[str] | None) -> tuple[dict[str, str], int]:
4347
"""Parse and validate contig sequences from an input file.
4448
4549
Reads genome records, restricted to IDs in contigs_filter if provided.
46-
Sequences are converted to uppercase and validated to contain only valid nucleotide characters.
50+
Sequences are converted to uppercase, ambiguous IUPAC DNA codes are mapped to N,
51+
and the result is validated to contain only valid nucleotide characters.
4752
4853
Args:
4954
inpath: Path to an input sequence file in FASTA/GenBank/EMBL format
@@ -64,6 +69,15 @@ def parse_contigs(inpath: str, contigs_filter: list[str] | None) -> tuple[dict[s
6469
to_process.discard(record.id)
6570

6671
seq = str(record.seq).upper()
72+
ambiguous_dna_letters = sorted(set(seq) & AMBIGUOUS_DNA_LETTERS)
73+
if ambiguous_dna_letters:
74+
logger.warning(
75+
'Contig %s contains ambiguous DNA codes %s; converting them to N.',
76+
record.id,
77+
', '.join(ambiguous_dna_letters),
78+
)
79+
80+
seq = seq.translate(AMBIGUOUS_DNA_TO_N)
6781
# Check if sequence is valid
6882
if not seq:
6983
raise ValueError(f"Contig {record.id} has no sequence.")

0 commit comments

Comments
 (0)