ec-knn-v2 / predict.py
chiru112's picture
Upload folder using huggingface_hub
db49a03 verified
Raw History Blame Contribute Delete
2.5 kB
import argparse
import json
import subprocess
import sys
import tempfile
import time
from pathlib import Path
import pandas as pd
HERE = Path(__file__).resolve().parent
sys.path.insert(0, str(HERE))
import knn
def main():
ap = argparse.ArgumentParser()
ap.add_argument('--input', required=True)
ap.add_argument('--output', required=True)
args = ap.parse_args()
t0 = time.perf_counter()
cfg = json.loads((HERE / 'config.json').read_text())
ec_map = json.loads((HERE / 'db' / 'ec_map.json').read_text())
fallback = json.loads((HERE / 'db' / 'fallback.json').read_text())
df = pd.read_parquet(args.input, columns=['id', 'sequence'])
# identical sequences count once; the first existing ID is kept (leaderboard rule)
uniq = df.drop_duplicates('sequence', keep='first').reset_index(drop=True)
qid = ['q%d' % i for i in range(len(uniq))]
with tempfile.TemporaryDirectory(dir='/tmp') as tmpdir:
tmp = Path(tmpdir)
with open(tmp / 'q.fa', 'w') as f:
for i, s in zip(qid, uniq['sequence']):
f.write('>%s\n%s\n' % (i, s))
out = tmp / 'hits.tsv'
cmd = [str(HERE / 'bin' / 'mmseqs'), 'easy-search', str(tmp / 'q.fa'), str(HERE / 'db' / 'train.fa'),
str(out), str(tmp / 'work'), '-s', str(cfg['sens']), '--max-seqs', '100', '-e', '10',
'--split-memory-limit', cfg['split_mem'], '--threads', str(cfg['threads']),
'--format-output', 'query,target,bits', '-v', '1']
r = subprocess.run(cmd, capture_output=True, text=True)
if r.returncode != 0:
sys.stderr.write(r.stdout[-2000:] + '\n' + r.stderr[-2000:] + '\n')
sys.exit('mmseqs failed with code %d' % r.returncode)
if out.exists() and out.stat().st_size > 0:
hits = pd.read_csv(out, sep='\t', names=['query', 'target', 'bits'])
else:
hits = pd.DataFrame(columns=['query', 'target', 'bits'])
sys.stderr.write('search done after %.0fs\n' % (time.perf_counter() - t0))
hl = knn.hits_from_df(hits, cfg['kmax'])
with open(args.output, 'w') as f:
for q, i in zip(qid, uniq['id']):
ecs = knn.select_ecs(hl.get(q, []), ec_map, fallback, cfg['K'], cfg['pw'], cfg['ratio'], cfg['max_ec'])
f.write(json.dumps({'id': i, 'prediction': ecs}) + '\n')
sys.stderr.write('total %.0fs for %d unique inputs\n' % (time.perf_counter() - t0, len(uniq)))
if __name__ == '__main__':
main()