Пример #1
0
def _move_label_properties_for_otu(otu, syntax_version):
    ol = find_val_literal_meta_first(otu, 'ot:originalLabel', syntax_version)
    assert ol is not None
    label_att = otu.get('@label')
    if label_att is not None:
        del otu['@label']
        if label_att != ol:
            ml = find_val_literal_meta_first(otu, 'ot:ottTaxonName', syntax_version)
            if (not ml) or (ml != label_att):
                add_literal_meta(otu, 'ot:altLabel', label_att, syntax_version)
Пример #2
0
 def add_or_replace_annotation(
         self,  #pylint: disable=R0201
         obj,
         annotation,
         agent,
         add_agent_only=False):
     '''Takes an `annotation` dictionary which is
     expected to have a string as the value of annotation['author']['name']
     This function will remove all annotations from obj that:
         1. have the same author/name, and
         2. have no messages that are flagged as messages to be preserved (values for 'preserve'
             that evaluate to true)
     '''
     nex = get_nexml_el(obj)
     nvers = detect_nexson_version(obj)
     _LOG.debug('detected version as ' + nvers)
     agents_obj = find_val_literal_meta_first(nex, 'ot:agents', nvers)
     if not agents_obj:
         agents_obj = add_literal_meta(nex, 'ot:agents', {'agent': []},
                                       nvers)
     agents_list = agents_obj.setdefault('agent', [])
     found_agent = False
     aid = agent['@id']
     for a in agents_list:
         if a.get('@id') == aid:
             found_agent = True
             break
     if not found_agent:
         agents_list.append(agent)
     if add_agent_only:
         delete_same_agent_annotation(obj, annotation)
     else:
         replace_same_agent_annotation(obj, annotation)
Пример #3
0
 def add_or_replace_annotation(self,  # pylint: disable=R0201
                               obj,
                               annotation,
                               agent,
                               add_agent_only=False):
     """Takes an `annotation` dictionary which is
     expected to have a string as the value of annotation['author']['name']
     This function will remove all annotations from obj that:
         1. have the same author/name, and
         2. have no messages that are flagged as messages to be preserved (values for 'preserve'
             that evaluate to true)
     """
     nex = get_nexml_el(obj)
     nvers = detect_nexson_version(obj)
     _LOG.debug('detected version as ' + nvers)
     agents_obj = find_val_literal_meta_first(nex, 'ot:agents', nvers)
     if not agents_obj:
         agents_obj = add_literal_meta(nex, 'ot:agents', {'agent': []}, nvers)
     agents_list = agents_obj.setdefault('agent', [])
     found_agent = False
     aid = agent['@id']
     for a in agents_list:
         if a.get('@id') == aid:
             found_agent = True
             break
     if not found_agent:
         agents_list.append(agent)
     if add_agent_only:
         delete_same_agent_annotation(obj, annotation)
     else:
         replace_same_agent_annotation(obj, annotation)
Пример #4
0
def get_annotation_list(nex_el, nexson_version):
    ae_s_obj = find_nested_meta_first(nex_el, 'ot:annotationEvents', nexson_version)
    if not ae_s_obj:
        ae_s_obj = add_literal_meta(nex_el, 'ot:annotationEvents', {'annotation': []}, nexson_version)
    # _LOG.debug('ae_s_obj = ' + str(ae_s_obj))
    annotation_list = ae_s_obj.setdefault('annotation', [])
    # _LOG.debug('annotation_list = ' + str(annotation_list))
    return annotation_list
Пример #5
0
def get_annotation_list(nex_el, nexson_version):
    ae_s_obj = find_nested_meta_first(nex_el, 'ot:annotationEvents',
                                      nexson_version)
    if not ae_s_obj:
        ae_s_obj = add_literal_meta(nex_el, 'ot:annotationEvents',
                                    {'annotation': []}, nexson_version)
    #_LOG.debug('ae_s_obj = ' + str(ae_s_obj))
    annotation_list = ae_s_obj.setdefault('annotation', [])
    #_LOG.debug('annotation_list = ' + str(annotation_list))
    return annotation_list
Пример #6
0
    def _post_key_check_validate_tree(self,
                                      tree_nex_id,
                                      tree_obj,
                                      vc,
                                      otus_group_id=None):
        node_list = tree_obj.get('node')
        if isinstance(node_list, dict):
            node_list = [node_list]
        elif (not node_list) or (not isinstance(node_list, list)):
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MissingCrucialContentWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=['node',])
            return errorReturn('no "node" in "trees"')
        edge_list = tree_obj.get('edge')
        if isinstance(edge_list, dict):
            edge_list = [edge_list]
        elif (not edge_list) or (not isinstance(edge_list, list)):
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MissingCrucialContentWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=['edge',])
            return errorReturn('no "edge" in tree')
        edge_id_list = [(i.get('@id'), i) for i in edge_list]
        valid = self._validate_edge_list(edge_id_list, vc)
        if not valid:
            return False
        node_id_obj_list = [(i.get('@id'), i) for i in node_list]
        valid = self._validate_node_list(node_id_obj_list, vc)
        if not valid:
            return False
        node_dict = {}
        for i in node_id_obj_list:
            nid, nd = i
            node_dict[nid] = nd
        missing_src = []
        missing_target = []
        for el in edge_id_list:
            e = el[1]
            sid = e.get('@source')
            tid = e.get('@target')
            if sid not in node_dict:
                missing_src.append(sid)
            if tid not in node_dict:
                missing_target.append(tid)
        if missing_src:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_ReferencedIDNotFoundWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=missing_src)
            return errorReturn('no "@source" in edge')
        if missing_target:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_ReferencedIDNotFoundWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=missing_target)
            return errorReturn('no "@target" in edge')
        if otus_group_id is None:
            tree_group = vc.anc_list[-1][1]
            otus_group_id = tree_group.get('@otus')

        lowest_nodeid_set = set()
        encountered_nodes = set()
        edge_by_target = {}
        edge_by_source = {}
        multi_parent_node = []
        for e in edge_list:
            t = e.get('@target')
            if t in edge_by_target:
                multi_parent_node.append(t)
            else:
                edge_by_target[t] = e
            #_LOG.debug('e=' + str(e))
            sid = e['@source']
            edge_by_source.setdefault(sid, []).append(e)
        if multi_parent_node:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_NodeWithMultipleParents,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=multi_parent_node)
        otuid2leaf = {}
        unflagged_leaves = []
        nonleaves_with_leaf_flags = []
        with_at_root_prop = {}
        first_lowest_node = None
        for nd in node_list:
            nid = nd.get('@id')
            cycle_node, path_to_root = construct_path_to_root(nd, encountered_nodes, edge_by_target)
            if cycle_node:
                self._error_event(_NEXEL.TREE,
                                  obj=tree_obj,
                                  err_type=gen_TreeCycleWarning,
                                  anc=vc.anc_list,
                                  obj_nex_id=tree_nex_id,
                                  cycle_node=cycle_node)
                return errorReturn('"@id" in node')
            if path_to_root:
                lowest_nodeid_set.add(path_to_root[-1])
                if first_lowest_node is None:
                    first_lowest_node = path_to_root[-1]
            is_flagged_as_leaf = self._find_first_literal_meta(nd, 'ot:isLeaf')
            ch_list = edge_by_source.get(nid)
            if ch_list is None:
                otu_id = nd.get('@otu')
                if otu_id is None:
                    vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
                    try:
                        self._error_event(_NEXEL.NODE,
                                          obj=nd,
                                          err_type=gen_MissingCrucialContentWarning,
                                          anc=vc.anc_list,
                                          obj_nex_id=nid,
                                          key_list=['@otu',])
                        return errorReturn('"@otu" in leaf')
                    finally:
                        vc.pop_context()
                else:
                    if otu_id in otuid2leaf:
                        vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
                        try:
                            self._error_event(_NEXEL.NODE,
                                              obj=nd,
                                              err_type=gen_RepeatedOTUWarning,
                                              anc=vc.anc_list,
                                              obj_nex_id=nid,
                                              key_list=[otu_id])
                            return errorReturn('repeated "@otu" in leaves')
                        finally:
                            vc.pop_context()
                    otuid2leaf[otu_id] = nd
                if not is_flagged_as_leaf:
                    if not self._logger.retain_deprecated:
                        add_literal_meta(nd, 'ot:isLeaf', True, self._syntax_version)
                    else:
                        unflagged_leaves.append(nid)
            elif is_flagged_as_leaf:
                if not self._logger.retain_deprecated:
                    delete_first_literal_meta(nd, 'ot:isLeaf', self._syntax_version)
                else:
                    nonleaves_with_leaf_flags.append(nid)
            if nd.get('@root'):
                with_at_root_prop[nid] = nd
        if unflagged_leaves:
            vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
            try:
                #_LOG.debug('unflagged_leaves="{f}"'.format(f=unflagged_leaves))
                self._error_event(_NEXEL.NODE,
                                  obj=tree_obj,
                                  err_type=gen_MissingMandatoryKeyWarning,
                                  anc=vc.anc_list,
                                  obj_nex_id=unflagged_leaves,
                                  key_list=['ot:isLeaf'])
            finally:
                vc.pop_context()
        if nonleaves_with_leaf_flags:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_InvalidKeyWarning,
                              anc=vc.anc_list,
                              obj_nex_id=nonleaves_with_leaf_flags,
                              key_list=['ot:isLeaf'])
            return errorReturn('"ot:isLeaf" for internal')
        self._detect_multilabelled_tree(otus_group_id,
                                        tree_nex_id,
                                        otuid2leaf)
        if len(lowest_nodeid_set) > 1:
            lowest_nodeid_set = list(lowest_nodeid_set)
            lowest_nodeid_set.sort()
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MultipleRootsWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=lowest_nodeid_set)
            return errorReturn('multiple roots in a tree')

        root_node_id = first_lowest_node

        if root_node_id not in with_at_root_prop:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MultipleRootsWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=list(with_at_root_prop.keys()) + [root_node_id])
            return errorReturn('root without "@root"')
        elif len(with_at_root_prop) > 1:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MultipleRootsWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=list(with_at_root_prop.keys()))
            return errorReturn('Multiple nodes with "@root"')
        elif len(with_at_root_prop) == 0:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_NoRootWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id)
            return errorReturn('no node with "@root"')
        og = set([i['@id'] for i in self._otu_group_by_id[otus_group_id]['otu']])
        nli = [(i['@id'], i) for i in node_list]
        return self._validate_otu_key_if_present(nli, og, vc)
Пример #7
0
    def _post_key_check_validate_tree(self,
                                      tree_nex_id,
                                      tree_obj,
                                      vc,
                                      otus_group_id=None):
        node_list = tree_obj.get('node')
        if isinstance(node_list, dict):
            node_list = [node_list]
        elif (not node_list) or (not isinstance(node_list, list)):
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MissingCrucialContentWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=[
                                  'node',
                              ])
            return errorReturn('no "node" in "trees"')
        edge_list = tree_obj.get('edge')
        if isinstance(edge_list, dict):
            edge_list = [edge_list]
        elif (not edge_list) or (not isinstance(edge_list, list)):
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MissingCrucialContentWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=[
                                  'edge',
                              ])
            return errorReturn('no "edge" in tree')
        edge_id_list = [(i.get('@id'), i) for i in edge_list]
        vc.push_context(_NEXEL.EDGE, (tree_obj, tree_nex_id))
        try:
            valid = self._validate_edge_list(edge_id_list, vc)
            if not valid:
                return False
        finally:
            vc.pop_context()
        node_id_obj_list = [(i.get('@id'), i) for i in node_list]
        vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
        try:
            valid = self._validate_node_list(node_id_obj_list, vc)
            if not valid:
                return False
        finally:
            vc.pop_context()
        node_dict = {}
        for i in node_id_obj_list:
            nid, nd = i
            node_dict[nid] = nd
        missing_src = []
        missing_target = []
        for el in edge_id_list:
            e = el[1]
            sid = e.get('@source')
            tid = e.get('@target')
            if sid not in node_dict:
                missing_src.append(sid)
            if tid not in node_dict:
                missing_target.append(tid)
        if missing_src:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_ReferencedIDNotFoundWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=missing_src)
            return errorReturn('no "@source" in edge')
        if missing_target:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_ReferencedIDNotFoundWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              key_list=missing_target)
            return errorReturn('no "@target" in edge')
        if otus_group_id is None:
            tree_group = vc.anc_list[-1][1]
            otus_group_id = tree_group.get('@otus')

        lowest_nodeid_set = set()
        encountered_nodes = set()
        edge_by_target = {}
        edge_by_source = {}
        multi_parent_node = []
        for e in edge_list:
            t = e.get('@target')
            if t in edge_by_target:
                multi_parent_node.append(t)
            else:
                edge_by_target[t] = e
            #_LOG.debug('e=' + str(e))
            sid = e['@source']
            edge_by_source.setdefault(sid, []).append(e)
        if multi_parent_node:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_NodeWithMultipleParents,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=multi_parent_node)
        otuid2leaf = {}
        unflagged_leaves = []
        nonleaves_with_leaf_flags = []
        with_at_root_prop = {}
        first_lowest_node = None
        for nd in node_list:
            nid = nd.get('@id')
            cycle_node, path_to_root = construct_path_to_root(
                nd, encountered_nodes, edge_by_target)
            if cycle_node:
                self._error_event(_NEXEL.TREE,
                                  obj=tree_obj,
                                  err_type=gen_TreeCycleWarning,
                                  anc=vc.anc_list,
                                  obj_nex_id=tree_nex_id,
                                  cycle_node=cycle_node)
                return errorReturn('"@id" in node')
            if path_to_root:
                lowest_nodeid_set.add(path_to_root[-1])
                if first_lowest_node is None:
                    first_lowest_node = path_to_root[-1]
            is_flagged_as_leaf = self._find_first_literal_meta(nd, 'ot:isLeaf')
            ch_list = edge_by_source.get(nid)
            if ch_list is None:
                otu_id = nd.get('@otu')
                if otu_id is None:
                    vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
                    try:
                        self._error_event(
                            _NEXEL.NODE,
                            obj=nd,
                            err_type=gen_MissingCrucialContentWarning,
                            anc=vc.anc_list,
                            obj_nex_id=nid,
                            key_list=[
                                '@otu',
                            ])
                        return errorReturn('"@otu" in leaf')
                    finally:
                        vc.pop_context()
                else:
                    if otu_id in otuid2leaf:
                        vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
                        try:
                            self._error_event(_NEXEL.NODE,
                                              obj=nd,
                                              err_type=gen_RepeatedOTUWarning,
                                              anc=vc.anc_list,
                                              obj_nex_id=nid,
                                              key_list=[otu_id])
                            return errorReturn('repeated "@otu" in leaves')
                        finally:
                            vc.pop_context()
                    otuid2leaf[otu_id] = nd
                if not is_flagged_as_leaf:
                    if not self._logger.retain_deprecated:
                        add_literal_meta(nd, 'ot:isLeaf', True,
                                         self._syntax_version)
                    else:
                        unflagged_leaves.append(nid)
            elif is_flagged_as_leaf:
                if not self._logger.retain_deprecated:
                    delete_first_literal_meta(nd, 'ot:isLeaf',
                                              self._syntax_version)
                else:
                    nonleaves_with_leaf_flags.append(nid)
            if nd.get('@root'):
                with_at_root_prop[nid] = nd
        if unflagged_leaves:
            vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
            try:
                #_LOG.debug('unflagged_leaves="{f}"'.format(f=unflagged_leaves))
                self._error_event(_NEXEL.NODE,
                                  obj=tree_obj,
                                  err_type=gen_MissingMandatoryKeyWarning,
                                  anc=vc.anc_list,
                                  obj_nex_id=unflagged_leaves,
                                  key_list=['ot:isLeaf'])
            finally:
                vc.pop_context()
        if nonleaves_with_leaf_flags:
            vc.push_context(_NEXEL.NODE, (tree_obj, tree_nex_id))
            try:
                self._error_event(_NEXEL.NODE,
                                  obj=tree_obj,
                                  err_type=gen_InvalidKeyWarning,
                                  anc=vc.anc_list,
                                  obj_nex_id=nonleaves_with_leaf_flags,
                                  key_list=['ot:isLeaf'])
                return errorReturn('"ot:isLeaf" for internal')
            finally:
                vc.pop_context()
        self._detect_multilabelled_tree(otus_group_id, tree_nex_id, otuid2leaf)
        if len(lowest_nodeid_set) > 1:
            lowest_nodeid_set = list(lowest_nodeid_set)
            lowest_nodeid_set.sort()
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MultipleRootsWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=lowest_nodeid_set)
            return errorReturn('multiple roots in a tree')

        root_node_id = first_lowest_node

        if root_node_id not in with_at_root_prop:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MultipleRootsWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=list(with_at_root_prop.keys()) +
                              [root_node_id])
            return errorReturn('root without "@root"')
        elif len(with_at_root_prop) > 1:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_MultipleRootsWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id,
                              node_id_list=list(with_at_root_prop.keys()))
            return errorReturn('Multiple nodes with "@root"')
        elif len(with_at_root_prop) == 0:
            self._error_event(_NEXEL.TREE,
                              obj=tree_obj,
                              err_type=gen_NoRootWarning,
                              anc=vc.anc_list,
                              obj_nex_id=tree_nex_id)
            return errorReturn('no node with "@root"')
        og = set(
            [i['@id'] for i in self._otu_group_by_id[otus_group_id]['otu']])
        nli = [(i['@id'], i) for i in node_list]
        return self._validate_otu_key_if_present(nli, og, vc)