diff --git a/python-module/CMakeLists.txt b/python-module/CMakeLists.txt index 2fbd478..db79874 100644 --- a/python-module/CMakeLists.txt +++ b/python-module/CMakeLists.txt @@ -23,7 +23,7 @@ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. find_package(Python REQUIRED COMPONENTS Interpreter Development) -find_package(Boost REQUIRED COMPONENTS python) +find_package(Boost 1.83 REQUIRED COMPONENTS python) # --------- diff --git a/python-module/dssp-python-plugin.cpp b/python-module/dssp-python-plugin.cpp index 5b6210e..003c701 100644 --- a/python-module/dssp-python-plugin.cpp +++ b/python-module/dssp-python-plugin.cpp @@ -263,7 +263,7 @@ BOOST_PYTHON_MODULE(mkdssp) .value("pp", dssp::helix_type::pp); enum_("helix_position_type") - .value("None", dssp::helix_position_type::None) + .value("NoHelix", dssp::helix_position_type::None) .value("Start", dssp::helix_position_type::Start) .value("End", dssp::helix_position_type::End) .value("StartAndEnd", dssp::helix_position_type::StartAndEnd) @@ -274,7 +274,7 @@ BOOST_PYTHON_MODULE(mkdssp) .value("anti_parallel", ladder_direction_type::antiparallel); enum_("chain_break_type") - .value("None", dssp::chain_break_type::None) + .value("NoGap", dssp::chain_break_type::None) .value("NewChain", dssp::chain_break_type::NewChain) .value("Gap", dssp::chain_break_type::Gap); @@ -313,20 +313,20 @@ BOOST_PYTHON_MODULE(mkdssp) .add_property("nr", &dssp::residue_info::nr) .add_property("type", &dssp::residue_info::type) .add_property("ssBridgeNr", &dssp::residue_info::ssBridgeNr) - .def("helix", &dssp::residue_info::helix) + .def("helix", &dssp::residue_info::helix, args("helix_type"), "Return the position of this residue in a helix with type helix_type") .add_property("is_alpha_helix_end_before_start", &dssp::residue_info::is_alpha_helix_end_before_start) .add_property("bend", &dssp::residue_info::bend) .add_property("accessibility", &dssp::residue_info::accessibility) - .def("bridge_partner", &dssp::residue_info::bridge_partner) + .def("bridge_partner", &dssp::residue_info::bridge_partner, args("indexnr"), "Return a tuple containing the residue, number and direction for the bridge partner with index indexnr") .add_property("sheet", &dssp::residue_info::sheet) .add_property("strand", &dssp::residue_info::strand) - .def("acceptor", &dssp::residue_info::acceptor) - .def("donor", &dssp::residue_info::donor); + .def("acceptor", &dssp::residue_info::acceptor, args("indexnr"), "Return a tuple containing the residue and bond energy for the acceptor with index indexnr") + .def("donor", &dssp::residue_info::donor, args("indexnr"), "Return a tuple containing the residue and bond energy for the donor with index indexnr"); class_("dssp", init>()) .add_property("statistics", &dssp_wrapper::get_statistics) .def("__iter__", iterator()) - .def("get", &dssp_wrapper::get); + .def("get", &dssp_wrapper::get, args("asym_id", "seq_id"), "Return the residue info object for the residue with specified asym_id and seq_id"); - def("TestBond", test_bond_between_residues); + def("TestBond", test_bond_between_residues, args("a", "b"), "Returns true if residues a and b are bonded according to DSSP"); } \ No newline at end of file diff --git a/python-module/test-mkdssp.py b/python-module/test-mkdssp.py index 0eaeeda..62f69ff 100644 --- a/python-module/test-mkdssp.py +++ b/python-module/test-mkdssp.py @@ -1,4 +1,4 @@ -import mkdssp +from mkdssp import dssp, helix_type, TestBond import os import gzip @@ -7,7 +7,7 @@ file_path = os.path.join("..", "test", "1cbs.cif.gz") with gzip.open(file_path, "rt") as f: file_content = f.read() -dssp = mkdssp.dssp(file_content) +dssp = dssp(file_content) print("residues: ", dssp.statistics.residues) print("chains: ", dssp.statistics.chains) @@ -43,10 +43,10 @@ for res in dssp: print("nr", res.nr) print("type", res.type) print("ssBridgeNr", res.ssBridgeNr) - print("helix(_3_10)", res.helix(mkdssp.helix_type._3_10)) - print("helix(alpha)", res.helix(mkdssp.helix_type.alpha)) - print("helix(pi)", res.helix(mkdssp.helix_type.pi)) - print("helix(pp)", res.helix(mkdssp.helix_type.pp)) + print("helix(_3_10)", res.helix(helix_type._3_10)) + print("helix(alpha)", res.helix(helix_type.alpha)) + print("helix(pi)", res.helix(helix_type.pi)) + print("helix(pp)", res.helix(helix_type.pp)) print("is_alpha_helix_end_before_start", res.is_alpha_helix_end_before_start) print("bend", res.bend) print("sheet", res.sheet) @@ -61,15 +61,16 @@ for res in dssp: (ri, e) = res.acceptor(i) if ri != None: print("acceptor ", i, ri.asym_id, ri.seq_id, ri.compound_id, e) - print("test bond: ", mkdssp.TestBond(res, ri)) + print("test bond: ", TestBond(res, ri)) for i in range(0, 1): (ri, e) = res.donor(i) if ri != None: print("donor ", i, ri.asym_id, ri.seq_id, ri.compound_id, e) - print("test bond: ", mkdssp.TestBond(res, ri)) + print("test bond: ", TestBond(res, ri)) print("accessibility", res.accessibility) + break print("count: ", count) @@ -79,4 +80,4 @@ b = dssp.get('A', 6) print ("a & b", a, b) -assert(mkdssp.TestBond(a, b)) +assert(TestBond(a, b)) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index d568537..1a86376 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -35,3 +35,12 @@ endif() add_test(NAME unit-test-dssp COMMAND $ --data-dir ${CMAKE_CURRENT_SOURCE_DIR} --rsrc-dir ${CMAKE_CURRENT_SOURCE_DIR}/../libdssp/mmcif_pdbx/) + +if(BUILD_PYTHON_MODULE) + find_package(Python REQUIRED Interpreter) + + add_test(NAME python_module COMMAND ${Python_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/test-python.py") + set_tests_properties(python_module PROPERTIES + ENVIRONMENT "PYTHONPATH=${CMAKE_BINARY_DIR}/lib" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") +endif() \ No newline at end of file diff --git a/test/test-python.py b/test/test-python.py new file mode 100644 index 0000000..30837e5 --- /dev/null +++ b/test/test-python.py @@ -0,0 +1,68 @@ +from mkdssp import dssp, TestBond, helix_type, chain_break_type, helix_type, helix_position_type, structure_type +import gzip +import unittest + +class TestDssp(unittest.TestCase): + def setUp(self): + with gzip.open("1cbs.cif.gz", "rt") as f: + file_content = f.read() + + self.dssp = dssp(file_content) + + def test_dssp(self): + stats = self.dssp.statistics + self.assertEqual(stats.residues, 137) + + def test_count(self): + count = 0 + for r in self.dssp: + count += 1 + self.assertEqual(count, 137) + + def test_bond(self): + a = self.dssp.get('A', 137) + b = self.dssp.get('A', 6) + self.assertTrue(TestBond(a, b)) + + def test_one_residue(self): + r = self.dssp.get("A", 15) + + self.assertEqual(r.asym_id, "A") + self.assertEqual(r.seq_id, 15) + + self.assertEqual(r.compound_letter, "F") + self.assertEqual(r.auth_asym_id, "A") + self.assertEqual(r.auth_seq_id, 15) + self.assertEqual(r.pdb_strand_id, "A") + self.assertEqual(r.pdb_seq_num, 15) + self.assertEqual(r.pdb_ins_code, '') + self.assertEqual(r.alpha, 44.76425552368164) + self.assertEqual(r.kappa, 73.85977935791016) + self.assertEqual(r.phi, -66.86814880371094) + self.assertEqual(r.psi, -48.56082534790039) + self.assertEqual(r.tco, 0.9395495057106018) + self.assertEqual(r.omega, 179.16152954101562) + self.assertEqual(r.is_pre_pro, False) + self.assertEqual(r.is_cis, False) + self.assertEqual(r.chiral_volume, 0.0) + self.assertEqual(r.chi, [-170.86489868164062, 59.921932220458984]) + self.assertEqual(r.ca_location, {'x': 22.385000228881836, 'y': 17.197999954223633, 'z': 17.680999755859375}) + self.assertEqual(r.chain_break, chain_break_type.NoGap) + self.assertEqual(r.nr, 15) + self.assertEqual(r.type, structure_type.Alphahelix) + self.assertEqual(r.ssBridgeNr, 0) + self.assertEqual(r.helix(helix_type._3_10), helix_position_type.NoHelix) + self.assertEqual(r.helix(helix_type.alpha), helix_position_type.Start) + self.assertEqual(r.helix(helix_type.pi), helix_position_type.NoHelix) + self.assertEqual(r.helix(helix_type.pp), helix_position_type.NoHelix) + self.assertEqual(r.is_alpha_helix_end_before_start, False) + self.assertEqual(r.bend, True) + self.assertEqual(r.sheet, 0) + self.assertEqual(r.strand, 0) + + (acceptor, energy) = r.acceptor(0) + self.assertEqual(acceptor.seq_id, 17) + self.assertEqual(energy, -0.2) + +if __name__ == "__main__": + unittest.main() \ No newline at end of file