Coverage for biobb_amber/leap/leap_gen_top.py: 65%
103 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-07 08:11 +0000
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-07 08:11 +0000
1#!/usr/bin/env python3
3"""Module containing the LeapGenTop class and the command line interface."""
4import argparse
5from pathlib import PurePath
6from biobb_common.generic.biobb_object import BiobbObject
7from biobb_common.configuration import settings
8from biobb_common.tools import file_utils as fu
9from biobb_common.tools.file_utils import launchlogger
10from biobb_amber.leap.common import check_input_path, check_output_path
13class LeapGenTop(BiobbObject):
14 """
15 | biobb_amber.leap.leap_gen_top LeapGenTop
16 | Wrapper of the `AmberTools (AMBER MD Package) leap tool <https://ambermd.org/AmberTools.php>`_ module.
17 | Generates a MD topology from a molecule structure using tLeap tool from the AmberTools MD package.
19 Args:
20 input_pdb_path (str): Input 3D structure PDB file. File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/leap/structure.leapin.pdb>`_. Accepted formats: pdb (edam:format_1476).
21 input_lib_path (str) (Optional): Input ligand library parameters file. File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/leap/ligand.lib>`_. Accepted formats: lib (edam:format_3889), zip (edam:format_3987).
22 input_frcmod_path (str) (Optional): Input ligand frcmod parameters file. File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/leap/ligand.frcmod>`_. Accepted formats: frcmod (edam:format_3888), zip (edam:format_3987).
23 input_params_path (str) (Optional): Additional leap parameter files to load with loadAmberParams Leap command. File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/leap/frcmod.ionsdang_spce.txt>`_. Accepted formats: in (edam:format_2330), leapin (edam:format_2330), txt (edam:format_2330), zip (edam:format_3987).
24 input_source_path (str) (Optional): Additional leap command files to load with source Leap command. File type: input. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/data/leap/leaprc.water.spce.txt>`_. Accepted formats: in (edam:format_2330), leapin (edam:format_2330), txt (edam:format_2330), zip (edam:format_3987).
25 output_pdb_path (str): Output 3D structure PDB file matching the topology file. File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/leap/structure.leap.pdb>`_. Accepted formats: pdb (edam:format_1476).
26 output_top_path (str): Output topology file (AMBER ParmTop). File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/leap/structure.leap.top>`_. Accepted formats: top (edam:format_3881), parmtop (edam:format_3881), prmtop (edam:format_3881).
27 output_crd_path (str): Output coordinates file (AMBER crd). File type: output. `Sample file <https://github.com/bioexcel/biobb_amber/raw/master/biobb_amber/test/reference/leap/structure.leap.crd>`_. Accepted formats: crd (edam:format_3878), mdcrd (edam:format_3878), inpcrd (edam:format_3878).
28 properties (dic - Python dictionary object containing the tool parameters, not input/output files):
29 * **forcefield** (*list*) - (["protein.ff14SB","DNA.bsc1","gaff"]) Forcefield to be used for the structure generation. Values: protein.ff14SB, protein.ff19SB, DNA.bsc1, DNA.OL15, RNA.OL3, gaff.
30 * **binary_path** (*str*) - ("tleap") Path to the tleap executable binary.
31 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
32 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
33 * **container_path** (*str*) - (None) Container path definition.
34 * **container_image** (*str*) - ('afandiadib/ambertools:serial') Container image definition.
35 * **container_volume_path** (*str*) - ('/tmp') Container volume path definition.
36 * **container_working_dir** (*str*) - (None) Container working directory definition.
37 * **container_user_id** (*str*) - (None) Container user_id definition.
38 * **container_shell_path** (*str*) - ('/bin/bash') Path to default shell inside the container.
40 Examples:
41 This is a use example of how to use the building block from Python::
43 from biobb_amber.leap.leap_gen_top import leap_gen_top
44 prop = {
45 'forcefield': ['protein.ff14SB']
46 }
47 leap_gen_top(input_pdb_path='/path/to/structure.pdb',
48 output_pdb_path='/path/to/newStructure.pdb',
49 output_top_path='/path/to/newTopology.top',
50 output_crd_path='/path/to/newCoordinates.crd',
51 properties=prop)
53 Info:
54 * wrapped_software:
55 * name: AmberTools tLeap
56 * version: >20.9
57 * license: LGPL 2.1
58 * ontology:
59 * name: EDAM
60 * schema: http://edamontology.org/EDAM.owl
62 """
64 def __init__(self, input_pdb_path: str, output_pdb_path: str,
65 output_top_path: str, output_crd_path: str,
66 input_lib_path: str = None, input_frcmod_path: str = None,
67 input_params_path: str = None, input_source_path: str = None,
68 properties: dict = None, **kwargs):
70 properties = properties or {}
72 # Call parent class constructor
73 super().__init__(properties)
74 self.locals_var_dict = locals().copy()
76 # Input/Output files
77 self.io_dict = {
78 'in': {'input_pdb_path': input_pdb_path,
79 'input_lib_path': input_lib_path,
80 'input_frcmod_path': input_frcmod_path,
81 'input_params_path': input_params_path,
82 'input_source_path': input_source_path},
83 'out': {'output_pdb_path': output_pdb_path,
84 'output_top_path': output_top_path,
85 'output_crd_path': output_crd_path}
86 }
88 # # Ligand Parameter lists
89 # self.ligands_lib_list = []
90 # if input_lib_path:
91 # self.ligands_lib_list.append(input_lib_path)
92 #
93 # self.ligands_frcmod_list = []
94 # if input_frcmod_path:
95 # self.ligands_frcmod_list.append(input_frcmod_path)
97 # Properties specific for BB
98 self.properties = properties
99 self.forcefield = properties.get('forcefield', ["protein.ff14SB", "DNA.bsc1", "gaff"])
100 self.binary_path = properties.get('binary_path', 'tleap')
102 # Check the properties
103 self.check_properties(properties)
104 self.check_arguments()
106 def check_data_params(self, out_log, err_log):
107 """ Checks input/output paths correctness """
109 # Check input(s)
110 self.io_dict["in"]["input_pdb_path"] = check_input_path(self.io_dict["in"]["input_pdb_path"], "input_pdb_path", False, out_log, self.__class__.__name__)
111 self.io_dict["in"]["input_lib_path"] = check_input_path(self.io_dict["in"]["input_lib_path"], "input_lib_path", True, out_log, self.__class__.__name__)
112 self.io_dict["in"]["input_frcmod_path"] = check_input_path(self.io_dict["in"]["input_frcmod_path"], "input_frcmod_path", True, out_log, self.__class__.__name__)
113 # self.io_dict["in"]["input_params_path"] = check_input_path(self.io_dict["in"]["input_params_path"], "input_params_path", True, out_log, self.__class__.__name__)
114 # self.io_dict["in"]["input_source_path"] = check_input_path(self.io_dict["in"]["input_source_path"], "input_source_path", True, out_log, self.__class__.__name__)
116 # Check output(s)
117 self.io_dict["out"]["output_pdb_path"] = check_output_path(self.io_dict["out"]["output_pdb_path"], "output_pdb_path", False, out_log, self.__class__.__name__)
118 self.io_dict["out"]["output_top_path"] = check_output_path(self.io_dict["out"]["output_top_path"], "output_top_path", False, out_log, self.__class__.__name__)
119 self.io_dict["out"]["output_crd_path"] = check_output_path(self.io_dict["out"]["output_crd_path"], "output_crd_path", False, out_log, self.__class__.__name__)
121 @launchlogger
122 def launch(self):
123 """Launches the execution of the LeapGenTop module."""
125 # check input/output paths and parameters
126 self.check_data_params(self.out_log, self.err_log)
128 # Setup Biobb
129 if self.check_restart():
130 return 0
131 self.stage_files()
133 # Creating temporary folder & Leap configuration (instructions) file
134 if self.container_path:
135 instructions_file = str(PurePath(self.stage_io_dict['unique_dir']).joinpath("leap.in"))
136 instructions_file_path = str(PurePath(self.container_volume_path).joinpath("leap.in"))
137 self.tmp_folder = None
138 else:
139 self.tmp_folder = fu.create_unique_dir()
140 instructions_file = str(PurePath(self.tmp_folder).joinpath("leap.in"))
141 fu.log('Creating %s temporary folder' % self.tmp_folder, self.out_log)
142 instructions_file_path = instructions_file
144 ligands_lib_list = []
145 if self.io_dict['in']['input_lib_path'] is not None:
146 if self.io_dict['in']['input_lib_path'].endswith('.zip'):
147 ligands_lib_list = fu.unzip_list(self.stage_io_dict['in']['input_lib_path'], dest_dir=self.tmp_folder, out_log=self.out_log)
148 else:
149 ligands_lib_list.append(self.stage_io_dict['in']['input_lib_path'])
151 ligands_frcmod_list = []
152 if self.io_dict['in']['input_frcmod_path'] is not None:
153 if self.io_dict['in']['input_frcmod_path'].endswith('.zip'):
154 ligands_frcmod_list = fu.unzip_list(self.stage_io_dict['in']['input_frcmod_path'], dest_dir=self.tmp_folder, out_log=self.out_log)
155 else:
156 ligands_frcmod_list.append(self.stage_io_dict['in']['input_frcmod_path'])
158 amber_params_list = []
159 if self.io_dict['in']['input_params_path'] is not None:
160 if self.io_dict['in']['input_params_path'].endswith('.zip'):
161 amber_params_list = fu.unzip_list(self.stage_io_dict['in']['input_params_path'], dest_dir=self.tmp_folder, out_log=self.out_log)
162 else:
163 amber_params_list.append(self.stage_io_dict['in']['input_params_path'])
165 leap_source_list = []
166 if self.io_dict['in']['input_source_path'] is not None:
167 if self.io_dict['in']['input_source_path'].endswith('.zip'):
168 leap_source_list = fu.unzip_list(self.stage_io_dict['in']['input_source_path'], dest_dir=self.tmp_folder, out_log=self.out_log)
169 else:
170 leap_source_list.append(self.stage_io_dict['in']['input_source_path'])
172 with open(instructions_file, 'w') as leapin:
173 # Forcefields loaded by default:
174 # Protein: ff14SB (PARM99 + frcmod.ff99SB + frcmod.parmbsc0 + OL3 for RNA)
175 # leapin.write("source leaprc.protein.ff14SB \n")
176 # DNA: parmBSC1 (ParmBSC1 (ff99 + bsc0 + bsc1) for DNA. Ivani et al. Nature Methods 13: 55, 2016)
177 # leapin.write("source leaprc.DNA.bsc1 \n")
178 # Ligands: GAFF (General Amber Force field, J. Comput. Chem. 2004 Jul 15;25(9):1157-74)
179 # leapin.write("source leaprc.gaff \n")
181 # Forcefields loaded from input forcefield property
182 for t in self.forcefield:
183 leapin.write("source leaprc.{}\n".format(t))
185 # Additional Leap commands
186 for leap_commands in leap_source_list:
187 leapin.write("source " + leap_commands + "\n")
189 # Additional Amber parameters
190 for amber_params in amber_params_list:
191 leapin.write("loadamberparams " + amber_params + "\n")
193 # Ions libraries
194 leapin.write("loadOff atomic_ions.lib \n")
196 # Ligand(s) libraries (if any)
197 for amber_lib in ligands_lib_list:
198 leapin.write("loadOff " + amber_lib + "\n")
199 for amber_frcmod in ligands_frcmod_list:
200 leapin.write("loadamberparams " + amber_frcmod + "\n")
202 # Loading PDB file
203 leapin.write("mol = loadpdb " + self.stage_io_dict['in']['input_pdb_path'] + " \n")
205 # Saving output PDB file, coordinates and topology
206 leapin.write("savepdb mol " + self.stage_io_dict['out']['output_pdb_path'] + " \n")
207 leapin.write("saveAmberParm mol " + self.stage_io_dict['out']['output_top_path'] + " " + self.stage_io_dict['out']['output_crd_path'] + "\n")
208 leapin.write("quit \n")
210 # Command line
211 self.cmd = [self.binary_path,
212 '-f', instructions_file_path
213 ]
215 # Run Biobb block
216 self.run_biobb()
218 # Copy files to host
219 self.copy_to_host()
221 # remove temporary folder(s)
222 self.tmp_files.extend([
223 self.stage_io_dict.get("unique_dir"),
224 self.tmp_folder,
225 "leap.log"
226 ])
227 self.remove_tmp_files()
229 self.check_arguments(output_files_created=True, raise_exception=False)
231 return self.return_code
234def leap_gen_top(input_pdb_path: str, output_pdb_path: str,
235 output_top_path: str, output_crd_path: str,
236 input_lib_path: str = None, input_frcmod_path: str = None,
237 input_params_path: str = None, input_source_path: str = None,
238 properties: dict = None, **kwargs) -> int:
239 """Create :class:`LeapGenTop <leap.leap_gen_top.LeapGenTop>`leap.leap_gen_top.LeapGenTop class and
240 execute :meth:`launch() <leap.leap_gen_top.LeapGenTop.launch>` method"""
242 return LeapGenTop(input_pdb_path=input_pdb_path,
243 input_lib_path=input_lib_path,
244 input_frcmod_path=input_frcmod_path,
245 input_params_path=input_params_path,
246 input_source_path=input_source_path,
247 output_pdb_path=output_pdb_path,
248 output_top_path=output_top_path,
249 output_crd_path=output_crd_path,
250 properties=properties).launch()
253def main():
254 parser = argparse.ArgumentParser(description='Generating a MD topology from a molecule structure using tLeap program from AmberTools MD package.', formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999))
255 parser.add_argument('--config', required=False, help='Configuration file')
257 # Specific args
258 required_args = parser.add_argument_group('required arguments')
259 required_args.add_argument('--input_pdb_path', required=True, help='Input 3D structure PDB file. Accepted formats: pdb.')
260 required_args.add_argument('--input_lib_path', required=False, help='Input ligand library parameters file. Accepted formats: lib, zip.')
261 required_args.add_argument('--input_frcmod_path', required=False, help='Input ligand frcmod parameters file. Accepted formats: frcmod, zip.')
262 required_args.add_argument('--input_params_path', required=False, help='Additional leap parameter files to load with loadAmberParams Leap command. Accepted formats: leapin, in, txt, zip.')
263 required_args.add_argument('--input_source_path', required=False, help='Additional leap command files to load with source Leap command. Accepted formats: leapin, in, txt, zip.')
264 required_args.add_argument('--output_pdb_path', required=True, help='Output 3D structure PDB file matching the topology file. Accepted formats: pdb.')
265 required_args.add_argument('--output_top_path', required=True, help='Output topology file (AMBER ParmTop). Accepted formats: top.')
266 required_args.add_argument('--output_crd_path', required=True, help='Output coordinates file (AMBER crd). Accepted formats: crd.')
268 args = parser.parse_args()
269 config = args.config if args.config else None
270 properties = settings.ConfReader(config=config).get_prop_dic()
272 # Specific call
273 leap_gen_top(input_pdb_path=args.input_pdb_path,
274 input_lib_path=args.input_lib_path,
275 input_frcmod_path=args.input_frcmod_path,
276 input_params_path=args.input_params_path,
277 input_source_path=args.input_source_path,
278 output_pdb_path=args.output_pdb_path,
279 output_top_path=args.output_top_path,
280 output_crd_path=args.output_crd_path,
281 properties=properties)
284if __name__ == '__main__':
285 main()