Files
PlantAI-rag-new/bioflow_kernel/scripts/get_meme_pos.py
T

86 lines
2.9 KiB
Python
Executable File

#!/usr/bin/env python3
import re
import sys
import xml.etree.ElementTree as ET
from pathlib import Path
def site_sequence(site):
return "".join(ref.get("letter_id", "") for ref in site.findall("letter_ref"))
def parse_xml(xml_file, out):
tree = ET.parse(xml_file)
root = tree.getroot()
seq_names = {
seq.get("id"): seq.get("name")
for seq in root.findall(".//sequence")
}
n_sites = 0
with open(f"{out}.motif_seq.txt", "w") as o1, \
open(f"{out}.motif_prot.bed", "w") as o2, \
open(f"{out}.motif_prot.txt", "w") as o3:
for motif in root.findall(".//motif"):
motif_name = motif.get("name") or motif.get("id", "")
meme = f"MEME-{motif_name}"
for hit in motif.findall("./contributing_sites/contributing_site"):
seq_name = seq_names.get(hit.get("sequence_id"), hit.get("sequence_id"))
start0 = int(hit.get("position"))
seq = site_sequence(hit.find("site"))
start1 = start0 + 1
end = start0 + len(seq)
pvalue = hit.get("pvalue", "")
o1.write(f"{meme}\t{seq_name}\n")
o2.write(f"{seq_name}\t{start0}\t{end}\t{meme}\n")
o3.write(f"{seq_name}\t{start1}\t{end}\t{seq}\t{meme}\t{pvalue}\n")
n_sites += 1
return n_sites
def parse_txt(meme_file, out):
n_sites = 0
with open(f"{out}.motif_seq.txt", "w") as o1, \
open(f"{out}.motif_prot.bed", "w") as o2, \
open(f"{out}.motif_prot.txt", "w") as o3, \
open(meme_file, encoding="utf-8", errors="replace") as fh:
it = iter(fh)
for line in it:
m = re.match(r"^\s*Motif\s+(\S+)(?:\s+\S+)?\s+sites sorted by position p-value", line.rstrip("\n"))
if not m:
continue
meme = f"MEME-{m.group(1)}"
for _ in range(3):
next(it, "")
for hit in it:
hit = hit.rstrip("\n")
if re.match(r"^-{5,}", hit):
break
f = hit.split()
if len(f) < 5:
continue
start = int(f[1])
seq = f[4]
end = start + len(seq) - 1
o1.write(f"{meme}\t{f[0]}\n")
o2.write(f"{f[0]}\t{start - 1}\t{end}\t{meme}\n")
o3.write(f"{f[0]}\t{start}\t{end}\t{seq}\t{meme}\t{f[2]}\n")
n_sites += 1
return n_sites
if len(sys.argv) != 3:
sys.exit(f"python3 {sys.argv[0]} <input.meme.txt> <output.prefix>")
meme_file = Path(sys.argv[1])
out = sys.argv[2]
xml_file = meme_file if meme_file.suffix == ".xml" else meme_file.with_name("meme.xml")
if xml_file.exists():
sites = parse_xml(xml_file, out)
else:
sites = parse_txt(meme_file, out)
if sites == 0:
sys.exit("No MEME motif sites parsed")