From a1a5c4b8684af2dd9c42b6c34cd5eb79a7cf4bf3 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Mon, 2 Dec 2024 14:54:25 -0800 Subject: [PATCH 01/15] add docstrings --- openfecli/commands/gather.py | 75 +++++++++++++++++++++++++++++++----- 1 file changed, 65 insertions(+), 10 deletions(-) diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index 165e9a127..180be6f42 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -4,11 +4,26 @@ import click from openfecli import OFECommandPlugin from openfecli.clicktypes import HyphenAwareChoice + +import os import pathlib import warnings -def _get_column(val): +def _get_column(val:float|int)->int: + """Determine the index (where the 0th index is the decimal) at which the + first non-zero value occurs in a full-precision string representation of a value. + + Parameters + ---------- + val : float|int + The raw value. + + Returns + ------- + int + Column index + """ import numpy as np if val == 0: return 0 @@ -27,6 +42,23 @@ def format_estimate_uncertainty( unc: float, unc_prec: int = 1, ) -> tuple[str, str]: + """Truncate raw estimate and uncertainty values to the appropriate + approximated uncertainty. + + Parameters + ---------- + est : float + Raw estimate value. + unc : float + Raw uncertainty value. + unc_prec : int, optional + Precision, by default 1 + + Returns + ------- + tuple[str, str] + The truncated raw and uncertainty values. + """ import numpy as np # get the last column needed for uncertainty unc_col = _get_column(unc) - (unc_prec - 1) @@ -41,21 +73,44 @@ def format_estimate_uncertainty( return est_str, unc_str -def is_results_json(f): - # sanity check on files before we try and deserialize - return 'estimate' in open(f, 'r').read(20) +def is_results_json(fpath:os.PathLike|str)->bool: + """Sanity check that file is a result json before we try to deserialize""" + return 'estimate' in open(fpath, 'r').read(20) + +def load_results(fpath:os.PathLike|str)->dict: + """_summary_ -def load_results(f): - # path to deserialized results + Parameters + ---------- + fpath : os.PathLike | str + The path to deserialized results. + + + Returns + ------- + dict + A dict containing data from the results JSON. + """ import json from gufe.tokenization import JSON_HANDLER - return json.load(open(f, 'r'), cls=JSON_HANDLER.decoder) + return json.load(open(fpath, 'r'), cls=JSON_HANDLER.decoder) -def get_names(result) -> tuple[str, str]: - # Result to tuple of ligand names +def get_names(result:dict) -> tuple[str, str]: + """_summary_ + + Parameters + ---------- + result : dict + A results dict. + + Returns + ------- + tuple[str, str] + Ligand names corresponding to the results. + """ nm = list(result['unit_results'].values())[0]['name'] toks = nm.split() if toks[2] == 'repeat': @@ -64,7 +119,7 @@ def get_names(result) -> tuple[str, str]: return toks[0], toks[2] -def get_type(res): +def get_type(res:dict): list_of_pur = list(res['protocol_result']['data'].values())[0] pur = list_of_pur[0] components = pur['inputs']['stateA']['components'] From 735a4749e98de2576c4f52d81e9f949290b52940 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 6 Dec 2024 09:51:03 -0800 Subject: [PATCH 02/15] Revert "add docstrings" This reverts commit 6ae5d1d33492c78a95ace4dcc0ef3890c03e2318. --- openfecli/commands/gather.py | 75 +++++------------------------------- 1 file changed, 10 insertions(+), 65 deletions(-) diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index 180be6f42..165e9a127 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -4,26 +4,11 @@ import click from openfecli import OFECommandPlugin from openfecli.clicktypes import HyphenAwareChoice - -import os import pathlib import warnings -def _get_column(val:float|int)->int: - """Determine the index (where the 0th index is the decimal) at which the - first non-zero value occurs in a full-precision string representation of a value. - - Parameters - ---------- - val : float|int - The raw value. - - Returns - ------- - int - Column index - """ +def _get_column(val): import numpy as np if val == 0: return 0 @@ -42,23 +27,6 @@ def format_estimate_uncertainty( unc: float, unc_prec: int = 1, ) -> tuple[str, str]: - """Truncate raw estimate and uncertainty values to the appropriate - approximated uncertainty. - - Parameters - ---------- - est : float - Raw estimate value. - unc : float - Raw uncertainty value. - unc_prec : int, optional - Precision, by default 1 - - Returns - ------- - tuple[str, str] - The truncated raw and uncertainty values. - """ import numpy as np # get the last column needed for uncertainty unc_col = _get_column(unc) - (unc_prec - 1) @@ -73,44 +41,21 @@ def format_estimate_uncertainty( return est_str, unc_str -def is_results_json(fpath:os.PathLike|str)->bool: - """Sanity check that file is a result json before we try to deserialize""" - return 'estimate' in open(fpath, 'r').read(20) - +def is_results_json(f): + # sanity check on files before we try and deserialize + return 'estimate' in open(f, 'r').read(20) -def load_results(fpath:os.PathLike|str)->dict: - """_summary_ - Parameters - ---------- - fpath : os.PathLike | str - The path to deserialized results. - - - Returns - ------- - dict - A dict containing data from the results JSON. - """ +def load_results(f): + # path to deserialized results import json from gufe.tokenization import JSON_HANDLER - return json.load(open(fpath, 'r'), cls=JSON_HANDLER.decoder) + return json.load(open(f, 'r'), cls=JSON_HANDLER.decoder) -def get_names(result:dict) -> tuple[str, str]: - """_summary_ - - Parameters - ---------- - result : dict - A results dict. - - Returns - ------- - tuple[str, str] - Ligand names corresponding to the results. - """ +def get_names(result) -> tuple[str, str]: + # Result to tuple of ligand names nm = list(result['unit_results'].values())[0]['name'] toks = nm.split() if toks[2] == 'repeat': @@ -119,7 +64,7 @@ def get_names(result:dict) -> tuple[str, str]: return toks[0], toks[2] -def get_type(res:dict): +def get_type(res): list_of_pur = list(res['protocol_result']['data'].values())[0] pur = list_of_pur[0] components = pur['inputs']['stateA']['components'] From 192a5d416cd59873e6edeff0c2fce5b2a392213f Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 6 Dec 2024 10:03:47 -0800 Subject: [PATCH 03/15] adding fixture --- openfecli/tests/commands/test_gather.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/openfecli/tests/commands/test_gather.py b/openfecli/tests/commands/test_gather.py index 6508763cf..2ae145374 100644 --- a/openfecli/tests/commands/test_gather.py +++ b/openfecli/tests/commands/test_gather.py @@ -34,7 +34,6 @@ def results_dir_serial(tmpdir): with resources.files('openfecli.tests.data') as d: t = tarfile.open(d / 'rbfe_results.tar.gz', mode='r') t.extractall('.') - yield @pytest.fixture @@ -44,9 +43,9 @@ def results_dir_parallel(tmpdir): with resources.files('openfecli.tests.data') as d: t = tarfile.open(d / 'results_parallel.tar.gz', mode='r') t.extractall('.') - yield + _EXPECTED_DG = b""" ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) lig_ejm_31 -0.09 0.05 From 637c5769fdcdf56e7f87b65ad8be3c28222fbf6f Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 6 Dec 2024 10:26:42 -0800 Subject: [PATCH 04/15] whitespace fixes --- openfecli/tests/commands/test_gather.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/openfecli/tests/commands/test_gather.py b/openfecli/tests/commands/test_gather.py index 2ae145374..6508763cf 100644 --- a/openfecli/tests/commands/test_gather.py +++ b/openfecli/tests/commands/test_gather.py @@ -34,6 +34,7 @@ def results_dir_serial(tmpdir): with resources.files('openfecli.tests.data') as d: t = tarfile.open(d / 'rbfe_results.tar.gz', mode='r') t.extractall('.') + yield @pytest.fixture @@ -43,8 +44,8 @@ def results_dir_parallel(tmpdir): with resources.files('openfecli.tests.data') as d: t = tarfile.open(d / 'results_parallel.tar.gz', mode='r') t.extractall('.') - yield + yield _EXPECTED_DG = b""" ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) From 270b5b54b84f2f4519fecaa0e27401b561c2a201 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 6 Dec 2024 14:55:24 -0800 Subject: [PATCH 05/15] added (failing) test for parallel results data --- openfecli/tests/commands/test_gather.py | 48 +++++++++--------- ...el.tar.gz => rbfe_results_parallel.tar.gz} | Bin 2 files changed, 24 insertions(+), 24 deletions(-) rename openfecli/tests/data/{results_parallel.tar.gz => rbfe_results_parallel.tar.gz} (100%) diff --git a/openfecli/tests/commands/test_gather.py b/openfecli/tests/commands/test_gather.py index 6508763cf..3cb1f66f7 100644 --- a/openfecli/tests/commands/test_gather.py +++ b/openfecli/tests/commands/test_gather.py @@ -26,27 +26,6 @@ def test_format_estimate_uncertainty(est, unc, unc_prec, est_str, unc_str): def test_get_column(val, col): assert _get_column(val) == col - -@pytest.fixture -def results_dir_serial(tmpdir): - """Example output data, with replicates run in serial (3 replicates per results JSON).""" - with tmpdir.as_cwd(): - with resources.files('openfecli.tests.data') as d: - t = tarfile.open(d / 'rbfe_results.tar.gz', mode='r') - t.extractall('.') - - yield - -@pytest.fixture -def results_dir_parallel(tmpdir): - """Identical data to results_dir_serial(), with replicates run in parallel (1 replicate per results JSON).""" - with tmpdir.as_cwd(): - with resources.files('openfecli.tests.data') as d: - t = tarfile.open(d / 'results_parallel.tar.gz', mode='r') - t.extractall('.') - - yield - _EXPECTED_DG = b""" ligand DG(MLE) (kcal/mol) uncertainty (kcal/mol) lig_ejm_31 -0.09 0.05 @@ -155,9 +134,29 @@ def results_dir_parallel(tmpdir): solvent lig_ejm_46 lig_jmc_28 23.4 0.8 """ +@pytest.fixture() +def results_dir_serial(tmpdir): + """Example output data, with replicates run in serial (3 replicates per results JSON).""" + with tmpdir.as_cwd(): + with resources.files('openfecli.tests.data') as d: + t = tarfile.open(d / 'rbfe_results.tar.gz', mode='r') + t.extractall('.') + + return os.path.abspath(t.getnames()[0]) + +@pytest.fixture() +def results_dir_parallel(tmpdir): + """Example output data, with replicates run in serial (3 replicates per results JSON).""" + with tmpdir.as_cwd(): + with resources.files('openfecli.tests.data') as d: + t = tarfile.open(d / 'rbfe_results_parallel.tar.gz', mode='r') + t.extractall('.') + + return os.path.abspath(t.getnames()[0]) -@pytest.mark.parametrize('report', ["", "dg", "ddg", "raw"]) -def test_gather(results_dir_serial, report): +@pytest.mark.parametrize('data_fixture', ['results_dir_parallel']) +@pytest.mark.parametrize('report', [""]) # , "dg", "ddg", "raw"]) +def test_gather(request, data_fixture, report): expected = { "": _EXPECTED_DG, "dg": _EXPECTED_DG, @@ -171,7 +170,8 @@ def test_gather(results_dir_serial, report): else: args = [] - result = runner.invoke(gather, ['results'] + args + ['-o', '-']) + results_dir = request.getfixturevalue(data_fixture) + result = runner.invoke(gather, [results_dir] + args + ['-o', '-']) assert result.exit_code == 0 diff --git a/openfecli/tests/data/results_parallel.tar.gz b/openfecli/tests/data/rbfe_results_parallel.tar.gz similarity index 100% rename from openfecli/tests/data/results_parallel.tar.gz rename to openfecli/tests/data/rbfe_results_parallel.tar.gz From 6bf8a0d95d54b19910f1fd30ee35c1341e101d5c Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 6 Dec 2024 15:11:57 -0800 Subject: [PATCH 06/15] add back all report types into testing --- openfecli/tests/commands/test_gather.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfecli/tests/commands/test_gather.py b/openfecli/tests/commands/test_gather.py index 3cb1f66f7..824b53829 100644 --- a/openfecli/tests/commands/test_gather.py +++ b/openfecli/tests/commands/test_gather.py @@ -155,7 +155,7 @@ def results_dir_parallel(tmpdir): return os.path.abspath(t.getnames()[0]) @pytest.mark.parametrize('data_fixture', ['results_dir_parallel']) -@pytest.mark.parametrize('report', [""]) # , "dg", "ddg", "raw"]) +@pytest.mark.parametrize('report', ["", "dg", "ddg", "raw"]) def test_gather(request, data_fixture, report): expected = { "": _EXPECTED_DG, From 09e423234af1993881add72491a2f94d8a874caf Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Mon, 9 Dec 2024 12:27:35 -0800 Subject: [PATCH 07/15] include serial and paralell in paramterize --- openfecli/tests/commands/test_gather.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfecli/tests/commands/test_gather.py b/openfecli/tests/commands/test_gather.py index 824b53829..8949e48ea 100644 --- a/openfecli/tests/commands/test_gather.py +++ b/openfecli/tests/commands/test_gather.py @@ -154,7 +154,7 @@ def results_dir_parallel(tmpdir): return os.path.abspath(t.getnames()[0]) -@pytest.mark.parametrize('data_fixture', ['results_dir_parallel']) +@pytest.mark.parametrize('data_fixture', ['results_dir_serial', 'results_dir_parallel']) @pytest.mark.parametrize('report', ["", "dg", "ddg", "raw"]) def test_gather(request, data_fixture, report): expected = { From 636d01027a14d9bd506bccd466262d7dc90fd74e Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 11 Dec 2024 12:29:46 -0800 Subject: [PATCH 08/15] adding support for raw output type --- openfecli/commands/gather.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index 52a16a2b2..73cc7bda8 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -258,14 +258,15 @@ def _write_raw(legs:dict, writer:Callable, allow_partial=True): writer.writerow(["leg", "ligand_i", "ligand_j", "DG(i->j) (kcal/mol)", "MBAR uncertainty (kcal/mol)"]) - for ligpair, vals in sorted(legs.items()): - for simtype, repeats in sorted(vals.items()): - for m, u in repeats: - if m is None: - m, u = 'NaN', 'NaN' - else: - m, u = format_estimate_uncertainty(m.m, u.m) - writer.writerow([simtype, *ligpair, m, u]) + for ligpair, results in sorted(legs.items()): + for simtype, repeats in sorted(results.items()): + for repeat in repeats: + for m, u in repeat: + if m is None: + m, u = 'NaN', 'NaN' + else: + m, u = format_estimate_uncertainty(m.m, u.m) + writer.writerow([simtype, *ligpair, m, u]) def _write_dg_raw(legs:dict, writer:Callable, allow_partial): # pragma: no-cover @@ -395,12 +396,11 @@ def gather(rootdir:os.PathLike|str, # 1) find all possible jsons json_fns = glob.glob(str(rootdir) + '/**/*json', recursive=True) - # 2) filter only result jsons result_fns = filter(is_results_json, json_fns) # 3) pair legs of simulations together into dict of dicts - legs = defaultdict(dict) + legs = defaultdict(lambda: defaultdict(list)) for result_fn in result_fns: result = load_results(result_fn) @@ -420,9 +420,9 @@ def gather(rootdir:os.PathLike|str, simtype = legacy_get_type(result_fn) if report.lower() == 'raw': - legs[names][simtype] = _parse_raw_units(result) + legs[names][simtype].append(_parse_raw_units(result)) else: - legs[names][simtype] = result['estimate'], result['uncertainty'] + legs[names][simtype].append(result['estimate'], result['uncertainty']) writer = csv.writer( output, From 709e517b7449fc50b41fa97466e1dc0c8b68c235 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 11 Dec 2024 16:20:46 -0800 Subject: [PATCH 09/15] expose uncertainty and estimate functions to gather --- .../protocols/openmm_rfe/equil_rfe_methods.py | 22 ++++++++++++++----- openfecli/commands/gather.py | 8 +++++-- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/openfe/protocols/openmm_rfe/equil_rfe_methods.py b/openfe/protocols/openmm_rfe/equil_rfe_methods.py index 2b80370e0..b7bb59053 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_methods.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_methods.py @@ -256,6 +256,15 @@ def __init__(self, **data): if any(len(pur_list) > 2 for pur_list in self.data.values()): raise NotImplementedError("Can't stitch together results yet") + @staticmethod + def compute_mean_estimate(dGs:list[dict]): + u = dGs[0].u + # convert all values to units of the first value, then take average of magnitude + # this would avoid a screwy case where each value was in different units + vals = [dG.to(u).m for dG in dGs] + + return np.average(vals) * u + def get_estimate(self) -> unit.Quantity: """Average free energy difference of this transformation @@ -267,24 +276,25 @@ def get_estimate(self) -> unit.Quantity: """ # TODO: Check this holds up completely for SAMS. dGs = [pus[0].outputs['unit_estimate'] for pus in self.data.values()] + return self.compute_mean_estimate(dGs) + + @staticmethod + def compute_uncertainty(dGs:list): u = dGs[0].u # convert all values to units of the first value, then take average of magnitude # this would avoid a screwy case where each value was in different units vals = [dG.to(u).m for dG in dGs] - return np.average(vals) * u + return np.std(vals) * u def get_uncertainty(self) -> unit.Quantity: """The uncertainty/error in the dG value: The std of the estimates of each independent repeat """ + dGs = [pus[0].outputs['unit_estimate'] for pus in self.data.values()] - u = dGs[0].u - # convert all values to units of the first value, then take average of magnitude - # this would avoid a screwy case where each value was in different units - vals = [dG.to(u).m for dG in dGs] + return self.compute_uncertainty(dGs) - return np.std(vals) * u def get_individual_estimates(self) -> list[tuple[unit.Quantity, unit.Quantity]]: """Return a list of tuples containing the individual free energy diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index 73cc7bda8..fd17c58fb 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -7,6 +7,8 @@ from typing import Callable, Literal import warnings +from openfe.protocols.openmm_rfe.equil_rfe_methods import RelativeHybridTopologyProtocolResult as rfe_result +from openfe.protocols import openmm_rfe from openfecli import OFECommandPlugin from openfecli.clicktypes import HyphenAwareChoice @@ -200,7 +202,6 @@ def _parse_raw_units(results: dict) -> list[tuple]: pu[0]['outputs']['unit_estimate_error']) for pu in list_of_pur] - def _get_ddgs(legs:dict, error_on_missing=True): import numpy as np DDGs = [] @@ -396,6 +397,7 @@ def gather(rootdir:os.PathLike|str, # 1) find all possible jsons json_fns = glob.glob(str(rootdir) + '/**/*json', recursive=True) + # 2) filter only result jsons result_fns = filter(is_results_json, json_fns) @@ -422,7 +424,9 @@ def gather(rootdir:os.PathLike|str, if report.lower() == 'raw': legs[names][simtype].append(_parse_raw_units(result)) else: - legs[names][simtype].append(result['estimate'], result['uncertainty']) + dGs = [v[0]['outputs']['unit_estimate'] for v in result['protocol_result']['data'].values()] + ## for jobs run in parallel, we need to compute these values + legs[names][simtype] = (rfe_result.compute_mean_estimate(dGs), rfe_result.compute_uncertainty(dGs)) writer = csv.writer( output, From a6103df8b74e15b25f6d6e823f57e14b001d229b Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 11 Dec 2024 16:40:47 -0800 Subject: [PATCH 10/15] pass dGs through - works but isn't pretty --- openfecli/commands/gather.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index fd17c58fb..2c44d0f0d 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -216,16 +216,21 @@ def _get_ddgs(legs:dict, error_on_missing=True): do_rhfe = (len(set_vals & {'vacuum', 'solvent'}) == 2) if do_rbfe: - DG1_mag, DG1_unc = vals['complex'] - DG2_mag, DG2_unc = vals['solvent'] + # TODO: make this less ugly + DG1_mag = rfe_result.compute_mean_estimate(vals['complex']) + DG1_unc = rfe_result.compute_uncertainty(vals['complex']) + DG2_mag = rfe_result.compute_mean_estimate(vals['solvent']) + DG2_unc = rfe_result.compute_uncertainty(vals['solvent']) if not ((DG1_mag is None) or (DG2_mag is None)): # DDG(2,1)bind = DG(1->2)complex - DG(1->2)solvent DDGbind = (DG1_mag - DG2_mag).m bind_unc = np.sqrt(np.sum(np.square([DG1_unc.m, DG2_unc.m]))) if do_rhfe: - DG1_mag, DG1_unc = vals['solvent'] - DG2_mag, DG2_unc = vals['vacuum'] + DG1_mag = rfe_result.compute_mean_estimate(vals['solvent']) + DG1_unc = rfe_result.compute_uncertainty(vals['solvent']) + DG2_mag = rfe_result.compute_mean_estimate(vals['vacuum']) + DG2_unc = rfe_result.compute_uncertainty(vals['vacuum']) if not ((DG1_mag is None) or (DG2_mag is None)): DDGhyd = (DG1_mag - DG2_mag).m hyd_unc = np.sqrt(np.sum(np.square([DG1_unc.m, DG2_unc.m]))) @@ -426,7 +431,7 @@ def gather(rootdir:os.PathLike|str, else: dGs = [v[0]['outputs']['unit_estimate'] for v in result['protocol_result']['data'].values()] ## for jobs run in parallel, we need to compute these values - legs[names][simtype] = (rfe_result.compute_mean_estimate(dGs), rfe_result.compute_uncertainty(dGs)) + legs[names][simtype].extend(dGs) writer = csv.writer( output, From 030e85c25889efaf9927619d779aa533712c311b Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Thu, 12 Dec 2024 07:31:02 -0800 Subject: [PATCH 11/15] remove todo --- openfecli/commands/gather.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openfecli/commands/gather.py b/openfecli/commands/gather.py index 2c44d0f0d..a3476b400 100644 --- a/openfecli/commands/gather.py +++ b/openfecli/commands/gather.py @@ -216,7 +216,6 @@ def _get_ddgs(legs:dict, error_on_missing=True): do_rhfe = (len(set_vals & {'vacuum', 'solvent'}) == 2) if do_rbfe: - # TODO: make this less ugly DG1_mag = rfe_result.compute_mean_estimate(vals['complex']) DG1_unc = rfe_result.compute_uncertainty(vals['complex']) DG2_mag = rfe_result.compute_mean_estimate(vals['solvent']) From 38d2f2ca87208b92f08ff5a8d51186e470649dc8 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 13 Dec 2024 10:43:17 -0800 Subject: [PATCH 12/15] updating changelog --- news/support_gather_parallel.rst | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 news/support_gather_parallel.rst diff --git a/news/support_gather_parallel.rst b/news/support_gather_parallel.rst new file mode 100644 index 000000000..6a21d0202 --- /dev/null +++ b/news/support_gather_parallel.rst @@ -0,0 +1,23 @@ +**Added:** + +* + +**Changed:** + +* ``openfe gather`` now supports replicates that have been submitted in parallel across separate directories. + +**Deprecated:** + +* + +**Removed:** + +* + +**Fixed:** + +* + +**Security:** + +* From 8d966d4da235dd7843dfb385609ee69986052bc0 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Fri, 13 Dec 2024 10:43:17 -0800 Subject: [PATCH 13/15] updating changelog --- news/support_gather_parallel.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/news/support_gather_parallel.rst b/news/support_gather_parallel.rst index 6a21d0202..5b3c00b8f 100644 --- a/news/support_gather_parallel.rst +++ b/news/support_gather_parallel.rst @@ -1,10 +1,10 @@ **Added:** -* +* ``openfe gather`` now supports replicates that have been submitted in parallel across separate directories. **Changed:** -* ``openfe gather`` now supports replicates that have been submitted in parallel across separate directories. +* **Deprecated:** From 47a9b8cc7b6cb16ee35c9f4cafc425654ff1ebd1 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz <31974495+atravitz@users.noreply.github.com> Date: Tue, 17 Dec 2024 14:53:09 -0800 Subject: [PATCH 14/15] Update openfe/protocols/openmm_rfe/equil_rfe_methods.py Co-authored-by: Hannah Baumann <43765638+hannahbaumann@users.noreply.github.com> --- openfe/protocols/openmm_rfe/equil_rfe_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_rfe/equil_rfe_methods.py b/openfe/protocols/openmm_rfe/equil_rfe_methods.py index b7bb59053..d0cecb6b8 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_methods.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_methods.py @@ -279,7 +279,7 @@ def get_estimate(self) -> unit.Quantity: return self.compute_mean_estimate(dGs) @staticmethod - def compute_uncertainty(dGs:list): + def compute_uncertainty(dGs:list[unit.Quantity]): u = dGs[0].u # convert all values to units of the first value, then take average of magnitude # this would avoid a screwy case where each value was in different units From 6ec1dcbafea688fa3840ecbd1890e670ada573d6 Mon Sep 17 00:00:00 2001 From: Alyssa Travitz Date: Wed, 18 Dec 2024 15:46:40 -0800 Subject: [PATCH 15/15] fix type hint --- openfe/protocols/openmm_rfe/equil_rfe_methods.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openfe/protocols/openmm_rfe/equil_rfe_methods.py b/openfe/protocols/openmm_rfe/equil_rfe_methods.py index d0cecb6b8..7bf92050e 100644 --- a/openfe/protocols/openmm_rfe/equil_rfe_methods.py +++ b/openfe/protocols/openmm_rfe/equil_rfe_methods.py @@ -257,7 +257,7 @@ def __init__(self, **data): raise NotImplementedError("Can't stitch together results yet") @staticmethod - def compute_mean_estimate(dGs:list[dict]): + def compute_mean_estimate(dGs:list[unit.Quantity]): u = dGs[0].u # convert all values to units of the first value, then take average of magnitude # this would avoid a screwy case where each value was in different units