pyjess 0.5.1__cp312-cp312-win_amd64.whl → 0.5.2__cp312-cp312-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyjess might be problematic. Click here for more details.
- pyjess/_jess.cp312-win_amd64.pyd +0 -0
- pyjess/_jess.pyi +2 -0
- pyjess/_jess.pyx +66 -29
- pyjess/tests/__init__.py +2 -0
- pyjess/tests/test_hit.py +33 -0
- pyjess/tests/test_jess.py +11 -0
- {pyjess-0.5.1.dist-info → pyjess-0.5.2.dist-info}/METADATA +1 -1
- {pyjess-0.5.1.dist-info → pyjess-0.5.2.dist-info}/RECORD +10 -9
- {pyjess-0.5.1.dist-info → pyjess-0.5.2.dist-info}/WHEEL +1 -1
- {pyjess-0.5.1.dist-info → pyjess-0.5.2.dist-info}/licenses/COPYING +0 -0
pyjess/_jess.cp312-win_amd64.pyd
CHANGED
|
Binary file
|
pyjess/_jess.pyi
CHANGED
|
@@ -183,6 +183,8 @@ class Query(Generic[_T], Iterator[Hit[_T]]):
|
|
|
183
183
|
def __next__(self) -> Hit[_T]: ...
|
|
184
184
|
|
|
185
185
|
class Hit(Generic[_T]):
|
|
186
|
+
def __getstate__(self) -> Dict[str, object]: ...
|
|
187
|
+
def __setstate__(self, state: Dict[str, object]) -> None: ...
|
|
186
188
|
@property
|
|
187
189
|
def rmsd(self) -> float: ...
|
|
188
190
|
@property
|
pyjess/_jess.pyx
CHANGED
|
@@ -1205,7 +1205,7 @@ cdef class Query:
|
|
|
1205
1205
|
cdef bint _rewind(self) noexcept nogil:
|
|
1206
1206
|
self._partial = True
|
|
1207
1207
|
|
|
1208
|
-
cdef int _copy_atoms(self, _Template* tpl, Hit hit) except -1 nogil:
|
|
1208
|
+
cdef int _copy_atoms(self, const _Template* tpl, Hit hit) except -1 nogil:
|
|
1209
1209
|
cdef _Atom** atoms = jess.jess.JessQuery_atoms(self._jq)
|
|
1210
1210
|
cdef int count = tpl.count(tpl)
|
|
1211
1211
|
|
|
@@ -1216,6 +1216,15 @@ cdef class Query:
|
|
|
1216
1216
|
memcpy(&hit._atoms[i], atoms[i], sizeof(_Atom))
|
|
1217
1217
|
return count
|
|
1218
1218
|
|
|
1219
|
+
cdef int _copy_superposition(self, _Superposition* sup, Hit hit) noexcept nogil:
|
|
1220
|
+
cdef const double* M = jess.super.Superposition_rotation(sup)
|
|
1221
|
+
cdef const double* c = jess.super.Superposition_centroid(sup, 0)
|
|
1222
|
+
cdef const double* v = jess.super.Superposition_centroid(sup, 1)
|
|
1223
|
+
memcpy(hit._rotation, M, 9*sizeof(double))
|
|
1224
|
+
memcpy(hit._centre[0], c, 3*sizeof(double))
|
|
1225
|
+
memcpy(hit._centre[1], v, 3*sizeof(double))
|
|
1226
|
+
return 0
|
|
1227
|
+
|
|
1219
1228
|
def __next__(self):
|
|
1220
1229
|
assert self._jq is not NULL
|
|
1221
1230
|
|
|
@@ -1227,11 +1236,11 @@ cdef class Query:
|
|
|
1227
1236
|
cdef Hit hit = Hit.__new__(Hit)
|
|
1228
1237
|
|
|
1229
1238
|
# prepare the hit to be returned
|
|
1230
|
-
hit._sup = NULL
|
|
1231
|
-
hit._atoms = NULL
|
|
1232
1239
|
hit.rmsd = INFINITY
|
|
1240
|
+
hit._atoms = NULL
|
|
1233
1241
|
hit._molecule = self.molecule
|
|
1234
1242
|
hit_tpl = NULL
|
|
1243
|
+
hit_found = False
|
|
1235
1244
|
|
|
1236
1245
|
# search the next hit without the GIL to allow parallel queries.
|
|
1237
1246
|
with nogil:
|
|
@@ -1240,14 +1249,13 @@ cdef class Query:
|
|
|
1240
1249
|
# was obtained with the current template and not with the
|
|
1241
1250
|
# previous one
|
|
1242
1251
|
tpl = jess.jess.JessQuery_template(self._jq)
|
|
1243
|
-
if
|
|
1252
|
+
if hit_found and hit_tpl != tpl:
|
|
1244
1253
|
self._rewind()
|
|
1245
1254
|
break
|
|
1246
1255
|
|
|
1247
1256
|
# load superposition and compute RMSD for the current iteration
|
|
1248
1257
|
sup = jess.jess.JessQuery_superposition(self._jq)
|
|
1249
1258
|
rmsd = jess.super.Superposition_rmsd(sup)
|
|
1250
|
-
keep_sup = False
|
|
1251
1259
|
|
|
1252
1260
|
# NB(@althonos): we don't need to compute the E-value to get the
|
|
1253
1261
|
# best match by molecule/template pair since the
|
|
@@ -1272,22 +1280,20 @@ cdef class Query:
|
|
|
1272
1280
|
stacklevel=2,
|
|
1273
1281
|
)
|
|
1274
1282
|
else:
|
|
1275
|
-
if hit._sup != NULL:
|
|
1276
|
-
jess.super.Superposition_free(hit._sup)
|
|
1277
1283
|
self._copy_atoms(tpl, hit)
|
|
1278
|
-
|
|
1284
|
+
self._copy_superposition(sup, hit)
|
|
1279
1285
|
hit.rmsd = rmsd
|
|
1280
1286
|
hit_tpl = tpl
|
|
1287
|
+
hit_found = True
|
|
1281
1288
|
|
|
1282
1289
|
# free superposition items that are not used in a hit, and
|
|
1283
1290
|
# return hits immediately if we are not in best match mode
|
|
1284
1291
|
self._candidates += 1
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
if hit._sup != NULL and not self.best_match:
|
|
1292
|
+
jess.super.Superposition_free(sup)
|
|
1293
|
+
if hit_found and not self.best_match:
|
|
1288
1294
|
break
|
|
1289
1295
|
|
|
1290
|
-
if
|
|
1296
|
+
if not hit_found:
|
|
1291
1297
|
raise StopIteration
|
|
1292
1298
|
|
|
1293
1299
|
# get the template object for the hit
|
|
@@ -1305,7 +1311,8 @@ cdef class Hit:
|
|
|
1305
1311
|
molecule (`~pyjess.Molecule`): The query molecule.
|
|
1306
1312
|
|
|
1307
1313
|
"""
|
|
1308
|
-
cdef
|
|
1314
|
+
cdef double[9] _rotation
|
|
1315
|
+
cdef double[2][3] _centre
|
|
1309
1316
|
cdef _Atom* _atoms
|
|
1310
1317
|
|
|
1311
1318
|
cdef readonly double rmsd
|
|
@@ -1313,19 +1320,49 @@ cdef class Hit:
|
|
|
1313
1320
|
cdef Molecule _molecule
|
|
1314
1321
|
|
|
1315
1322
|
def __dealloc__(self):
|
|
1316
|
-
jess.super.Superposition_free(self._sup)
|
|
1317
1323
|
free(self._atoms)
|
|
1318
1324
|
|
|
1325
|
+
def __getstate__(self):
|
|
1326
|
+
return {
|
|
1327
|
+
"rotation": list(self._rotation),
|
|
1328
|
+
"centre": list(self._centre),
|
|
1329
|
+
"atoms": self.atoms(transform=False),
|
|
1330
|
+
"rmsd": self.rmsd,
|
|
1331
|
+
"template": self.template,
|
|
1332
|
+
"molecule": self.molecule(transform=False),
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
def __setstate__(self, state):
|
|
1336
|
+
cdef size_t i
|
|
1337
|
+
cdef size_t count
|
|
1338
|
+
cdef Atom atom
|
|
1339
|
+
|
|
1340
|
+
self.rmsd = state["rmsd"]
|
|
1341
|
+
self.template = state["template"]
|
|
1342
|
+
self._molecule = state["molecule"]
|
|
1343
|
+
self._rotation = state["rotation"]
|
|
1344
|
+
self._centre = state["centre"]
|
|
1345
|
+
|
|
1346
|
+
# check number of atoms is consistent
|
|
1347
|
+
count = len(self.template)
|
|
1348
|
+
if len(state["atoms"]) != count:
|
|
1349
|
+
raise ValueError(f"unexpected number of atoms: {len(state['atoms'])!r} (expected {count!r})")
|
|
1350
|
+
# allocate or reallocate memory for atoms
|
|
1351
|
+
self._atoms = <_Atom*> realloc(self._atoms, count * sizeof(_Atom))
|
|
1352
|
+
if self._atoms is NULL:
|
|
1353
|
+
raise MemoryError("Failed to allocate hit atoms")
|
|
1354
|
+
# copy atom data
|
|
1355
|
+
for i, atom in enumerate(state["atoms"]):
|
|
1356
|
+
memcpy(&self._atoms[i], atom._atom, sizeof(_Atom))
|
|
1357
|
+
|
|
1319
1358
|
@property
|
|
1320
1359
|
def determinant(self):
|
|
1321
1360
|
"""`float`: The determinant of the rotation matrix.
|
|
1322
1361
|
"""
|
|
1323
|
-
|
|
1324
|
-
cdef const double* p
|
|
1362
|
+
cdef const double* p = self._rotation
|
|
1325
1363
|
cdef double det = 0.0
|
|
1326
1364
|
|
|
1327
1365
|
with nogil:
|
|
1328
|
-
p = jess.super.Superposition_rotation(self._sup)
|
|
1329
1366
|
det += p[0] * (p[4] * p[8] - p[5] * p[7])
|
|
1330
1367
|
det -= p[1] * (p[3] * p[8] - p[5] * p[6])
|
|
1331
1368
|
det += p[2] * (p[3] * p[7] - p[4] * p[6])
|
|
@@ -1369,7 +1406,6 @@ cdef class Hit:
|
|
|
1369
1406
|
|
|
1370
1407
|
"""
|
|
1371
1408
|
assert self.template._tpl is not NULL
|
|
1372
|
-
assert self._sup is not NULL
|
|
1373
1409
|
|
|
1374
1410
|
cdef Atom atom
|
|
1375
1411
|
cdef int i
|
|
@@ -1378,21 +1414,23 @@ cdef class Hit:
|
|
|
1378
1414
|
cdef int count = self.template._tpl.count(self.template._tpl)
|
|
1379
1415
|
cdef list atoms = []
|
|
1380
1416
|
|
|
1381
|
-
cdef const double* M =
|
|
1382
|
-
cdef const double* c =
|
|
1383
|
-
cdef const double* v =
|
|
1417
|
+
cdef const double* M = self._rotation
|
|
1418
|
+
cdef const double* c = self._centre[0]
|
|
1419
|
+
cdef const double* v = self._centre[1]
|
|
1384
1420
|
|
|
1385
1421
|
for k in range(count):
|
|
1386
|
-
|
|
1387
1422
|
atom = Atom.__new__(Atom)
|
|
1388
|
-
atom._atom = <_Atom*> malloc(sizeof(_Atom))
|
|
1389
|
-
memcpy(atom._atom, &self._atoms[k], sizeof(_Atom))
|
|
1390
|
-
|
|
1391
1423
|
if transform:
|
|
1424
|
+
atom._atom = <_Atom*> malloc(sizeof(_Atom))
|
|
1425
|
+
memcpy(atom._atom, &self._atoms[k], sizeof(_Atom))
|
|
1392
1426
|
for i in range(3):
|
|
1393
1427
|
atom._atom.x[i] = v[i]
|
|
1394
1428
|
for j in range(3):
|
|
1395
1429
|
atom._atom.x[i] += M[3*i + j] * (self._atoms[k].x[j] - c[j])
|
|
1430
|
+
else:
|
|
1431
|
+
atom.owned = True
|
|
1432
|
+
atom.owner = self
|
|
1433
|
+
atom._atom = &self._atoms[k]
|
|
1396
1434
|
|
|
1397
1435
|
atoms.append(atom)
|
|
1398
1436
|
|
|
@@ -1413,16 +1451,15 @@ cdef class Hit:
|
|
|
1413
1451
|
|
|
1414
1452
|
"""
|
|
1415
1453
|
assert self.template._tpl is not NULL
|
|
1416
|
-
assert self._sup is not NULL
|
|
1417
1454
|
|
|
1418
1455
|
cdef _Atom* atom
|
|
1419
1456
|
cdef Molecule mol
|
|
1420
1457
|
cdef size_t i
|
|
1421
1458
|
cdef size_t j
|
|
1422
1459
|
cdef size_t k
|
|
1423
|
-
cdef const double* M
|
|
1424
|
-
cdef const double* c
|
|
1425
|
-
cdef const double* v
|
|
1460
|
+
cdef const double* M = self._rotation
|
|
1461
|
+
cdef const double* c = self._centre[0]
|
|
1462
|
+
cdef const double* v = self._centre[1]
|
|
1426
1463
|
|
|
1427
1464
|
if not transform:
|
|
1428
1465
|
return self._molecule
|
pyjess/tests/__init__.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from . import (
|
|
2
2
|
test_atom,
|
|
3
|
+
test_hit,
|
|
3
4
|
test_jess,
|
|
4
5
|
test_molecule,
|
|
5
6
|
test_template_atom,
|
|
@@ -8,6 +9,7 @@ from . import (
|
|
|
8
9
|
|
|
9
10
|
def load_tests(loader, suite, pattern):
|
|
10
11
|
suite.addTests(loader.loadTestsFromModule(test_atom))
|
|
12
|
+
suite.addTests(loader.loadTestsFromModule(test_hit))
|
|
11
13
|
suite.addTests(loader.loadTestsFromModule(test_jess))
|
|
12
14
|
suite.addTests(loader.loadTestsFromModule(test_molecule))
|
|
13
15
|
suite.addTests(loader.loadTestsFromModule(test_template_atom))
|
pyjess/tests/test_hit.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import math
|
|
2
|
+
import unittest
|
|
3
|
+
import sys
|
|
4
|
+
import pickle
|
|
5
|
+
|
|
6
|
+
from .._jess import Template, Molecule, Jess
|
|
7
|
+
from .utils import files
|
|
8
|
+
from . import data
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TestHit(unittest.TestCase):
|
|
12
|
+
|
|
13
|
+
@unittest.skipUnless(files, "importlib.resources not available")
|
|
14
|
+
@classmethod
|
|
15
|
+
def setUpClass(cls):
|
|
16
|
+
with files(data).joinpath("template_01.qry").open() as f:
|
|
17
|
+
template = Template.load(f)
|
|
18
|
+
jess = Jess([template])
|
|
19
|
+
with files(data).joinpath("pdb1lnb.pdb").open() as f:
|
|
20
|
+
molecule = Molecule.load(f)
|
|
21
|
+
|
|
22
|
+
cls.hit = next(jess.query(molecule, 1, 2, 2))
|
|
23
|
+
|
|
24
|
+
def test_pickle(self):
|
|
25
|
+
hit = pickle.loads(pickle.dumps(self.hit))
|
|
26
|
+
self.assertIsNot(self.hit, hit)
|
|
27
|
+
self.assertEqual(self.hit.rmsd, hit.rmsd)
|
|
28
|
+
self.assertEqual(self.hit.determinant, hit.determinant)
|
|
29
|
+
self.assertEqual(self.hit.evalue, hit.evalue)
|
|
30
|
+
self.assertEqual(self.hit.template, hit.template)
|
|
31
|
+
self.assertListEqual(self.hit.atoms(transform=True), hit.atoms(transform=True))
|
|
32
|
+
self.assertListEqual(self.hit.atoms(transform=False), hit.atoms(transform=False))
|
|
33
|
+
self.assertEqual(self.hit.molecule(transform=False), hit.molecule(transform=False))
|
pyjess/tests/test_jess.py
CHANGED
|
@@ -240,3 +240,14 @@ class TestJess(unittest.TestCase):
|
|
|
240
240
|
self.assertAlmostEqual(atom.occupancy, float(atom_line[55:61]), places=3)
|
|
241
241
|
self.assertAlmostEqual(atom.temperature_factor, float(atom_line[61:67]), places=3)
|
|
242
242
|
|
|
243
|
+
atoms = hit.atoms(transform=False)
|
|
244
|
+
self.assertEqual(len(atoms), len(atom_lines))
|
|
245
|
+
for atom, atom_line in zip(atoms, atom_lines):
|
|
246
|
+
self.assertEqual(atom.serial, int(atom_line[7:12]))
|
|
247
|
+
self.assertEqual(atom.name, atom_line[13:17].strip())
|
|
248
|
+
self.assertEqual(atom.residue_name, atom_line[17:21].strip())
|
|
249
|
+
self.assertEqual(atom.chain_id, atom_line[21:23].strip())
|
|
250
|
+
self.assertEqual(atom.residue_number, int(atom_line[23:27]))
|
|
251
|
+
self.assertAlmostEqual(atom.occupancy, float(atom_line[55:61]), places=3)
|
|
252
|
+
self.assertAlmostEqual(atom.temperature_factor, float(atom_line[61:67]), places=3)
|
|
253
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: pyjess
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Cython bindings and Python interface to JESS, a 3D template matching software.
|
|
5
5
|
Keywords: bioinformatics,structure,template,matching
|
|
6
6
|
Author-Email: Martin Larralde <martin.larralde@embl.de>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
pyjess/.gitignore,sha256=u14v4OOy8U50Kp9SUKU8DupCG-mQIuel47gdbNDmAwg,21
|
|
2
2
|
pyjess/__init__.py,sha256=Xe9GBQUBm9ik-ty5tcE3UQ9Ip1p-C_IGvTPuGULolng,766
|
|
3
|
-
pyjess/_jess.cp312-win_amd64.pyd,sha256=
|
|
4
|
-
pyjess/_jess.pyi,sha256=
|
|
5
|
-
pyjess/_jess.pyx,sha256=
|
|
3
|
+
pyjess/_jess.cp312-win_amd64.pyd,sha256=Ho-TAV-b8x4Pw5doINzpgGicogT8Qec1XbkHTMuKc_0,317440
|
|
4
|
+
pyjess/_jess.pyi,sha256=1U7KeCDydiOT0vGts0sidGz_gI2PycD1sBiUmcafd7c,7239
|
|
5
|
+
pyjess/_jess.pyx,sha256=tyAyYZaYYm8-dAMDMrH6WrpV5hM8hnn9DYHh4idoAOA,53500
|
|
6
6
|
pyjess/CMakeLists.txt,sha256=H9eXbrFcGF2OLP8muQctb4cOb27Qp2uZj5KRjoDAROg,36
|
|
7
7
|
pyjess/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
pyjess/tests/__init__.py,sha256=
|
|
8
|
+
pyjess/tests/__init__.py,sha256=J7rYASCuQsCu5gktf5XqjNxJoBkBqxbREAiaSOta5xE,617
|
|
9
9
|
pyjess/tests/data/1.3.3.tpl,sha256=gleyiSSHAVJbRJaK8Nlh9setsj6EI38Sr1XU5OEduQE,1011
|
|
10
10
|
pyjess/tests/data/1AMY+1.3.3.txt,sha256=Wyq9Eh9QVaOPH_jsZ6iF9WYhFdTGESqOzjfX14-0gAo,105456
|
|
11
11
|
pyjess/tests/data/1AMY.pdb,sha256=fIbowuYS46hQh82xBtVaIPC50o7U08CnHNcnq4nM944,323162
|
|
@@ -14,12 +14,13 @@ pyjess/tests/data/pdb1lnb.pdb,sha256=F8A6OdRly5c-pxsDw1LjTFINI75r1HaKaYB_eXv1QuM
|
|
|
14
14
|
pyjess/tests/data/template_01.qry,sha256=izCIhUUTEk-IvQowhSVLiJaCAhpPbyvrfyoR4Q6-Pm0,616
|
|
15
15
|
pyjess/tests/data/template_02.qry,sha256=5IYRTqsvO_roB2INLwfFDEaWJW9VRcXdbK4oe8VKMxE,618
|
|
16
16
|
pyjess/tests/test_atom.py,sha256=clLN9IVuivadztGtagDhdPBDGoMkUgs41lEWuTCCmFA,4741
|
|
17
|
-
pyjess/tests/
|
|
17
|
+
pyjess/tests/test_hit.py,sha256=3p7MkvZL84e-tSbVlMSXHbO1yCZkaLIMD2e09occw1A,1244
|
|
18
|
+
pyjess/tests/test_jess.py,sha256=Hp12b3xkRX0U8RFcejwDPFTEX8JzpOQTF6_zMXYAWDM,11616
|
|
18
19
|
pyjess/tests/test_molecule.py,sha256=9k6uiTeOWc5NiO7epyxY9lm_GgksPb7-o-ZcNFNxutw,5452
|
|
19
20
|
pyjess/tests/test_template.py,sha256=AIN-ba5-YTnGdT9SGPU4q45AZ03QnPE769WyItSpoPs,4657
|
|
20
21
|
pyjess/tests/test_template_atom.py,sha256=oK8cfKe4_k3Pm1PqoTTxTzAoeUVLiCFsg6QmiTQ-RCQ,3496
|
|
21
22
|
pyjess/tests/utils.py,sha256=Z7rUPC-D8dZlRfHAnLaXHUg6M10D3zFvNiwDvvHA3xc,202
|
|
22
|
-
pyjess-0.5.
|
|
23
|
-
pyjess-0.5.
|
|
24
|
-
pyjess-0.5.
|
|
25
|
-
pyjess-0.5.
|
|
23
|
+
pyjess-0.5.2.dist-info/METADATA,sha256=tsCMCW4Qh7vkECoA8aybf9sb0I8QTcdifZ7P7SDm1oI,11248
|
|
24
|
+
pyjess-0.5.2.dist-info/WHEEL,sha256=chqeLhPBtPdrOoreR34YMcofSk3yWDQhkrsDJ2n48LU,106
|
|
25
|
+
pyjess-0.5.2.dist-info/licenses/COPYING,sha256=Iyx2bRDPnLgoEzW2KVanb61cjhW8lnhJNU-mjS-KhIY,1124
|
|
26
|
+
pyjess-0.5.2.dist-info/RECORD,,
|
|
File without changes
|