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

Add SAXS scoring module #551

Draft
wants to merge 34 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
38d23ae
Add SAXS scoring module
cvnoort Jun 21, 2022
18f10c4
Merge branch 'haddocking:main' into saxs_score
cvnoort Jul 7, 2022
813c067
Add default w_saxs
cvnoort Jul 7, 2022
437083c
Write HADDOCKsaxs scores
cvnoort Jul 14, 2022
de0e360
Assign HADDOCKsaxs scores
cvnoort Jul 14, 2022
2181136
Update SAXS scoring module
cvnoort Jul 15, 2022
59f9eb4
Merge branch 'haddocking:main' into saxs_score
cvnoort Sep 5, 2022
9ac19fd
Update SAXS scoring module
cvnoort Sep 9, 2022
e75faa2
Add SAXS scoring example
cvnoort Sep 16, 2022
de7c759
Merge branch 'haddocking:main' into saxs_score
cvnoort Sep 30, 2022
4d27c29
Change HADDOCKsaxs calculation
cvnoort Sep 30, 2022
5432c2d
Update SAXS scoring module
cvnoort Sep 30, 2022
7775ac9
Update SAXS scoring module
cvnoort Sep 30, 2022
c5549e0
Update SAXS scoring module
cvnoort Sep 30, 2022
11d002d
Update SAXS scoring module
cvnoort Sep 30, 2022
4e891c8
Merge branch 'haddocking:main' into saxs_score
cvnoort Oct 19, 2022
962aca3
Move SAXS scoring to analysis
cvnoort Oct 19, 2022
d347545
Correct SAXS score
cvnoort Oct 31, 2022
bb1302e
Add documentation to SAXS scoring module
cvnoort Oct 31, 2022
3f31873
Update SAXS scoring module
cvnoort Nov 1, 2022
8468bcb
Merge branch 'haddocking:main' into saxs_score
cvnoort Dec 12, 2022
efcaf1d
Manage CRYSOL output
cvnoort Dec 12, 2022
5ff4d8c
Fix lint SAXS scoring module
cvnoort Dec 12, 2022
2937ea6
Merge branch 'haddocking:main' into saxs_score
cvnoort Nov 12, 2023
7157df1
Merge branch 'haddocking:main' into saxs_score
cvnoort Jul 18, 2024
2bf7457
update `saxsscore` module
rvhonorato Jul 18, 2024
f38191c
add tests [wip]
rvhonorato Jul 18, 2024
1431d35
Merge branch 'haddocking:main' into saxs_score
cvnoort Jul 22, 2024
fd026c2
Merge branch 'haddocking:main' into saxs_score
cvnoort Jul 25, 2024
7c44de1
Update saxsscore module
cvnoort Jul 29, 2024
b360f7a
Merge branch 'haddocking:main' into saxs_score
cvnoort Aug 15, 2024
8459072
Update saxsscore module
cvnoort Aug 15, 2024
3943d99
Merge branch 'saxs_score' of https://github.com/cvnoort/haddock3 into…
cvnoort Aug 15, 2024
af8a52e
Fix atsas_path parameter default value
cvnoort Aug 15, 2024
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
52 changes: 52 additions & 0 deletions examples/scoring-saxs/data/protein-protein_saxs.dat
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Simulated scattering data for examples/docking-protein-protein/data/e2a-hpr_1GGR.pdb
0.000000E+00 0.110408E+08
0.100000E-01 0.109074E+08
0.200000E-01 0.105167E+08
0.300000E-01 0.989488E+07
0.400000E-01 0.908313E+07
0.500000E-01 0.813279E+07
0.600000E-01 0.710047E+07
0.700000E-01 0.604272E+07
0.800000E-01 0.501118E+07
0.900000E-01 0.404870E+07
0.100000E+00 0.318682E+07
0.110000E+00 0.244476E+07
0.120000E+00 0.182985E+07
0.130000E+00 0.133915E+07
0.140000E+00 0.961881E+06
0.150000E+00 0.682183E+06
0.160000E+00 0.481886E+06
0.170000E+00 0.342843E+06
0.180000E+00 0.248682E+06
0.190000E+00 0.185849E+06
0.200000E+00 0.144003E+06
0.210000E+00 0.115863E+06
0.220000E+00 0.967074E+05
0.230000E+00 0.836887E+05
0.240000E+00 0.751560E+05
0.250000E+00 0.700796E+05
0.260000E+00 0.676557E+05
0.270000E+00 0.670955E+05
0.280000E+00 0.675737E+05
0.290000E+00 0.682738E+05
0.300000E+00 0.684887E+05
0.310000E+00 0.677076E+05
0.320000E+00 0.656805E+05
0.330000E+00 0.624174E+05
0.340000E+00 0.581470E+05
0.350000E+00 0.532498E+05
0.360000E+00 0.481699E+05
0.370000E+00 0.433383E+05
0.380000E+00 0.391132E+05
0.390000E+00 0.357524E+05
0.400000E+00 0.334000E+05
0.410000E+00 0.320988E+05
0.420000E+00 0.318072E+05
0.430000E+00 0.324247E+05
0.440000E+00 0.338126E+05
0.450000E+00 0.358077E+05
0.460000E+00 0.382327E+05
0.470000E+00 0.409038E+05
0.480000E+00 0.436358E+05
0.490000E+00 0.462483E+05
0.500000E+00 0.485731E+05
27 changes: 27 additions & 0 deletions examples/scoring-saxs/saxsscore-test.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# ====================================================================
# Scoring example

# directory in which the scoring will be done
run_dir = "saxsscore-test"
ncores = 40
mode = "local"

# ensemble to be scored
molecules = ["../scoring/data/protein-protein_1w.pdb",
"../scoring/data/protein-protein_2w.pdb"
]


# ====================================================================
# Parameters for each stage are defined below

[topoaa]
autohis = true

[emscoring]

[saxsscore]
saxs_fname = "data/protein-protein_saxs.dat"
atsas_path = "/Applications/ATSAS" # CHANGE IF INSTALLED ELSEWHERE

# ====================================================================
76 changes: 76 additions & 0 deletions integration_tests/test_saxs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
from haddock.modules.analysis.saxsscore import HaddockModule as SaxsModule

import shutil
from pathlib import Path
import pytest
from haddock.libs.libontology import PDBFile
from tests import golden_data

from haddock.modules.analysis.saxsscore import (
DEFAULT_CONFIG as DEFAULT_SAXSSCORE_CONFIG,
)
from haddock.modules.analysis.saxsscore.saxs import run_crysol


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

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

return model_list

def output(self):
return None


@pytest.fixture
def saxsscore():
return SaxsModule(
order=0,
path=Path("."),
init_params=DEFAULT_SAXSSCORE_CONFIG,
)


@pytest.fixture
def saxs_data():
yield Path(golden_data, "saxs.dat")


ATSAS_PATH = "/home/rodrigo/software/ATSAS-3.2.1-1"


def test_saxsscore(saxsscore, saxs_data):

saxsscore.previous_io = MockPreviousIO(path=saxsscore.path)
saxsscore.params["saxs_fname"] = saxs_data
saxsscore.params["atsas_path"] = ATSAS_PATH

saxsscore.run()

assert Path("saxsscore.tsv").exists()


def test_crysol_is_executable(saxs_data):
pdb_f = Path(golden_data, "hpr_ensemble_1_haddock.pdb")
run_crysol(
atsas_path=ATSAS_PATH,
input_f=pdb_f,
saxs_data=saxs_data,
lm=20,
ns=20,
)

assert Path(f"{Path(pdb_f.stem)}_saxs.fit").exists()
110 changes: 110 additions & 0 deletions src/haddock/modules/analysis/saxsscore/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
"""
SAXS scoring module
===================

Requires ATSAS 2.6.0 or newer.

This module adds a SAXS term to the HADDOCK score.
The SAXS term is based on the fit (Chi^2) of a model to corresponding
scattering data, as calculated by the ATSAS program CRYSOL.

By default the weights of the HADDOCK score (calculated by the preceding module)
and the Chi value are 1 and 50, respectively.
If the preceding module did not provide HADDOCK scores,
the Chi^2 values are returned as is (not multiplied by 50).

The resulting scores are found in ``saxsscore.tsv``.
This module does not alter the models themselves
and passes them on unchanged to the subsequent module.

For more information on SAXS-based scoring in HADDOCK, see

Karaca E, Bonvin AMJJ. 2013. On the Usefulness of Ion-Mobility Mass Spectrometry
and SAXS Data in Scoring Docking Decoys. *Acta Crystallographica* D69:683-694.
"""

import math
from pathlib import Path

from haddock.libs.libutil import check_subprocess
from haddock.modules import BaseHaddockModule
from haddock.modules.analysis.saxsscore.saxs import (
run_crysol,
read_chi2,
calculate_haddocksaxs_score,
output_saxsscore,
)


RECIPE_PATH = Path(__file__).resolve().parent
DEFAULT_CONFIG = Path(RECIPE_PATH, "defaults.yaml")


class HaddockModule(BaseHaddockModule):
"""HADDOCK3 module to perform SAXS-based scoring."""

name = RECIPE_PATH.name

def __init__(self, order, path, *ignore, init_params=DEFAULT_CONFIG,
**everything):
super().__init__(order, path, init_params)

@classmethod
def confirm_installation(cls):
"""Confirm this module is installed."""
check_subprocess("crysol -h")

def _run(self):
"""Execute module."""
models_to_score = self.previous_io.retrieve_models(individualize=True)

# Get parameters from .yaml/.cfg
saxs_data = self.params["saxs_fname"]
lm = self.params["lm"]
ns = self.params["ns"]
cst = self.params["cst"]
w_haddock = self.params["w_haddock"]
w_saxs = self.params["w_saxs"]

for model in models_to_score:

# Run CRYSOL
run_crysol(
atsas_path=self.params["atsas_path"],
input_f=model.rel_path,
saxs_data=saxs_data,
lm=lm,
ns=ns,
cst=cst,
)

# Read Chi^2 value
fit_file = (Path(model.file_name).stem
+ "_" + Path(saxs_data).stem + ".fit")
model.chi2 = read_chi2(fit_file=fit_file)

# Calculate HADDOCKsaxs score
if math.isnan(model.score):
haddocksaxs_score = model.chi2
else:
haddocksaxs_score = calculate_haddocksaxs_score(
score=model.score,
chi2=model.chi2,
w_haddock=w_haddock,
w_saxs=w_saxs,
)

model.score = haddocksaxs_score

# Write output
self.output_models = models_to_score
output_fname="saxsscore.tsv"
self.log(f"Saving output to {output_fname}")

output_saxsscore(
output_models=self.output_models,
output_fname=output_fname,
)

# Send models (unchanged) to the next step
self.export_io_models()
80 changes: 80 additions & 0 deletions src/haddock/modules/analysis/saxsscore/defaults.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#
# Group scoring
#
w_haddock:
default: 1.0
type: float
min: 0
max: 9999
precision: 3
title: Weight of the HADDOCK score
short: Weight of the HADDOCK score in HADDOCKsaxs.
long: Weight of the HADDOCK score in the HADDOCKsaxs score.
The HADDOCK score from the previous module is multiplied by this weight
and added to the chi term to get the HADDOCKsaxs score.
group: "scoring"
explevel: expert
w_saxs:
default: 50.0
type: float
min: 0
max: 9999
precision: 3
title: Weight of the SAXS term
short: Weight of the SAXS term in the scoring function.
long: Weight of the SAXS term in the scoring function.
The chi value is multiplied by this weight
and added to the HADDOCK score to get the HADDOCKsaxs score.
group: "scoring"
explevel: expert
#
# Group CRYSOL
#
saxs_fname:
default: ""
type: file
title: Path to SAXS data
short: Path to SAXS data.
long: Path to the .dat file containing SAXS data for CRYSOL.
Two or three columns separated by whitespace, containing (in this order)
momentum transfer, scattering intensity, and (optional) standard deviation.
group: "scoring"
explevel: easy
lm:
default: 18
type: integer
min: 1
max: 100
title: Maximum order of harmonics
short: Maximum order of harmonics.
long: Maximum order of harmonics for CRYSOL.
group: "scoring"
explevel: expert
ns:
default: 256
type: integer
min: 1
max: 10001
title: Number of calculated data points in computed curve
short: Number of calculated data points in computed curve.
long: Number of calculated data points in computed curve from CRYSOL.
group: "scoring"
explevel: expert
cst:
default: true
type: boolean
title: Subtract constant
short: Subtract constant.
long: Subtract constant in CRYSOL.
group: "scoring"
explevel: expert
atsas_path:
default: "~/software/ATSAS"
type: string
minchars: 5
maxchars: 4095
title: Path to ATSAS installation
short: Path to ATSAS installation.
long: Path to the installation of ATSAS.
group: "scoring"
explevel: easy
Loading
Loading