Coverage for biobb_vs/utils/extract_model_pdbqt.py: 77%

79 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-28 12:00 +0000

1#!/usr/bin/env python3 

2 

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

4 

5import argparse 

6import warnings 

7from pathlib import PurePath 

8from typing import Optional 

9 

10from Bio import BiopythonDeprecationWarning 

11from biobb_common.configuration import settings 

12from biobb_common.generic.biobb_object import BiobbObject 

13from biobb_common.tools import file_utils as fu 

14from biobb_common.tools.file_utils import launchlogger 

15 

16from biobb_vs.utils.common import check_input_path, check_output_path 

17 

18with warnings.catch_warnings(): 

19 warnings.simplefilter("ignore", BiopythonDeprecationWarning) 

20 # try: 

21 # import Bio.SubsMat.MatrixInfo 

22 # except ImportError: 

23 import Bio.Align.substitution_matrices 

24 import Bio.pairwise2 

25 import Bio.PDB 

26 

27 

28class ExtractModelPDBQT(BiobbObject): 

29 """ 

30 | biobb_vs ExtractModelPDBQT 

31 | Extracts a model from a PDBQT file with several models. 

32 | Extracts a model from a PDBQT file with several models. The model number to extract is defined by the user. 

33 

34 Args: 

35 input_pdbqt_path (str): Input PDBQT file. File type: input. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/data/utils/models.pdbqt>`_. Accepted formats: pdbqt (edam:format_1476). 

36 output_pdbqt_path (str): Output PDBQT file. File type: output. `Sample file <https://github.com/bioexcel/biobb_vs/raw/master/biobb_vs/test/reference/utils/ref_extract_model.pdbqt>`_. Accepted formats: pdbqt (edam:format_1476). 

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

38 * **model** (*int*) - (1) [0~1000|1] Model number to extract from input_pdbqt_path. 

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

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

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

42 

43 Examples: 

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

45 

46 from biobb_vs.utils.extract_model_pdbqt import extract_model_pdbqt 

47 prop = { 

48 'model': 1 

49 } 

50 extract_model_pdbqt(input_pdbqt_path='/path/to/myStructure.pdbqt', 

51 output_pdbqt_path='/path/to/newStructure.pdbqt', 

52 properties=prop) 

53 

54 Info: 

55 * wrapped_software: 

56 * name: In house using Biopython 

57 * version: >=1.76 

58 * license: Apache-2.0 

59 * ontology: 

60 * name: EDAM 

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

62 

63 """ 

64 

65 def __init__( 

66 self, input_pdbqt_path, output_pdbqt_path, properties=None, **kwargs 

67 ) -> None: 

68 properties = properties or {} 

69 

70 # Call parent class constructor 

71 super().__init__(properties) 

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

73 

74 # Input/Output files 

75 self.io_dict = { 

76 "in": {"input_pdbqt_path": input_pdbqt_path}, 

77 "out": {"output_pdbqt_path": output_pdbqt_path}, 

78 } 

79 

80 # Properties specific for BB 

81 self.model = properties.get("model", 1) 

82 self.properties = properties 

83 

84 # Check the properties 

85 self.check_properties(properties) 

86 self.check_arguments() 

87 

88 def check_data_params(self, out_log, err_log): 

89 """Checks all the input/output paths and parameters""" 

90 self.io_dict["in"]["input_pdbqt_path"] = check_input_path( 

91 self.io_dict["in"]["input_pdbqt_path"], 

92 "input_pdbqt_path", 

93 out_log, 

94 self.__class__.__name__, 

95 ) 

96 self.io_dict["out"]["output_pdbqt_path"] = check_output_path( 

97 self.io_dict["out"]["output_pdbqt_path"], 

98 "output_pdbqt_path", 

99 False, 

100 out_log, 

101 self.__class__.__name__, 

102 ) 

103 

104 @launchlogger 

105 def launch(self) -> int: 

106 """Execute the :class:`ExtractModelPDBQT <utils.extract_model_pdbqt.ExtractModelPDBQT>` utils.extract_model_pdbqt.ExtractModelPDBQT object.""" 

107 

108 # check input/output paths and parameters 

109 self.check_data_params(self.out_log, self.err_log) 

110 

111 # Setup Biobb 

112 if self.check_restart(): 

113 return 0 

114 self.stage_files() 

115 

116 if self.restart: 

117 output_file_list = [self.io_dict["out"]["output_pdbqt_path"]] 

118 if fu.check_complete_files(output_file_list): 

119 fu.log( 

120 "Restart is enabled, this step: %s will the skipped" % self.step, 

121 self.out_log, 

122 self.global_log, 

123 ) 

124 return 0 

125 

126 structure_name = PurePath(self.io_dict["in"]["input_pdbqt_path"]).name 

127 parser = Bio.PDB.PDBParser(QUIET=True) 

128 structPDB = parser.get_structure( 

129 structure_name, self.io_dict["in"]["input_pdbqt_path"] 

130 ) 

131 

132 models = [] 

133 for model in structPDB.get_models(): 

134 models.append(model.id + 1) 

135 

136 if self.model not in models: 

137 fu.log( 

138 self.__class__.__name__ + ": Selected model %d not found in %s structure." 

139 % (self.model, self.io_dict["in"]["input_pdbqt_path"]), 

140 self.out_log, 

141 ) 

142 raise SystemExit( 

143 self.__class__.__name__ + ": Selected model %d not found in %s structure." 

144 % (self.model, self.io_dict["in"]["input_pdbqt_path"]) 

145 ) 

146 

147 save = False 

148 lines = 0 

149 with open(self.io_dict["in"]["input_pdbqt_path"], "r") as input_pdb, open( 

150 self.io_dict["out"]["output_pdbqt_path"], "w" 

151 ) as output_pdb: 

152 for line in input_pdb: 

153 if line.startswith("MODEL") and line.split()[1] == str(self.model): 

154 save = True 

155 if line.startswith("ENDMDL"): 

156 save = False 

157 if save and not line.startswith("MODEL"): 

158 lines = lines + 1 

159 output_pdb.write(line) 

160 

161 fu.log( 

162 "Saving model %d to %s" 

163 % (self.model, self.io_dict["out"]["output_pdbqt_path"]), 

164 self.out_log, 

165 ) 

166 

167 # Copy files to host 

168 self.copy_to_host() 

169 

170 # self.tmp_files.extend([self.stage_io_dict.get("unique_dir", "")]) 

171 self.remove_tmp_files() 

172 

173 self.check_arguments(output_files_created=True, raise_exception=False) 

174 

175 return 0 

176 

177 

178def extract_model_pdbqt( 

179 input_pdbqt_path: str, 

180 output_pdbqt_path: str, 

181 properties: Optional[dict] = None, 

182 **kwargs, 

183) -> int: 

184 """Execute the :class:`ExtractModelPDBQT <utils.extract_model_pdbqt.ExtractModelPDBQT>` class and 

185 execute the :meth:`launch() <utils.extract_model_pdbqt.ExtractModelPDBQT.launch>` method.""" 

186 

187 return ExtractModelPDBQT( 

188 input_pdbqt_path=input_pdbqt_path, 

189 output_pdbqt_path=output_pdbqt_path, 

190 properties=properties, 

191 **kwargs, 

192 ).launch() 

193 

194 extract_model_pdbqt.__doc__ = ExtractModelPDBQT.__doc__ 

195 

196 

197def main(): 

198 """Command line execution of this building block. Please check the command line documentation.""" 

199 parser = argparse.ArgumentParser( 

200 description="Extracts a model from a PDBQT file with several models.", 

201 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999), 

202 ) 

203 parser.add_argument("--config", required=False, help="Configuration file") 

204 

205 # Specific args of each building block 

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

207 required_args.add_argument( 

208 "--input_pdbqt_path", 

209 required=True, 

210 help="Input PDBQT file. Accepted formats: pdbqt.", 

211 ) 

212 required_args.add_argument( 

213 "--output_pdbqt_path", 

214 required=True, 

215 help="Output PDBQT file. Accepted formats: pdbqt.", 

216 ) 

217 

218 args = parser.parse_args() 

219 args.config = args.config or "{}" 

220 properties = settings.ConfReader(config=args.config).get_prop_dic() 

221 

222 # Specific call of each building block 

223 extract_model_pdbqt( 

224 input_pdbqt_path=args.input_pdbqt_path, 

225 output_pdbqt_path=args.output_pdbqt_path, 

226 properties=properties, 

227 ) 

228 

229 

230if __name__ == "__main__": 

231 main()