Download model/Protenix-pxd/runner/msa_search.py from OneScience-Group/PXDesign: direct link, hf CLI and curl.
- Browser
- Download file 4.61 kB
-
https://huggingface.co/OneScience-Group/PXDesign/resolve/main/model/Protenix-pxd/runner/msa_search.py
- Command line
-
hf download hf://OneScience-Group/PXDesign/model/Protenix-pxd/runner/msa_search.py
-
curl -L -o msa_search.py https://huggingface.co/OneScience-Group/PXDesign/resolve/main/model/Protenix-pxd/runner/msa_search.py
4.61 kB
| # Copyright 2024 ByteDance and/or its affiliates. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| import json | |
| import os | |
| import uuid | |
| from typing import Sequence | |
| from protenix.utils.logger import get_logger | |
| from protenix.web_service.colab_request_parser import RequestParser | |
| logger = get_logger(__name__) | |
| def need_msa_search(json_data: dict) -> bool: | |
| need_msa = False | |
| for sequence in json_data["sequences"]: | |
| if "proteinChain" in sequence.keys(): | |
| proteinChain = sequence["proteinChain"] | |
| if "msa" not in proteinChain.keys() or len(proteinChain["msa"]) == 0: | |
| need_msa = True | |
| return need_msa | |
| def msa_search(seqs: Sequence[str], msa_res_dir: str) -> Sequence[str]: | |
| """ | |
| do msa search with mmseqs and return result subdirs. | |
| """ | |
| os.makedirs(msa_res_dir, exist_ok=True) | |
| tmp_fasta_fpath = os.path.join(msa_res_dir, f"tmp_{uuid.uuid4().hex}.fasta") | |
| RequestParser.msa_search( | |
| seqs_pending_msa=seqs, | |
| tmp_fasta_fpath=tmp_fasta_fpath, | |
| msa_res_dir=msa_res_dir, | |
| ) | |
| msa_res_subdirs = RequestParser.msa_postprocess( | |
| seqs_pending_msa=seqs, | |
| msa_res_dir=msa_res_dir, | |
| ) | |
| return msa_res_subdirs | |
| def update_seq_msa(infer_seq: dict, msa_res_dir: str) -> dict: | |
| protein_seqs = [] | |
| for sequence in infer_seq["sequences"]: | |
| if "proteinChain" in sequence.keys(): | |
| protein_seqs.append(sequence["proteinChain"]["sequence"]) | |
| if len(protein_seqs) > 0: | |
| protein_seqs = sorted(protein_seqs) | |
| msa_res_subdirs = msa_search(protein_seqs, msa_res_dir) | |
| assert len(msa_res_subdirs) == len(msa_res_subdirs), "msa search failed" | |
| protein_msa_res = dict(zip(protein_seqs, msa_res_subdirs)) | |
| for sequence in infer_seq["sequences"]: | |
| if "proteinChain" in sequence.keys(): | |
| sequence["proteinChain"]["msa"] = { | |
| "precomputed_msa_dir": protein_msa_res[ | |
| sequence["proteinChain"]["sequence"] | |
| ], | |
| "pairing_db": "uniref100", | |
| } | |
| return infer_seq | |
| def update_infer_json(json_file: str, out_dir: str, use_msa: bool = True) -> str: | |
| """ | |
| update json file for inference. | |
| for every infer_data, if it needs to inference with msa and | |
| msa is not complete or missing in the json file, | |
| it will run msa searching if use_msa is True, | |
| else it will pass. | |
| """ | |
| if not os.path.exists(json_file): | |
| raise RuntimeError(f"`{json_file}` not exists.") | |
| with open(json_file, "r") as f: | |
| json_data = json.load(f) | |
| actual_updated = False | |
| for seq_idx, infer_data in enumerate(json_data): | |
| if use_msa and need_msa_search(infer_data): | |
| actual_updated = True | |
| seq_name = infer_data.get("name", f"seq_{seq_idx}") | |
| logger.info( | |
| f"starting to update msa result for seq {seq_idx} in {json_file}" | |
| ) | |
| update_seq_msa( | |
| infer_data, | |
| os.path.join(out_dir, seq_name, "msa_res" f"msa_seq_{seq_idx}"), | |
| ) | |
| if actual_updated: | |
| updated_json = os.path.join( | |
| os.path.dirname(os.path.abspath(json_file)), | |
| f"{os.path.splitext(os.path.basename(json_file))[0]}-add-msa.json", | |
| ) | |
| with open(updated_json, "w") as f: | |
| json.dump(json_data, f, indent=4) | |
| logger.info(f"update msa result success and save to {updated_json}") | |
| return updated_json | |
| elif not use_msa: | |
| logger.warning( | |
| f"the inference json file {json_file} \n" | |
| + "do not contain msa and will not be updated,\n" | |
| + "and you set not using msa, in this mode, \n" | |
| + "if you do not use esm feature, model performance might degrade significantly" | |
| ) | |
| return json_file | |
| else: | |
| logger.info(f"do not need to update msa result, so return itself {json_file}") | |
| return json_file | |