<jupyter_start><jupyter_text>Homology Modelling  Author: <NAME>This notebook shows examples of how to perform homology modelling in KinoML.<jupyter_code># get relevant imports
from kinoml.modeling.homology import HomologyModel
from kinoml.modeling.alignment import Alignment
from kinoml.core.proteins import ProteinStructure<jupyter_output><empty_output><jupyter_text>Basic usage To start, we need a template from which to base our homology model on.<jupyter_code>hm = HomologyModel()

# If we already have our model (e.g. if prepared using Spruce TK etc), so we can load it easily
structure = ProteinStructure.from_file("./4yne_protein.pdb")

# If we just want to grab a structure from the PDB we could use the `from_name` attribute in `ProteinStructure`, e.g:
structure_from_pdb = ProteinStructure.from_name('4yne')

# Once we have our structure, we need to extract it's sequence. Note, this will often not be the canonical sequence.
sequence = structure_from_pdb.sequence<jupyter_output><empty_output><jupyter_text>We now have our template structure and its sequence. If, for some reason, we didn't have access to the structure but did have access to the sequence we could run a BLAST search to find a PDB structure for our template:<jupyter_code>model_templates = hm.get_pdb_template(sequence)
model_templates.keys()
model_template = list(model_templates.keys())[0]<jupyter_output><empty_output><jupyter_text>In this toy example our BLAST search using the `4YNE` sequence has, as expected, returned the `4YNE` structure in the PDB as the "best" model for us to use as our template.Typically, we will want to search the PDB with a query sequence and find the most relevant PDB structure to use as our template. We can use the `get_sequence` attribute to obtain the full canonical sequence from a database based on the a unique ID (either using the default `backend="uniprot"` or `backend="ncbi"`). Defaults: `backend=True` and `kinase=True`, the latter ensures we refine our search to sequences that contain a kinase domain.<jupyter_code>uniprot_seq = hm.get_sequence('P04629', kinase=True)  # Get sequence based on the UNIPROT ID = P04629. Default: `kinase=True` is shown here for clarity.<jupyter_output><empty_output><jupyter_text>We can then run a blast search using this canonical sequence to search the PDB for the best template model to use.<jupyter_code>model_templates = hm.get_pdb_template(uniprot_seq) # Need to fix timeouts
model_templates.keys()<jupyter_output><empty_output><jupyter_text>Here, `model_templates.keys()` has returned a number of PDB structures we could use as templates for our homology model.   Generating the alignment A structure (either from a user made one or one downloaded from the PDB with `ProteinStructure.from_name()`) can be used as template on to which we can build our homology model. We also need a target sequence, this is downloaded from the UniProt server using `HomologyModel().get_sequence()` as shown above.This information can be used in `Alignment.get_alignment()` to produce an alignment of the two sequences. The user can also use `Alignment.make_ali_file()` that generates an alignment file based on MODELLER formatting.  Generating an alignment and homology model: no ligand In this example we shall use the `4yne` PDB structure as a template and use the Uniprot sequence for NTRK1 to build a homolgy model.<jupyter_code>structure_from_pdb = ProteinStructure.from_name('4yne') 
uniprot_seq = hm.get_sequence('P04629', kinase=True)
# Generate the sequence alignment between the template and target sequence
seq_alignment = Alignment.get_alignment(structure_from_pdb.sequence.sequence, up_seq)
# To access the alignment information you can use the metadata keys:
seq_alignment.metadata.keys()
# Now, we can generate an alignment file (based on Modeller)
seq_alignment.make_ali_file(
    seq_alignment.metadata['symbols'][0], # the aligned template sequence
    seq_alignment.metadata['symbols'][1], # the aligned target sequence
    structure_from_pdb,
    uniprot_seq
    )<jupyter_output><empty_output><jupyter_text>The alignment file can now be used to generate a homolgy model using Modeller. In a real use case the user will need to generate a large number of models and score them (e.g. using DOPE, QMEAN etc). Here, we shall only generate one.<jupyter_code>hm.make_model(structure_from_pdb, uniprot_seq, seq_alignment, num_models=1)<jupyter_output>.0000       1.000
 9 Distance restraints 1 (CA-CA)      :       0       0      0   0.000   0.000      0.0000       1.000
10 Distance restraints 2 (N-O)        :       0       0      0   0.000   0.000      0.0000       1.000
11 Mainchain Phi dihedral restraints  :       0       0      0   0.000   0.000      0.0000       1.000
12 Mainchain Psi dihedral restraints  :       0       0      0   0.000   0.000      0.0000       1.000
13 Mainchain Omega dihedral restraints:      36       4      6   0.261   0.261      95.357       1.000
14 Sidechain Chi_1 dihedral restraints:      28       0      2   1.616   1.616      20.504       1.000
15 Sidechain Chi_2 dihedral restraints:      21       0      3   1.358   1.358      19.340       1.000
16 Sidechain Chi_3 dihedral restraints:      14       0      0   1.143   1.143      9.9072       1.000
17 Sidechain Chi_4 dihedral restraints:       6       0      0   1.778   1.778      5.2542       1.000
18 Disulfide distance restraints      :       0       0[...]<jupyter_text>Generating an alignment and homology model: with ligand Often, structures will contain the coordinates of bound ligands. If these are of interest and need to be retained this is easy to do:<jupyter_code># We generate the same alignment file (based on Modeller), but now retain the bound ligand
seq_alignment.make_ali_file(
    seq_alignment.metadata['symbols'][0], # the aligned template sequence
    seq_alignment.metadata['symbols'][1], # the aligned target sequence
    structure_from_pdb,
    uniprot_seq,
    ligand=True
    )
hm.make_model(structure_from_pdb, uniprot_seq, seq_alignment, num_models=1, ligand=True)<jupyter_output>24.805       1.000
14 Sidechain Chi_1 dihedral restraints:      29       0      1   1.336   1.336      10.207       1.000
15 Sidechain Chi_2 dihedral restraints:      22       0      0   1.424   1.424      14.724       1.000
16 Sidechain Chi_3 dihedral restraints:      14       0      0   1.901   1.901      11.528       1.000
17 Sidechain Chi_4 dihedral restraints:       6       0      0   1.474   1.474      2.8384       1.000
18 Disulfide distance restraints      :       0       0      0   0.000   0.000      0.0000       1.000
19 Disulfide angle restraints         :       0       0      0   0.000   0.000      0.0000       1.000
20 Disulfide dihedral angle restraints:       0       0      0   0.000   0.000      0.0000       1.000
21 Lower bound distance restraints    :       0       0      0   0.000   0.000      0.0000       1.000
22 Upper bound distance restraints    :       0       0      0   0.000   0.000      0.0000       1.000
23 Distance restraints 3 (SDCH-MNCH)  :       0     [...]
{'fraction_non_alphanumeric': 0.0652050919377652, 'fraction_numerical': 0.06591230551626591, 'mean_word_length': 3.1520845566647093, 'pattern_counts': {'":': 0, '<': 32, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '8', 'dir': 'jupyter-structured-clean-dedup', 'id': '642159', 'license': 'MIT', 'n_tokens_mistral': 2343, 'n_tokens_neox': 2047, 'n_words': 821, 'path': 'examples/homology.ipynb', 'repo_name': 't-kimber/kinoml', 'size': '7077'}