def get_link_inf(f, path):
    """Given a path to a node, returns information about
    the link, or None, if the path is not part of a link.  Returned link_inf has keys:
        link_type - type of link, either 'hard' or 'soft'
        loc  - location (key) of link group associated with link.  i.e. in links['lg'][link_type]
        is_source - For link_type "soft" returns True if is a link source (not the target
            of the link-group).  For link type 'hard' this is not returned.
    Note: This routine called 'get_link_inf' (not 'get_link_info") because the returned
    dictionary is different than what is stored in the node class, "link_info" dict.
    """
    link_type = (
        'hard' if path in f.links['path2lg']['hard']
               else 'soft' if path in f.links['path2lg']['soft'] 
                                       or path in f.links['lg']['soft']  # this in case path is the target
                            else 'ext' if path in f.links['path2lg']['ext'] else None)
    if link_type is None:
        # node is not in a hard, soft or ext link-group, so is not part of a link
        return None
    if link_type == 'soft':
        # soft link.  This is the target if it is the location for a soft link group
        is_source = not path in f.links['lg']['soft']
        loc = f.links['path2lg']['soft'][path] if is_source else path
        link_inf = {'link_type': link_type, 'loc': loc, 'is_source': is_source}
    else:
        # must be hard or external.  loc for hard is a tuple, for ext is file\npath
        loc = f.links['path2lg'][link_type][path]
        link_inf = {'link_type': link_type, 'loc': loc}
    return link_inf