CodeEntropy 2.3.0__py3-none-any.whl → 2.4.2__py3-none-any.whl
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.
- CodeEntropy/__init__.py +1 -1
- CodeEntropy/levels/axes.py +343 -61
- CodeEntropy/levels/nodes/accumulators.py +13 -6
- CodeEntropy/levels/nodes/covariance.py +66 -10
- {codeentropy-2.3.0.dist-info → codeentropy-2.4.2.dist-info}/METADATA +8 -6
- {codeentropy-2.3.0.dist-info → codeentropy-2.4.2.dist-info}/RECORD +65 -65
- {codeentropy-2.3.0.dist-info → codeentropy-2.4.2.dist-info}/WHEEL +1 -1
- {codeentropy-2.3.0.dist-info → codeentropy-2.4.2.dist-info}/entry_points.txt +0 -0
- {codeentropy-2.3.0.dist-info → codeentropy-2.4.2.dist-info}/licenses/LICENSE +0 -0
CodeEntropy/__init__.py
CHANGED
CodeEntropy/levels/axes.py
CHANGED
|
@@ -61,13 +61,15 @@ class AxesCalculator:
|
|
|
61
61
|
self._rot_axes = None
|
|
62
62
|
self._number_of_beads = None
|
|
63
63
|
|
|
64
|
-
def get_residue_axes(
|
|
64
|
+
def get_residue_axes(
|
|
65
|
+
self, data_container, index: int, relative_index: int, residue=None
|
|
66
|
+
):
|
|
65
67
|
"""Compute residue-level translational and rotational axes.
|
|
66
68
|
|
|
67
69
|
The translational and rotational axes at the residue level.
|
|
68
70
|
|
|
69
71
|
- Identify the residue (either provided or selected by `resindex index`).
|
|
70
|
-
- Determine whether the residue is bonded to
|
|
72
|
+
- Determine whether the residue is bonded to neighbouring residues
|
|
71
73
|
(previous/next in sequence) using MDAnalysis bonded selections.
|
|
72
74
|
- If there are *no* bonds to other residues:
|
|
73
75
|
* Use a custom principal axes, from a moment-of-inertia (MOI) tensor
|
|
@@ -76,13 +78,21 @@ class AxesCalculator:
|
|
|
76
78
|
* Set translational axes equal to rotational axes (as per the original
|
|
77
79
|
code convention).
|
|
78
80
|
- If bonded to other residues:
|
|
79
|
-
*
|
|
81
|
+
* Translational axes are principal axes of data_container.
|
|
82
|
+
* Find edge heavy atoms (i.e. heavy atoms bonded to neighbour residues)
|
|
83
|
+
and find the shortest chain between them: the backbone. Edge
|
|
84
|
+
atoms + backbone COM are used to determine residue rotational axes.
|
|
85
|
+
(see get_residue_custom_axes).Compute a custom MOI, using heavy atom
|
|
86
|
+
positions and heavy atom + hydrogen masses.
|
|
80
87
|
|
|
81
88
|
Args:
|
|
82
89
|
data_container (MDAnalysis.Universe or AtomGroup):
|
|
83
90
|
Molecule and trajectory data (the fragment/molecule container).
|
|
84
91
|
index (int):
|
|
85
92
|
Residue index (resindex) within `data_container`.
|
|
93
|
+
relative_index (int):
|
|
94
|
+
Index of first residue within 'data_container'.
|
|
95
|
+
This is used to obtain index in MDA Universe for atom selections.
|
|
86
96
|
residue (MDAnalysis.AtomGroup, optional):
|
|
87
97
|
If provided, this residue selection will be used rather than
|
|
88
98
|
selecting again.
|
|
@@ -99,41 +109,75 @@ class AxesCalculator:
|
|
|
99
109
|
If the residue selection is empty.
|
|
100
110
|
"""
|
|
101
111
|
# TODO refine selection so that it will work for branched polymers
|
|
102
|
-
|
|
103
|
-
|
|
112
|
+
|
|
113
|
+
index_prev = index + relative_index - 1
|
|
114
|
+
index_next = index + relative_index + 1
|
|
104
115
|
|
|
105
116
|
if residue is None:
|
|
106
|
-
residue = data_container.select_atoms(f"resindex {index}")
|
|
117
|
+
residue = data_container.select_atoms(f"resindex {index + relative_index}")
|
|
118
|
+
# residue of interest
|
|
107
119
|
if len(residue) == 0:
|
|
108
|
-
raise ValueError(
|
|
120
|
+
raise ValueError(
|
|
121
|
+
f"Empty residue selection for resindex={index + relative_index}"
|
|
122
|
+
)
|
|
109
123
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
f"(resindex {index_prev} or
|
|
124
|
+
edge_atom_set = data_container.atoms.select_atoms(
|
|
125
|
+
f"resindex {index + relative_index} and "
|
|
126
|
+
f"(bonded resindex {index_prev} or "
|
|
127
|
+
f"resindex {index_next})"
|
|
113
128
|
)
|
|
114
129
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
uas = residue.select_atoms("mass 2 to 999")
|
|
120
|
-
ua_masses = self.get_UA_masses(residue)
|
|
130
|
+
uas = residue.select_atoms("mass 2 to 999")
|
|
131
|
+
ua_masses = self.get_UA_masses(residue)
|
|
132
|
+
|
|
133
|
+
if len(edge_atom_set) == 0:
|
|
121
134
|
moi_tensor = self.get_moment_of_inertia_tensor(
|
|
122
|
-
center_of_mass=
|
|
135
|
+
center_of_mass=np.array(residue.center_of_mass()),
|
|
123
136
|
positions=uas.positions,
|
|
124
137
|
masses=ua_masses,
|
|
125
138
|
dimensions=data_container.dimensions[:3],
|
|
126
139
|
)
|
|
127
140
|
rot_axes, moment_of_inertia = self.get_custom_principal_axes(moi_tensor)
|
|
128
141
|
trans_axes = rot_axes # per original convention
|
|
142
|
+
rot_center = np.array(residue.center_of_mass())
|
|
129
143
|
else:
|
|
130
|
-
# If bonded to other residues, use default axes and MOI.
|
|
131
144
|
make_whole(data_container.atoms)
|
|
132
145
|
trans_axes = data_container.atoms.principal_axes()
|
|
133
|
-
rot_axes, moment_of_inertia = self.get_vanilla_axes(residue)
|
|
134
|
-
center = residue.center_of_mass(unwrap=True)
|
|
135
146
|
|
|
136
|
-
|
|
147
|
+
if len(edge_atom_set) == 1:
|
|
148
|
+
if index == 0:
|
|
149
|
+
# first residue: use first heavy atom
|
|
150
|
+
edges = [residue.atoms[0], edge_atom_set[0]]
|
|
151
|
+
backbone = self.get_chain(
|
|
152
|
+
residue, residue.atoms[0], edge_atom_set[0]
|
|
153
|
+
)
|
|
154
|
+
else:
|
|
155
|
+
# last residue: last heavy atom
|
|
156
|
+
last_index = len(uas) - 1
|
|
157
|
+
last = None
|
|
158
|
+
if last_index > 0 and last is None:
|
|
159
|
+
heavy_atom = uas[last_index]
|
|
160
|
+
last = heavy_atom
|
|
161
|
+
edges = [edge_atom_set[0], last]
|
|
162
|
+
|
|
163
|
+
backbone = self.get_chain(residue, edge_atom_set[0], last)
|
|
164
|
+
else:
|
|
165
|
+
edges = [edge_atom_set[0], edge_atom_set[1]]
|
|
166
|
+
backbone = self.get_chain(residue, edge_atom_set[0], edge_atom_set[1])
|
|
167
|
+
backbone_center = np.zeros(3)
|
|
168
|
+
for heavy_atom in backbone:
|
|
169
|
+
backbone_center += heavy_atom.position
|
|
170
|
+
backbone_center = backbone_center / len(backbone)
|
|
171
|
+
rot_center, rot_axes = self.get_residue_custom_axes(edges, backbone_center)
|
|
172
|
+
|
|
173
|
+
moment_of_inertia = self.get_custom_residue_moment_of_inertia(
|
|
174
|
+
center_of_mass=rot_center,
|
|
175
|
+
positions=uas.positions,
|
|
176
|
+
masses=ua_masses,
|
|
177
|
+
custom_rot_axes=rot_axes,
|
|
178
|
+
dimensions=data_container.dimensions[:3],
|
|
179
|
+
)
|
|
180
|
+
return trans_axes, rot_axes, rot_center, moment_of_inertia
|
|
137
181
|
|
|
138
182
|
def get_residue_axes_from_topology(
|
|
139
183
|
self,
|
|
@@ -170,7 +214,6 @@ class AxesCalculator:
|
|
|
170
214
|
if box is not None
|
|
171
215
|
else np.asarray(u.dimensions[:3], dtype=float)
|
|
172
216
|
)
|
|
173
|
-
|
|
174
217
|
center = residue_atoms.center_of_mass(unwrap=True)
|
|
175
218
|
|
|
176
219
|
if not topology.has_neighbor_bonds:
|
|
@@ -193,7 +236,7 @@ class AxesCalculator:
|
|
|
193
236
|
|
|
194
237
|
return trans_axes, rot_axes, center, moment_of_inertia
|
|
195
238
|
|
|
196
|
-
def get_UA_axes(self, data_container, index: int):
|
|
239
|
+
def get_UA_axes(self, data_container, index: int, res_position):
|
|
197
240
|
"""Compute united-atom-level translational and rotational axes.
|
|
198
241
|
|
|
199
242
|
The translational and rotational axes at the united-atom level.
|
|
@@ -201,22 +244,29 @@ class AxesCalculator:
|
|
|
201
244
|
This preserves the original behaviour and its rationale:
|
|
202
245
|
|
|
203
246
|
- Translational axes:
|
|
204
|
-
Use the same
|
|
205
|
-
|
|
206
|
-
|
|
247
|
+
Use the same approach as residue level rotational.
|
|
248
|
+
Identify residue of interest and neighbours, then select
|
|
249
|
+
edge heavy atoms (i.e. heavy atoms bonded to neighbour residues).
|
|
250
|
+
If there are no bonds to neighbouring residues, use residue
|
|
251
|
+
.principal axes Otherwise, find the shortest chain between edge
|
|
252
|
+
residues: the backbone. Edge atoms + backbone COM are used to
|
|
253
|
+
determine UA translational axes (see get_residue_custom_axes)
|
|
207
254
|
|
|
208
255
|
- Rotational axes:
|
|
209
256
|
Identify heavy atoms in the residue/molecule of interest and choose
|
|
210
257
|
the `index`-th heavy atom (where index corresponds to the bead index).
|
|
211
258
|
Use bonded topology around that heavy atom to determine UA rotational
|
|
212
259
|
axes (see :meth:`get_bonded_axes`).
|
|
260
|
+
Compute a custom MOI tensor using heavy-atom coordinates but UA masses
|
|
261
|
+
(heavy + bonded H masses), then compute the principal axes from it.
|
|
213
262
|
|
|
214
263
|
Args:
|
|
215
264
|
data_container (MDAnalysis.Universe or AtomGroup):
|
|
216
265
|
Molecule and trajectory data.
|
|
217
266
|
index (int):
|
|
218
267
|
Bead index (ordinal among heavy atoms).
|
|
219
|
-
|
|
268
|
+
res_position: where the residue of interest is
|
|
269
|
+
in data_container
|
|
220
270
|
Returns:
|
|
221
271
|
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
|
|
222
272
|
- trans_axes: Translational axes (3, 3).
|
|
@@ -228,51 +278,124 @@ class AxesCalculator:
|
|
|
228
278
|
IndexError:
|
|
229
279
|
If `index` does not correspond to an existing heavy atom.
|
|
230
280
|
ValueError:
|
|
231
|
-
If
|
|
281
|
+
If axis construction fails.
|
|
232
282
|
"""
|
|
233
283
|
|
|
234
|
-
index = int(index) # bead index
|
|
235
|
-
|
|
284
|
+
index = int(index) # UA bead index
|
|
285
|
+
heavy_atoms = data_container.select_atoms("mass 2 to 999")
|
|
236
286
|
# use the same customPI trans axes as the residue level
|
|
237
|
-
heavy_atoms = data_container.select_atoms("prop mass > 1.1")
|
|
238
287
|
if len(heavy_atoms) > 1:
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
288
|
+
if len(data_container.residues) == 1:
|
|
289
|
+
# only the one residue => use principal axes
|
|
290
|
+
residue = data_container
|
|
291
|
+
trans_center = data_container.atoms.center_of_mass(unwrap=True)
|
|
292
|
+
trans_axes = data_container.atoms.principal_axes()
|
|
293
|
+
residue_heavy_atoms = heavy_atoms
|
|
294
|
+
else:
|
|
295
|
+
# residue of interest has at least one neighbour
|
|
296
|
+
if res_position == -1:
|
|
297
|
+
residue = data_container.residues[0]
|
|
298
|
+
resindex = residue.resindex
|
|
299
|
+
resindex_next = resindex + 1
|
|
300
|
+
|
|
301
|
+
second_edge = data_container.select_atoms(
|
|
302
|
+
f"resindex {resindex} and bonded resindex {resindex_next}"
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
edges = [residue.atoms[0], second_edge[0]]
|
|
306
|
+
backbone = self.get_chain(
|
|
307
|
+
residue, residue.atoms[0], second_edge.atoms[0]
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
elif res_position == 0:
|
|
311
|
+
# between 2 residues
|
|
312
|
+
residue = data_container.residues[1]
|
|
313
|
+
resindex = residue.resindex
|
|
314
|
+
resindex_next = resindex + 1
|
|
315
|
+
resindex_prev = resindex - 1
|
|
316
|
+
|
|
317
|
+
edge_set = data_container.select_atoms(
|
|
318
|
+
f"resindex {resindex} and "
|
|
319
|
+
f"(bonded resindex {resindex_prev} or "
|
|
320
|
+
f"resindex {resindex_next})"
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
edges = [edge_set[0], edge_set[1]]
|
|
324
|
+
backbone = self.get_chain(residue, edge_set[0], edge_set[1])
|
|
325
|
+
|
|
326
|
+
else:
|
|
327
|
+
# last resid
|
|
328
|
+
# always resindex 1 in data_container
|
|
329
|
+
residue = data_container.residues[1]
|
|
330
|
+
resindex = residue.resindex
|
|
331
|
+
resindex_prev = resindex - 1
|
|
332
|
+
first_edge = data_container.select_atoms(
|
|
333
|
+
f"resindex {resindex} and bonded resindex {resindex_prev}"
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
last_index = len(heavy_atoms) - 1
|
|
337
|
+
last = None
|
|
338
|
+
# look for last heavy atom
|
|
339
|
+
# with only one bond to another
|
|
340
|
+
if last_index > 0 and last is None:
|
|
341
|
+
heavy_atom = heavy_atoms[last_index]
|
|
342
|
+
last = heavy_atom
|
|
343
|
+
|
|
344
|
+
edges = [first_edge.atoms[0], last]
|
|
345
|
+
backbone = self.get_chain(residue, first_edge.atoms[0], last)
|
|
346
|
+
|
|
347
|
+
backbone_center = np.zeros(3)
|
|
348
|
+
for heavy_atom in backbone:
|
|
349
|
+
backbone_center += heavy_atom.position
|
|
350
|
+
backbone_center = backbone_center / len(backbone)
|
|
351
|
+
|
|
352
|
+
trans_center, trans_axes = self.get_residue_custom_axes(
|
|
353
|
+
edges, backbone_center
|
|
354
|
+
)
|
|
355
|
+
residue_heavy_atoms = residue.atoms.select_atoms("mass 2 to 999")
|
|
356
|
+
|
|
357
|
+
# look for heavy atoms in residue of interest
|
|
358
|
+
heavy_atom_indices = []
|
|
359
|
+
for atom in residue_heavy_atoms:
|
|
360
|
+
heavy_atom_indices.append(atom.index)
|
|
361
|
+
# we find the nth heavy atom
|
|
362
|
+
# where n is the bead index
|
|
363
|
+
heavy_atom_index = heavy_atom_indices[index]
|
|
364
|
+
heavy_atom = residue.atoms.select_atoms(f"index {heavy_atom_index}")[0]
|
|
365
|
+
rot_center = heavy_atom.position
|
|
366
|
+
rot_axes, moment_of_inertia = self.get_bonded_axes(
|
|
367
|
+
system=data_container,
|
|
368
|
+
atom=heavy_atom,
|
|
369
|
+
dimensions=data_container.dimensions[:3],
|
|
246
370
|
)
|
|
371
|
+
|
|
247
372
|
else:
|
|
248
|
-
#
|
|
249
|
-
|
|
250
|
-
|
|
373
|
+
# 1 heavy atom in the data_container
|
|
374
|
+
heavy_atom = heavy_atoms[0]
|
|
375
|
+
# trans and rot centres are centre of mass
|
|
376
|
+
rot_center = data_container.center_of_mass()
|
|
377
|
+
rot_axes, moment_of_inertia = self.get_bonded_axes(
|
|
378
|
+
system=data_container,
|
|
379
|
+
atom=heavy_atom,
|
|
380
|
+
dimensions=data_container.dimensions[:3],
|
|
381
|
+
)
|
|
382
|
+
trans_center = rot_center
|
|
383
|
+
# principal axes
|
|
384
|
+
trans_axes = rot_axes
|
|
385
|
+
|
|
386
|
+
if trans_axes is None:
|
|
387
|
+
raise ValueError("Unable to compute translation axes for UA bead.")
|
|
251
388
|
|
|
252
|
-
# look for heavy atoms in residue of interest
|
|
253
|
-
heavy_atom_indices = []
|
|
254
|
-
for atom in heavy_atoms:
|
|
255
|
-
heavy_atom_indices.append(atom.index)
|
|
256
|
-
# we find the nth heavy atom
|
|
257
|
-
# where n is the bead index
|
|
258
|
-
heavy_atom_index = heavy_atom_indices[index]
|
|
259
|
-
heavy_atom = data_container.select_atoms(f"index {heavy_atom_index}")
|
|
260
|
-
|
|
261
|
-
center = heavy_atom.positions[0]
|
|
262
|
-
rot_axes, moment_of_inertia = self.get_bonded_axes(
|
|
263
|
-
system=data_container,
|
|
264
|
-
atom=heavy_atom[0],
|
|
265
|
-
dimensions=data_container.dimensions[:3],
|
|
266
|
-
)
|
|
267
389
|
if rot_axes is None or moment_of_inertia is None:
|
|
268
390
|
raise ValueError("Unable to compute bonded axes for UA bead.")
|
|
269
391
|
|
|
270
|
-
logger.debug(
|
|
271
|
-
logger.debug(
|
|
272
|
-
logger.debug(
|
|
273
|
-
logger.debug(
|
|
392
|
+
logger.debug("Translational Axes: %s", trans_axes)
|
|
393
|
+
logger.debug("Rotational Axes: %s", rot_axes)
|
|
394
|
+
logger.debug("Translational center: %s", trans_center)
|
|
395
|
+
logger.debug("Rotational center: %s", rot_center)
|
|
396
|
+
logger.debug("Moment of Inertia: %s", moment_of_inertia)
|
|
274
397
|
|
|
275
|
-
return trans_axes, rot_axes,
|
|
398
|
+
return trans_axes, rot_axes, rot_center, moment_of_inertia
|
|
276
399
|
|
|
277
400
|
def get_UA_axes_from_topology(
|
|
278
401
|
self,
|
|
@@ -429,6 +552,55 @@ class AxesCalculator:
|
|
|
429
552
|
|
|
430
553
|
return custom_axes, custom_moment_of_inertia
|
|
431
554
|
|
|
555
|
+
def get_residue_custom_axes(self, edges, center):
|
|
556
|
+
"""
|
|
557
|
+
Compute rotation axes at the residue level, given
|
|
558
|
+
two edge atoms of the residue (E1+E2),
|
|
559
|
+
and the centre of geometry of backbone atoms
|
|
560
|
+
that are not edges (C).
|
|
561
|
+
x axis is O-E1
|
|
562
|
+
y axis is O-C (perpendicular to O-E1 in the
|
|
563
|
+
same plane as E2)
|
|
564
|
+
z axis is perpendicular to the two other axes
|
|
565
|
+
|
|
566
|
+
::
|
|
567
|
+
|
|
568
|
+
C
|
|
569
|
+
|
|
|
570
|
+
|
|
|
571
|
+
E1 ---- O --- E2
|
|
572
|
+
|
|
573
|
+
Args:
|
|
574
|
+
edges: (2,3) positions of two edge atoms
|
|
575
|
+
center: (3,) coordinates of the inner backbone
|
|
576
|
+
centre of geometry
|
|
577
|
+
|
|
578
|
+
Returns:
|
|
579
|
+
rot_center: (3,) rotation centre,
|
|
580
|
+
lies on the E1-E2 vector
|
|
581
|
+
rot_axes: (3,3) rotation axes of residue
|
|
582
|
+
"""
|
|
583
|
+
first_edge_centre_of_geometry_vector = center - edges[0].position
|
|
584
|
+
# look for projection of E1-O onto E1-E2 (E1-C)
|
|
585
|
+
first_edge_second_edge_vector = edges[1].position - edges[0].position
|
|
586
|
+
first_edge_origin_vector = (
|
|
587
|
+
np.dot(first_edge_second_edge_vector, first_edge_centre_of_geometry_vector)
|
|
588
|
+
/ (np.linalg.norm(first_edge_second_edge_vector) ** 2)
|
|
589
|
+
) * first_edge_second_edge_vector
|
|
590
|
+
x_axis = -first_edge_origin_vector
|
|
591
|
+
# O-C = O-E1 + E1-C
|
|
592
|
+
origin_centre_of_geometry_vector = (
|
|
593
|
+
-first_edge_origin_vector + first_edge_centre_of_geometry_vector
|
|
594
|
+
)
|
|
595
|
+
y_axis = origin_centre_of_geometry_vector
|
|
596
|
+
z_axis = np.cross(x_axis, y_axis)
|
|
597
|
+
x_axis /= np.linalg.norm(x_axis)
|
|
598
|
+
y_axis /= np.linalg.norm(y_axis)
|
|
599
|
+
z_axis /= np.linalg.norm(z_axis)
|
|
600
|
+
rot_axes = np.array([x_axis, y_axis, z_axis])
|
|
601
|
+
rot_center = first_edge_origin_vector + edges[0].position
|
|
602
|
+
return rot_center, rot_axes
|
|
603
|
+
|
|
432
604
|
def get_bonded_axes(self, system, atom, dimensions: np.ndarray):
|
|
433
605
|
r"""Compute UA rotational axes from bonded topology around a heavy atom.
|
|
434
606
|
|
|
@@ -659,6 +831,41 @@ class AxesCalculator:
|
|
|
659
831
|
scaled_custom_axes = unscaled_custom_axes / mod[:, np.newaxis]
|
|
660
832
|
return scaled_custom_axes
|
|
661
833
|
|
|
834
|
+
def get_custom_residue_moment_of_inertia(
|
|
835
|
+
self,
|
|
836
|
+
center_of_mass: np.ndarray,
|
|
837
|
+
positions: np.ndarray,
|
|
838
|
+
masses: np.ndarray,
|
|
839
|
+
custom_rot_axes: np.ndarray,
|
|
840
|
+
dimensions: np.ndarray,
|
|
841
|
+
):
|
|
842
|
+
"""
|
|
843
|
+
Compute moment of inertia around custom axes for a bead
|
|
844
|
+
formed of multiple UAs.
|
|
845
|
+
|
|
846
|
+
Args:
|
|
847
|
+
center_of_mass: (3, ) COM for bead
|
|
848
|
+
positions: (N,3) positions of the UAs in the bead
|
|
849
|
+
masses: (N,) masses of the UAs in the bead
|
|
850
|
+
custom_rot_axes: (3,3) array of residue rotation axes
|
|
851
|
+
dimensions: (3,) simulation_box_dimensions
|
|
852
|
+
|
|
853
|
+
Returns:
|
|
854
|
+
np.ndarray: (3,) moment of inertia array.
|
|
855
|
+
|
|
856
|
+
"""
|
|
857
|
+
|
|
858
|
+
translated_coords = self.get_vector(center_of_mass, positions, dimensions)
|
|
859
|
+
custom_moment_of_inertia = np.zeros(3, dtype=float)
|
|
860
|
+
|
|
861
|
+
for coord, mass in zip(translated_coords, masses, strict=True):
|
|
862
|
+
axis_component = np.sum(
|
|
863
|
+
np.cross(custom_rot_axes, coord) ** 2 * mass, axis=1
|
|
864
|
+
)
|
|
865
|
+
custom_moment_of_inertia += axis_component
|
|
866
|
+
|
|
867
|
+
return custom_moment_of_inertia
|
|
868
|
+
|
|
662
869
|
def get_custom_moment_of_inertia(
|
|
663
870
|
self,
|
|
664
871
|
UA,
|
|
@@ -849,3 +1056,78 @@ class AxesCalculator:
|
|
|
849
1056
|
ua_mass += float(h.mass)
|
|
850
1057
|
ua_masses.append(ua_mass)
|
|
851
1058
|
return ua_masses
|
|
1059
|
+
|
|
1060
|
+
def get_chain(self, residue, first, last):
|
|
1061
|
+
"""
|
|
1062
|
+
For a given MDAnalysis AtomGroup and two given heavy atoms
|
|
1063
|
+
within that AtomGroup, return the
|
|
1064
|
+
shortest path between the two atoms.
|
|
1065
|
+
|
|
1066
|
+
Args:
|
|
1067
|
+
residue: MDAnalysis AtomGroup representing
|
|
1068
|
+
the residue/monomer of interest.
|
|
1069
|
+
first: First heavy atom in the chain
|
|
1070
|
+
last: Last heavy atom in the chain
|
|
1071
|
+
|
|
1072
|
+
Returns:
|
|
1073
|
+
chain: Array containing chain atoms.
|
|
1074
|
+
"""
|
|
1075
|
+
|
|
1076
|
+
chain = []
|
|
1077
|
+
# at the beggining we've only visited the first atom
|
|
1078
|
+
visited_dict = {first: True}
|
|
1079
|
+
# keep the previous atom to trace back the path
|
|
1080
|
+
prev = {}
|
|
1081
|
+
# queue of next heavy atoms to visit
|
|
1082
|
+
next_to_visit = [first]
|
|
1083
|
+
# all others heavy atoms in the residue, we have not yet visited
|
|
1084
|
+
remaining_heavy_atoms = residue.atoms.select_atoms(
|
|
1085
|
+
f"(mass 2 to 999) and not index {first.index}"
|
|
1086
|
+
)
|
|
1087
|
+
for atom in remaining_heavy_atoms:
|
|
1088
|
+
visited_dict[atom] = False
|
|
1089
|
+
current = first
|
|
1090
|
+
|
|
1091
|
+
while not visited_dict[last]:
|
|
1092
|
+
# we haven't found a path to the last residue
|
|
1093
|
+
next_to_visit.pop(0)
|
|
1094
|
+
# we're visiting the current atom => we remove it from the queue
|
|
1095
|
+
bonded_atoms = residue.atoms.select_atoms(
|
|
1096
|
+
f"(mass 2 to 999) and bonded index {current.index}"
|
|
1097
|
+
)
|
|
1098
|
+
|
|
1099
|
+
if last in bonded_atoms:
|
|
1100
|
+
# we found a path to the last atom
|
|
1101
|
+
visited_dict[last] = True
|
|
1102
|
+
chain.append(last)
|
|
1103
|
+
prev[last] = current
|
|
1104
|
+
|
|
1105
|
+
else:
|
|
1106
|
+
for bonded_atom in bonded_atoms:
|
|
1107
|
+
# look for unvisited bonded atoms to the current atom we're visiting
|
|
1108
|
+
if not visited_dict[bonded_atom]:
|
|
1109
|
+
# we're going to want to visit the atoms
|
|
1110
|
+
next_to_visit.append(bonded_atom)
|
|
1111
|
+
prev[bonded_atom] = current
|
|
1112
|
+
# we visit the next atom in the queue
|
|
1113
|
+
current = next_to_visit[0]
|
|
1114
|
+
visited_dict[current] = True
|
|
1115
|
+
|
|
1116
|
+
# we track the previous atom back to the first atom now
|
|
1117
|
+
current = last
|
|
1118
|
+
chain = [last]
|
|
1119
|
+
# subtract index of first atom in resid
|
|
1120
|
+
# most likely will coincide with first
|
|
1121
|
+
# but this will work even if it doesn't
|
|
1122
|
+
# accout for in-residue index
|
|
1123
|
+
# start from last atom in chain
|
|
1124
|
+
while chain[-1] != first:
|
|
1125
|
+
# we haven't yet returned to the first atom
|
|
1126
|
+
current = prev[current]
|
|
1127
|
+
chain.append(current)
|
|
1128
|
+
|
|
1129
|
+
chain = np.flip(chain)
|
|
1130
|
+
# only get in between residues
|
|
1131
|
+
chain = chain[1:-1]
|
|
1132
|
+
# accout for in-residue index
|
|
1133
|
+
return chain
|
|
@@ -86,17 +86,24 @@ class InitCovarianceAccumulatorsNode:
|
|
|
86
86
|
|
|
87
87
|
@staticmethod
|
|
88
88
|
def _build_group_index(groups: dict[int, Any]) -> GroupIndex:
|
|
89
|
-
"""Build group
|
|
89
|
+
"""Build deterministic mappings between group IDs and contiguous indices.
|
|
90
|
+
|
|
91
|
+
Group IDs are sorted before indices are assigned, ensuring that the
|
|
92
|
+
resulting mappings do not depend on dictionary insertion order.
|
|
90
93
|
|
|
91
94
|
Args:
|
|
92
|
-
groups: Mapping of group
|
|
95
|
+
groups: Mapping of group IDs to their members.
|
|
93
96
|
|
|
94
97
|
Returns:
|
|
95
|
-
|
|
98
|
+
Bidirectional mappings between group IDs and contiguous indices.
|
|
96
99
|
"""
|
|
97
|
-
group_ids =
|
|
98
|
-
gid2i = {gid:
|
|
99
|
-
|
|
100
|
+
group_ids = sorted(groups)
|
|
101
|
+
gid2i = {gid: index for index, gid in enumerate(group_ids)}
|
|
102
|
+
|
|
103
|
+
return GroupIndex(
|
|
104
|
+
group_id_to_index=gid2i,
|
|
105
|
+
index_to_group_id=group_ids,
|
|
106
|
+
)
|
|
100
107
|
|
|
101
108
|
@staticmethod
|
|
102
109
|
def _build_accumulators(n_groups: int) -> CovarianceAccumulators:
|
|
@@ -185,6 +185,15 @@ class FrameCovarianceNode:
|
|
|
185
185
|
molcount: dict[tuple[int, int], int],
|
|
186
186
|
) -> None:
|
|
187
187
|
"""Compute united-atom second moments for one molecule.
|
|
188
|
+
If there are multiple residues in the molecule, build
|
|
189
|
+
residue group and attribute res_position:
|
|
190
|
+
- First residue: residue_group contains first two
|
|
191
|
+
residues. res_position is -1.
|
|
192
|
+
- Last residue: residue_group contains last two
|
|
193
|
+
residues. res_position is 1.
|
|
194
|
+
- Non-terminal residue: residue_group contains
|
|
195
|
+
residue of interest + two neighbours. res_position
|
|
196
|
+
is 0.
|
|
188
197
|
|
|
189
198
|
Args:
|
|
190
199
|
u: Universe-like object used to resolve bead atom indices.
|
|
@@ -203,6 +212,32 @@ class FrameCovarianceNode:
|
|
|
203
212
|
molcount: Per-residue group sample counters, mutated in place.
|
|
204
213
|
"""
|
|
205
214
|
for local_res_i, res in enumerate(mol.residues):
|
|
215
|
+
if len(mol.residues) > 1:
|
|
216
|
+
if local_res_i == 0:
|
|
217
|
+
relative_id = res.resindex
|
|
218
|
+
# index relative to first in mda universe
|
|
219
|
+
res_position = -1
|
|
220
|
+
residue_group = mol.select_atoms(
|
|
221
|
+
f"resindex {local_res_i + relative_id} "
|
|
222
|
+
f"or resindex {local_res_i + 1 + relative_id}"
|
|
223
|
+
)
|
|
224
|
+
elif local_res_i == len(mol.residues) - 1:
|
|
225
|
+
res_position = 1
|
|
226
|
+
residue_group = mol.select_atoms(
|
|
227
|
+
f"resindex {local_res_i - 1 + relative_id} "
|
|
228
|
+
f"or resindex {local_res_i + relative_id}"
|
|
229
|
+
)
|
|
230
|
+
else:
|
|
231
|
+
res_position = 0
|
|
232
|
+
residue_group = mol.select_atoms(
|
|
233
|
+
f"resindex {local_res_i - 1 + relative_id} "
|
|
234
|
+
f"or resindex {local_res_i + relative_id} "
|
|
235
|
+
f"or resindex {local_res_i + 1 + relative_id}"
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
else:
|
|
239
|
+
res_position = None
|
|
240
|
+
residue_group = res
|
|
206
241
|
bead_key = (mol_id, "united_atom", local_res_i)
|
|
207
242
|
bead_idx_list = beads.get(bead_key, [])
|
|
208
243
|
if not bead_idx_list:
|
|
@@ -216,7 +251,7 @@ class FrameCovarianceNode:
|
|
|
216
251
|
u=u,
|
|
217
252
|
mol_id=mol_id,
|
|
218
253
|
local_res_i=local_res_i,
|
|
219
|
-
|
|
254
|
+
residue_group=residue_group,
|
|
220
255
|
bead_groups=bead_groups,
|
|
221
256
|
axes_manager=axes_manager,
|
|
222
257
|
axes_topology=axes_topology,
|
|
@@ -224,6 +259,7 @@ class FrameCovarianceNode:
|
|
|
224
259
|
force_partitioning=force_partitioning,
|
|
225
260
|
customised_axes=customised_axes,
|
|
226
261
|
is_highest=is_highest,
|
|
262
|
+
res_position=res_position,
|
|
227
263
|
)
|
|
228
264
|
|
|
229
265
|
F, T = self._ft.compute_frame_covariance(force_vecs, torque_vecs)
|
|
@@ -406,13 +442,14 @@ class FrameCovarianceNode:
|
|
|
406
442
|
mol_id: int,
|
|
407
443
|
local_res_i: int,
|
|
408
444
|
bead_groups: list[Any],
|
|
409
|
-
|
|
445
|
+
residue_group: Any,
|
|
410
446
|
axes_manager: Any,
|
|
411
447
|
axes_topology: Any | None,
|
|
412
448
|
box: np.ndarray | None,
|
|
413
449
|
force_partitioning: float,
|
|
414
450
|
customised_axes: bool,
|
|
415
451
|
is_highest: bool,
|
|
452
|
+
res_position: int,
|
|
416
453
|
) -> tuple[list[np.ndarray], list[np.ndarray]]:
|
|
417
454
|
"""Build force and torque vectors for united-atom beads.
|
|
418
455
|
|
|
@@ -421,13 +458,14 @@ class FrameCovarianceNode:
|
|
|
421
458
|
mol_id: Molecule index used in axes-topology lookup keys.
|
|
422
459
|
local_res_i: Local residue index used in axes-topology lookup keys.
|
|
423
460
|
bead_groups: Atom groups representing UA beads in a residue.
|
|
424
|
-
|
|
461
|
+
residue_group: Atom group for the parent residue group.
|
|
425
462
|
axes_manager: Axes helper used to select axes, centres, and moments.
|
|
426
463
|
axes_topology: Optional cached axes topology generated during static setup.
|
|
427
464
|
box: Optional periodic box vector.
|
|
428
465
|
force_partitioning: Force partitioning factor for highest-level vectors.
|
|
429
466
|
customised_axes: Whether customised UA axes should be used.
|
|
430
467
|
is_highest: Whether UA is the highest active level.
|
|
468
|
+
res_position: Where the residue is in the residue group
|
|
431
469
|
|
|
432
470
|
Returns:
|
|
433
471
|
A tuple containing lists of force vectors and torque vectors.
|
|
@@ -436,29 +474,39 @@ class FrameCovarianceNode:
|
|
|
436
474
|
torque_vecs: list[np.ndarray] = []
|
|
437
475
|
|
|
438
476
|
for ua_i, bead in enumerate(bead_groups):
|
|
477
|
+
if res_position == -1:
|
|
478
|
+
residue = residue_group.residues[0]
|
|
479
|
+
elif res_position == 0 or res_position == 1:
|
|
480
|
+
residue = residue_group.residues[1]
|
|
481
|
+
else:
|
|
482
|
+
residue = residue_group
|
|
483
|
+
|
|
439
484
|
if customised_axes:
|
|
440
485
|
ua_topology = None
|
|
441
486
|
if axes_topology is not None:
|
|
442
487
|
ua_topology = axes_topology.ua.get((mol_id, local_res_i, ua_i))
|
|
443
|
-
|
|
444
488
|
if ua_topology is not None:
|
|
445
489
|
trans_axes, rot_axes, center, moi = (
|
|
446
490
|
axes_manager.get_UA_axes_from_topology(
|
|
447
491
|
u=u,
|
|
448
|
-
residue_atoms=
|
|
492
|
+
residue_atoms=residue.atoms,
|
|
449
493
|
topology=ua_topology,
|
|
450
494
|
box=box,
|
|
451
495
|
)
|
|
452
496
|
)
|
|
453
497
|
else:
|
|
498
|
+
# we don't use the topology
|
|
499
|
+
make_whole(residue_group)
|
|
500
|
+
make_whole(bead)
|
|
454
501
|
trans_axes, rot_axes, center, moi = axes_manager.get_UA_axes(
|
|
455
|
-
|
|
502
|
+
residue_group, ua_i, res_position
|
|
456
503
|
)
|
|
504
|
+
|
|
457
505
|
else:
|
|
458
|
-
|
|
506
|
+
# principal axes
|
|
507
|
+
make_whole(residue.atoms)
|
|
459
508
|
make_whole(bead)
|
|
460
|
-
|
|
461
|
-
trans_axes = residue_atoms.principal_axes()
|
|
509
|
+
trans_axes = residue.atoms.principal_axes()
|
|
462
510
|
rot_axes, moi = axes_manager.get_vanilla_axes(bead)
|
|
463
511
|
center = bead.center_of_mass(unwrap=True)
|
|
464
512
|
|
|
@@ -518,6 +566,8 @@ class FrameCovarianceNode:
|
|
|
518
566
|
force_vecs: list[np.ndarray] = []
|
|
519
567
|
torque_vecs: list[np.ndarray] = []
|
|
520
568
|
|
|
569
|
+
relative_res_i = mol.residues[0].resindex
|
|
570
|
+
|
|
521
571
|
for local_res_i, bead in enumerate(bead_groups):
|
|
522
572
|
trans_axes, rot_axes, center, moi = self._get_residue_axes(
|
|
523
573
|
u=u,
|
|
@@ -525,6 +575,7 @@ class FrameCovarianceNode:
|
|
|
525
575
|
mol_id=mol_id,
|
|
526
576
|
bead=bead,
|
|
527
577
|
local_res_i=local_res_i,
|
|
578
|
+
relative_res_i=relative_res_i,
|
|
528
579
|
axes_manager=axes_manager,
|
|
529
580
|
axes_topology=axes_topology,
|
|
530
581
|
box=box,
|
|
@@ -561,6 +612,7 @@ class FrameCovarianceNode:
|
|
|
561
612
|
mol_id: int,
|
|
562
613
|
bead: Any,
|
|
563
614
|
local_res_i: int,
|
|
615
|
+
relative_res_i: int,
|
|
564
616
|
axes_manager: Any,
|
|
565
617
|
axes_topology: Any | None,
|
|
566
618
|
box: np.ndarray | None,
|
|
@@ -574,6 +626,8 @@ class FrameCovarianceNode:
|
|
|
574
626
|
mol_id: Molecule index used in axes-topology lookup keys.
|
|
575
627
|
bead: Atom group representing the residue bead.
|
|
576
628
|
local_res_i: Residue index local to ``mol``.
|
|
629
|
+
relative_res_i: Residue index of first residue within ``mol``. This
|
|
630
|
+
might differ from residue index of first residue in topology.
|
|
577
631
|
axes_manager: Axes helper used to select axes, centres, and moments.
|
|
578
632
|
axes_topology: Optional cached axes topology generated during static setup.
|
|
579
633
|
box: Optional periodic box vector.
|
|
@@ -597,7 +651,9 @@ class FrameCovarianceNode:
|
|
|
597
651
|
box=box,
|
|
598
652
|
)
|
|
599
653
|
|
|
600
|
-
return axes_manager.get_residue_axes(
|
|
654
|
+
return axes_manager.get_residue_axes(
|
|
655
|
+
mol, local_res_i, relative_res_i, residue=res.atoms
|
|
656
|
+
)
|
|
601
657
|
|
|
602
658
|
make_whole(mol.atoms)
|
|
603
659
|
make_whole(bead)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: CodeEntropy
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.2
|
|
4
4
|
Summary: CodeEntropy is a Python package for computing the configurational entropy of macromolecular systems using forces sampled from molecular dynamics (MD) simulations. It implements the multiscale cell correlation method to provide accurate and efficient entropy estimates, supporting a wide range of applications in molecular simulation and statistical mechanics.
|
|
5
5
|
Keywords: entropy,macromolecular systems,MD simulation
|
|
6
6
|
Author-email: Arghya 'Argo' Chakravorty <arghyac@umich.edu>, Donald Chung-HK <donald.chung@stfc.ac.uk>, Sarah Fegan <sarah.fegan@stfc.ac.uk>, James Gebbie-Rayet <james.gebbie@stfc.ac.uk>, Sarah Harris <sarah.harris@sheffield.ac.uk>, Richard Henchman <rhen7213@uni.sydney.edu.au>, Jonathan Higham <j.higham4@lancaster.ac.uk>, Jas Kalayan <jas.kalayan@stfc.ac.uk>, Ioana Papa <iapapa1@sheffield.ac.uk>
|
|
@@ -29,8 +29,10 @@ Requires-Dist: matplotlib>=3.11,<3.12
|
|
|
29
29
|
Requires-Dist: waterEntropy>=2,<2.3
|
|
30
30
|
Requires-Dist: requests>=2.32,<3.0
|
|
31
31
|
Requires-Dist: rdkit>=2025.9.5
|
|
32
|
-
Requires-Dist: numba>=0.65.
|
|
33
|
-
Requires-Dist: dask
|
|
32
|
+
Requires-Dist: numba>=0.65.1,<0.70
|
|
33
|
+
Requires-Dist: dask>=2026.1.2,<2026.2.0
|
|
34
|
+
Requires-Dist: dask-jobqueue>=0.9.0,<0.10
|
|
35
|
+
Requires-Dist: distributed>=2026.1.2,<2026.2.0
|
|
34
36
|
Requires-Dist: sphinx>=9.1,<9.2 ; extra == "docs"
|
|
35
37
|
Requires-Dist: nbsphinx>=0.9,<1.0 ; extra == "docs"
|
|
36
38
|
Requires-Dist: sphinx_rtd_theme>=3,<3.2 ; extra == "docs"
|
|
@@ -40,19 +42,19 @@ Requires-Dist: sphinx_copybutton>=0.5,<1.0 ; extra == "docs"
|
|
|
40
42
|
Requires-Dist: furo>=2025.0,<2026.0 ; extra == "docs"
|
|
41
43
|
Requires-Dist: markupsafe>=3.0,<4.0 ; extra == "docs"
|
|
42
44
|
Requires-Dist: pre-commit>=4.5,<5.0 ; extra == "pre-commit"
|
|
43
|
-
Requires-Dist: ruff>=0.
|
|
45
|
+
Requires-Dist: ruff>=0.16,<0.17 ; extra == "pre-commit"
|
|
44
46
|
Requires-Dist: pylint>=4.0,<5.0 ; extra == "pre-commit"
|
|
45
47
|
Requires-Dist: rstcheck>=6.2,<7.0 ; extra == "pre-commit"
|
|
46
48
|
Requires-Dist: pytest>=9.0,<10.0 ; extra == "testing"
|
|
47
49
|
Requires-Dist: pytest-cov>=7.0,<8.0 ; extra == "testing"
|
|
48
50
|
Requires-Dist: pytest-sugar>=1.1,<2.0 ; extra == "testing"
|
|
49
|
-
Requires-Dist: pytest-xdist ; extra == "testing"
|
|
50
51
|
Project-URL: Documentation, https://codeentropy.readthedocs.io
|
|
51
52
|
Project-URL: Homepage, https://ccpbiosim.github.io/CodeEntropy/
|
|
52
53
|
Project-URL: Repository, https://github.com/CCPBioSim/CodeEntropy
|
|
53
54
|
Provides-Extra: docs
|
|
54
55
|
Provides-Extra: pre-commit
|
|
55
56
|
Provides-Extra: testing
|
|
57
|
+
Import-Name: CodeEntropy
|
|
56
58
|
|
|
57
59
|
CodeEntropy
|
|
58
60
|
==============================
|
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
CodeEntropy/__init__.py,sha256=
|
|
2
|
-
CodeEntropy/__main__.py,sha256=5i_ZrxQaq0q2aPllbB4SZ6BApV6oUFCgx0cGyjfMPrU,108
|
|
3
|
-
CodeEntropy/cli.py,sha256=xgSgagCV6HQ3CoXUpG7p7Ef5hCExgxp7orz6dZZWA6c,960
|
|
4
|
-
CodeEntropy/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
CodeEntropy/config/argparse.py,sha256=Yjb2SWNdfKhHmfznU439cZPtdPM_QjhUD4uug2fnsek,19515
|
|
6
|
-
CodeEntropy/config/runtime.py,sha256=iyeUrSAmz3eGpkAslAGsDzEzu7s4T8npy_Di3d8tnaU,14846
|
|
7
|
-
CodeEntropy/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
-
CodeEntropy/core/dask_clusters.py,sha256=FsvLyYQPImTWRf9J4x7wUILqf3syS0Ji5JUsJN-Qp1A,8992
|
|
9
|
-
CodeEntropy/core/logging.py,sha256=XLr2lSSC5kGPq7rQDhWCi7Vcvh3DGO9e5TDbI4l2Bvc,7775
|
|
10
|
-
CodeEntropy/entropy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
CodeEntropy/entropy/configurational.py,sha256=3erd1Ul4sGL5BMBDYq33f27aRTZqiEb6hv1bVfWo9QA,2392
|
|
12
|
-
CodeEntropy/entropy/graph.py,sha256=LeDF2KxxNVgpetrIE9j0dnW64UhGywDLqoBJEf54vtc,4612
|
|
13
|
-
CodeEntropy/entropy/orientational.py,sha256=gfpYqCKQjAAx22rrUdbiLvzfEIXy1nwJoub1rgYKCvY,3415
|
|
14
|
-
CodeEntropy/entropy/vibrational.py,sha256=jgPWWiUW6aRCx949cFrNKuLB1MJoawD-9Uk8OB04Cs8,9366
|
|
15
|
-
CodeEntropy/entropy/water.py,sha256=Ob3V08DyQNSWDMqpQ27rqjgHeU5AlKZfjqf9EqUdgqc,8225
|
|
16
|
-
CodeEntropy/entropy/workflow.py,sha256=bxg8AVXGk7uwlv4u2AZ4kTQ26PMge_Z5ubWghdLtn9U,16100
|
|
17
|
-
CodeEntropy/entropy/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
CodeEntropy/entropy/nodes/aggregate.py,sha256=4SyXP1_bM0IesOuqflRLvPgEfFu0PmKiEm4EFgnNxwg,3062
|
|
19
|
-
CodeEntropy/entropy/nodes/configurational.py,sha256=-3j2ji_p-twPjZyjQ1T3tgN0pYLSIof9any1w5NI2as,7135
|
|
20
|
-
CodeEntropy/entropy/nodes/orientational.py,sha256=yPN_XRJ1LOxJ7hOE2cnsjIbgQlI2avM1g3mFbGhW6fM,2481
|
|
21
|
-
CodeEntropy/entropy/nodes/vibrational.py,sha256=3uhRqaMpK8u7QK2SDQ6RLRcr2rS3sPh6-GlTaNdTFWw,16978
|
|
22
|
-
CodeEntropy/levels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
CodeEntropy/levels/axes.py,sha256=
|
|
24
|
-
CodeEntropy/levels/forces.py,sha256=c7XnNIBTFCHHXllr1WxTIrxEV_CkUB2b1vdFO8hUofY,11595
|
|
25
|
-
CodeEntropy/levels/hierarchy.py,sha256=3cd4t6Tywg7VMgw4TboFF5VAHdhG4FaGBXsMptchisY,5158
|
|
26
|
-
CodeEntropy/levels/linalg.py,sha256=PJlrKtIOYcYDycW3Tbetm6k94FKFZTq-hm28qiu_tS0,3565
|
|
27
|
-
CodeEntropy/levels/neighbors.py,sha256=vswveQCIVBlDPQBFGc0e3whzmTJD01GjEJTpJ2UMnZ0,6255
|
|
28
|
-
CodeEntropy/levels/search.py,sha256=p4aqyj6GV7YGLDnlmZqi12cDbjfajSIB8IIcBAoUmaQ,8769
|
|
29
|
-
CodeEntropy/levels/dihedrals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
-
CodeEntropy/levels/dihedrals/angle_observations.py,sha256=ZsIaXRvNRzZQjBxafiWD2_3zn_GnKjc9EkN8GjrVh6Q,9861
|
|
31
|
-
CodeEntropy/levels/dihedrals/conformational_state_builder.py,sha256=3ajT_v1Cga1JocIvuJtHPx2JZwGUtleemuF45S31iAQ,7598
|
|
32
|
-
CodeEntropy/levels/dihedrals/kernels.py,sha256=gX75jgDDs-dv-IdI0V-u7NM-M4RVmpVppDAADFkHWxc,3594
|
|
33
|
-
CodeEntropy/levels/dihedrals/peak_detection.py,sha256=h8j78gczkf9tlYFTMqITDc51K9l9NxS5Y-ul1gHytzw,9486
|
|
34
|
-
CodeEntropy/levels/dihedrals/state_assignment.py,sha256=QtfYjXEBbW95lomT9linK1_5uU0nsHh1P6PyMT_VR1g,9672
|
|
35
|
-
CodeEntropy/levels/dihedrals/topology.py,sha256=LJ_u6cY-N91A5CuNBYzk_I0xHEpvqYSC30u9T4aku7c,8825
|
|
36
|
-
CodeEntropy/levels/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
-
CodeEntropy/levels/execution/chunks.py,sha256=VD1LQA-thRaJZKVR_5qIQk5VZQWHGE2e2JzF5JspDe0,754
|
|
38
|
-
CodeEntropy/levels/execution/policy.py,sha256=4Yoxd7wgjyIph8YwKYpS9vHDt1u-7X7GVcoOVo9k-9Q,2915
|
|
39
|
-
CodeEntropy/levels/execution/reducers.py,sha256=7H3vXtV2Jhe7tCQLyjxEmSEhn6iYLwyXMXKsm9XiB2s,14751
|
|
40
|
-
CodeEntropy/levels/execution/scheduler.py,sha256=luVBarqXNO24SWwQjKNJhecFO3fng6Yu8kcd5Ky_uOc,10629
|
|
41
|
-
CodeEntropy/levels/execution/tasks.py,sha256=hGRbC2VmJOWndGX6PnZopUxdQhcLTL6RjAudXAESd2g,11125
|
|
42
|
-
CodeEntropy/levels/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
-
CodeEntropy/levels/graph/conformation_dag.py,sha256=2d9d9SwffYJn3ffRkPrL5HM_O5i5uiN0n_uRD-vt8O8,3147
|
|
44
|
-
CodeEntropy/levels/graph/frame_dag.py,sha256=YxdFt81q6mhPBZuNWqN4MHZecyXpavfRw_tV3Jkv9MU,3683
|
|
45
|
-
CodeEntropy/levels/graph/level_dag.py,sha256=RglkyLjvR0pYd4e_ScUXG75j-H9T0SWKmtLiBviiZK8,7324
|
|
46
|
-
CodeEntropy/levels/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
-
CodeEntropy/levels/nodes/accumulators.py,sha256=
|
|
48
|
-
CodeEntropy/levels/nodes/axes_topology.py,sha256=QzrWbCL9YA8fzF4_WWpQGaIAAsOnjY6cVH7INDE40dk,11285
|
|
49
|
-
CodeEntropy/levels/nodes/beads.py,sha256=9Ow065FY4jrIqPKCZJCvDNfIekJ17OBSX-bmEFsxtbc,8010
|
|
50
|
-
CodeEntropy/levels/nodes/covariance.py,sha256=
|
|
51
|
-
CodeEntropy/levels/nodes/detect_levels.py,sha256=YrM5SSceLiMqbOhr8Fy6SV-E_zkKRpvgHfDT8Grbin8,1864
|
|
52
|
-
CodeEntropy/levels/nodes/detect_molecules.py,sha256=jILCddEicVngA7FjvQzafbG8HslaRICpT6hj2Uyi6YY,3059
|
|
53
|
-
CodeEntropy/molecules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
|
-
CodeEntropy/molecules/grouping.py,sha256=rlRVbRcxS_bPCZV8yoOCZKSpLS1F5AdpdIhaK2nWf1U,6426
|
|
55
|
-
CodeEntropy/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
-
CodeEntropy/results/reporter.py,sha256=ZmCEKhh_h7-0JGumlyrpH0Y-FaG8aGv-KkzdRAamEAQ,18368
|
|
57
|
-
CodeEntropy/trajectory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
-
CodeEntropy/trajectory/frames.py,sha256=MSx_swzFjo4TgkZTR1y6W-1zuKNPg_C36I_uFqvOKpk,4354
|
|
59
|
-
CodeEntropy/trajectory/mda.py,sha256=cWqgSgamdPnL4n3aWEKUgycjtzjpdgRgMVX6G5fln94,15803
|
|
60
|
-
CodeEntropy/trajectory/source.py,sha256=NfYsdm1amr29h2tmJP-RKyCp3phb1SOAtAELJmGm740,1475
|
|
61
|
-
codeentropy-2.
|
|
62
|
-
codeentropy-2.
|
|
63
|
-
codeentropy-2.
|
|
64
|
-
codeentropy-2.
|
|
65
|
-
codeentropy-2.
|
|
1
|
+
CodeEntropy/__init__.py,sha256=ZKr8Gv-y5ra4wZypIjXV5VnpMidnqUVDAe_9f0s-zqo,404
|
|
2
|
+
CodeEntropy/__main__.py,sha256=5i_ZrxQaq0q2aPllbB4SZ6BApV6oUFCgx0cGyjfMPrU,108
|
|
3
|
+
CodeEntropy/cli.py,sha256=xgSgagCV6HQ3CoXUpG7p7Ef5hCExgxp7orz6dZZWA6c,960
|
|
4
|
+
CodeEntropy/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
CodeEntropy/config/argparse.py,sha256=Yjb2SWNdfKhHmfznU439cZPtdPM_QjhUD4uug2fnsek,19515
|
|
6
|
+
CodeEntropy/config/runtime.py,sha256=iyeUrSAmz3eGpkAslAGsDzEzu7s4T8npy_Di3d8tnaU,14846
|
|
7
|
+
CodeEntropy/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
CodeEntropy/core/dask_clusters.py,sha256=FsvLyYQPImTWRf9J4x7wUILqf3syS0Ji5JUsJN-Qp1A,8992
|
|
9
|
+
CodeEntropy/core/logging.py,sha256=XLr2lSSC5kGPq7rQDhWCi7Vcvh3DGO9e5TDbI4l2Bvc,7775
|
|
10
|
+
CodeEntropy/entropy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
CodeEntropy/entropy/configurational.py,sha256=3erd1Ul4sGL5BMBDYq33f27aRTZqiEb6hv1bVfWo9QA,2392
|
|
12
|
+
CodeEntropy/entropy/graph.py,sha256=LeDF2KxxNVgpetrIE9j0dnW64UhGywDLqoBJEf54vtc,4612
|
|
13
|
+
CodeEntropy/entropy/orientational.py,sha256=gfpYqCKQjAAx22rrUdbiLvzfEIXy1nwJoub1rgYKCvY,3415
|
|
14
|
+
CodeEntropy/entropy/vibrational.py,sha256=jgPWWiUW6aRCx949cFrNKuLB1MJoawD-9Uk8OB04Cs8,9366
|
|
15
|
+
CodeEntropy/entropy/water.py,sha256=Ob3V08DyQNSWDMqpQ27rqjgHeU5AlKZfjqf9EqUdgqc,8225
|
|
16
|
+
CodeEntropy/entropy/workflow.py,sha256=bxg8AVXGk7uwlv4u2AZ4kTQ26PMge_Z5ubWghdLtn9U,16100
|
|
17
|
+
CodeEntropy/entropy/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
+
CodeEntropy/entropy/nodes/aggregate.py,sha256=4SyXP1_bM0IesOuqflRLvPgEfFu0PmKiEm4EFgnNxwg,3062
|
|
19
|
+
CodeEntropy/entropy/nodes/configurational.py,sha256=-3j2ji_p-twPjZyjQ1T3tgN0pYLSIof9any1w5NI2as,7135
|
|
20
|
+
CodeEntropy/entropy/nodes/orientational.py,sha256=yPN_XRJ1LOxJ7hOE2cnsjIbgQlI2avM1g3mFbGhW6fM,2481
|
|
21
|
+
CodeEntropy/entropy/nodes/vibrational.py,sha256=3uhRqaMpK8u7QK2SDQ6RLRcr2rS3sPh6-GlTaNdTFWw,16978
|
|
22
|
+
CodeEntropy/levels/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
+
CodeEntropy/levels/axes.py,sha256=PzFKuac22C_JQvkQamKB7j4W6OUXBx-YMAyKHXlw_E0,44699
|
|
24
|
+
CodeEntropy/levels/forces.py,sha256=c7XnNIBTFCHHXllr1WxTIrxEV_CkUB2b1vdFO8hUofY,11595
|
|
25
|
+
CodeEntropy/levels/hierarchy.py,sha256=3cd4t6Tywg7VMgw4TboFF5VAHdhG4FaGBXsMptchisY,5158
|
|
26
|
+
CodeEntropy/levels/linalg.py,sha256=PJlrKtIOYcYDycW3Tbetm6k94FKFZTq-hm28qiu_tS0,3565
|
|
27
|
+
CodeEntropy/levels/neighbors.py,sha256=vswveQCIVBlDPQBFGc0e3whzmTJD01GjEJTpJ2UMnZ0,6255
|
|
28
|
+
CodeEntropy/levels/search.py,sha256=p4aqyj6GV7YGLDnlmZqi12cDbjfajSIB8IIcBAoUmaQ,8769
|
|
29
|
+
CodeEntropy/levels/dihedrals/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
|
+
CodeEntropy/levels/dihedrals/angle_observations.py,sha256=ZsIaXRvNRzZQjBxafiWD2_3zn_GnKjc9EkN8GjrVh6Q,9861
|
|
31
|
+
CodeEntropy/levels/dihedrals/conformational_state_builder.py,sha256=3ajT_v1Cga1JocIvuJtHPx2JZwGUtleemuF45S31iAQ,7598
|
|
32
|
+
CodeEntropy/levels/dihedrals/kernels.py,sha256=gX75jgDDs-dv-IdI0V-u7NM-M4RVmpVppDAADFkHWxc,3594
|
|
33
|
+
CodeEntropy/levels/dihedrals/peak_detection.py,sha256=h8j78gczkf9tlYFTMqITDc51K9l9NxS5Y-ul1gHytzw,9486
|
|
34
|
+
CodeEntropy/levels/dihedrals/state_assignment.py,sha256=QtfYjXEBbW95lomT9linK1_5uU0nsHh1P6PyMT_VR1g,9672
|
|
35
|
+
CodeEntropy/levels/dihedrals/topology.py,sha256=LJ_u6cY-N91A5CuNBYzk_I0xHEpvqYSC30u9T4aku7c,8825
|
|
36
|
+
CodeEntropy/levels/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
CodeEntropy/levels/execution/chunks.py,sha256=VD1LQA-thRaJZKVR_5qIQk5VZQWHGE2e2JzF5JspDe0,754
|
|
38
|
+
CodeEntropy/levels/execution/policy.py,sha256=4Yoxd7wgjyIph8YwKYpS9vHDt1u-7X7GVcoOVo9k-9Q,2915
|
|
39
|
+
CodeEntropy/levels/execution/reducers.py,sha256=7H3vXtV2Jhe7tCQLyjxEmSEhn6iYLwyXMXKsm9XiB2s,14751
|
|
40
|
+
CodeEntropy/levels/execution/scheduler.py,sha256=luVBarqXNO24SWwQjKNJhecFO3fng6Yu8kcd5Ky_uOc,10629
|
|
41
|
+
CodeEntropy/levels/execution/tasks.py,sha256=hGRbC2VmJOWndGX6PnZopUxdQhcLTL6RjAudXAESd2g,11125
|
|
42
|
+
CodeEntropy/levels/graph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
43
|
+
CodeEntropy/levels/graph/conformation_dag.py,sha256=2d9d9SwffYJn3ffRkPrL5HM_O5i5uiN0n_uRD-vt8O8,3147
|
|
44
|
+
CodeEntropy/levels/graph/frame_dag.py,sha256=YxdFt81q6mhPBZuNWqN4MHZecyXpavfRw_tV3Jkv9MU,3683
|
|
45
|
+
CodeEntropy/levels/graph/level_dag.py,sha256=RglkyLjvR0pYd4e_ScUXG75j-H9T0SWKmtLiBviiZK8,7324
|
|
46
|
+
CodeEntropy/levels/nodes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
47
|
+
CodeEntropy/levels/nodes/accumulators.py,sha256=XM7phCAIo0RK9YAtx2wrdo2oinmpwXYrH9mp1_LQD7U,6259
|
|
48
|
+
CodeEntropy/levels/nodes/axes_topology.py,sha256=QzrWbCL9YA8fzF4_WWpQGaIAAsOnjY6cVH7INDE40dk,11285
|
|
49
|
+
CodeEntropy/levels/nodes/beads.py,sha256=9Ow065FY4jrIqPKCZJCvDNfIekJ17OBSX-bmEFsxtbc,8010
|
|
50
|
+
CodeEntropy/levels/nodes/covariance.py,sha256=zwLPG_VRAH6hmCXeKkeQgqk7e_FRTBq0XXo-bNsR-U8,30210
|
|
51
|
+
CodeEntropy/levels/nodes/detect_levels.py,sha256=YrM5SSceLiMqbOhr8Fy6SV-E_zkKRpvgHfDT8Grbin8,1864
|
|
52
|
+
CodeEntropy/levels/nodes/detect_molecules.py,sha256=jILCddEicVngA7FjvQzafbG8HslaRICpT6hj2Uyi6YY,3059
|
|
53
|
+
CodeEntropy/molecules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
54
|
+
CodeEntropy/molecules/grouping.py,sha256=rlRVbRcxS_bPCZV8yoOCZKSpLS1F5AdpdIhaK2nWf1U,6426
|
|
55
|
+
CodeEntropy/results/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
CodeEntropy/results/reporter.py,sha256=ZmCEKhh_h7-0JGumlyrpH0Y-FaG8aGv-KkzdRAamEAQ,18368
|
|
57
|
+
CodeEntropy/trajectory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
58
|
+
CodeEntropy/trajectory/frames.py,sha256=MSx_swzFjo4TgkZTR1y6W-1zuKNPg_C36I_uFqvOKpk,4354
|
|
59
|
+
CodeEntropy/trajectory/mda.py,sha256=cWqgSgamdPnL4n3aWEKUgycjtzjpdgRgMVX6G5fln94,15803
|
|
60
|
+
CodeEntropy/trajectory/source.py,sha256=NfYsdm1amr29h2tmJP-RKyCp3phb1SOAtAELJmGm740,1475
|
|
61
|
+
codeentropy-2.4.2.dist-info/entry_points.txt,sha256=8Oa3H9ErsrGtx5Hc6hIHOw73wK3Ylkvfgtl_4cBb_GU,52
|
|
62
|
+
codeentropy-2.4.2.dist-info/licenses/LICENSE,sha256=hgMaAAVW1Q6dL586OHoz8vFO-6BYn-d2aAFBpVQylFc,1072
|
|
63
|
+
codeentropy-2.4.2.dist-info/WHEEL,sha256=_yMHPaBV-s6fQMwUoo83NSdTCM3c8xXWFXRhqafN-7Y,81
|
|
64
|
+
codeentropy-2.4.2.dist-info/METADATA,sha256=4OPOdf_Rgxt3pTbRbGiV0UznL2bUvKXPKlqw3X2hr48,6593
|
|
65
|
+
codeentropy-2.4.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|