Coverage for biobb_pmx / pmxbiobb / pmxmerge_ff.py: 94%
52 statements
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-22 11:48 +0000
« prev ^ index » next coverage.py v7.13.0, created at 2025-12-22 11:48 +0000
1#!/usr/bin/env python3
3"""Module containing the PMX merge_ff class and the command line interface."""
5import glob
6import os
7import sys
8from pathlib import Path
9from typing import Optional
11from biobb_common.generic.biobb_object import BiobbObject
12from biobb_common.tools import file_utils as fu
13from biobb_common.tools.file_utils import launchlogger
14from pmx import ligand_alchemy # type: ignore
17class Pmxmerge_ff(BiobbObject):
18 """
19 | biobb_pmx Pmxmerge_ff
20 | Wrapper class for the `PMX merge_ff <https://github.com/deGrootLab/pmx>`_ module.
21 | Merge ligand topology files.
23 Args:
24 input_topology_path (str): Path to the input ligand topologies as a zip file containing a list of itp files. File type: input. `Sample file <https://github.com/bioexcel/biobb_pmx/raw/master/biobb_pmx/test/data/pmx/itps_to_merge.zip>`_. Accepted formats: zip (edam:format_3987).
25 output_topology_path (str): Path to the merged ligand topology file. File type: output. `Sample file <https://github.com/bioexcel/biobb_pmx/raw/master/biobb_pmx/test/reference/pmx/ref_mergedTopology.itp>`_. Accepted formats: itp (edam:format_3883).
27 properties (dic):
28 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
29 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
30 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
31 * **container_path** (*str*) - (None) Path to the binary executable of your container.
32 * **container_image** (*str*) - (None) Container Image identifier.
33 * **container_volume_path** (*str*) - ("/inout") Path to an internal directory in the container.
34 * **container_working_dir** (*str*) - (None) Path to the internal CWD in the container.
35 * **container_user_id** (*str*) - (None) User number id to be mapped inside the container.
36 * **container_shell_path** (*str*) - ("/bin/bash") Path to the binary executable of the container shell.
38 Examples:
39 This is a use example of how to use the building block from Python::
41 from biobb_pmx.pmxbiobb.pmxmerge_ff import pmxmerge_ff
42 prop = {
43 'remove_tmp' : True
44 }
45 pmxmerge_ff(input_topology_path='/path/to/myTopologies.zip',
46 output_topology_path='/path/to/myMergedTopology.itp',
47 properties=prop)
49 Info:
50 * wrapped_software:
51 * name: PMX merge_ff
52 * version: >=1.0.1
53 * license: GNU
54 * ontology:
55 * name: EDAM
56 * schema: http://edamontology.org/EDAM.owl
58 """
60 def __init__(
61 self,
62 input_topology_path: str,
63 output_topology_path: str,
64 properties: Optional[dict] = None,
65 **kwargs,
66 ) -> None:
67 properties = properties or {}
69 # Call parent class constructor
70 super().__init__(properties)
71 self.locals_var_dict = locals().copy()
73 # Input/Output files
74 self.io_dict = {
75 "in": {"input_topology_path": input_topology_path},
76 "out": {"output_topology_path": output_topology_path},
77 }
79 # Properties specific for BB
80 # None yet
82 # Properties common in all PMX BB
83 self.gmx_lib = properties.get("gmx_lib", None)
84 if not self.gmx_lib and os.environ.get("CONDA_PREFIX", ""):
85 python_version = f"{sys.version_info.major}.{sys.version_info.minor}"
86 self.gmx_lib = str(
87 Path(os.environ.get("CONDA_PREFIX", "")).joinpath(
88 f"lib/python{python_version}/site-packages/pmx/data/mutff/"
89 )
90 )
91 if properties.get("container_path"):
92 self.gmx_lib = str(
93 Path("/usr/local/").joinpath(
94 "lib/python3.7/site-packages/pmx/data/mutff/"
95 )
96 )
97 self.binary_path = properties.get("binary_path", "pmx")
99 # Check the properties
100 self.check_properties(properties)
101 self.check_arguments()
103 @launchlogger
104 def launch(self) -> int:
105 """Execute the :class:`Pmxmerge_ff <pmx.pmxmerge_ff.Pmxmerge_ff>` pmx.pmxmerge_ff.Pmxmerge_ff object."""
107 # Setup Biobb
108 if self.check_restart():
109 return 0
110 self.stage_files()
112 # Creating temporary folder
113 tmp_folder = fu.create_unique_dir()
114 fu.log("Creating %s temporary folder" % tmp_folder, self.out_log)
116 fu.unzip_list(
117 self.stage_io_dict["in"]["input_topology_path"],
118 tmp_folder,
119 out_log=self.out_log,
120 )
121 files = glob.glob(tmp_folder + "/*.itp")
122 ffsIn_list = []
123 for itp in files:
124 ffsIn_list.append(itp)
126 fu.log("Running merge_FF_files from pmx package...\n", self.out_log)
127 ligand_alchemy._merge_FF_files(
128 self.stage_io_dict["out"]["output_topology_path"], ffsIn=ffsIn_list
129 )
130 # ffsIn=[self.stage_io_dict["in"]["input_topology1_path"],self.stage_io_dict["in"]["input_topology2_path"]] )
132 fu.log("Exit code 0\n", self.out_log)
134 if self.gmx_lib:
135 self.env_vars_dict["GMXLIB"] = self.gmx_lib
137 # Run Biobb block
138 # self.run_biobb()
140 # Copy files to host
141 self.copy_to_host()
143 self.tmp_files.append(tmp_folder)
144 self.remove_tmp_files()
146 self.check_arguments(output_files_created=True, raise_exception=False)
147 return self.return_code
150def pmxmerge_ff(
151 input_topology_path: str,
152 output_topology_path: str,
153 properties: Optional[dict] = None,
154 **kwargs,
155) -> int:
156 """Create the :class:`Pmxmerge_ff <pmx.pmxmerge_ff.Pmxmerge_ff>` class and
157 execute the :meth:`launch() <pmx.pmxmerge_ff.Pmxmerge_ff.launch> method."""
158 return Pmxmerge_ff(**dict(locals())).launch()
161pmxmerge_ff.__doc__ = Pmxmerge_ff.__doc__
162main = Pmxmerge_ff.get_main(pmxmerge_ff, "Run PMX merge_ff module")
164if __name__ == "__main__":
165 main()