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