<jupyter_start><jupyter_text>- for a given model, for each ligand that is Zn, check for atoms within 5 and 10 angstrom. turn this into a function, possibly a python script.- make a 2d and 3d vidsual from the atoms center of mass, using then go into 3d the center of origin will be on the zinc ligand, look for offset from zinc atomhttps://proteopedia.org/wiki/index.php/Hetero_atomsHETNon-standard residues<jupyter_code>import atomium
import numpy as np
import matplotlib.pyplot as plt
# %matplotlib inline
# %matplotlib notebook # must restart kernel to switch from widget to notebook, commnt out one
%matplotlib widget
from mpl_toolkits import mplot3d<jupyter_output><empty_output><jupyter_text>Get Data<jupyter_code>ligands = zinc_ligands(MODEL)

ligand_center = ligands[1].center_of_mass #ndarray
atoms = nearby_ligand_atoms(ligands[0], MODEL, radius=5.0)
# [{'atom': <Atom 3394 (ZN)>,
#   'location': (-11.953, 22.816, 27.173),
#   'distance': 0.0,
#   'is_metal': True,
#   'atom_id': 3394,
#   'near_hets': [<Residue CYS (A.111)>,
#    <Residue CYS (A.97)>,
#    <Residue CYS (A.103)>,
#    <Residue CYS (A.100)>]},
    # ...]<jupyter_output><empty_output><jupyter_text>Plot data<jupyter_code>fig = plt.figure()
ax = plt.axes(projection='3d')

# Data for ligand center of mass
xdata = ligand_center[0]
ydata = ligand_center[1]
zdata = ligand_center[2]
ax.scatter3D(xdata, ydata, zdata, c="green", s=100);

# Data for atoms
for atom in atoms:
    xdata = atom["location"][0]
    ydata = atom["location"][1]
    zdata = atom["location"][2]
    ax.scatter3D(xdata, ydata, zdata, c='blue', s=20);
    ax.plot([xdata, ligand_center[0]],[ydata, ligand_center[1]],[zdata, ligand_center[2]], 'gray');<jupyter_output><empty_output><jupyter_text>Globals<jupyter_code># The basic structures within a model are chains, residues, ligands, and atoms
# Biological molecules are hierarchical, building from atoms to residues to chains to assemblies

MODEL_NAME = "1ADG"
FILE = atomium.fetch(MODEL_NAME)
MODEL = atomium.fetch(MODEL_NAME).model
MODEL_CENTER_MASS = MODEL.center_of_mass
print(FILE.title)<jupyter_output>CRYSTALLOGRAPHIC STUDIES OF TWO ALCOHOL DEHYDROGENASE-BOUND ANALOGS OF THIAZOLE-4-CARBOXAMIDE ADENINE DINUCLEOTIDE (TAD), THE ACTIVE ANABOLITE OF THE ANTITUMOR AGENT TIAZOFURIN<jupyter_text>Helpers<jupyter_code>def nearby_ligand_atoms(ligand, model, radius=10.0, sort_atoms=True):
    """
    Takes a ligand obj and a model's center of mass and returns a dictionary of atom data
    where the atoms fall within some set distance of the ligand's center
    
    - radius in angstroms
    - sort_atoms sorts the dict data structure by distance from ligand center
    """
    ligand_center = tuple(ligand.center_of_mass)
    atoms_in_radius = list(model.atoms_in_sphere(ligand_center, radius))
    
    atoms = []
    for idx, atom in enumerate(atoms_in_radius):
        atoms.append(
            {
                "atom": atom,
                "location": atom.location, #see Atom class: self._location = np.array([x, y, z])
                "distance": atom.distance_to(tuple(ligand.center_of_mass)),
                "is_metal": atom.is_metal,
                "atom_id": atom.id,
                "near_hets": list(atom.nearby_hets(cutoff=3))
            }
        )

    if sort_atoms:
        return sorted(atoms, key=lambda d: d["distance"]) 
    else:
        return atoms
def zinc_ligands(model, optimize=True):
    """
    For a given model name, query model via atomium API
    and return an array of any ZN ligand objects found in the model.
    
    model_name is a string, e.g. "1ADG"
    """
    # pdb = atomium.fetch(model_name) #should check for nil here i.e. does the model exist
    ligands = model.ligands()
    
    if optimize:
        model = model.optimise_distances()
    
    zn_ligands = []
    for ligand in ligands:
        if ligand.name == "ZN":
            zn_ligands.append(ligand)
    return zn_ligands<jupyter_output><empty_output><jupyter_text>Testing<jupyter_code># test

ligands = zinc_ligands(MODEL)
print(len(nearby_ligand_atoms(ligands[1], MODEL, radius=5.0)))
print(nearby_ligand_atoms(ligands[1], MODEL, radius=5.0))

# [{'atom': <Atom 3393 (ZN)>,
#   'distance': 0.0,
#   'is_metal': True,
#   'atom_id': 3393,
#   'near_hets': [<Water HOH (A.388)>,<Residue CYS (A.174)>,<Residue HIS (A.67)>,<Residue CYS (A.46)>]
#  },
#  {'atom': <Atom 3473 (O)>,
#   'distance': 1.6169613477136673,
#   'is_metal': False,
#   'atom_id': 3473,
#   'near_hets': [<Ligand ZN (A.376)>,<Residue CYS (A.174)>,<Residue SER (A.48)>,<Water HOH (A.391)>,<Residue HIS (A.67)>]
#  },
#    ...


# hets:
# sorted_dist_to_lig_a376[1]["atom"].nearby_hets(cutoff=3)
# ...
# {<Ligand ZN (A.376)>,
#  <Residue CYS (A.174)>,
#  <Residue HIS (A.67)>,
#  <Residue SER (A.48)>,
#  <Water HOH (A.391)>}<jupyter_output><empty_output>