Coverage for biobb_gromacs/gromacs/editconf.py: 87%
61 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-28 06:50 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-28 06:50 +0000
1#!/usr/bin/env python3
3"""Module containing the Editconf class and the command line interface."""
5from pathlib import PurePath
6from typing import Optional
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
12from biobb_gromacs.gromacs.common import get_gromacs_version
15class Editconf(BiobbObject):
16 """
17 | biobb_gromacs Editconf
18 | Wrapper class for the `GROMACS editconf <http://manual.gromacs.org/current/onlinehelp/gmx-editconf.html>`_ module.
19 | The GROMACS editconf converts generic structure format to .gro, .g96 or .pdb.
21 Args:
22 input_gro_path (str): Path to the input GRO file. File type: input. `Sample file <https://github.com/bioexcel/biobb_gromacs/raw/master/biobb_gromacs/test/data/gromacs/editconf.gro>`_. Accepted formats: gro (edam:format_2033), pdb (edam:format_1476).
23 output_gro_path (str): Path to the output GRO file. File type: output. `Sample file <https://github.com/bioexcel/biobb_gromacs/raw/master/biobb_gromacs/test/reference/gromacs/ref_editconf.gro>`_. Accepted formats: pdb (edam:format_1476), gro (edam:format_2033).
24 properties (dict - Python dictionary object containing the tool parameters, not input/output files):
25 * **distance_to_molecule** (*float*) - (1.0) [0~100|0.1] Distance of the box from the outermost atom in nm. ie 1.0nm = 10 Angstroms.
26 * **box_vector_lenghts** (*str*) - (None) Array of floats defining the box vector lenghts ie "0.5 0.5 0.5". If this option is used the distance_to_molecule property will be ignored.
27 * **box_type** (*str*) - ("cubic") Geometrical shape of the solvent box. Values: cubic (rectangular box with all sides equal), triclinic (triclinic box), dodecahedron (rhombic dodecahedron), octahedron (truncated octahedron).
28 * **center_molecule** (*bool*) - (True) Center molecule in the box.
29 * **gmx_lib** (*str*) - (None) Path set GROMACS GMXLIB environment variable.
30 * **binary_path** (*str*) - ("gmx") Path to the GROMACS 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 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
34 * **container_path** (*str*) - (None) Path to the binary executable of your container.
35 * **container_image** (*str*) - (None) Container Image identifier.
36 * **container_volume_path** (*str*) - ("/data") Path to an internal directory in the container.
37 * **container_working_dir** (*str*) - (None) Path to the internal CWD in the container.
38 * **container_user_id** (*str*) - (None) User number id to be mapped inside the container.
39 * **container_shell_path** (*str*) - ("/bin/bash") Path to the binary executable of the container shell.
41 Examples:
42 This is a use example of how to use the building block from Python::
44 from biobb_gromacs.gromacs.editconf import editconf
45 prop = { 'distance_to_molecule': 1.0,
46 'box_type': 'cubic'}
47 editconf(input_gro_path='/path/to/structure.gro',
48 output_gro_path='/path/to/newStructure.gro',
49 properties=prop)
51 Info:
52 * wrapped_software:
53 * name: GROMACS Solvate
54 * version: 2025.2
55 * license: LGPL 2.1
56 * ontology:
57 * name: EDAM
58 * schema: http://edamontology.org/EDAM.owl
59 """
61 def __init__(
62 self,
63 input_gro_path: str,
64 output_gro_path: str,
65 properties: Optional[dict] = None,
66 **kwargs,
67 ) -> None:
68 properties = properties or {}
70 # Call parent class constructor
71 super().__init__(properties)
72 self.locals_var_dict = locals().copy()
74 # Input/Output files
75 self.io_dict = {
76 "in": {"input_gro_path": input_gro_path},
77 "out": {"output_gro_path": output_gro_path},
78 }
80 # Properties specific for BB
81 self.distance_to_molecule = properties.get("distance_to_molecule", 1.0)
82 self.box_vector_lenghts = properties.get("box_vector_lenghts")
83 self.box_type = properties.get("box_type", "cubic")
84 self.center_molecule = properties.get("center_molecule", True)
86 # Properties common in all GROMACS BB
87 self.gmx_lib = properties.get("gmx_lib", None)
88 self.binary_path: str = properties.get("binary_path", "gmx")
89 self.gmx_nobackup = properties.get("gmx_nobackup", True)
90 self.gmx_nocopyright = properties.get("gmx_nocopyright", True)
91 if self.gmx_nobackup:
92 self.binary_path += " -nobackup"
93 if self.gmx_nocopyright:
94 self.binary_path += " -nocopyright"
95 if not self.container_path:
96 self.gmx_version = get_gromacs_version(self.binary_path)
98 # Check the properties
99 self.check_properties(properties)
100 self.check_arguments()
102 @launchlogger
103 def launch(self) -> int:
104 """Execute the :class:`Editconf <gromacs.editconf.Editconf>` object."""
106 # Setup Biobb
107 if self.check_restart():
108 return 0
109 self.stage_files()
111 if self.container_path:
112 working_dir = self.container_volume_path if self.container_volume_path else "/data"
113 else:
114 working_dir = self.stage_io_dict.get('unique_dir', '')
116 # Create command line
117 self.cmd = [
118 "cd", working_dir, ";",
119 self.binary_path,
120 "editconf",
121 "-f",
122 PurePath(self.stage_io_dict["in"]["input_gro_path"]).name,
123 "-o",
124 PurePath(self.stage_io_dict["out"]["output_gro_path"]).name,
125 "-bt",
126 self.box_type,
127 ]
129 if self.box_vector_lenghts:
130 if not isinstance(self.box_vector_lenghts, str):
131 self.box_vector_lenghts = " ".join(map(str, self.box_vector_lenghts))
132 self.cmd.append("-box")
133 self.cmd.append(self.box_vector_lenghts)
134 else:
135 self.cmd.append("-d")
136 self.cmd.append(str(self.distance_to_molecule))
137 fu.log(
138 "Distance of the box to molecule: %6.2f" % self.distance_to_molecule,
139 self.out_log,
140 self.global_log,
141 )
143 if self.center_molecule:
144 self.cmd.append("-c")
145 fu.log("Centering molecule in the box.", self.out_log, self.global_log)
147 fu.log("Box type: %s" % self.box_type, self.out_log, self.global_log)
149 if self.gmx_lib:
150 self.env_vars_dict = self.gmx_lib
152 # Run Biobb block
153 self.run_biobb()
155 # Copy files to host
156 self.copy_to_host()
158 # Remove temporal files
159 self.remove_tmp_files()
161 # self.check_arguments(output_files_created=True, raise_exception=False)
162 return self.return_code
165def editconf(
166 input_gro_path: str,
167 output_gro_path: str,
168 properties: Optional[dict] = None,
169 **kwargs,
170) -> int:
171 """Create :class:`Editconf <gromacs.editconf.Editconf>` class and
172 execute the :meth:`launch() <gromacs.editconf.Editconf.launch>` method."""
173 return Editconf(**dict(locals())).launch()
176editconf.__doc__ = Editconf.__doc__
177main = Editconf.get_main(editconf, "Wrapper of the GROMACS gmx editconf module.")
180if __name__ == "__main__":
181 main()