Coverage for biobb_mem/ambertools/cpptraj_density.py: 89%

62 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-08 09:07 +0000

1#!/usr/bin/env python3 

2 

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

4from pathlib import PurePath 

5from biobb_common.generic.biobb_object import BiobbObject 

6from biobb_common.tools.file_utils import launchlogger 

7 

8 

9class CpptrajDensity(BiobbObject): 

10 """ 

11 | biobb_mem CpptrajDensity 

12 | Wrapper of the Ambertools Cpptraj module for calculating density profile along an axis of a given cpptraj compatible trajectory. 

13 | 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://raw.githubusercontent.com/Amber-MD/cpptraj/master/doc/CpptrajManual.pdf>`_. 

14 

15 Args: 

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

17 input_traj_path (str): Path to the input trajectory to be processed. File type: input. `Sample file <https://github.com/bioexcel/biobb_mem/raw/main/biobb_mem/test/data/ambertools/trajectory.xtc>`_. 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). 

18 output_cpptraj_path (str): Path to the output processed density analysis. File type: output. `Sample file <https://github.com/bioexcel/biobb_mem/raw/main/biobb_mem/test/reference/ambertools/reference/density_default.dat>`_. Accepted formats: dat (edam:format_1637), agr (edam:format_2033), xmgr (edam:format_2033), gnu (edam:format_2033). 

19 output_traj_path (str) (Optional): Path to the output processed trajectory. File type: output. `Sample file <https://github.com/bioexcel/biobb_mem/raw/main/biobb_mem/test/reference/ambertools/trajectory_out.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). 

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

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

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

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

24 * **density_type** (*str*) - ("number") Number, mass, partial charge (q) or electron (Ne - q) density. Electron density will be converted to e-/Å3 by dividing the average area spanned by the other two dimensions. 

25 * **mask** (*str*) - ("*") Arbitrary number of masks for atom selection; a dataset is created and the output will contain entries for each mask.. Default: all atoms. 

26 * **delta** (*float*) - (0.25) Resolution, i.e. determines number of slices (i.e. histogram bins). 

27 * **axis** (*str*) - ("z") Coordinate (axis) for density calculation. Vales: x, y, z. 

28 * **bintype** (*str*) - ("bincenter") Determine whether histogram bin coordinates will be based on bin center (default) or bin edges. Values: bicenter, binedge. 

29 * **restrict** (*str*) - (None) If specified, only calculate the density within a cylinder or square shape from the specified axis as defined by a distance cutoff. Values: cylinder, square. 

30 * **cutoff** (*float*) - (None) The distance cutoff for 'restrict'. Required if 'restrict' is specified. 

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

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 

36 Examples: 

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

38 

39 from biobb_mem.ambertools.cpptraj_density import cpptraj_density 

40 prop = { 

41 'density_type': 'number' 

42 } 

43 cpptraj_density(input_top_path='/path/to/myTopology.top', 

44 input_traj_path='/path/to/myTrajectory.xtc', 

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

46 properties=prop) 

47 

48 Info: 

49 * wrapped_software: 

50 * name: Ambertools Cpptraj 

51 * version: >=22.5 

52 * license: GNU 

53 * ontology: 

54 * name: EDAM 

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

56 

57 """ 

58 

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

60 output_traj_path=None, properties=None, **kwargs) -> None: 

61 properties = properties or {} 

62 

63 # Call parent class constructor 

64 super().__init__(properties) 

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

66 

67 # Input/Output files 

68 self.io_dict = { 

69 "in": {"input_top_path": input_top_path, "input_traj_path": input_traj_path}, 

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

71 } 

72 

73 # Properties specific for BB 

74 self.instructions_file = 'instructions.in' 

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

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

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

78 self.slice = f' {self.start} {self.end} {self.steps}' 

79 self.density_type = properties.get('density_type', 'number') 

80 self.mask = properties.get('mask', '*') 

81 self.delta = properties.get('delta', 0.25) 

82 self.axis = properties.get('axis', 'z') 

83 self.bintype = properties.get('bintype', 'bincenter') 

84 self.restrict = properties.get('restrict', None) 

85 self.cutoff = properties.get('cutoff', None) 

86 self.binary_path = properties.get('binary_path', 'cpptraj') 

87 self.properties = properties 

88 

89 # Check the properties 

90 self.check_properties(properties) 

91 self.check_arguments() 

92 

93 def create_instructions_file(self, stage_io_dict, out_log, err_log): 

94 """Creates an input file using the properties file settings.""" 

95 instructions_list = [] 

96 # Different path if container execution or not 

97 if self.container_path: 

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

99 else: 

100 self.instructions_file = self.create_tmp_file(self.instructions_file) 

101 instructions_list.append('parm ' + stage_io_dict["in"]["input_top_path"]) 

102 instructions_list.append('trajin ' + stage_io_dict["in"]["input_traj_path"] + self.slice) 

103 density_command = f'density {self.density_type} out {stage_io_dict["out"]["output_cpptraj_path"]} {self.mask} delta {self.delta} {self.axis} {self.bintype}' 

104 if self.restrict: 

105 density_command += f' restrict {self.restrict}' 

106 if self.cutoff: 

107 density_command += f' cutoff {self.cutoff}' 

108 instructions_list.append(density_command) 

109 

110 # trajout 

111 if ("output_traj_path" in stage_io_dict["out"]): 

112 instructions_list.append('trajout ' + stage_io_dict["out"]["output_traj_path"]) 

113 

114 # Create .in file 

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

116 for line in instructions_list: 

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

118 

119 return self.instructions_file 

120 

121 @launchlogger 

122 def launch(self) -> int: 

123 """Execute the :class:`CpptrajDensity <ambertools.cpptraj_density.CpptrajDensity>` object.""" 

124 

125 # Setup Biobb 

126 if self.check_restart(): 

127 return 0 

128 self.stage_files() 

129 

130 # create instructions file 

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

132 # create cmd and launch execution 

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

134 # Run Biobb block 

135 self.run_biobb() 

136 # Copy files to host 

137 self.copy_to_host() 

138 # remove temporary folder(s) 

139 self.remove_tmp_files() 

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

141 return self.return_code 

142 

143 

144def cpptraj_density(input_top_path: str, 

145 input_traj_path: str, 

146 output_cpptraj_path: str, 

147 output_traj_path: str = None, 

148 properties: dict = None, 

149 **kwargs) -> int: 

150 """Execute the :class:`CpptrajDensity <ambertools.cpptraj_density.CpptrajDensity>` class and 

151 execute the :meth:`launch() <ambertools.cpptraj_density.CpptrajDensity.launch>` method.""" 

152 return CpptrajDensity(**dict(locals())).launch() 

153 

154 

155cpptraj_density.__doc__ = CpptrajDensity.__doc__ 

156main = CpptrajDensity.get_main(cpptraj_density, "Calculates the density along an axis of a given cpptraj compatible trajectory.") 

157 

158if __name__ == '__main__': 

159 main()