mirror of
https://github.com/OpenFreeEnergy/openfe.git
synced 2026-06-04 14:14:22 +08:00
Merge branch 'main' into fix/charge_molecules_cli_formatting
This commit is contained in:
@@ -378,18 +378,25 @@ Now the CLI tool should work as well ::
|
||||
--log PATH logging configuration file
|
||||
-h, --help Show this message and exit.
|
||||
|
||||
Setup Commands:
|
||||
atommapping Check the atom mapping of a given pair of ligands
|
||||
plan-rhfe-network Plan a relative hydration free energy network, saved in a
|
||||
dir with multiple JSON files
|
||||
plan-rbfe-network Plan a relative binding free energy network, saved in a
|
||||
dir with multiple JSON files.
|
||||
Network Planning Commands:
|
||||
plan-rhfe-network Plan a relative hydration free energy network, saved as
|
||||
JSON files for the quickrun command.
|
||||
plan-rbfe-network Plan a relative binding free energy network, saved as
|
||||
JSON files for the quickrun command.
|
||||
view-ligand-network Visualize a ligand network
|
||||
|
||||
Simulation Commands:
|
||||
gather Gather DAG result jsons for network of RFE results into single TSV
|
||||
file
|
||||
Quickrun Executor Commands:
|
||||
gather Gather result jsons for network of RFE results into a TSV file
|
||||
quickrun Run a given transformation, saved as a JSON file
|
||||
|
||||
Miscellaneous Commands:
|
||||
fetch Fetch tutorial or other resource.
|
||||
charge-molecules Generate partial charges for a set of molecules.
|
||||
test Run the OpenFE test suite
|
||||
|
||||
|
||||
|
||||
|
||||
To make sure everything is working, run the tests ::
|
||||
|
||||
$ pytest --pyargs openfe openfecli
|
||||
|
||||
23
news/add_filepaths_support.rst
Normal file
23
news/add_filepaths_support.rst
Normal file
@@ -0,0 +1,23 @@
|
||||
**Added:**
|
||||
|
||||
* ``openfe gather`` now accepts any number of filepaths and/or directories containing results JSON files, instead of only accepting one results directory.
|
||||
|
||||
**Changed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Deprecated:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Removed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Fixed:**
|
||||
|
||||
* <news item>
|
||||
|
||||
**Security:**
|
||||
|
||||
* <news item>
|
||||
@@ -4,7 +4,7 @@
|
||||
import click
|
||||
import os
|
||||
import pathlib
|
||||
from typing import Callable, Literal
|
||||
from typing import Callable, Literal, List
|
||||
import warnings
|
||||
|
||||
from openfecli import OFECommandPlugin
|
||||
@@ -370,8 +370,9 @@ def _write_dg_mle(legs:dict, writer:Callable, allow_partial:bool):
|
||||
'gather',
|
||||
short_help="Gather result jsons for network of RFE results into a TSV file"
|
||||
)
|
||||
@click.argument('rootdir',
|
||||
type=click.Path(dir_okay=True, file_okay=False,
|
||||
@click.argument('results',
|
||||
nargs=-1, # accept any number of results
|
||||
type=click.Path(dir_okay=True, file_okay=True,
|
||||
path_type=pathlib.Path),
|
||||
required=True)
|
||||
@click.option(
|
||||
@@ -395,14 +396,15 @@ def _write_dg_mle(legs:dict, writer:Callable, allow_partial:bool):
|
||||
"(Skip those edges and issue warning instead.)"
|
||||
)
|
||||
)
|
||||
def gather(rootdir:os.PathLike|str,
|
||||
def gather(results:List[os.PathLike|str],
|
||||
output:os.PathLike|str,
|
||||
report:Literal['dg','ddg','raw'],
|
||||
allow_partial:bool
|
||||
):
|
||||
"""Gather simulation result jsons of relative calculations to a tsv file
|
||||
"""Gather simulation result JSON files of relative calculations to a tsv file.
|
||||
|
||||
This walks ROOTDIR recursively and finds all result JSON files from the
|
||||
|
||||
This walks RESULTS recursively and finds all result JSON files from the
|
||||
quickrun command (these files must end in .json). Each of these contains
|
||||
the results of a separate leg from a relative free energy thermodynamic
|
||||
cycle.
|
||||
@@ -427,8 +429,19 @@ def gather(rootdir:os.PathLike|str,
|
||||
import glob
|
||||
import csv
|
||||
|
||||
results = sorted(results) # not necessary, but ensures reproducibility
|
||||
def collect_jsons(results:List[os.PathLike]):
|
||||
all_jsons = []
|
||||
for p in results:
|
||||
if str(p).endswith('json'):
|
||||
all_jsons.append(p)
|
||||
elif p.is_dir():
|
||||
all_jsons.extend(glob.glob(f"{p}/**/*json", recursive=True))
|
||||
|
||||
return all_jsons
|
||||
|
||||
# 1) find all possible jsons
|
||||
json_fns = glob.glob(str(rootdir) + '/**/*json', recursive=True)
|
||||
json_fns = collect_jsons(results)
|
||||
|
||||
# 2) filter only result jsons
|
||||
result_fns = filter(is_results_json, json_fns)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import glob
|
||||
from click.testing import CliRunner
|
||||
import os
|
||||
import pathlib
|
||||
@@ -230,7 +231,8 @@ def rbfe_result_dir()->pathlib.Path:
|
||||
@pytest.mark.skipif(not os.path.exists(POOCH_CACHE) and not HAS_INTERNET,reason="Internet seems to be unavailable and test data is not cached locally.")
|
||||
@pytest.mark.parametrize('dataset', ['rbfe_results_serial_repeats', 'rbfe_results_parallel_repeats'])
|
||||
@pytest.mark.parametrize('report', ["", "dg", "ddg", "raw"])
|
||||
def test_gather(rbfe_result_dir, dataset, report):
|
||||
@pytest.mark.parametrize('input_mode', ['directory','filepaths'])
|
||||
def test_gather(rbfe_result_dir, dataset, report, input_mode):
|
||||
|
||||
expected = {
|
||||
"": _EXPECTED_DG,
|
||||
@@ -245,12 +247,18 @@ def test_gather(rbfe_result_dir, dataset, report):
|
||||
else:
|
||||
args = []
|
||||
|
||||
results_dir = rbfe_result_dir(dataset)
|
||||
result = runner.invoke(gather, [str(results_dir)] + args + ['-o', '-'])
|
||||
results = rbfe_result_dir(dataset)
|
||||
if input_mode == 'directory':
|
||||
results = [str(results)]
|
||||
elif input_mode == 'filepaths':
|
||||
results = glob.glob(f"{results}/*", recursive=True)
|
||||
assert len(results) > 1 # sanity check to make sure we're passing in multiple paths
|
||||
|
||||
assert_click_success(result)
|
||||
cli_result = runner.invoke(gather, results + args + ['-o', '-'])
|
||||
|
||||
actual_lines = set(result.stdout_bytes.split(b'\n'))
|
||||
assert_click_success(cli_result)
|
||||
|
||||
actual_lines = set(cli_result.stdout_bytes.split(b'\n'))
|
||||
assert set(expected.split(b'\n')) == actual_lines
|
||||
|
||||
@pytest.mark.skipif(not os.path.exists(POOCH_CACHE) and not HAS_INTERNET,reason="Internet seems to be unavailable and test data is not cached locally.")
|
||||
|
||||
Reference in New Issue
Block a user