Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integration tests #1014

Merged
merged 14 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion integration_tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
)

tests_path = Path(__file__).resolve().parents[0]
golden_data = Path(tests_path, 'golden_data')
GOLDEN_DATA = Path(tests_path, "golden_data")
25 changes: 25 additions & 0 deletions integration_tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pathlib import Path

import pytest

from haddock.modules.analysis.caprieval.capri import load_contacts
from haddock.libs.libontology import PDBFile


def calc_fnat_with_caprieval(model: Path, native: Path) -> float:
model_pdb = PDBFile(model)
native_pdb = PDBFile(native)

model_contacts = load_contacts(model_pdb)
native_contacts = load_contacts(native_pdb)

intersection = native_contacts & model_contacts

fnat = len(intersection) / float(len(model_contacts))

return fnat


@pytest.fixture
def calc_fnat():
return calc_fnat_with_caprieval
1,139 changes: 1,139 additions & 0 deletions integration_tests/golden_data/2oob.pdb

Large diffs are not rendered by default.

352 changes: 352 additions & 0 deletions integration_tests/golden_data/2oob_A.pdb

Large diffs are not rendered by default.

3,326 changes: 3,326 additions & 0 deletions integration_tests/golden_data/2oob_A.psf

Large diffs are not rendered by default.

576 changes: 576 additions & 0 deletions integration_tests/golden_data/2oob_B.pdb

Large diffs are not rendered by default.

5,362 changes: 5,362 additions & 0 deletions integration_tests/golden_data/2oob_B.psf

Large diffs are not rendered by default.

2,322 changes: 2,322 additions & 0 deletions integration_tests/golden_data/e2aP_1F3G.pdb

Large diffs are not rendered by default.

12,971 changes: 12,971 additions & 0 deletions integration_tests/golden_data/hpr_ensemble.pdb

Large diffs are not rendered by default.

38 changes: 23 additions & 15 deletions integration_tests/test_alascan.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,48 @@
import pytest
import shutil
import pandas as pd
import numpy as np

from haddock.modules.analysis.alascan import DEFAULT_CONFIG as DEFAULT_ALASCAN_CONFIG
from haddock.modules.analysis.alascan import HaddockModule as AlascanModule
from haddock.libs.libontology import PDBFile
from . import CNS_EXEC, DATA_DIR, has_cns
from tests import golden_data


@pytest.fixture
def alascan_module():
"""Return a default alascan module."""
with tempfile.TemporaryDirectory(dir=".") as tmpdir:
with tempfile.TemporaryDirectory() as tmpdir:
alascan = AlascanModule(
order=0, path=".", initial_params=DEFAULT_ALASCAN_CONFIG
order=0, path=Path(tmpdir), initial_params=DEFAULT_ALASCAN_CONFIG
)
alascan.params["int_cutoff"] = 3.5
yield alascan

class MockPreviousIO():


class MockPreviousIO:
def __init__(self, path):
self.path = path

def retrieve_models(self, individualize: bool = False):
shutil.copy(Path(golden_data, "protprot_complex_1.pdb"), Path(".", "protprot_complex_1.pdb"))
shutil.copy(Path(golden_data, "protprot_complex_2.pdb"), Path(".", "protprot_complex_2.pdb"))
shutil.copy(
Path(golden_data, "protprot_complex_1.pdb"),
Path(self.path, "protprot_complex_1.pdb"),
)
shutil.copy(
Path(golden_data, "protprot_complex_2.pdb"),
Path(self.path, "protprot_complex_2.pdb"),
)
model_list = [
PDBFile(file_name="protprot_complex_1.pdb", path="."),
PDBFile(file_name="protprot_complex_2.pdb", path="."),
PDBFile(file_name="protprot_complex_1.pdb", path=self.path),
PDBFile(file_name="protprot_complex_2.pdb", path=self.path),
]

return model_list

def output(self):
return None

@has_cns

def test_alascan_default(alascan_module, mocker):
"""Test the alascan module."""
alascan_module.previous_io = MockPreviousIO(path=alascan_module.path)
Expand All @@ -52,15 +58,17 @@ def test_alascan_default(alascan_module, mocker):
assert expected_csv1.exists(), f"{expected_csv1} does not exist"
assert expected_csv2.exists(), f"{expected_csv2} does not exist"
assert expected_clt_csv.exists(), f"{expected_clt_csv} does not exist"

# check single complex csv
df = pd.read_csv(expected_csv1, sep="\t", comment="#")
assert df.shape == (10, 15), f"{expected_csv1} has wrong shape"
# ARG 17 B should have a negative delta_score
assert df.loc[df["ori_resname"] == "ARG"].iloc[0,:]["delta_score"] < 0.0
assert df.loc[df["ori_resname"] == "ARG"].iloc[0, :]["delta_score"] < 0.0

# check clt csv
df_clt = pd.read_csv(expected_clt_csv, sep="\t", comment="#")
assert df_clt.shape == (18, 11), f"{expected_clt_csv} has wrong shape"
# average delta score of A-38-ASP should be negative
assert df_clt.loc[df_clt["full_resname"] == "A-38-ASP"].iloc[0,:]["delta_score"] < 0.0
# average delta score of A-38-ASP should be negative
rvhonorato marked this conversation as resolved.
Show resolved Hide resolved
assert (
df_clt.loc[df_clt["full_resname"] == "A-38-ASP"].iloc[0, :]["delta_score"] < 0.0
)
30 changes: 17 additions & 13 deletions integration_tests/test_cli_score.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,12 @@
import io
from contextlib import redirect_stdout
import os
from . import has_cns

@has_cns

def test_cli_score():
"""Test the haddock3-score CLI."""
pdb_f = Path(golden_data, "protprot_complex_1.pdb")
# tempdir
# tempdir
with tempfile.TemporaryDirectory(dir=".") as tmpdir:
# parsing
f = io.StringIO()
Expand All @@ -32,21 +31,26 @@ def test_cli_score():

# now putting some non-standard emscoring parameters
kwargs_dict = {
"elecflag": "False", # this is a boolean
"epsilon": "2.0", # this is a float
"nemsteps": "100", # this is an int
}
"elecflag": "False", # this is a boolean
"epsilon": "2.0", # this is a float
"nemsteps": "100", # this is an int
}
f = io.StringIO()
with redirect_stdout(f):
cli_score.main(pdb_f, tmpdir, full=True, keep_all=False, **kwargs_dict)
out = f.getvalue().split(os.linesep)

assert out[0].startswith("* ATTENTION * Value (False) of parameter elecflag different from default")
assert out[1].startswith("* ATTENTION * Value (2.0) of parameter epsilon different from default")
assert out[2].startswith("* ATTENTION * Value (100) of parameter nemsteps different from default")

assert out[0].startswith(
"* ATTENTION * Value (False) of parameter elecflag different from default"
)
assert out[1].startswith(
"* ATTENTION * Value (2.0) of parameter epsilon different from default"
)
assert out[2].startswith(
"* ATTENTION * Value (100) of parameter nemsteps different from default"
)
# check the used parameters
assert out[4].startswith("used emscoring parameters: ")
assert out[4].split("elecflag':")[1].split(",")[0].strip() == "False"

assert out[-3].startswith("> HADDOCK-score (emscoring) = ")

assert out[-3].startswith("> HADDOCK-score (emscoring) = ")
6 changes: 3 additions & 3 deletions integration_tests/test_clustfcc.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from haddock.modules.analysis.clustfcc import DEFAULT_CONFIG as clustfcc_pars
from haddock.modules.analysis.clustfcc import HaddockModule as ClustFCCModule

from . import golden_data
from integration_tests import GOLDEN_DATA


class MockPreviousIO:
Expand All @@ -20,12 +20,12 @@ def __init__(self, path):

def retrieve_models(self, individualize: bool = False):
shutil.copy(
Path(golden_data, "protprot_complex_1.pdb"),
Path(GOLDEN_DATA, "protprot_complex_1.pdb"),
Path(self.path, "protprot_complex_1.pdb"),
)

shutil.copy(
Path(golden_data, "protprot_complex_2.pdb"),
Path(GOLDEN_DATA, "protprot_complex_2.pdb"),
Path(self.path, "protprot_complex_2.pdb"),
)

Expand Down
11 changes: 7 additions & 4 deletions integration_tests/test_cnsjob.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
from pathlib import Path
from typing import Generator

from . import golden_data, CNS_EXEC, has_cns
from integration_tests import GOLDEN_DATA, CNS_EXEC


@pytest.fixture
Expand Down Expand Up @@ -39,16 +39,18 @@ def cnsjob_no_files(cns_inp_str):

@pytest.fixture
def cns_seed_filename(cns_output_filename) -> Generator[str, None, None]:
yield str(Path(Path(cns_output_filename).stem).with_suffix(".seed"))
seed_filename = Path(Path(cns_output_filename).stem).with_suffix(".seed")
yield str(seed_filename)
seed_filename.unlink(missing_ok=True)


@pytest.fixture
def cns_inp_str(cns_seed_filename, cns_output_pdb_filename):
yield f"""
structure
@@{golden_data}/prot.psf
@@{GOLDEN_DATA}/prot.psf
end
coor @@{golden_data}/prot.pdb
coor @@{GOLDEN_DATA}/prot.pdb

write coordinates format=pdbo output={cns_output_pdb_filename} end

Expand Down Expand Up @@ -117,6 +119,7 @@ def test_cnsjob_compress_seed(cnsjob, cns_output_pdb_filename, cns_seed_filename

assert Path(f"{cns_seed_filename}.gz").exists()
assert Path(f"{cns_seed_filename}.gz").stat().st_size > 0
Path(f"{cns_seed_filename}.gz").unlink()

assert Path(cns_output_pdb_filename).exists()
assert Path(cns_output_pdb_filename).stat().st_size > 0
Expand Down
3 changes: 1 addition & 2 deletions integration_tests/test_contactmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
from haddock.modules.analysis.contactmap import HaddockModule as CMapModule
from haddock.modules.analysis.contactmap import DEFAULT_CONFIG as CONTMAP_CONF

tests_path = Path(__file__).resolve().parents[0]
GOLDEN_DATA = Path(tests_path, 'golden_data')
from integration_tests import GOLDEN_DATA


@pytest.fixture
Expand Down
131 changes: 131 additions & 0 deletions integration_tests/test_emref.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import shutil
import tempfile
from pathlib import Path

import pytest

from haddock.libs.libontology import Format, PDBFile, Persistent
from haddock.modules.refinement.emref import DEFAULT_CONFIG as DEFAULT_EMREF_CONFIG
from haddock.modules.refinement.emref import HaddockModule as FlexrefModule

from integration_tests import GOLDEN_DATA


@pytest.fixture
def emref_module():
with tempfile.TemporaryDirectory() as tmpdir:
emref = FlexrefModule(
order=0, path=Path(tmpdir), initial_params=DEFAULT_EMREF_CONFIG
)
yield emref


class MockPreviousIO:
def __init__(self, path):
self.path = path

def retrieve_models(self, crossdock: bool = False):
shutil.copy(
Path(GOLDEN_DATA, "2oob.pdb"),
Path(self.path, "2oob.pdb"),
)
shutil.copy(
Path(GOLDEN_DATA, "2oob_A.psf"),
Path(self.path, "2oob_A.psf"),
)

shutil.copy(
Path(GOLDEN_DATA, "2oob_B.psf"),
Path(self.path, "2oob_B.psf"),
)

model = PDBFile(
file_name="2oob.pdb",
path=self.path,
topology=(
Persistent(
file_name="2oob_A.psf",
path=self.path,
file_type=Format.TOPOLOGY,
),
Persistent(
file_name="2oob_B.psf",
path=self.path,
file_type=Format.TOPOLOGY,
),
),
)

model.seed = 42 # type: ignore

return [model]

def output(self):
return None


def test_emref_defaults(emref_module, calc_fnat):

emref_module.previous_io = MockPreviousIO(path=emref_module.path)

emref_module.run()

assert Path(emref_module.path, "emref_1.pdb").exists()
assert Path(emref_module.path, "emref_1.out.gz").exists()

fnat = calc_fnat(
model=Path(emref_module.path, "emref_1.pdb"),
native=Path(GOLDEN_DATA, "2oob.pdb"),
)

assert fnat == pytest.approx(0.95, abs=0.05)


def test_emref_fle(emref_module, calc_fnat):

emref_module.previous_io = MockPreviousIO(path=emref_module.path)

emref_module.params["nfle "] = 1

emref_module.params["fle_sta_1 "] = 66
emref_module.params["fle_end_1 "] = 77
emref_module.params["fle_seg_1 "] = "B"

emref_module.run()

assert Path(emref_module.path, "emref_1.pdb").exists()
assert Path(emref_module.path, "emref_1.out.gz").exists()

fnat = calc_fnat(
model=Path(emref_module.path, "emref_1.pdb"),
native=Path(GOLDEN_DATA, "2oob.pdb"),
)

assert fnat == pytest.approx(0.95, abs=0.05)


def test_emref_mutliple_fle(emref_module, calc_fnat):

emref_module.previous_io = MockPreviousIO(path=emref_module.path)

emref_module.params["nfle "] = 2

emref_module.params["fle_sta_1 "] = 66
emref_module.params["fle_end_1 "] = 77
emref_module.params["fle_seg_1 "] = "B"

emref_module.params["fle_sta_2 "] = 41
emref_module.params["fle_end_2 "] = 47
emref_module.params["fle_seg_2 "] = "B"

emref_module.run()

assert Path(emref_module.path, "emref_1.pdb").exists()
assert Path(emref_module.path, "emref_1.out.gz").exists()

fnat = calc_fnat(
model=Path(emref_module.path, "emref_1.pdb"),
native=Path(GOLDEN_DATA, "2oob.pdb"),
)

assert fnat == pytest.approx(0.95, abs=0.05)
Loading
Loading