Download EPT/scripts/process_data/non_redundant_pdb.py from BAAI/AIDD: direct link, hf CLI and curl.
- Browser
- Download file 3.28 kB
-
https://huggingface.co/BAAI/AIDD/resolve/main/EPT/scripts/process_data/non_redundant_pdb.py
- Command line
-
hf download hf://BAAI/AIDD/EPT/scripts/process_data/non_redundant_pdb.py
-
curl -L -o non_redundant_pdb.py https://huggingface.co/BAAI/AIDD/resolve/main/EPT/scripts/process_data/non_redundant_pdb.py
3.28 kB
| #!/usr/bin/python | |
| # -*- coding:utf-8 -*- | |
| import os | |
| import re | |
| import shutil | |
| import argparse | |
| from collections import defaultdict | |
| import numpy as np | |
| def exec_mmseq(cmd): | |
| r = os.popen(cmd) | |
| text = r.read() | |
| r.close() | |
| return text | |
| def clustering(fasta, tmp_dir, seq_id): | |
| # clustering | |
| db = os.path.join(tmp_dir, 'DB') | |
| cmd = f'mmseqs createdb {fasta} {db}' | |
| exec_mmseq(cmd) | |
| db_clustered = os.path.join(tmp_dir, 'DB_clu') | |
| cmd = f'mmseqs cluster {db} {db_clustered} {tmp_dir} --min-seq-id {seq_id} -c 0.95 --cov-mode 1' # simlarity > 0.4 in the same cluster | |
| res = exec_mmseq(cmd) | |
| num_clusters = re.findall(r'Number of clusters: (\d+)', res) | |
| if not len(num_clusters): | |
| raise ValueError('cluster failed!') | |
| # write clustering results | |
| tsv = os.path.join(tmp_dir, 'DB_clu.tsv') | |
| cmd = f'mmseqs createtsv {db} {db} {db_clustered} {tsv}' | |
| exec_mmseq(cmd) | |
| # read tsv of class \t pdb | |
| with open(tsv, 'r') as fin: | |
| entries = fin.read().strip().split('\n') | |
| id2clu, clu2id = {}, defaultdict(list) | |
| for entry in entries: | |
| cluster, _id = entry.strip().split('\t') | |
| id2clu[_id] = cluster | |
| for _id in id2clu: | |
| cluster = id2clu[_id] | |
| clu2id[cluster].append(_id) | |
| clu_cnt = [len(clu2id[clu]) for clu in clu2id] | |
| print(f'cluster number: {len(clu2id)}, member number ' + | |
| f'mean: {np.mean(clu_cnt)}, min: {min(clu_cnt)}, ' + | |
| f'max: {max(clu_cnt)}') | |
| return id2clu, clu2id | |
| def get_non_redundant(mmap_dir): | |
| np.random.seed(12) | |
| index_path = os.path.join(mmap_dir, 'index.txt') | |
| parent_dir = mmap_dir | |
| # load index file | |
| items = {} | |
| with open(index_path, 'r') as fin: | |
| lines = fin.readlines() | |
| for line_id, line in enumerate(lines): | |
| values = line.strip().split('\t') | |
| _id, seq = values[0], values[-1] | |
| items[_id] = (seq, line) | |
| # make temporary directory | |
| tmp_dir = os.path.join(parent_dir, 'tmp') | |
| if not os.path.exists(tmp_dir): | |
| os.makedirs(tmp_dir) | |
| else: | |
| raise ValueError(f'Working directory {tmp_dir} exists!') | |
| # 1. get non-redundant dimer by 90% seq-id | |
| fasta = os.path.join(tmp_dir, 'seq.fasta') | |
| # receptor | |
| with open(fasta, 'w') as fout: | |
| for _id in items: | |
| fout.write(f'>{_id}\n{items[_id][0]}\n') | |
| id2clu, clu2id = clustering(fasta, tmp_dir, 0.9) | |
| shutil.rmtree(tmp_dir) | |
| os.makedirs(tmp_dir) | |
| # overall clustering | |
| non_redundant = [] | |
| for clu in clu2id: | |
| ids = clu2id[clu] | |
| non_redundant.append(np.random.choice(ids)) | |
| print(f'Non-redundant entries: {len(non_redundant)}') | |
| # 2. construct non_redundant items | |
| items = { _id: items[_id] for _id in non_redundant } | |
| return items | |
| def main(args): | |
| items = get_non_redundant(args.mmap_dir) | |
| out = open(os.path.join(args.mmap_dir, 'non_redundant_index.txt'), 'w') | |
| for _id in items: | |
| out.write(items[_id][-1]) | |
| out.close() | |
| def parse(): | |
| parser = argparse.ArgumentParser(description='non redundant pdb index') | |
| parser.add_argument('--mmap_dir', type=str, required=True, help='Directory of the mmap') | |
| return parser.parse_args() | |
| if __name__ == '__main__': | |
| main(parse()) |