Skip to content

Instantly share code, notes, and snippets.

@dominicrufa
Created May 31, 2022 17:16
Show Gist options
  • Save dominicrufa/f1ec5374b8cf8948de81d64d3800f7ab to your computer and use it in GitHub Desktop.
Save dominicrufa/f1ec5374b8cf8948de81d64d3800f7ab to your computer and use it in GitHub Desktop.
a first attempt ant Velocity RealNVP generative modelling of vacuum alanine dipeptide
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "ba078915-fb0c-44ed-89d7-e531abb87ef9",
"metadata": {},
"source": [
"test the alanine RNVP..."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "a2757c39-eb9d-4301-a26e-d6e1f05ad23a",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/dominic/anaconda3/envs/aquaregia/lib/python3.10/site-packages/google/colab/data_table.py:30: UserWarning: IPython.utils.traitlets has moved to a top-level traitlets package.\n",
" from IPython.utils import traitlets as _traitlets\n",
"WARNING:absl:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)\n"
]
}
],
"source": [
"from jax.config import config\n",
"config.update(\"jax_enable_x64\", True)\n",
"config.update(\"jax_debug_nans\", True) \n",
"import jax\n",
"import jax.numpy as jnp\n",
"from jax import random\n",
"import numpy as np\n",
"from functools import partial\n",
"import haiku as hk\n",
"from aquaregia.utils import Array, ArrayTree, polynomial_switching_fn, kinetic_energy\n",
"from jax.example_libraries.optimizers import adam\n",
"from aquaregia import tfn\n",
"from aquaregia import tfn\n",
"from aquaregia.rnvp import RNVPModule, NFFactory\n",
"from simtk import unit, openmm\n",
"import jax_md\n",
"\n",
"\n",
"# constants\n",
"feature_size=8\n",
"DEFAULT_TEMPERATURE = 300. #kelvin\n",
"from openmmtools.constants import kB\n",
"kT = (DEFAULT_TEMPERATURE * unit.kelvin * kB).value_in_unit_system(unit.md_unit_system)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "108ea957-4460-4c94-8a18-bfb5a8148c93",
"metadata": {},
"outputs": [],
"source": [
"from openmmtools.testsystems import AlanineDipeptideVacuum"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "626ba452-33ef-44a5-9ae6-eedc98955938",
"metadata": {},
"outputs": [],
"source": [
"ala = AlanineDipeptideVacuum(constraints=None, hydrogenMass=4.0*unit.amus)\n",
"top = ala.topology"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "e078c173-3573-4aab-960f-57ff8d4e1653",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Topology; 1 chains, 3 residues, 22 atoms, 21 bonds>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"top"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "1c146ac1-9be2-459b-836c-1e1d6590ce58",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"H1 <Residue 0 (ACE) of chain 0>\n",
"CH3 <Residue 0 (ACE) of chain 0>\n",
"H2 <Residue 0 (ACE) of chain 0>\n",
"H3 <Residue 0 (ACE) of chain 0>\n",
"C <Residue 0 (ACE) of chain 0>\n",
"O <Residue 0 (ACE) of chain 0>\n",
"N <Residue 1 (ALA) of chain 0>\n",
"H <Residue 1 (ALA) of chain 0>\n",
"CA <Residue 1 (ALA) of chain 0>\n",
"HA <Residue 1 (ALA) of chain 0>\n",
"CB <Residue 1 (ALA) of chain 0>\n",
"HB1 <Residue 1 (ALA) of chain 0>\n",
"HB2 <Residue 1 (ALA) of chain 0>\n",
"HB3 <Residue 1 (ALA) of chain 0>\n",
"C <Residue 1 (ALA) of chain 0>\n",
"O <Residue 1 (ALA) of chain 0>\n",
"N <Residue 2 (NME) of chain 0>\n",
"H <Residue 2 (NME) of chain 0>\n",
"C <Residue 2 (NME) of chain 0>\n",
"H1 <Residue 2 (NME) of chain 0>\n",
"H2 <Residue 2 (NME) of chain 0>\n",
"H3 <Residue 2 (NME) of chain 0>\n"
]
}
],
"source": [
"for atom in top.atoms():\n",
" print(atom.name, atom.residue)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "36e66893-dd0e-4e47-99e2-bec1675ea133",
"metadata": {},
"outputs": [],
"source": [
"num_forces = ala.system.getNumForces()\n",
"num_particles = ala.system.getNumParticles()\n",
"ala.system.removeForce(num_forces-1)\n",
"dimension=3 #i hope"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "d908f84f-1efc-4658-ae04-b32cfff15f5b",
"metadata": {},
"outputs": [],
"source": [
"from aquaregia.openmm import make_canonical_energy_fn\n",
"from aquaregia.utils import get_vacuum_neighbor_list\n",
"displacement_fn, shift_fn = jax_md.space.free()\n",
"vacuum_neighbor_list = get_vacuum_neighbor_list(num_particles=num_particles) #get a vacuum neighbor list\n",
"# u_params, u_fn = make_canonical_energy_fn(system = ala.system,\n",
"# displacement_fn = displacement_fn,\n",
"# kwargs_dict={'neighbor_list': vacuum_neighbor_list}\n",
"# )\n",
"\n",
"u_params, u_fn = make_canonical_energy_fn(system=ala.system,\n",
" displacement_fn=displacement_fn,\n",
" omit_unhandled_forces=False)\n",
"beta_low = 1. / kT\n",
"logp_posit_posterior = lambda _x: -u_fn(_x, vacuum_neighbor_list, u_params)/kT"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "f0ff1fa2-84e7-4f33-9164-d001771916f7",
"metadata": {},
"outputs": [],
"source": [
"import os"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "dd9e6b85-2696-4854-bc31-b3e26df73d0f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'/mnt/c/Users/domin/jax_flow/ala2/dimer_experiments'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"os.getcwd()"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "1505f003-e1eb-4bca-bd3a-e48eb4f282a7",
"metadata": {},
"outputs": [],
"source": [
"low_dict = jnp.load('/mnt/c/Users/domin/jax_flow/ala2/ala2.T0.npz')\n",
"low_positions = Array(low_dict['positions'])\n",
"low_omm_energies = Array(low_dict['energies'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "373bda1f-7c02-444e-8c95-4915deed4048",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 11,
"id": "c0017d01-1ace-40ac-bce4-f3dffe66a224",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"22\n"
]
}
],
"source": [
"import numpy as np\n",
"from rdkit import Chem\n",
"from rdkit.Chem import RDKFingerprint, rdFingerprintGenerator\n",
"from aquaregia.utils import compute_atom_centered_fingerprints, generate_edges_from_mol\n",
"import mdtraj as md\n",
"from rdkit.Chem import SDMolSupplier\n",
"suppl = SDMolSupplier('/mnt/c/Users/domin/jax_flow/ala.sdf', removeHs=False)\n",
"for mol in suppl:\n",
" print(mol.GetNumAtoms())\n",
"\n",
"\n",
"fpSize=feature_size\n",
"generator = rdFingerprintGenerator.GetRDKitFPGenerator(minPath=10, maxPath=10, fpSize=fpSize)\n",
"fp = Array(compute_atom_centered_fingerprints(mol, generator, fpSize, normalize=True))\n",
"edges = Array(generate_edges_from_mol(mol, normalize=False))[:,:,0]\n",
"normalized_fp = (fp - fp.mean(axis=0)) / fp.std(axis=0)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "d14565eb-2e2e-457a-8f67-564b8738afca",
"metadata": {},
"outputs": [],
"source": [
"feature_dict = { 0:normalized_fp[..., jnp.newaxis], 1: None}\n",
"\n",
"from aquaregia.cnf import VectorModule, make_diff_fn_inits\n",
"from aquaregia.integrators import thermalize"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "02c6a419-8527-4686-953f-78ac2d9f3bb6",
"metadata": {},
"outputs": [],
"source": [
"VectorMLP_kwargs = make_diff_fn_inits(feature_dictionary=feature_dict,\n",
" time_convolution_mlp_kwargs = {'output_sizes': [8,8], 'activation': jax.nn.swish},\n",
" conv_mlp_kwargs = {'output_sizes': [16,16], 'activation': jax.nn.swish},\n",
" tf_mlp_kwargs = {'output_sizes': [16,16], 'nonlinearity': jax.nn.swish},\n",
" SinusoidalBasis_kwargs={'r_switch': 19., \n",
" 'r_cut': 20.,\n",
" 'basis_init': hk.initializers.Constant(constant=jnp.linspace(1e-3, 19., 16))})"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "eca79844-20fb-4bdf-9fe5-ab0ce958d39c",
"metadata": {},
"outputs": [],
"source": [
"nf_factory = NFFactory(position_dimension=(22,3),\n",
" logp_position_posterior = logp_posit_posterior,\n",
" posterior_train_samples = low_positions[:1000],\n",
" posterior_validate_samples = low_positions[1000:1100],\n",
" RNVPModule_kwargs = {'VectorModule_kwargs':VectorMLP_kwargs, 'num_iters':4}\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "fae1591e-37e8-453e-a0f4-414fe394b99f",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/dominic/anaconda3/envs/aquaregia/lib/python3.10/site-packages/jax/_src/tree_util.py:185: FutureWarning: jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() instead as a drop-in replacement.\n",
" warnings.warn('jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() '\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"training...\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"Bar desc: 0%| | 0/5000 [00:00<?, ?it/s]/home/dominic/anaconda3/envs/aquaregia/lib/python3.10/site-packages/jax/_src/tree_util.py:185: FutureWarning: jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() instead as a drop-in replacement.\n",
" warnings.warn('jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() '\n",
"-84.33761559433347: 100%|███████████████████████████████████████████████████████████| 5000/5000 [22:48<00:00, 3.65it/s]\n"
]
}
],
"source": [
"out_params, train_vals = nf_factory.train(key=jax.random.PRNGKey(36), \n",
" batch_size=16, \n",
" optimizer=adam, \n",
" optimizer_kwargs={'step_size': 1e-3}, \n",
" clip_grad_max_norm=1., \n",
" num_iters=5000)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "8443f779-d7a0-4cb0-b846-2989a058a8d6",
"metadata": {},
"outputs": [],
"source": [
"from matplotlib import pyplot as plt"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "b9394f4f-5d7b-4cd7-92f1-8264a45c900a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x7f67ea032830>]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAXkAAAD4CAYAAAAJmJb0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/YYfK9AAAACXBIWXMAAAsTAAALEwEAmpwYAAAt3ElEQVR4nO3deXxU1dnA8d+TnbBvYYewI7sQUKuCICibYvWtS21damu11rrWgriv1Pq6VW21KtqK8lJXFEEBUdkhKMgOAcIOCSBbAlkm5/1j7kzuZGaSkJnJJHee7+eTDzPn3pl7zjDz3HPPOfccMcaglFLKmeKinQGllFKRo0FeKaUcTIO8Uko5mAZ5pZRyMA3ySinlYAnRzoBds2bNTHp6erSzoZRStcrKlSsPGmOaB9pWo4J8eno6mZmZ0c6GUkrVKiKyI9g2ba5RSikH0yCvlFIOpkFeKaUcTIO8Uko5mAZ5pZRyMA3ySinlYCEHeRFpJyLzRWSDiKwTkTus9CYiMkdEtlj/Ng49u0oppU5HOGryxcA9xpgzgLOB20SkJzABmGeM6QrMs55HzGer93I0vyiSh1BKqVon5CBvjNlnjPneenwc2AC0AcYD71i7vQNcFuqxgtl+MI/b3/+Bu6avitQhlFKqVgprm7yIpANnAsuAFsaYfeA+EQBpQV5zs4hkikhmbm5ulY6bX1gMwNcbcyh2lVTpPZRSyonCFuRFpB7wIXCnMeZYZV9njHndGJNhjMlo3jzg1AuVeI/SxzdMWVGl91BKKScKS5AXkUTcAX6qMeYjK/mAiLSytrcCcsJxrIoszDrIqSJXdRxKKaVqvHCMrhHgTWCDMeY526YZwPXW4+uBT0M9VjCuEt91aifP2hipQymlVK0Sjpr8ucCvgeEissr6GwNMBkaKyBZgpPU8IprUTfJ5/vbibG2bV0opwjDVsDFmISBBNl8Y6vtXRrsmqX5p8zflMrJni+o4vFJK1ViOvePVM+JGKaVimWODvLbLK6WUg4P8vqOnop0FpZSKOscE+ezJY8mePDba2VBKqRrFMUFeKaWUPw3ySinlYBrklVLKwRwX5O8Z2S3aWVBKqRrDcUF+ZC+9AUoppTwcF+R7tGwQ7SwopVSNEfK0BjVRp2Z1o50FpZSqERxXkwfo3rI+8XHBptNRSqnY4cggbwxsyTkR7WwopVTUOTLIz163H4DDeYVRzolSSkWXI4O8R3GJzimvlIptjg7yxlS8j1JKOZkjg/zj43sBUFyiUV4pFdscGeRTk9wjQ10uDfJKqdjmyCDvGT6Zp6tDKaVinCOD/LyNOQD87ctNUc6JUkpFlyODfH6BuwZ/4JiuDqWUim2ODPKe5hqXdrwqpWKcI4N8Qrw7yOvoGqVUrHNmkI9zF0tr8kqpWOfIIH9+12YADEpvHOWcKKVUdDkyyJ/TuSkA3XVueaVUjIt4kBeRUSKySUSyRGRCpI8HECfuNvnHP19fHYdTSqkaK6JBXkTigVeA0UBP4BoR6RnJYwJoS7xSSrlFuiY/GMgyxmwzxhQC04DxET4mRmcmU0opIPJBvg2wy/Z8t5XmJSI3i0imiGTm5uaG5aAa45VSyi3SQT7QGnw+IdgY87oxJsMYk9G8efOwHLRJ3aSwvI9SStV2kV7IezfQzva8LbA3wsekbnICrRum8LMuzSJ9KKWUqtEiXZNfAXQVkY4ikgRcDcyI8DEBOHqySOeuUUrFvIjW5I0xxSLyR+BLIB54yxizLpLH9MgrdLFgy8HqOJRSStVYkW6uwRjzBfBFpI+jlFLKnyPveFVKKeWmQV4ppRxMg7xSSjmYBnmllHIwDfJKKeVgGuSVUsrBHBvku6bVi3YWlFIq6iI+Tj5a+rRpyMkiV7SzoZRSUeXYmnxcnOhslEqpmOfcIC9QolFeKRXjHNtcMz1zd7SzoJRSUefYmrzH0ZNF0c6CUkpFjeOD/I5DedHOglJKRY3jg7yrRNvllVKxy/FBXmO8UiqWOTbI/+bcjgA0rOPYvmWllKqQY4P8wA6NAa3JK6Vim2ODfLxVsmKXRnmlVOxycJB3F01viFJKxTLHBvmEOAGgWNtrlFIxzLFBPs4K8q6SkijnRCmlosexQT7BG+SjnBGllIoixwb5eE9zjUZ5pVQMc2yQP5JfCMCL87ZEOSdKKRU9jg3yh/LcQX7Z9sNRzolSSkWPY4O8p01eKaViWUhBXkT+JiIbReRHEflYRBrZtk0UkSwR2SQiF4ec09PkGSevlFKxLNRIOAfobYzpC2wGJgKISE/gaqAXMAp4VUTiQzzWadGavFJKhRjkjTFfGWOKradLgbbW4/HANGNMgTFmO5AFDA7lWKcrXoO8UkqFtU3+N8As63EbYJdt224rzY+I3CwimSKSmZubG7bMaE1eKaUqscariMwFWgbYNMkY86m1zySgGJjqeVmA/QPOL2CMeR14HSAjIyNscxDEaZBXSqmKg7wxZkR520XkemAccKEx3tnAdgPtbLu1BfZWNZNKKaWqJtTRNaOAvwCXGmPybZtmAFeLSLKIdAS6AstDOZZSSqnTF+qySS8DycAcEQFYaoy5xRizTkSmA+txN+PcZoxxhXis05KSWK2DeZRSqkYKKcgbY7qUs+1J4MlQ3j8UQ7o2i9ahlVKqxnDsHUPWlYVSSsU0xwZ5pZRSDg/yl/RrTauGKdHOhlJKRY2jg3zdpHhd41UpFdMcHeQT4oUilwZ5pVTscnSQ37DvOIfzCtlz5GS0s6KUUlHh6CC/csdPAHy3OXxz4iilVG3i6CDvoc3ySqlYFRNBXjtflVKxKiaCvKtEg7xSKjbFRJAvcpVEOwtKKRUVMRHkCzXIK6ViVGwE+WIN8kqp2OToIO9ZAlCDvFIqVjk6yCcluIunQV4pFascHeSf+Z++AAzs0DjKOVFKqehwdJDv2KwuAIfzC6OcE6WUig5HB/l4q01+0sdro5wTpZSKDkcH+ThdHUopFeMcHuSjnQOllIouRwd50CivlIptjg7yWpNXSsU6hwd5jfJKqdjm6CCvMV4pFescHeS1Jq+UinWODvINUhKjnQWllIoqRwf5hqka5JVSsS0sQV5E7hURIyLNbGkTRSRLRDaJyMXhOI5SSqnTkxDqG4hIO2AksNOW1hO4GugFtAbmikg3Y4wr1OMppZSqvHDU5J8H7gPsC6mOB6YZYwqMMduBLGBwGI6llFLqNIQU5EXkUmCPMWZ1mU1tgF2257uttEDvcbOIZIpIZm5ubijZUUopVUaFzTUiMhdoGWDTJOB+4KJALwuQZgKkYYx5HXgdICMjI+A+4eAqMd5ZKZVSKlZUGOSNMSMCpYtIH6AjsFrc49HbAt+LyGDcNfd2tt3bAntDzm0I8guLqa9DKpVSMabKzTXGmDXGmDRjTLoxJh13YB9gjNkPzACuFpFkEekIdAWWhyXHp+mawe5zzec/7ovG4ZVSKqoiMk7eGLMOmA6sB2YDt0VrZE3dJPfFyuOfr4/G4ZVSKqpCHkLpYdXm7c+fBJ4M1/tXVXy8ux3eVRKx5n6llKqxHH3HK0C8aJBXSsUuxwf5BGtETbEGeaVUDHJ8kI+Pc3wRlVIqKMdHwHjHl1AppYJzfAiMs90AdapIp85RSsUWxwf5BFuQ33k4P4o5UUqp6uf4IK9t8kqpWOb4CBiv09UopWKY44N8nE5KppSKYc4P8rbFvDXcK6VijeOD/P8MbOt9/M0mna9eKRVbHB/kUxLjvY837j8exZwopcLBGMOGfceinY1aw/FB3q7QVRLtLCilQvTJqj2MfnEBX63bH+2s1AoxFeQ/Wx3VdUuUUmHguSLfmpsX5ZzUDjEV5JVSzmECryiqytAgr5SqVcQaJ2c0xldKTAT5M1o18D42+s1QSsWQmAjyf7/mTO/j/yzdEcWcKKVCJXrDy2mJiSDfJa2e9/FDn67j2KmiKOZGKRUKjfGnJyaCfFnvLdsZ7SwopVS1iMkgP3nWxmhnQSmlqkVMBnmlVO2ngygqR4O8UiosDhw7xbTlkW8K1Y7X05MQ7QwopZzhN2+vYN3eYww/I420+ikRP55W5CtHa/JKqbA4dKIQgGJXZKOv92aoiB7FOTTIK6VqFW2uOT0hB3kRuV1ENonIOhF5xpY+UUSyrG0Xh3ocpVTNsS33BOkTZrIo66Dftj9/sJqj+XovSk0RUpAXkWHAeKCvMaYX8KyV3hO4GugFjAJeFZH4oG9UDf51XYbP812H86OUE6Vqv+XbDwMwY1XpzK6eGvairEO88k1WNLKlAgi1Jn8rMNkYUwBgjMmx0scD04wxBcaY7UAWMDjEY4UkOcG3qC/O2xKlnChV+3mW1Syx9X7aW1GqY3ijdrxWTqhBvhtwvogsE5FvRWSQld4G2GXbb7eV5kdEbhaRTBHJzM2N3PJ8Zb8P2qynVAisH1CJ7Ycl1dRYXlN+uyUlhqdnbWDvkZPRzkq5KhxCKSJzgZYBNk2yXt8YOBsYBEwXkU4E/n8IeN41xrwOvA6QkZERsXPzoPTGPs/X7dXlw5SqKk9NPpbndF+9+wivfbuNH3YcYfot50Q7O0FVWJM3xowwxvQO8Pcp7hr6R8ZtOVACNLPS29nepi0Q1WWZUpMSeOrnfbzP1+87xpBn5kcxR0rVXnFWNS4qTSbWCeb95TuZtWZfFDLg5rmKKSqp2cuKhtpc8wkwHEBEugFJwEFgBnC1iCSLSEegK7A8xGOF7Jdntfd5vvNwPicKiqOUG6VqL/E21xi/tIgf2/p3/7FT3Dr1++o5aC0WapB/C+gkImuBacD1Vq1+HTAdWA/MBm4zxrhCPFZE/ObtFdHOglK1jie2x9kie6yOX6/pHcAhTWtgjCkEfhVk25PAk6G8f3XwDAVTSlWeJ7DZ47rUmC7R6lFbTmp6x6tSSjlYzAX5Dk1To50FpWo9bwuFrTZbbW3ytaQGXVPEXJC/eUgnv7QX524hfcJMpi7T9V+VqgzPzU72JppYjb01vEk+9oL8tWd18Et7fu5mACZ9vJaThS6u/OcSvly3v7qzplStUVFgq+mdkeHgPanV8MLGXJCvyBkPzWZ59mF+/5+V0c6KUjVeNJpOakoHb2mTVdXyk3u8gEc/W0exK7Lj7GMyyP8+QJNNIO9bq9wcOlHAsVPuWfV+3H2Ef323LWJ5U6pWCDS6prqmNagZMd7bZBVXxfw8PGMtUxZl8/XGnIp3DkFMrgx12/AuvFaJQD3xozXc//EajHH/Rw7vkcbcDe7/kKycE8TFCU9f3qeCd1Hh9MHK3VzQvTnN6iVHOyuOsnLHYbbm5nFlRruKd6Z0OgN7wK0hsTfs1u45SkpiPF3S6gXcXtVyFxa7a/CRPjnGZE0+7jQ+VE9zW4nBG+AB/i9zF+8v38lbC7cDcLLQRd9HvmTehgNhzasqtefISe7972pufVeb0sLtin8s4b4Pfqz0/gGboav5jtfqMu7vCxnx3Ld+6aE2xZd4bygL7X0qEpNBvl5yAj1a1g/Lez32+XrW7jlK9qE8jp0q5qZ3MkmfMJMlWw8B7sUVThXVyJt9a50iq+Zz4FhBlHOiPGJ5dI0nxle1Jl7ibe6J7CcXk801AGP6tGLj/uNhea+JH62hQR3fj/KFuZvZtL8lj3y2nrF9W3FVRjtaNEihe5hOLrFIZz6sOUoDXPB9il0l3DBlBX+6sCuDOzYJ7XjG0HHiF9x7UbeQ3icSqhqivdM0R/jsGLNBvk+bhmF7rzV7jvqlLdt+mGXWlAmz1+5n5o/u2fKyJ48N23FjjXdSrJo96V9M8E5r4HMzlG+02nf0FAuzDrL9YB6f334ejesmVfl4noD47FebuWdkzQj0JSWhVTZMNdXkY7K5BmBYjzTm3DWkWo7lCvHLoNw8v4WiCA85UxULdDUVLFTtOXKSMx+fw7bcE1U+XjRmu6yIy/h3Pp8Oo23ykde1RfU3nfzyX0s5VeTiaH4Rh05o2/Lp8NR48gu1j6PmqPwslDtCWFe5Jt5vVDpJm7bJ12hN6iZxOK+Q+Diplhr34q2HGPPSArbl5gHwxGW9eeCTtbRumMKnfzyP5vV1aGAwJUF+6W8s2MbwHml0ah54iJsKv0DNNT7bw3w835r86YyOM2w6cJweLRuEOUehX6GXhHglUFkxXZMHmHPXEObcNYRl919YbWPePQEe4IFP1gKw9+gpZq31XeVmw75j7DiUh3Lz/M7ti0SfLHTxxMwNXPna0ijlClbtOuId8xwrAvUZlq3R+gWvSsTE7IN5bAowIKKqNfl/L9nBqBcW8O3m8K8f7Qo037LN2j1HeX7O5qCvLx1CqW3yEdW0XjJdW9SnWb1kxvdvTc9WDfjw1nOokxhPQqQby8rIsYYGLtt2iHkbDjD6xQUM/ds31ZqHmsx+z4KHpzZ0oqAopPdekX2YrJzTbzPemnuCy15ZxFNfbAjp+LVOgKhbNlZVZWjhBc9+w8UvfOeXHuwqriKeealufy/8K0h5Ol6DlfKyVxbx4rwtPpUSu9JJ3iIr5oO8XWpSAl/ccT4DOzRhw+Oj2Pj4KNo2ruOzz7ldmkbs+C/PzyLn+Cmuen0pN72T6U3/LgK1kOpWUmKY9PEaNu6v+gLqnh+6vdPPe8kb4k/lF/9cEvCGl4oczisE3LU2JytylbDlgH8Nu7w47jf6xLbv0ZOnd1KuasPIkXz3cY6dCv8yn8Ul5bepe7YHOz95Pp5INxJrkC9HQnwc3/55mE/aHRd24+4IDuEa/OQ8v7Tr3lpOz4dmY4zh0IkCb2AJ5KLnv+Wq15ZELH+VUVDs8qu97DlykqnLdnLT25lBXlUxb5C31+StVpJojZ2viR2CkfD0FxsZ+fx37LI6T0uba4JHeb/Pxno+Z/0B+j36FSuyg6/KVrZiU9WafCR52uTjK7jiD5b3QN/nSNAgX4H4OGH5/Rey+YnRfH3PUAZ3bMLtw7uQ9eTogJ2kN56bztpHLw57PvILXVzy8kIGPjGXAY/PYc3uwDXHzQdOsGz7YZZvPxzyON6q+CmvkO4PzOaf3/rODeQdSVCFb9zxU0WkT5jJW4vcU0jYS+WK8o/fVFPnWbRl7nAHZE8FI1DHa9mbC4MFN8/d4Kt3HQl6vOveWs7eIye9z42ty6Myn/XxU0UR//57a/IVBvnA6bsOu8s3u0xfXLhpkK+EtAYpJCXEeUdviAgJ8XGsmDSCWXecTxPrJo+zOzXh4Ut6US85MoOW1u4pbeq45OWFnPXUXIY8Mz/gtAlXvraEcya7rwq25p4gfcJMJn60hhunLI/o4uW51rDQD7/f7ZMeSieT55L73aXuWUHtUT7a9yBUpkbrRMHame38TsDWR1TZr0B+YWkTy+nU5PMLi+nzyFcR7yfxTBFcUdfdJz/sCZh+0PqtvL98V1jzVZYG+RCd0aoB7/3uLACuGdzem/7ni7tH/BbsA8cK2Hk4nx4PzubGKe4mnbLbj50q4oedRwD31MnzN+WGfWrTGav38saCbVz31nJvEC9bi/Je2pbzC/964wH6P/YVJ61x8L95ewWPfba+3MvhSAf5R2asY35lPi+HxPgN+9wViemZu3jbunIKpOzomkBB3y+t7NMK/uvs2+27lt9EZPi/Fe6g+cmqveUfIEQVtcl7LMg6WO72Qp1Pvubr0bIB6x69mPH923jTbhvWhT8O71pteZi/KTfgTUK/emMZ9/53tV96+oSZTM/cRZGrBGMMf/tyI5v2H8dVYvjtO5l0mzSLRVkHOWrVorflnmDWGv/LysVZB/nT+z/wxMwNfLc51xuQtx30HfpZmWaNp7/YyJH8Inb95G73/XpjjreJxue9bD/5yjbXVLX56u3F2dxoXfkcOlHAs19u8jmx2A9/JL+w1k9GN/rFBQDc98GPPPLZ+gr393SgBvpvKPtxL7fa4D1fgSe/2MAbC4JP+V1gG5Za2Zr8J6v28Ggl8h0OrkoG+WCLgtgnSTwZwRv8NMiHSd3TaKL57y3ncO1Z7SveMQx+DNJ2D+4fctdJs1i39xivzN/KxS98x30f/MjcDQcodJVw7RvL6PfYVyzOOsjw//2WW6d+T7GrhEdmrOMPU1eyLfcEv3xjmc97LgxSa/EE4+NVGOXg13/n0/Fa8Y//u825XPnaEt5YWPEaAsYY5m/KCfije/DTtbw8P4sFW/xHOwnQ/7E5/PrNZX7bnMDzmb84bwvZB/O8zz215bJB+Ke8Qr+rrH98s9Wvdv/EzOBNKvZmRfv7l9fJvvlA6TDYk4XhHVFT9p6VyjbXFLkC57dNo9KRe69+kxVa5sqhQT7Cyo7EyXpyNIPSm4Q8K184jfv7Qu/jsm3pgE8g7zJpFm8vzuaLNfsD3qaeX1D6w/p+50/eoYU/7nL/m3O8gOfmbCZ9wky/H3ywn27ZQF5cYnCVGDbuP0bO8VPu1wZ48XvLdnLtG0vZ/ZO7g8t+E1owczfkcOOUFUz6eI3ftlNF7h91scs/4PxgdSKuyP4JgDW7j/Ln/67mVJGLEc99y6IKLtkjbf6mHBaHIQ9fb8zhhinL/dLLnms/+mFPwNp3cTkn5bv+b5XP85zjtmk/7E03Za8QtgcepZNXydqxMYaHP13LE5+vZ/dPvt9pz5UswNC/feNzpVZec439O+uyzahnjOG5OZvZuP+Yz/f9+50/VSqvVaFBPsL+OKwL39x7gfd5Qrz7Ix/TpxX3jOxWbTX6SCgKcJenvfnk8lcXM+7vC8nKOc59H5YuSPHSvC3ufUsMxhj+/N/VnPP0PHYecv/ABHyahgI1gbw4bwujXljAFf8IPlz0/o/XsCjrkPdGqbI356RPmEmPB2f5BOA86yS19WAe06zlHz287c/2ROtJ2Tteb3x7Bf9duZuVO34iK+cED89Y57P9ic/Xkz5hJqeKXDz62TpOFBRzqsjF1GU7/E5qWTnH/caVu0pM0BFWdrsO5/PcV5u4ccoKfvnGsnKbRyrrZJHLZ5K4tXuOBgzoVwW4C7m8yeU+DtJBCe67ij3KVg4+XOlfMTkduScKeGfJDt5YuJ0r/+n7fZq/ybc/xp7/8oZQ2n8HxSWGiR+tYdm2Q+QXunhp3hau/OcSn89sUdYh7/c/3GJ+7ppIi4sT0pvV9UtPjI/j9gu78vXGA0xdtjPAK2u+mwMsdu6p7dqNeM7/DkaAV7/ZynMBbvs+VVTCrVNL71D0tBPbfb/Dt+ZTUFxC+oSZPHppL67/WbpPIHjqi42Au+N58daDDEpvwv1jzvAe61rblcrbi7MBOHGqiAkfldbmi10lpVMdG/fJacbqvTSokxiwbJ7ffWltz3f7G9aKYu8u3cGURdmkJMYTJ/DK/K3UT0nk0n6tvft6Pj/PNNVvLtzO45+7250/++N59Gnb0Lvv1GU76N26If3aNQLglndXsm5v6aisJ2ZuoHn9ZL5ad4A+bRtyy9DOAfNfEXv/z7i/L+Spn/tPCXKiwL+5pKjY+PXLPPDJGu9wwrKMMYgIr36z1Zbmu8+eIyf5fudPHD1ZxD9s+5W1+cBxugWYlDApvrSuu//YKZ9tZZuc7M88zTCBauH21x07WcT7W3by/vKdrHnkIsD9vUhNivd5zcG8Ato3TQ2a/6oKKciLSH/gn0AKUAz8wRiz3No2EbgJcAF/MsZ8GVpWa79AbXeD0kubbebcNYSRzwcOiLWFp5ZeGYECPLiHh9oFusQPFEAAHp6xjjaN6pCaHB9w+45D+ew4lM8HQWp/nhpj2ZrztBW7SLAG+btKDHPWH+COaau8wbQszyW851Ld3lZs5+lcnL8xx1sjLO9u0P1HT3kDPMCBY6foQ2mQn/Sxey4kzwkhUN/CHdNWATBzzb5KB3n7mgkHjhXwYpn/5/sDNG8FUhRgMQDv0NgAPli5m19ktPPphC37bViYdTBoX5BdXpDvjF2JcTe1eMa+l+3YD9QMs++o74nB/T6l+622XXF5ii/4jxKK1C0fodbknwEeNcbMEpEx1vMLRKQncDXQC2gNzBWRbsaY2j30IASrH74o4GVd/ZTSmmDXFvW9P87b3/+Bz1ZHdghYbbaqnBtpfvvvqt9V63HwhO9dxXkFxSQmuIP824uzObdzMwByjvn/wO+ZvtpbI7S33+86nE9ag2RvHwG4a+XgeyPRg5+s5ekvNrD+sVE+77t460FunOJ7j8OmA8cZ0bNF0HLsPhK4huzzHuWskHY0v4gTYezALHKVnNacNp77LjxDO6HqwXD7wTzObN/YJ2165i7aNvKduuSdJdks3XaIxqlJnNm+kc82T7Pc0m2HeGle8M7SYEN7i0s8nbXifVwqMlE+1CBvAM8cng0BT1QaD0wzxhQA20UkCxgMRPd++yhqGOSyHmDBfcN87u4DeOGq/hzOK2BR1iHuG9WdOonxvDI/yy/4qOoxddlOMjq4A8Ry645iCFyLs3de25u0Zqzey9++3OSzb7ApKvILXfR6aDbrbIH+9/9e6VOjBfjbl5uol5xAckIcndNKp1p2lRhW7fqpwtkxH/xkLf9ZusMnzd7UdebjX4V1Go+iYnNatxS8/HUWvzm3o0/ageP+n3ll3D19NWP6tCIl0X2Vlz5hZsD99h09xZfrDgDQt20jn22Dn5pH9uSxXP16+bOeButf9gZ/8T8RROqWj1CD/J3AlyLyLO5O3J9Z6W0A+6ew20rzIyI3AzcDtG9fezshQ9GuSSrtmvi2xcXHCW9eP4hDeYXeoVYXdE/jy3X7mTxrY8D3Gd+/NZ9G+AaQWLXzcD47Q1j0AvAL8BXJK3TxwCelzSDHy2miKqvz/V9U6hhlAzxAx4mlry0x7iX3wiVQc0158gtdjH95kU/aeyH0YfV4cDZTbhzE3PUHKrV/oPsw7pj2Q4WvCza0t8g2IqdsM2SkmmsqHF0jInNFZG2Av/HArcBdxph2wF3Am56XBXirgEUwxrxujMkwxmQ0b968quVwpJTEeJ+xtB2b1eWGn6UH3f+y/m145JKeAbd1j8IqWCp05bVX10bbcvN47bvTG+GzKcDsl6G4ccqKcgc77LKdzAPdyRuoIuUqMez+KZ8nPl9PQbGLDUFmW3W5Sm8KLFuTLyiOTGu2VGYOiqAvFjkKNDLGGHE3tB01xjSwOl0xxjxt7fcl8IgxptzmmoyMDJOZGXp7qtNlH8yjZcMUVmQf5tdvuscsf/Gn8+nZunT1m12H8zn/mfne5y9c1Z+8wmKWbjuM4G46UEqFx/ldm5FXUMz31hQiwfz1ij785cM1NEpN9M7JZOfpkztdIrLSGJMRaFuozTV7gaHAN8BwwNPlPgN4T0Sew93x2hXwv4NCVYlnSOb5XUuvfLq18F36rmzzT2J8HNee1YFrz+oAwIieLfhuc27QUSZKqcpbsOWg35DIQP7yobv5LVCAj5RQb4b6HfC/IrIaeAqrbd0Ysw6YDqwHZgO3xfLImuoQaMTCwr+UzoV/Rivf5ppL+7VmeI80AB4a15MtT45m4ugeTP3tWZHNqFIOVVMXmA+pJm+MWQgMDLLtSeDJUN5fVeysjk1Ytv1wwE6Qto1TyZ48lsLiEpIS/M/no3u3ZMqNgxjatTlxccLvh3YOetdd7zYNWLvnGG0b1/EZAti5eV1aNaxTqXHKSqnqp9Ma1HJv3jCIWXecX+7CBYECPLhr/8O6p/m8tn3TVD689Ryeu7KfN218/9a8e5O7hn9Z/zbMvXsI8+4ZyiOX9OQ/N53FS9ec6ffes+443/v48fG9fLb9aXgXxvRpWWHZJo7uUeE+quaJxKI5gVT3Gsy1lQb5Wq5ecgJntGpQ8Y6nYWCHJlw+oC3/us7dj9M4NYlGqUmsfugi7h7ZjS5p9encvB43nNuR1o3q0KRuEtmTx7L64Yu872HP04AOvjeg3H1Rd1755YAK8+FZjMVjTJ+WLLhvmN9+N53X0S+tKoZ119Fd4WAPvpEMxCsmjQi67eYhnSJ23NpGg7wKasQZaTx+WW/+Mspdo26YmljuFUN5N3xNvrwPvz2vo3dIaKA+hF8MbAtA/ZQE/npFH64Y0JY02xKLvVo3pF2TVH53fmlQX/3QRTw4znfYaPsmFc//IeIfJF69diDJtquejs3q8vIv/a9SVHA3/Czd5zOsykpgldE4NZHGZSoBdvde1D0ix62NNMiroESEX5/dgTqVGDXg8c9fDfSuiOVZFEEQrh7cngfG9WTRhOHefa8Z3J7LB5TeI/fY+N4A/O78Tlw1qD1xccJXdw3h6cvdk1+dZU3PPGlsT7InjyV78lgaprpPLH+9onSCrA9uPccnT559/3BB6Twtc+4a6rdGb52keDY9Mdr7/D83DWZc39akVzBplKcDuyr+HqCpqzZLToxDRGjb2H0yD7QOcmW0bJBS7vbzuvpedXW13e3bo2X9oE2U4dauSR3vndCB9A8yt1EgnQJMZBgOGuRVWI3q3dK7IlZFq9g/fXkfnruyP+C+aqiTFM/2p8dw+/Au3n0apSZxzeD2bHpiFBm2ydzK6mytvzu2byvS6qcwpJs7CFwzuJ13n/tG9fAG/C5p9QK+D8CvznbfeV0/2X0C+fKuIWwoM4+MO2+JLJk4nLduGFRuORdNGO4zq6SnGQzgElt6VdhPXDWBp+b+0R9+xnu/O4vpt5SecMteYc23TcFt17JBCl/fO5S3bvAd9j3SNkePp8/osv7uz+/+MWd4ryBm3zkktEIEsHzShQHTm9VL5grrCjSQ1o3KP1n5iFDLlk41rCLm1WsH8PbibJ9lzgL5/sGR3sXPg01elZxQ/tXEwA6NeXx8Ly61lmB89hd9ue7N5VVagvGRS3px27Au3quEQMd+7sp+XD6g9Mf90jVnsutwPud0bsq05TuZnrmbp37eh6sHtSMuTnjpmjMZ27cVJ04Vc37XZvRoWZ87R/jmbUD7Rny/8wiX9mvtvVlt5QMjaFovme4PzPKbtwbcawkfPFHA9MzQ7ndoWjeJ87o244afpfPzVxdzSb/W5U6QVz85geMFxcy9eygN6yTy7tIdvDhvi3cxnLT6KaTVdwe4sjf4nCgoxlViaFgnkc1PjKbbA7N8tn92+3mkJiUwvEcL5t97AcOe/QaA56/qT++H3ZPZJlrTAz96aW86Na/H0G7N+eGhkRGZ/2XTE6NITojnTxd29ZtltUFKYrnNlO0ah3/q4NOlNXkVMR2a1uXhS3qV244P7g7WUC+vRYRfn5Pu/cGl1U9h9p1DfKaFCGTazWf7pSXEx9Gqof/r3rohw3tpPqjMVcWl/Vpz27AuDGjfmJuHdKZ9k1Qu6tXCp+wX92rJFQPbkpIYz+w7hzCqdysAfn5mG8b0acmUGwbz31vO8RmtVC/FffL73yv70SWtnt9NbyLCM//TzyctMd59TE/fRaPU4EGoWT13u3bmAyN48eozObN9Y7Inj/VpRhrSrTlz7x7K1/cM9aZ9e98wXvv1QLqk1aN5/WTuGtmNVQ+NZFj3ipuu6iUneP+fkhLi2P70GObe7X7vOPFt4uloa8Kol5zAI5f05LpzOnjTGqYm8qcLuxIXJ6QmJXgrC2X949rAHf2je5eO8vomyJWF5yQ/8gzf2T5vGdqZZ3/Rr/wKuJQ2FwYz9+7wX3nYaU1exbSzOzWt9L7De7RgeI/g0/p6dEmrx3cBRgEF8/xV/b2Py5484q0rm3F9WzOub2uu+MdiAEac0YIrBvjO+Xdul6Y0Sk3imSv6ehchmTTW3Sm9YEsuZ3Vs6lNrvnNEV64Y0JYV2YcDXkGtfsg9Wqqh7STx6rUDmLJoO03qJnFxL99hsI1Sg3eElkdE6JJWjwfH9eTcLv7/H1/fM9S7hvIN51Z+JNX2p8fw7tIdjOnTynuy9Pjuz8NISYojrX6KdzZK++I+6U1TyS5zz0iftg25KqMd/5e5i4EdGjPBGuLbrLx+hwquLDY+Pso78V2kOqk1yKuYt2jC8Eg1h1bZsO7Nmb8p169f45VfDuCjH3Zz69DOPoE568nRxMdJ0OYuzxQYI85IY+6GHLY+Ncb73mWnwPBoGOAKYEyfVozp06pKZapIsKGwnZoH7z8pj+fqziN78lhmr91Pp+Z1fVZg6tA01W/K56/vuYDHPl/vc9UAeDuUf2Frhx+U3oSpvz2LLQeO88hn7gVdJo7uwdOzNtKsXukJoGndJA6VOU5KYrx39slIfQc1yKuYV1GTTjT841cDyT1e4Be0WzZM4Q8XdPHbPyG+cs1db1xffiex043q7X8T3vx7LvBLi4sTHrm0l1/674d2pn5KAr/IaOeTfm6XZjSwLQD0u/M7kdYgmUv6lnasL5l4ISXGECfic0XlOdk2ruKVUEU0yCtVA6UkxgetYavwsvebxEn5i3ckJcQFbTLq07YhN53XEZe1fODPz2zr99pAOjevy0PjejKuX2SukDTIK6WUZcnECzkUwuprZW/MqwwR4Tdhums7EA3ySilladEghRYV3IhV2+gQSqWUcjAN8kop5WDaXKOUUtXsg1vOYVtuXrUcS4O8UkpVs4z0JuXOxRRO2lyjlFIOpkFeKaUcTIO8Uko5mAZ5pZRyMA3ySinlYBrklVLKwTTIK6WUg2mQV0opBxNjIrAoYhWJSC6wI4S3aAYcDFN2aoNYKy9omWOFlvn0dDDGNA+0oUYF+VCJSKYxJqPiPZ0h1soLWuZYoWUOH22uUUopB9Mgr5RSDua0IP96tDNQzWKtvKBljhVa5jBxVJu8UkopX06rySullLLRIK+UUg7miCAvIqNEZJOIZInIhGjnJxQi8paI5IjIWltaExGZIyJbrH8b27ZNtMq9SUQutqUPFJE11raXRESquyyVISLtRGS+iGwQkXUicoeV7uQyp4jIchFZbZX5USvdsWX2EJF4EflBRD63nju6zCKSbeV1lYhkWmnVW2ZjTK3+A+KBrUAnIAlYDfSMdr5CKM8QYACw1pb2DDDBejwB+Kv1uKdV3mSgo/U5xFvblgPnAALMAkZHu2xBytsKGGA9rg9stsrl5DILUM96nAgsA852cpltZb8beA/43OnfbSuv2UCzMmnVWmYn1OQHA1nGmG3GmEJgGjA+ynmqMmPMd8DhMsnjgXesx+8Al9nSpxljCowx24EsYLCItAIaGGOWGPc35N+219Qoxph9xpjvrcfHgQ1AG5xdZmOMOWE9TbT+DA4uM4CItAXGAm/Ykh1d5iCqtcxOCPJtgF2257utNCdpYYzZB+6gCKRZ6cHK3sZ6XDa9RhORdOBM3DVbR5fZarZYBeQAc4wxji8z8AJwH1BiS3N6mQ3wlYisFJGbrbRqLbMTFvIO1DYVK+NCg5W91n0mIlIP+BC40xhzrJwmR0eU2RjjAvqLSCPgYxHpXc7utb7MIjIOyDHGrBSRCyrzkgBptarMlnONMXtFJA2YIyIby9k3ImV2Qk1+N9DO9rwtsDdKeYmUA9YlG9a/OVZ6sLLvth6XTa+RRCQRd4Cfaoz5yEp2dJk9jDFHgG+AUTi7zOcCl4pINu4m1eEi8i7OLjPGmL3WvznAx7ibl6u1zE4I8iuAriLSUUSSgKuBGVHOU7jNAK63Hl8PfGpLv1pEkkWkI9AVWG5dAh4XkbOtXvjrbK+pUaz8vQlsMMY8Z9vk5DI3t2rwiEgdYASwEQeX2Rgz0RjT1hiTjvs3+rUx5lc4uMwiUldE6nseAxcBa6nuMke79zkcf8AY3KMytgKTop2fEMvyPrAPKMJ9Br8JaArMA7ZY/zax7T/JKvcmbD3uQIb1hdoKvIx1d3NN+wPOw33p+SOwyvob4/Ay9wV+sMq8FnjISndsmcuU/wJKR9c4tsy4R/yttv7WeWJTdZdZpzVQSikHc0JzjVJKqSA0yCullINpkFdKKQfTIK+UUg6mQV4ppRxMg7xSSjmYBnmllHKw/wdfU+SmQBbktwAAAABJRU5ErkJggg==\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.plot(np.array(train_vals))"
]
},
{
"cell_type": "markdown",
"id": "133f4dba-a5ed-4edf-a915-b9d06c51a2a4",
"metadata": {},
"source": [
"can we just generate some conformations and look at what their energies are?"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "93077e76-f8cc-4ef6-b3d0-56e0e27aff9d",
"metadata": {},
"outputs": [],
"source": [
"prior_xs, prior_vs = jax.vmap(nf_factory._prior_sampler)(jax.random.split(jax.random.PRNGKey(3226), \n",
" num=1000))"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "7eca346d-ca38-4a1a-9e5b-d58a3931c2e5",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/dominic/anaconda3/envs/aquaregia/lib/python3.10/site-packages/jax/_src/tree_util.py:185: FutureWarning: jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() instead as a drop-in replacement.\n",
" warnings.warn('jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() '\n"
]
}
],
"source": [
"out_xs, out_vs, _ = jax.vmap(nf_factory._rnvp_apply, in_axes=(None, 0,0, None))(out_params, prior_xs, prior_vs, True)"
]
},
{
"cell_type": "markdown",
"id": "c12ea37c-9948-42c0-b901-a82ab8e23dda",
"metadata": {},
"source": [
"now can we save (just) the positions and see if we can look at the outputs to see if they look anything like adp?"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "b8debcd3-22f3-4172-8e16-c7a339231039",
"metadata": {},
"outputs": [],
"source": [
"import mdtraj"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "bb4fa692-6321-40c0-97c3-55113f53c712",
"metadata": {},
"outputs": [],
"source": [
"out_traj = mdtraj.Trajectory(xyz=out_xs, topology=ala.mdtraj_topology)"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "9eb19a75-d9dc-4c0c-9ba0-907daf296627",
"metadata": {},
"outputs": [],
"source": [
"out_traj.save(\"generated_ala.pdb\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "6481c4c0-db82-465d-acad-15dca3b22efd",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "68d092e1-5a7c-468a-8518-6480eba4167b",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 23,
"id": "2c3523ea-dd1f-4a5f-8b6d-d149877b36df",
"metadata": {},
"outputs": [],
"source": [
"prior_xs, prior_vs = jax.vmap(nf_factory._prior_sampler)(jax.random.split(jax.random.PRNGKey(3226), \n",
" num=1000))\n",
"posterior_xs, posterior_vs = jax.vmap(nf_factory._posterior_sampler)(jax.random.split(jax.random.PRNGKey(3456), \n",
" num=100))"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "46837aed-62f3-4f70-b354-5cce3097aabe",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/dominic/anaconda3/envs/aquaregia/lib/python3.10/site-packages/jax/_src/tree_util.py:185: FutureWarning: jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() instead as a drop-in replacement.\n",
" warnings.warn('jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() '\n",
"/home/dominic/anaconda3/envs/aquaregia/lib/python3.10/site-packages/jax/_src/tree_util.py:185: FutureWarning: jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() instead as a drop-in replacement.\n",
" warnings.warn('jax.tree_util.tree_multimap() is deprecated. Please use jax.tree_util.tree_map() '\n"
]
}
],
"source": [
"forward_works = nf_factory._forward_batch_loss_function(out_params, prior_xs, prior_vs)\n",
"backward_works = nf_factory._backward_batch_loss_function(out_params, posterior_xs, posterior_vs)"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "c05fed6e-adca-461a-9fe2-f5213a200d46",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DeviceArray(89564.2277343, dtype=float64)"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"min(forward_works)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "06235f63-92e6-40d3-9770-80c727d9c225",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"DeviceArray(458, dtype=int64)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"np.argmin(forward_works)"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "11c46143-c523-4775-b5de-508f43ec5472",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([ 2., 3., 9., 23., 19., 24., 13., 6., 0., 1.]),\n",
" array([ 57.4636161 , 62.38628219, 67.30894827, 72.23161435,\n",
" 77.15428043, 82.07694651, 86.99961259, 91.92227867,\n",
" 96.84494475, 101.76761084, 106.69027692]),\n",
" <BarContainer object of 10 artists>)"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.hist(np.array(sorted(forward_works))[:100], alpha=0.5, bins=100)\n",
"plt.hist(-np.array(backward_works), alpha=0.5)"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "41249714-f8e0-4bc8-8fcf-f1756dc63e6d",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(array([ 2., 3., 9., 23., 19., 24., 13., 6., 0., 1.]),\n",
" array([ 57.4636161 , 62.38628219, 67.30894827, 72.23161435,\n",
" 77.15428043, 82.07694651, 86.99961259, 91.92227867,\n",
" 96.84494475, 101.76761084, 106.69027692]),\n",
" <BarContainer object of 10 artists>)"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.hist(-np.array(backward_works), alpha=0.5)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f6cc92aa-5d63-45dc-8887-88e51913dd55",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.4"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment