### Install setuptools and bioservices Source: https://github.com/sj584/epigraph/blob/main/README.md Installs necessary Python packages for the project. Ensure setuptools is version less than 58.0. ```python pip install "setuptools<58.0" # setuptools setting pip install bioservices # wheels setting ``` -------------------------------- ### Install Dependencies and Pre-download ESM Models Source: https://context7.com/sj584/epigraph/llms.txt Installs necessary Python packages and downloads pre-trained ESM models. Ensure dssp is installed via apt-get for RSA calculations. ```bash pip install "setuptools<58.0" pip install bioservices conda env create --file conda_env.yaml --name Bepitope conda activate Bepitope pip install wget pip install biopython==1.83 pip install biotite==0.40.0 pip install fair-esm sudo apt-get install dssp # required for RSA calculation via Biopython python - <<'EOF' import torch _, _ = torch.hub.load("facebookresearch/esm:main", "esm2_t33_650M_UR50D") import esm _, _ = esm.pretrained.esm_if1_gvp4_t16_142M_UR50() EOF cp pretrained.py ~/anaconda3/envs/Bepitope/lib/python3.8/site-packages/esm/pretrained.py ``` -------------------------------- ### Install additional Python packages Source: https://github.com/sj584/epigraph/blob/main/README.md Installs required Python libraries including wget, biopython, biotite, and fair-esm. Also installs dssp for RSA generation. ```python pip install wget pip install biopython==1.83 pip install biotite==0.40.0 pip install fair-esm sudo apt-get install dssp # for generating RSA using Biopython ``` -------------------------------- ### Load and Subset Training Data with Pandas Source: https://github.com/sj584/epigraph/blob/main/Data_processing_example.ipynb Loads a CSV file into a pandas DataFrame and selects the first 5 rows for example usage. Ensure the CSV file exists at the specified path. ```python import pandas as pd df_train = pd.read_csv("epitope3d_dataset_180_Train.csv") # use the subset of df_train as example df_example = df_train[:5] df_example ``` -------------------------------- ### Train models and save checkpoints Source: https://github.com/sj584/epigraph/blob/main/README.md Initiates the model training process and saves the trained models to a specified directory. GPU is recommended for faster training. ```bash # to train the models and save # in model training, we recommend using GPU. CPU work is quite slow. python train.py --model_save_dir models ``` -------------------------------- ### Instantiate and Run GAT Model Source: https://context7.com/sj584/epigraph/llms.txt Demonstrates how to instantiate the GAT model and perform a forward pass with synthetic data. The model expects PyTorch Geometric Data objects with node attributes and edge indices. ```python import torch from torch_geometric.data import Data from model import GAT # Instantiate the GAT model (configuration used in all training/inference scripts) model = GAT( in_dim=1792, # ESM-IF (512) + ESM-2 (1280) concatenated node features hid_dim=128, # hidden dimension per attention head out_dim=1, # binary epitope score per residue num_head=8, # attention heads in input/mid layers out_head=1 # attention heads in output layer (concat=False → averaged) ) # Forward pass with synthetic data (246 residues, 4866 edges as in PDB 1YBW) num_nodes = 246 node_attrs = torch.randn(num_nodes, 1792) edge_index = torch.randint(0, num_nodes, (2, 4866)) data = Data(node_attrs=node_attrs, edge_index=edge_index) model.eval() with torch.no_grad(): scores = model(data) # shape: (246, 1) print(scores.shape) # torch.Size([246, 1]) print(scores[:5]) # tensor([[0.4821], # [0.5103], # [0.4672], # [0.5289], # [0.4910]]) ``` -------------------------------- ### View script arguments Source: https://github.com/sj584/epigraph/blob/main/README.md Demonstrates how to view the available command-line arguments for inference, training, and evaluation scripts using the -h option. ```bash Each python program contains more arguments. You can check with -h option ex) python inference.py/inference_CustomPDB.py/train.py/evaluate.py -h ``` -------------------------------- ### Create and activate Conda environment Source: https://github.com/sj584/epigraph/blob/main/README.md Generates a new Conda environment named 'Bepitope' using the provided 'conda_env.yaml' file and then activates it. ```bash conda env create --file conda_env.yaml --name Bepitope conda activate Bepitope ``` -------------------------------- ### Run Inference on Custom PDB File Source: https://context7.com/sj584/epigraph/llms.txt Execute the inference pipeline on a local PDB file. Ensure the PDB file is placed in the specified directory. ```bash # Custom PDB file: place 6FNZ.pdb in ./Custom_PDB/ first python inference_customPDB.py --pdb 6FNZ ``` ```bash # With a custom local directory python inference_customPDB.py \ --pdb 6FNZ \ --pdb_path Custom_PDB \ --save_path PDB_Processed \ --distance_threshold 10 \ --RSA_threshold 0.15 \ --model_path checkpoint \ --kfold 10 \ --out_path Result \ --classification_threshold 0.1481 \ --device cuda ``` -------------------------------- ### Load ESM-2 and ESM-IF models Source: https://github.com/sj584/epigraph/blob/main/README.md Downloads and loads the ESM-2 and ESM-IF models from PyTorch Hub and esm library respectively. This may take time on the first run. ```python # at first, it may take some time to download the esm-2, esm-if model import torch _, _ = torch.hub.load("facebookresearch/esm:main", "esm2_t33_650M_UR50D") # load esm-2 model import esm _, _ = esm.pretrained.esm_if1_gvp4_t16_142M_UR50() # load esm-if model ``` -------------------------------- ### Inference using local PDB file Source: https://github.com/sj584/epigraph/blob/main/README.md Executes inference using a PDB file located on your local computer. The PDB file should be in the 'Custom_PDB' directory or a path specified by '--pdb_path'. ```bash # for inference using pdb file from local computer... # the pdb file must be located in Custom_PDB(default) directory # or any directory you assign with --pdb_path python inference_CustomPDB.py --pdb 6FNZ ``` -------------------------------- ### Evaluate models with specified checkpoint Source: https://github.com/sj584/epigraph/blob/main/README.md Evaluates models using a specific checkpoint directory. If '--model_checkpoint' is not provided, it defaults to evaluating models in the 'checkpoint' directory. ```bash # assign new directory with --model_checkpoint # python evaluate.py simply evaluate the models saved in checkpoint python evaluate.py --model_checkpoint models ``` -------------------------------- ### Run Inference from RCSB PDB using CLI Source: https://context7.com/sj584/epigraph/llms.txt Command-line interface for fetching PDB structures, building protein graphs, and running ensemble prediction. Supports single PDB inference, batch inference, and various customization options. ```bash # Basic usage: predict epitopes for PDB 1cfi (auto-downloaded from rcsb.org) python inference.py --pdb 1cfi # All arguments with custom settings python inference.py \ --pdb 1cfi \ --pdb_path PDB \ --save_path PDB_Processed \ --distance_threshold 10 \ --RSA_threshold 0.15 \ --model_path checkpoint \ --kfold 10 \ --out_path Result \ --classification_threshold 0.1481 \ --device cuda \ # Batch inference over multiple PDB IDs for pdb in 1cfi 1yqv 3pmf 4o38 5x59 do python inference.py --pdb $pdb done # Output: Result/1cfi.csv ``` -------------------------------- ### Train EpiGraph Model Source: https://context7.com/sj584/epigraph/llms.txt Train the EpiGraph model from scratch using 10-fold cross-validation on the Epitope3D training dataset. Only surface-exposed residues are used for loss computation. Best models are saved as checkpoints. ```bash # Train with defaults (GPU recommended; CPU is very slow) python train.py --model_save_dir models ``` ```bash # Full argument set python train.py \ --epochs 50 \ --batch_size 8 \ --seed 30 \ --kfold 10 \ --hid_dim 128 \ --num_head 8 \ --learning_rate 1e-5 \ --weight_decay 1e-8 \ --model_save_dir models \ --device cuda ``` -------------------------------- ### Generate PyTorch Geometric Protein Graph Data Object Source: https://context7.com/sj584/epigraph/llms.txt Builds a complete PyTorch Geometric `Data` object from a preprocessed PDB file. Integrates ESM embeddings, spatial edge construction, and DSSP-based RSA computation. Requires 'inference' module. ```python from inference import generate_graph # same logic in inference_customPDB.py # PDB file must be in save_path/ with heteroatoms already removed data = generate_graph( pdb="1YBW", save_path="Example_PDB", distance_threshold=10, # Angstroms RSA_threshold=0.15 # 15% RSA cutoff for surface vs. buried residues ) print(data) # Data(edge_index=[2, 4866], coords=[246, 3], node_id=[246], # node_attrs=[246, 1792], num_nodes=246, name='1YBW', # train_mask=[246], rsa=[246]) # Surface-exposed residues used for prediction print(data.train_mask.sum().item()) # e.g., 178 surface residues print(data.node_id[:3]) # ['A:LEU:487', 'A:ILE:483', 'A:HIS:496'] ``` -------------------------------- ### Process PDB Data to PyTorch Geometric Graphs Source: https://context7.com/sj584/epigraph/llms.txt Loads a CSV dataset, processes a subset using generate_graph, inspects the resulting PyG Data objects, and saves the processed data. Ensure PDB files are available in the specified path. ```python import pandas as pd import pickle from torch_geometric.data import Data # Load Epitope3D CSV dataset df_train = pd.read_csv("csv files/epitope3d_dataset_180_Train.csv") # Columns: PDB, Epitope # Example row: # PDB: '1YBW' # Epitope: 'A:LEU:487, A:ILE:483, A:HIS:496, ...' # Process a small subset for demonstration df_subset = df_train[:5] # generate_graph returns a list of PyG Data objects with labels pyg_list = generate_graph( df=df_subset, path="Example_PDB", # directory with preprocessed .pdb files distance_threshold=10, # Angstroms RSA_threshold=0.15 ) # Inspect one graph g = pyg_list[0] print(g) # Data(edge_index=[2, 4866], y=[246], coords=[246, 3], node_id=[246], # node_attrs=[246, 1792], num_nodes=246, name='1YBW', # train_mask=[246], rsa=[246]) print("Epitope residues:", g.y[g.train_mask].sum().item(), "/", g.train_mask.sum().item()) # Epitope residues: 18 / 178 # Save processed data for use with train.py / evaluate.py with open("epitope3d_train_data.pkl", "wb") as f: pickle.dump(pyg_list, f) ``` -------------------------------- ### Evaluate trained model on test set Source: https://github.com/sj584/epigraph/blob/main/README.md Evaluates the performance of a trained model using the epitope3D test set. Assumes trained models are in the 'checkpoint' directory. ```bash # simply evaluate the trained model(in checkpoint directory) on the epitope3d test set (45 PDB) python evaluate.py ``` -------------------------------- ### Predict epitopes from fetched PDB Source: https://github.com/sj584/epigraph/blob/main/README.md Runs the inference script to predict epitopes from a given PDB ID. The PDB is fetched automatically. ```bash # predict the epitopes from pdb (fetched) python inference.py --pdb 1cfi ``` -------------------------------- ### Evaluate Ensemble Models Programmatically Source: https://context7.com/sj584/epigraph/llms.txt Programmatically evaluate ensemble models using saved test data and calculate AUC-ROC and F1 scores. Requires PyTorch and scikit-learn. ```python import pickle, torch from evaluate import ensemble, to_label from sklearn import metrics with open("epitope3d_test_data.pkl", "rb") as f: test_pyg_list = pickle.load(f) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") true_labels, pred_scores = ensemble(direc="checkpoint", data_pyg_list=test_pyg_list, kfold=10) fpr, tpr, _ = metrics.roc_curve(true_labels, pred_scores) print("AUC-ROC:", metrics.auc(fpr, tpr)) binary = to_label(pred_scores, threshold=0.1481) from sklearn.metrics import f1_score print("F1:", f1_score(true_labels, binary)) ``` -------------------------------- ### Generate Protein Structure Graph Data Source: https://github.com/sj584/epigraph/blob/main/Data_processing_example.ipynb Generates PyTorch Geometric Data objects from protein structure files. It integrates ESM embeddings, calculates residue-level features like RSA, and constructs graph edges based on spatial proximity. Requires specific libraries like esm_embedding and torch_geometric. ```python from esm_embedding import esm_if_2_embedding from Bio.PDB.DSSP import dssp_dict_from_pdb_file, residue_max_acc from torch_geometric.data import Data import torch import warnings warnings.filterwarnings('ignore') def generate_graph(df, path, distance_threshold, RSA_threshold): # iterate the pdbs pyg_data_list = [] for idx, row in df.iterrows(): pdb_id = row["PDB"] print("PDB is :", pdb_id) # get the list of epitopes epitope_list = row["Epitope"].split(", ") esm_if_rep, esm2_rep, node_list, coord_list = esm_if_2_embedding(pdb_id, path) esm_node_features = torch.concat((esm_if_rep, esm2_rep), dim=1) # iterate per-chain node_list into whole-chain node_list node_all_list = [] for chain_node in node_list: for node in chain_node: node_all_list.append(node) # iterate per-chain coord_list into whole-chain coord_list coord_all_list = [] for chain_coord in coord_list: for coord in chain_coord: coord_all_list.append(coord) coord_all_list = torch.tensor(coord_all_list) # generate the edge connection within 10 Angstrome distance (while removing self-connection) edges = edge_connection(coord_all_list, threshold=distance_threshold) # generate the label for each node based on the epitope annotation y_list = list() for node in node_all_list: if node in epitope_list: y_list.append(int(1)) else: y_list.append(int(0)) y_list = torch.tensor(y_list) # generate rsa feature by extracting dssp from pdb file dssp = dssp_dict_from_pdb_file(f"{path}/{pdb_id}.pdb") rsa_list = [] for node in node_all_list: chain, res_name, res_id = node.split(":") try: # indexing the dssp such as ('A', (' ', 53, ' ')) key = (chain, (' ', int(res_id), ' ')) # generate rsa va;ie by normalizing asa by residue_max_acc -> rsa = dssp[0][key][2] / residue_max_acc["Sander"][res_name] rsa_list.append(rsa) except: rsa_list.append(0) print("Key Error... appending rsa: 0") # The surface residues were selected with RSA cutoff 10% # surface residues can be chosen by indexing as [data.train_mask] train_mask = torch.tensor([rsa >= RSA_threshold for rsa in rsa_list]) data = Data(coords=coord_all_list, node_id=node_all_list, node_attrs=esm_node_features, edge_index=edges.contiguous(), y=y_list, num_nodes=len(node_all_list), name=pdb_id, train_mask=train_mask, rsa=rsa_list) pyg_data_list.append(data) return pyg_data_list ``` -------------------------------- ### Evaluate Ensemble Models Source: https://context7.com/sj584/epigraph/llms.txt Assess the performance of ensemble models against a blind test set using various metrics like AUC-ROC, AUC-PR, F1, Balanced Accuracy, and MCC. Can be run via command line or programmatically. ```bash # Evaluate pretrained models in ./checkpoint/ on the blind test set python evaluate.py ``` ```bash # Evaluate custom-trained models with explicit settings python evaluate.py \ --model_checkpoint models \ --kfold 10 \ --hid_dim 128 \ --num_head 8 \ --threshold 0.1481 \ --device cuda ``` -------------------------------- ### Build Sparse Edge Index for Protein Graph Source: https://context7.com/sj584/epigraph/llms.txt Constructs a sparse edge index tensor for a protein graph. Connects residue pairs within a specified distance threshold. Self-connections are removed by setting diagonal distances to infinity. Requires a `euclidean_dist` function. ```python import torch def euclidean_dist(x, y): return ((x[:, None] - y) ** 2).sum(-1).sqrt() def edge_connection(coord_list, threshold): distances = euclidean_dist(coord_list, coord_list) distances.fill_diagonal_(float("inf")) edges = (distances < threshold).nonzero(as_tuple=False).t() return edges # Example: 5 residues with random Cα coordinates coords = torch.rand(5, 3) * 20 # scale to Angstrom range edges = edge_connection(coords, threshold=10.0) print(edges.shape) # torch.Size([2, N_edges]) print(edges[:, :4]) # tensor([[0, 0, 1, 1], # [2, 3, 0, 2]]) ``` -------------------------------- ### Generate Graph from DataFrame Source: https://github.com/sj584/epigraph/blob/main/Data_processing_example.ipynb Generates a graph representation from a pandas DataFrame. Specify the output path for PDB files and thresholds for distance and relative surface area (RSA). ```python example_pyg_list = generate_graph(df_example, path="Example_PDB", distance_threshold=10, RSA_threshold=0.15) ``` -------------------------------- ### Calculate Euclidean Distance and Generate Edges Source: https://github.com/sj584/epigraph/blob/main/Data_processing_example.ipynb Provides functions to compute pairwise Euclidean distances between 3D coordinates and generate graph edges based on a distance threshold. Self-connections are explicitly avoided by setting their distance to infinity. ```python # calculate the euclidean distance between two nodes (Ca coordinates) def euclidean_dist(x, y): return ((x[:, None] - y) ** 2).sum(-1).sqrt() # based on the distance, generate edge connection for distance within threshold def edge_connection(coord_list, threshold): # Compute pairwise euclidean distances distances = euclidean_dist(coord_list, coord_list) # to avoid self-connection, make the distance 0 between self nodes into infinity distances.fill_diagonal_(float("inf")) # edges are constructed within threshold edges = (distances < threshold).nonzero(as_tuple=False).t() return edges ``` -------------------------------- ### Perform Ensemble Prediction Source: https://context7.com/sj584/epigraph/llms.txt Load checkpoint models, run inference on protein graph data, and average predictions. Buried residues are handled by forcing their scores to 0 before averaging. Requires PyTorch and the model definition. ```python import torch, os from model import GAT from inference import ensemble_pred, generate_graph device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # Build graph for a local PDB data = generate_graph("6FNZ", "PDB_Processed", distance_threshold=10, RSA_threshold=0.15) # Run ensemble inference ensem_scores, rsa_list, node_list = ensemble_pred( model_path="checkpoint", data=data, kfold=10, RSA_threshold=0.15, device=device ) # Convert continuous scores to binary epitope labels def to_labels(scores, threshold=0.1481): return [1 if s > threshold else 0 for s in scores] binary_preds = to_labels(ensem_scores) # Inspect top-scoring epitope candidates import pandas as pd df = pd.DataFrame({"Residue": node_list, "Score": ensem_scores, "Epitope": binary_preds, "RSA": rsa_list}) print(df[df["Epitope"] == 1].sort_values("Score", ascending=False).head(10)) ``` -------------------------------- ### Batch inference for multiple PDBs Source: https://github.com/sj584/epigraph/blob/main/README.md A bash loop to perform inference on a list of PDB IDs sequentially. Replace 'pdb1' through 'pdb10' with actual PDB identifiers. ```bash # for multiple inference... in bash for pdb in pdb1 pdb2 pdb3 pdb4 pdb5 pdb6 ... pdb10 > do > python inference.py --pdb $pdb > done ``` -------------------------------- ### Accessing Graph Data Source: https://github.com/sj584/epigraph/blob/main/Data_processing_example.ipynb Accesses the first element of the generated graph list, which is a PyTorch Geometric Data object. ```python example_pyg_list[0] ``` -------------------------------- ### Compute Pairwise Euclidean Distances Source: https://context7.com/sj584/epigraph/llms.txt Computes pairwise Euclidean distances between two sets of 3D coordinates. Uses PyTorch for efficient computation via broadcasting. Suitable for Cα atom coordinates. ```python import torch def euclidean_dist(x, y): return ((x[:, None] - y) ** 2).sum(-1).sqrt() coords = torch.tensor([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]) dist_matrix = euclidean_dist(coords, coords) print(dist_matrix) # tensor([[ 0.0000, 5.1962, 10.3923], # [ 5.1962, 0.0000, 5.1962], # [10.3923, 5.1962, 0.0000]]) ``` -------------------------------- ### Generate Combined ESM Embeddings for PDB Source: https://context7.com/sj584/epigraph/llms.txt Generates per-residue feature tensors by combining ESM-IF1 and ESM-2 embeddings for a given PDB ID. Requires the PDB file to be present in the specified path. ```python from esm_embedding import esm_if_2_embedding import torch # PDB 1YBW must exist at Example_PDB/1YBW.pdb (heteroatoms already removed) esm_if_rep, esm2_rep, node_list, coord_list = esm_if_2_embedding("1YBW", "Example_PDB") # esm_if_rep: (N_residues_total, 512) — structural embeddings from ESM-IF1 # esm2_rep: (N_residues_total, 1280) — sequence embeddings from ESM-2 # node_list: list of lists, one per chain; each element is "chain:resName:resID" # coord_list: list of lists, one per chain; each element is a Cα [x, y, z] # Concatenate to form the full node feature matrix node_features = torch.concat((esm_if_rep, esm2_rep), dim=1) print(node_features.shape) # e.g., torch.Size([246, 1792]) ``` -------------------------------- ### Compute ESM-2 Per-Residue Embeddings Source: https://context7.com/sj584/epigraph/llms.txt Computes per-residue embeddings for a single amino acid sequence using the ESM-2 model. Sequences longer than 1022 residues are truncated. Requires the 'esm_embedding' library. ```python from esm_embedding import esm2_residue_embedding import numpy as np sequence = "MKTAYIAKQRQISFVKSHFSRQLEERLGLIEVQAPILSRVGDGTQDNLSGAEKAVQVKVKALPDAQFEVVHSLAKWKRQTLGQHDFSAGEGLYTHMKALRPDEDRLSPLHSVYVDQWDWERVMGDGERQFSTLKSTVEAIWAGIKATEAAVSEEFGLAPFLPDQIHFVHSQELLSRYPDLDAKGRERAIAKDLGAVFLVGIGGKLSDGHRHDVRAPDYDDWSTPSELGHAGLNGDILVWNPVLEDAFELSSMGIRVDADTLKHQLALTGDEDRLELEWHQALLRGEMPQTIGGGIGQSRLTMLLLQLPHIGQVQAGVWPAAVRESVPSLL" emb = esm2_residue_embedding(sequence) # numpy array print(emb.shape) # (len(sequence), 1280) # e.g., (330, 1280) print(np.linalg.norm(emb[0])) # L2 norm of first residue embedding # e.g., 18.42 ``` -------------------------------- ### Define Non-Heteroatom Residue Selector Source: https://github.com/sj584/epigraph/blob/main/Data_processing_example.ipynb A custom selector for Bio.PDB to include only standard residues, excluding heteroatoms. This is useful for cleaning PDB files before certain types of analysis. ```python from Bio.PDB.Select import Select class NonHetSelect(Select): def accept_residue(self, residue): return 1 if residue.id[0] == " " else 0 ``` -------------------------------- ### Flatten Node Identifiers Source: https://context7.com/sj584/epigraph/llms.txt Flattens a list of node identifiers across multiple chains into a single list. Useful for processing graph data where nodes are organized by chain. ```python node_all = [node for chain in node_list for node in chain] print(node_all[:3]) # ['A:LEU:487', 'A:ILE:483', 'A:HIS:496'] ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.