diff --git a/higra/algo/horizontal_cuts.py b/higra/algo/horizontal_cuts.py index fef6b3a5..35b99231 100644 --- a/higra/algo/horizontal_cuts.py +++ b/higra/algo/horizontal_cuts.py @@ -77,20 +77,23 @@ def __labelisation_leaves(self, tree, leaf_graph, handle_rag=True): return labels -# @hg.extend_class(hg.HorizontalCutExplorer, method_name="__new__") -# def __make_HorizontalCutExplorer(cls, tree, altitudes): -# """ -# Creates an horizontal cut explorer for th given valued hierarchy. -# -# Altitudes must be increasing -# -# :param tree: input tree -# :param altitudes: tree nodes altitudes -# :return: an ``HorizontalCutExplorer`` -# """ -# return cls._make_HorizontalCutExplorer(tree, altitudes) -# -# -# @hg.extend_class(hg.HorizontalCutExplorer, method_name="__init__") -# def __dummy_init_HorizontalCutExplorer(*_): -# pass +@hg.extend_class(hg.HorizontalCutExplorer, method_name="__new__") +def __make_HorizontalCutExplorer(cls, tree, altitudes): + """ + Creates an horizontal cut explorer for the given valued hierarchy. + + Altitudes must be increasing + + :param tree: input tree + :param altitudes: tree nodes altitudes + :return: an ``HorizontalCutExplorer`` + """ + if not hg.test_altitudes_increasingness(tree, altitudes): + raise ValueError("'altitudes' must be increasing for 'tree'.") + + return cls._make_HorizontalCutExplorer(tree, altitudes) + + +@hg.extend_class(hg.HorizontalCutExplorer, method_name="__init__") +def __dummy_init_HorizontalCutExplorer(*_): + pass diff --git a/higra/algo/py_horizontal_cuts.cpp b/higra/algo/py_horizontal_cuts.cpp index c4874392..670a3577 100644 --- a/higra/algo/py_horizontal_cuts.cpp +++ b/higra/algo/py_horizontal_cuts.cpp @@ -67,10 +67,10 @@ struct def_horizontal_cut_explorer_ctr { template static void def(C &c, const char *doc) { - c.def(py::init( + c.def_static("_make_HorizontalCutExplorer", [](const typename c_t::tree_type &tree, const xt::pyarray &altitudes) { return c_t(tree, altitudes); - }), + }, doc, py::arg("tree"), py::arg("altitudes")); @@ -92,15 +92,7 @@ Each cut of the hierarchy can be accessed through: - the altitude of the cut. This operations runs in :math:`\mathcal{O}(k*\log(n))`, with :math:`k` the number of regions in the retrieved cut.)""" ); add_type_overloads, HG_TEMPLATE_NUMERIC_TYPES> - (c, - R"(Create an horizontal cut explorer for the provided valued hierarchy. - -Altitudes must be increasing - -:param tree: input tree -:param altitudes: tree nodes altitudes -:return: an ``HorizontalCutExplorer`` -)"); + (c,""); c.def("num_cuts", &class_t::num_cuts, "Number of horizontal cuts in the hierarchy."); c.def("num_regions_cut", &class_t::num_regions_cut, diff --git a/test/python/test_algo/test_horizontal_cuts.py b/test/python/test_algo/test_horizontal_cuts.py index 8516aaf2..814c31a5 100644 --- a/test/python/test_algo/test_horizontal_cuts.py +++ b/test/python/test_algo/test_horizontal_cuts.py @@ -35,6 +35,12 @@ def test_horizontal_cut_explorer_indexed(self): self.assertTrue(np.all(np.sort(c.nodes()) == np.sort(cut_nodes[i]))) self.assertTrue(c.altitude() == alt_cuts[i]) + def test_horizontal_cut_explorer_assert(self): + tree = hg.Tree(np.asarray((5, 5, 6, 6, 7, 7, 7, 7))) + altitudes = np.asarray((0, 0, 1, 0, 0, 2, 1, 1)) + with self.assertRaises(ValueError): + hch = hg.HorizontalCutExplorer(tree, altitudes) + def test_horizontal_cut_explorer_altitudes(self): tree = hg.Tree((11, 11, 11, 12, 12, 16, 13, 13, 13, 14, 14, 17, 16, 15, 15, 18, 17, 18, 18)) altitudes = np.asarray((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 3, 1, 2, 3))