Coverage for biobb_structure_utils/utils/extract_model.py: 76%
72 statements
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-14 19:03 +0000
« prev ^ index » next coverage.py v7.5.3, created at 2024-06-14 19:03 +0000
1#!/usr/bin/env python3
3"""Module containing the ExtractModel class and the command line interface."""
4import argparse
5import shutil
6from biobb_common.configuration import settings
7from biobb_common.generic.biobb_object import BiobbObject
8from biobb_common.tools import file_utils as fu
9from biobb_common.tools.file_utils import launchlogger
10from biobb_structure_utils.utils.common import check_input_path, check_output_path
13class ExtractModel(BiobbObject):
14 """
15 | biobb_structure_utils ExtractModel
16 | This class is a wrapper of the Structure Checking tool to extract a model from a 3D structure.
17 | Wrapper for the `Structure Checking <https://github.com/bioexcel/biobb_structure_checking>`_ tool to extract a model from a 3D structure.
19 Args:
20 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/extract_model.pdb>`_. Accepted formats: pdb (edam:format_1476), pdbqt (edam:format_1476).
21 output_structure_path (str): Output structure file path. File type: output. `Sample file <https://github.com/bioexcel/biobb_structure_utils/raw/master/biobb_structure_utils/test/reference/utils/ref_extract_model.pdb>`_. Accepted formats: pdb (edam:format_1476), pdbqt (edam:format_1476).
22 properties (dic - Python dictionary object containing the tool parameters, not input/output files):
23 * **models** (*list*) - (None) List of models to be extracted from the input_structure_path file. If empty, all the models of the structure will be returned.
24 * **binary_path** (*string*) - ("check_structure") path to the check_structure application
25 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files.
26 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist.
27 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory.
29 Examples:
30 This is a use example of how to use the building block from Python::
32 from biobb_structure_utils.utils.extract_model import extract_model
33 prop = {
34 'models': [ 1, 2, 3 ]
35 }
36 extract_model(input_structure_path='/path/to/myStructure.pdb',
37 output_structure_path='/path/to/newStructure.pdb',
38 properties=prop)
40 Info:
41 * wrapped_software:
42 * name: Structure Checking from MDWeb
43 * version: >=3.0.3
44 * license: Apache-2.0
45 * ontology:
46 * name: EDAM
47 * schema: http://edamontology.org/EDAM.owl
49 """
51 def __init__(self, input_structure_path, output_structure_path, properties=None, **kwargs) -> None:
52 properties = properties or {}
54 # Call parent class constructor
55 super().__init__(properties)
56 self.locals_var_dict = locals().copy()
58 # Input/Output files
59 self.io_dict = {
60 "in": {"input_structure_path": input_structure_path},
61 "out": {"output_structure_path": output_structure_path}
62 }
64 # Properties specific for BB
65 self.binary_path = properties.get('binary_path', 'check_structure')
66 self.models = properties.get('models', [])
67 self.properties = properties
69 # Check the properties
70 self.check_properties(properties)
71 self.check_arguments()
73 @launchlogger
74 def launch(self) -> int:
75 """Execute the :class:`ExtractModel <utils.extract_model.ExtractModel>` utils.extract_model.ExtractModel object."""
77 self.io_dict['in']['input_structure_path'] = check_input_path(self.io_dict['in']['input_structure_path'],
78 self.out_log, self.__class__.__name__)
79 self.io_dict['out']['output_structure_path'] = check_output_path(self.io_dict['out']['output_structure_path'],
80 self.out_log, self.__class__.__name__)
82 # Setup Biobb
83 if self.check_restart():
84 return 0
85 self.stage_files()
87 # check if user has passed models properly
88 models = check_format_models(self.models, self.out_log)
90 if models == 'All':
91 shutil.copyfile(self.io_dict['in']['input_structure_path'], self.io_dict['out']['output_structure_path'])
93 return 0
94 else:
95 # create temporary folder
96 tmp_folder = fu.create_unique_dir()
97 fu.log('Creating %s temporary folder' % tmp_folder, self.out_log)
99 filenames = []
101 for model in models:
103 tmp_file = tmp_folder + '/model' + str(model) + '.pdb'
105 self.cmd = [self.binary_path,
106 '-i', self.stage_io_dict['in']['input_structure_path'],
107 '-o', tmp_file,
108 '--force_save',
109 'models', '--select', str(model)]
111 # Run Biobb block
112 self.run_biobb()
114 filenames.append(tmp_file)
116 # concat tmp_file and save them into output file
117 with open(self.io_dict['out']['output_structure_path'], 'w') as outfile:
118 for i, fname in enumerate(filenames):
119 with open(fname) as infile:
120 outfile.write('MODEL ' + "{:>4}".format(str(i + 1)) + '\n')
121 for line in infile:
122 if not line.startswith("END"):
123 outfile.write(line)
124 else:
125 outfile.write('ENDMDL\n')
127 # Copy files to host
128 self.copy_to_host()
130 # Remove temporal files
131 self.tmp_files.extend([self.stage_io_dict.get("unique_dir"), tmp_folder])
132 self.remove_tmp_files()
134 self.check_arguments(output_files_created=True, raise_exception=False)
136 return self.return_code
139def check_format_models(models, out_log):
140 """ Check format of models list """
141 if not models:
142 fu.log('Empty models parameter, all models will be returned.', out_log)
143 return 'All'
145 if not isinstance(models, list):
146 fu.log('Incorrect format of models parameter, all models will be returned.', out_log)
147 return 'All'
149 return models
152def extract_model(input_structure_path: str, output_structure_path: str, properties: dict = None, **kwargs) -> int:
153 """Execute the :class:`ExtractModel <utils.extract_model.ExtractModel>` class and
154 execute the :meth:`launch() <utils.extract_model.ExtractModel.launch>` method."""
156 return ExtractModel(input_structure_path=input_structure_path,
157 output_structure_path=output_structure_path,
158 properties=properties, **kwargs).launch()
161def main():
162 """Command line execution of this building block. Please check the command line documentation."""
163 parser = argparse.ArgumentParser(description="Extract a model from a 3D structure.", formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999))
164 parser.add_argument('-c', '--config', required=False, help="This file can be a YAML file, JSON file or JSON string")
166 # Specific args of each building block
167 required_args = parser.add_argument_group('required arguments')
168 required_args.add_argument('-i', '--input_structure_path', required=True, help="Input structure file path. Accepted formats: pdb.")
169 required_args.add_argument('-o', '--output_structure_path', required=True, help="Output structure file path. Accepted formats: pdb.")
171 args = parser.parse_args()
172 config = args.config if args.config else None
173 properties = settings.ConfReader(config=config).get_prop_dic()
175 # Specific call of each building block
176 extract_model(input_structure_path=args.input_structure_path,
177 output_structure_path=args.output_structure_path,
178 properties=properties)
181if __name__ == '__main__':
182 main()