Coverage for biobb_cmip / cmip / cmip_prepare_structure.py: 92%

49 statements  

« prev     ^ index     » next       coverage.py v7.13.0, created at 2025-12-22 12:26 +0000

1#!/usr/bin/env python3 

2 

3"""Module containing the PrepareStructure class and the command line interface.""" 

4from typing import Optional 

5import warnings 

6from pathlib import Path 

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 

10 

11# Write the CMIP PDB 

12from biobb_cmip.cmip.common import write_cmip_pdb 

13# Dani's methods using a topology and a PDB file 

14from biobb_cmip.cmip.common import get_topology_cmip_elements_canonical 

15from biobb_cmip.cmip.common import get_topology_charges 

16# JLG methods using just the PDB file 

17from biobb_cmip.cmip.common import get_pdb_charges 

18from biobb_cmip.cmip.common import get_pdb_cmip_elements_canonical 

19 

20 

21class CmipPrepareStructure(BiobbObject): 

22 """ 

23 | biobb_cmip PrepareStructure 

24 | Generate a CMIP suitable PDB input. 

25 | Generate a CMIP suitable PDB input from a common PDB file or a Topology + PDB file. 

26 

27 Args: 

28 input_pdb_path (str): Path to the input PDB file. File type: input. `Sample file <https://github.com/bioexcel/biobb_cmip/raw/master/biobb_cmip/test/data/cmip/egfr.pdb>`_. Accepted formats: pdb (edam:format_1476). 

29 input_topology_path (str) (Optional): Path to the input topology path. File type: input. `Sample file <https://github.com/bioexcel/biobb_cmip/raw/master/biobb_cmip/test/data/cmip/egfr_topology.zip>`_. Accepted formats: zip (edam:format_3987), top (edam:format_3880), psf (edam:format_3882), prmtop (edam:format_3881). 

30 output_cmip_pdb_path (str): Path to the output PDB file. File type: output. `Sample file <https://github.com/bioexcel/biobb_cmip/raw/master/biobb_cmip/test/reference/cmip/egfr_cmip.pdb>`_. Accepted formats: pdb (edam:format_1476). 

31 properties (dict - Python dictionary object containing the tool parameters, not input/output files): 

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. 

35 * **container_path** (*str*) - (None) Path to the binary executable of your container. 

36 * **container_image** (*str*) - ("cmip/cmip:latest") Container Image identifier. 

37 * **container_volume_path** (*str*) - ("/data") Path to an internal directory in the container. 

38 * **container_working_dir** (*str*) - (None) Path to the internal CWD in the container. 

39 * **container_user_id** (*str*) - (None) User number id to be mapped inside the container. 

40 * **container_shell_path** (*str*) - ("/bin/bash") Path to the binary executable of the container shell. 

41 

42 

43 Examples: 

44 This is a use example of how to use the building block from Python:: 

45 

46 from biobb_cmip.cmip.prepare_structure import prepare_structure 

47 prop = { } 

48 prepare_structure(input_pdb_path='/path/to/myStructure.pdb', 

49 output_cmip_pdb_path='/path/to/newStructure.pdb', 

50 properties=prop) 

51 

52 Info: 

53 * wrapped_software: 

54 * name: CMIP cmip 

55 * version: 2.7.0 

56 * license: Apache-2.0 

57 * ontology: 

58 * name: EDAM 

59 * schema: http://edamontology.org/EDAM.owl 

60 """ 

61 

62 def __init__(self, input_pdb_path: str, output_cmip_pdb_path: str, input_topology_path: Optional[str] = None, properties: Optional[dict] = None, **kwargs) -> None: 

63 properties = properties or {} 

64 

65 # Call parent class constructor 

66 super().__init__(properties) 

67 self.locals_var_dict = locals().copy() 

68 

69 # Input/Output files 

70 self.io_dict = { 

71 "in": {"input_pdb_path": input_pdb_path, "input_topology_path": input_topology_path}, 

72 "out": {"output_cmip_pdb_path": output_cmip_pdb_path} 

73 } 

74 

75 # Check the properties 

76 self.check_properties(properties) 

77 self.check_arguments() 

78 

79 @launchlogger 

80 def launch(self) -> int: 

81 """Execute the :class:`Cmip <cmip.cmip.PrepareStructure>` object.""" 

82 # Setup Biobb 

83 if self.check_restart(): 

84 return 0 

85 

86 # Dani's method 

87 if self.io_dict['in']['input_topology_path']: 

88 top_file = self.io_dict['in']['input_topology_path'] 

89 if self.io_dict['in']['input_topology_path'].lower().endswith(".zip"): 

90 # Unzip topology to topology_out 

91 top_file = fu.unzip_top(zip_file=self.io_dict['in']['input_topology_path'], out_log=self.out_log) 

92 top_dir = str(Path(top_file).parent) 

93 self.tmp_files.append(top_dir) 

94 

95 with warnings.catch_warnings(): 

96 warnings.filterwarnings("ignore", category=UserWarning) 

97 fu.log(f'Reading: {top_file} to extract charges', self.out_log, self.global_log) 

98 charges_list = get_topology_charges(top_file) 

99 fu.log(f'Reading: {top_file} to extract elements', self.out_log, self.global_log) 

100 elements_list = get_topology_cmip_elements_canonical(top_file) 

101 two_letter_elements = {"CL": "Cl", "NA": "Na", "ZN": "Zn", "MG": "Mg"} 

102 elements_list = [two_letter_elements.get(element, element) for element in elements_list] 

103 

104 # JLG's method 

105 else: 

106 charges_list = get_pdb_charges(self.io_dict['in']['input_pdb_path']) 

107 elements_list = get_pdb_cmip_elements_canonical(self.io_dict['in']['input_pdb_path']) 

108 

109 write_cmip_pdb(self.io_dict['in']['input_pdb_path'], 

110 self.io_dict['out']['output_cmip_pdb_path'], 

111 charges_list, 

112 elements_list) 

113 

114 ################################### 

115 

116 # remove temporary folder(s) 

117 self.remove_tmp_files() 

118 

119 self.check_arguments(output_files_created=True, raise_exception=False) 

120 

121 return 0 

122 

123 

124def cmip_prepare_structure(input_pdb_path: str, output_cmip_pdb_path: str, input_topology_path: Optional[str] = None, 

125 properties: Optional[dict] = None, **kwargs) -> int: 

126 """Create :class:`Cmip <cmip.cmip.PrepareStructure>` class and 

127 execute the :meth:`launch() <cmip.cmip.PrepareStructure.launch>` method.""" 

128 return CmipPrepareStructure(**dict(locals())).launch() 

129 

130 

131cmip_prepare_structure.__doc__ = CmipPrepareStructure.__doc__ 

132main = CmipPrepareStructure.get_main(cmip_prepare_structure, "Wrapper of the cmip prepare_structure module.") 

133 

134if __name__ == '__main__': 

135 main()