Example #1
0
 def test_get_names(self):
     names = pymaid.get_names(config_test.test_skids,
                              remote_instance=self.rm)
     self.assertIsInstance(names, dict)
     self.assertIsInstance(
         pymaid.get_skids_by_name(list(names.values()),
                                  remote_instance=self.rm), pd.DataFrame)
Example #2
0
def segments_to_skids(seg_ids,
                      autoseg_instance,
                      name_pattern="Google: {id}",
                      merge_annotation_pattern="Merged: {name}",
                      verbose=True):
    """Retrieve skeleton IDs of neurons corresponding to given segmentation ID(s).

    If a given segmentation ID has been merged into another fragment, will try
    retrieving by annotation.

    Parameters
    ----------
    seg_ids :                   int | list of int
                                Segmentation ID(s) of autoseg skeletons to retrieve.
    autoseg_instance :          pymaid.CatmaidInstance
                                Instance with autoseg skeletons.
    name_pattern :              str, optional
                                Segmentation IDs are encoded in the name. Use
                                this parameter to define that pattern.
    merge_annotation_pattern :  str, optional
                                When neurons are merged, a reference to the
                                loosing skeleton's name is kept as annotation.
                                Use this parameter to define that pattern.

    Returns
    -------
    Dict
                        Dictionary mapping segmentation ID to skeleton ID.
                        Will be ``None`` if no skeleton found.

    """
    assert isinstance(autoseg_instance, pymaid.CatmaidInstance)

    assert isinstance(seg_ids,
                      (list, np.ndarray, set, tuple, pd.Index, int, str))

    seg_ids = navis.utils.make_iterable(seg_ids)

    # Prepare map seg ID -> skeleton ID
    seg2skid = {int(i): None for i in seg_ids}

    # First find neurons by name
    # Do NOT change the order of "names"!
    names = [name_pattern.format(id=i) for i in seg_ids]
    by_name = pymaid.get_skids_by_name(names,
                                       allow_partial=False,
                                       raise_not_found=False,
                                       remote_instance=autoseg_instance)

    by_name['skeleton_id'] = by_name.skeleton_id.astype(int)

    # Update map by those that could be found by name
    name2skid = by_name.set_index('name').skeleton_id.to_dict()
    seg2skid.update({
        int(i): int(name2skid[n])
        for i, n in zip(seg_ids, names) if n in by_name.name.values
    })

    # Look for missing IDs
    not_found = [s for s in seg_ids if not seg2skid[int(s)]]

    # Try finding by annotation (temporarily raise logger level)
    if not_found:
        map = merge_annotation_pattern
        an = [map.format(name=name_pattern.format(id=n)) for n in not_found]
        old_lvl = pymaid.logger.level
        pymaid.set_loggers('ERROR')
        by_annotation = pymaid.get_skids_by_annotation(
            an,
            raise_not_found=False,
            allow_partial=False,
            intersect=False,
            remote_instance=autoseg_instance)
        pymaid.set_loggers(old_lvl)

        if by_annotation:
            annotations = pymaid.get_annotations(
                by_annotation, remote_instance=autoseg_instance)

            for seg, a in zip(not_found, an):
                for skid in annotations:
                    if a in annotations[skid]:
                        seg2skid[int(seg)] = int(skid)
                        break

    # Figure out if we are still missing skeletons for any of the seg IDs
    if verbose:
        missing = [str(k) for k, v in seg2skid.items() if not v]
        if missing:
            # Check if skeleton ID has ever existed
            hist = pymaid.get_skeleton_change(missing,
                                              remote_instance=autoseg_instance)
            # Flatten the list of links (and convert to string)
            existed = set([str(e) for l in hist for e in l[0]])

            still_missing = set(missing) & existed

            if still_missing:
                msg = "{} out of {} segmentation IDs could not be found: {}"
                msg = msg.format(len(still_missing), len(seg_ids),
                                 ", ".join(still_missing))
                print(msg)

    return seg2skid