Esempio n. 1
0
async def query_root_taxa() \
        -> List[TaxonBO]:
    """
        Return all taxa with no parent.
    """
    sce = TaxonomyService()
    ret = sce.query_roots()
    return ret
Esempio n. 2
0
async def taxa_tree_status(current_user: int = Depends(get_current_user)):
    """
        Return the status of taxonomy tree w/r to freshness.
    """
    sce = TaxonomyService()
    refresh_date = sce.status(_current_user_id=current_user)
    return TaxonomyTreeStatus(
        last_refresh=refresh_date.isoformat() if refresh_date else None)
Esempio n. 3
0
async def query_taxa(taxon_id: int,
                     _current_user: Optional[int] = Depends(get_optional_current_user)) \
        -> Optional[TaxonBO]:
    """
        Information about a single taxon, including its lineage.
    """
    sce = TaxonomyService()
    ret = sce.query(taxon_id)
    return ret
Esempio n. 4
0
async def query_taxa_in_worms(aphia_id: int,
                              _current_user: Optional[int] = Depends(get_optional_current_user)) \
        -> Optional[TaxonBO]:
    """
        Information about a single taxon in WoRMS reference, including its lineage.
    """
    sce = TaxonomyService()
    ret = sce.query_worms(aphia_id)
    return ret
Esempio n. 5
0
async def query_taxa_set(ids: str,
                         _current_user: Optional[int] = Depends(get_optional_current_user)) \
        -> List[TaxonBO]:
    """
        Information about several taxa, including their lineage.
        The separator between numbers is arbitrary non-digit, e.g. ":", "|" or ","
    """
    sce = TaxonomyService()
    num_ids = _split_num_list(ids)
    ret = sce.query_set(num_ids)
    return ret
Esempio n. 6
0
async def search_taxa(
    query: str,
    project_id: Optional[int],
    current_user: Optional[int] = Depends(get_optional_current_user)):
    """
        Search for taxa by name.

        Queries can be 'small', i.e. of length < 3 and even zero-length.
        For a public, unauthenticated call:
        - zero-length and small queries always return nothing.
        - otherwise, a full search is done and results are returned in alphabetical order.

        Behavior for an authenticated call:
        - zero-length queries: return the MRU list in full.
        - small queries: the MRU list is searched, so that taxa in the recent list are returned, if matching.
        - otherwise, a full search is done. Results are ordered so that taxa in the project list are in first,
            and are signalled as such in the response.
    """
    sce = TaxonomyService()
    ret = sce.search(current_user_id=current_user,
                     prj_id=project_id,
                     query=query)
    return ret
Esempio n. 7
0
    def do_match(
            self
    ) -> Tuple[Dict[ClassifIDT, WoRMS], Dict[ClassifIDT, ClassifIDT]]:
        """
            Returns: A dict with matched Phylo taxo ids->WoRMS entry. The taxa might be Morpho ones,
                        as the XLSX data source contains such mappings.
                    + Another dict with unmatched Morpho entries.

        :return:
        """
        ret: Dict[ClassifIDT, WoRMS] = {}

        # Do the manual (i.e. XLSX-driven) matching of what can be.
        # In this part, both Morpho and Phylo taxa are matched to WoRMS.
        to_worms: ToWorms = ToWorms()
        to_worms.prepare()
        to_worms.apply()
        manual_ids = set(to_worms.done_remaps.keys()).intersection(
            self.taxa_ids)
        for a_manual_id in list(manual_ids):
            # Get the mapping
            aphia_id = to_worms.done_remaps[a_manual_id]
            if aphia_id is None:
                # No mapping -> re-add to auto matching to come, who knows...
                manual_ids.remove(a_manual_id)
                continue
            worms_rec = self.session.query(WoRMS).get(aphia_id)
            assert worms_rec is not None
            ret[a_manual_id] = worms_rec

        # Do auto matching of the rest
        ids_for_auto_match = self.taxa_ids.difference(manual_ids)

        # Only keep Phylo taxa, the Morpho ones will get aggregated with their nearest Phylo parent
        phylo_auto_ids = TaxonomyBO.keep_phylo(self.session,
                                               list(ids_for_auto_match))

        # Lookup parents of morpho taxa
        with TaxonomyService() as taxo_sce:
            morpho_ids = list(ids_for_auto_match.difference(phylo_auto_ids))
            # Borrow taxo tree from ToWorms which has nearly all we need.
            to_worms.add_to_unieuk(morpho_ids, taxo_sce)
            unieuk_per_id = to_worms.unieuk
            needed_parents = []
            for a_morpho_id in morpho_ids:
                for a_parent_id in unieuk_per_id[a_morpho_id].id_lineage:
                    if a_parent_id not in unieuk_per_id:
                        needed_parents.append(a_parent_id)
            to_worms.add_to_unieuk(needed_parents, taxo_sce)

        # Build morpho -> nearest phylo mapping
        phylo_per_morpho: Dict[ClassifIDT, ClassifIDT] = {}
        for a_morpho_id in morpho_ids:
            for a_parent_id in unieuk_per_id[a_morpho_id].id_lineage:
                if unieuk_per_id[a_parent_id].type == 'P':
                    phylo_per_morpho[a_morpho_id] = a_parent_id
                    if a_parent_id not in ret:
                        phylo_auto_ids.add(a_parent_id)
                    break

        # Do more matches
        ret.update(WoRMSSetFromTaxaSet(self.session, list(phylo_auto_ids)).res)

        # Sanity check
        # for an_id in ret.keys():
        #     assert unieuk_per_id[an_id].type == 'P' # Not true
        for a_morpho_id, a_phylo_id in phylo_per_morpho.items():
            assert unieuk_per_id[a_morpho_id].type == 'M'
            assert unieuk_per_id[a_phylo_id].type == 'P'

        return ret, phylo_per_morpho