Coverage for biobb_amber / sander / sander_mdrun.py: 54%

191 statements  

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

1#!/usr/bin/env python3 

2 

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

4from typing import Optional 

5import shutil 

6import re 

7from pathlib import Path, PurePath 

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 

11from biobb_amber.sander.common import check_input_path, check_output_path 

12 

13 

14class SanderMDRun(BiobbObject): 

15 """ 

16 | biobb_amber SanderMDRun 

17 | Wrapper of the `AmberTools (AMBER MD Package) sander tool <https://ambermd.org/AmberTools.php>`_ module. 

18 | Runs energy minimization, molecular dynamics, and NMR refinements using sander tool from the AmberTools MD package. 

19 

20 Args: 

21 input_top_path (str): Input topology file (AMBER ParmTop). File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/sander/cln025.prmtop>`_. Accepted formats: top (edam:format_3881), parmtop (edam:format_3881), prmtop (edam:format_3881). 

22 input_crd_path (str): Input coordinates file (AMBER crd). File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/sander/cln025.inpcrd>`_. Accepted formats: crd (edam:format_3878), mdcrd (edam:format_3878), inpcrd (edam:format_3878), netcdf (edam:format_3650), nc (edam:format_3650), ncrst (edam:format_3886), rst (edam:format_3886). 

23 input_mdin_path (str) (Optional): Input configuration file (MD run options) (AMBER mdin). File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/sander/npt.mdin>`_. Accepted formats: mdin (edam:format_2330), in (edam:format_2330), txt (edam:format_2330). 

24 input_cpin_path (str) (Optional): Input constant pH file (AMBER cpin). File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/sander/cln025.cpin>`_. Accepted formats: cpin (edam:format_2330). 

25 input_ref_path (str) (Optional): Input reference coordinates for position restraints. File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/sander/sander.rst>`_. Accepted formats: rst (edam:format_3886), rst7 (edam:format_3886), netcdf (edam:format_3650), nc (edam:format_3650), ncrst (edam:format_3886), crd (edam:format_3878). 

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

27 output_traj_path (str): Output trajectory file. File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/sander/sander.x>`_. Accepted formats: trj (edam:format_3878), crd (edam:format_3878), mdcrd (edam:format_3878), x (edam:format_3878), netcdf (edam:format_3650), nc (edam:format_3650). 

28 output_rst_path (str): Output restart file. File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/sander/sander.rst>`_. Accepted formats: rst (edam:format_3886), rst7 (edam:format_3886), netcdf (edam:format_3650), nc (edam:format_3650), ncrst (edam:format_3886). 

29 output_cpout_path (str) (Optional): Output constant pH file (AMBER cpout). File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/sander/sander.cpout>`_. Accepted formats: cpout (edam:format_2330). 

30 output_cprst_path (str) (Optional): Output constant pH restart file (AMBER rstout). File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/sander/sander.cprst>`_. Accepted formats: cprst (edam:format_3886), rst (edam:format_3886), rst7 (edam:format_3886). 

31 output_mdinfo_path (str) (Optional): Output MD info. File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/sander/sander.mdinfo>`_. Accepted formats: mdinfo (edam:format_2330). 

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

33 * **mdin** (*dict*) - ({}) Sander MD run options specification. (Used if *input_mdin_path* is None) 

34 * **simulation_type** (*str*) - ("minimization") Default options for the mdin file. Each creates a different mdin file. Values: `minimization <https://biobb-amber.readthedocs.io/en/latest/_static/mdins/min.mdin>`_ (Runs an energy minimization), `min_vacuo <https://biobb-amber.readthedocs.io/en/latest/_static/mdins/min_vacuo.mdin>`_ (Runs an energy minimization in vacuo), `NVT <https://biobb-amber.readthedocs.io/en/latest/_static/mdins/nvt.mdin>`_ (Runs an NVT equilibration), `npt <https://biobb-amber.readthedocs.io/en/latest/_static/mdins/npt.mdin>`_ (Runs an NPT equilibration), `free <https://biobb-amber.readthedocs.io/en/latest/_static/mdins/free.mdin>`_ (Runs a MD simulation), `heat <https://biobb-amber.readthedocs.io/en/latest/_static/mdins/heat.mdin>`_ (Heats the MD system). 

35 * **binary_path** (*str*) - ("sander") sander binary path to be used. 

36 * **direct_mdin** (*bool*) - (False) Use input_mdin_path as it is, skip file parsing. 

37 * **mpi_bin** (*str*) - (None) Path to the MPI runner. Usually "mpirun" or "srun". 

38 * **mpi_np** (*int*) - (0) [0~1000|1] Number of MPI processes. Usually an integer bigger than 1. 

39 * **mpi_flags** (*str*) - (None) Path to the MPI hostlist file. 

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

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

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

43 * **container_path** (*str*) - (None) Container path definition. 

44 * **container_image** (*str*) - ('afandiadib/ambertools:serial') Container image definition. 

45 * **container_volume_path** (*str*) - ('/tmp') Container volume path definition. 

46 * **container_working_dir** (*str*) - (None) Container working directory definition. 

47 * **container_user_id** (*str*) - (None) Container user_id definition. 

48 * **container_shell_path** (*str*) - ('/bin/bash') Path to default shell inside the container. 

49 

50 Examples: 

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

52 

53 from biobb_amber.sander.sander_mdrun import sander_mdrun 

54 prop = { 

55 'simulation_type' : 'minimization', 

56 'mdin' : { 

57 'dt' : 0.002 

58 } 

59 } 

60 sander_mdrun(input_top_path='/path/to/topology.top', 

61 input_crd_path='/path/to/coordinates.crd', 

62 output_traj_path='/path/to/newTrajectory.crd', 

63 output_rst_path='/path/to/newRestart.rst', 

64 output_log_path='/path/to/newAmberlog.log', 

65 properties=prop) 

66 

67 Info: 

68 * wrapped_software: 

69 * name: AmberTools Sander 

70 * version: >20.9 

71 * license: LGPL 2.1 

72 * multinode: mpi 

73 * ontology: 

74 * name: EDAM 

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

76 

77 """ 

78 

79 def __init__(self, input_top_path: str, input_crd_path: str, output_log_path: str, output_traj_path: str, output_rst_path: str, 

80 input_ref_path: Optional[str] = None, input_mdin_path: Optional[str] = None, input_cpin_path: Optional[str] = None, output_cpout_path: Optional[str] = None, output_cprst_path: Optional[str] = None, output_mdinfo_path: Optional[str] = None, 

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

82 

83 properties = properties or {} 

84 

85 # Call parent class constructor 

86 super().__init__(properties) 

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

88 

89 # Input/Output files 

90 self.io_dict = { 

91 'in': {'input_top_path': input_top_path, 

92 'input_crd_path': input_crd_path, 

93 'input_mdin_path': input_mdin_path, 

94 'input_ref_path': input_ref_path, 

95 'input_cpin_path': input_cpin_path}, 

96 'out': {'output_log_path': output_log_path, 

97 'output_traj_path': output_traj_path, 

98 'output_rst_path': output_rst_path, 

99 'output_cpout_path': output_cpout_path, 

100 'output_cprst_path': output_cprst_path, 

101 'output_mdinfo_path': output_mdinfo_path} 

102 } 

103 

104 # Properties specific for BB 

105 self.properties = properties 

106 self.simulation_type = properties.get('simulation_type', "minimization") 

107 self.binary_path = properties.get('binary_path', "sander") 

108 

109 self.direct_mdin = properties.get('direct_mdin', False) 

110 self.mdin = {k: str(v) for k, v in properties.get('mdin', dict()).items()} 

111 

112 if 'restraintmask' in self.mdin and self.mdin['restraintmask'][0] != '"' and self.mdin['restraintmask'][-1] != '"': 

113 self.mdin['restraintmask'] = "\"" + self.mdin['restraintmask'] + "\"" 

114 

115 # Properties for MPI 

116 self.mpi_bin = properties.get('mpi_bin') 

117 self.mpi_np = properties.get('mpi_np') 

118 self.mpi_flags = properties.get('mpi_flags') 

119 

120 # Check the properties 

121 self.check_properties(properties) 

122 self.check_arguments() 

123 

124 def check_data_params(self, out_log, out_err): 

125 """ Checks input/output paths correctness """ 

126 

127 # Check input(s) 

128 self.io_dict["in"]["input_top_path"] = check_input_path(self.io_dict["in"]["input_top_path"], "input_top_path", False, out_log, self.__class__.__name__) 

129 self.io_dict["in"]["input_crd_path"] = check_input_path(self.io_dict["in"]["input_crd_path"], "input_crd_path", False, out_log, self.__class__.__name__) 

130 self.io_dict["in"]["input_mdin_path"] = check_input_path(self.io_dict["in"]["input_mdin_path"], "input_mdin_path", True, out_log, self.__class__.__name__) 

131 self.io_dict["in"]["input_cpin_path"] = check_input_path(self.io_dict["in"]["input_cpin_path"], "input_cpin_path", True, out_log, self.__class__.__name__) 

132 self.io_dict["in"]["input_ref_path"] = check_input_path(self.io_dict["in"]["input_ref_path"], "input_ref_path", True, out_log, self.__class__.__name__) 

133 

134 # Check output(s) 

135 self.io_dict["out"]["output_log_path"] = check_output_path(self.io_dict["out"]["output_log_path"], "output_log_path", False, out_log, self.__class__.__name__) 

136 self.io_dict["out"]["output_traj_path"] = check_output_path(self.io_dict["out"]["output_traj_path"], "output_traj_path", False, out_log, self.__class__.__name__) 

137 self.io_dict["out"]["output_rst_path"] = check_output_path(self.io_dict["out"]["output_rst_path"], "output_rst_path", False, out_log, self.__class__.__name__) 

138 self.io_dict["out"]["output_cpout_path"] = check_output_path(self.io_dict["out"]["output_cpout_path"], "output_cpout_path", True, out_log, self.__class__.__name__) 

139 self.io_dict["out"]["output_cprst_path"] = check_output_path(self.io_dict["out"]["output_cprst_path"], "output_cprst_path", True, out_log, self.__class__.__name__) 

140 self.io_dict["out"]["output_mdinfo_path"] = check_output_path(self.io_dict["out"]["output_mdinfo_path"], "output_mdinfo_path", True, out_log, self.__class__.__name__) 

141 

142 def create_mdin(self, path: Optional[str] = None) -> str: 

143 """Creates an AMBER MD configuration file (mdin) using the properties file settings""" 

144 mdin_list = [] 

145 mdin_firstPart = [] 

146 mdin_middlePart = [] 

147 mdin_lastPart = [] 

148 

149 self.output_mdin_path = path 

150 

151 if self.io_dict['in']['input_mdin_path']: 

152 # MDIN parameters read from an input mdin file 

153 if (not self.direct_mdin): 

154 mdin_firstPart.append("Mdin read from input file: " + self.stage_io_dict['in']['input_mdin_path']) 

155 mdin_firstPart.append("and modified by the biobb_amber module from the BioBB library ") 

156 with open(self.stage_io_dict['in']['input_mdin_path']) as input_params: 

157 firstPart = True 

158 secondPart = False 

159 for line in input_params: 

160 if '=' in line and not secondPart: 

161 firstPart = False 

162 mdin_middlePart.append(line.rstrip()) 

163 else: 

164 if (firstPart): 

165 mdin_firstPart.append(line.rstrip()) 

166 elif (secondPart): 

167 mdin_lastPart.append(line.rstrip()) 

168 else: 

169 secondPart = True 

170 mdin_lastPart.append(line.rstrip()) 

171 

172 for line in mdin_middlePart: 

173 if ('!' in line or '#' in line) and not ('!@' in line or '!:' in line): 

174 # Parsing lines with comments (#,!), e.g. : 

175 # ntc=2, ntf=2, ! SHAKE, constrain lenghts of the bonds having H 

176 params = re.split('!|#', line) 

177 for param in params[0].split(','): 

178 if param.strip(): 

179 mdin_list.append(" " + param.strip() + " ! " + params[1]) 

180 elif ('@' in line or ':' in line): 

181 # Parsing masks, e.g. : 

182 # restraintmask = ":1-40@P,O5',C5',C4',C3',O3'", restraint_wt = 0.5 

183 mylist = re.findall(r'(?:[^,"]|"(?:\\.|[^"])*")+', line) 

184 [mdin_list.append(" " + i.lstrip()) for i in mylist] # type: ignore 

185 else: 

186 for param in line.split(','): 

187 if param.strip(): 

188 if not param.strip().startswith('!'): 

189 mdin_list.append(" " + param.strip()) 

190 

191 else: 

192 # MDIN parameters added by the biobb_amber module 

193 mdin_list.append("This mdin file has been created by the biobb_amber module from the BioBB library ") 

194 

195 sim_type = self.properties.get('simulation_type', 'minimization') 

196 # sim_type = self.mdin.get('simulation_type', 'minimization') 

197 minimization = (sim_type == 'minimization') 

198 min_vacuo = (sim_type == 'min_vacuo') 

199 heat = (sim_type == 'heat') 

200 nvt = (sim_type == 'nvt') 

201 npt = (sim_type == 'npt') 

202 free = (sim_type == 'free') 

203 md = (nvt or npt or free or heat) 

204 

205 mdin_list.append("Type of mdin: " + sim_type) 

206 mdin_list.append("&cntrl") 

207 

208 # Pre-configured simulation type parameters 

209 if minimization: 

210 mdin_list.append(" imin = 1 ! BioBB simulation_type minimization") 

211 if min_vacuo: 

212 mdin_list.append(" imin = 1 ! BioBB simulation_type min_vacuo") 

213 mdin_list.append(" ncyc = 250 ! BioBB simulation_type min_vacuo") 

214 mdin_list.append(" ntb = 0 ! BioBB simulation_type min_vacuo") 

215 mdin_list.append(" igb = 0 ! BioBB simulation_type min_vacuo") 

216 mdin_list.append(" cut = 12 ! BioBB simulation_type min_vacuo") 

217 if md: 

218 mdin_list.append(" imin = 0 ! BioBB simulation_type nvt|npt|free|heat") 

219 mdin_list.append(" cut = 10.0 ! BioBB simulation_type nvt|npt|free|heat") 

220 mdin_list.append(" ntr = 0 ! BioBB simulation_type nvt|npt|free|heat") 

221 mdin_list.append(" ntc = 2 ! BioBB simulation_type nvt|npt|free|heat") 

222 mdin_list.append(" ntf = 2 ! BioBB simulation_type nvt|npt|free|heat") 

223 mdin_list.append(" ntt = 3 ! BioBB simulation_type nvt|npt|free|heat") 

224 mdin_list.append(" ig = -1 ! BioBB simulation_type nvt|npt|free|heat") 

225 mdin_list.append(" ioutfm = 1 ! BioBB simulation_type nvt|npt|free|heat") 

226 mdin_list.append(" iwrap = 1 ! BioBB simulation_type nvt|npt|free|heat") 

227 mdin_list.append(" nstlim = 5000 ! BioBB simulation_type nvt|npt|free|heat") 

228 mdin_list.append(" dt = 0.002 ! BioBB simulation_type nvt|npt|free|heat") 

229 if npt: 

230 mdin_list.append(" irest = 1 ! BioBB simulation_type npt") 

231 mdin_list.append(" gamma_ln = 5.0 ! BioBB simulation_type npt") 

232 mdin_list.append(" pres0 = 1.0 ! BioBB simulation_type npt") 

233 mdin_list.append(" ntp = 1 ! BioBB simulation_type npt") 

234 mdin_list.append(" taup = 2.0 ! BioBB simulation_type npt") 

235 mdin_list.append(" ntx = 5 ! BioBB simulation_type npt") 

236 if nvt: 

237 mdin_list.append(" irest = 1 ! BioBB simulation_type nvt") 

238 mdin_list.append(" gamma_ln = 5.0 ! BioBB simulation_type nvt") 

239 mdin_list.append(" ntb = 1 ! BioBB simulation_type nvt") 

240 mdin_list.append(" ntx = 5 ! BioBB simulation_type nvt") 

241 if heat: 

242 mdin_list.append(" tempi = 0.0 ! BioBB simulation_type heat") 

243 mdin_list.append(" temp0 = 300.0 ! BioBB simulation_type heat") 

244 mdin_list.append(" irest = 0 ! BioBB simulation_type heat") 

245 mdin_list.append(" ntb = 1 ! BioBB simulation_type heat") # periodic boundaries 

246 mdin_list.append(" gamma_ln = 1.0 ! BioBB simulation_type heat") 

247 # mdin_list.append(" nmropt = 1 ! BioBB simulation_type heat") 

248 

249 # mdin_lastPart.append("/") 

250 # mdin_lastPart.append("&wt") 

251 # mdin_lastPart.append(" TYPE = 'TEMP0' ! BioBB simulation_type heat") 

252 # mdin_lastPart.append(" ISTEP1 = 1 ! BioBB simulation_type heat") 

253 # mdin_lastPart.append(" ISTEP2 = 4000 ! BioBB simulation_type heat") 

254 # mdin_lastPart.append(" VALUE1 = 10.0 ! BioBB simulation_type heat") 

255 # mdin_lastPart.append(" VALUE2 = 300.0 ! BioBB simulation_type heat") 

256 # mdin_lastPart.append("/") 

257 # mdin_lastPart.append("&wt") 

258 # mdin_lastPart.append(" TYPE = 'END' ! BioBB simulation_type heat") 

259 # mdin_lastPart.append("/") 

260 

261 if (not self.direct_mdin): 

262 

263 # Adding the rest of parameters in the config file to the mdin file 

264 # if the parameter has already been added replace the value 

265 parameter_keys = [parameter.split('=')[0].strip() for parameter in mdin_list] 

266 for k, v in self.mdin.items(): 

267 config_parameter_key = str(k).strip() 

268 if config_parameter_key in parameter_keys: 

269 mdin_list[parameter_keys.index(config_parameter_key)] = ' ' + config_parameter_key + ' = ' + str(v) + ' ! BioBB property' 

270 else: 

271 mdin_list.append(' ' + config_parameter_key + ' = '+str(v) + ' ! BioBB property') 

272 

273 # Writing MD configuration file (mdin) 

274 with open(str(self.output_mdin_path), 'w') as mdin: 

275 # Start of file keyword(s) 

276 if mdin_firstPart: 

277 for line in mdin_firstPart: 

278 mdin.write(line + '\n') 

279 

280 # MD config parameters 

281 for line in mdin_list: 

282 mdin.write(line + '\n') 

283 

284 # End of file keyword(s) 

285 if mdin_lastPart: 

286 for line in mdin_lastPart: 

287 mdin.write(line + '\n') 

288 else: 

289 mdin.write("&end\n") 

290 else: 

291 # Copying generated output file to the final (user-given) file name 

292 shutil.copy2(self.io_dict['in']['input_mdin_path'], str(self.output_mdin_path)) 

293 

294 return str(self.output_mdin_path) 

295 

296 @launchlogger 

297 def launch(self): 

298 """Launches the execution of the BuildLinearStructure module.""" 

299 

300 # check input/output paths and parameters 

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

302 

303 # Setup Biobb 

304 if self.check_restart(): 

305 return 0 

306 self.stage_files() 

307 

308 # Creating temporary folder 

309 # tmp_folder = fu.create_unique_dir() 

310 # fu.log('Creating %s temporary folder' % tmp_folder, self.out_log) 

311 

312 # if self.io_dict['in']['input_mdin_path']: 

313 # self.output_mdin_path = self.io_dict['in']['input_mdin_path'] 

314 # else: 

315 # self.output_mdin_path = self.create_mdin(path=str(Path(tmp_folder).joinpath("sander.mdin"))) 

316 # self.output_mdin_path = self.create_mdin(path=str(Path(tmp_folder).joinpath("sander.mdin"))) 

317 

318 # Creating temporary folder & Sander configuration (instructions) file 

319 if self.container_path: 

320 # instructions_file = str(PurePath(self.stage_io_dict['unique_dir']).joinpath("leap.in")) 

321 # instructions_file_path = str(PurePath(self.container_volume_path).joinpath("leap.in")) 

322 instructions_file = self.create_mdin(path=str(Path(self.stage_io_dict['unique_dir']).joinpath("sander.mdin"))) 

323 self.output_mdin_path = str(PurePath(self.container_volume_path).joinpath(PurePath(instructions_file).name)) 

324 tmp_folder = None 

325 else: 

326 tmp_folder = fu.create_unique_dir() 

327 fu.log('Creating %s temporary folder' % tmp_folder, self.out_log) 

328 self.output_mdin_path = self.create_mdin(path=str(Path(tmp_folder).joinpath("sander.mdin"))) 

329 

330 # Command line 

331 # sander -O -i mdin/min.mdin -p $1.cpH.prmtop -c ph$i/$1.inpcrd -r ph$i/$1.min.rst7 -o ph$i/$1.min.o 

332 self.cmd = [self.binary_path, 

333 '-O', 

334 '-i', self.output_mdin_path, 

335 '-p', self.stage_io_dict['in']['input_top_path'], 

336 '-c', self.stage_io_dict['in']['input_crd_path'], 

337 '-r', self.stage_io_dict['out']['output_rst_path'], 

338 '-o', self.stage_io_dict['out']['output_log_path'], 

339 '-x', self.stage_io_dict['out']['output_traj_path'] 

340 ] 

341 

342 if self.io_dict['in']['input_ref_path']: 

343 self.cmd.append('-ref') 

344 self.cmd.append(self.stage_io_dict['in']['input_ref_path']) 

345 

346 if self.io_dict['in']['input_cpin_path']: 

347 self.cmd.append('-cpin') 

348 self.cmd.append(self.stage_io_dict['in']['input_cpin_path']) 

349 

350 if self.io_dict['out']['output_mdinfo_path']: 

351 self.cmd.append('-inf') 

352 self.cmd.append(self.stage_io_dict['out']['output_mdinfo_path']) 

353 

354 if self.io_dict['out']['output_cpout_path']: 

355 self.cmd.append('-cpout') 

356 self.cmd.append(self.stage_io_dict['out']['output_cpout_path']) 

357 

358 if self.io_dict['out']['output_cprst_path']: 

359 self.cmd.append('-cprestrt') 

360 self.cmd.append(self.stage_io_dict['out']['output_cprst_path']) 

361 

362 # general mpi properties 

363 if self.mpi_bin: 

364 mpi_cmd = [self.mpi_bin] 

365 if self.mpi_np: 

366 mpi_cmd.append('-n') 

367 mpi_cmd.append(str(self.mpi_np)) 

368 if self.mpi_flags: 

369 mpi_cmd.extend(self.mpi_flags) 

370 self.cmd = mpi_cmd + self.cmd 

371 

372 # Run Biobb block 

373 self.run_biobb() 

374 

375 # Copy files to host 

376 self.copy_to_host() 

377 

378 # remove temporary folder(s) 

379 self.tmp_files.extend(["mdinfo", str(tmp_folder)]) 

380 self.remove_tmp_files() 

381 

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

383 

384 return self.return_code 

385 

386 

387def sander_mdrun(input_top_path: str, input_crd_path: str, 

388 output_log_path: str, output_traj_path: str, output_rst_path: str, 

389 input_mdin_path: Optional[str] = None, input_cpin_path: Optional[str] = None, 

390 output_cpout_path: Optional[str] = None, output_cprst_path: Optional[str] = None, 

391 output_mdinfo_path: Optional[str] = None, input_ref_path: Optional[str] = None, 

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

393 """Create :class:`SanderMDRun <sander.sander_mdrun.SanderMDRun>`sander.sander_mdrun.SanderMDRun class and 

394 execute :meth:`launch() <sander.sander_mdrun.SanderMDRun.launch>` method""" 

395 return SanderMDRun(**dict(locals())).launch() 

396 

397 

398sander_mdrun.__doc__ = SanderMDRun.__doc__ 

399main = SanderMDRun.get_main(sander_mdrun, "Running energy minimization, molecular dynamics, and NMR refinements using sander tool from the AmberTools MD package.") 

400 

401if __name__ == '__main__': 

402 main()