Coverage for biobb_analysis/ambertools/cpptraj_rms.py: 83%

94 statements  

« prev     ^ index     » next       coverage.py v7.6.4, created at 2024-11-14 14:38 +0000

1#!/usr/bin/env python3 

2 

3"""Module containing the Cpptraj Rms class and the command line interface.""" 

4import argparse 

5from typing import Optional 

6from pathlib import PurePath 

7from biobb_common.generic.biobb_object import BiobbObject 

8from biobb_common.configuration import settings 

9from biobb_common.tools import file_utils as fu 

10from biobb_common.tools.file_utils import launchlogger 

11from biobb_analysis.ambertools.common import get_default_value, check_top_path, check_traj_path, check_out_path, get_binary_path, get_in_parameters, get_negative_mask, copy_instructions_file_to_container, setup_structure, get_mask, get_reference_rms 

12 

13 

14class CpptrajRms(BiobbObject): 

15 """ 

16 | biobb_analysis CpptrajRms 

17 | Wrapper of the Ambertools Cpptraj module for calculating the Root Mean Square deviation (RMSd) of a given cpptraj compatible trajectory. 

18 | Cpptraj (the successor to ptraj) is the main program in Ambertools for processing coordinate trajectories and data files. The parameter names and defaults are the same as the ones in the official `Cpptraj manual <https://amber-md.github.io/cpptraj/CPPTRAJ.xhtml>`_. 

19 

20 Args: 

21 input_top_path (str): Path to the input structure or topology file. File type: input. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/data/ambertools/cpptraj.parm.top>`_. Accepted formats: top (edam:format_3881), pdb (edam:format_1476), prmtop (edam:format_3881), parmtop (edam:format_3881), zip (edam:format_3987). 

22 input_traj_path (str): Path to the input trajectory to be processed. File type: input. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/data/ambertools/cpptraj.traj.dcd>`_. Accepted formats: mdcrd (edam:format_3878), crd (edam:format_3878), cdf (edam:format_3650), netcdf (edam:format_3650), nc (edam:format_3650), restart (edam:format_3886), ncrestart (edam:format_3886), restartnc (edam:format_3886), dcd (edam:format_3878), charmm (edam:format_3887), cor (edam:format_2033), pdb (edam:format_1476), mol2 (edam:format_3816), trr (edam:format_3910), gro (edam:format_2033), binpos (edam:format_3885), xtc (edam:format_3875), cif (edam:format_1477), arc (edam:format_2333), sqm (edam:format_2033), sdf (edam:format_3814), conflib (edam:format_2033). 

23 input_exp_path (str) (Optional): Path to the experimental reference file (required if reference = experimental). File type: input. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/data/ambertools/experimental.1e5t.pdb>`_. Accepted formats: pdb (edam:format_1476). 

24 output_cpptraj_path (str): Path to the output processed analysis. File type: output. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/reference/ambertools/ref_cpptraj.rms.first.dat>`_. Accepted formats: dat (edam:format_1637), agr (edam:format_2033), xmgr (edam:format_2033), gnu (edam:format_2033). 

25 output_traj_path (str) (Optional): Path to the output processed trajectory. File type: output. `Sample file <https://github.com/bioexcel/biobb_analysis/raw/master/biobb_analysis/test/data/ambertools/cpptraj.traj.dcd>`_. Accepted formats: mdcrd (edam:format_3878), crd (edam:format_3878), cdf (edam:format_3650), netcdf (edam:format_3650), nc (edam:format_3650), restart (edam:format_3886), ncrestart (edam:format_3886), restartnc (edam:format_3886), dcd (edam:format_3878), charmm (edam:format_3887), cor (edam:format_2033), pdb (edam:format_1476), mol2 (edam:format_3816), trr (edam:format_3910), gro (edam:format_2033), binpos (edam:format_3885), xtc (edam:format_3875), cif (edam:format_1477), arc (edam:format_2333), sqm (edam:format_2033), sdf (edam:format_3814), conflib (edam:format_2033). 

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

27 * **start** (*int*) - (1) [1~100000|1] Starting frame for slicing 

28 * **end** (*int*) - (-1) [-1~100000|1] Ending frame for slicing 

29 * **steps** (*int*) - (1) [1~100000|1] Step for slicing 

30 * **mask** (*str*) - ("all-atoms") Mask definition. Values: c-alpha (All c-alpha atoms; protein only), backbone (Backbone atoms), all-atoms (All system atoms), heavy-atoms (System heavy atoms; not hydrogen), side-chain (All not backbone atoms), solute (All system atoms except solvent atoms), ions (All ion molecules), solvent (All solvent atoms), AnyAmberFromatMask (Amber atom selection syntax like `@*`). 

31 * **reference** (*str*) - ("first") Reference definition. Values: first (Use the first trajectory frame as reference), average (Use the average of all trajectory frames as reference), experimental (Use the experimental structure as reference). 

32 * **nofit** (*bool*) - (False) Do not perform best-fit RMSD 

33 * **norotate** (*bool*) - (False) Translate but do not rotate coordinates 

34 * **nomod** (*bool*) - (False) Do not modify coordinates 

35 * **binary_path** (*str*) - ("cpptraj") Path to the cpptraj executable binary. 

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

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

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

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

40 * **container_image** (*str*) - ('afandiadib/ambertools:serial') Container image definition. 

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

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

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

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

45 

46 Examples: 

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

48 

49 from biobb_analysis.ambertools.cpptraj_rms import cpptraj_rms 

50 prop = { 

51 'start': 1, 

52 'end': -1, 

53 'steps': 1, 

54 'mask': 'c-alpha', 

55 'reference': 'first' 

56 } 

57 cpptraj_rms(input_top_path='/path/to/myTopology.top', 

58 input_traj_path='/path/to/myTrajectory.dcd', 

59 output_cpptraj_path='/path/to/newAnalysis.dat', 

60 input_exp_path= '/path/to/myExpStructure.pdb', 

61 output_traj_path='/path/to/newTrajectory.netcdf', 

62 properties=prop) 

63 

64 Info: 

65 * wrapped_software: 

66 * name: Ambertools Cpptraj 

67 * version: >=20.0 

68 * license: GNU 

69 * ontology: 

70 * name: EDAM 

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

72 

73 """ 

74 

75 def __init__(self, input_top_path, input_traj_path, output_cpptraj_path, 

76 input_exp_path=None, output_traj_path=None, properties=None, **kwargs) -> None: 

77 properties = properties or {} 

78 

79 # Call parent class constructor 

80 super().__init__(properties) 

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

82 

83 # Input/Output files 

84 self.io_dict = { 

85 "in": {"input_top_path": input_top_path, "input_traj_path": input_traj_path, "input_exp_path": input_exp_path}, 

86 "out": {"output_cpptraj_path": output_cpptraj_path, "output_traj_path": output_traj_path} 

87 } 

88 

89 # Properties specific for BB 

90 self.instructions_file = get_default_value('instructions_file') 

91 self.start = properties.get('start', 1) 

92 self.end = properties.get('end', -1) 

93 self.steps = properties.get('steps', 1) 

94 self.mask = properties.get('mask', 'all-atoms') 

95 self.reference = properties.get('reference', 'first') 

96 self.nofit = properties.get('nofit', False) 

97 self.norotate = properties.get('norotate', False) 

98 self.nomod = properties.get('nomod', False) 

99 self.properties = properties 

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

101 

102 # Check the properties 

103 self.check_properties(properties) 

104 self.check_arguments() 

105 

106 def check_data_params(self, out_log, err_log): 

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

108 self.io_dict["in"]["input_top_path"], self.input_top_path_orig = check_top_path(self.io_dict["in"]["input_top_path"], out_log, self.__class__.__name__) 

109 self.io_dict["in"]["input_traj_path"] = check_traj_path(self.io_dict["in"]["input_traj_path"], out_log, self.__class__.__name__) 

110 self.io_dict["out"]["output_cpptraj_path"] = check_out_path(self.io_dict["out"]["output_cpptraj_path"], out_log, self.__class__.__name__) 

111 if self.io_dict["out"]["output_traj_path"]: 

112 self.io_dict["out"]["output_traj_path"] = check_out_path(self.io_dict["out"]["output_traj_path"], out_log, self.__class__.__name__) 

113 self.in_parameters = {'start': self.start, 'end': self.end, 'step': self.steps, 'mask': self.mask, 'reference': self.reference} 

114 

115 def create_instructions_file(self, container_io_dict, out_log, err_log): 

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

117 instructions_list = [] 

118 # different path if container execution or not 

119 if self.container_path: 

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

121 else: 

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

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

124 

125 # parm 

126 instructions_list.append('parm ' + container_io_dict["in"]["input_top_path"]) 

127 

128 # trajin 

129 in_params = get_in_parameters(self.in_parameters, out_log) 

130 instructions_list.append('trajin ' + container_io_dict["in"]["input_traj_path"] + ' ' + in_params) 

131 

132 # Set up 

133 instructions_list += setup_structure(self) 

134 

135 # mask 

136 mask = self.in_parameters.get('mask', '') 

137 ref_mask = '' 

138 if mask: 

139 strip_mask = get_negative_mask(mask, out_log) 

140 ref_mask = get_mask(mask, out_log) 

141 instructions_list.append('strip ' + strip_mask) 

142 

143 # reference 

144 reference = self.in_parameters.get('reference', '') 

145 inp_exp_pth = None 

146 if "input_exp_path" in container_io_dict["in"]: 

147 inp_exp_pth = container_io_dict["in"]["input_exp_path"] 

148 instructions_list += get_reference_rms(reference, container_io_dict["out"]["output_cpptraj_path"], inp_exp_pth, ref_mask, True, 

149 self.__class__.__name__, out_log, self.nofit, self.norotate, self.nomod) 

150 

151 # trajout 

152 if ("output_traj_path" in container_io_dict["out"]): 

153 instructions_list.append('trajout ' + container_io_dict["out"]["output_traj_path"]) 

154 

155 # create .in file 

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

157 for line in instructions_list: 

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

159 

160 return self.instructions_file 

161 

162 @launchlogger 

163 def launch(self) -> int: 

164 """Execute the :class:`CpptrajRms <ambertools.cpptraj_rms.CpptrajRms>` ambertools.cpptraj_rms.CpptrajRms object.""" 

165 

166 # check input/output paths and parameters 

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

168 

169 # Setup Biobb 

170 if self.check_restart(): 

171 return 0 

172 self.stage_files() 

173 

174 # create instructions file 

175 self.create_instructions_file(self.stage_io_dict, self.out_log, self.err_log) 

176 

177 # if container execution, copy intructions file to container 

178 if self.container_path: 

179 copy_instructions_file_to_container(self.instructions_file, self.stage_io_dict['unique_dir']) 

180 

181 # create cmd and launch execution 

182 self.cmd = [self.binary_path, '-i', self.instructions_file] 

183 

184 # Run Biobb block 

185 self.run_biobb() 

186 

187 # Copy files to host 

188 self.copy_to_host() 

189 

190 # remove temporary folder(s) 

191 self.tmp_files.extend([ 

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

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

194 ]) 

195 self.remove_tmp_files() 

196 

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

198 

199 return self.return_code 

200 

201 

202def cpptraj_rms(input_top_path: str, input_traj_path: str, output_cpptraj_path: str, input_exp_path: Optional[str] = None, output_traj_path: Optional[str] = None, properties: Optional[dict] = None, **kwargs) -> int: 

203 """Execute the :class:`CpptrajRms <ambertools.cpptraj_rms.CpptrajRms>` class and 

204 execute the :meth:`launch() <ambertools.cpptraj_rms.CpptrajRms.launch>` method.""" 

205 

206 return CpptrajRms(input_top_path=input_top_path, 

207 input_traj_path=input_traj_path, 

208 output_cpptraj_path=output_cpptraj_path, 

209 input_exp_path=input_exp_path, 

210 output_traj_path=output_traj_path, 

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

212 

213 

214def main(): 

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

216 parser = argparse.ArgumentParser(description="Calculates the Root Mean Square deviation (RMSd) of a given cpptraj compatible trajectory.", formatter_class=lambda prog: argparse.RawTextHelpFormatter(prog, width=99999)) 

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

218 

219 # Specific args of each building block 

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

221 required_args.add_argument('--input_top_path', required=True, help='Path to the input structure or topology file. Accepted formats: top, pdb, prmtop, parmtop, zip.') 

222 required_args.add_argument('--input_traj_path', required=True, help='Path to the input trajectory to be processed. Accepted formats: crd, cdf, netcdf, restart, ncrestart, restartnc, dcd, charmm, cor, pdb, mol2, trr, gro, binpos, xtc, cif, arc, sqm, sdf, conflib.') 

223 parser.add_argument('--input_exp_path', required=False, help='Path to the experimental reference file (required if reference = experimental).') 

224 required_args.add_argument('--output_cpptraj_path', required=True, help='Path to the output processed analysis.') 

225 parser.add_argument('--output_traj_path', required=False, help='Path to the output processed trajectory.') 

226 

227 args = parser.parse_args() 

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

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

230 

231 # Specific call of each building block 

232 cpptraj_rms(input_top_path=args.input_top_path, 

233 input_traj_path=args.input_traj_path, 

234 output_cpptraj_path=args.output_cpptraj_path, 

235 input_exp_path=args.input_exp_path, 

236 output_traj_path=args.output_traj_path, 

237 properties=properties) 

238 

239 

240if __name__ == '__main__': 

241 main()