Coverage for biobb_structure_utils/utils/structure_check.py: 76%
58 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 11:54 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-28 11:54 +0000
1#!/usr/bin/env python3
3"""Module containing the StructureCheck class and the command line interface."""
5import argparse
6from typing import Optional
8from biobb_common.configuration import settings
9from biobb_common.generic.biobb_object import BiobbObject
10from biobb_common.tools import file_utils as fu
11from biobb_common.tools.file_utils import launchlogger
13from biobb_structure_utils.utils.common import (
14 _from_string_to_list,
15 check_input_path,
16 check_output_path_json,
17)
20class StructureCheck(BiobbObject):
21 """
22 | biobb_structure_utils StructureCheck
23 | This class is a wrapper of the Structure Checking tool to generate summary checking results on a json file.
24 | Wrapper for the `Structure Checking <https://github.com/bioexcel/biobb_structure_checking>`_ tool to generate summary checking results on a json file from a given structure and a list of features.
26 Args:
27 input_structure_path (str): Input structure file path. File type: input. `Sample file <https://github.com/bioexcel/biobb_structure_utils/raw/master/biobb_structure_utils/test/data/utils/2vgb.pdb>`_. Accepted formats: pdb (edam:format_1476), pdbqt (edam:format_1476).
28 output_summary_path (str): Output summary checking results. File type: output. `Sample file <https://github.com/bioexcel/biobb_structure_utils/raw/master/biobb_structure_utils/test/reference/utils/summary.json>`_. Accepted formats: json (edam:format_3464).
29 properties (dic - Python dictionary object containing the tool parameters, not input/output files):
30 * **features** (*list*) - (None) Features to summarize. If None, all the features will be computed. Values: models (multiple molecules or coordinate sets in a single file), chains (multiple chains in a single file), altloc (atom alternative conformation given an alternate location indicator and occupancy), metals (metals present in the structure), ligands (heteroatoms present in the structure), chiral (to say that a structure is chiral is to say that its mirror image is not the same as it self), getss (detect SS bonds or disulfides), cistransbck (detact cis/trans backbone), backbone (detect backbone breaks), amide (detect too close amides), clashes (detect clashes).
31 * **binary_path** (*string*) - ("check_structure") path to the check_structure application
32 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
33 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
34 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
36 Examples:
37 This is a use example of how to use the building block from Python::
39 from biobb_structure_utils.utils.structure_check import structure_check
40 prop = {
41 'features': ['models', 'chains', 'ligands']
42 }
43 structure_check(input_structure_path='/path/to/myInputStr.pdb',
44 output_summary_path='/path/to/newSummary.json',
45 properties=prop)
47 Info:
48 * wrapped_software:
49 * name: Structure Checking from MDWeb
50 * version: >=3.0.3
51 * license: Apache-2.0
52 * ontology:
53 * name: EDAM
54 * schema: http://edamontology.org/EDAM.owl
56 """
58 def __init__(
59 self, input_structure_path, output_summary_path, properties=None, **kwargs
60 ) -> None:
61 properties = properties or {}
63 # Call parent class constructor
64 super().__init__(properties)
65 self.locals_var_dict = locals().copy()
67 # Input/Output files
68 self.io_dict = {
69 "in": {"input_structure_path": input_structure_path},
70 "out": {"output_summary_path": output_summary_path},
71 }
73 # Properties specific for BB
74 self.binary_path = properties.get("binary_path", "check_structure")
75 self.features = _from_string_to_list(properties.get("features", None))
76 self.properties = properties
78 # Check the properties
79 self.check_properties(properties)
80 self.check_arguments()
82 @launchlogger
83 def launch(self) -> int:
84 """Execute the :class:`StructureCheck <utils.structure_check.StructureCheck>` utils.structure_check.StructureCheck object."""
86 self.io_dict["in"]["input_structure_path"] = check_input_path(
87 self.io_dict["in"]["input_structure_path"],
88 self.out_log,
89 self.__class__.__name__,
90 )
91 self.io_dict["out"]["output_summary_path"] = check_output_path_json(
92 self.io_dict["out"]["output_summary_path"],
93 self.out_log,
94 self.__class__.__name__,
95 )
97 # Setup Biobb
98 if self.check_restart():
99 return 0
100 self.stage_files()
102 tmp_folder = None
104 if not self.features or self.features is None or self.features == "None":
105 fu.log(
106 "No features provided, all features will be computed: %s"
107 % "models, chains, altloc, metals, ligands, chiral, getss, cistransbck, backbone, amide, clashes",
108 self.out_log,
109 )
111 self.cmd = [
112 self.binary_path,
113 "-i",
114 self.stage_io_dict["in"]["input_structure_path"],
115 "--json",
116 self.stage_io_dict["out"]["output_summary_path"],
117 "--check_only",
118 "--non_interactive",
119 "checkall",
120 ]
121 else:
122 fu.log("Computing features: %s" % ", ".join(self.features), self.out_log)
124 # create temporary folder
125 tmp_folder = fu.create_unique_dir()
126 fu.log("Creating %s temporary folder" % tmp_folder, self.out_log)
128 command_list = tmp_folder + "/command_list.lst"
130 with open(command_list, "w") as f:
131 for item in self.features:
132 f.write("%s\n" % item)
134 self.cmd = [
135 self.binary_path,
136 "-i",
137 self.stage_io_dict["in"]["input_structure_path"],
138 "--json",
139 self.stage_io_dict["out"]["output_summary_path"],
140 "--check_only",
141 "--non_interactive",
142 "command_list",
143 "--list",
144 command_list,
145 ]
147 # Run Biobb block
148 self.run_biobb()
150 # Copy files to host
151 self.copy_to_host()
153 # Remove temporal files
154 self.tmp_files.extend([
155 # self.stage_io_dict.get("unique_dir", ""),
156 tmp_folder
157 ])
158 self.remove_tmp_files()
160 self.check_arguments(output_files_created=True, raise_exception=False)
162 return self.return_code
165def structure_check(
166 input_structure_path: str,
167 output_summary_path: str,
168 properties: Optional[dict] = None,
169 **kwargs,
170) -> int:
171 """Execute the :class:`StructureCheck <utils.structure_check.StructureCheck>` class and
172 execute the :meth:`launch() <utils.structure_check.StructureCheck.launch>` method."""
174 return StructureCheck(
175 input_structure_path=input_structure_path,
176 output_summary_path=output_summary_path,
177 properties=properties,
178 **kwargs,
179 ).launch()
181 structure_check.__doc__ = StructureCheck.__doc__
184def main():
185 """Command line execution of this building block. Please check the command line documentation."""
186 parser = argparse.ArgumentParser(
187 description="This class is a wrapper of the Structure Checking tool to generate summary checking results on a json file.",
188 formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999),
189 )
190 parser.add_argument(
191 "-c",
192 "--config",
193 required=False,
194 help="This file can be a YAML file, JSON file or JSON string",
195 )
197 # Specific args of each building block
198 required_args = parser.add_argument_group("required arguments")
199 required_args.add_argument(
200 "-i",
201 "--input_structure_path",
202 required=True,
203 help="Input structure file path. Accepted formats: pdb.",
204 )
205 required_args.add_argument(
206 "-o",
207 "--output_summary_path",
208 required=True,
209 help="Output summary checking results. Accepted formats: json.",
210 )
212 args = parser.parse_args()
213 config = args.config if args.config else None
214 properties = settings.ConfReader(config=config).get_prop_dic()
216 # Specific call of each building block
217 structure_check(
218 input_structure_path=args.input_structure_path,
219 output_summary_path=args.output_summary_path,
220 properties=properties,
221 )
224if __name__ == "__main__":
225 main()