Coverage for biobb_haddock/haddock/topology.py: 91%

53 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-03 15:55 +0000

1#!/usr/bin/env python3 

2 

3"""Module containing the HADDOCK3 Topology class and the command line interface.""" 

4 

5from pathlib import Path 

6from typing import Optional 

7from biobb_common.generic.biobb_object import BiobbObject 

8from biobb_common.tools import file_utils as fu 

9from biobb_common.tools.file_utils import launchlogger 

10from biobb_haddock.haddock.common import create_cfg, move_to_container_path, zip_wf_output 

11 

12 

13class Topology(BiobbObject): 

14 """ 

15 | biobb_haddock Topology 

16 | Wrapper class for the HADDOCK3 Topology module. 

17 | The Topology module. `HADDOCK3 Topology module <https://www.bonvinlab.org/haddock3/modules/topology/haddock.modules.topology.topoaa.html#haddock.modules.topology.topoaa.HaddockModule>`_ creates a topology from a system to be used for docking. 

18 

19 Args: 

20 mol1_input_pdb_path (str): Path to the input PDB file. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/data/haddock/e2aP_1F3G.pdb>`_. Accepted formats: pdb (edam:format_1476). 

21 mol1_output_top_zip_path (str) (Optional): Path to the output PDB file collection in zip format. File type: output. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/reference/haddock/ref_mol1_top.zip>`_. Accepted formats: zip (edam:format_3987). 

22 mol2_input_pdb_path (str) (Optional): Path to the input PDB file. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/data/haddock/hpr_ensemble.pdb>`_. Accepted formats: pdb (edam:format_1476). 

23 mol2_output_top_zip_path (str) (Optional): Path to the output PDB file collection in zip format. File type: output. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/reference/haddock/ref_mol2_top.zip>`_. Accepted formats: zip (edam:format_3987). 

24 output_haddock_wf_data (dir): Path to the output zipball containing all the current Haddock workflow data. File type: output. `Sample file <https://github.com/bioexcel/biobb_haddock/raw/master/biobb_haddock/test/data/haddock/haddock_wf_data_emref.zip>`_. Accepted formats: zip (edam:format_3987). 

25 haddock_config_path (str) (Optional): Haddock configuration CFG file path. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/data/haddock/run.cfg>`_. Accepted formats: cfg (edam:format_1476). 

26 properties (dict - Python dictionary object containing the tool parameters, not input/output files): 

27 * **cfg** (*dict*) - ({}) Haddock configuration options specification. 

28 * **global_cfg** (*dict*) - ({"postprocess": False}) `Global configuration options <https://www.bonvinlab.org/haddock3-user-manual/global_parameters.html>`_ specification. 

29 * **binary_path** (*str*) - ("haddock") Path to the haddock haddock executable binary. 

30 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files. 

31 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist. 

32 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory. 

33 * **container_path** (*str*) - (None) Path to the binary executable of your container. 

34 * **container_image** (*str*) - (None) Container Image identifier. 

35 * **container_volume_path** (*str*) - ("/data") Path to an internal directory in the container. 

36 * **container_working_dir** (*str*) - (None) Path to the internal CWD in the container. 

37 * **container_user_id** (*str*) - (None) User number id to be mapped inside the container. 

38 * **container_shell_path** (*str*) - ("/bin/bash") Path to the binary executable of the container shell. 

39 

40 

41 Examples: 

42 This is a use example of how to use the building block from Python:: 

43 

44 from biobb_haddock.haddock.topology import topology 

45 prop = { 'binary_path': 'haddock' } 

46 topology(mol1_input_pdb_path='/path/to/myStructure.pdb', 

47 mol1_output_top_zip_path='/path/to/topology.zip', 

48 properties=prop) 

49 

50 Info: 

51 * wrapped_software: 

52 * name: HADDOCK3 

53 * version: 2025.5 

54 * license: Apache-2.0 

55 * ontology: 

56 * name: EDAM 

57 * schema: http://edamontology.org/EDAM.owl 

58 """ 

59 

60 def __init__( 

61 self, 

62 mol1_input_pdb_path: str, 

63 output_haddock_wf_data: str, 

64 mol1_output_top_zip_path: Optional[str] = None, 

65 mol2_input_pdb_path: Optional[str] = None, 

66 mol2_output_top_zip_path: Optional[str] = None, 

67 haddock_config_path: Optional[str] = None, 

68 properties: Optional[dict] = None, 

69 **kwargs, 

70 ) -> None: 

71 properties = properties or {} 

72 

73 # Call parent class constructor 

74 super().__init__(properties) 

75 self.locals_var_dict = locals().copy() 

76 

77 # Input/Output files 

78 self.io_dict = { 

79 "in": { 

80 "mol1_input_pdb_path": mol1_input_pdb_path, 

81 "mol2_input_pdb_path": mol2_input_pdb_path, 

82 "haddock_config_path": haddock_config_path, 

83 }, 

84 "out": { 

85 "output_haddock_wf_data": output_haddock_wf_data, 

86 "mol1_output_top_zip_path": mol1_output_top_zip_path, 

87 "mol2_output_top_zip_path": mol2_output_top_zip_path, 

88 }, 

89 } 

90 

91 # Properties specific for BB 

92 self.haddock_step_name = "topoaa" 

93 # Handle configuration options from propierties 

94 self.cfg = {k: v for k, v in properties.get("cfg", dict()).items()} 

95 # Global HADDOCK configuration options 

96 self.global_cfg = properties.get("global_cfg", dict(postprocess=False)) 

97 # Properties specific for BB 

98 self.binary_path = properties.get("binary_path", "haddock3") 

99 # Check the properties 

100 self.check_init(properties) 

101 

102 @launchlogger 

103 def launch(self) -> int: 

104 """Execute the :class:`Topology <biobb_haddock.haddock.topology>` object.""" 

105 

106 # Setup Biobb 

107 if self.check_restart(): 

108 return 0 

109 self.stage_files() 

110 

111 self.run_dir = self.stage_io_dict["out"]["output_haddock_wf_data"] 

112 self.run_dir = self.run_dir[:-4] if self.run_dir[-4:] == ".zip" else self.run_dir 

113 workflow_dict = { 

114 "run_dir": self.run_dir, 

115 "molecules": [self.stage_io_dict["in"]["mol1_input_pdb_path"]], 

116 "haddock_step_name": self.haddock_step_name, 

117 } 

118 workflow_dict.update(self.global_cfg) 

119 

120 if mol2_input_pdb_path := self.stage_io_dict["in"].get("mol2_input_pdb_path"): 

121 workflow_dict["molecules"].append(mol2_input_pdb_path) 

122 

123 # Create workflow configuration 

124 self.output_cfg_path = create_cfg( 

125 output_cfg_path=self.create_tmp_file('_haddock.cfg'), 

126 workflow_dict=workflow_dict, 

127 input_cfg_path=self.stage_io_dict["in"].get("haddock_config_path"), 

128 cfg_properties_dict=self.cfg, 

129 ) 

130 

131 if self.container_path: 

132 fu.log("Container execution enabled", self.out_log) 

133 move_to_container_path(self) 

134 

135 self.cmd = [self.binary_path, self.output_cfg_path] 

136 

137 # Run Biobb block 

138 self.run_biobb() 

139 

140 # Copy output 

141 haddock_output_path = Path(f'{workflow_dict["run_dir"]}/0_{self.haddock_step_name}') 

142 mol1_name = str(Path(self.io_dict["in"]["mol1_input_pdb_path"]).stem) 

143 mol1_output_file_list = list( 

144 haddock_output_path.glob(mol1_name + r"*_haddock.pdb*") 

145 ) 

146 fu.zip_list( 

147 self.io_dict["out"]["mol1_output_top_zip_path"], 

148 mol1_output_file_list, 

149 ) 

150 

151 if self.io_dict["out"].get("mol1_output_top_zip_path"): 

152 mol2_name = str(Path(self.io_dict["in"]["mol2_input_pdb_path"]).stem) 

153 mol2_output_file_list = list( 

154 haddock_output_path.glob(mol2_name + r"*_haddock.pdb*") 

155 ) 

156 fu.zip_list( 

157 self.io_dict["out"]["mol2_output_top_zip_path"], 

158 mol2_output_file_list, 

159 self.out_log, 

160 ) 

161 

162 # Create zip output 

163 if self.stage_io_dict["out"]["output_haddock_wf_data"][-4:] == ".zip": 

164 zip_wf_output(self) 

165 

166 # Copy files to host 

167 self.copy_to_host() 

168 # Remove temporary files 

169 self.remove_tmp_files() 

170 

171 return self.return_code 

172 

173 

174def topology( 

175 mol1_input_pdb_path: str, 

176 output_haddock_wf_data: str, 

177 mol1_output_top_zip_path: Optional[str] = None, 

178 mol2_input_pdb_path: Optional[str] = None, 

179 mol2_output_top_zip_path: Optional[str] = None, 

180 haddock_config_path: Optional[str] = None, 

181 properties: Optional[dict] = None, 

182 **kwargs, 

183) -> int: 

184 """Create :class:`Topology <biobb_haddock.haddock.topology>` class and 

185 execute the :meth:`launch() <biobb_haddock.haddock.topology.launch>` method.""" 

186 return Topology(**dict(locals())).launch() 

187 

188 

189topology.__doc__ = Topology.__doc__ 

190main = Topology.get_main(topology, "Wrapper of the HADDOCK3 Topology module.") 

191 

192 

193if __name__ == "__main__": 

194 main()