From 3b1cef246c9f57be568de09a4ea256079e618029 Mon Sep 17 00:00:00 2001 From: KuangYu Date: Sat, 21 Oct 2023 17:19:20 +0800 Subject: [PATCH 1/2] Add sGNN generator fixed a few problems in ADMPPmeGenerator --- dmff/api/graph.py | 2 +- dmff/generators/__init__.py | 3 +- dmff/generators/admp.py | 34 +++++--- dmff/generators/ml.py | 74 +++++++++++++++++ dmff/operators/templatetype.py | 5 ++ dmff/sgnn/gnn.py | 76 +++++++++--------- dmff/sgnn/graph.py | 14 ++++ examples/classical/test_xml.py | 3 +- examples/sgnn/model1.pickle | Bin 17100 -> 26 bytes examples/sgnn/peg.xml | 48 +++++++++++ examples/sgnn/peg4.pdb | 64 +-------------- examples/sgnn/ref_out | 42 ++-------- examples/sgnn/residues.xml | 37 +++++++++ examples/sgnn/run.py | 67 ++++++++------- examples/sgnn/{ => test_backend}/model.pickle | Bin examples/sgnn/test_backend/model1.pickle | Bin 0 -> 17100 bytes examples/sgnn/{ => test_backend}/model1.pth | Bin .../sgnn/{ => test_backend}/mse_testing.xvg | 0 examples/sgnn/test_backend/peg4.pdb | 63 +++++++++++++++ .../sgnn/{ => test_backend}/pth2pickle.py | 0 examples/sgnn/test_backend/ref_out | 37 +++++++++ examples/sgnn/test_backend/run.py | 45 +++++++++++ .../sgnn/{ => test_backend}/set_test.pickle | Bin .../{ => test_backend}/set_test_lowT.pickle | Bin examples/sgnn/{ => test_backend}/test.py | 0 .../sgnn/{ => test_backend}/test_data.xvg | 0 examples/sgnn/{ => test_backend}/train.py | 0 examples/water_fullpol/monopole_nonpol/run.py | 11 +-- .../water_fullpol/monopole_polarizable/run.py | 11 +-- .../water_fullpol/quadrupole_nonpol/run.py | 10 +-- examples/water_fullpol/run.py | 10 +-- tests/data/admp_mono.xml | 34 ++++++++ tests/data/admp_nonpol.xml | 40 +++++++++ tests/data/peg4.pdb | 64 +++++++++++++++ tests/data/peg_sgnn.xml | 48 +++++++++++ tests/data/sgnn_model.pickle | Bin 0 -> 17100 bytes tests/test_admp/test_compute.py | 54 ++++++++++++- tests/test_sgnn/test_energy.py | 51 ++++++++++++ 38 files changed, 740 insertions(+), 207 deletions(-) create mode 100644 dmff/generators/ml.py mode change 100644 => 120000 examples/sgnn/model1.pickle create mode 100644 examples/sgnn/peg.xml mode change 100644 => 120000 examples/sgnn/peg4.pdb create mode 100644 examples/sgnn/residues.xml rename examples/sgnn/{ => test_backend}/model.pickle (100%) create mode 100644 examples/sgnn/test_backend/model1.pickle rename examples/sgnn/{ => test_backend}/model1.pth (100%) rename examples/sgnn/{ => test_backend}/mse_testing.xvg (100%) create mode 100644 examples/sgnn/test_backend/peg4.pdb rename examples/sgnn/{ => test_backend}/pth2pickle.py (100%) create mode 100644 examples/sgnn/test_backend/ref_out create mode 100755 examples/sgnn/test_backend/run.py rename examples/sgnn/{ => test_backend}/set_test.pickle (100%) rename examples/sgnn/{ => test_backend}/set_test_lowT.pickle (100%) rename examples/sgnn/{ => test_backend}/test.py (100%) rename examples/sgnn/{ => test_backend}/test_data.xvg (100%) rename examples/sgnn/{ => test_backend}/train.py (100%) create mode 100644 tests/data/admp_mono.xml create mode 100644 tests/data/admp_nonpol.xml create mode 100644 tests/data/peg4.pdb create mode 100644 tests/data/peg_sgnn.xml create mode 100644 tests/data/sgnn_model.pickle create mode 100644 tests/test_sgnn/test_energy.py diff --git a/dmff/api/graph.py b/dmff/api/graph.py index 6e1ccd6c0..64e9af10a 100644 --- a/dmff/api/graph.py +++ b/dmff/api/graph.py @@ -13,7 +13,7 @@ def matchTemplate(graph, template): if graph.number_of_nodes() != template.number_of_nodes(): - print("Node with different number of nodes.") + # print("Node with different number of nodes.") return False, {}, {} def match_func(n1, n2): diff --git a/dmff/generators/__init__.py b/dmff/generators/__init__.py index 7ddb93293..6f37cf7f0 100644 --- a/dmff/generators/__init__.py +++ b/dmff/generators/__init__.py @@ -1,2 +1,3 @@ from .classical import * -from .admp import * \ No newline at end of file +from .admp import * +from .ml import * diff --git a/dmff/generators/admp.py b/dmff/generators/admp.py index bf1cce2e0..cada68fe1 100644 --- a/dmff/generators/admp.py +++ b/dmff/generators/admp.py @@ -822,15 +822,28 @@ def __init__(self, ffinfo: dict, paramset: ParamSet): kzs.append(kz) # record multipoles c0.append(float(attribs["c0"])) - dX.append(float(attribs["dX"])) - dY.append(float(attribs["dY"])) - dZ.append(float(attribs["dZ"])) - qXX.append(float(attribs["qXX"])) - qYY.append(float(attribs["qYY"])) - qZZ.append(float(attribs["qZZ"])) - qXY.append(float(attribs["qXY"])) - qXZ.append(float(attribs["qXZ"])) - qYZ.append(float(attribs["qYZ"])) + if self.lmax >= 1: + dX.append(float(attribs["dX"])) + dY.append(float(attribs["dY"])) + dZ.append(float(attribs["dZ"])) + else: + dX.append(0.0) + dY.append(0.0) + dZ.append(0.0) + if self.lmax >= 2: + qXX.append(float(attribs["qXX"])) + qYY.append(float(attribs["qYY"])) + qZZ.append(float(attribs["qZZ"])) + qXY.append(float(attribs["qXY"])) + qXZ.append(float(attribs["qXZ"])) + qYZ.append(float(attribs["qYZ"])) + else: + qXX.append(0.0) + qYY.append(0.0) + qZZ.append(0.0) + qXY.append(0.0) + qXZ.append(0.0) + qYZ.append(0.0) mask = 1.0 if "mask" in attribs and attribs["mask"].upper() == "TRUE": mask = 0.0 @@ -1146,6 +1159,7 @@ def createPotential(self, topdata: DMFFTopology, nonbondedMethod, nonbondedCutof pme_force = ADMPPmeForce(box, axis_types, axis_indices, rc, self.ethresh, self.lmax, self.lpol, lpme, self.step_pol) + self.pme_force = pme_force def potential_fn(positions, box, pairs, params): positions = positions * 10 @@ -1181,4 +1195,4 @@ def getMetaData(self): return self._meta -_DMFFGenerators["ADMPPmeForce"] = ADMPPmeGenerator \ No newline at end of file +_DMFFGenerators["ADMPPmeForce"] = ADMPPmeGenerator diff --git a/dmff/generators/ml.py b/dmff/generators/ml.py new file mode 100644 index 000000000..afec8cee8 --- /dev/null +++ b/dmff/generators/ml.py @@ -0,0 +1,74 @@ +from ..api.topology import DMFFTopology +from ..api.paramset import ParamSet +from ..api.hamiltonian import _DMFFGenerators +from ..utils import DMFFException, isinstance_jnp +from ..utils import jit_condition +import numpy as np +import jax +import jax.numpy as jnp +import openmm.app as app +import openmm.unit as unit +import pickle + +from ..sgnn.graph import MAX_VALENCE, TopGraph, from_pdb +from ..sgnn.gnn import MolGNNForce, prm_transform_f2i + + +class SGNNGenerator: + def __init__(self, ffinfo: dict, paramset: ParamSet): + + self.name = "SGNNForce" + self.ffinfo = ffinfo + paramset.addField(self.name) + self.key_type = None + + self.file = self.ffinfo["Forces"][self.name]["meta"]["file"] + self.nn = int(self.ffinfo["Forces"][self.name]["meta"]["nn"]) + self.pdb = self.ffinfo["Forces"][self.name]["meta"]["pdb"] + + # load ML potential parameters + with open(self.file, 'rb') as ifile: + params = pickle.load(ifile) + + # convert to jnp array + for k in params: + params[k] = jnp.array(params[k]) + # set mask to all true + paramset.addParameter(params[k], k, field=self.name, mask=jnp.ones(params[k].shape)) + + # mask = jax.tree_util.tree_map(lambda x: jnp.ones(x.shape), params) + # paramset.addParameter(params, "params", field=self.name, mask=mask) + + + def getName(self) -> str: + return self.name + + def overwrite(self, paramset): + # do not use xml to handle ML potentials + # for ML potentials, xml only documents param file path + # so for ML potentials, overwrite function overwrites the file directly + with open(self.file, 'wb') as ofile: + pickle.dump(paramset[self.name], ofile) + return + + def createPotential(self, topdata: DMFFTopology, nonbondedMethod, nonbondedCutoff, **kwargs): + self.G = from_pdb(self.pdb) + n_atoms = topdata.getNumAtoms() + self.model = MolGNNForce(self.G, nn=self.nn) + n_layers = self.model.n_layers + def potential_fn(positions, box, pairs, params): + # convert unit to angstrom + positions = positions * 10 + box = box * 10 + prms = prm_transform_f2i(params[self.name], n_layers) + return self.model.get_energy(positions, box, prms) + + self._jaxPotential = potential_fn + return potential_fn + + def getJaxPotential(self): + return self._jaxPotential + + +_DMFFGenerators["SGNNForce"] = SGNNGenerator + diff --git a/dmff/operators/templatetype.py b/dmff/operators/templatetype.py index f4b7802d8..ce18fdc3b 100644 --- a/dmff/operators/templatetype.py +++ b/dmff/operators/templatetype.py @@ -93,6 +93,11 @@ def match_all(self, topdata: DMFFTopology, templates): graph = self.generate_residue_graph(topdata, res) all_fail = True for ntemp, template in enumerate(templates): + # debug + # print(res) + # print(template) + # print(dir(template)) + # print('-------') is_matched, _, atype_dict = matchTemplate(graph, template) if is_matched: all_fail = False diff --git a/dmff/sgnn/gnn.py b/dmff/sgnn/gnn.py index 49a5ee985..403d36429 100755 --- a/dmff/sgnn/gnn.py +++ b/dmff/sgnn/gnn.py @@ -13,6 +13,39 @@ from jax import value_and_grad, vmap +def prm_transform_f2i(params, n_layers): + p = {} + for k in params: + p[k] = jnp.array(params[k]) + for i_nn in [0, 1]: + nn_name = 'fc%d' % i_nn + p['%s.weight' % nn_name] = [] + p['%s.bias' % nn_name] = [] + for i_layer in range(n_layers[i_nn]): + k_w = '%s.%d.weight' % (nn_name, i_layer) + k_b = '%s.%d.bias' % (nn_name, i_layer) + p['%s.weight' % nn_name].append(p.pop(k_w, None)) + p['%s.bias' % nn_name].append(p.pop(k_b, None)) + return p + + +def prm_transform_i2f(params, n_layers): + # transform format + p = {} + p['w'] = params['w'] + p['fc_final.weight'] = params['fc_final.weight'] + p['fc_final.bias'] = params['fc_final.bias'] + for i_nn in range(2): + nn_name = 'fc%d' % i_nn + for i_layer in range(n_layers[i_nn]): + p[nn_name + '.%d.weight' % + i_layer] = params[nn_name + '.weight'][i_layer] + p[nn_name + + '.%d.bias' % i_layer] = params[nn_name + + '.bias'][i_layer] + return p + + class MolGNNForce: def __init__(self, @@ -146,6 +179,7 @@ def message_pass(f_in, nb_connect, w, nn): return + def load_params(self, ifn): """ Load the network parameters from saved file @@ -160,32 +194,12 @@ def load_params(self, ifn): for k in params.keys(): params[k] = jnp.array(params[k]) # transform format - keys = list(params.keys()) - for i_nn in [0, 1]: - nn_name = 'fc%d' % i_nn - keys_weight = [] - keys_bias = [] - for k in keys: - if re.search(nn_name + '.[0-9]+.weight', k) is not None: - keys_weight.append(k) - elif re.search(nn_name + '.[0-9]+.bias', k) is not None: - keys_bias.append(k) - if len(keys_weight) != self.n_layers[i_nn] or len( - keys_bias) != self.n_layers[i_nn]: - sys.exit( - 'Error while loading GNN params, inconsistent inputs with the GNN structure, check your input!' - ) - params['%s.weight' % nn_name] = [] - params['%s.bias' % nn_name] = [] - for i_layer in range(self.n_layers[i_nn]): - k_w = '%s.%d.weight' % (nn_name, i_layer) - k_b = '%s.%d.bias' % (nn_name, i_layer) - params['%s.weight' % nn_name].append(params.pop(k_w, None)) - params['%s.bias' % nn_name].append(params.pop(k_b, None)) - # params[nn_name] - self.params = params + self.params = prm_transform_f2i(params, self.n_layers) return + + + def save_params(self, ofn): """ Save the network parameters to a pickle file @@ -196,18 +210,8 @@ def save_params(self, ofn): """ # transform format - params = {} - params['w'] = self.params['w'] - params['fc_final.weight'] = self.params['fc_final.weight'] - params['fc_final.bias'] = self.params['fc_final.bias'] - for i_nn in range(2): - nn_name = 'fc%d' % i_nn - for i_layer in range(self.n_layers[i_nn]): - params[nn_name + '.%d.weight' % - i_layer] = self.params[nn_name + '.weight'][i_layer] - params[nn_name + - '.%d.bias' % i_layer] = self.params[nn_name + - '.bias'][i_layer] + params = prm_transform_i2f(self.params, self.n_layers) with open(ofn, 'wb') as ofile: pickle.dump(params, ofile) return + diff --git a/dmff/sgnn/graph.py b/dmff/sgnn/graph.py index 93f6a809a..164a41f3f 100755 --- a/dmff/sgnn/graph.py +++ b/dmff/sgnn/graph.py @@ -1219,6 +1219,20 @@ def from_pdb(pdb): return TopGraph(list_atom_elems, bonds, positions=positions, box=box) +# def from_dmff_top(topdata): +# ''' +# Build the sGNN TopGraph object from a DMFFTopology object + +# Parameters +# ---------- +# topdata: DMFFTopology data +# ''' +# list_atom_elems = np.array([a.element for a in topdata.atoms()]) +# bonds = np.array([np.sort([b.atom1.index, b.atom2.index]) for b in topdata.bonds()]) +# n_atoms = len(list_atom_elems) +# return TopGraph(list_atom_elems, bonds, positions=jnp.zeros((n_atoms, 3)), box=jnp.eye(3)*10) + + def validation(): G = from_pdb('peg4.pdb') nn = 1 diff --git a/examples/classical/test_xml.py b/examples/classical/test_xml.py index e84c6d849..1affb8974 100755 --- a/examples/classical/test_xml.py +++ b/examples/classical/test_xml.py @@ -54,6 +54,7 @@ def getEnergyDecomposition(context, forcegroups): h = Hamiltonian("gaff-2.11.xml", "lig-prm.xml") pot = h.createPotential(pdb.topology, nonbondedMethod=app.NoCutoff) params = h.getParameters() + print(params) positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) positions = jnp.array(positions) @@ -82,4 +83,4 @@ def getEnergyDecomposition(context, forcegroups): print("Nonbonded:", nbE(positions, box, pairs, params)) etotal = pot.getPotentialFunc() - print("Total:", etotal(positions, box, pairs, params)) \ No newline at end of file + print("Total:", etotal(positions, box, pairs, params)) diff --git a/examples/sgnn/model1.pickle b/examples/sgnn/model1.pickle deleted file mode 100644 index 0c3959cd9d0ef4fac155676861aa6743acb96c99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17100 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 diff --git a/examples/sgnn/model1.pickle b/examples/sgnn/model1.pickle new file mode 120000 index 000000000..88c340bb9 --- /dev/null +++ b/examples/sgnn/model1.pickle @@ -0,0 +1 @@ +test_backend/model1.pickle \ No newline at end of file diff --git a/examples/sgnn/peg.xml b/examples/sgnn/peg.xml new file mode 100644 index 000000000..d3f41baaf --- /dev/null +++ b/examples/sgnn/peg.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/sgnn/peg4.pdb b/examples/sgnn/peg4.pdb deleted file mode 100644 index 2c11081d1..000000000 --- a/examples/sgnn/peg4.pdb +++ /dev/null @@ -1,63 +0,0 @@ -REMARK -CRYST1 50.000 50.000 50.000 90.00 90.00 90.00 P 1 1 -ATOM 1 C00 TER 1 -2.962 3.637 -1.170 -ATOM 2 H01 TER 1 -2.608 4.142 -0.296 -ATOM 3 H02 TER 1 -4.032 3.635 -1.171 -ATOM 4 O03 TER 1 -2.484 2.289 -1.168 -ATOM 5 C04 TER 1 -2.961 1.615 0.000 -ATOM 6 H05 TER 1 -2.604 0.606 0.000 -ATOM 7 H06 TER 1 -2.604 2.119 0.874 -ATOM 8 H07 TER 1 -4.031 1.615 0.000 -ATOM 9 C00 INT 2 -2.449 6.384 -3.596 -ATOM 10 H01 INT 2 -2.804 5.879 -4.470 -ATOM 11 H02 INT 2 -1.379 6.386 -3.595 -ATOM 12 O03 INT 2 -2.927 5.710 -2.429 -ATOM 13 C04 INT 2 -2.448 4.362 -2.427 -ATOM 14 H05 INT 2 -2.803 3.856 -3.301 -ATOM 15 H06 INT 2 -1.378 4.364 -2.425 -ATOM 16 C00 INT 3 -2.966 9.857 -4.767 -ATOM 17 H01 INT 3 -2.612 10.363 -3.893 -ATOM 18 H02 INT 3 -4.036 9.855 -4.768 -ATOM 19 O03 INT 3 -2.488 8.509 -4.765 -ATOM 20 C04 INT 3 -2.965 7.835 -3.597 -ATOM 21 H05 INT 3 -2.610 8.340 -2.724 -ATOM 22 H06 INT 3 -4.035 7.833 -3.599 -ATOM 23 C00 TER 4 -2.452 10.582 -6.024 -ATOM 24 H01 TER 4 -2.807 10.077 -6.898 -ATOM 25 H02 TER 4 -1.382 10.584 -6.022 -ATOM 26 O03 TER 4 -2.931 11.930 -6.026 -ATOM 27 C04 TER 4 -2.453 12.604 -7.193 -ATOM 28 H05 TER 4 -2.808 12.099 -8.067 -ATOM 29 H06 TER 4 -2.812 13.613 -7.194 -ATOM 30 H07 TER 4 -1.383 12.606 -7.192 -TER -CONECT 5 6 -CONECT 5 7 -CONECT 5 8 -CONECT 5 4 -CONECT 4 1 -CONECT 1 2 -CONECT 1 3 -CONECT 1 13 -CONECT 13 14 -CONECT 13 15 -CONECT 13 12 -CONECT 12 9 -CONECT 9 10 -CONECT 9 11 -CONECT 9 20 -CONECT 20 21 -CONECT 20 22 -CONECT 20 19 -CONECT 19 16 -CONECT 16 17 -CONECT 16 18 -CONECT 16 23 -CONECT 23 24 -CONECT 23 25 -CONECT 23 26 -CONECT 26 27 -CONECT 27 28 -CONECT 27 29 -CONECT 27 30 -END diff --git a/examples/sgnn/peg4.pdb b/examples/sgnn/peg4.pdb new file mode 120000 index 000000000..3c2bb15b6 --- /dev/null +++ b/examples/sgnn/peg4.pdb @@ -0,0 +1 @@ +test_backend/peg4.pdb \ No newline at end of file diff --git a/examples/sgnn/ref_out b/examples/sgnn/ref_out index 96bc1e62f..039b75427 100644 --- a/examples/sgnn/ref_out +++ b/examples/sgnn/ref_out @@ -1,37 +1,5 @@ -Energy: -21.588394 -Force -[[ 90.02814 2.0374336 35.38877 ] - [ -98.410095 -1.6865425 -30.066338 ] - [ 48.29245 31.675808 -43.390694 ] - [ 59.717484 -35.94304 50.599678 ] - [ -24.63767 218.36092 168.47194 ] - [ 43.258293 81.24294 -87.22882 ] - [ -67.66767 -17.780457 -5.6038494 ] - [ -22.928284 -302.96246 -123.14815 ] - [ 306.24683 -21.33866 -156.95491 ] - [ -4.715515 13.664352 -23.222527 ] - [-258.61304 -26.577957 85.58963 ] - [ -10.179474 106.21161 64.846924 ] - [-210.20566 -52.107193 58.04005 ] - [ 118.68472 -8.033836 -81.18109 ] - [ 44.02272 -34.508667 46.852356 ] - [-214.84206 115.90286 -227.59117 ] - [ 44.243336 -7.151741 26.06369 ] - [ 87.46674 38.574554 192.17757 ] - [ 27.345726 -58.87986 -44.685863 ] - [ -83.354774 -29.714098 214.93097 ] - [ -71.111305 34.880676 -77.53289 ] - [ 141.12836 49.28147 -97.597305 ] - [-220.25613 -134.58449 -23.567059 ] - [ 75.2593 58.432755 -63.99505 ] - [ 123.56466 -82.0066 94.63971 ] - [ 57.822285 17.07631 -53.788273 ] - [ -73.37115 0.50865555 16.240654 ] - [ 54.86133 97.53715 73.672806 ] - [ -23.997787 -73.92179 -13.749107 ] - [ 62.348286 21.809956 25.78839 ]] -Batched Energies: -[-21.653 -39.830627 9.988983 -48.292953 -32.959183 -49.7164 - -47.617737 -51.76767 -37.42943 -35.06703 -46.111145 -31.748154 - -6.939003 -5.1853027 -27.427734 -44.695312 -52.027237 3.1541443 - -72.8221 -28.33014 ] +-21.588284621154912 +[-21.58828462 -39.79334159 10.03889335 -48.22451239 -32.90970162 + -49.68568287 -47.58035178 -51.73860617 -37.39235277 -35.01933271 + -46.06621902 -31.69327601 -6.86739655 -5.13698524 -27.4031207 + -44.65301991 -52.00357797 3.1734038 -72.79081259 -28.27007722] diff --git a/examples/sgnn/residues.xml b/examples/sgnn/residues.xml new file mode 100644 index 000000000..aa78866eb --- /dev/null +++ b/examples/sgnn/residues.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/sgnn/run.py b/examples/sgnn/run.py index f87c887b5..14c7c1b84 100755 --- a/examples/sgnn/run.py +++ b/examples/sgnn/run.py @@ -1,45 +1,44 @@ #!/usr/bin/env python import sys -import numpy as np +import jax import jax.numpy as jnp -import jax.lax as lax -from jax import vmap, value_and_grad -import dmff -from dmff.sgnn.gnn import MolGNNForce -from dmff.utils import jit_condition -from dmff.sgnn.graph import MAX_VALENCE -from dmff.sgnn.graph import TopGraph, from_pdb +import openmm.app as app +import openmm.unit as unit +from dmff.api import Hamiltonian +from dmff.common import nblist +from jax import value_and_grad import pickle -import re -from collections import OrderedDict -from functools import partial - if __name__ == '__main__': - # params = load_params('benchmark/model1.pickle') - G = from_pdb('peg4.pdb') - model = MolGNNForce(G, nn=1) - model.load_params('model1.pickle') - E = model.get_energy(G.positions, G.box, model.params) + + H = Hamiltonian('peg.xml') + app.Topology.loadBondDefinitions("residues.xml") + pdb = app.PDBFile("peg4.pdb") + rc = 0.6 + # generator stores all force field parameters + pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.nanometer, ethresh=5e-4) + + # construct inputs + positions = jnp.array(pdb.positions._value) + a, b, c = pdb.topology.getPeriodicBoxVectors() + box = jnp.array([a._value, b._value, c._value]) + # neighbor list + nbl = nblist.NeighborList(box, rc, pots.meta['cov_map']) + nbl.allocate(positions) + + + paramset = H.getParameters() + # params = paramset.parameters - with open('set_test_lowT.pickle', 'rb') as ifile: + with open('test_backend/set_test_lowT.pickle', 'rb') as ifile: data = pickle.load(ifile) - # pos = jnp.array(data['positions'][0:100]) - # box = jnp.tile(jnp.eye(3) * 50, (100, 1, 1)) - pos = jnp.array(data['positions'][0]) - box = jnp.eye(3) * 50 + # input in nm + pos = jnp.array(data['positions'][0:20]) / 10 + box = jnp.eye(3) * 5 - # energies = model.batch_forward(pos, box, model.params) - E, F = value_and_grad(model.get_energy, argnums=(0))(pos, box, model.params) - F = -F - print('Energy:', E) - print('Force') - print(F) + efunc = jax.jit(pots.getPotentialFunc()) + efunc_vmap = jax.vmap(jax.jit(pots.getPotentialFunc()), in_axes=(0, None, None, None), out_axes=0) + print(efunc(pos[0], box, nbl.pairs, paramset)) + print(efunc_vmap(pos, box, nbl.pairs, paramset)) - # test batch processing - pos = jnp.array(data['positions'][:20]) - box = jnp.tile(box, (20, 1, 1)) - E = model.batch_forward(pos, box, model.params) - print('Batched Energies:') - print(E) diff --git a/examples/sgnn/model.pickle b/examples/sgnn/test_backend/model.pickle similarity index 100% rename from examples/sgnn/model.pickle rename to examples/sgnn/test_backend/model.pickle diff --git a/examples/sgnn/test_backend/model1.pickle b/examples/sgnn/test_backend/model1.pickle new file mode 100644 index 0000000000000000000000000000000000000000..0c3959cd9d0ef4fac155676861aa6743acb96c99 GIT binary patch literal 17100 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 literal 0 HcmV?d00001 diff --git a/examples/sgnn/model1.pth b/examples/sgnn/test_backend/model1.pth similarity index 100% rename from examples/sgnn/model1.pth rename to examples/sgnn/test_backend/model1.pth diff --git a/examples/sgnn/mse_testing.xvg b/examples/sgnn/test_backend/mse_testing.xvg similarity index 100% rename from examples/sgnn/mse_testing.xvg rename to examples/sgnn/test_backend/mse_testing.xvg diff --git a/examples/sgnn/test_backend/peg4.pdb b/examples/sgnn/test_backend/peg4.pdb new file mode 100644 index 000000000..2c11081d1 --- /dev/null +++ b/examples/sgnn/test_backend/peg4.pdb @@ -0,0 +1,63 @@ +REMARK +CRYST1 50.000 50.000 50.000 90.00 90.00 90.00 P 1 1 +ATOM 1 C00 TER 1 -2.962 3.637 -1.170 +ATOM 2 H01 TER 1 -2.608 4.142 -0.296 +ATOM 3 H02 TER 1 -4.032 3.635 -1.171 +ATOM 4 O03 TER 1 -2.484 2.289 -1.168 +ATOM 5 C04 TER 1 -2.961 1.615 0.000 +ATOM 6 H05 TER 1 -2.604 0.606 0.000 +ATOM 7 H06 TER 1 -2.604 2.119 0.874 +ATOM 8 H07 TER 1 -4.031 1.615 0.000 +ATOM 9 C00 INT 2 -2.449 6.384 -3.596 +ATOM 10 H01 INT 2 -2.804 5.879 -4.470 +ATOM 11 H02 INT 2 -1.379 6.386 -3.595 +ATOM 12 O03 INT 2 -2.927 5.710 -2.429 +ATOM 13 C04 INT 2 -2.448 4.362 -2.427 +ATOM 14 H05 INT 2 -2.803 3.856 -3.301 +ATOM 15 H06 INT 2 -1.378 4.364 -2.425 +ATOM 16 C00 INT 3 -2.966 9.857 -4.767 +ATOM 17 H01 INT 3 -2.612 10.363 -3.893 +ATOM 18 H02 INT 3 -4.036 9.855 -4.768 +ATOM 19 O03 INT 3 -2.488 8.509 -4.765 +ATOM 20 C04 INT 3 -2.965 7.835 -3.597 +ATOM 21 H05 INT 3 -2.610 8.340 -2.724 +ATOM 22 H06 INT 3 -4.035 7.833 -3.599 +ATOM 23 C00 TER 4 -2.452 10.582 -6.024 +ATOM 24 H01 TER 4 -2.807 10.077 -6.898 +ATOM 25 H02 TER 4 -1.382 10.584 -6.022 +ATOM 26 O03 TER 4 -2.931 11.930 -6.026 +ATOM 27 C04 TER 4 -2.453 12.604 -7.193 +ATOM 28 H05 TER 4 -2.808 12.099 -8.067 +ATOM 29 H06 TER 4 -2.812 13.613 -7.194 +ATOM 30 H07 TER 4 -1.383 12.606 -7.192 +TER +CONECT 5 6 +CONECT 5 7 +CONECT 5 8 +CONECT 5 4 +CONECT 4 1 +CONECT 1 2 +CONECT 1 3 +CONECT 1 13 +CONECT 13 14 +CONECT 13 15 +CONECT 13 12 +CONECT 12 9 +CONECT 9 10 +CONECT 9 11 +CONECT 9 20 +CONECT 20 21 +CONECT 20 22 +CONECT 20 19 +CONECT 19 16 +CONECT 16 17 +CONECT 16 18 +CONECT 16 23 +CONECT 23 24 +CONECT 23 25 +CONECT 23 26 +CONECT 26 27 +CONECT 27 28 +CONECT 27 29 +CONECT 27 30 +END diff --git a/examples/sgnn/pth2pickle.py b/examples/sgnn/test_backend/pth2pickle.py similarity index 100% rename from examples/sgnn/pth2pickle.py rename to examples/sgnn/test_backend/pth2pickle.py diff --git a/examples/sgnn/test_backend/ref_out b/examples/sgnn/test_backend/ref_out new file mode 100644 index 000000000..96bc1e62f --- /dev/null +++ b/examples/sgnn/test_backend/ref_out @@ -0,0 +1,37 @@ +Energy: -21.588394 +Force +[[ 90.02814 2.0374336 35.38877 ] + [ -98.410095 -1.6865425 -30.066338 ] + [ 48.29245 31.675808 -43.390694 ] + [ 59.717484 -35.94304 50.599678 ] + [ -24.63767 218.36092 168.47194 ] + [ 43.258293 81.24294 -87.22882 ] + [ -67.66767 -17.780457 -5.6038494 ] + [ -22.928284 -302.96246 -123.14815 ] + [ 306.24683 -21.33866 -156.95491 ] + [ -4.715515 13.664352 -23.222527 ] + [-258.61304 -26.577957 85.58963 ] + [ -10.179474 106.21161 64.846924 ] + [-210.20566 -52.107193 58.04005 ] + [ 118.68472 -8.033836 -81.18109 ] + [ 44.02272 -34.508667 46.852356 ] + [-214.84206 115.90286 -227.59117 ] + [ 44.243336 -7.151741 26.06369 ] + [ 87.46674 38.574554 192.17757 ] + [ 27.345726 -58.87986 -44.685863 ] + [ -83.354774 -29.714098 214.93097 ] + [ -71.111305 34.880676 -77.53289 ] + [ 141.12836 49.28147 -97.597305 ] + [-220.25613 -134.58449 -23.567059 ] + [ 75.2593 58.432755 -63.99505 ] + [ 123.56466 -82.0066 94.63971 ] + [ 57.822285 17.07631 -53.788273 ] + [ -73.37115 0.50865555 16.240654 ] + [ 54.86133 97.53715 73.672806 ] + [ -23.997787 -73.92179 -13.749107 ] + [ 62.348286 21.809956 25.78839 ]] +Batched Energies: +[-21.653 -39.830627 9.988983 -48.292953 -32.959183 -49.7164 + -47.617737 -51.76767 -37.42943 -35.06703 -46.111145 -31.748154 + -6.939003 -5.1853027 -27.427734 -44.695312 -52.027237 3.1541443 + -72.8221 -28.33014 ] diff --git a/examples/sgnn/test_backend/run.py b/examples/sgnn/test_backend/run.py new file mode 100755 index 000000000..f87c887b5 --- /dev/null +++ b/examples/sgnn/test_backend/run.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python +import sys +import numpy as np +import jax.numpy as jnp +import jax.lax as lax +from jax import vmap, value_and_grad +import dmff +from dmff.sgnn.gnn import MolGNNForce +from dmff.utils import jit_condition +from dmff.sgnn.graph import MAX_VALENCE +from dmff.sgnn.graph import TopGraph, from_pdb +import pickle +import re +from collections import OrderedDict +from functools import partial + + +if __name__ == '__main__': + # params = load_params('benchmark/model1.pickle') + G = from_pdb('peg4.pdb') + model = MolGNNForce(G, nn=1) + model.load_params('model1.pickle') + E = model.get_energy(G.positions, G.box, model.params) + + with open('set_test_lowT.pickle', 'rb') as ifile: + data = pickle.load(ifile) + + # pos = jnp.array(data['positions'][0:100]) + # box = jnp.tile(jnp.eye(3) * 50, (100, 1, 1)) + pos = jnp.array(data['positions'][0]) + box = jnp.eye(3) * 50 + + # energies = model.batch_forward(pos, box, model.params) + E, F = value_and_grad(model.get_energy, argnums=(0))(pos, box, model.params) + F = -F + print('Energy:', E) + print('Force') + print(F) + + # test batch processing + pos = jnp.array(data['positions'][:20]) + box = jnp.tile(box, (20, 1, 1)) + E = model.batch_forward(pos, box, model.params) + print('Batched Energies:') + print(E) diff --git a/examples/sgnn/set_test.pickle b/examples/sgnn/test_backend/set_test.pickle similarity index 100% rename from examples/sgnn/set_test.pickle rename to examples/sgnn/test_backend/set_test.pickle diff --git a/examples/sgnn/set_test_lowT.pickle b/examples/sgnn/test_backend/set_test_lowT.pickle similarity index 100% rename from examples/sgnn/set_test_lowT.pickle rename to examples/sgnn/test_backend/set_test_lowT.pickle diff --git a/examples/sgnn/test.py b/examples/sgnn/test_backend/test.py similarity index 100% rename from examples/sgnn/test.py rename to examples/sgnn/test_backend/test.py diff --git a/examples/sgnn/test_data.xvg b/examples/sgnn/test_backend/test_data.xvg similarity index 100% rename from examples/sgnn/test_data.xvg rename to examples/sgnn/test_backend/test_data.xvg diff --git a/examples/sgnn/train.py b/examples/sgnn/test_backend/train.py similarity index 100% rename from examples/sgnn/train.py rename to examples/sgnn/test_backend/train.py diff --git a/examples/water_fullpol/monopole_nonpol/run.py b/examples/water_fullpol/monopole_nonpol/run.py index 3b1b4799f..617e96e76 100755 --- a/examples/water_fullpol/monopole_nonpol/run.py +++ b/examples/water_fullpol/monopole_nonpol/run.py @@ -13,18 +13,19 @@ H = Hamiltonian('forcefield.xml') pdb = app.PDBFile("pair.pdb") - rc = 6 + rc = 0.6 # generator stores all force field parameters params = H.getParameters() - pot_pme = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom).dmff_potentials['ADMPPmeForce'] + pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.nanometer) + pot_pme = pots.dmff_potentials['ADMPPmeForce'] # construct inputs - positions = jnp.array(pdb.positions._value) * 10 + positions = jnp.array(pdb.positions._value) a, b, c = pdb.topology.getPeriodicBoxVectors() - box = jnp.array([a._value, b._value, c._value]) * 10 + box = jnp.array([a._value, b._value, c._value]) # neighbor list - nbl = nblist.NeighborList(box, rc, H.getGenerators()[0].covalent_map) + nbl = nblist.NeighborList(box, rc, pots.meta['cov_map']) nbl.allocate(positions) E_pme, F_pme = value_and_grad(pot_pme)(positions, box, nbl.pairs, params) diff --git a/examples/water_fullpol/monopole_polarizable/run.py b/examples/water_fullpol/monopole_polarizable/run.py index 808ee5801..560cd8da0 100755 --- a/examples/water_fullpol/monopole_polarizable/run.py +++ b/examples/water_fullpol/monopole_polarizable/run.py @@ -13,18 +13,19 @@ H = Hamiltonian('forcefield.xml') pdb = app.PDBFile("waterbox_31ang.pdb") - rc = 6 + rc = 0.6 # generator stores all force field parameters params = H.getParameters() - pot_pme = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom).dmff_potentials['ADMPPmeForce'] + pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.nanometer) + pot_pme = pots.dmff_potentials['ADMPPmeForce'] # construct inputs - positions = jnp.array(pdb.positions._value) * 10 + positions = jnp.array(pdb.positions._value) a, b, c = pdb.topology.getPeriodicBoxVectors() - box = jnp.array([a._value, b._value, c._value]) * 10 + box = jnp.array([a._value, b._value, c._value]) # neighbor list - nbl = nblist.NeighborList(box, rc, H.getGenerators()[0].covalent_map) + nbl = nblist.NeighborList(box, rc, pots.meta['cov_map']) nbl.allocate(positions) E_pme, F_pme = value_and_grad(pot_pme)(positions, box, nbl.pairs, params) diff --git a/examples/water_fullpol/quadrupole_nonpol/run.py b/examples/water_fullpol/quadrupole_nonpol/run.py index b408792aa..0b6fe6394 100755 --- a/examples/water_fullpol/quadrupole_nonpol/run.py +++ b/examples/water_fullpol/quadrupole_nonpol/run.py @@ -14,20 +14,20 @@ H = Hamiltonian('forcefield.xml') app.Topology.loadBondDefinitions("residues.xml") pdb = app.PDBFile("waterbox_31ang.pdb") - rc = 6 + rc = 0.6 # generator stores all force field parameters params = H.getParameters() - pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom) + pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.nanometer) pot_disp = pots.dmff_potentials['ADMPDispForce'] pot_pme = pots.dmff_potentials['ADMPPmeForce'] # construct inputs - positions = jnp.array(pdb.positions._value) * 10 + positions = jnp.array(pdb.positions._value) a, b, c = pdb.topology.getPeriodicBoxVectors() - box = jnp.array([a._value, b._value, c._value]) * 10 + box = jnp.array([a._value, b._value, c._value]) # neighbor list - nbl = nblist.NeighborList(box, rc, H.getGenerators()[0].covalent_map) + nbl = nblist.NeighborList(box, rc, pots.meta["cov_map"]) nbl.allocate(positions) diff --git a/examples/water_fullpol/run.py b/examples/water_fullpol/run.py index dccf92921..f024a8d66 100755 --- a/examples/water_fullpol/run.py +++ b/examples/water_fullpol/run.py @@ -13,18 +13,18 @@ H = Hamiltonian('forcefield.xml') app.Topology.loadBondDefinitions("residues.xml") pdb = app.PDBFile("waterbox_31ang.pdb") - rc = 6 + rc = 0.6 # generator stores all force field parameters disp_generator, pme_generator = H.getGenerators() - pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom, ethresh=5e-4) + pots = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.nanometer, ethresh=5e-4) # construct inputs - positions = jnp.array(pdb.positions._value) * 10 + positions = jnp.array(pdb.positions._value) a, b, c = pdb.topology.getPeriodicBoxVectors() - box = jnp.array([a._value, b._value, c._value]) * 10 + box = jnp.array([a._value, b._value, c._value]) # neighbor list - nbl = nblist.NeighborList(box, rc, H.getGenerators()[0].covalent_map) + nbl = nblist.NeighborList(box, rc, pots.meta['cov_map']) nbl.allocate(positions) diff --git a/tests/data/admp_mono.xml b/tests/data/admp_mono.xml new file mode 100644 index 000000000..3970ff522 --- /dev/null +++ b/tests/data/admp_mono.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/admp_nonpol.xml b/tests/data/admp_nonpol.xml new file mode 100644 index 000000000..7cc1b4653 --- /dev/null +++ b/tests/data/admp_nonpol.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/peg4.pdb b/tests/data/peg4.pdb new file mode 100644 index 000000000..eee06d7da --- /dev/null +++ b/tests/data/peg4.pdb @@ -0,0 +1,64 @@ +HEADER +TITLE MDANALYSIS FRAME 0: Created by PDBWriter +CRYST1 50.000 50.000 50.000 90.00 90.00 90.00 P 1 1 +ATOM 1 C00 TER X 1 47.381 10.286 49.808 0.00 1.00 SYST +ATOM 2 H01 TER X 1 47.251 11.255 50.307 0.00 1.00 SYST +ATOM 3 H02 TER X 1 46.907 9.487 50.425 0.00 1.00 SYST +ATOM 4 O03 TER X 1 48.814 10.202 49.785 0.00 1.00 SYST +ATOM 5 C04 TER X 1 49.336 9.203 50.665 0.00 1.00 SYST +ATOM 6 H05 TER X 1 50.344 9.329 51.054 0.00 1.00 SYST +ATOM 7 H06 TER X 1 48.796 9.176 51.611 0.00 1.00 SYST +ATOM 8 H07 TER X 1 49.296 8.320 50.177 0.00 1.00 SYST +ATOM 9 C00 INT X 2 46.552 8.760 46.601 0.00 1.00 SYST +ATOM 10 H01 INT X 2 46.737 9.609 45.939 0.00 1.00 SYST +ATOM 11 H02 INT X 2 45.532 8.628 46.649 0.00 1.00 SYST +ATOM 12 O03 INT X 2 47.247 8.976 47.799 0.00 1.00 SYST +ATOM 13 C04 INT X 2 46.919 10.250 48.371 0.00 1.00 SYST +ATOM 14 H05 INT X 2 47.190 11.176 47.880 0.00 1.00 SYST +ATOM 15 H06 INT X 2 45.801 10.369 48.307 0.00 1.00 SYST +ATOM 16 C00 INT X 3 46.760 5.982 44.153 0.00 1.00 SYST +ATOM 17 H01 INT X 3 47.759 6.173 43.770 0.00 1.00 SYST +ATOM 18 H02 INT X 3 46.121 5.894 43.168 0.00 1.00 SYST +ATOM 19 O03 INT X 3 46.268 7.098 44.918 0.00 1.00 SYST +ATOM 20 C04 INT X 3 47.139 7.493 45.949 0.00 1.00 SYST +ATOM 21 H05 INT X 3 47.292 6.726 46.769 0.00 1.00 SYST +ATOM 22 H06 INT X 3 48.124 7.662 45.625 0.00 1.00 SYST +ATOM 23 C00 TER X 4 46.610 4.692 44.880 0.00 1.00 SYST +ATOM 24 H01 TER X 4 45.686 4.613 45.520 0.00 1.00 SYST +ATOM 25 H02 TER X 4 47.444 4.603 45.516 0.00 1.00 SYST +ATOM 26 O03 TER X 4 46.501 3.674 43.869 0.00 1.00 SYST +ATOM 27 C04 TER X 4 45.802 2.493 44.226 0.00 1.00 SYST +ATOM 28 H05 TER X 4 45.959 1.651 43.497 0.00 1.00 SYST +ATOM 29 H06 TER X 4 46.125 2.280 45.251 0.00 1.00 SYST +ATOM 30 H07 TER X 4 44.695 2.638 44.209 0.00 1.00 SYST +CONECT 1 2 3 4 13 +CONECT 2 1 +CONECT 3 1 +CONECT 4 1 5 +CONECT 5 4 6 7 8 +CONECT 6 5 +CONECT 7 5 +CONECT 8 5 +CONECT 9 10 11 12 20 +CONECT 10 9 +CONECT 11 9 +CONECT 12 9 13 +CONECT 13 1 12 14 15 +CONECT 14 13 +CONECT 15 13 +CONECT 16 17 18 19 23 +CONECT 17 16 +CONECT 18 16 +CONECT 19 16 20 +CONECT 20 9 19 21 22 +CONECT 21 20 +CONECT 22 20 +CONECT 23 16 24 25 26 +CONECT 24 23 +CONECT 25 23 +CONECT 26 23 27 +CONECT 27 26 28 29 30 +CONECT 28 27 +CONECT 29 27 +CONECT 30 27 +END diff --git a/tests/data/peg_sgnn.xml b/tests/data/peg_sgnn.xml new file mode 100644 index 000000000..206326d1e --- /dev/null +++ b/tests/data/peg_sgnn.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/sgnn_model.pickle b/tests/data/sgnn_model.pickle new file mode 100644 index 0000000000000000000000000000000000000000..0c3959cd9d0ef4fac155676861aa6743acb96c99 GIT binary patch literal 17100 zcmYhjc|28J^gmAKAyY_*1~L^=63$*Xr4mVLpj0v>4d|LmrOb2Y$XF7RREWaa>!!>p zB}p1I7fmWEY4~}b&*%Ame)o_2y03HhzH6O(&RXyNUhBP2h=7}$&z?Qo-TZg@c>9Ul z`MPiS-R^F=)6HL;%co<{<=1xP=i}qs$DQEj9pJS$NZ-xJce}n!ym~N``>}?{y}@U zi*v;tCyZP1n9r54;j`h7=1SUgCu-XW{A-)xO08P8%KGp4>)$sUK7X#XYwQw11rJ#c zSH_*^@^&ulkCeM9|y+js8p^ykWX3V8l&dy?n4VR?J5!as(!ZRSUD6+I`$E)JQ- z$G1T+fcBgerYQfCJnLyCU5n1L30H2haA*$%7`q}YKMGyJIdm3Jif)~eM88DUuz!uc zNNAHD+&Oj~KmEz4?{+8A_PLsLs9c+veQ%*5X%DISqnE5w(ZYq^-y~7^*j0K*{~jG? zo0*RZ6-;YuG?Mo3Bsg^!h6>seBNG)o+1p0szEs1!-xHuICy&g3U4{qL>*3;vItT?J z++%M;@YfPJ%(@T_&OuNe=EM21Ps#JaKr1#@`jJY_vKV!_Lxq4MtdG?`%+ za8xiyTN-Hc7!zA9hPRsjl2rp@OquL=HvHWcni(O?s%SVeJ!8|Tdy+V;@zlZZItF#` z%);yGiaS(6Hjg^4&&Fz%Od?jim7Q>^1;4KifrysX5WY~0RQ(pit&#W0lmgrOgJDv< zx&`%6#crm}t;cD_+kE9m zyJaiMx=bnTIHUm~7pMV&TLd7zWFD1n4<*z7PJ_7zwouFJ1hY32#o>|pN%G5Q5k| z)2AF`t9s<9UuG0de00TJbnYBDGh3Z7k-hZs@j1l9PY80l=aC@6e8RtBElO;gi%lnz zuxr&8(x@wmTG!W-w{ca3(Vj^A&W;iO{7hW^CyG8@zlRtsmu6ZXpJ19w3Sq~myQq2O z8Qu-6!4wH&tedwSS#?EJ4^#sqrVF>X#BesXDG>gBmUul!hey?BQ(kU8=X2jl8l5!2 zR+g_uA%_esv$n-6-LpV@K$;LmX`I(oMLexz@J50j{T`G_RWpPjZPPN=PBH{}mUd`x zTL9E;&B&l!CE6qz(y4t>#5H~u8!A{#{(fiC>X{DjOieSLANP#5&5Q-V`IjjFfz9yf z$piAlV?Fv@ngg>BJ~CfE$qM|9U((AWPpQZUF^;c(F3c&Nj6EfH$?WTva6mB;YG)nc zOmqo=zn@m4b^3W;@Qx?&!E7}wkbVcf`U^QK)@oQSeTL|zFM`)rQ*j>-lY|K@b%AU$ z@2LdL4eTNZ?uo#$KkMqxDTdeYds9rVE$C){Mx0`HSxCZijVX}*_(}b#vHOJgS()-b zyGe~729a$u)lltlmARK%2T^cd1&7u@VTE?sQnf7;cn0}47zdj8;8isp-W>*;cLk%1 zya%<2n^;${Bn01D%>kur5qL6rE$(Z%3x$b^)ZZ!s?^>sz+?U@hi{nr_HpG*=u=RVOp zdJsa6>}RH5+=>P(LuvnX5q!~TOTWj6a~jHO;K$-A7%a4xhanx<_1POlqFYfRWF}8P zZ34&j`+KswYX$5WJPaN$1Yl)w5BYRIf|;qc0CIgJ$m#cH^zKIhdu=b8-RI8SJMoC* z*iI$F&zI8TE8;Nq_ZDd0B1x|FYMCn)CeTygmy_yJKDZ*R!g@T)lDN#=yPgj+svk*}fH3U2z>uE9@#Kc)1{B|2i`(J{>8(fah*rWf zRKBeQ=24$;rCI@WytE?S7r&DC1N+hT9FQf&44q}zLhHKXNxvz}rXI{9DK)!j6tO~q zM~~>-kKa*njE{aToQQ8q_^HA-P4aXhAFr{$j+QL-Ak7-BWYDr0SAUsI_Pn`8j8<3! z&p8A?2lX%_Q7xbvkVK4<=itfH3-E&4T-+5Q#0k6l2RD^jgT479W|0;@_!u@(6?;{h z))x#B!7`la+FuaI`N&Q$D8-wN(>P(9*WswLOZ}T2a&%}}EciU%4oki}l8M}9c>Vh- z5*D}shnx4{!KsrWf8R9TnS|G@*h)>BN~CCT!b)6YTFc&=mO%Apm{75vt)za|HD>v! zC}?n0!D-bVb~I85RWE0O^!aL9q4=J(ttM%T$FI9 zHm8qLts7p{MA8!rO+)G5w*%%sQv5K;;0)fGbc>l_kOG%qhfxw10}8&GwDG|ic1Qb7 zeDi%f7OXYq%ovHp)%ANxcA_fE!a5k7kxaHu^r8(7;;i`8-B?^_$~e*p;%wK;4i@gg z`DYiBA$H1QP6~oRJ{SN#DxZSv zXcF$4vJ-AwhB1v|h4t#^X3$ubNZNJf0<5AVDAoCk=pQm68~!K)_FRF|*YddBRRSNk zU5BHxe@RM}HZ9v0Mt6CBqlOwNsGFUc;z3$gY3epTdv6ky_NhJ)` zPgTMpy8=A=YZgZ%kVnrR%p>BwLVDO`5e77bfL(_=3H@r0i>vy`^MKzp^mQGT%U7dM zmidrhq87Atwh+YECe@em?!v3nlg$IypP-YRi@|WoZ16nGkLHU?i00}MD2$edqwXp= zN#!B2*)C1i8koX|3VRf7n@DE3d}en~(4}TpgCsbmoVNEHf%3H&-hMk95dOH1$bOzc zWA+Q-hU`2#!`l}`H$I{^D}G|_r@y#&!w)K%K0qINzopr|S*&bg7;|qCKO_}duyUd+ z=}^y2GV`4pY@CJc%JUOBULRk4M`W9pZTD5}PtCNA7TPi9}#3USF@k`7l~da#;of7u_UUsg2a?L=*k3 z^oTC78HVVo&5Y@rdsNPGPrYjSUe<7#4edrQhNc`Nn|IHK$Key<+6+yi-=F}(g{xq7 z*9J2BDS~Xzox+;6y}$r+9jz5>QE`$2uhvfwcnOYFv&|I)Ya%gy>Q0&)k`&&tCME!u6xaNaryRg6er7R3VNL!~N)4WX!W@sD;d^ z+tkDB9QX=4)<-v8$8Qduu$+ou<+J_ds#gIvPHScNeba>OUDEiva5`I|xgX_i^FaTI zFj{#>BgRVBe|;|iTBjsI>7fICK4mK~-M``c_ul%ki>ACfbSyL=_Nv|9()z3d?`tw!j>-|xwYc|AMFZXbJK+ZVF%w-&u5yM~4t zj%NVhEQZ&fKq}hG;e(OI}YD{$|CnGX5j6lzck|cVqCJ|9C@_65)$o3F^6vwt@2q;_C*@OnSrbD z+g$^0O#XpUg%Z45FAjj6lss?BuglC^&1iGMpU*j4f<@4ILN{~XK>{4EiD6`I8tiRY ziEm35(w8^H$?LPC)I+~@JRTEBe{wkqoxGFgTplE`wh7E%whs%;%s54E{Io>qDzJK| z>DYx8G;}N&cKW5z_wp}DO0_J_kL2LF4TiMW(TI2{*n_Qe03A-H*c6b6MmKEWo~j9H zaC$-iTo0mq7cgYUReid#(V9tZ$|UgzRiIatpNu35!-9R!!A#>MbEHolhYJnqK2#-@ zxBif$FEn`ZhtxU!;U1iq%BPs3?^^7g?k#lh=UZf|*)mkMe!$@61ZtP}kOT^*kU1}! zXvW$<#38kr=HK1O>g$vc!RHOsb+#UjRnKP<*9e33N)LwL$%$cW6d2!<2TXd4De26; zf}RG+bz;XKlW4;%qF38TgT1Qhr)B5a(16X1Vs;I&35=!u6P3t4F@ADbLXs3zXp*Zp z+F1q7WE9@Ufy$VDXq+g>ep_5kYnGJ2;O4(%)B6j&-R|m~m#tH=(fk^W-O=NnkC)<1 z%~9Yi1AltLY6CnzWX7?Zo(lP8UrGL?$!N}<1h&7-q4Uuwxv{x`b!_^>Y#F^qS28bI zWy!~eq1C{VL9~K zEnVhAXCC>;|C+pABtTa^6+zh_iSWbxCHt%9CoSgHk(NG1dN{0xr~l^^6nqt z46<-KG=qdxCc{12P9la*g6xxgG}5!CmKIUuqk;fVzbMEVK@Z-*Cm9GfQRZx#Yen@^ zyUFb7*NC@#D|Cpxqvxjk(`+MkI*)FJX08cd&bSQPWfLGIcsaaM*no1I`CxuhE*+>j z#6A%Tqz8R}na5-%(9r3RneM%(q5OUUQNJ=mS9n&!iaF^-&?}FLeq8_qazpfWa}qo; zJcb!=??{i@9pY~6g)T0uaGk+pV*EXZGC=KXEdAXJpz4R;3<2UD_Ob0_Uqi-)V> zUGOgH6F%42MT~n^AZNcX)%)H?ecj(t?T-Vf=Pzw0{$?-8KKu@8HEwWPScfzDls->x zavWX9-#~8t%piZ{1!<>vviZ|1?wDLBLN1Q#!3Fh?jQKokP#Os$zmEySj0XlVA~i~l zgC7$e;a0fsK9xy3UQc%Tl@oo>bVklr2n3?}sB_sLa>*ecK5fwC%b6H8~C^^H89FHU~zOIdKIJ;C1E##1uEe@pm2gJ3favq|ApK zW7|MIWDajykvG07noPba$?*JJLb2k`8zL(%MNXm*Jr?ST#b;EB(3k~O&ydF9+H>r- z)h1Lv>N&IeKtA2VS4+g#6_fiNc?_92lbn{?0M!s$(XHn_NM=?d9m?Pb&nrCh zg0;isbGIS=D?Ae&n;Xfo-W9NUX$iSmxS!5W5ykZndud|MWL!5Zf`-5eh~X~4z~OVy z$z%Y3^ffj^$_*D%IdaLOgi$r2$6fwqR{K{AYI{doE_ONN=+XY5rx1e^2&J;jYtb) z7bypmI|jAHcFBBZvfW;cQyienO6Sw2+)(@yzl9cXB=F6_B$Sh>W8@wvW5f?t*tm8v z?HX((l~Je3tOKRgN=k}`Ri%&~lV@;l^BpK^i-C1rxgg;f34Pydq5s@&T%3#-9!~R@4M6)bbfkW&}s;a3=UgXx1lDu}>IinQ! zpQwN#!60fSW`oye9wO1}x(V$sf-f^pQ+bJryv5#6p}2b+QBt4J{xZxUS7lR4ThUSW zOmjQY-g6cXNxmnEqRVKPeK80J?1tGl*Fdt-d|tpDK5VgUM(d9C`0L>%`Y}odeZO4C zgSq!fvaCPkJ;(u#Gy~3pqaB#F^axK{*$MXZf1|RSuaZgbF~rHsg#Pv>WW|PSJ}%l-LpfKr%eFk4Zlu#mmAH zdRgx*7?+e2$CKH_Wd1i4%U;49-5Sbx$7Vv~WLc2=I3HZVE$o z{pk0E##s!qM;`1Y{abZ$_hmu6+ZRUGHqXNC*9?fFi3Dbi4zgvv&S-V_JZ^EwqIHji zIGHwDP;r3aBpw_Fk$4df^JXVZjs1?E8=qpv<|Q1Pq3>kNnpn>3X>z>lMv1&Y<;kC9!P2_h-G0i?F1N$7L;cMSUxGKm2(W2QfqBX#r)fgd0RtrI6 zeJU+A?|qV!K~o{{q$IFgsfs%eRlmnWyfz>j{c-672LE|v$Q=?^gDPA}uG zA!>H=S1gH{lZrh}S#BwM^?UD`)W`C~ zd){>L6rGEH$Is%l>RlN2X%@6?ih);SZXiy-?~#64H6hB{5+*LX2TUKtC!42!VvudR+Kc z1SNyQ@T0a0>|6N?Hmtgg_iqod;XbKk_WcN0{;C>V@~7~0f)XIraUUl%CmK5a%5cq; zbQqo%%~tFQLC*wpl4KT6e+_3rtm1erWIZ3a#sy)Kfe{$K^P&cW2@qPNip6pQ*dRWU z7?y@$^rFRNefM#){p1aNFZ95Ct=~W_f{xkiyP6nmk6vO(Z z`pl88rRILVbHV<5IaN_NWw#ueNor60zy!zBRN&M_rpDzkR%8G&m&36!;WiBFtz#y% zB;%iLL9lMK9u)a6hpczvr2nG~Z*#c`&urr{n&M~8I~UXg=U)nO3Z58pL@#PnVXs=# zoq0!@nT6Hl?ze4FxM~J$IdhgozRMuT7B7WT!$6WR76$D~v#IL0qqH+f1WG?2CbPGR z!OX~$w8MZ4vf*1<$bCuLjds*WUdtg-eN$l3R2Xje&*UtP3&&Gy_kqWfJ{Z!R zOfKG$!<|Q3;Njj?@HpfLUGuCEKUcaFAGhhO-GOuD`1n1(R<8qhU-?PT&-+Zyk5!T9 z*UOmCXU{Vgf4>OXw&0ab_{K-BAuB zS^4N~9tTc$yvfKZey|nqqhF1G)xUDuk5?iTNqLepgnTKby!G>mwMiEd^(#RX?LybM zh0tND3AjIyv`L-DhL0>%m$zf9lpuDD4AkA3p$p2~cw(ZI#mqes0>Mw**x9rE>9vG7 z>TN8Ce?&ql-@|J9cK99HrX4_qLM9>qrbNg{tsvf3g~Yc$oWj||L~`H$c zsm2-0Qt1Todg?U9(5LeW6qYHH#!t zO7MJb4|!o{ie~i;=&Cs42PG+Lm7Gb#2c@ZwiZNaPJrW9b`LN9`TPPknPkYAyOfCt+{NpB|)R%_Z} zONI!poiI!%jYUJ$;RvWYnNEq_OrBzBBOJMZ7v-f4c;AwuA>PQ8qaY$j$2Wco%Ty*qi)$NPyEy@# z$!)GJ)6=9AJNiLLK8eNqXUtU&zMz|)>cgSE3cP(?spOQ&QM6n?LLX_2(YYn@7__ty z&RFHMnm??d`97DYr!4{jj3G~RTRew1I)$gzBLLs&R(eD~$z1LI43r*>B_FHK5eFF~ zYI&}lMksaBq}mo5)8vFc9}URomEyR*MiO7>vSjetdv-5GlgPt2>x;TB(k_j#`nG|I zczU-2-aos6)$y+<(?U`8$T5OEAa`#~M2NRsUzXg^T?ZXq5bs#6L2A^kN0tcE6 zcde6QZJQ_hZaNDGj15TdHCayHgG-S1jSK7gqCqf7lQSwmiC*?cvRG*%uP39Md{8yQ z@T%9auA?0Ngr}q5uE~s`N*^)FYQw7e7&2vAH zzweMSdp3p8=MqGBcK`$WN|?AZ1y0(Ua6D7QI0ea1VS>Q}xIOhQs5J5*CukmWEI+}@ z;>o-@;sWF%dxHd?j|Lr)3Y3t{fjP?c=*vxmv5Y+!Zm^W+^u`9#|6HY~>rH?=*`KTA z>L~vIvdQ>plB9Z#8)|c#(82d`|dhH8YJ(a&XEj z8KUKnG4ju+(@m?Y$*I4>F!(!={yn*#+%Yew^ZW(bPH#^Tc{0o-z1zYXnx>N4tUv7L zRnzg+)t#`!J%Eg5En}5ac9G*|zsVF%7L`BP%5c^Ex$6HX$e8<|AY%laanIBf)!NgP%<>o9FLVXQ{SDY7~&i0t&(fMy;(u=-Lo8tt&g zPgA4_+hM?4w)Ys8o+(1U_2UgbyJ)N&N&$~%Lx@}vkISFkBwe+!;PrYZbdMKpy~ONr zW9ndv%Wv7hlZaPLD5!K*fRG9Ot&f{jen%^kq3jhA3e#R zo#n9O&pXEcNj&oJiz0Kj_d=DC7tGQfgk)|sELr&pgAd4%CT%%((m^jU&pi%XeB4n} zJ(NiFSHhyDiqutHmCi^ng?T#mXr4)r zrgHF%_#dMEGo3DNs3nUZ7D2`2*QDsF4(@&{#o0}raWu{gddjk~X!HOi8jKLfVpUL7 z$%Gq!Ht?x} z_bvx;Funs9ngv02%_W+gv6DP1oXT67R1Wc}wz%rUEnw3|@Z9Zqc zhe6YozlgM@1uTqKf{({Uu)r%B+ru|O`0+}b@xBmtbu5PBPwmu5GM--C@R062yqO-! ztz)w1-J)6h1EA*ePB{1|fh1;e;DN+U+_~lw_LkYZ3yGc!Jj5wa+EAeuq9K9NO3Lh7w(@7VEN$i31 zBqn4pv2^mM^ByOIU|k^Ne0M!e7)+*>K56FO<3)o}{#zvS$xrsnvnx1c&XnFr;d}9QR-c-N?u1>{!tQj^+=U{U0Z+7RKBD__hOqC`NgVw?wL_a;2d~!QT zY!Z3&<&_G&5U7vst%M%+41vhfBF0WL4t9PPL9dvZyld*$sKM(sD6TRG?W3BozkHOu z*!T;s!)c3_AJ!-y!`6o*^ooWNU152F?g-yW<3tv-A8$IE zTfAGrTkBG8el*np2XZH%-P>poTXvEjeZGTgPRk|_6i?zFUKu&NBAf|-qe)I5eowxq zj1$Y^7-}LR3IZD^gXN4*L}NuMI{%u3lMbK2{YQR5NQV%HNL?TorWugyX@E3f z0kCxpHC$wPy`ArvmtJlFC-h;{Ze>ooo-k#< zbW#=B(B^};JgV5=Ru|0$f+q1yqyyn~Tpx_MkI`G4xtLih!CByY9{-Rn^}5wru%tN< z`m_pgqUC+^@$_b3bo-$^uA1)Zw?&r;<>XGU5Lqes5c?a_kV%z<#qzSiai~VKp7qrJ z_e!wlvq1MiY3Ojw2J0OQsf7tYiBy!w&*J%{W*YKiTD17+*mi*1jWoKb7t5T5<;T6Zp3*W~m^z=U4 zz3C=dRToRn>YOFZ@)Teo&xY{!h0%)3LfHB#4I^c3@ugn@>V0V-5iK!n$z}`qV0{_9 zC7MAbbpXtg+`*$}CGmZ2!8re%Ln6B`)$^tgQ31&gFxjj_g61$VaC!yIUzJN@#RurK zpZl2rqaWsu@1y9Ou-ft5qX_%0{*ZU-vb-a;C)jUc#yCrHK3?k&MgOWROvTlOxG{1L zd6~4FW0V~Mc{67*DO*_*qiD>QvZ?f5^C@B-(nki{%yD!_G}#@RhezyZkqAoX9foO=#xt!YpHJNLy|ur!U_@9E?FDN< zTxuhga2P;GP9@2qGl6qPA7A$Ow;c)A$jV)fv0m}1ROs&;o?9wTt0OdbY{3<<~0HKK(!9OUe!gS?|r!Ma*L-li>Ek&(Ox{B3bmv%CjdPAq~Xix=cz@7DSz z^)9%%tqz)vR>3yOs~{_E0cj^HsX_8WEMOng&akKTmx~KgG)x{2=ijCuH@|=pmvm;O zTsrdU&cbDTPQ(8A035C~!SzcQfzzRvbcx|^nr^L%5gq_l3xa_SIYzp^WZ|EiC#jda z0hoh2E;l{|J2uXN`>$8QzTr5u^azL7G0k|+@CQWkO*U;W*$;<*XyOrtCYqWt4IGNq zaCC&9#QfxgLo>v2Rb&#R?23T-SLT7^7c-PzvK%|U9DwJ`^I-J)E#k~K1w`LOqsx!a z5c1U&azZ4qckfP|sPTflUb`7g+qy}T7>_A7>roGG zGyL`&L9XUIrO$s8v!}xKgBNe(g6VR2Iqe=6z#3%gy>O3Erp9*{AFeI@VtJ zbMv?`W`ze?7}ZK&eC5%in}JNO-$W#9gg99qi^;>+wM=KfI7!M%g2SZ|?9}ypz?T!Urkd(*7vlYnI^ykj{KSDNF|6f9;^&fN5{)f4YYvOhPWiF9iy?+SV>Lqp)AVx}! z<}~Eu%XW9b=F=qS@Ju-9_!Kk_G?3rYjv$ghk6*A<6h)1{B(m5v@w zxbmDSmdmF(Lmq6w3rpnA_UF#|KLTa+AA!>U&kcir+%UA~&ix+(B_G8#`iDR*66WK( z*Pw<2jn9eO$;+s8_BhG7tO(Ocs&yn)eh9KZ(ik{;^s_QhHi1dGf z_f;LN!B;H1;M`aLO!?%)ana8f_>n!C=lM_s3=+4J%?Zy~ zNBOJ&xagR=ohmL}M&-qx(ks5pvHSRF{jAC) zv=B%mhSodLZpl3Kah?YYgY-b7AR0AhM56P^PMRPd4zDl|zSKXii~aK$zaKWifJzB? z_v$M&rb}_&4Oaj@AAxm~_;@?^yK!zj-iW!ey{LEh#<;pvfwS}eRd9aG!%aHTu={N; znhpNKw^>Iqz+H+asknj7yL)7Ga2>vmkibaab`p)pm<G~10v)_YOm&aoG zWI1vrR%|?o)M@Uqm_2}x|trH zs0)47Rv2?O4t`1%f@#okVlZUP**i}f0$vXhzr{{W-*_U@E^9G0IC_%~6v}hbT4ONY zV;D0ZCDZ=+Q$(aeh<8Unj5dGQN4a@XbiTkRGLn#jN8DY`|Yp|i)8T}!W%zoXHpYF~@BWfyVE zXBo5_(t=Z;k04!8ikA;*vQAUO%?(H`z63ce7W+v=^OHeZ{1V1p;1;*3X{PN!Ohff(%VH@bE67$K5Vc+h<~Ecgh*RgoeS}8)u-|@-JB(^92?; z^FgC-D6>bm8Pc4aNL(Es=V7`g%}g4FL(|Wqtn@tMuze-OMQYOfAKGcwTLaAf*~nO^ z@IxYbUgxOH$2pa8m9?~vW0f>}D1Fk!Za*N*am{k3PepdX=+0g;Sgp@_5cP^ieih(# zt9}5TjxegKy%^^lS`0sTz9X)dA4$pHGiVg7g_%bdW0nZRnJ835UY=ddyBhHm)6cBI z)yt*mrNj~tmMw(!7L9D?#0b1PuI9h~O`3P}X*znZy+bx^Z^xUj-jUj;-stenmHMB` zp*8uLASsrIVjm(d< zMUa<}L<8KH!t%*w5O5KIT?3%OSE`kf3U zIGlkGu@_KEf`Oxnp_uVnl1TC%GA}a6%zj%H!>(6dq-MhhcIZJEsyr}cyDn$qw>C}E z$e&1L85`_76#?tMN@Iy$I$gKF1|Li~$SxO@!8KnvbgKtTWUUTyN*1f3l0goAy~6;V zENYmyI*PcaD;Y{7V^Foin}%k4V_UB(I-DuT?u2orZ;l>t=lOHz{~rJv{SN>d|A#ya z{y`oSd+x&j1whk(0nmHuI=25@KKfm>9%u6z@V7r6ini>9BcrF;)sKZ?^&Tg1e07mb z^>l&r$4?@wY{vF&ssVn#c-r~#IjQywMNAu|d-6}frm@HoeG9G) zr^&aQ*XZtDo56~H$Iyts`4R2ppDY;E9$tm9^G@Izcu3 zCa26<_Ur>YRka09SjeF9rf+m&;YJiVwvX8+o{69D6`|XLg4c*_hc}m&R9DjK! zj>SbyUY2D6298%J-$*Ti0}sao!{<0zfgM!iWGGlXeNLBzZAF)B2g#cY*|=!2Jes>b zCO`Td;5SoCFRh8E%RlR&;lNN`RyP9$<6HhT7g)fBrK&J@z979`n?cjeT2R$R3tdKh z$zkES;CkE{u`L=>rkqCUSqrc`{x>~eI}ImlS>vBDC$MX2q@_O?GUM+Xy2^>t*{ybv zZh4q2d}>C`)@5O``&}@IwSxJ(-=gEnPat%U;MasB97bc??5UX2GF8i2n`1zrm*f`;ZiaB{B)8SP`Z6Nb>eIFr5~si3Q{0-OXs zzyzDCD7G#eJ`~(wURe7Or%Wlhu`~|5pCyyNW=VQSm7fT&y@-F#yAhpdMu3X zY5Q#e-6sri!lN}LciAd%Jg@||ycXx^5-HSw)5zHJ-ce0XHJQ}*jifnp;IF<2dX)Yp zULo@J!=+m|Et#c^Rq|5sm*U~`bqny;K_BwXRsp805#@-M_0YI4uB5Xt0?d|QXHss>K$*rq zS|bLq@O?JCk3sjx+e{LTJ-ahr&4*h_V9>Z73LW>P<9M0m|}acOHm>MO0nM9xEU zU3V>doiM~9ts{8Gd=VU3qmTCTy`(E%81~LpgzYhWH1kC>H0vuuZSF2SzqgRYn987c z;1=?$w;Bqvl`(#@H9p82ueO5#>d2p_5fL-tu6`y_6L!XWt$1=XDFJ-nD&xoAajB+? z4`%KhCs41?(2BeW8rk5E>l|tswQZ~LXl)leO&|%&P7tCSpo&RHggK8p1jqk79Z-C1 zPxfwXV@}rHMQAtco_`tOlK+s$ z@*m_`YR_HvzW})WUjXzpUj~u)$M-aT&?8glOXG(E1=KY=N}lId&_j;K%a z`Nxfw_FUV4+z_`JXMn5z0l;Yje0=(|v!TFzKS}W|po;1$ko09g&?TXms8fpbHO^wX zj~|ZRc~6ea5~P~L&sqJKTu|Uoq)l^Ile^^+bm475B4DD6@_%jN=s9P2^(h6;JR8Q# zA0kj?_G?-4Jib>)`K31DP_+HDl_phVZ0xiMnc@}+Gc7r{C zyNq@!-m5=zL!X?wca{E_&PR4{wucI?7vYqQzb{7mZDcJq1z4y*It)cj>+G@YWj z&-{QzBpbT>3M*a`O1syK0jY>$Z55=b%8JF*_1s+YSkj10a}r>k?**H`5K^muaj&cX zWUC^xYISp+UE?WcG5;S%L&KupJ#q>afAQGd`fM0$_E?IQ6Sz{ZRI`Gtm;J$NAJt%2 z-fmzuofont*KUtrzl|8IZwN}3_2if5V)o(YX;2i{PP$WmQ|a9c=!((^vYgvV;`}vH zc6cMXQs@Te$5vv~_M_&1iqGPHl`?Aeu$K64+>GLH))YI8w}bu|BMep8Z<(#QHxG}#`nt-K3zNxjVa=K{E(Cm2uo)H3tdbm7qTR%)HT z4j0F{ApLw59FE1K{Um8fSfoxHvUOqIi!J0;&P?j@S7`m?rfXb+<(9%;%4n z3tbO~QKt#D-w*SNUqyIzc1)8$Cz^6{khv+1A@68j$-5UoxQgEySTgfyKr}S z{`0H{Pi@EXqkP<*!Q5SrBIBO|xBL2yKNf6%x9IRkelHVByl@Bs~CLXT<9O literal 0 HcmV?d00001 diff --git a/tests/test_admp/test_compute.py b/tests/test_admp/test_compute.py index 02d81ead4..be4b9d99d 100644 --- a/tests/test_admp/test_compute.py +++ b/tests/test_admp/test_compute.py @@ -24,13 +24,17 @@ def test_init(self): """ rc = 4.0 H = Hamiltonian('tests/data/admp.xml') + H1 = Hamiltonian('tests/data/admp_mono.xml') + H2 = Hamiltonian('tests/data/admp_nonpol.xml') pdb = app.PDBFile('tests/data/water_dimer.pdb') potential = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom, ethresh=5e-4, step_pol=5) + potential1 = H1.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom, ethresh=5e-4, step_pol=5) + potential2 = H2.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom, ethresh=5e-4, step_pol=5) - yield potential, H.paramset + yield potential, potential1, potential2, H.paramset, H1.paramset, H2.paramset def test_ADMPPmeForce(self, pot_prm): - potential, paramset = pot_prm + potential, potential1, potential2, paramset, paramset1, paramset2 = pot_prm rc = 0.4 pdb = app.PDBFile('tests/data/water_dimer.pdb') positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) @@ -51,7 +55,7 @@ def test_ADMPPmeForce(self, pot_prm): def test_ADMPPmeForce_jit(self, pot_prm): - potential, paramset = pot_prm + potential, potential1, potential2, paramset, paramset1, paramset2 = pot_prm rc = 0.4 pdb = app.PDBFile('tests/data/water_dimer.pdb') positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) @@ -67,5 +71,47 @@ def test_ADMPPmeForce_jit(self, pot_prm): pot = potential.getPotentialFunc(names=["ADMPPmeForce"]) j_pot_pme = jit(value_and_grad(pot)) energy, grad = j_pot_pme(positions, box, pairs, paramset.parameters) - print(energy) + print('hahahah', energy) np.testing.assert_almost_equal(energy, -35.71585296268245, decimal=1) + + + def test_ADMPPmeForce_mono(self, pot_prm): + potential, potential1, potential2, paramset, paramset1, paramset2 = pot_prm + rc = 0.4 + pdb = app.PDBFile('tests/data/water_dimer.pdb') + positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) + positions = jnp.array(positions) + a, b, c = pdb.topology.getPeriodicBoxVectors().value_in_unit(unit.nanometer) + box = jnp.array([a, b, c]) + # neighbor list + + covalent_map = potential1.meta["cov_map"] + + nblist = NeighborList(box, rc, covalent_map) + nblist.allocate(positions) + pairs = nblist.pairs + pot = potential1.getPotentialFunc(names=["ADMPPmeForce"]) + energy = pot(positions, box, pairs, paramset1) + print(energy) + np.testing.assert_almost_equal(energy, -66.55921382, decimal=2) + + + def test_ADMPPmeForce_nonpol(self, pot_prm): + potential, potential1, potential2, paramset, paramset1, paramset2 = pot_prm + rc = 0.4 + pdb = app.PDBFile('tests/data/water_dimer.pdb') + positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) + positions = jnp.array(positions) + a, b, c = pdb.topology.getPeriodicBoxVectors().value_in_unit(unit.nanometer) + box = jnp.array([a, b, c]) + # neighbor list + + covalent_map = potential2.meta["cov_map"] + + nblist = NeighborList(box, rc, covalent_map) + nblist.allocate(positions) + pairs = nblist.pairs + pot = potential2.getPotentialFunc(names=["ADMPPmeForce"]) + energy = pot(positions, box, pairs, paramset2) + print(energy) + np.testing.assert_almost_equal(energy, -31.69025446, decimal=2) diff --git a/tests/test_sgnn/test_energy.py b/tests/test_sgnn/test_energy.py new file mode 100644 index 000000000..a771f4508 --- /dev/null +++ b/tests/test_sgnn/test_energy.py @@ -0,0 +1,51 @@ +import openmm.app as app +import openmm.unit as unit +import numpy as np +import jax.numpy as jnp +import numpy.testing as npt +import pytest +from dmff import Hamiltonian, NeighborList +from jax import jit, value_and_grad + +class TestADMPAPI: + + """ Test sGNN related generators + """ + + @pytest.fixture(scope='class', name='pot_prm') + def test_init(self): + """load generators from XML file + + Yields: + Tuple: ( + ADMPDispForce, + ADMPPmeForce, # polarized + ) + """ + rc = 4.0 + H = Hamiltonian('tests/data/peg_sgnn.xml') + pdb = app.PDBFile('tests/data/peg4.pdb') + potential = H.createPotential(pdb.topology, nonbondedCutoff=rc*unit.angstrom, ethresh=5e-4, step_pol=5) + + yield potential, H.paramset + + def test_sGNN_energy(self, pot_prm): + potential, paramset = pot_prm + rc = 0.4 + pdb = app.PDBFile('tests/data/peg4.pdb') + positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) + positions = jnp.array(positions) + a, b, c = pdb.topology.getPeriodicBoxVectors().value_in_unit(unit.nanometer) + box = jnp.array([a, b, c]) + # neighbor list + covalent_map = potential.meta["cov_map"] + + nblist = NeighborList(box, rc, covalent_map) + nblist.allocate(positions) + pairs = nblist.pairs + pot = potential.getPotentialFunc(names=["SGNNForce"]) + energy = pot(positions, box, pairs, paramset) + print(energy) + np.testing.assert_almost_equal(energy, -21.81780787, decimal=2) + + From 4be24752806da1e34f00be033b052ad0d3a672df Mon Sep 17 00:00:00 2001 From: KuangYu Date: Sat, 21 Oct 2023 17:31:24 +0800 Subject: [PATCH 2/2] remove debugging codes --- .github/workflows/ut.yml | 3 ++- dmff/operators/templatetype.py | 5 ----- examples/classical/test_xml.py | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ut.yml b/.github/workflows/ut.yml index 701acf9bb..5b8de3ba1 100644 --- a/.github/workflows/ut.yml +++ b/.github/workflows/ut.yml @@ -33,4 +33,5 @@ jobs: pytest -vs tests/test_common/test_* pytest -vs tests/test_admp/test_* pytest -vs tests/test_utils.py - pytest -vs tests/test_mbar/test_* + pytest -vs tests/test_mbar/test_* + pytest -vs tests/test_sgnn/test_* diff --git a/dmff/operators/templatetype.py b/dmff/operators/templatetype.py index ce18fdc3b..f4b7802d8 100644 --- a/dmff/operators/templatetype.py +++ b/dmff/operators/templatetype.py @@ -93,11 +93,6 @@ def match_all(self, topdata: DMFFTopology, templates): graph = self.generate_residue_graph(topdata, res) all_fail = True for ntemp, template in enumerate(templates): - # debug - # print(res) - # print(template) - # print(dir(template)) - # print('-------') is_matched, _, atype_dict = matchTemplate(graph, template) if is_matched: all_fail = False diff --git a/examples/classical/test_xml.py b/examples/classical/test_xml.py index 1affb8974..c5d594033 100755 --- a/examples/classical/test_xml.py +++ b/examples/classical/test_xml.py @@ -54,7 +54,6 @@ def getEnergyDecomposition(context, forcegroups): h = Hamiltonian("gaff-2.11.xml", "lig-prm.xml") pot = h.createPotential(pdb.topology, nonbondedMethod=app.NoCutoff) params = h.getParameters() - print(params) positions = pdb.getPositions(asNumpy=True).value_in_unit(unit.nanometer) positions = jnp.array(positions) @@ -84,3 +83,4 @@ def getEnergyDecomposition(context, forcegroups): etotal = pot.getPotentialFunc() print("Total:", etotal(positions, box, pairs, params)) +