Skip to content

Commit a3023ff

Browse files
authored
Merge pull request #24 from wehs7661/refactor_w_combine
Refactoring codes for weight combination
2 parents 006b608 + 9a1373e commit a3023ff

File tree

5 files changed

+201
-99
lines changed

5 files changed

+201
-99
lines changed

docs/simulations.rst

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,24 @@ include parameters for data analysis here.
282282
- :code:`acceptance`: (Optional, Default: :code:`metropolis`)
283283
The Monte Carlo method for swapping simulations. Available options include :code:`same-state`/:code:`same_state`, :code:`metropolis`, and :code:`metropolis-eq`/:code:`metropolis_eq`.
284284
For more details, please refer to :ref:`doc_acceptance`.
285-
- :code:`w_combine`: (Optional, Default: :code:`False`)
286-
Whether to combine weights across multiple replicas for an weight-updating EEXE simulations.
287-
For more details, please refer to :ref:`doc_w_schemes`.
285+
- :code:`w_combine`: (Optional, Default: :code:`None`)
286+
The type of weights to be combined across multiple replicas in a weight-updating EEXE simulation. The following options are available:
287+
288+
- :code:`None`: No weight combination.
289+
- :code:`final`: Combine the final weights.
290+
- :code:`avg`: Combine the weights averaged over from last time the Wang-Landau incrementor was updated.
291+
292+
For more details about weight combination, please refer to :ref:`doc_w_schemes`.
293+
294+
- :code:`rmse_cutoff`: (Optional, Default: :code:`None`)
295+
The cutoff for the root-mean-square error (RMSE) between the weights of the current iteration
296+
and the weights averaged over from the last time the Wang-Landau incrementor was updated.
297+
For each replica, the RMSE between the averaged weights and the current weights will be calculated.
298+
When :code:`rmse_cutoff` is specified, weight combination will be performed only if the maximum RMSE across all replicas
299+
is smaller than the cutoff. Otherwise, weight combination is deactivated (even if :code:`w_combine` is specified)
300+
because a larger RMSE indicates that the weights are noisy and should not be combined.
301+
The default value is infinity, which means that weight combination will always be performed if :code:`w_combine` is specified.
302+
The units of the cutoff are :math:`k_B T`.
288303
- :code:`N_cutoff`: (Optional, Default: 1000)
289304
The histogram cutoff. -1 means that no histogram correction will be performed.
290305
- :code:`n_ex`: (Optional, Default: 1)
@@ -352,7 +367,8 @@ include parameters for data analysis here.
352367
-------------------------------
353368
For convenience, here is a template of the input YAML file, with each optional parameter specified with the default and required
354369
parameters left with a blank. Note that specifying :code:`null` is the same as leaving the parameter unspecified (i.e. :code:`None`).
355-
370+
Note that the default value :code:`None` for the parameter :code:`rmse_cutoff` will be converted to
371+
infinity internally.
356372

357373
.. code-block:: yaml
358374
@@ -373,7 +389,8 @@ parameters left with a blank. Note that specifying :code:`null` is the same as l
373389
add_swappables: null
374390
proposal: 'exhaustive'
375391
acceptance: 'metropolis'
376-
w_combine: False
392+
w_combine: null
393+
rmse_cutoff: null
377394
N_cutoff: 1000
378395
n_ex: 1
379396
mdp_args: null

ensemble_md/cli/run_EEXE.py

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from datetime import datetime
2020

2121
from ensemble_md.utils import utils
22-
from ensemble_md.utils import gmx_parser
2322
from ensemble_md.ensemble_EXE import EnsembleEXE
2423

2524

@@ -154,45 +153,64 @@ def main():
154153
# Note after `get_swapping_pattern`, `states_` and `weights_` won't be necessarily
155154
# since they are updated by `get_swapping_pattern`. (Even if the function does not explicitly
156155
# returns `states_` and `weights_`, `states_` and `weights_` can still be different after
157-
# the use of the function.) Therefore, here we create copyes for `states_` and `weights_`
156+
# the use of the function.) Therefore, here we create copies for `states_` and `weights_`
158157
# before the use of `get_swapping_pattern`, so we can use them in `histogram_correction`,
159158
# `combine_weights` and `update_MDP`.
160159
states = copy.deepcopy(states_)
161160
weights = copy.deepcopy(weights_)
162161
swap_pattern, swap_list = EEXE.get_swapping_pattern(dhdl_files, states_, weights_) # swap_list will only be used for modify_coords # noqa: E501
163162

164-
# 3-3. Calculate the weights averaged since the last update of the Wang-Landau incrementor.
165-
# Note that the averaged weights are used for histogram correction/weight combination.
166-
# For calculating the acceptance ratio (inside get_swapping_pattern), final weights should be used.
167-
if EEXE.N_cutoff != -1 or EEXE.w_combine is True:
163+
# 3-3. Perform histogram correction/weight combination
164+
if wl_delta != [None for i in range(EEXE.n_sim)]: # weight-updating
165+
print(f'\nCurrent Wang-Landau incrementors: {wl_delta}\n')
166+
167+
# (1) First we prepare the weights to be combined.
168+
# Note that although averaged weights are sometimes used for histogram correction/weight combination,
169+
# the final weights are always used for calculating the acceptance ratio.
170+
if EEXE.N_cutoff != -1 or EEXE.w_combine is not None:
168171
# Only when histogram correction/weight combination is needed.
169172
weights_avg, weights_err = EEXE.get_averaged_weights(log_files)
173+
weights_input = EEXE.prepare_weights(weights_avg, weights) # weights_input is for weight combination # noqa: E501
170174

171-
# 3-4. Perform histogram correction/weight combination
172-
# Note that we never use final weights but averaged weights here.
175+
# (2) Now we perform histogram correction/weight combination.
173176
# The product of this step should always be named as "weights" to be used in update_MDP
174-
if wl_delta != [None for i in range(EEXE.n_sim)]: # weight-updating
175-
print(f'\nCurrent Wang-Landau incrementors: {wl_delta}')
176-
if EEXE.N_cutoff != -1 and EEXE.w_combine is True:
177+
if EEXE.N_cutoff != -1 and EEXE.w_combine is not None:
177178
# perform both
178-
weights_avg = EEXE.histogram_correction(weights_avg, counts)
179-
weights, g_vec = EEXE.combine_weights(weights_avg) # inverse-variance weighting seems worse
180-
EEXE.g_vecs.append(g_vec)
181-
elif EEXE.N_cutoff == -1 and EEXE.w_combine is True:
179+
if weights_input is None:
180+
# Then only histogram correction will be performed
181+
print('Note: Weight combination is deactivated because the weights are too noisy.')
182+
weights = EEXE.histogram_correction(weights, counts)
183+
_ = EEXE.combine_weights(weights, print_weights=False)[1] # just to print the combiend weights
184+
else:
185+
weights_preprocessed = EEXE.histogram_correction(weights_input, counts)
186+
if EEXE.verbose is True:
187+
print('Performing weight combination ...')
188+
else:
189+
print('Performing weight combination ...', end='')
190+
weights, g_vec = EEXE.combine_weights(weights_preprocessed) # inverse-variance weighting seems worse # noqa: E501
191+
EEXE.g_vecs.append(g_vec)
192+
elif EEXE.N_cutoff == -1 and EEXE.w_combine is not None:
182193
# only perform weight combination
183-
print('\nNote: No histogram correction will be performed.')
184-
weights, g_vec = EEXE.combine_weights(weights_avg) # inverse-variance weighting seems worse
185-
EEXE.g_vecs.append(g_vec)
186-
elif EEXE.N_cutoff != -1 and EEXE.w_combine is False:
194+
print('Note: No histogram correction will be performed.')
195+
if weights_input is None:
196+
print('Note: Weight combination is deactivated because the weights are too noisy.')
197+
_ = EEXE.combine_weights(weights, print_weights=False)[1] # just to print the combined weights
198+
else:
199+
if EEXE.verbose is True:
200+
print('Performing weight combination ...')
201+
else:
202+
print('Performing weight combination ...', end='')
203+
weights, g_vec = EEXE.combine_weights(weights_input) # inverse-variance weighting seems worse
204+
EEXE.g_vecs.append(g_vec)
205+
elif EEXE.N_cutoff != -1 and EEXE.w_combine is None:
187206
# only perform histogram correction
188-
print('\nNote: No weight combination will be performed.')
189-
weights = EEXE.histogram_correction(weights_avg, counts)
207+
print('Note: No weight combination will be performed.')
208+
weights = EEXE.histogram_correction(weights_input, counts)
209+
_ = EEXE.combine_weights(weights, print_weights=False)[1] # just to print the combined weights
190210
else:
191-
weights_current = [gmx_parser.parse_log(log_files[i])[0][-1] for i in range(EEXE.n_sim)]
192-
w_for_printing = EEXE.combine_weights(weights_current)[1]
193-
print('\nNote: No histogram correction will be performed.')
211+
print('Note: No histogram correction will be performed.')
194212
print('Note: No weight combination will be performed.')
195-
print(f'The alchemical weights of all states: \n {list(np.round(w_for_printing, decimals=3))}')
213+
_ = EEXE.combine_weights(weights, print_weights=False)[1] # just to print the combiend weights
196214

197215
# 3-5. Modify the MDP files and swap out the GRO files (if needed)
198216
# Here we keep the lambda range set in mdp the same across different iterations in the same folder but swap out the gro file # noqa: E501

0 commit comments

Comments
 (0)