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.
- vdw_surfgen-0.1/PKG-INFO +12 -0
- vdw_surfgen-0.1/pyproject.toml +3 -0
- vdw_surfgen-0.1/setup.cfg +4 -0
- vdw_surfgen-0.1/setup.py +16 -0
- vdw_surfgen-0.1/vdw_surfgen/__init__.py +1 -0
- vdw_surfgen-0.1/vdw_surfgen/cli.py +119 -0
- vdw_surfgen-0.1/vdw_surfgen.egg-info/PKG-INFO +12 -0
- vdw_surfgen-0.1/vdw_surfgen.egg-info/SOURCES.txt +10 -0
- vdw_surfgen-0.1/vdw_surfgen.egg-info/dependency_links.txt +1 -0
- vdw_surfgen-0.1/vdw_surfgen.egg-info/entry_points.txt +2 -0
- vdw_surfgen-0.1/vdw_surfgen.egg-info/requires.txt +2 -0
- vdw_surfgen-0.1/vdw_surfgen.egg-info/top_level.txt +1 -0
vdw_surfgen-0.1/PKG-INFO
ADDED
|
@@ -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
|
vdw_surfgen-0.1/setup.py
ADDED
|
@@ -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 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
vdw_surfgen
|