⬅ biobb_gromacs/gromacs/gmxselect.py source

1 #!/usr/bin/env python3
2  
3 """Module containing the Select class and the command line interface."""
4 import argparse
5 from typing import Optional
6 from pathlib import Path
7 from biobb_common.generic.biobb_object import BiobbObject
8 from biobb_common.configuration import settings
9 from biobb_common.tools import file_utils as fu
10 from biobb_common.tools.file_utils import launchlogger
11 from biobb_gromacs.gromacs.common import get_gromacs_version
12  
13  
14 class Gmxselect(BiobbObject):
15 """
16 | biobb_gromacs Gmxselect
17 | Wrapper of the `GROMACS select <http://manual.gromacs.org/current/onlinehelp/gmx-select.html>`_ module.
18 | The GROMACS select module writes out basic data about dynamic selections. It can be used for some simple analyses, or the output can be combined with output from other programs and/or external analysis programs to calculate more complex things.
19  
20 Args:
21 input_structure_path (str): Path to the input GRO/PDB/TPR file. File type: input. `Sample file <https://github.com/bioexcel/biobb_gromacs/raw/master/biobb_gromacs/test/data/gromacs/make_ndx.tpr>`_. Accepted formats: pdb (edam:format_1476), gro (edam:format_2033), tpr (edam:format_2333).
22 output_ndx_path (str): Path to the output index NDX file. File type: output. `Sample file <https://github.com/bioexcel/biobb_gromacs/raw/master/biobb_gromacs/test/reference/gromacs/ref_select.ndx>`_. Accepted formats: ndx (edam:format_2033).
23 input_ndx_path (str) (Optional): Path to the input index NDX file. File type: input. Accepted formats: ndx (edam:format_2033).
24 properties (dict - Python dictionary object containing the tool parameters, not input/output files):
25 * **selection** (*str*) - ("a CA C N O") Heavy atoms. Atom selection string.
26 * **append** (*bool*) - (False) Append the content of the input_ndx_path to the output_ndx_path.
27 * **binary_path** (*str*) - ("gmx") Path to the GROMACS executable binary.
28 * **gmx_lib** (*str*) - (None) Path set GROMACS GMXLIB environment variable.
29 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
30 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
31 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
32 * **container_path** (*str*) - (None) Path to the binary executable of your container.
33 * **container_image** (*str*) - ("gromacs/gromacs:latest") Container Image identifier.
34 * **container_volume_path** (*str*) - ("/data") Path to an internal directory in the container.
35 * **container_working_dir** (*str*) - (None) Path to the internal CWD in the container.
36 * **container_user_id** (*str*) - (None) User number id to be mapped inside the container.
37 * **container_shell_path** (*str*) - ("/bin/bash") Path to the binary executable of the container shell.
38  
39 Examples:
40 This is a use example of how to use the building block from Python::
41  
42 from biobb_gromacs.gromacs.gmxselect import gmxselect
43 prop = { 'selection': '"Mynewgroup" group "Protein-H" and not same residue as within 0.4 of resname ARG' }
44 gmxselect(input_structure_path='/path/to/myStructure.gro',
45 output_ndx_path='/path/to/newIndex.ndx',
46 properties=prop)
47  
48 Info:
49 * wrapped_software:
50 * name: GROMACS Gmxselect
51 * version: 2025.2
52 * license: LGPL 2.1
53 * ontology:
54 * name: EDAM
55 * schema: http://edamontology.org/EDAM.owl
56 """
57  
58 def __init__(self, input_structure_path: str, output_ndx_path: str, input_ndx_path: Optional[str] = None,
59 properties: Optional[dict] = None, **kwargs) -> None:
60 properties = properties or {}
61  
62 # Call parent class constructor
63 super().__init__(properties)
64 self.locals_var_dict = locals().copy()
65  
66 # Input/Output files
67 self.io_dict = {
68 "in": {"input_structure_path": input_structure_path, "input_ndx_path": input_ndx_path},
69 "out": {"output_ndx_path": output_ndx_path}
70 }
71  
72 # Properties specific for BB
73 self.selection = properties.get('selection', "a CA C N O")
74 self.append = properties.get('append', False)
75  
76 # Properties common in all GROMACS BB
77 self.gmx_lib = properties.get('gmx_lib', None)
78 self.binary_path = properties.get('binary_path', 'gmx')
79 self.gmx_nobackup = properties.get('gmx_nobackup', True)
80 self.gmx_nocopyright = properties.get('gmx_nocopyright', True)
81 if self.gmx_nobackup:
82 self.binary_path += ' -nobackup'
83 if self.gmx_nocopyright:
84 self.binary_path += ' -nocopyright'
85 if not self.container_path:
86 self.gmx_version = get_gromacs_version(self.binary_path)
87  
88 # Check the properties
89 self.check_properties(properties)
90 self.check_arguments()
91  
92 @launchlogger
93 def launch(self) -> int:
94 """Execute the :class:`Gmxselect <gromacs.gmxselect.Gmxselect>` object."""
95  
96 # Setup Biobb
97 if self.check_restart():
98 return 0
99 self.stage_files()
100  
101 self.cmd = [self.binary_path, 'select',
102 '-s', self.stage_io_dict["in"]["input_structure_path"],
103 '-on', self.stage_io_dict["out"]["output_ndx_path"]
104 ]
105  
106 if self.stage_io_dict["in"].get("input_ndx_path") and Path(
107 self.stage_io_dict["in"].get("input_ndx_path")).exists():
108 self.cmd.append('-n')
109 self.cmd.append(self.stage_io_dict["in"].get("input_ndx_path"))
110  
111 self.cmd.append('-select')
112 self.cmd.append("\'"+self.selection+"\'")
113  
114 if self.gmx_lib:
115 self.env_vars_dict['GMXLIB'] = self.gmx_lib
116  
117 # Run Biobb block
118 self.run_biobb()
119  
120 # Copy files to host
121 self.copy_to_host()
122  
123 if self.io_dict["in"].get("input_ndx_path"):
124 if self.append:
125 fu.log(f"Appending {self.io_dict['in'].get('input_ndx_path')} to {self.io_dict['out']['output_ndx_path']}", self.out_log, self.global_log)
126 with open(self.io_dict["out"]["output_ndx_path"], 'a') as out_ndx_file:
127 out_ndx_file.write('\n')
128 with open(self.io_dict["in"].get("input_ndx_path", '')) as in_ndx_file:
129 for line in in_ndx_file:
130 out_ndx_file.write(line)
131  
132 # Remove temporal files
133 # self.tmp_files.append(self.stage_io_dict.get("unique_dir", ''))
134 self.remove_tmp_files()
135  
136 self.check_arguments(output_files_created=True, raise_exception=False)
137 return self.return_code
138  
139  
140 def gmxselect(input_structure_path: str, output_ndx_path: str,
141 input_ndx_path: Optional[str] = None, properties: Optional[dict] = None,
142 **kwargs) -> int:
143 """Create :class:`Gmxselect <gromacs.gmxselect.Gmxselect>` class and
144 execute the :meth:`launch() <gromacs.gmxselect.Gmxselect.launch>` method."""
145 return Gmxselect(input_structure_path=input_structure_path,
146 output_ndx_path=output_ndx_path,
147 input_ndx_path=input_ndx_path,
148 properties=properties, **kwargs).launch()
149  
150  
  • E303 Too many blank lines (2)
151 gmxselect.__doc__ = Gmxselect.__doc__
152  
153  
154 def main():
155 """Command line execution of this building block. Please check the command line documentation."""
156 parser = argparse.ArgumentParser(description="Wrapper for the GROMACS select module.",
157 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999))
158 parser.add_argument('-c', '--config', required=False, help="This file can be a YAML file, JSON file or JSON string")
159  
160 # Specific args of each building block
161 required_args = parser.add_argument_group('required arguments')
162 required_args.add_argument('--input_structure_path', required=True)
163 required_args.add_argument('--output_ndx_path', required=True)
164 parser.add_argument('--input_ndx_path', required=False)
165  
166 args = parser.parse_args()
167 config = args.config if args.config else None
168 properties = settings.ConfReader(config=config).get_prop_dic()
169  
170 # Specific call of each building block
171 gmxselect(input_structure_path=args.input_structure_path,
172 output_ndx_path=args.output_ndx_path,
173 input_ndx_path=args.input_ndx_path,
174 properties=properties)
175  
176  
177 if __name__ == '__main__':
178 main()