Coverage for biobb_haddock/haddock_restraints/haddock3_restrain_bodies.py: 71%

52 statements  

« prev     ^ index     » next       coverage.py v7.10.2, created at 2025-08-07 08:48 +0000

1#!/usr/bin/env python3 

2 

3"""Module containing the haddock class and the command line interface.""" 

4 

5import argparse 

6from typing import Optional 

7 

8from biobb_common.configuration import settings 

9from biobb_common.generic.biobb_object import BiobbObject 

10from biobb_common.tools.file_utils import launchlogger 

11 

12 

13class Haddock3RestrainBodies(BiobbObject): 

14 """ 

15 | biobb_haddock Haddock3RestrainBodies 

16 | Wrapper class for the Haddock-Restraints restrain_bodies module. 

17 | `Haddock-Restraints restrain_bodies <https://www.bonvinlab.org/haddock3/clients/haddock.clis.restraints.restrain_bodies.html>`_ creates distance restraints to lock several chains together. Useful to avoid unnatural flexibility or movement due to sequence/numbering gaps. 

18 

19 Args: 

20 input_structure_path (str): Path to the input PDB structure to be restrained. File type: input. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/data/haddock_restraints/4G6K_clean.pdb>`_. Accepted formats: pdb (edam:format_1476). 

21 output_tbl_path (str): Path to the output HADDOCK tbl file with Ambiguous Interaction Restraints (AIR) information. File type: output. `Sample file <https://raw.githubusercontent.com/bioexcel/biobb_haddock/master/biobb_haddock/test/reference/haddock_restraints/antibody-unambig.tbl>`_. Accepted formats: tbl (edam:format_2330), txt (edam:format_2330), out (edam:format_2330). 

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

23 * **exclude** (*str*) - (None) Chains to exclude from the calculation. 

24 * **verbose** (*int*) - (0) Tune verbosity of the output. 

25 * **binary_path** (*str*) - ("haddock3-restraints") Path to the HADDOCK3 restraints executable binary. 

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

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

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

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

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

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

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

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

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

35 

36 

37 Examples: 

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

39 

40 from biobb_haddock.haddock_restraints.haddock3_restrain_bodies import haddock3_restrain_bodies 

41 haddock3_restrain_bodies( 

42 input_structure_path='/path/to/structure.pdb', 

43 output_tbl_path='/path/to/body_restraints.tbl' 

44 ) 

45 

46 Info: 

47 * wrapped_software: 

48 * name: Haddock33-restraints 

49 * version: 2025.5 

50 * license: Apache-2.0 

51 * ontology: 

52 * name: EDAM 

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

54 """ 

55 

56 def __init__( 

57 self, 

58 input_structure_path: str, 

59 output_tbl_path: str, 

60 properties: Optional[dict] = None, 

61 **kwargs, 

62 ) -> None: 

63 properties = properties or {} 

64 

65 # Call parent class constructor 

66 super().__init__(properties) 

67 

68 # Input/Output files 

69 self.io_dict = { 

70 "in": { 

71 "input_structure_path": input_structure_path 

72 }, 

73 "out": { 

74 "output_tbl_path": output_tbl_path, 

75 }, 

76 } 

77 

78 # Properties specific for BB 

79 self.binary_path = properties.get("binary_path", "haddock3-restraints") 

80 self.exclude = properties.get("exclude", None) 

81 self.verbose = properties.get("verbose", 0) 

82 

83 # Check the properties 

84 self.check_properties(properties) 

85 

86 @launchlogger 

87 def launch(self) -> int: 

88 """Execute the :class:`Haddock3RestrainBodies <biobb_haddock.haddock_restraints.haddock3_restrain_bodies>` object.""" 

89 

90 # Setup Biobb 

91 if self.check_restart(): 

92 return 0 

93 self.stage_files() 

94 

95 # haddock3-restraints restrain_bodies <structure> [--exclude] [--verbose] 

96 self.cmd = [self.binary_path, "restrain_bodies", 

97 self.stage_io_dict['in']['input_structure_path']] 

98 

99 if self.exclude is not None: 

100 self.cmd.extend(["--exclude", self.exclude]) 

101 

102 if self.verbose > 0: 

103 self.cmd.extend(["--verbose", str(self.verbose)]) 

104 

105 self.cmd.append(">") 

106 self.cmd.append(self.stage_io_dict['out']['output_tbl_path']) 

107 self.cmd.append("2>&1") 

108 

109 # Run Biobb block 

110 self.run_biobb() 

111 

112 # Remove deprecation warning if present 

113 with open(self.stage_io_dict['out']['output_tbl_path'], 'r') as file: 

114 lines = file.readlines() 

115 if lines and "DEPRECATION NOTICE" in lines[0]: 

116 with open(self.stage_io_dict['out']['output_tbl_path'], 'w') as file: 

117 file.writelines(lines[1:]) 

118 

119 # Copy files to host 

120 self.copy_to_host() 

121 

122 # Remove temporal files 

123 self.tmp_files.extend([self.stage_io_dict["unique_dir"]]) 

124 self.remove_tmp_files() 

125 

126 return self.return_code 

127 

128 

129def haddock3_restrain_bodies( 

130 input_structure_path: str, 

131 output_tbl_path: str, 

132 properties: Optional[dict] = None, 

133 **kwargs, 

134) -> int: 

135 """Create :class:`Haddock3RestrainBodies <biobb_haddock.haddock_restraints.haddock3_restrain_bodies>` class and 

136 execute the :meth:`launch() <biobb_haddock.haddock_restraints.haddock3_restrain_bodies.launch>` method.""" 

137 

138 return Haddock3RestrainBodies( 

139 input_structure_path=input_structure_path, 

140 output_tbl_path=output_tbl_path, 

141 properties=properties, 

142 **kwargs, 

143 ).launch() 

144 

145 

146haddock3_restrain_bodies.__doc__ = Haddock3RestrainBodies.__doc__ 

147 

148 

149def main(): 

150 parser = argparse.ArgumentParser( 

151 description="Wrapper of the haddock-restraints restrain_bodies module.", 

152 formatter_class=lambda prog: argparse.RawTextHelpFormatter( 

153 prog, width=99999), 

154 ) 

155 parser.add_argument( 

156 "-c", 

157 "--config", 

158 required=False, 

159 help="This file can be a YAML file, JSON file or JSON string", 

160 ) 

161 

162 # Specific args of each building block 

163 required_args = parser.add_argument_group("required arguments") 

164 required_args.add_argument("--input_structure_path", required=True) 

165 required_args.add_argument("--output_tbl_path", required=True) 

166 

167 args = parser.parse_args() 

168 config = args.config if args.config else None 

169 properties = settings.ConfReader(config=config).get_prop_dic() 

170 

171 # Specific call of each building block 

172 haddock3_restrain_bodies( 

173 input_structure_path=args.input_structure_path, 

174 output_tbl_path=args.output_tbl_path, 

175 properties=properties, 

176 ) 

177 

178 

179if __name__ == "__main__": 

180 main()