vdw-surfgen 0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: vdw-surfgen
3
+ Version: 0.1
4
+ Summary: Generate van der Waals surface points from XYZ molecules
5
+ Author: Stephen O. Ajagbe
6
+ Requires-Python: >=3.7
7
+ Requires-Dist: numpy
8
+ Requires-Dist: matplotlib
9
+ Dynamic: author
10
+ Dynamic: requires-dist
11
+ Dynamic: requires-python
12
+ Dynamic: summary
@@ -0,0 +1,3 @@
1
+ [build-system]
2
+ requires = ["setuptools", "wheel"]
3
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,16 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ setup(
4
+ name="vdw-surfgen",
5
+ version="0.1",
6
+ packages=find_packages(),
7
+ install_requires=["numpy", "matplotlib"],
8
+ entry_points={
9
+ "console_scripts": [
10
+ "vsg=vdw_surfgen.cli:cli_entry",
11
+ ]
12
+ },
13
+ author="Stephen O. Ajagbe",
14
+ description="Generate van der Waals surface points from XYZ molecules",
15
+ python_requires=">=3.7",
16
+ )
@@ -0,0 +1 @@
1
+ __version__ = "0.1"
@@ -0,0 +1,119 @@
1
+ import argparse
2
+ import numpy as np
3
+ import os
4
+ from pathlib import Path
5
+ import matplotlib.pyplot as plt
6
+
7
+ VDW_RADII = { # shortened for brevity
8
+ 'H': 1.20, 'C': 1.70, 'N': 1.55, 'O': 1.52, 'F': 1.47, 'P': 1.80, 'S': 1.80, 'Cl': 1.75,
9
+ 'Br': 1.85, 'I': 1.98, 'He': 1.40, 'Ne': 1.54, 'Ar': 1.88, 'Kr': 2.02, 'Xe': 2.16,
10
+ 'Li': 1.82, 'Na': 2.27, 'K': 2.75, 'Rb': 3.03, 'Cs': 3.43, 'Fr': 3.48, 'Be': 2.00,
11
+ 'Mg': 1.73, 'Ca': 2.31, 'Sr': 2.49, 'Ba': 2.68, 'Ra': 2.83, 'B': 1.92, 'Al': 1.84,
12
+ 'Si': 2.10, 'Ti': 2.15, 'Fe': 2.00, 'Zn': 2.10, 'Cu': 1.95, 'Mn': 2.05, 'Hg': 2.05,
13
+ 'Pb': 2.02, 'U': 1.86
14
+ }
15
+
16
+ def read_xyz_file(filepath):
17
+ with open(filepath) as f:
18
+ lines = f.readlines()
19
+ natoms = int(lines[0])
20
+ atom_types = []
21
+ coords = []
22
+ for line in lines[2:2 + natoms]:
23
+ parts = line.split()
24
+ atom_types.append(parts[0])
25
+ coords.append([float(x) for x in parts[1:4]])
26
+ return atom_types, np.array(coords)
27
+
28
+
29
+ def fibonacci_sphere(samples):
30
+ indices = np.arange(0, samples, dtype=float) + 0.5
31
+ phi = np.arccos(1 - 2 * indices / samples)
32
+ theta = np.pi * (1 + 5 ** 0.5) * indices
33
+ x = np.cos(theta) * np.sin(phi)
34
+ y = np.sin(theta) * np.sin(phi)
35
+ z = np.cos(phi)
36
+ return np.stack((x, y, z), axis=1)
37
+
38
+
39
+ def generate_surface(coordinates, elements, scale_factor=1.0, density=1.0):
40
+ surface_points = []
41
+ for pos, elem in zip(coordinates, elements):
42
+ r = VDW_RADII.get(elem, 1.5) * scale_factor
43
+ area = 4 * np.pi * r ** 2
44
+ n_points = max(10, int(area * density))
45
+ directions = fibonacci_sphere(n_points)
46
+ points = pos + directions * r
47
+ surface_points.append(points)
48
+ return np.concatenate(surface_points, axis=0)
49
+
50
+
51
+ def save_txt(filename, coords):
52
+ with open(filename, 'w') as f:
53
+ for p in coords:
54
+ f.write(f"{p[0]:.6f} {p[1]:.6f} {p[2]:.6f}\n")
55
+
56
+
57
+ def save_xyz(filename, coords, atom='X'):
58
+ with open(filename, 'w') as f:
59
+ f.write(f"{len(coords)}\n")
60
+ f.write("VDW surface points\n")
61
+ for p in coords:
62
+ f.write(f"{atom} {p[0]:.6f} {p[1]:.6f} {p[2]:.6f}\n")
63
+
64
+
65
+ def save_surface_figure(coords, original_coords, output_path):
66
+ fig = plt.figure(figsize=(8, 6))
67
+ ax = fig.add_subplot(projection='3d')
68
+ ax.scatter(coords[:, 0], coords[:, 1], coords[:, 2], s=1, alpha=0.5, label='VDW surface')
69
+ ax.scatter(original_coords[:, 0], original_coords[:, 1], original_coords[:, 2],
70
+ color='red', s=20, label='Atoms')
71
+ ax.set_xlabel('X')
72
+ ax.set_ylabel('Y')
73
+ ax.set_zlabel('Z')
74
+ ax.legend()
75
+ plt.tight_layout()
76
+ plt.savefig(output_path, dpi=300)
77
+ plt.close()
78
+
79
+
80
+ def main():
81
+ parser = argparse.ArgumentParser(description="Generate VDW surface points from an XYZ file.")
82
+ parser.add_argument("xyz_file", help="Path to input XYZ file")
83
+ parser.add_argument("--scale", type=float, default=1.0, help="Scale factor for VDW radii (default: 1.0)")
84
+ parser.add_argument("--density", type=float, default=1.0, help="Point density per Ų (default: 1.0)")
85
+ parser.add_argument("--save_txt", action="store_true", help="Save surface points as TXT file")
86
+ parser.add_argument("--save_xyz", action="store_true", help="Save surface points as XYZ file")
87
+ parser.add_argument("--save_img", action="store_true", help="Save 3D surface plot image")
88
+
89
+ args = parser.parse_args()
90
+ xyz_file = args.xyz_file
91
+
92
+ if not os.path.isfile(xyz_file):
93
+ print(f"File not found: {xyz_file}")
94
+ return
95
+
96
+ name = Path(xyz_file).stem
97
+ elements, coords = read_xyz_file(xyz_file)
98
+ surface = generate_surface(coords, elements, scale_factor=args.scale, density=args.density)
99
+
100
+ if args.save_txt:
101
+ save_txt(f"{name}_vdw_surface.txt", surface)
102
+ if args.save_xyz:
103
+ save_xyz(f"{name}_vdw_surface.xyz", surface)
104
+ if args.save_img:
105
+ save_surface_figure(surface, coords, f"{name}_vdw_surface.png")
106
+
107
+ print(f"Generated {len(surface)} surface points.")
108
+ if args.save_txt or args.save_xyz or args.save_img:
109
+ print("Saved outputs:")
110
+ if args.save_txt:
111
+ print(f" - {name}_vdw_surface.txt")
112
+ if args.save_xyz:
113
+ print(f" - {name}_vdw_surface.xyz")
114
+ if args.save_img:
115
+ print(f" - {name}_vdw_surface.png")
116
+
117
+
118
+ def cli_entry():
119
+ main()
@@ -0,0 +1,12 @@
1
+ Metadata-Version: 2.4
2
+ Name: vdw-surfgen
3
+ Version: 0.1
4
+ Summary: Generate van der Waals surface points from XYZ molecules
5
+ Author: Stephen O. Ajagbe
6
+ Requires-Python: >=3.7
7
+ Requires-Dist: numpy
8
+ Requires-Dist: matplotlib
9
+ Dynamic: author
10
+ Dynamic: requires-dist
11
+ Dynamic: requires-python
12
+ Dynamic: summary
@@ -0,0 +1,10 @@
1
+ pyproject.toml
2
+ setup.py
3
+ vdw_surfgen/__init__.py
4
+ vdw_surfgen/cli.py
5
+ vdw_surfgen.egg-info/PKG-INFO
6
+ vdw_surfgen.egg-info/SOURCES.txt
7
+ vdw_surfgen.egg-info/dependency_links.txt
8
+ vdw_surfgen.egg-info/entry_points.txt
9
+ vdw_surfgen.egg-info/requires.txt
10
+ vdw_surfgen.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ vsg = vdw_surfgen.cli:cli_entry
@@ -0,0 +1,2 @@
1
+ numpy
2
+ matplotlib
@@ -0,0 +1 @@
1
+ vdw_surfgen