Coverage for biobb_flexdyn/flexdyn/concoord_dist.py: 86%
78 statements
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-28 07:02 +0000
« prev ^ index » next coverage.py v7.14.1, created at 2026-05-28 07:02 +0000
1#!/usr/bin/env python3
3"""Module containing the concoord_dist class and the command line interface."""
4from typing import Optional
5import os
6import shutil
7from pathlib import Path, PurePath
8from biobb_common.tools import file_utils as fu
9from biobb_common.generic.biobb_object import BiobbObject
10from biobb_common.tools.file_utils import launchlogger
13class ConcoordDist(BiobbObject):
14 """
15 | biobb_flexdyn ConcoordDist
16 | Wrapper of the Dist tool from the Concoord package.
17 | Structure interpretation and bond definitions from a PDB/GRO file.
19 Args:
20 input_structure_path (str): Input structure file. File type: input. `Sample file <https://github.com/bioexcel/biobb_flexdyn/raw/master/biobb_flexdyn/test/data/flexdyn/structure.pdb>`_. Accepted formats: pdb (edam:format_1476), gro (edam:format_2033).
21 output_pdb_path (str): Output pdb file. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexdyn/raw/master/biobb_flexdyn/test/reference/flexdyn/dist.pdb>`_. Accepted formats: pdb (edam:format_1476).
22 output_gro_path (str): Output gro file. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexdyn/raw/master/biobb_flexdyn/test/reference/flexdyn/dist.gro>`_. Accepted formats: gro (edam:format_2033).
23 output_dat_path (str): Output dat with structure interpretation and bond definitions. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexdyn/raw/master/biobb_flexdyn/test/reference/flexdyn/dist.dat>`_. Accepted formats: dat (edam:format_1637), txt (edam:format_2330).
24 properties (dict - Python dictionary object containing the tool parameters, not input/output files):
25 * **binary_path** (*str*) - ("dist") Concoord dist binary path to be used.
26 * **vdw** (*int*) - (1) Select a set of Van der Waals parameters. Values: 1 (OPLS-UA -united atoms- parameters), 2 (OPLS-AA -all atoms- parameters), 3 (PROLSQ repel parameters), 4 (Yamber2 parameters), 5 (Li et al. parameters), 6 (OPLS-X parameters -recommended for NMR structure determination-).
27 * **concoord_lib_path** (*str*) - (None) Path to Concoord library files. If not specified will look for CONCOORDLIB conda environment variable.
28 * **bond_angle** (*int*) - (1) Select a set of bond/angle parameters. Values: 1 (Concoord default parameters), 2 (Engh-Huber parameters).
29 * **retain_hydrogens** (*bool*) - (False) Retain hydrogen atoms
30 * **nb_interactions** (*bool*) - (False) Try to find alternatives for non-bonded interactions (by default the native contacts will be preserved)
31 * **cutoff** (*float*) - (4.0) cut-off radius (Angstroms) for non-bonded interacting pairs (the cut-off distances are additional to the sum of VDW radii)
32 * **min_distances** (*int*) - (50) Minimum number of distances to be defined for each atom
33 * **damp** (*float*) - (1.0) Multiply each distance margin by this value
34 * **fixed_atoms** (*bool*) - (False) Interpret zero occupancy as atoms to keep fixed
35 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
36 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
37 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
38 * **container_path** (*str*) - (None) Path to the binary executable of your container.
39 * **container_image** (*str*) - ("cmip/cmip:latest") Container Image identifier.
40 * **container_volume_path** (*str*) - ("/data") Path to an internal directory in the container.
41 * **container_working_dir** (*str*) - (None) Path to the internal CWD in the container.
42 * **container_user_id** (*str*) - (None) User number id to be mapped inside the container.
43 * **container_shell_path** (*str*) - ("/bin/bash") Path to the binary executable of the container shell.
45 Examples:
46 This is a use example of how to use the building block from Python::
48 from biobb_flexdyn.flexdyn.concoord_dist import concoord_dist
49 prop = {
50 'vdw' : 4,
51 'bond_angle' : 1
52 }
53 concoord_dist( input_structure_path='/path/to/structure.pdb',
54 output_pdb_path='/path/to/output.pdb',
55 output_gro_path='/path/to/output.gro',
56 output_dat_path='/path/to/output.dat',
57 properties=prop)
59 Info:
60 * wrapped_software:
61 * name: Concoord
62 * version: >=2.1.2
63 * license: other
64 * ontology:
65 * name: EDAM
66 * schema: http://edamontology.org/EDAM.owl
68 """
70 def __init__(self, input_structure_path: str, output_pdb_path: str,
71 output_gro_path: str, output_dat_path: str, properties: Optional[dict] = None, **kwargs) -> None:
73 properties = properties or {}
75 # Call parent class constructor
76 super().__init__(properties)
77 self.locals_var_dict = locals().copy()
79 # Input/Output files
80 self.io_dict = {
81 'in': {'input_structure_path': input_structure_path},
82 'out': {'output_pdb_path': output_pdb_path,
83 'output_gro_path': output_gro_path,
84 'output_dat_path': output_dat_path}
85 }
87 # Properties specific for BB
88 self.properties = properties
89 self.binary_path = properties.get('binary_path', 'dist')
90 self.retain_hydrogens = properties.get('retain_hydrogens', False)
91 self.nb_interactions = properties.get('nb_interactions', False)
92 self.cutoff = properties.get('cutoff', 4.0)
93 self.min_distances = properties.get('min_distances', 50)
94 self.damp = properties.get('damp', 1.0)
95 self.fixed_atoms = properties.get('fixed_atoms', False)
97 self.vdw = properties.get('vdw', 1)
98 self.concoord_lib_path = properties.get('concoord_lib_path', None)
99 self.bond_angle = properties.get('bond_angle', 1)
101 # Check the properties
102 self.check_properties(properties)
103 self.check_arguments()
105 @launchlogger
106 def launch(self):
107 """Launches the execution of the FlexDyn ConcoordDist module."""
109 # Set input params
110 self.io_dict['in']['stdin_file_path'] = fu.create_stdin_file(f'{self.vdw}\n{self.bond_angle}\n')
112 # Setup Biobb
113 if self.check_restart():
114 return 0
115 self.stage_files()
117 # Copy auxiliary file (HBONDS) to the working dir
118 if self.concoord_lib_path is None:
119 concoord_lib = os.getenv("CONCOORDLIB")
120 else:
121 concoord_lib = self.concoord_lib_path
123 hbonds_file = str(concoord_lib) + "/HBONDS.DAT"
124 shutil.copy2(hbonds_file, self.stage_io_dict.get("unique_dir", ""))
126 # Determine working directory (host unique_dir or container volume path)
127 if self.container_path:
128 working_dir = self.container_volume_path if self.container_volume_path else "/data"
129 else:
130 working_dir = self.stage_io_dict.get('unique_dir', '')
132 # Command line
133 # (concoord) OROZCO67:biobb_flexdyn hospital$ dist -p biobb_flexdyn/test/data/flexdyn/structure.pdb
134 # -op dist.pdb -og dist.gro -od dist.dat
135 # Select a set of Van der Waals parameters:
136 # 1: OPLS-UA (united atoms) parameters
137 # 2: OPLS-AA (all atoms) parameters
138 # 3: PROLSQ repel parameters
139 # 4: Yamber2 parameters
140 # 5: Li et al. parameters
141 # 6: OPLS-X parameters (recommended for NMR structure determination)
142 # 2
143 # Selected parameter set 2
144 # copying /opt/anaconda3/envs/concoord/share/concoord/lib/ATOMS_oplsaa.DAT to ATOMS.DAT in current working directory
145 # copying /opt/anaconda3/envs/concoord/share/concoord/lib/MARGINS_oplsaa.DAT to MARGINS.DAT in current working directory
146 # Select a set of bond/angle parameters:
147 # 1: Concoord default parameters
148 # 2: Engh-Huber parameters
149 # 1
150 # Selected parameter set 1
151 # copying /opt/anaconda3/envs/concoord/share/concoord/lib/BONDS.DAT.noeh to BONDS.DAT in current working directory
153 self.cmd = [
154 "cd", working_dir, ";", self.binary_path,
155 "-op", PurePath(self.stage_io_dict["out"]["output_pdb_path"]).name,
156 "-og", PurePath(self.stage_io_dict["out"]["output_gro_path"]).name,
157 "-od", PurePath(self.stage_io_dict["out"]["output_dat_path"]).name
158 ]
159 # If input structure in pdb format:
160 file_extension = Path(self.stage_io_dict["in"]["input_structure_path"]).suffix
161 if file_extension == ".pdb":
162 self.cmd.append('-p')
163 self.cmd.append(PurePath(self.stage_io_dict["in"]["input_structure_path"]).name)
165 elif file_extension == ".gro":
166 self.cmd.append('-g')
167 self.cmd.append(PurePath(self.stage_io_dict["in"]["input_structure_path"]).name)
169 else:
170 fu.log("ERROR: input_structure_path ({}) must be a PDB or a GRO formatted file ({})".format(self.io_dict["in"]["input_structure_path"], file_extension), self.out_log, self.global_log)
172 if self.retain_hydrogens:
173 self.cmd.append('-r')
175 if self.nb_interactions:
176 self.cmd.append('-nb')
178 if self.fixed_atoms:
179 self.cmd.append('-q')
181 if self.cutoff:
182 self.cmd.append('-c')
183 self.cmd.append(str(self.cutoff))
185 if self.min_distances:
186 self.cmd.append('-m')
187 self.cmd.append(str(self.min_distances))
189 if self.damp:
190 self.cmd.append('-damp')
191 self.cmd.append(str(self.damp))
193 # Add stdin input file
194 self.cmd.append('<')
195 self.cmd.append(PurePath(self.stage_io_dict["in"]["stdin_file_path"]).name)
197 # Run Biobb block
198 self.run_biobb()
200 # Copy files to host
201 self.copy_to_host()
203 # remove temporary folder(s)
204 self.tmp_files.append(self.io_dict['in'].get("stdin_file_path", ""))
205 self.remove_tmp_files()
207 self.check_arguments(output_files_created=True, raise_exception=False)
209 return self.return_code
212def concoord_dist(input_structure_path: str,
213 output_pdb_path: str, output_gro_path: str, output_dat_path: str,
214 properties: Optional[dict] = None, **kwargs) -> int:
215 """Create :class:`ConcoordDist <flexdyn.concoord_dist.ConcoordDist>`flexdyn.concoord_dist.ConcoordDist class and
216 execute :meth:`launch() <flexdyn.concoord_dist.ConcoordDist.launch>` method"""
217 return ConcoordDist(**dict(locals())).launch()
220concoord_dist.__doc__ = ConcoordDist.__doc__
221main = ConcoordDist.get_main(concoord_dist, "Structure interpretation and bond definitions from a PDB/GRO file.")
223if __name__ == '__main__':
224 main()