def get_closest_sibling_state(state_m, from_logical_port=None):
    """ Calculate the closest sibling also from optional logical port of handed state model

    :param StateModel state_m: Reference State model the closest sibling state should be find for
    :param str from_logical_port: The logical port of handed state model to be used as reference.
    :rtype: tuple
    :return: distance, StateModel of closest state
    """
    if not state_m.parent:
        logger.warning("A state can not have a closest sibling state if it has not parent as {0}".format(state_m))
        return

    margin = cal_margin(state_m.parent.get_meta_data_editor()['size'])
    pos = state_m.get_meta_data_editor()['rel_pos']
    size = state_m.get_meta_data_editor()['size']  # otherwise measure from reference state itself
    if from_logical_port in ["outcome", "income"]:
        size = (margin, margin)
    if from_logical_port == "outcome":
        outcomes_m = [outcome_m for outcome_m in state_m.outcomes if outcome_m.outcome.outcome_id >= 0]
        free_outcomes_m = [oc_m for oc_m in outcomes_m
                           if not state_m.state.parent.get_transition_for_outcome(state_m.state, oc_m.outcome)]
        if free_outcomes_m:
            outcome_m = free_outcomes_m[0]
        else:
            outcome_m = outcomes_m[0]
        pos = add_pos(pos, outcome_m.get_meta_data_editor()['rel_pos'])
    elif from_logical_port == "income":
        pos = add_pos(pos, state_m.income.get_meta_data_editor()['rel_pos'])

    min_distance = None
    for sibling_state_m in state_m.parent.states.values():
        if sibling_state_m is state_m:
            continue

        sibling_pos = sibling_state_m.get_meta_data_editor()['rel_pos']
        sibling_size = sibling_state_m.get_meta_data_editor()['size']

        distance = geometry.cal_dist_between_2_coord_frame_aligned_boxes(pos, size, sibling_pos, sibling_size)

        if not min_distance or min_distance[0] > distance:
            min_distance = (distance, sibling_state_m)

    return min_distance
Calculate the closest sibling also from optional logical port of handed state model

    :param StateModel state_m: Reference State model the closest sibling state should be find for
    :param str from_logical_port: The logical port of handed state model to be used as reference.
    :rtype: tuple
    :return: distance, StateModel of closest state