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

Drop class name analogies favoring technical names #21

Merged
merged 16 commits into from
Jul 13, 2021
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,8 @@ dmypy.json

.DS_Store

# Specific to this project
## Specific to this project
bin/cns
# ignore generated data of the examples
examples/recipes/scoring/step_1
examples/recipes/scoring/topology
13 changes: 8 additions & 5 deletions bin/haddock3.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
from haddock.version import CURRENT_VERSION
from haddock.cli import greeting, adieu
from haddock.cooking import Chef
from haddock.workflow import WorkflowManager
from haddock.error import HaddockError


Expand All @@ -30,7 +30,8 @@ def positive_int(n):
help="The input recipe file name")
# Version
parser.add_argument("-V", "-v", "--version", help="show version",
action="version", version="%s %s" % (parser.prog, CURRENT_VERSION))
action="version",
version="%s %s" % (parser.prog, CURRENT_VERSION))

# Special case only using print instead of logging
options = parser.parse_args()
Expand All @@ -39,15 +40,17 @@ def positive_int(n):

# Configuring logging
logging.basicConfig(level=options.log_level,
format="[%(asctime)s] %(levelname)s - %(name)s: %(message)s",
format=("[%(asctime)s] %(levelname)s - "
"%(name)s: %(message)s"),
datefmt="%d/%m/%Y %H:%M:%S")

try:
# Let the chef work
chef = Chef(recipe_path=options.recipe.name, start=options.restart)
workflow = WorkflowManager(recipe_path=options.recipe.name,
start=options.restart)

# Main loop of execution
chef.cook()
workflow.run()

except HaddockError as he:
logging.error(he)
Expand Down
4 changes: 2 additions & 2 deletions examples/recipes/scoring/scoring.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ order = ["topology", "scoring"]

#####################################################################-1
[stage.topology]
flavour = "default"
mode = "default"
autohis = true

# Definition of the input molecules:
Expand All @@ -18,5 +18,5 @@ file = "T161-rescoring-5.pdb"

#####################################################################-2
[stage.scoring]
flavour = ""
mode = ""

15 changes: 10 additions & 5 deletions haddock/cns/engine.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
"""Running CNS scripts"""
import subprocess
from haddock.error import CNSRunningError
from haddock.parallel import CaptainHaddock
from haddock.parallel import Scheduler
from haddock.defaults import CNS_EXE, NUM_CORES


class CNSJob:
"""A CNS job script"""
def __init__(self, input_file, output_file, cns_folder='.', cns_exec=CNS_EXE):
def __init__(self, input_file, output_file, cns_folder='.',
cns_exec=CNS_EXE):
"""
:param input_file: input CNS script
:param output_file: CNS output
Expand All @@ -24,7 +25,11 @@ def run(self):
with open(self.input_file) as inp:
with open(self.output_file, 'w+') as outf:
env = {'RUN': self.cns_folder}
p = subprocess.Popen(self.cns_exec, stdin=inp, stdout=outf, close_fds=True, env=env)
p = subprocess.Popen(self.cns_exec,
stdin=inp,
stdout=outf,
close_fds=True,
env=env)
out, error = p.communicate()
p.kill()
if error:
Expand All @@ -45,5 +50,5 @@ def __init__(self, jobs, num_cores=0):

def run(self):
"""Run all provided jobs"""
captain = CaptainHaddock(self.jobs, self.num_cores)
captain.drink()
scheduler = Scheduler(self.jobs, self.num_cores)
scheduler.execute()
33 changes: 22 additions & 11 deletions haddock/cns/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,31 @@ def get_topology_header(protonation=None):
axis = load_axis(Default.AXIS)
water_box = load_waterbox(Default.WATER_BOX['boxtyp20'])

return param, top, link, topology_protonation, trans_vec, tensor, scatter, axis, water_box
return (param, top, link, topology_protonation, trans_vec, tensor, scatter,
axis, water_box)


def generate_topology(input_pdb, course_path, recipe_str, defaults, protonation=None):
def generate_topology(input_pdb, course_path, recipe_str, defaults,
protonation=None):
"""Generate a HADDOCK topology file from input_pdb"""
general_param = load_recipe_params(defaults)

param, top, link, topology_protonation, trans_vec, tensor, scatter, axis, water_box = get_topology_header(protonation)
param, top, link, topology_protonation, \
trans_vec, tensor, scatter, \
axis, water_box = get_topology_header(protonation)

abs_path = input_pdb.resolve().parent.absolute()
output_pdb_filename = abs_path / f'{input_pdb.stem}_haddock{input_pdb.suffix}'
output_psf_filename = abs_path / f'{input_pdb.stem}_haddock.{Format.TOPOLOGY}'
output_pdb_filename = abs_path / (f'{input_pdb.stem}_'
f'haddock{input_pdb.suffix}')
output_psf_filename = abs_path / (f'{input_pdb.stem}_'
f'haddock.{Format.TOPOLOGY}')
output = prepare_output(output_psf_filename, output_pdb_filename)

input_str = prepare_input(str(input_pdb.resolve().absolute()), course_path)

inp = general_param + param + top + input_str + output + link + topology_protonation \
+ trans_vec + tensor + scatter + axis + water_box + recipe_str
inp = general_param + param + top + input_str + output + link \
+ topology_protonation + trans_vec + tensor + scatter + axis \
+ water_box + recipe_str

output_inp_filename = abs_path / f'{input_pdb.stem}.{Format.CNS_INPUT}'
with open(output_inp_filename, 'w') as output_handler:
Expand All @@ -45,8 +52,10 @@ def generate_topology(input_pdb, course_path, recipe_str, defaults, protonation=
def prepare_output(output_psf_filename, output_pdb_filename):
"""Output of the CNS file"""
output = f'{linesep}! Output structure{linesep}'
output += f"eval ($output_psf_filename= \"{output_psf_filename}\"){linesep}"
output += f"eval ($output_pdb_filename= \"{output_pdb_filename}\"){linesep}"
output += ("eval ($output_psf_filename="
f" \"{output_psf_filename}\"){linesep}")
output += ("eval ($output_pdb_filename="
f" \"{output_pdb_filename}\"){linesep}")
return output


Expand All @@ -72,10 +81,12 @@ def load_protonation_state(protononation):

hise_str = ''
for e in [(i + 1, c + 1, r) for c, r in enumerate(hise_l)]:
hise_str += f'eval ($toppar.hise_resid_{e[0]}_{e[1]} = {e[2]}){linesep}'
hise_str += (f'eval ($toppar.hise_resid_{e[0]}_{e[1]}'
f' = {e[2]}){linesep}')
hisd_str = ''
for e in [(i + 1, c + 1, r) for c, r in enumerate(hisd_l)]:
hisd_str += f'eval ($toppar.hisd_resid_{e[0]}_{e[1]} = {e[2]}){linesep}'
hisd_str += (f'eval ($toppar.hisd_resid_{e[0]}_{e[1]}'
f' = {e[2]}){linesep}')

protonation_header += hise_str
protonation_header += hisd_str
Expand Down
59 changes: 7 additions & 52 deletions haddock/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
# Number of cores to use
NUM_CORES = int(os.getenv("HADDOCK3_NUM_CORES", multiprocessing.cpu_count()))

# Module input and generated data will be stored in folder starting by this prefix
# Module input and generated data will be stored in folder starting by
# this prefix
MODULE_PATH_NAME = "step_"

# Default name for exchange module information file
Expand All @@ -37,57 +38,11 @@ class Default:
LINK_FILE = data_path / "toppar/protein-allhdg5-4-noter.link"

TRANSLATION_VECTORS = {
"trans_vector_0": data_path / "toppar/initial_positions/trans_vector_0",
"trans_vector_1": data_path / "toppar/initial_positions/trans_vector_1",
"trans_vector_2": data_path / "toppar/initial_positions/trans_vector_2",
"trans_vector_3": data_path / "toppar/initial_positions/trans_vector_3",
"trans_vector_4": data_path / "toppar/initial_positions/trans_vector_4",
"trans_vector_5": data_path / "toppar/initial_positions/trans_vector_5",
"trans_vector_6": data_path / "toppar/initial_positions/trans_vector_6",
"trans_vector_7": data_path / "toppar/initial_positions/trans_vector_7",
"trans_vector_8": data_path / "toppar/initial_positions/trans_vector_8",
"trans_vector_9": data_path / "toppar/initial_positions/trans_vector_9",
"trans_vector_10": data_path / "toppar/initial_positions/trans_vector_10",
"trans_vector_11": data_path / "toppar/initial_positions/trans_vector_11",
"trans_vector_12": data_path / "toppar/initial_positions/trans_vector_12",
"trans_vector_13": data_path / "toppar/initial_positions/trans_vector_13",
"trans_vector_14": data_path / "toppar/initial_positions/trans_vector_14",
"trans_vector_15": data_path / "toppar/initial_positions/trans_vector_15",
"trans_vector_16": data_path / "toppar/initial_positions/trans_vector_16",
"trans_vector_17": data_path / "toppar/initial_positions/trans_vector_17",
"trans_vector_18": data_path / "toppar/initial_positions/trans_vector_18",
"trans_vector_19": data_path / "toppar/initial_positions/trans_vector_19",
"trans_vector_20": data_path / "toppar/initial_positions/trans_vector_20",
"trans_vector_21": data_path / "toppar/initial_positions/trans_vector_21",
"trans_vector_22": data_path / "toppar/initial_positions/trans_vector_22",
"trans_vector_23": data_path / "toppar/initial_positions/trans_vector_23",
"trans_vector_24": data_path / "toppar/initial_positions/trans_vector_24",
"trans_vector_25": data_path / "toppar/initial_positions/trans_vector_25",
"trans_vector_26": data_path / "toppar/initial_positions/trans_vector_26",
"trans_vector_27": data_path / "toppar/initial_positions/trans_vector_27",
"trans_vector_28": data_path / "toppar/initial_positions/trans_vector_28",
"trans_vector_29": data_path / "toppar/initial_positions/trans_vector_29",
"trans_vector_30": data_path / "toppar/initial_positions/trans_vector_30",
"trans_vector_31": data_path / "toppar/initial_positions/trans_vector_31",
"trans_vector_32": data_path / "toppar/initial_positions/trans_vector_32",
"trans_vector_33": data_path / "toppar/initial_positions/trans_vector_33",
"trans_vector_34": data_path / "toppar/initial_positions/trans_vector_34",
"trans_vector_35": data_path / "toppar/initial_positions/trans_vector_35",
"trans_vector_36": data_path / "toppar/initial_positions/trans_vector_36",
"trans_vector_37": data_path / "toppar/initial_positions/trans_vector_37",
"trans_vector_38": data_path / "toppar/initial_positions/trans_vector_38",
"trans_vector_39": data_path / "toppar/initial_positions/trans_vector_39",
"trans_vector_40": data_path / "toppar/initial_positions/trans_vector_40",
"trans_vector_41": data_path / "toppar/initial_positions/trans_vector_41",
"trans_vector_42": data_path / "toppar/initial_positions/trans_vector_42",
"trans_vector_43": data_path / "toppar/initial_positions/trans_vector_43",
"trans_vector_44": data_path / "toppar/initial_positions/trans_vector_44",
"trans_vector_45": data_path / "toppar/initial_positions/trans_vector_45",
"trans_vector_46": data_path / "toppar/initial_positions/trans_vector_46",
"trans_vector_47": data_path / "toppar/initial_positions/trans_vector_47",
"trans_vector_48": data_path / "toppar/initial_positions/trans_vector_48",
"trans_vector_49": data_path / "toppar/initial_positions/trans_vector_49",
"trans_vector_50": data_path / "toppar/initial_positions/trans_vector_50"
f"trans_vector_{i}": Path(data_path,
'toppar',
'initial_positions',
f'trans_vector_{i}')
for i in range(51)
}

TENSORS = {
Expand Down
45 changes: 30 additions & 15 deletions haddock/modules/sampling/lightdock.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,36 @@ def run(self, module_information):

# Check if multiple models are provided
if len(models_to_score) > 1:
self.finish_with_error("Only one model allowed in LightDock sampling module")
_msg = "Only one model allowed in LightDock sampling module"
self.finish_with_error(_msg)

model = models_to_score[0]
# Check if chain IDs are present
segids, chains = PDBFactory.identify_chainseg(Path(model.path) / model.file_name)
_path = Path(model.path, model.file_name)
segids, chains = PDBFactory.identify_chainseg(_path)
if set(segids) != set(chains):
logger.info("No chain IDs found, using segid information")
PDBFactory.swap_segid_chain(Path(model.path) / model.file_name,
self.path / model.file_name)
self.path / model.file_name)
else:
# Copy original model to this working path
shutil.copyfile(Path(model.path) / model.file_name, self.path / model.file_name)
shutil.copyfile(Path(model.path) / model.file_name, self.path /
model.file_name)

model_with_chains = self.path / model.file_name
# Split by chain
new_models = PDBFactory.split_by_chain(model_with_chains)
if model_with_chains in new_models:
self.finish_with_error(f"Input {model_with_chains} cannot be split by chain")
self.finish_with_error(f"Input {model_with_chains} cannot be"
" split by chain")

# Receptor and ligand PDB structures
rec_chain = self.defaults["params"]["receptor_chains"][0]
lig_chain = self.defaults["params"]["ligand_chains"][0]
receptor_pdb_file = f"{Path(model.file_name).stem}_{rec_chain}.{Format.PDB}"
ligand_pdb_file = f"{Path(model.file_name).stem}_{lig_chain}.{Format.PDB}"
receptor_pdb_file = (f"{Path(model.file_name).stem}_"
f"{rec_chain}.{Format.PDB}")
ligand_pdb_file = (f"{Path(model.file_name).stem}_"
f"{lig_chain}.{Format.PDB}")

# Setup
logger.info("Running LightDock setup")
Expand All @@ -63,7 +69,8 @@ def run(self, module_information):
glowworms = self.defaults["params"]["glowworms"]
noxt = self.defaults["params"]["noxt"]
noh = self.defaults["params"]["noh"]
cmd = f"lightdock3_setup.py {receptor_pdb_file} {ligand_pdb_file} -s {swarms} -g {glowworms}"
cmd = (f"lightdock3_setup.py {receptor_pdb_file}"
f" {ligand_pdb_file} -s {swarms} -g {glowworms}")
if noxt:
cmd += " --noxt"
if noh:
Expand All @@ -89,18 +96,24 @@ def run(self, module_information):
cmd = f"lgd_rank.py {swarms} {steps}"
subprocess.call(cmd, shell=True)

# Generate top, requires a hack to use original structures (H, OXT, etc.)
# Generate top, requires a hack to use original structures (H, OXT,
# etc.)
logger.info("Generating top structures")
with working_directory(self.path):
# Save structures, needs error control
shutil.copyfile(self.path / receptor_pdb_file, self.path / f"tmp_{receptor_pdb_file}")
shutil.copyfile(self.path / ligand_pdb_file, self.path / f"tmp_{ligand_pdb_file}")
shutil.copy(self.path / receptor_pdb_file, self.path / f"lightdock_{receptor_pdb_file}")
shutil.copy(self.path / ligand_pdb_file, self.path / f"lightdock_{ligand_pdb_file}")
shutil.copyfile(self.path / receptor_pdb_file, self.path /
f"tmp_{receptor_pdb_file}")
shutil.copyfile(self.path / ligand_pdb_file, self.path /
f"tmp_{ligand_pdb_file}")
shutil.copy(self.path / receptor_pdb_file, self.path /
f"lightdock_{receptor_pdb_file}")
shutil.copy(self.path / ligand_pdb_file, self.path /
f"lightdock_{ligand_pdb_file}")
# Create top
steps = self.defaults["params"]["steps"]
top = self.defaults["params"]["top"]
cmd = f"lgd_top.py {receptor_pdb_file} {ligand_pdb_file} rank_by_scoring.list {top}"
cmd = (f"lgd_top.py {receptor_pdb_file} {ligand_pdb_file}"
f" rank_by_scoring.list {top}")
subprocess.call(cmd, shell=True)

# Tidy top files
Expand All @@ -110,7 +123,9 @@ def run(self, module_information):
file_name = f"top_{i+1}.{Format.PDB}"
tidy_file_name = f"haddock_top_{i+1}.{Format.PDB}"
PDBFactory.tidy(self.path / file_name, self.path / tidy_file_name)
expected.append(PDBFile(tidy_file_name, topology=model.topology, path=(self.path / tidy_file_name)))
expected.append(PDBFile(tidy_file_name,
topology=model.topology,
path=(self.path / tidy_file_name)))

# Save module information
io = ModuleIO()
Expand Down
Loading