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

68 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-22 13:24 +0000

1#!/usr/bin/env python3 

2 

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

4import warnings 

5from pathlib import PurePath 

6from typing import Optional 

7from Bio import BiopythonDeprecationWarning 

8from biobb_common.generic.biobb_object import BiobbObject 

9from biobb_common.tools import file_utils as fu 

10from biobb_common.tools.file_utils import launchlogger 

11 

12from biobb_vs.utils.common import check_input_path, check_output_path 

13 

14with warnings.catch_warnings(): 

15 warnings.simplefilter("ignore", BiopythonDeprecationWarning) 

16 # try: 

17 # import Bio.SubsMat.MatrixInfo 

18 # except ImportError: 

19 import Bio.Align.substitution_matrices 

20 import Bio.pairwise2 

21 import Bio.PDB 

22 

23 

24class ExtractModelPDBQT(BiobbObject): 

25 """ 

26 | biobb_vs ExtractModelPDBQT 

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

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

29 

30 Args: 

31 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). 

32 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). 

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

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

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

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

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

38 

39 Examples: 

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

41 

42 from biobb_vs.utils.extract_model_pdbqt import extract_model_pdbqt 

43 prop = { 

44 'model': 1 

45 } 

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

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

48 properties=prop) 

49 

50 Info: 

51 * wrapped_software: 

52 * name: In house using Biopython 

53 * version: >=1.76 

54 * license: Apache-2.0 

55 * ontology: 

56 * name: EDAM 

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

58 

59 """ 

60 

61 def __init__( 

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

63 ) -> None: 

64 properties = properties or {} 

65 

66 # Call parent class constructor 

67 super().__init__(properties) 

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

69 

70 # Input/Output files 

71 self.io_dict = { 

72 "in": {"input_pdbqt_path": input_pdbqt_path}, 

73 "out": {"output_pdbqt_path": output_pdbqt_path}, 

74 } 

75 

76 # Properties specific for BB 

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

78 self.properties = properties 

79 

80 # Check the properties 

81 self.check_properties(properties) 

82 self.check_arguments() 

83 

84 def check_data_params(self, out_log, err_log): 

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

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

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

88 "input_pdbqt_path", 

89 out_log, 

90 self.__class__.__name__, 

91 ) 

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

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

94 "output_pdbqt_path", 

95 False, 

96 out_log, 

97 self.__class__.__name__, 

98 ) 

99 

100 @launchlogger 

101 def launch(self) -> int: 

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

103 

104 # check input/output paths and parameters 

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

106 

107 # Setup Biobb 

108 if self.check_restart(): 

109 return 0 

110 self.stage_files() 

111 

112 if self.restart: 

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

114 if fu.check_complete_files(output_file_list): 

115 fu.log( 

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

117 self.out_log, 

118 self.global_log, 

119 ) 

120 return 0 

121 

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

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

124 structPDB = parser.get_structure( 

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

126 ) 

127 

128 models = [] 

129 for model in structPDB.get_models(): 

130 models.append(model.id + 1) 

131 

132 if self.model not in models: 

133 fu.log( 

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

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

136 self.out_log, 

137 ) 

138 raise SystemExit( 

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

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

141 ) 

142 

143 save = False 

144 lines = 0 

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

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

147 ) as output_pdb: 

148 for line in input_pdb: 

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

150 save = True 

151 if line.startswith("ENDMDL"): 

152 save = False 

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

154 lines = lines + 1 

155 output_pdb.write(line) 

156 

157 fu.log( 

158 "Saving model %d to %s" 

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

160 self.out_log, 

161 ) 

162 

163 # Copy files to host 

164 self.copy_to_host() 

165 # Remove temporal files 

166 self.remove_tmp_files() 

167 

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

169 

170 return 0 

171 

172 

173def extract_model_pdbqt( 

174 input_pdbqt_path: str, 

175 output_pdbqt_path: str, 

176 properties: Optional[dict] = None, 

177 **kwargs, 

178) -> int: 

179 """Create the :class:`ExtractModelPDBQT <utils.extract_model_pdbqt.ExtractModelPDBQT>` class and 

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

181 return ExtractModelPDBQT(**dict(locals())).launch() 

182 

183 

184extract_model_pdbqt.__doc__ = ExtractModelPDBQT.__doc__ 

185main = ExtractModelPDBQT.get_main(extract_model_pdbqt, "Extracts a model from a PDBQT file with several models.") 

186 

187 

188if __name__ == "__main__": 

189 main()