modelcraft 5.0.3__py3-none-any.whl → 6.0.0__py3-none-any.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.
- modelcraft/__init__.py +16 -31
- modelcraft/__main__.py +0 -1
- modelcraft/arguments.py +35 -7
- modelcraft/combine.py +22 -41
- modelcraft/contents.py +188 -164
- modelcraft/environ.py +0 -7
- modelcraft/geometry.py +39 -27
- modelcraft/job.py +6 -5
- modelcraft/jobs/acedrg.py +2 -0
- modelcraft/jobs/buccaneer.py +22 -4
- modelcraft/jobs/comit.py +2 -0
- modelcraft/jobs/ctruncate.py +3 -1
- modelcraft/jobs/emda.py +2 -0
- modelcraft/jobs/findwaters.py +2 -0
- modelcraft/jobs/freerflag.py +2 -0
- modelcraft/jobs/libg.py +2 -0
- modelcraft/jobs/molrep.py +2 -0
- modelcraft/jobs/nautilus.py +28 -14
- modelcraft/jobs/nucleofind.py +88 -0
- modelcraft/jobs/parrot.py +13 -2
- modelcraft/jobs/phasematch.py +2 -1
- modelcraft/jobs/refmac.py +3 -1
- modelcraft/jobs/servalcat.py +36 -2
- modelcraft/jobs/sheetbend.py +2 -0
- modelcraft/modelcraftem.py +49 -6
- modelcraft/modelcraftxray.py +90 -42
- modelcraft/monlib.py +55 -52
- modelcraft/pdbe.py +54 -0
- modelcraft/pipeline.py +1 -1
- modelcraft/prune.py +69 -0
- modelcraft/reflections.py +11 -1
- modelcraft/scripts/contents.py +5 -215
- modelcraft/scripts/copies.py +26 -17
- modelcraft/scripts/modelcraft.py +1 -0
- modelcraft/scripts/sidechains.py +141 -0
- modelcraft/scripts/validate.py +81 -0
- modelcraft/sequence.py +106 -0
- modelcraft/solvent.py +42 -113
- modelcraft/structure.py +64 -41
- modelcraft/tests/ccp4/__init__.py +7 -11
- modelcraft/tests/ccp4/test_acedrg.py +2 -0
- modelcraft/tests/ccp4/test_arguments.py +3 -0
- modelcraft/tests/ccp4/test_buccaneer.py +3 -2
- modelcraft/tests/ccp4/test_cell.py +4 -1
- modelcraft/tests/ccp4/test_comit.py +2 -0
- modelcraft/tests/ccp4/test_contents.py +99 -17
- modelcraft/tests/ccp4/test_copies.py +1 -0
- modelcraft/tests/ccp4/test_ctruncate.py +2 -0
- modelcraft/tests/ccp4/test_findwaters.py +2 -0
- modelcraft/tests/ccp4/test_freerflag.py +2 -0
- modelcraft/tests/ccp4/test_libg.py +1 -0
- modelcraft/tests/ccp4/test_molrep.py +3 -0
- modelcraft/tests/ccp4/test_monlib.py +75 -45
- modelcraft/tests/ccp4/test_nautilus.py +5 -3
- modelcraft/tests/ccp4/test_nucleofind.py +62 -0
- modelcraft/tests/ccp4/test_parrot.py +3 -1
- modelcraft/tests/ccp4/test_phasematch.py +2 -0
- modelcraft/tests/ccp4/test_prune.py +17 -0
- modelcraft/tests/ccp4/test_reflections.py +110 -1
- modelcraft/tests/ccp4/test_refmac.py +3 -0
- modelcraft/tests/{unittests/test_contents.py → ccp4/test_sequence.py} +5 -12
- modelcraft/tests/ccp4/test_servalcat.py +52 -0
- modelcraft/tests/ccp4/test_sheetbend.py +4 -3
- modelcraft/tests/ccp4/test_sidechains.py +25 -0
- modelcraft/tests/ccp4/test_solvent.py +12 -26
- modelcraft/tests/ccp4/test_structure.py +1 -0
- modelcraft/tests/ccp4/test_validation.py +19 -0
- modelcraft/tests/ccp4/test_xray.py +12 -6
- modelcraft/tests/ccpem/test_em.py +3 -0
- modelcraft/tests/ccpem/test_emda.py +2 -0
- modelcraft/tests/ccpem/test_refmac.py +1 -0
- modelcraft/tests/ccpem/test_servalcat.py +4 -3
- modelcraft/utils.py +16 -4
- modelcraft/validation.py +101 -0
- modelcraft-6.0.0.dist-info/METADATA +76 -0
- modelcraft-6.0.0.dist-info/RECORD +85 -0
- {modelcraft-5.0.3.dist-info → modelcraft-6.0.0.dist-info}/WHEEL +1 -1
- {modelcraft-5.0.3.dist-info → modelcraft-6.0.0.dist-info}/entry_points.txt +2 -0
- modelcraft/coot/prune.py +0 -1085
- modelcraft/coot/sidechains.py +0 -68
- modelcraft/jobs/acorn.py +0 -114
- modelcraft/jobs/coot.py +0 -104
- modelcraft/tests/ccp4/test_coot.py +0 -29
- modelcraft/tests/ccp4/test_geometry.py +0 -20
- modelcraft/tests/unittests/__init__.py +0 -0
- modelcraft/tests/unittests/test_reflections.py +0 -101
- modelcraft-5.0.3.dist-info/METADATA +0 -49
- modelcraft-5.0.3.dist-info/RECORD +0 -82
- modelcraft-5.0.3.dist-info/licenses/LICENSE +0 -504
- {modelcraft-5.0.3.dist-info → modelcraft-6.0.0.dist-info}/top_level.txt +0 -0
|
@@ -1,61 +1,91 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
1
3
|
import gemmi
|
|
2
|
-
|
|
3
|
-
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from modelcraft.monlib import MonLib
|
|
7
|
+
from modelcraft.sequence import DNA_CODES, PROTEIN_CODES, RNA_CODES
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture(name="monlib", scope="module")
|
|
11
|
+
def monlib_fixture():
|
|
12
|
+
return MonLib({"COM", "2GP"}, include_standard=True)
|
|
4
13
|
|
|
5
14
|
|
|
6
|
-
def test_hoh_ids():
|
|
15
|
+
def test_hoh_ids(monlib: MonLib):
|
|
7
16
|
ids = {"O", "H1", "H2"}
|
|
8
|
-
assert atom_ids("HOH") == ids
|
|
17
|
+
assert monlib.atom_ids("HOH") == ids
|
|
9
18
|
|
|
10
19
|
|
|
11
|
-
def test_gly_ids():
|
|
20
|
+
def test_gly_ids(monlib: MonLib):
|
|
12
21
|
ids = {"N", "H", "H2", "H3", "CA", "HA3", "HA2", "C", "O", "OXT"}
|
|
13
|
-
assert atom_ids("GLY") == ids
|
|
22
|
+
assert monlib.atom_ids("GLY") == ids
|
|
14
23
|
|
|
15
24
|
|
|
16
|
-
def test_com_ids():
|
|
25
|
+
def test_com_ids(monlib: MonLib):
|
|
17
26
|
ids = {"C1", "C2", "S1", "S2", "O1S", "O2S", "O3S"}
|
|
18
27
|
ids |= {"H11", "H12", "H21", "H22", "HS1", "HOS3"}
|
|
19
|
-
assert atom_ids("COM") == ids
|
|
28
|
+
assert monlib.atom_ids("COM") == ids
|
|
20
29
|
|
|
21
30
|
|
|
22
|
-
def test_in_library():
|
|
31
|
+
def test_in_library(monlib: MonLib):
|
|
23
32
|
for code in PROTEIN_CODES.values():
|
|
24
|
-
assert
|
|
33
|
+
assert code in monlib
|
|
25
34
|
for code in DNA_CODES.values():
|
|
26
|
-
assert
|
|
35
|
+
assert code in monlib
|
|
27
36
|
for code in RNA_CODES.values():
|
|
28
|
-
assert
|
|
29
|
-
assert
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def test_group():
|
|
33
|
-
assert group("GLY") == gemmi.ChemComp.Group.Peptide
|
|
34
|
-
assert group("ALA") == gemmi.ChemComp.Group.Peptide
|
|
35
|
-
assert group("MSE") == gemmi.ChemComp.Group.Peptide
|
|
36
|
-
assert group("PRO") == gemmi.ChemComp.Group.PPeptide
|
|
37
|
-
assert group("U") == gemmi.ChemComp.Group.Rna
|
|
38
|
-
assert group("DT") == gemmi.ChemComp.Group.Dna
|
|
39
|
-
assert group("HOH") == gemmi.ChemComp.Group.NonPolymer
|
|
40
|
-
assert group("NOT_IN_MONLIB")
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
def test_protein():
|
|
44
|
-
assert is_protein("GLY")
|
|
45
|
-
assert is_protein("ALA")
|
|
46
|
-
assert is_protein("MSE")
|
|
47
|
-
assert is_protein("PRO")
|
|
48
|
-
assert not is_protein("U")
|
|
49
|
-
assert not is_protein("DT")
|
|
50
|
-
assert not is_protein("HOH")
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
assert not is_nucleic("
|
|
56
|
-
assert not is_nucleic("
|
|
57
|
-
assert
|
|
58
|
-
assert is_nucleic("
|
|
59
|
-
assert is_nucleic("
|
|
60
|
-
|
|
61
|
-
|
|
37
|
+
assert code in monlib
|
|
38
|
+
assert "NOT_IN_MONLIB" not in monlib
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def test_group(monlib: MonLib):
|
|
42
|
+
assert monlib.group("GLY") == gemmi.ChemComp.Group.Peptide
|
|
43
|
+
assert monlib.group("ALA") == gemmi.ChemComp.Group.Peptide
|
|
44
|
+
assert monlib.group("MSE") == gemmi.ChemComp.Group.Peptide
|
|
45
|
+
assert monlib.group("PRO") == gemmi.ChemComp.Group.PPeptide
|
|
46
|
+
assert monlib.group("U") == gemmi.ChemComp.Group.Rna
|
|
47
|
+
assert monlib.group("DT") == gemmi.ChemComp.Group.Dna
|
|
48
|
+
assert monlib.group("HOH") == gemmi.ChemComp.Group.NonPolymer
|
|
49
|
+
assert monlib.group("NOT_IN_MONLIB") == gemmi.ChemComp.Group.Null
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def test_protein(monlib: MonLib):
|
|
53
|
+
assert monlib.is_protein("GLY")
|
|
54
|
+
assert monlib.is_protein("ALA")
|
|
55
|
+
assert monlib.is_protein("MSE")
|
|
56
|
+
assert monlib.is_protein("PRO")
|
|
57
|
+
assert not monlib.is_protein("U")
|
|
58
|
+
assert not monlib.is_protein("DT")
|
|
59
|
+
assert not monlib.is_protein("HOH")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def test_nucleic(monlib: MonLib):
|
|
63
|
+
assert not monlib.is_nucleic("GLY")
|
|
64
|
+
assert not monlib.is_nucleic("ALA")
|
|
65
|
+
assert not monlib.is_nucleic("PRO")
|
|
66
|
+
assert monlib.is_nucleic("U")
|
|
67
|
+
assert monlib.is_nucleic("DT")
|
|
68
|
+
assert not monlib.is_nucleic("HOH")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@pytest.mark.parametrize("code,expected", [("HOH", 18), ("2GP", 432)])
|
|
72
|
+
def test_volume(monlib: MonLib, code: str, expected: float):
|
|
73
|
+
assert math.isclose(monlib.volume(code), expected, abs_tol=0.01)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def test_not_in_monlib(monlib: MonLib):
|
|
77
|
+
with pytest.raises(KeyError):
|
|
78
|
+
monlib["NOT_IN_MONLIB"]
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@pytest.mark.parametrize(
|
|
82
|
+
"code,expected",
|
|
83
|
+
[
|
|
84
|
+
("ALA", 89.09),
|
|
85
|
+
("ASP", 132.09),
|
|
86
|
+
("ASN", 132.12),
|
|
87
|
+
("UNK", 103.12),
|
|
88
|
+
],
|
|
89
|
+
)
|
|
90
|
+
def test_weight(monlib: MonLib, code: str, expected: float):
|
|
91
|
+
assert math.isclose(monlib.weight(code), expected, abs_tol=0.01)
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import gemmi
|
|
2
|
+
|
|
2
3
|
from modelcraft.jobs.freerflag import FreeRFlag
|
|
3
4
|
from modelcraft.jobs.nautilus import Nautilus
|
|
4
5
|
from modelcraft.jobs.refmac import Refmac
|
|
5
6
|
from modelcraft.pipeline import Pipeline
|
|
6
7
|
from modelcraft.reflections import DataItem
|
|
7
|
-
from modelcraft.scripts.contents import
|
|
8
|
+
from modelcraft.scripts.contents import AsuContents
|
|
8
9
|
from modelcraft.structure import (
|
|
9
|
-
contains_residue,
|
|
10
10
|
ModelStats,
|
|
11
|
+
contains_residue,
|
|
11
12
|
read_structure,
|
|
12
13
|
remove_residues,
|
|
13
14
|
)
|
|
15
|
+
|
|
14
16
|
from . import in_temp_directory, pdbe_download
|
|
15
17
|
|
|
16
18
|
|
|
@@ -27,7 +29,7 @@ def test_102d():
|
|
|
27
29
|
fsigf = DataItem(mtz, "FP,SIGFP")
|
|
28
30
|
freer = FreeRFlag(fsigf).run().freer
|
|
29
31
|
refmac = Refmac(structure=structure, fsigf=fsigf, freer=freer, cycles=0).run()
|
|
30
|
-
contents =
|
|
32
|
+
contents = AsuContents.from_pdbe("102d")
|
|
31
33
|
pipeline = Pipeline(keep_jobs=True)
|
|
32
34
|
# Test without an input structure
|
|
33
35
|
nautilus = Nautilus(
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import shutil
|
|
2
|
+
|
|
3
|
+
import gemmi
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from modelcraft.jobs.freerflag import FreeRFlag
|
|
7
|
+
from modelcraft.jobs.nucleofind import NucleoFindBuild, NucleoFindPredict
|
|
8
|
+
from modelcraft.jobs.refmac import Refmac
|
|
9
|
+
from modelcraft.pipeline import Pipeline
|
|
10
|
+
from modelcraft.reflections import DataItem
|
|
11
|
+
from modelcraft.scripts.contents import AsuContents
|
|
12
|
+
from modelcraft.structure import (
|
|
13
|
+
ModelStats,
|
|
14
|
+
contains_residue,
|
|
15
|
+
read_structure,
|
|
16
|
+
remove_residues,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
from . import in_temp_directory, pdbe_download
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.mark.skipif(not shutil.which("nucleofind"), reason="NucleoFind not installed")
|
|
23
|
+
@in_temp_directory
|
|
24
|
+
def test_102d():
|
|
25
|
+
# Prepare input data
|
|
26
|
+
pdbe_download("102d.cif")
|
|
27
|
+
structure = read_structure("102d.cif")
|
|
28
|
+
pdbe_download("r102dsf.ent")
|
|
29
|
+
doc = gemmi.cif.read("r102dsf.ent")
|
|
30
|
+
rblocks = gemmi.as_refln_blocks(doc)
|
|
31
|
+
cif2mtz = gemmi.CifToMtz()
|
|
32
|
+
mtz = cif2mtz.convert_block_to_mtz(rblocks[0])
|
|
33
|
+
fsigf = DataItem(mtz, "FP,SIGFP")
|
|
34
|
+
freer = FreeRFlag(fsigf).run().freer
|
|
35
|
+
refmac = Refmac(structure=structure, fsigf=fsigf, freer=freer, cycles=0).run()
|
|
36
|
+
contents = AsuContents.from_pdbe("102d")
|
|
37
|
+
pipeline = Pipeline(keep_jobs=True)
|
|
38
|
+
# Test without an input structure
|
|
39
|
+
prediction = NucleoFindPredict(fphi=refmac.fphi_best).run(pipeline)
|
|
40
|
+
build_result = NucleoFindBuild(
|
|
41
|
+
contents=contents,
|
|
42
|
+
fphi=refmac.fphi_best,
|
|
43
|
+
prediction=prediction,
|
|
44
|
+
).run(pipeline)
|
|
45
|
+
stats = ModelStats(build_result.structure)
|
|
46
|
+
assert stats.residues > 12
|
|
47
|
+
# Test with an input structure
|
|
48
|
+
remove_residues(structure, ["HOH"])
|
|
49
|
+
build_result = NucleoFindBuild(
|
|
50
|
+
contents=contents,
|
|
51
|
+
fphi=refmac.fphi_best,
|
|
52
|
+
prediction=prediction,
|
|
53
|
+
structure=structure,
|
|
54
|
+
).run(pipeline)
|
|
55
|
+
stats = ModelStats(build_result.structure)
|
|
56
|
+
assert contains_residue(build_result.structure, "DT")
|
|
57
|
+
assert stats.residues > 22
|
|
58
|
+
assert build_result.fragments_built > 2
|
|
59
|
+
assert build_result.residues_built > 22
|
|
60
|
+
assert build_result.residues_sequenced > 20
|
|
61
|
+
assert build_result.longest_fragment > 11
|
|
62
|
+
# TODO: assert contains_residue(nautilus.structure, "TNT")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from ...prune import prune
|
|
2
|
+
from ...structure import ModelStats
|
|
3
|
+
from . import insulin_refmac
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def test_insulin_prune():
|
|
7
|
+
refmac = insulin_refmac()
|
|
8
|
+
pruned = prune(
|
|
9
|
+
structure=refmac.structure,
|
|
10
|
+
fphi_best=refmac.fphi_best,
|
|
11
|
+
fphi_diff=refmac.fphi_diff,
|
|
12
|
+
fphi_calc=refmac.fphi_calc,
|
|
13
|
+
residue_threshold=-2,
|
|
14
|
+
)
|
|
15
|
+
stats_in = ModelStats(refmac.structure)
|
|
16
|
+
stats_out = ModelStats(pruned)
|
|
17
|
+
assert stats_out.residues < stats_in.residues
|
|
@@ -1,9 +1,118 @@
|
|
|
1
1
|
from typing import List
|
|
2
|
+
|
|
2
3
|
import gemmi
|
|
3
|
-
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from modelcraft.reflections import (
|
|
7
|
+
DataItem,
|
|
8
|
+
column_refs,
|
|
9
|
+
contract_label,
|
|
10
|
+
convert_to_fsigf_and_phifom,
|
|
11
|
+
expand_label,
|
|
12
|
+
)
|
|
13
|
+
|
|
4
14
|
from . import ccp4_path
|
|
5
15
|
|
|
6
16
|
|
|
17
|
+
@pytest.mark.parametrize(
|
|
18
|
+
"label,expanded",
|
|
19
|
+
[
|
|
20
|
+
("HL", "HLA,HLB,HLC,HLD"),
|
|
21
|
+
("HLanom", "HLanomA,HLanomB,HLanomC,HLanomD"),
|
|
22
|
+
("HLABCD.F_sigF", "HLABCD.F_sigF.F,HLABCD.F_sigF.sigF"),
|
|
23
|
+
("parrot.ABCD", "parrot.ABCD.A,parrot.ABCD.B,parrot.ABCD.C,parrot.ABCD.D"),
|
|
24
|
+
("parrot.F_phi", "parrot.F_phi.F,parrot.F_phi.phi"),
|
|
25
|
+
("FreeR_flag", "FreeR_flag"),
|
|
26
|
+
("prefix.HL", "prefix.HLA,prefix.HLB,prefix.HLC,prefix.HLD"),
|
|
27
|
+
("prefix.label", "prefix.label"),
|
|
28
|
+
("prefix_ABCD", "prefix_ABCD.A,prefix_ABCD.B,prefix_ABCD.C,prefix_ABCD.D"),
|
|
29
|
+
("prefix_HL", "prefix_HLA,prefix_HLB,prefix_HLC,prefix_HLD"),
|
|
30
|
+
("x.y.HL", "x.y.HLA,x.y.HLB,x.y.HLC,x.y.HLD"),
|
|
31
|
+
("prefix.FreeR_flag", "prefix.FreeR_flag"),
|
|
32
|
+
("prefix.I_sigI", "prefix.I_sigI.I,prefix.I_sigI.sigI"),
|
|
33
|
+
("prefix.phi_fom", "prefix.phi_fom.phi,prefix.phi_fom.fom"),
|
|
34
|
+
],
|
|
35
|
+
)
|
|
36
|
+
def test_expand_label(label: str, expanded: str):
|
|
37
|
+
assert expand_label(label) == expanded
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@pytest.mark.parametrize(
|
|
41
|
+
"label,contracted",
|
|
42
|
+
[
|
|
43
|
+
("FreeR_flag", "FreeR_flag"),
|
|
44
|
+
("prefix.FreeR_flag", "prefix.FreeR_flag"),
|
|
45
|
+
("prefix.F_phi.F,prefix.F_phi.phi", "prefix.F_phi"),
|
|
46
|
+
("prefix.F_sigF.F,prefix.F_sigF.sigF", "prefix.F_sigF"),
|
|
47
|
+
("prefix.I_sigI.I,prefix.I_sigI.sigI", "prefix.I_sigI"),
|
|
48
|
+
("prefix.phi_fom.phi,prefix.phi_fom.fom", "prefix.phi_fom"),
|
|
49
|
+
("prefix.ABCD.A,prefix.ABCD.B,prefix.ABCD.C,prefix.ABCD.D", "prefix.ABCD"),
|
|
50
|
+
],
|
|
51
|
+
)
|
|
52
|
+
def test_contract_label(label: str, contracted: str):
|
|
53
|
+
assert contract_label(label) == contracted
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@pytest.mark.parametrize(
|
|
57
|
+
"columns,project,crystal,dataset,label",
|
|
58
|
+
[
|
|
59
|
+
("label", "", "", "", "label"),
|
|
60
|
+
("/label", "", "", "", "label"),
|
|
61
|
+
("/label/", "", "", "", "label"),
|
|
62
|
+
("[label]", "", "", "", "label"),
|
|
63
|
+
("[[label]]", "", "", "", "label"),
|
|
64
|
+
("/*/*/*/*/*/*/*/*/*/[[label]]//", "", "", "", "label"),
|
|
65
|
+
("dataset/label", "", "", "dataset", "label"),
|
|
66
|
+
("crystal/dataset/label", "", "crystal", "dataset", "label"),
|
|
67
|
+
("project/crystal/dataset/label", "project", "crystal", "dataset", "label"),
|
|
68
|
+
],
|
|
69
|
+
)
|
|
70
|
+
def test_single_column_ref(
|
|
71
|
+
columns: str, project: str, crystal: str, dataset: str, label: str
|
|
72
|
+
):
|
|
73
|
+
refs = column_refs(columns)
|
|
74
|
+
assert refs[0].project == project
|
|
75
|
+
assert refs[0].crystal == crystal
|
|
76
|
+
assert refs[0].dataset == dataset
|
|
77
|
+
assert refs[0].label == label
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@pytest.mark.parametrize(
|
|
81
|
+
"columns",
|
|
82
|
+
[
|
|
83
|
+
("label1,label2"),
|
|
84
|
+
("[label1,label2]"),
|
|
85
|
+
("/*/*/*/label1,label2"),
|
|
86
|
+
("/*/*/*/[label1,label2]"),
|
|
87
|
+
],
|
|
88
|
+
)
|
|
89
|
+
def test_multiple_column_refs(columns: str):
|
|
90
|
+
refs = column_refs(columns)
|
|
91
|
+
for ref in refs:
|
|
92
|
+
assert ref.project == ""
|
|
93
|
+
assert ref.crystal == ""
|
|
94
|
+
assert ref.dataset == ""
|
|
95
|
+
assert refs[0].label == "label1"
|
|
96
|
+
assert refs[1].label == "label2"
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def test_column_refs_with_duplicate_labels():
|
|
100
|
+
refs1 = column_refs("/xtal/peak/[F(+),SIGF(+),F(-),SIGF(-)]")
|
|
101
|
+
refs2 = column_refs("/xtal/infl/[F(+),SIGF(+),F(-),SIGF(-)]")
|
|
102
|
+
labels = ["F(+)", "SIGF(+)", "F(-)", "SIGF(-)"]
|
|
103
|
+
assert len(refs1) == len(labels)
|
|
104
|
+
assert len(refs2) == len(labels)
|
|
105
|
+
for i, label in enumerate(labels):
|
|
106
|
+
assert refs1[i].project == ""
|
|
107
|
+
assert refs2[i].project == ""
|
|
108
|
+
assert refs1[i].crystal == "xtal"
|
|
109
|
+
assert refs2[i].crystal == "xtal"
|
|
110
|
+
assert refs1[i].dataset == "peak"
|
|
111
|
+
assert refs2[i].dataset == "infl"
|
|
112
|
+
assert refs1[i].label == label
|
|
113
|
+
assert refs2[i].label == label
|
|
114
|
+
|
|
115
|
+
|
|
7
116
|
def search_test(
|
|
8
117
|
mtz: gemmi.Mtz, types: str, expected: List[str], sequential: bool = True
|
|
9
118
|
) -> None:
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
guess_sequence_type,
|
|
5
|
-
PolymerType,
|
|
6
|
-
sequences_in_file,
|
|
7
|
-
)
|
|
2
|
+
|
|
3
|
+
from modelcraft.sequence import PolymerType, sequences_in_file
|
|
8
4
|
|
|
9
5
|
|
|
10
6
|
@pytest.mark.parametrize(
|
|
@@ -18,8 +14,8 @@ from modelcraft.contents import (
|
|
|
18
14
|
("GGGG", PolymerType.PROTEIN),
|
|
19
15
|
],
|
|
20
16
|
)
|
|
21
|
-
def
|
|
22
|
-
assert
|
|
17
|
+
def test_polymer_type(sequence: str, expected: PolymerType):
|
|
18
|
+
assert PolymerType.guess(sequence) == expected
|
|
23
19
|
|
|
24
20
|
|
|
25
21
|
@pytest.mark.parametrize(
|
|
@@ -27,19 +23,16 @@ def test_guess_sequence_type(sequence: str, expected: PolymerType):
|
|
|
27
23
|
[
|
|
28
24
|
("A", PolymerType.PROTEIN, "ALA"),
|
|
29
25
|
("B", PolymerType.PROTEIN, "ASX"),
|
|
30
|
-
("J", PolymerType.PROTEIN, "UNK"),
|
|
31
26
|
("X", PolymerType.PROTEIN, "UNK"),
|
|
32
27
|
("Z", PolymerType.PROTEIN, "GLX"),
|
|
33
28
|
("A", PolymerType.RNA, "A"),
|
|
34
|
-
("J", PolymerType.RNA, "N"),
|
|
35
29
|
("X", PolymerType.RNA, "N"),
|
|
36
30
|
("A", PolymerType.DNA, "DA"),
|
|
37
|
-
("J", PolymerType.DNA, "DN"),
|
|
38
31
|
("X", PolymerType.DNA, "DN"),
|
|
39
32
|
],
|
|
40
33
|
)
|
|
41
34
|
def test_code1_to_code3(code1: str, polymer_type: PolymerType, expected: str):
|
|
42
|
-
assert
|
|
35
|
+
assert polymer_type.codes[code1] == expected
|
|
43
36
|
|
|
44
37
|
|
|
45
38
|
@pytest.mark.parametrize(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import gemmi
|
|
2
|
+
|
|
3
|
+
from modelcraft.jobs.servalcat import ServalcatFw
|
|
4
|
+
from modelcraft.reflections import DataItem
|
|
5
|
+
|
|
6
|
+
from . import ccp4_path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def ianom_test(path: str, label: str) -> None:
|
|
10
|
+
mtz = gemmi.read_mtz_file(path)
|
|
11
|
+
observations = DataItem(mtz, label)
|
|
12
|
+
servalcat = ServalcatFw(observations=observations).run()
|
|
13
|
+
assert servalcat.fmean.nreflections == observations.nreflections
|
|
14
|
+
assert servalcat.fanom.nreflections == observations.nreflections
|
|
15
|
+
assert servalcat.imean.nreflections == observations.nreflections
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def imean_test(path: str, label: str) -> None:
|
|
19
|
+
mtz = gemmi.read_mtz_file(path)
|
|
20
|
+
observations = DataItem(mtz, label)
|
|
21
|
+
servalcat = ServalcatFw(observations=observations).run()
|
|
22
|
+
assert servalcat.fmean.nreflections == observations.nreflections
|
|
23
|
+
assert servalcat.fanom is None
|
|
24
|
+
assert servalcat.imean is None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_1rxf():
|
|
28
|
+
path = ccp4_path("examples", "data", "1rxf.mtz")
|
|
29
|
+
imean_test(path, "I,SIGI")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_ianom():
|
|
33
|
+
path = ccp4_path("examples", "data", "1vr7_lr_i.mtz")
|
|
34
|
+
imean_test(path, "IMEAN,SIGIMEAN")
|
|
35
|
+
ianom_test(path, "I(+),SIGI(+),I(-),SIGI(-)")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_deuterolysin():
|
|
39
|
+
path = ccp4_path("examples", "data", "deuterolysin.mtz")
|
|
40
|
+
imean_test(path, "IMEAN,SIGIMEAN")
|
|
41
|
+
ianom_test(path, "I(+),SIGI(+),I(-),SIGI(-)")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_gere():
|
|
45
|
+
path = ccp4_path("examples", "data", "gere.mtz")
|
|
46
|
+
imean_test(path, "IMEAN,SIGIMEAN")
|
|
47
|
+
ianom_test(path, "I(+),SIGI(+),I(-),SIGI(-)")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def test_insulin():
|
|
51
|
+
path = ccp4_path("examples", "data", "insulin.mtz")
|
|
52
|
+
imean_test(path, "IMEAN,SIGIMEAN")
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import gemmi
|
|
2
|
+
|
|
2
3
|
from modelcraft.jobs.sheetbend import Sheetbend
|
|
3
4
|
from modelcraft.reflections import DataItem
|
|
4
|
-
from modelcraft.structure import
|
|
5
|
+
from modelcraft.structure import read_structure
|
|
6
|
+
|
|
5
7
|
from . import ccp4_path
|
|
6
8
|
|
|
7
9
|
|
|
@@ -12,5 +14,4 @@ def test_1rxf():
|
|
|
12
14
|
freer = DataItem(mtz, "FreeR_flag")
|
|
13
15
|
pdb_path = ccp4_path("examples", "data", "1rxf_randomise.pdb")
|
|
14
16
|
structure = read_structure(pdb_path)
|
|
15
|
-
|
|
16
|
-
assert ModelStats(structure) == ModelStats(sheetbend.structure)
|
|
17
|
+
Sheetbend(structure=structure, fsigf=fsigf, freer=freer).run()
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from tempfile import TemporaryDirectory
|
|
3
|
+
|
|
4
|
+
import gemmi
|
|
5
|
+
|
|
6
|
+
from modelcraft.reflections import write_mtz
|
|
7
|
+
from modelcraft.scripts.sidechains import any_missing_side_chains
|
|
8
|
+
from modelcraft.scripts.sidechains import main as fix_side_chains
|
|
9
|
+
from modelcraft.structure import write_mmcif
|
|
10
|
+
|
|
11
|
+
from . import insulin_refmac
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_insulin():
|
|
15
|
+
refmac = insulin_refmac()
|
|
16
|
+
assert any_missing_side_chains(refmac.structure)
|
|
17
|
+
with TemporaryDirectory() as tempdir:
|
|
18
|
+
xyzin = str(Path(tempdir, "input.cif"))
|
|
19
|
+
hklin = str(Path(tempdir, "input.mtz"))
|
|
20
|
+
xyzout = str(Path(tempdir, "output.cif"))
|
|
21
|
+
write_mmcif(xyzin, refmac.structure)
|
|
22
|
+
write_mtz(hklin, [refmac.fphi_best], ["FWT,PHWT"])
|
|
23
|
+
fix_side_chains([xyzin, hklin, xyzout])
|
|
24
|
+
structure = gemmi.read_structure(xyzout)
|
|
25
|
+
assert not any_missing_side_chains(structure)
|
|
@@ -1,30 +1,16 @@
|
|
|
1
|
-
import
|
|
1
|
+
import gemmi
|
|
2
2
|
import pytest
|
|
3
|
-
from modelcraft.contents import Polymer, PolymerType
|
|
4
|
-
from modelcraft.solvent import _library_volume, _library_weight, _polymer_weight
|
|
5
3
|
|
|
4
|
+
from modelcraft.contents import AsuContents
|
|
5
|
+
from modelcraft.solvent import solvent_fraction
|
|
6
6
|
|
|
7
|
-
@pytest.mark.parametrize(
|
|
8
|
-
"code,expected",
|
|
9
|
-
[
|
|
10
|
-
("ALA", 89.09),
|
|
11
|
-
("ASP", 132.09),
|
|
12
|
-
("ASN", 132.12),
|
|
13
|
-
("UNK", 103.12),
|
|
14
|
-
],
|
|
15
|
-
)
|
|
16
|
-
def test_library_weight(code: str, expected: float):
|
|
17
|
-
weight = _library_weight(code)
|
|
18
|
-
assert math.isclose(weight, expected, abs_tol=0.01)
|
|
19
7
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
weight = _polymer_weight(polymer)
|
|
30
|
-
assert math.isclose(weight, 132.12, abs_tol=0.01)
|
|
8
|
+
def test_1o6a():
|
|
9
|
+
contents = AsuContents.from_pdbe("1o6a")
|
|
10
|
+
cell = gemmi.UnitCell(61.481, 61.481, 113.148, 90, 90, 90)
|
|
11
|
+
spacegroup = gemmi.SpaceGroup("P 41 21 2")
|
|
12
|
+
fraction = solvent_fraction(contents, cell, spacegroup, resolution=1.85)
|
|
13
|
+
assert fraction == pytest.approx(0.5, abs=0.1)
|
|
14
|
+
contents.copies = None
|
|
15
|
+
guessed = solvent_fraction(contents, cell, spacegroup, resolution=1.85)
|
|
16
|
+
assert guessed == fraction
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import math
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from ...monlib import MonLib
|
|
6
|
+
from ...validation import validate_refmac
|
|
7
|
+
from . import insulin_refmac
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def test_insulin():
|
|
11
|
+
refmac = insulin_refmac()
|
|
12
|
+
monlib = MonLib(refmac.structure[0].get_all_residue_names())
|
|
13
|
+
metrics = validate_refmac(refmac, monlib)
|
|
14
|
+
assert len(metrics) > 0
|
|
15
|
+
assert math.isclose(np.median(metrics["BFac"]), 0)
|
|
16
|
+
assert math.isclose(np.median(metrics["RSCC"]), 0)
|
|
17
|
+
assert math.isclose(np.median(metrics["Diff"]), 0)
|
|
18
|
+
assert math.isclose(np.median(metrics["Geom"]), 0)
|
|
19
|
+
assert math.isclose(np.median(metrics["Score"]), 0)
|