1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 from math import cos, sin
24 from numpy import array, dot, eye, float64, zeros
25
26
27 from lib.geometry.rotations import two_vect_to_R
28 from lib.structure.angles import angles_regular, angles_uniform
29 from lib.structure.conversion import get_proton_name
30 from lib.structure.geometric import generate_vector_dist
31
32
33 -def cone_edge(mol=None, cone_obj=None, res_name='CON', res_num=None, chain_id='', apex=None, axis=None, R=None, scale=None, inc=None, distribution='uniform'):
34 """Add a residue to the atomic data representing a cone of the given angle.
35
36 A series of vectors totalling the number of increments and starting at the origin are equally spaced around the cone axis. The atoms representing neighbouring vectors will be directly bonded together. This will generate an object representing the outer edge of a cone.
37
38
39 @keyword mol: The molecule container.
40 @type mol: MolContainer instance
41 @keyword cone_obj: The cone object. This should provide the limit_check() method with determines the limits of the distribution accepting two arguments, the polar angle phi and the azimuthal angle theta, and return True if the point is in the limits or False if outside. It should also provide the phi_max() method for returning the phi value for the given theta.
42 @type cone_obj: class instance
43 @keyword res_name: The residue name.
44 @type res_name: str
45 @keyword res_num: The residue number.
46 @type res_num: int
47 @keyword chain_id: The chain identifier.
48 @type chain_id: str
49 @keyword apex: The apex of the cone.
50 @type apex: numpy array, len 3
51 @keyword axis: The central axis of the cone. If supplied, then this arg will be used to construct the rotation matrix.
52 @type axis: numpy array, len 3
53 @keyword R: A 3x3 rotation matrix. If the axis arg supplied, then this matrix will be ignored.
54 @type R: 3x3 numpy array
55 @keyword scale: The scaling factor to stretch all points by.
56 @type scale: float
57 @keyword inc: The number of increments or number of vectors used to generate the outer edge of the cone.
58 @type inc: int
59 @keyword distribution: The type of point distribution to use. This can be 'uniform' or 'regular'.
60 @type distribution: str
61 """
62
63
64 atom_num = 1
65 if len(mol.atom_num):
66 atom_num = mol.atom_num[-1]+1
67
68
69 mol.atom_add(pdb_record='HETATM', atom_num=atom_num, atom_name='APX', res_name=res_name, res_num=res_num, pos=apex, segment_id=None, element='H')
70 origin_atom = atom_num
71
72
73 if distribution == 'uniform':
74 phi, theta = angles_uniform(inc)
75 else:
76 phi, theta = angles_regular(inc)
77
78
79 if R is None:
80 R = eye(3)
81
82
83 if axis != None:
84 two_vect_to_R(array([0, 0, 1], float64), axis, R)
85
86
87 phi_max = zeros(len(theta), float64)
88 for i in range(len(theta)):
89 phi_max[i] = cone_obj.phi_max(theta[i])
90
91
92 atom_num = atom_num + 1
93 for i in range(len(theta)):
94
95 x = cos(theta[i]) * sin(phi_max[i])
96 y = sin(theta[i])* sin(phi_max[i])
97 z = cos(phi_max[i])
98 vector = array([x, y, z], float64)
99
100
101 vector = dot(R, vector)
102
103
104 atom_id = 'T' + repr(i)
105
106
107 pos = apex+vector*scale
108
109
110 mol.atom_add(pdb_record='HETATM', atom_num=atom_num, atom_name=get_proton_name(atom_num), res_name=res_name, res_num=res_num, pos=pos, segment_id=None, element='H')
111
112
113 mol.atom_connect(index1=origin_atom-1, index2=atom_num-1)
114
115
116 atom_num = atom_num + 1
117
118
119 for i in range(origin_atom, atom_num-2):
120 mol.atom_connect(index1=i, index2=i+1)
121
122
123 mol.atom_connect(index1=atom_num-2, index2=origin_atom)
124
125
126 -def cone(mol=None, cone_obj=None, start_res=1, apex=None, axis=None, R=None, inc=None, scale=30.0, distribution='regular', axis_flag=True):
127 """Create a structural representation of the given cone object.
128
129 @keyword mol: The molecule container.
130 @type mol: MolContainer instance
131 @keyword cone_obj: The cone object. This should provide the limit_check() method with determines the limits of the distribution accepting two arguments, the polar angle phi and the azimuthal angle theta, and return True if the point is in the limits or False if outside. It should also provide the theta_max() method for returning the theta value for the given phi, the phi_max() method for returning the phi value for the given theta.
132 @type cone_obj: class instance
133 @keyword start_res: The starting residue number.
134 @type start_res: str
135 @keyword apex: The apex of the cone.
136 @type apex: rank-1, 3D numpy array
137 @keyword axis: The central axis of the cone. If not supplied, the z-axis will be used.
138 @type axis: rank-1, 3D numpy array
139 @keyword R: The rotation matrix.
140 @type R: rank-2, 3D numpy array
141 @keyword inc: The increment number used to determine the number of latitude and longitude lines.
142 @type inc: int
143 @keyword scale: The scaling factor to stretch the unit cone by.
144 @type scale: float
145 @keyword distribution: The type of point distribution to use. This can be 'uniform' or 'regular'.
146 @type distribution: str
147 @keyword axis_flag: A flag which if True will create the cone's axis.
148 @type axis_flag: bool
149 """
150
151
152 if not axis:
153 axis = array([0, 0, 1], float64)
154
155
156 if R is None:
157 R = eye(3)
158
159
160 start_atom = 1
161 if hasattr(mol, 'atom_num') and len(mol.atom_num):
162 start_atom = mol.atom_num[-1]+1
163
164
165 if axis_flag:
166
167 mol.atom_add(pdb_record='HETATM', atom_num=start_atom, atom_name='R', res_name='CNC', res_num=start_res, pos=apex, element='C')
168
169
170 print("\nGenerating the axis vectors.")
171 res_num = generate_vector_residues(mol=mol, vector=dot(R, axis), atom_name='Axis', res_name_vect='CNX', res_num=start_res+1, origin=apex, scale=scale)
172
173
174 print("\nGenerating the cone outer edge.")
175 edge_start_atom = 1
176 if hasattr(mol, 'atom_num') and len(mol.atom_num):
177 edge_start_atom = mol.atom_num[-1]+1
178 cone_edge(mol=mol, cone_obj=cone_obj, res_name='CNE', res_num=start_res+2, apex=apex, R=R, scale=scale, inc=inc, distribution=distribution)
179
180
181 print("\nGenerating the cone cap.")
182 cone_start_atom = mol.atom_num[-1]+1
183 generate_vector_dist(mol=mol, res_name='CON', res_num=start_res+3, centre=apex, R=R, phi_max_fn=cone_obj.phi_max, scale=scale, inc=inc, distribution=distribution)
184