diff --git a/archives/prospr_core.tar.gz b/archives/prospr_core.tar.gz index d80a4eb..ec4589e 100644 Binary files a/archives/prospr_core.tar.gz and b/archives/prospr_core.tar.gz differ diff --git a/archives/prospr_core.zip b/archives/prospr_core.zip index 5652619..d0aee49 100644 Binary files a/archives/prospr_core.zip and b/archives/prospr_core.zip differ diff --git a/docs/source/quickstart.rst b/docs/source/quickstart.rst index 523055f..27a921e 100644 --- a/docs/source/quickstart.rst +++ b/docs/source/quickstart.rst @@ -75,6 +75,9 @@ all keep track of exactly. p_2d.solutions_checked >>> 0 + p_2d.aminos_placed + >>> 1 + p_2d.bond_values >>> {"HH": -1} diff --git a/prospr/__init__.py b/prospr/__init__.py index b85b33b..a4b0ddb 100644 --- a/prospr/__init__.py +++ b/prospr/__init__.py @@ -1,5 +1,6 @@ from prospr_core import AminoAcid, Protein, depth_first, depth_first_bnb from .datasets import load_vanEck250, load_vanEck1000 +from .visualize import plot_protein __all__ = [ "AminoAcid", @@ -8,4 +9,5 @@ "depth_first_bnb", "load_vanEck250", "load_vanEck1000", + "plot_protein", ] diff --git a/prospr/core/core_module.cpp b/prospr/core/core_module.cpp index c80d916..9c55def 100644 --- a/prospr/core/core_module.cpp +++ b/prospr/core/core_module.cpp @@ -43,6 +43,8 @@ PYBIND11_MODULE(prospr_core, m) { py::arg("bond_symmetry")=true) .def_property_readonly("solutions_checked", &Protein::get_solutions_checked) + .def_property_readonly("aminos_placed", + &Protein::get_aminos_placed) .def_property_readonly("cur_len", &Protein::get_cur_len) .def_property_readonly("dim", &Protein::get_dim) .def_property_readonly("bond_values", &Protein::get_bond_values) diff --git a/prospr/core/src/depth_first_bnb.cpp b/prospr/core/src/depth_first_bnb.cpp index e8c83e1..b2e696b 100644 --- a/prospr/core/src/depth_first_bnb.cpp +++ b/prospr/core/src/depth_first_bnb.cpp @@ -17,7 +17,7 @@ /* Returns true if the branch cannot produce a better score. */ bool prune_branch(Protein* protein, int max_length, int no_neighbors, int move, int best_score) { - protein->place_amino(move); + protein->place_amino(move, false); int cur_len = protein->get_cur_len(); int cur_score = protein->get_score(); diff --git a/prospr/core/src/protein.cpp b/prospr/core/src/protein.cpp index 7bc7c41..eb15837 100644 --- a/prospr/core/src/protein.cpp +++ b/prospr/core/src/protein.cpp @@ -22,6 +22,7 @@ Protein::Protein(std::string sequence, int dim, std::string model, last_pos.assign(dim, 0); score = 0; solutions_checked = 0; + aminos_placed = 0; /* Deduct what model to use, or apply custom one. */ if (model == "HP") { @@ -94,6 +95,7 @@ Protein::Protein(std::string sequence, int dim, std::string model, if (sequence.size() != 0) { space[last_pos] = amino_acids[0]; cur_len++; + aminos_placed++; } } @@ -147,6 +149,11 @@ int Protein::get_solutions_checked() { return solutions_checked; } +/* Returns the number of amino acids placed. */ +int Protein::get_aminos_placed() { + return aminos_placed; +} + /* Returns if the amino acid at the given index is weighted. */ bool Protein::is_weighted(int index) { return weighted_amino_acids.find(sequence[index]) != std::string::npos; @@ -176,6 +183,7 @@ void Protein::reset() { last_move = 0; score = 0; solutions_checked = 0; + aminos_placed = 0; space[last_pos] = amino_acids[0]; } @@ -227,9 +235,13 @@ void Protein::place_amino(int move, bool track) { cur_len++; - /* Update number of found solutions. */ - if (track && cur_len == (int)sequence.size()) { - solutions_checked++; + /* Update number of found solutions and amino acids placed. */ + if (track) { + aminos_placed++; + + if (cur_len == (int)sequence.size()) { + solutions_checked++; + } } } diff --git a/prospr/core/src/protein.hpp b/prospr/core/src/protein.hpp index 6e4aa55..88783fd 100644 --- a/prospr/core/src/protein.hpp +++ b/prospr/core/src/protein.hpp @@ -50,6 +50,9 @@ class Protein { /* Returns the number of performed changes. */ int get_solutions_checked(); + /* Returns the number of amino acids placed. */ + int get_aminos_placed(); + /* Returns if the amino acid at the given index is weighted. */ bool is_weighted(int index); @@ -91,6 +94,7 @@ class Protein { int last_move; std::vector last_pos; int score; + int aminos_placed; int solutions_checked; std::vector amino_acids; diff --git a/setup.py b/setup.py index 0e84e4a..d0c7bb3 100644 --- a/setup.py +++ b/setup.py @@ -12,7 +12,7 @@ from setuptools import setup from pybind11.setup_helpers import Pybind11Extension, build_ext -__version__ = "0.2a4" +__version__ = "0.2a5" # Define core module extension. ext_modules = [ @@ -43,7 +43,7 @@ packages=["prospr"], package_data={"prospr": ["data/*/*.csv"]}, platforms=["any"], - python_requires=">=3.6", + python_requires=">=3.9", zip_safe=False, install_requires=[ "matplotlib", diff --git a/tests/core/test_depth_first.py b/tests/core/test_depth_first.py index c357dc7..a9b8be3 100644 --- a/tests/core/test_depth_first.py +++ b/tests/core/test_depth_first.py @@ -30,6 +30,8 @@ def test_protein_2d_depth_first(self, protein_2d): """ p = depth_first(protein_2d) assert p.score == -3 + assert p.solutions_checked == 1000 + assert p.aminos_placed == 1574 def test_protein_3d_depth_first(self, protein_3d): """ @@ -37,3 +39,5 @@ def test_protein_3d_depth_first(self, protein_3d): """ p = depth_first(protein_3d) assert p.score == -4 + assert p.solutions_checked == 186455 + assert p.aminos_placed == 235818 diff --git a/tests/core/test_depth_first_bnb.py b/tests/core/test_depth_first_bnb.py index 6d41741..0d4982b 100644 --- a/tests/core/test_depth_first_bnb.py +++ b/tests/core/test_depth_first_bnb.py @@ -30,6 +30,8 @@ def test_protein_2d_depth_first_bnb(self, protein_2d): """ p = depth_first_bnb(protein_2d) assert p.score == -3 + assert p.solutions_checked == 4 + assert p.aminos_placed == 53 def test_protein_3d_depth_first_bnb(self, protein_3d): """ @@ -37,3 +39,5 @@ def test_protein_3d_depth_first_bnb(self, protein_3d): """ p = depth_first_bnb(protein_3d) assert p.score == -4 + assert p.solutions_checked == 5 + assert p.aminos_placed == 49368 diff --git a/tests/core/test_protein.py b/tests/core/test_protein.py index 23a4300..6eda715 100644 --- a/tests/core/test_protein.py +++ b/tests/core/test_protein.py @@ -33,6 +33,7 @@ def test_protein_2d_generation(self, protein_2d): assert protein_2d.last_pos == [0, 0] assert protein_2d.score == 0 assert protein_2d.solutions_checked == 0 + assert protein_2d.aminos_placed == 1 def test_protein_3d_generation(self, protein_3d): """Test if a 3D protein is generated correctly.""" @@ -44,32 +45,37 @@ def test_protein_3d_generation(self, protein_3d): assert protein_3d.last_pos == [0, 0, 0] assert protein_3d.score == 0 assert protein_3d.solutions_checked == 0 + assert protein_3d.aminos_placed == 1 def test_protein_2d_place_moves(self, protein_2d): """Test if a 2D protein can move in all directions.""" assert protein_2d.cur_len == 1 moves = [1, 2, -1, -1, -2] scores = [0, 0, -1, -1, -1] + track_placed = [1, 0, 1, 0, 1] for i, m in enumerate(moves): - protein_2d.place_amino(m) + protein_2d.place_amino(m, track=bool(track_placed[i])) assert protein_2d.hash_fold() == moves[: i + 1] assert protein_2d.cur_len == len(moves[: i + 1]) + 1 assert protein_2d.last_move == m assert protein_2d.score == scores[i] + assert protein_2d.aminos_placed == 1 + sum(track_placed[: i + 1]) def test_protein_3d_place_moves(self, protein_3d): """Test if a 3D protein can move in all directions.""" assert protein_3d.cur_len == 1 moves = [1, 2, -1, 3, -2, -1, -3] scores = [0, 0, -1, -1, -1, -1, -2] + track_placed = [1, 0, 1, 0, 1, 0, 1] for i, m in enumerate(moves): - protein_3d.place_amino(m) + protein_3d.place_amino(m, track=bool(track_placed[i])) assert protein_3d.hash_fold() == moves[: i + 1] assert protein_3d.cur_len == len(moves[: i + 1]) + 1 assert protein_3d.last_move == m assert protein_3d.score == scores[i] + assert protein_3d.aminos_placed == 1 + sum(track_placed[: i + 1]) def test_protein_2d_undo_moves(self, protein_2d): """Test if a 2D protein can remove amino acids in all directions."""