From 94ea87881e50863f734e052f5749b386ea5795df Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:14:55 -0400 Subject: [PATCH 01/16] GIT: update workflow --- .github/workflows/main.yml | 2 +- ChemSpaceAL/tests/test_config.py | 7 +++++++ tests/test_config.py | 6 ------ 3 files changed, 8 insertions(+), 7 deletions(-) create mode 100644 ChemSpaceAL/tests/test_config.py delete mode 100644 tests/test_config.py diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 840bd69..7af98e4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,7 +2,7 @@ name: Python application test with pytest on: push: - branches: [ main ] + branches: [ main, sandbox ] jobs: build: diff --git a/ChemSpaceAL/tests/test_config.py b/ChemSpaceAL/tests/test_config.py new file mode 100644 index 0000000..11e3cdb --- /dev/null +++ b/ChemSpaceAL/tests/test_config.py @@ -0,0 +1,7 @@ +import ChemSpaceAL.InitializeWorkspace as iw +import os + +def test_config(): + base_path = os.getcwd() + "/PaperRuns/" + assert isinstance(iw.FOLDER_STRUCTURE, dict) + assert True diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index 1662e2c..0000000 --- a/tests/test_config.py +++ /dev/null @@ -1,6 +0,0 @@ -import ChemSpaceAL.InitializeWorkspace -import os - -def test_config(): - base_path = os.getcwd() + "/PaperRuns/" - assert True From c94601b266d5de8260034e1927fe8cd02f0b94f2 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:17:14 -0400 Subject: [PATCH 02/16] GIT: update workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7af98e4..ea3d213 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: python setup.py install - name: Run tests and collect coverage - run: pytest --cov + run: pytest --cov=ChemSpaceAL - name: Upload coverage to Codecov uses: codecov/codecov-action@v4-beta env: From f1306ee895e2d289f756e515725cfb23afbc2113 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:21:34 -0400 Subject: [PATCH 03/16] TESTS: check folder creation --- ChemSpaceAL/tests/test_config.py | 7 ------- ChemSpaceAL/tests/test_initialize_workspace.py | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 7 deletions(-) delete mode 100644 ChemSpaceAL/tests/test_config.py create mode 100644 ChemSpaceAL/tests/test_initialize_workspace.py diff --git a/ChemSpaceAL/tests/test_config.py b/ChemSpaceAL/tests/test_config.py deleted file mode 100644 index 11e3cdb..0000000 --- a/ChemSpaceAL/tests/test_config.py +++ /dev/null @@ -1,7 +0,0 @@ -import ChemSpaceAL.InitializeWorkspace as iw -import os - -def test_config(): - base_path = os.getcwd() + "/PaperRuns/" - assert isinstance(iw.FOLDER_STRUCTURE, dict) - assert True diff --git a/ChemSpaceAL/tests/test_initialize_workspace.py b/ChemSpaceAL/tests/test_initialize_workspace.py new file mode 100644 index 0000000..3438fec --- /dev/null +++ b/ChemSpaceAL/tests/test_initialize_workspace.py @@ -0,0 +1,18 @@ +import os +import tempfile +from unittest.mock import patch +import ChemSpaceAL.InitializeWorkspace as iw + + +def test_create_default_folders(): + # Using a temporary directory for testing + with tempfile.TemporaryDirectory() as tempdir: + iw.create_folders(base_path=tempdir) + + # Check if the main folders are created + assert os.path.exists(os.path.join(tempdir, "1_Pretraining")) + assert os.path.exists(os.path.join(tempdir, "2_Generation")) + + # Check if subfolders are created + assert os.path.exists(os.path.join(tempdir, "1_Pretraining", "datasets")) + # ... (add more assertions for other subfolders) From 317f91ff5b2ce58c7b0221ef1d5157efa5c8399e Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:35:05 -0400 Subject: [PATCH 04/16] TESTS: do absolute imports --- ChemSpaceAL/tests/test_initialize_workspace.py | 2 +- README.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChemSpaceAL/tests/test_initialize_workspace.py b/ChemSpaceAL/tests/test_initialize_workspace.py index 3438fec..fa4bf24 100644 --- a/ChemSpaceAL/tests/test_initialize_workspace.py +++ b/ChemSpaceAL/tests/test_initialize_workspace.py @@ -1,7 +1,7 @@ import os import tempfile from unittest.mock import patch -import ChemSpaceAL.InitializeWorkspace as iw +from ChemSpaceAL import InitializeWorkspace as iw def test_create_default_folders(): diff --git a/README.md b/README.md index 400eaf6..156487d 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,6 @@ ChemSpaceAL: An Efficient Active Learning Methodology Applied to Protein- Specif [![Checked with mypy](https://www.mypy-lang.org/static/mypy_badge.svg)](https://mypy-lang.org/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![codecov](https://codecov.io/gh/batistagroup/ChemSpaceAL/graph/badge.svg?token=ROJSISYJWC)](https://codecov.io/gh/batistagroup/ChemSpaceAL) ![A description of the active learning methodology](media/toc_figure.jpg) From 4a1f3882d73e529add0871f7f896e818e59fd7ec Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:42:34 -0400 Subject: [PATCH 05/16] TESTS: add codecov components --- codecov.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 codecov.yml diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..6b4e5e0 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,31 @@ +codecov: + project: + enabled: false + patch: + only_pulls: true + notify: + require_ci_to_pass: yes + +coverage: + precision: 2 + round: down + range: "0...90" + + status: + project: yes + patch: yes + changes: no + +comment: + layout: "header, diff, components" + +component_management: + default_rules: + statuses: + - type: patch + target: auto + individual_components: + - component_id: module_iw + name: InitializeWorkspace + paths: + - "ChemSpaceAL/InitializeWorkspace.py" From aeb8580db218a86f15a1f03e51fb2c7b4571ebe1 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:46:56 -0400 Subject: [PATCH 06/16] TESTS: update codecov.yml --- codecov.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/codecov.yml b/codecov.yml index 6b4e5e0..4cea1e8 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,11 +1,3 @@ -codecov: - project: - enabled: false - patch: - only_pulls: true - notify: - require_ci_to_pass: yes - coverage: precision: 2 round: down From 4b9c2e1f85012741355f1b52e96f8e4132dcc459 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:55:17 -0400 Subject: [PATCH 07/16] TESTS: add more checks --- ChemSpaceAL/tests/test_initialize_workspace.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ChemSpaceAL/tests/test_initialize_workspace.py b/ChemSpaceAL/tests/test_initialize_workspace.py index fa4bf24..b03ce7c 100644 --- a/ChemSpaceAL/tests/test_initialize_workspace.py +++ b/ChemSpaceAL/tests/test_initialize_workspace.py @@ -16,3 +16,11 @@ def test_create_default_folders(): # Check if subfolders are created assert os.path.exists(os.path.join(tempdir, "1_Pretraining", "datasets")) # ... (add more assertions for other subfolders) + assert isinstance(iw.FOLDER_STRUCTURE, dict) + + +@patch("builtins.input", return_value="Y") +def test_create_folders_without_base_path(mock_input): + with tempfile.TemporaryDirectory() as tempdir: + os.chdir(tempdir) # Change working directory + iw.create_folders() From 3edbe102ba82b012e6266aafe733a48cea45dd6b Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 16:58:36 -0400 Subject: [PATCH 08/16] TESTS: modify workflow --- .github/workflows/main.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index ea3d213..a09261d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,10 +23,6 @@ jobs: python -m pip install --upgrade pip pip install pytest pytest-cov - - name: Install package - run: | - python setup.py install - - name: Run tests and collect coverage run: pytest --cov=ChemSpaceAL - name: Upload coverage to Codecov From 5866267ddc25ed8c41824f1002df20cdb6b88954 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:00:19 -0400 Subject: [PATCH 09/16] GIT: try relative imports --- ChemSpaceAL/tests/test_initialize_workspace.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ChemSpaceAL/tests/test_initialize_workspace.py b/ChemSpaceAL/tests/test_initialize_workspace.py index b03ce7c..1a2476b 100644 --- a/ChemSpaceAL/tests/test_initialize_workspace.py +++ b/ChemSpaceAL/tests/test_initialize_workspace.py @@ -1,7 +1,7 @@ import os import tempfile from unittest.mock import patch -from ChemSpaceAL import InitializeWorkspace as iw +from .. import InitializeWorkspace as iw def test_create_default_folders(): From 799351d8112a71b7f6e8e79d6b5100b6dafeb960 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:01:37 -0400 Subject: [PATCH 10/16] GIT: make tests a module folder --- ChemSpaceAL/tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 ChemSpaceAL/tests/__init__.py diff --git a/ChemSpaceAL/tests/__init__.py b/ChemSpaceAL/tests/__init__.py new file mode 100644 index 0000000..e69de29 From efb218d80395f1dbcedc2b8d711a514b7b5b3cae Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:07:01 -0400 Subject: [PATCH 11/16] TESTS: add .coveragerc --- .coveragerc | 10 ++++++++++ ChemSpaceAL/Configuration.py | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .coveragerc diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..147c6da --- /dev/null +++ b/.coveragerc @@ -0,0 +1,10 @@ +[run] +source = + ChemSpaceAL/InitializeWorkspace.py + +omit = + ChemSpaceAL/Model.py + ChemSpaceAL/Dataset.py + ChemSpaceAL/Docking.py + ChemSpaceAL/Generation.py + ChemSpaceAL/Training.py diff --git a/ChemSpaceAL/Configuration.py b/ChemSpaceAL/Configuration.py index 48d1943..69a8399 100644 --- a/ChemSpaceAL/Configuration.py +++ b/ChemSpaceAL/Configuration.py @@ -2,7 +2,7 @@ from torch.nn import Module import os from typing import Union, Dict, Any, List, Tuple, Optional, Any, Set, Callable, cast -from ChemSpaceAL.InitializeWorkspace import FOLDER_STRUCTURE as fldr_struc +from .InitializeWorkspace import FOLDER_STRUCTURE as fldr_struc import textwrap from rdkit.Chem import Descriptors from rdkit import Chem From dd84f3413ad7416da0497bf2e12ec3edde2ab450 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:10:27 -0400 Subject: [PATCH 12/16] TESTS: remove patch tracking? --- codecov.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codecov.yml b/codecov.yml index 4cea1e8..289ecd5 100644 --- a/codecov.yml +++ b/codecov.yml @@ -5,7 +5,7 @@ coverage: status: project: yes - patch: yes + patch: no changes: no comment: From b8c3352bc2142011b09860d26ade9464aa446e09 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:25:29 -0400 Subject: [PATCH 13/16] TESTS: probability conversion tests --- ChemSpaceAL/ALConstruction.py | 4 +- ChemSpaceAL/Configuration.py | 2 +- ChemSpaceAL/tests/test_al_construction.py | 75 +++++++++++++++++++++++ codecov.yml | 6 +- 4 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 ChemSpaceAL/tests/test_al_construction.py diff --git a/ChemSpaceAL/ALConstruction.py b/ChemSpaceAL/ALConstruction.py index 0bcc3cf..afba815 100644 --- a/ChemSpaceAL/ALConstruction.py +++ b/ChemSpaceAL/ALConstruction.py @@ -67,7 +67,6 @@ def _preprocess_scores_linearly( normalized = {k: v / total for k, v in negated.items()} return normalized - def _preprocess_scores_softmax( scores: Dict[int, Number], do_negation: bool = False, @@ -89,8 +88,7 @@ def _preprocess_scores_softmax( total = sum(exponentiate.values()) softmax = {k: v / total for k, v in exponentiate.items()} return softmax - - + def balance_cluster_to_n( cluster_to_n: Dict[int, int], cluster_to_len: Dict[int, int] ) -> Dict[int, int]: diff --git a/ChemSpaceAL/Configuration.py b/ChemSpaceAL/Configuration.py index 69a8399..48d1943 100644 --- a/ChemSpaceAL/Configuration.py +++ b/ChemSpaceAL/Configuration.py @@ -2,7 +2,7 @@ from torch.nn import Module import os from typing import Union, Dict, Any, List, Tuple, Optional, Any, Set, Callable, cast -from .InitializeWorkspace import FOLDER_STRUCTURE as fldr_struc +from ChemSpaceAL.InitializeWorkspace import FOLDER_STRUCTURE as fldr_struc import textwrap from rdkit.Chem import Descriptors from rdkit import Chem diff --git a/ChemSpaceAL/tests/test_al_construction.py b/ChemSpaceAL/tests/test_al_construction.py new file mode 100644 index 0000000..a872a6f --- /dev/null +++ b/ChemSpaceAL/tests/test_al_construction.py @@ -0,0 +1,75 @@ +from ..ALConstruction import _preprocess_scores_linearly, _preprocess_scores_softmax +import pytest + + +@pytest.mark.parametrize( + "scores, do_negation, expected", + [ + ( + {1: 2, 2: 2, 3: 2}, + False, + {1: 1 / 3, 2: 1 / 3, 3: 1 / 3}, + ), + ( + {1: 1, 2: 0, 3: 0}, + False, + {1: 1, 2: 0, 3: 0}, + ), + ({}, False, {}), + ( + {1: 0, 2: -2, 3: -2}, + True, + {1: 0, 2: 0.5, 3: 0.5}, + ), + ], +) +def test_preprocess_scores_linearly(scores, do_negation, expected): + result = _preprocess_scores_linearly(scores, do_negation) + for k, v in expected.items(): + assert result[k] == pytest.approx(v) + + +@pytest.mark.parametrize( + "scores, do_negation, divide, divide_factor, expected", + [ + ( + {1: 2, 2: 2, 3: 2}, + False, + False, + None, + {1: 1 / 3, 2: 1 / 3, 3: 1 / 3}, + ), + ( + {1: 1, 2: 0, 3: 0}, + False, + False, + None, + {1: 0.5761168847658291, 2: 0.21194155761708544, 3: 0.21194155761708544}, + ), + ( + {1: 1, 2: 0, 3: 0}, + False, + True, + 0.5, + {1: 0.7869860421615985, 2: 0.10650697891920075, 3: 0.10650697891920075}, + ), + ( + {1: -1, 2: -1, 3: 0}, + True, + True, + 0.5, + {1: 0.4683105308334812, 2: 0.4683105308334812, 3: 0.06337893833303762}, + ), + ], +) +def test_preprocess_scores_softmax( + scores, do_negation, divide, divide_factor, expected +): + result = _preprocess_scores_softmax(scores, do_negation, divide, divide_factor) + for k, v in expected.items(): + assert result[k] == pytest.approx(v) + + +def test_preprocess_scores_softmax_exception(): + with pytest.raises(AssertionError): + _preprocess_scores_softmax({1: 2, 2: 3, 3: 4}, False, True, None) diff --git a/codecov.yml b/codecov.yml index 289ecd5..32bbacd 100644 --- a/codecov.yml +++ b/codecov.yml @@ -5,7 +5,7 @@ coverage: status: project: yes - patch: no + patch: yes changes: no comment: @@ -21,3 +21,7 @@ component_management: name: InitializeWorkspace paths: - "ChemSpaceAL/InitializeWorkspace.py" + - component_id: module_al_construct + name: AL Training Set Construction + paths: + - "ChemSpaceAL/ALConstruction.py" From dc2169afc5c8ae974ccb5a9424344d9e4ae362b0 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:26:43 -0400 Subject: [PATCH 14/16] GIT: add dependencies to workflow --- .github/workflows/main.yml | 1 + ChemSpaceAL/ALConstruction.py | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a09261d..6a18e2a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,6 +21,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip + pip install pandas, numpy pip install pytest pytest-cov - name: Run tests and collect coverage diff --git a/ChemSpaceAL/ALConstruction.py b/ChemSpaceAL/ALConstruction.py index afba815..7b6a1da 100644 --- a/ChemSpaceAL/ALConstruction.py +++ b/ChemSpaceAL/ALConstruction.py @@ -1,7 +1,6 @@ import pandas as pd import numpy as np import pickle -import plotly.graph_objects as go from ChemSpaceAL.Configuration import Config from typing import Union, Dict, List, Callable, Optional, cast @@ -88,7 +87,7 @@ def _preprocess_scores_softmax( total = sum(exponentiate.values()) softmax = {k: v / total for k, v in exponentiate.items()} return softmax - + def balance_cluster_to_n( cluster_to_n: Dict[int, int], cluster_to_len: Dict[int, int] ) -> Dict[int, int]: From a705741f19ff290b925805b4e2124a6790d45868 Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:27:55 -0400 Subject: [PATCH 15/16] GIT: who writes commas in pip install.... --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6a18e2a..17e0bed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pandas, numpy + pip install pandas numpy pip install pytest pytest-cov - name: Run tests and collect coverage From 721152dc64dfbcd0a7752046ff315b460371694f Mon Sep 17 00:00:00 2001 From: Anton Morgunov Date: Tue, 24 Oct 2023 17:33:59 -0400 Subject: [PATCH 16/16] GIT: add more dependencies to the workflow --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 17e0bed..d8342b9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,7 +21,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install pandas numpy + pip install pandas numpy torch rdkit pip install pytest pytest-cov - name: Run tests and collect coverage