Coverage for biobb_flexserv/flexserv/dmd_run.py: 75%

68 statements  

« prev     ^ index     » next       coverage.py v7.9.1, created at 2025-06-19 15:08 +0000

1#!/usr/bin/env python3 

2 

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

4import argparse 

5from typing import Optional 

6from pathlib import Path 

7from biobb_common.generic.biobb_object import BiobbObject 

8from biobb_common.configuration import settings 

9from biobb_common.tools.file_utils import launchlogger 

10 

11 

12class DMDRun(BiobbObject): 

13 """ 

14 | biobb_flexserv DMDRun 

15 | Wrapper of the Discrete Molecular Dynamics tool from the FlexServ module. 

16 | Generates protein conformational structures using the Discrete Molecular Dynamics (DMD) method. 

17 

18 Args: 

19 input_pdb_path (str): Input PDB file. File type: input. `Sample file <https://github.com/bioexcel/biobb_flexserv/raw/master/biobb_flexserv/test/data/flexserv/structure.ca.pdb>`_. Accepted formats: pdb (edam:format_1476). 

20 output_log_path (str): Output log file. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexserv/raw/master/biobb_flexserv/test/reference/flexserv/dmd_run_out.log>`_. Accepted formats: log (edam:format_2330), out (edam:format_2330), txt (edam:format_2330), o (edam:format_2330). 

21 output_crd_path (str): Output ensemble. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexserv/raw/master/biobb_flexserv/test/reference/flexserv/dmd_run_out.crd>`_. Accepted formats: crd (edam:format_3878), mdcrd (edam:format_3878), inpcrd (edam:format_3878). 

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

23 * **binary_path** (*str*) - ("dmdgoopt") DMD binary path to be used. 

24 * **dt** (*float*) - (1e-12) Integration time (s) 

25 * **temperature** (*int*) - (300) Simulation temperature (K) 

26 * **frames** (*int*) - (1000) Number of frames in the final ensemble 

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

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

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

30 

31 Examples: 

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

33 

34 from biobb_flexserv.flexserv.dmd_run import dmd_run 

35 prop = { 

36 'binary_path': 'dmdgoopt' 

37 } 

38 flexserv_run(input_pdb_path='/path/to/dmd_input.pdb', 

39 output_log_path='/path/to/dmd_log.log', 

40 output_crd_path='/path/to/dmd_ensemble.crd', 

41 properties=prop) 

42 

43 Info: 

44 * wrapped_software: 

45 * name: FlexServ Discrete Molecular Dynamics 

46 * version: >=1.0 

47 * license: Apache-2.0 

48 * ontology: 

49 * name: EDAM 

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

51 

52 """ 

53 

54 def __init__(self, input_pdb_path: str, output_log_path: str, 

55 output_crd_path: str, properties: Optional[dict] = None, **kwargs) -> None: 

56 

57 properties = properties or {} 

58 

59 # Call parent class constructor 

60 super().__init__(properties) 

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

62 

63 # Input/Output files 

64 self.io_dict = { 

65 'in': {'input_pdb_path': input_pdb_path}, 

66 'out': {'output_log_path': output_log_path, 

67 'output_crd_path': output_crd_path} 

68 } 

69 

70 # Properties specific for BB 

71 self.properties = properties 

72 self.binary_path = properties.get('binary_path', 'dmdgoopt') 

73 # self.dt = properties.get('dt', 1.D-12) 

74 self.dt = properties.get('dt', 1e-12) 

75 self.temperature = properties.get('temperature', 300) 

76 self.frames = properties.get('frames', 1000) 

77 

78 # Check the properties 

79 self.check_properties(properties) 

80 self.check_arguments() 

81 

82 @launchlogger 

83 def launch(self): 

84 """Launches the execution of the FlexServ BDRun module.""" 

85 

86 # Setup Biobb 

87 if self.check_restart(): 

88 return 0 

89 self.stage_files() 

90 

91 # Internal file paths 

92 try: 

93 # Using rel paths to shorten the amount of characters due to fortran path length limitations 

94 input_pdb = str(Path(self.stage_io_dict["in"]["input_pdb_path"]).relative_to(Path.cwd())) 

95 output_crd = str(Path(self.stage_io_dict["out"]["output_crd_path"]).relative_to(Path.cwd())) 

96 output_log = str(Path(self.stage_io_dict["out"]["output_log_path"]).relative_to(Path.cwd())) 

97 except ValueError: 

98 # Container or remote case 

99 input_pdb = self.stage_io_dict["in"]["input_pdb_path"] 

100 output_crd = self.stage_io_dict["out"]["output_crd_path"] 

101 output_log = self.stage_io_dict["out"]["output_log_path"] 

102 

103 # Config file 

104 instructions_file = str(Path(self.stage_io_dict.get("unique_dir", "")).joinpath("dmd.in")) 

105 with open(instructions_file, 'w') as dmdin: 

106 

107 dmdin.write("&INPUT\n") 

108 dmdin.write(" FILE9='{}',\n".format(input_pdb)) 

109 dmdin.write(" FILE21='{}',\n".format(output_crd)) 

110 dmdin.write(" TSNAP={},\n".format(self.dt)) 

111 dmdin.write(" NBLOC={},\n".format(self.frames)) 

112 dmdin.write(" TEMP={},\n".format(self.temperature)) 

113 dmdin.write(" RCUTGO=8,\n") 

114 dmdin.write(" RCA=0.5,\n") 

115 dmdin.write(" SIGMA=0.05,\n") 

116 dmdin.write(" SIGMAGO=0.1,\n") 

117 dmdin.write(" KKK=2839\n") 

118 dmdin.write("&END\n") 

119 

120 # Command line 

121 # dmdgoopt < dmd.in > dmd.log 

122 self.cmd = [self.binary_path, 

123 '<', instructions_file, 

124 '>', output_log 

125 ] 

126 

127 # Run Biobb block 

128 self.run_biobb() 

129 

130 # Copy files to host 

131 self.copy_to_host() 

132 

133 # remove temporary folder(s) 

134 # self.tmp_files.extend([ 

135 # self.stage_io_dict.get("unique_dir", "") 

136 # ]) 

137 self.remove_tmp_files() 

138 

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

140 

141 return self.return_code 

142 

143 

144def dmd_run(input_pdb_path: str, 

145 output_log_path: str, output_crd_path: str, 

146 properties: Optional[dict] = None, **kwargs) -> int: 

147 """Create :class:`DMDRun <flexserv.dmd_run.DMDRun>`flexserv.dmd_run.DMDRun class and 

148 execute :meth:`launch() <flexserv.dmd_run.DMDRun.launch>` method""" 

149 

150 return DMDRun(input_pdb_path=input_pdb_path, 

151 output_log_path=output_log_path, 

152 output_crd_path=output_crd_path, 

153 properties=properties).launch() 

154 

155 dmd_run.__doc__ = DMDRun.__doc__ 

156 

157 

158def main(): 

159 parser = argparse.ArgumentParser(description='Generates protein conformational structures using the Discrete Molecular Dynamics method.', formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999)) 

160 parser.add_argument('--config', required=False, help='Configuration file') 

161 

162 # Specific args 

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

164 required_args.add_argument('--input_pdb_path', required=True, help='Input PDB file. Accepted formats: pdb.') 

165 required_args.add_argument('--output_log_path', required=True, help='Output log file. Accepted formats: log, out, txt.') 

166 required_args.add_argument('--output_crd_path', required=True, help='Output ensemble file. Accepted formats: crd, mdcrd, inpcrd.') 

167 

168 args = parser.parse_args() 

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

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

171 

172 # Specific call 

173 dmd_run(input_pdb_path=args.input_pdb_path, 

174 output_log_path=args.output_log_path, 

175 output_crd_path=args.output_crd_path, 

176 properties=properties) 

177 

178 

179if __name__ == '__main__': 

180 main()