Coverage for biobb_analysis/gromacs/gmx_energy.py: 81%

68 statements  

« prev     ^ index     » next       coverage.py v7.5.1, created at 2024-05-06 15:22 +0000

1#!/usr/bin/env python3 

2 

3"""Module containing the GMX Energy class and the command line interface.""" 

4import argparse 

5from pathlib import PurePath 

6from biobb_common.generic.biobb_object import BiobbObject 

7from biobb_common.configuration import settings 

8from biobb_common.tools import file_utils as fu 

9from biobb_common.tools.file_utils import launchlogger 

10from biobb_analysis.gromacs.common import get_binary_path, get_default_value, check_energy_path, check_out_xvg_path, get_xvg, get_terms, copy_instructions_file_to_container 

11 

12 

13class GMXEnergy(BiobbObject): 

14 """ 

15 | biobb_analysis GMXEnergy 

16 | Wrapper of the GROMACS energy module for extracting energy components from a given GROMACS energy file. 

17 | `GROMACS energy <http://manual.gromacs.org/current/onlinehelp/gmx-energy.html>`_ extracts energy components from an energy file. The user is prompted to interactively select the desired energy terms. 

18 

19 Args: 

20 input_energy_path (str): Path to the input EDR file. File type: input. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/data/gromacs/energy.edr>`_. Accepted formats: edr (edam:format_2330). 

21 output_xvg_path (str): Path to the XVG output file. File type: output. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/reference/gromacs/ref_energy.xvg>`_. Accepted formats: xvg (edam:format_2030). 

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

23 * **xvg** (*str*) - ("none") XVG plot formatting. Values: xmgrace, xmgr, none. 

24 * **terms** (*list*) - (["Potential"]) Energy terms. Values: Angle, Proper-Dih., Improper-Dih., LJ-14, Coulomb-14, LJ-\(SR\), Coulomb-\(SR\), Coul.-recip., Position-Rest., Potential, Kinetic-En., Total-Energy, Temperature, Pressure, Constr.-rmsd, Box-X, Box-Y, Box-Z, Volume, Density, pV, Enthalpy, Vir-XX, Vir-XY, Vir-XZ, Vir-YX, Vir-YY, Vir-YZ, Vir-ZX, Vir-ZY, Vir-ZZ, Pres-XX, Pres-XY, Pres-XZ, Pres-YX, Pres-YY, Pres-YZ, Pres-ZX, Pres-ZY, Pres-ZZ, #Surf*SurfTen, Box-Vel-XX, Box-Vel-YY, Box-Vel-ZZ, Mu-X, Mu-Y, Mu-Z, T-Protein, T-non-Protein, Lamb-Protein, Lamb-non-Protein. 

25 * **binary_path** (*str*) - ("gmx") Path to the GROMACS executable binary. 

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

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

28 * **container_path** (*str*) - (None) Container path definition. 

29 * **container_image** (*str*) - ('gromacs/gromacs:2022.2') Container image definition. 

30 * **container_volume_path** (*str*) - ('/tmp') Container volume path definition. 

31 * **container_working_dir** (*str*) - (None) Container working directory definition. 

32 * **container_user_id** (*str*) - (None) Container user_id definition. 

33 * **container_shell_path** (*str*) - ('/bin/bash') Path to default shell inside the container. 

34 

35 Examples: 

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

37 

38 from biobb_analysis.gromacs.gmx_energy import gmx_energy 

39 prop = { 

40 'xvg': 'xmgr', 

41 'terms': ['Potential', 'Pressure'] 

42 } 

43 gmx_energy(input_energy_path='/path/to/myEnergyFile.edr', 

44 output_xvg_path='/path/to/newXVG.xvg', 

45 properties=prop) 

46 

47 Info: 

48 * wrapped_software: 

49 * name: GROMACS energy 

50 * version: >=2019.1 

51 * license: LGPL 2.1 

52 * ontology: 

53 * name: EDAM 

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

55 

56 """ 

57 

58 def __init__(self, input_energy_path, output_xvg_path, 

59 properties=None, **kwargs) -> None: 

60 properties = properties or {} 

61 

62 # Call parent class constructor 

63 super().__init__(properties) 

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

65 

66 # Input/Output files 

67 self.io_dict = { 

68 "in": {"input_energy_path": input_energy_path}, 

69 "out": {"output_xvg_path": output_xvg_path} 

70 } 

71 

72 # Properties specific for BB 

73 self.xvg = properties.get('xvg', "none") 

74 self.terms = properties.get('terms', ["Potential"]) 

75 self.instructions_file = get_default_value('instructions_file') 

76 self.properties = properties 

77 

78 # Properties common in all GROMACS BB 

79 self.binary_path = get_binary_path(properties, 'binary_path') 

80 

81 # Check the properties 

82 self.check_properties(properties) 

83 self.check_arguments() 

84 

85 def check_data_params(self, out_log, err_log): 

86 """ Checks all the input/output paths and parameters """ 

87 self.io_dict["in"]["input_energy_path"] = check_energy_path(self.io_dict["in"]["input_energy_path"], out_log, self.__class__.__name__) 

88 self.io_dict["out"]["output_xvg_path"] = check_out_xvg_path(self.io_dict["out"]["output_xvg_path"], out_log, self.__class__.__name__) 

89 self.xvg = get_xvg(self.properties, out_log, self.__class__.__name__) 

90 self.terms = get_terms(self.properties, out_log, self.__class__.__name__) 

91 

92 def create_instructions_file(self): 

93 """Creates an input file using the properties file settings""" 

94 instructions_list = [] 

95 # different path if container execution or not 

96 if self.container_path: 

97 self.instructions_file = str(PurePath(self.container_volume_path).joinpath(self.instructions_file)) 

98 else: 

99 self.instructions_file = str(PurePath(fu.create_unique_dir()).joinpath(self.instructions_file)) 

100 # self.instructions_file = str(PurePath(fu.create_unique_dir()).joinpath(self.instructions_file)) 

101 fu.create_name(prefix=self.prefix, step=self.step, name=self.instructions_file) 

102 

103 for t in self.terms: 

104 instructions_list.append(t) 

105 

106 # create instructions file 

107 with open(self.instructions_file, 'w') as mdp: 

108 for line in instructions_list: 

109 mdp.write(line.strip() + '\n') 

110 

111 return self.instructions_file 

112 

113 @launchlogger 

114 def launch(self) -> int: 

115 """Execute the :class:`GMXEnergy <gromacs.gmx_energy.GMXEnergy>` gromacs.gmx_energy.GMXEnergy object.""" 

116 

117 # check input/output paths and parameters 

118 self.check_data_params(self.out_log, self.err_log) 

119 

120 # Setup Biobb 

121 if self.check_restart(): 

122 return 0 

123 self.stage_files() 

124 

125 # create instructions file 

126 self.create_instructions_file() 

127 

128 # if container execution, copy intructions file to container 

129 if self.container_path: 

130 copy_instructions_file_to_container(self.instructions_file, self.stage_io_dict.get("unique_dir")) 

131 

132 self.cmd = [self.binary_path, 'energy', 

133 '-f', self.stage_io_dict["in"]["input_energy_path"], 

134 '-o', self.stage_io_dict["out"]["output_xvg_path"], 

135 '-xvg', self.xvg, 

136 '<', self.instructions_file] 

137 

138 # Run Biobb block 

139 self.run_biobb() 

140 

141 # Copy files to host 

142 self.copy_to_host() 

143 

144 self.tmp_files.extend([ 

145 self.stage_io_dict.get("unique_dir"), 

146 str(PurePath(self.instructions_file).parent) 

147 ]) 

148 self.remove_tmp_files() 

149 

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

151 

152 return self.return_code 

153 

154 

155def gmx_energy(input_energy_path: str, output_xvg_path: str, properties: dict = None, **kwargs) -> int: 

156 """Execute the :class:`GMXEnergy <gromacs.gmx_energy.GMXEnergy>` class and 

157 execute the :meth:`launch() <gromacs.gmx_energy.GMXEnergy.launch>` method.""" 

158 

159 return GMXEnergy(input_energy_path=input_energy_path, 

160 output_xvg_path=output_xvg_path, 

161 properties=properties, **kwargs).launch() 

162 

163 

164def main(): 

165 """Command line execution of this building block. Please check the command line documentation.""" 

166 parser = argparse.ArgumentParser(description="Extracts energy components from a given GROMACS energy file.", formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999)) 

167 parser.add_argument('--config', required=False, help='Configuration file') 

168 

169 # Specific args of each building block 

170 required_args = parser.add_argument_group('required arguments') 

171 required_args.add_argument('--input_energy_path', required=True, help='Path to the input EDR file. Accepted formats: edr.') 

172 required_args.add_argument('--output_xvg_path', required=True, help='Path to the XVG output file. Accepted formats: xvg.') 

173 

174 args = parser.parse_args() 

175 args.config = args.config or "{}" 

176 properties = settings.ConfReader(config=args.config).get_prop_dic() 

177 

178 # Specific call of each building block 

179 gmx_energy(input_energy_path=args.input_energy_path, 

180 output_xvg_path=args.output_xvg_path, 

181 properties=properties) 

182 

183 

184if __name__ == '__main__': 

185 main()