Skip to content

Commit 312e589

Browse files
authored
Merge pull request #162 from CCPBioSim/161-issues-with-averaging-for-protein-multimer
Fix Averaging and Conformational Analysis for Protein Multimers
2 parents c5b4c32 + abce5f1 commit 312e589

4 files changed

Lines changed: 54 additions & 6 deletions

File tree

CodeEntropy/levels.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ def get_dihedrals(self, data_container, level):
205205
# if residue level, looking for dihedrals involving residues
206206
if level == "residue":
207207
num_residues = len(data_container.residues)
208+
logger.debug(f"Number Residues: {num_residues}")
208209
if num_residues < 4:
209210
logger.debug("no residue level dihedrals")
210211

@@ -249,7 +250,7 @@ def get_dihedrals(self, data_container, level):
249250
atom_group = atom1 + atom2 + atom3 + atom4
250251
dihedrals.append(atom_group.dihedral)
251252

252-
logger.debug(f"Dihedrals: {dihedrals}")
253+
logger.debug(f"Level: {level}, Dihedrals: {dihedrals}")
253254

254255
return dihedrals
255256

@@ -309,6 +310,7 @@ def compute_dihedral_conformations(
309310
if state
310311
]
311312

313+
logger.debug(f"level: {level}, states: {states}")
312314
return states
313315

314316
def get_beads(self, data_container, level):
@@ -1138,11 +1140,11 @@ def build_conformational_states(
11381140
)
11391141

11401142
if key in states_ua:
1141-
states_ua[key].append(states)
1143+
states_ua[key].extend(states)
11421144
else:
11431145
states_ua[key] = states
11441146

1145-
elif level == "res":
1147+
elif level == "residue":
11461148
states = self.compute_dihedral_conformations(
11471149
mol,
11481150
level,
@@ -1157,7 +1159,7 @@ def build_conformational_states(
11571159
if states_res[group_id] is None:
11581160
states_res[group_id] = states
11591161
else:
1160-
states_res[group_id] += states
1162+
states_res[group_id].extend(states)
11611163

11621164
progress.advance(task)
11631165

docs/getting_started.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ The top_traj_file argument is necessary to identify your simulation data, the ot
130130
- ``molecules``
131131
- ``str``
132132

133+
Averaging
134+
^^^^^^^^^
135+
The code is able to average over molecules of the same type.
136+
The grouping arguement is used to control how the averaging is done.
137+
The default is "molecules" which defines molecules by the number and names of the atoms and groups molecules that are the same.
138+
You can also use "each" which makes each molecule its own group, effectively not averaging over molecules.
133139

134140
Example #1
135141
^^^^^^^^^^

tests/test_CodeEntropy/test_entropy.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,46 @@ def test_process_conformational_residue_level(self):
777777
results = [entry[3] for entry in df]
778778
self.assertIn(3.33, results)
779779

780+
def test_process_conformational_entropy_no_states_entry(self):
781+
"""
782+
Tests that `_process_conformational_entropy` logs zero entropy when
783+
the group_id is not present in the states dictionary.
784+
"""
785+
# Setup minimal mock universe
786+
u = MagicMock()
787+
788+
# Setup managers and arguments
789+
args = MagicMock()
790+
run_manager = MagicMock()
791+
level_manager = MagicMock()
792+
data_logger = DataLogger()
793+
group_molecules = MagicMock()
794+
manager = EntropyManager(
795+
run_manager, args, u, data_logger, level_manager, group_molecules
796+
)
797+
798+
# States dict does NOT contain group_id=1
799+
states = {0: np.ones((10, 3))}
800+
801+
# Mock entropy calculator
802+
ce = MagicMock()
803+
804+
# Run method with group_id=1 (not in states)
805+
manager._process_conformational_entropy(
806+
group_id=1,
807+
mol_container=MagicMock(),
808+
ce=ce,
809+
level="residue",
810+
states=states,
811+
number_frames=10,
812+
)
813+
814+
# Assert entropy is zero
815+
self.assertEqual(data_logger.molecule_data[0][3], 0)
816+
817+
# Assert calculator was not called
818+
ce.conformational_entropy_calculation.assert_not_called()
819+
780820
def test_compute_entropies_united_atom(self):
781821
"""
782822
Test that _process_united_atom_entropy is called correctly for 'united_atom'

tests/test_CodeEntropy/test_levels.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,7 +1253,7 @@ def test_build_conformational_states_united_atom_accumulates_states(self):
12531253
ce,
12541254
)
12551255

1256-
assert states_ua[(0, 0)] == ["ua_state_1", ["ua_state_2"]]
1256+
assert states_ua[(0, 0)] == ["ua_state_1", "ua_state_2"]
12571257

12581258
# Confirm compute_dihedral_conformations was called twice (once per molecule)
12591259
assert level_manager.compute_dihedral_conformations.call_count == 2
@@ -1291,7 +1291,7 @@ def test_build_conformational_states_residue_level_accumulates_states(self):
12911291

12921292
# Setup inputs with 2 molecules in same group
12931293
groups = {0: [0, 1]} # Both mol 0 and mol 1 are in group 0
1294-
levels = [["res"], ["res"]]
1294+
levels = [["residue"], ["residue"]]
12951295
start, end, step = 0, 10, 1
12961296
number_frames = 10
12971297
bin_width = 0.1

0 commit comments

Comments
 (0)