Coverage for biobb_flexserv / pcasuite / pcz_bfactor.py: 95%

43 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-03-05 13:10 +0000

1#!/usr/bin/env python3 

2 

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

4from typing import Optional 

5import shutil 

6from pathlib import PurePath 

7from biobb_common.tools import file_utils as fu 

8from biobb_common.generic.biobb_object import BiobbObject 

9from biobb_common.tools.file_utils import launchlogger 

10 

11 

12class PCZbfactor(BiobbObject): 

13 """ 

14 | biobb_flexserv PCZbfactor 

15 | Extract residue bfactors x PCA mode from a compressed PCZ file. 

16 | Wrapper of the pczdump tool from the PCAsuite FlexServ module. 

17 

18 Args: 

19 input_pcz_path (str): Input compressed trajectory file. File type: input. `Sample file <https://github.com/bioexcel/biobb_flexserv/raw/master/biobb_flexserv/test/data/pcasuite/pcazip.pcz>`_. Accepted formats: pcz (edam:format_3874). 

20 output_dat_path (str): Output Bfactor x residue x PCA mode file. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexserv/raw/master/biobb_flexserv/test/reference/pcasuite/bfactors.dat>`_. Accepted formats: dat (edam:format_1637), txt (edam:format_2330), csv (edam:format_3752). 

21 output_pdb_path (str) (Optional): Output PDB with Bfactor x residue x PCA mode file. File type: output. `Sample file <https://github.com/bioexcel/biobb_flexserv/raw/master/biobb_flexserv/test/reference/pcasuite/bfactors.pdb>`_. Accepted formats: pdb (edam:format_1476). 

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

23 * **binary_path** (*str*) - ("pczdump") pczdump binary path to be used. 

24 * **eigenvector** (*int*) - (0) PCA mode (eigenvector) from which to extract bfactor values per residue (0 means average over all modes). 

25 * **pdb** (*bool*) - (False) Generate a PDB file with the computed bfactors (to be easily represented with colour scale) 

26 * **remove_tmp** (*bool*) - (True) [WF property] Remove temporal files. 

27 * **restart** (*bool*) - (False) [WF property] Do not execute if output files exist. 

28 * **sandbox_path** (*str*) - ("./") [WF property] Parent path to the sandbox directory. 

29 

30 Examples: 

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

32 

33 from biobb_flexserv.pcasuite.pcz_bfactor import pcz_bfactor 

34 prop = { 

35 'eigenvector': 1, 

36 'pdb': True 

37 } 

38 pcz_bfactor( input_pcz_path='/path/to/pcazip_input.pcz', 

39 output_dat_path='/path/to/bfactors_mode1.dat', 

40 output_pdb_path='/path/to/bfactors_mode1.pdb', 

41 properties=prop) 

42 

43 Info: 

44 * wrapped_software: 

45 * name: FlexServ PCAsuite 

46 * version: >=1.0 

47 * license: Apache-2.0 

48 * ontology: 

49 * name: EDAM 

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

51 

52 """ 

53 

54 def __init__(self, input_pcz_path: str, output_dat_path: str, 

55 output_pdb_path: str, properties: Optional[dict] = None, **kwargs) -> None: 

56 

57 properties = properties or {} 

58 

59 # Call parent class constructor 

60 super().__init__(properties) 

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

62 

63 # Input/Output files 

64 self.io_dict = { 

65 'in': {'input_pcz_path': input_pcz_path}, 

66 'out': {'output_dat_path': output_dat_path, 

67 'output_pdb_path': output_pdb_path} 

68 } 

69 

70 # Properties specific for BB 

71 self.properties = properties 

72 self.binary_path = properties.get('binary_path', 'pczdump') 

73 self.eigenvector = properties.get('eigenvector', 1) 

74 self.pdb = properties.get('pdb', False) 

75 

76 # Check the properties 

77 self.check_properties(properties) 

78 self.check_arguments() 

79 

80 @launchlogger 

81 def launch(self): 

82 """Launches the execution of the FlexServ pcz_bfactor module.""" 

83 

84 # Setup Biobb 

85 if self.check_restart(): 

86 return 0 

87 # self.stage_files() 

88 

89 # # Internal file paths 

90 # try: 

91 # # Using rel paths to shorten the amount of characters due to fortran path length limitations 

92 # input_pcz = str(Path(self.stage_io_dict["in"]["input_pcz_path"]).relative_to(Path.cwd())) 

93 # output_pdb = str(Path(self.stage_io_dict["out"]["output_pdb_path"]).relative_to(Path.cwd())) 

94 # output_dat = str(Path(self.stage_io_dict["out"]["output_dat_path"]).relative_to(Path.cwd())) 

95 # except ValueError: 

96 # # Container or remote case 

97 # input_pcz = self.stage_io_dict["in"]["input_pcz_path"] 

98 # output_pdb = self.stage_io_dict["out"]["output_pdb_path"] 

99 # output_dat = self.stage_io_dict["out"]["output_dat_path"] 

100 

101 # Manually creating a Sandbox to avoid issues with input parameters buffer overflow: 

102 # Long strings defining a file path makes Fortran or C compiled programs crash if the string 

103 # declared is shorter than the input parameter path (string) length. 

104 # Generating a temporary folder and working inside this folder (sandbox) fixes this problem. 

105 # The problem was found in Galaxy executions, launching Singularity containers (May 2023). 

106 

107 # Creating temporary folder 

108 tmp_folder = fu.create_unique_dir() 

109 fu.log('Creating %s temporary folder' % tmp_folder, self.out_log) 

110 

111 shutil.copy2(self.io_dict["in"]["input_pcz_path"], tmp_folder) 

112 

113 # Command line (1: dat file) 

114 # pczdump -i structure.ca.std.pcz --fluc=1 -o bfactor_1.dat 

115 # self.cmd = [self.binary_path, 

116 # "-i", input_pcz, 

117 # "-o", output_dat, 

118 # "--bfactor", 

119 # "--fluc={}".format(self.eigenvector) 

120 # ] 

121 

122 self.cmd = ['cd', tmp_folder, ';', 

123 self.binary_path, 

124 '-i', PurePath(self.io_dict["in"]["input_pcz_path"]).name, 

125 '-o', PurePath(self.io_dict["out"]["output_dat_path"]).name, 

126 "--bfactor", 

127 "--fluc={}".format(self.eigenvector) 

128 ] 

129 

130 # Run Biobb block 

131 self.run_biobb() 

132 

133 if self.pdb: 

134 # Command line (2: pdb file) 

135 # pczdump -i structure.ca.std.pcz --fluc=1 --pdb -o bfactor_1.pdb 

136 # self.cmd = [self.binary_path, 

137 # "-i", input_pcz, 

138 # "-o", output_pdb, 

139 # "--bfactor", 

140 # "--fluc={}".format(self.eigenvector), 

141 # "--pdb" 

142 # ] 

143 

144 self.cmd = ['cd', tmp_folder, ';', 

145 self.binary_path, 

146 '-i', PurePath(self.io_dict["in"]["input_pcz_path"]).name, 

147 '-o', PurePath(self.io_dict["out"]["output_pdb_path"]).name, 

148 "--bfactor", 

149 "--fluc={}".format(self.eigenvector), 

150 "--pdb" 

151 ] 

152 

153 # Run Biobb block 

154 self.run_biobb() 

155 

156 # Copy outputs from temporary folder to output path 

157 shutil.copy2(PurePath(tmp_folder).joinpath(PurePath(self.io_dict["out"]["output_dat_path"]).name), PurePath(self.io_dict["out"]["output_dat_path"])) 

158 

159 if self.pdb: 

160 shutil.copy2(PurePath(tmp_folder).joinpath(PurePath(self.io_dict["out"]["output_pdb_path"]).name), PurePath(self.io_dict["out"]["output_pdb_path"])) 

161 

162 # Copy files to host 

163 # self.copy_to_host() 

164 

165 # Remove temporary folder(s) 

166 self.tmp_files.append(tmp_folder) 

167 self.remove_tmp_files() 

168 

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

170 

171 return self.return_code 

172 

173 

174def pcz_bfactor(input_pcz_path: str, output_dat_path: str, output_pdb_path: str, 

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

176 """Create :class:`PCZbfactor <flexserv.pcasuite.pcz_bfactor>`flexserv.pcasuite.PCZbfactor class and 

177 execute :meth:`launch() <flexserv.pcasuite.pcz_bfactor.launch>` method""" 

178 return PCZbfactor(**dict(locals())).launch() 

179 

180 

181pcz_bfactor.__doc__ = PCZbfactor.__doc__ 

182main = PCZbfactor.get_main(pcz_bfactor, "Extract residue bfactors x PCA mode from a compressed PCZ file.") 

183 

184if __name__ == '__main__': 

185 main()