Exemplo n.º 1
0
 def test_all_nonroot_branchlengths_zero(self):
     newicks = ['((b:0)a:0)root:0;', '((b:0)a:0)root:1;']
     for nwk in newicks:
         st = parse_newick(nwk)
         with self.assertRaisesRegex(ValueError,
                                     "must have a positive length"):
             validate_tree(st)
Exemplo n.º 2
0
 def test_nonroot_negative_branchlengths(self):
     newicks = [
         '((b:-1)a:1)root:1;', '((b:100)a:-100)root:0;', '(b:1,c:-1)a:2;',
         '((b:-1)a:0)root;'
     ]
     for nwk in newicks:
         st = parse_newick(nwk)
         with self.assertRaisesRegex(ValueError,
                                     "must have nonnegative lengths"):
             validate_tree(st)
Exemplo n.º 3
0
    def _validate_and_match_data(self, ignore_missing_samples,
                                 filter_extra_samples,
                                 filter_missing_features,
                                 shear_to_table,
                                 shear_to_feature_metadata):

        if self.is_community_plot:
            self.table, self.samples, self.tip_md, self.int_md = match_inputs(
                self.tree, self.table, self.samples, self.features,
                self.ordination, ignore_missing_samples, filter_extra_samples,
                filter_missing_features
            )
            # Remove empty samples and features from the table (and remove the
            # removed samples from the sample metadata). We also pass in the
            # ordination, if present, to this function -- so we can throw an
            # error if the ordination actually contains these empty
            # samples/features.
            #
            # We purposefully do this removal *after* matching (so we know the
            # data inputs match up) and *before* shearing (so empty features
            # in the table are no longer included as tips in the tree).
            self.table, self.samples = remove_empty_samples_and_features(
                self.table, self.samples, self.ordination
            )
            # remove unobserved features from the phylogeny (shear the tree)
            if shear_to_table:
                features = set(self.table.ids(axis='observation'))
                self.tree = self.tree.shear(features)
                # Remove features in the feature metadata that are no longer
                # present in the tree, due to being shorn off
                if self.tip_md is not None or self.int_md is not None:
                    # (Technically they should always both be None or both be
                    # DataFrames -- there's no in-between)
                    self.tip_md, self.int_md = filter_feature_metadata_to_tree(
                        self.tip_md, self.int_md, self.tree
                    )

        else:
            if shear_to_feature_metadata:
                features = set(self.features.index)
                all_tips = set(bp_tree_tips(self.tree))
                # check that feature metadata contains at least 1 tip
                if not features.intersection(all_tips):
                    raise ValueError(
                        "Cannot shear tree to feature metadata: no tips in "
                        "the tree are present in the feature metadata."
                    )
                self.tree = self.tree.shear(features)
            self.tip_md, self.int_md = match_tree_and_feature_metadata(
                self.tree, self.features
            )
        validate_tree(self.tree)
Exemplo n.º 4
0
 def test_validate_tree_duplicate_internal_node_names(self):
     bad_newicks = [
         # Two non-root internal nodes have same name
         '((a:1,b:3)c:2,(d:2,e:3)c:5)r:2;',
         # Two internal nodes (one of which is the root) have same name
         '((a:1,b:3)c:2,(d:2,e:3)f:5)c:2;'
     ]
     for nwk in bad_newicks:
         t = parse_newick(nwk)
         with self.assertWarnsRegex(
                 TreeFormatWarning,
                 "Internal node names in the tree are not unique"):
             validate_tree(t)
Exemplo n.º 5
0
 def test_validate_tree_overlapping_tip_and_internal_node_names(self):
     bad_newicks = [
         # Tip overlaps with non-root internal node
         '((a:1,b:3)a:2,d:5)e:2;',
         # Tip overlaps with root node
         '((a:1,b:3)c:2,d:5)a:2;',
         # Tip overlaps with both non-root and root internal nodes
         '((a:1,b:3)a:2,d:5)a:2;'
     ]
     for nwk in bad_newicks:
         t = parse_newick(nwk)
         with self.assertRaisesRegex(
                 ValueError,
                 "Tip names in the tree cannot overlap with internal node names"
         ):
             validate_tree(t)
Exemplo n.º 6
0
    def test_validate_tree(self):
        validate_tree(self.tree)

        # check the tree is still equivalent
        obs = self.tree
        exp = parse_newick(self.nwk)

        self.assertEqual(len(obs), len(exp))

        for i in range(1, len(exp) + 1):
            node_o = obs.postorderselect(i)
            node_e = exp.postorderselect(i)

            self.assertEqual(node_o, node_e)
            self.assertEqual(obs.length(node_o), exp.length(node_e))
            self.assertEqual(obs.name(node_o), exp.name(node_e))
Exemplo n.º 7
0
 def test_validate_tree_duplicate_tip_names(self):
     t = parse_newick('((i:1,a:3)b:2,i:5)r:2;')
     with self.assertRaisesRegex(ValueError,
                                 "Tip names in the tree must be unique"):
         validate_tree(t)